summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/COPYING2
-rw-r--r--src/H5.c60
-rw-r--r--src/H5A.c149
-rw-r--r--src/H5AC.c583
-rw-r--r--src/H5ACprivate.h75
-rw-r--r--src/H5ACpublic.h30
-rw-r--r--src/H5Abtree2.c98
-rw-r--r--src/H5Adense.c205
-rw-r--r--src/H5Adeprec.c4
-rw-r--r--src/H5Aint.c638
-rw-r--r--src/H5Apkg.h33
-rw-r--r--src/H5Aprivate.h1
-rw-r--r--src/H5Apublic.h4
-rw-r--r--src/H5Atest.c2
-rw-r--r--src/H5B.c409
-rw-r--r--src/H5B2.c971
-rw-r--r--src/H5B2cache.c461
-rw-r--r--src/H5B2dbg.c198
-rw-r--r--src/H5B2hdr.c613
-rw-r--r--src/H5B2int.c1454
-rw-r--r--src/H5B2pkg.h221
-rw-r--r--src/H5B2private.h96
-rw-r--r--src/H5B2stat.c83
-rw-r--r--src/H5B2test.c267
-rw-r--r--src/H5Bcache.c63
-rw-r--r--src/H5Bdbg.c284
-rw-r--r--src/H5Bpkg.h8
-rw-r--r--src/H5Bprivate.h17
-rw-r--r--src/H5Bpublic.h11
-rw-r--r--src/H5C.c2952
-rw-r--r--src/H5Cpkg.h128
-rw-r--r--src/H5Cprivate.h156
-rw-r--r--src/H5D.c222
-rw-r--r--src/H5Dbtree.c (renamed from src/H5Distore.c)1070
-rw-r--r--src/H5Dchunk.c1706
-rw-r--r--src/H5Dcompact.c183
-rw-r--r--src/H5Dcontig.c239
-rw-r--r--src/H5Ddbg.c2
-rw-r--r--src/H5Ddeprec.c12
-rw-r--r--src/H5Defl.c110
-rw-r--r--src/H5Dfill.c43
-rw-r--r--src/H5Dint.c640
-rw-r--r--src/H5Dio.c57
-rw-r--r--src/H5Dlayout.c466
-rw-r--r--src/H5Dmpio.c268
-rw-r--r--src/H5Doh.c84
-rw-r--r--src/H5Dpkg.h151
-rw-r--r--src/H5Dprivate.h37
-rw-r--r--src/H5Dpublic.h13
-rw-r--r--src/H5Dscatgath.c78
-rw-r--r--src/H5Dselect.c14
-rw-r--r--src/H5Dtest.c48
-rw-r--r--src/H5E.c101
-rw-r--r--src/H5EA.c1150
-rw-r--r--src/H5EAcache.c2106
-rw-r--r--src/H5EAdbg.c442
-rw-r--r--src/H5EAdblkpage.c318
-rw-r--r--src/H5EAdblock.c487
-rw-r--r--src/H5EAhdr.c732
-rw-r--r--src/H5EAiblock.c481
-rw-r--r--src/H5EAint.c144
-rw-r--r--src/H5EApkg.h453
-rw-r--r--src/H5EAprivate.h147
-rw-r--r--src/H5EAsblock.c446
-rw-r--r--src/H5EAstat.c116
-rw-r--r--src/H5EAtest.c422
-rw-r--r--src/H5Edefin.h27
-rw-r--r--src/H5Edeprec.c4
-rw-r--r--src/H5Einit.h389
-rw-r--r--src/H5Eint.c132
-rw-r--r--src/H5Eprivate.h87
-rw-r--r--src/H5Epubgen.h54
-rw-r--r--src/H5Epublic.h2
-rw-r--r--src/H5Eterm.h29
-rw-r--r--src/H5F.c2003
-rw-r--r--src/H5FA.c740
-rw-r--r--src/H5FAcache.c1129
-rw-r--r--src/H5FAdbg.c287
-rw-r--r--src/H5FAdblkpage.c312
-rw-r--r--src/H5FAdblock.c442
-rw-r--r--src/H5FAhdr.c488
-rw-r--r--src/H5FApkg.h289
-rw-r--r--src/H5FAprivate.h131
-rw-r--r--src/H5FAstat.c113
-rw-r--r--src/H5FAtest.c431
-rw-r--r--src/H5FD.c1045
-rw-r--r--src/H5FDcore.c291
-rw-r--r--src/H5FDdirect.c92
-rw-r--r--src/H5FDdirect.h4
-rw-r--r--src/H5FDfamily.c319
-rw-r--r--src/H5FDint.c312
-rw-r--r--src/H5FDlog.c262
-rw-r--r--src/H5FDmpi.h5
-rw-r--r--src/H5FDmpio.c179
-rw-r--r--src/H5FDmpio.h2
-rw-r--r--src/H5FDmpiposix.c39
-rw-r--r--src/H5FDmpiposix.h3
-rw-r--r--src/H5FDmulti.c187
-rw-r--r--src/H5FDpkg.h8
-rw-r--r--src/H5FDprivate.h34
-rw-r--r--src/H5FDpublic.h114
-rw-r--r--src/H5FDsec2.c328
-rw-r--r--src/H5FDsec2.h1
-rw-r--r--src/H5FDspace.c1648
-rw-r--r--src/H5FDstdio.c103
-rw-r--r--src/H5FDwindows.c232
-rw-r--r--src/H5FL.c631
-rw-r--r--src/H5FLprivate.h50
-rw-r--r--src/H5FO.c72
-rw-r--r--src/H5FOprivate.h2
-rw-r--r--src/H5FS.c646
-rw-r--r--src/H5FScache.c139
-rw-r--r--src/H5FSdbg.c23
-rw-r--r--src/H5FSpkg.h46
-rw-r--r--src/H5FSprivate.h44
-rw-r--r--src/H5FSsection.c1302
-rw-r--r--src/H5FSstat.c105
-rw-r--r--src/H5FStest.c154
-rw-r--r--src/H5Faccum.c702
-rw-r--r--src/H5Fdbg.c58
-rw-r--r--src/H5Fdeprec.c173
-rw-r--r--src/H5Ffake.c6
-rw-r--r--src/H5Fio.c173
-rw-r--r--src/H5Fmount.c111
-rw-r--r--src/H5Fmpi.c181
-rw-r--r--src/H5Fpkg.h185
-rw-r--r--src/H5Fprivate.h201
-rw-r--r--src/H5Fpublic.h94
-rw-r--r--src/H5Fquery.c838
-rw-r--r--src/H5Fsfile.c2
-rw-r--r--src/H5Fsuper.c1122
-rw-r--r--src/H5Fsuper_cache.c920
-rw-r--r--src/H5Ftest.c75
-rw-r--r--src/H5G.c280
-rw-r--r--src/H5Gbtree2.c102
-rw-r--r--src/H5Gcache.c438
-rw-r--r--src/H5Gcompact.c15
-rw-r--r--src/H5Gdense.c316
-rw-r--r--src/H5Gdeprec.c24
-rw-r--r--src/H5Gent.c130
-rw-r--r--src/H5Gint.c11
-rw-r--r--src/H5Glink.c15
-rw-r--r--src/H5Gloc.c26
-rw-r--r--src/H5Gname.c34
-rw-r--r--src/H5Gnode.c511
-rw-r--r--src/H5Gobj.c334
-rw-r--r--src/H5Goh.c181
-rw-r--r--src/H5Gpkg.h61
-rw-r--r--src/H5Gprivate.h19
-rw-r--r--src/H5Gpublic.h2
-rw-r--r--src/H5Groot.c269
-rw-r--r--src/H5Gstab.c94
-rw-r--r--src/H5Gtest.c98
-rw-r--r--src/H5Gtraverse.c119
-rw-r--r--src/H5HF.c38
-rw-r--r--src/H5HFbtree2.c639
-rw-r--r--src/H5HFcache.c284
-rw-r--r--src/H5HFdbg.c13
-rw-r--r--src/H5HFdblock.c58
-rw-r--r--src/H5HFdtable.c8
-rw-r--r--src/H5HFhdr.c112
-rw-r--r--src/H5HFhuge.c186
-rw-r--r--src/H5HFiblock.c94
-rw-r--r--src/H5HFiter.c7
-rw-r--r--src/H5HFman.c33
-rw-r--r--src/H5HFpkg.h48
-rw-r--r--src/H5HFprivate.h2
-rw-r--r--src/H5HFsection.c112
-rw-r--r--src/H5HFspace.c14
-rw-r--r--src/H5HFstat.c43
-rw-r--r--src/H5HFtest.c24
-rw-r--r--src/H5HFtiny.c2
-rw-r--r--src/H5HG.c767
-rw-r--r--src/H5HGcache.c452
-rw-r--r--src/H5HGdbg.c9
-rw-r--r--src/H5HGpkg.h56
-rw-r--r--src/H5HGprivate.h6
-rw-r--r--src/H5HL.c561
-rw-r--r--src/H5HLcache.c479
-rw-r--r--src/H5HLdbg.c4
-rw-r--r--src/H5HLpkg.h21
-rw-r--r--src/H5HLprivate.h3
-rw-r--r--src/H5HP.c64
-rw-r--r--src/H5I.c1079
-rw-r--r--src/H5Iprivate.h14
-rw-r--r--src/H5Ipublic.h3
-rw-r--r--src/H5L.c58
-rw-r--r--src/H5Lexternal.c318
-rw-r--r--src/H5Lprivate.h9
-rw-r--r--src/H5Lpublic.h9
-rw-r--r--src/H5MF.c1170
-rw-r--r--src/H5MFaggr.c727
-rw-r--r--src/H5MFdbg.c306
-rw-r--r--src/H5MFpkg.h175
-rw-r--r--src/H5MFprivate.h57
-rw-r--r--src/H5MFsection.c533
-rw-r--r--src/H5MM.c16
-rw-r--r--src/H5MP.c10
-rw-r--r--src/H5O.c526
-rw-r--r--src/H5Oainfo.c79
-rw-r--r--src/H5Oalloc.c486
-rw-r--r--src/H5Oattr.c343
-rw-r--r--src/H5Oattribute.c320
-rw-r--r--src/H5Obogus.c7
-rw-r--r--src/H5Obtreek.c19
-rw-r--r--src/H5Ocache.c117
-rw-r--r--src/H5Ocont.c9
-rw-r--r--src/H5Ocopy.c46
-rw-r--r--src/H5Odbg.c28
-rw-r--r--src/H5Odrvinfo.c21
-rw-r--r--src/H5Odtype.c224
-rw-r--r--src/H5Oefl.c29
-rw-r--r--src/H5Ofill.c68
-rw-r--r--src/H5Ofsinfo.c309
-rw-r--r--src/H5Oginfo.c11
-rw-r--r--src/H5Olayout.c367
-rw-r--r--src/H5Olinfo.c21
-rw-r--r--src/H5Olink.c31
-rw-r--r--src/H5Omessage.c41
-rw-r--r--src/H5Omtime.c28
-rw-r--r--src/H5Oname.c60
-rw-r--r--src/H5Opkg.h91
-rw-r--r--src/H5Opline.c49
-rw-r--r--src/H5Oprivate.h136
-rw-r--r--src/H5Opublic.h37
-rw-r--r--src/H5Orefcount.c11
-rw-r--r--src/H5Osdspace.c12
-rw-r--r--src/H5Oshared.c58
-rw-r--r--src/H5Oshared.h19
-rw-r--r--src/H5Oshmesg.c11
-rw-r--r--src/H5Ostab.c47
-rw-r--r--src/H5Otest.c94
-rw-r--r--src/H5Ounknown.c2
-rw-r--r--src/H5P.c106
-rw-r--r--src/H5Pdapl.c273
-rw-r--r--src/H5Pdcpl.c1465
-rw-r--r--src/H5Pdeprec.c58
-rw-r--r--src/H5Pdxpl.c12
-rw-r--r--src/H5Pfapl.c125
-rw-r--r--src/H5Pfcpl.c309
-rw-r--r--src/H5Pgcpl.c12
-rw-r--r--src/H5Pint.c355
-rw-r--r--src/H5Plapl.c413
-rw-r--r--src/H5Plcpl.c2
-rwxr-xr-xsrc/H5Pocpl.c1163
-rw-r--r--src/H5Ppkg.h3
-rw-r--r--src/H5Pprivate.h17
-rw-r--r--src/H5Ppublic.h77
-rw-r--r--src/H5Ptest.c24
-rw-r--r--src/H5R.c44
-rw-r--r--src/H5RC.c34
-rw-r--r--src/H5RS.c118
-rw-r--r--src/H5Rpublic.h2
-rw-r--r--src/H5S.c325
-rw-r--r--src/H5SL.c1089
-rw-r--r--src/H5SLprivate.h6
-rwxr-xr-xsrc/H5SM.c538
-rwxr-xr-xsrc/H5SMbtree2.c339
-rw-r--r--src/H5SMcache.c79
-rw-r--r--src/H5SMmessage.c358
-rwxr-xr-xsrc/H5SMpkg.h58
-rwxr-xr-xsrc/H5SMprivate.h2
-rw-r--r--src/H5SMtest.c6
-rw-r--r--src/H5ST.c232
-rw-r--r--src/H5Sall.c3
-rw-r--r--src/H5Shyper.c355
-rw-r--r--src/H5Smpio.c338
-rw-r--r--src/H5Snone.c13
-rw-r--r--src/H5Spkg.h2
-rw-r--r--src/H5Spoint.c144
-rw-r--r--src/H5Sprivate.h5
-rw-r--r--src/H5Spublic.h3
-rw-r--r--src/H5Sselect.c132
-rw-r--r--src/H5Stest.c14
-rw-r--r--src/H5T.c1344
-rw-r--r--src/H5Tarray.c106
-rw-r--r--src/H5Tbit.c145
-rw-r--r--src/H5Tcommit.c122
-rw-r--r--src/H5Tcompound.c322
-rw-r--r--src/H5Tconv.c2516
-rw-r--r--src/H5Tcset.c8
-rw-r--r--src/H5Tdeprec.c5
-rw-r--r--src/H5Tenum.c2
-rw-r--r--src/H5Tfields.c125
-rw-r--r--src/H5Tnative.c14
-rw-r--r--src/H5Toffset.c6
-rw-r--r--src/H5Toh.c10
-rw-r--r--src/H5Torder.c2
-rw-r--r--src/H5Tpkg.h56
-rw-r--r--src/H5Tprivate.h32
-rw-r--r--src/H5Tpublic.h4
-rw-r--r--src/H5Tvisit.c2
-rw-r--r--src/H5Tvlen.c277
-rw-r--r--src/H5Vprivate.h60
-rw-r--r--src/H5WB.c2
-rw-r--r--src/H5Z.c452
-rw-r--r--src/H5Zdeflate.c11
-rw-r--r--src/H5Zfletcher32.c2
-rw-r--r--src/H5Znbit.c10
-rw-r--r--src/H5Zpkg.h28
-rw-r--r--src/H5Zprivate.h11
-rw-r--r--src/H5Zpublic.h30
-rw-r--r--src/H5Zscaleoffset.c138
-rw-r--r--src/H5Zshuffle.c2
-rw-r--r--src/H5Zszip.c6
-rw-r--r--src/H5Ztrans.c274
-rw-r--r--src/H5checksum.c6
-rw-r--r--src/H5config.h.in58
-rw-r--r--src/H5detect.c250
-rw-r--r--src/H5err.txt5
-rw-r--r--src/H5overflow.h1381
-rw-r--r--src/H5overflow.txt43
-rw-r--r--src/H5private.h597
-rw-r--r--src/H5public.h39
-rw-r--r--src/H5system.c156
-rw-r--r--src/H5trace.c546
-rw-r--r--src/H5vers.txt2
-rw-r--r--src/H5version.h150
-rw-r--r--src/H5win32defs.h19
-rwxr-xr-xsrc/Makefile.am56
-rw-r--r--src/Makefile.in410
-rw-r--r--src/libhdf5.settings.in61
322 files changed, 53200 insertions, 24431 deletions
diff --git a/src/COPYING b/src/COPYING
index ef0cbaf..6903daf 100755
--- a/src/COPYING
+++ b/src/COPYING
@@ -1,5 +1,5 @@
- Copyright by The HDF Group (THG) and
+ Copyright by The HDF Group and
The Board of Trustees of the University of Illinois.
All rights reserved.
diff --git a/src/H5.c b/src/H5.c
index 795e30e..6bd96cb 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -28,6 +28,7 @@
#include "H5Lprivate.h" /* Links */
#include "H5Pprivate.h" /* Property lists */
#include "H5Tprivate.h" /* Datatypes */
+#include "H5SLprivate.h" /* Skip lists */
/****************/
@@ -60,6 +61,10 @@ static void H5_debug_mask(const char*);
/* Library Private Variables */
/*****************************/
+/* HDF5 API Entered variable */
+/* (move to H5.c when new FUNC_ENTER macros in actual use -QAK) */
+hbool_t H5_api_entered_g = FALSE;
+
/* statically initialize block for pthread_once call used in initializing */
/* the first global mutex */
#ifdef H5_HAVE_THREADSAFE
@@ -270,6 +275,9 @@ H5_term_library(void)
/* Don't shut down the ID code until other APIs which use them are shut down */
if(pending == 0)
pending += DOWN(I);
+ /* Don't shut down the skip list code until everything that uses it is down */
+ if(pending == 0)
+ pending += DOWN(SL);
/* Don't shut down the free list code until _everything_ else is down */
if(pending == 0)
pending += DOWN(FL);
@@ -344,7 +352,7 @@ H5dont_atexit(void)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API_NOINIT_NOFS(H5dont_atexit)
+ FUNC_ENTER_API_NOINIT_NOERR_NOFS(H5dont_atexit)
H5TRACE0("e","");
if(H5_dont_atexit_g)
@@ -405,6 +413,9 @@ done:
* global lists, up to 3 MB of total storage might be allocated (1MB on
* each of regular, array and block type lists).
*
+ * The settings for block free lists are duplicated to factory free lists.
+ * Factory free list limits cannot be set independently currently.
+ *
* Parameters:
* int reg_global_lim; IN: The limit on all "regular" free list memory used
* int reg_list_lim; IN: The limit on memory used in each "regular" free list
@@ -420,7 +431,9 @@ done:
* Programmer: Quincey Koziol
* Wednesday, August 2, 2000
*
- * Modifications:
+ * Modifications: Neil Fortner
+ * Wednesday, April 8, 2009
+ * Added support for factory free lists
*
*-------------------------------------------------------------------------
*/
@@ -435,7 +448,8 @@ H5set_free_list_limits(int reg_global_lim, int reg_list_lim, int arr_global_lim,
arr_list_lim, blk_global_lim, blk_list_lim);
/* Call the free list function to actually set the limits */
- if(H5FL_set_free_list_limits(reg_global_lim, reg_list_lim, arr_global_lim, arr_list_lim, blk_global_lim, blk_list_lim)<0)
+ if(H5FL_set_free_list_limits(reg_global_lim, reg_list_lim, arr_global_lim, arr_list_lim,
+ blk_global_lim, blk_list_lim, blk_global_lim, blk_list_lim)<0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSET, FAIL, "can't set garbage collection limits")
done:
@@ -600,6 +614,8 @@ done:
"The HDF5 header files used to compile this application do not match\n" \
"the version used by the HDF5 library to which this application is linked.\n" \
"Data corruption or segmentation faults may occur if the application continues.\n" \
+ "This can happen when an application was compiled by one version of HDF5 but\n" \
+ "linked with a different version of static or shared HDF5 library.\n" \
"You should recompile the application or check your shared library related\n" \
"settings such as 'LD_LIBRARY_PATH'.\n"
@@ -609,10 +625,11 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum)
char lib_str[256];
char substr[] = H5_VERS_SUBRELEASE;
static int checked = 0; /* If we've already checked the version info */
- static int disable_version_check = 0; /* Set if the version check should be disabled */
- herr_t ret_value=SUCCEED; /* Return value */
+ static unsigned int disable_version_check = 0; /* Set if the version check should be disabled */
+ static const char *version_mismatch_warning = VERSION_MISMATCH_WARNING;
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API_NOINIT_NOFS(H5check_version)
+ FUNC_ENTER_API_NOINIT_NOERR_NOFS(H5check_version)
H5TRACE3("e", "IuIuIu", majnum, minnum, relnum);
/* Don't check again, if we already have */
@@ -625,39 +642,44 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum)
s = HDgetenv ("HDF5_DISABLE_VERSION_CHECK");
if (s && HDisdigit(*s))
- disable_version_check = (int)HDstrtol (s, NULL, 0);
+ disable_version_check = (unsigned int)HDstrtol (s, NULL, 0);
}
if (H5_VERS_MAJOR!=majnum || H5_VERS_MINOR!=minnum ||
H5_VERS_RELEASE!=relnum) {
switch (disable_version_check) {
case 0:
- HDfputs (VERSION_MISMATCH_WARNING
+ HDfprintf(stderr, "%s%s", version_mismatch_warning,
"You can, at your own risk, disable this warning by setting the environment\n"
"variable 'HDF5_DISABLE_VERSION_CHECK' to a value of '1'.\n"
- "Setting it to 2 will suppress the warning messages totally.\n",
- stderr);
+ "Setting it to 2 or higher will suppress the warning messages totally.\n");
/* Mention the versions we are referring to */
HDfprintf (stderr, "Headers are %u.%u.%u, library is %u.%u.%u\n",
majnum, minnum, relnum,
(unsigned)H5_VERS_MAJOR, (unsigned)H5_VERS_MINOR, (unsigned)H5_VERS_RELEASE);
+ /* Show library settings if available */
+ HDfprintf (stderr, "%s", H5libhdf5_settings);
/* Bail out now. */
HDfputs ("Bye...\n", stderr);
HDabort ();
- case 2:
- /* continue silently */
- break;
- default:
+ case 1:
/* continue with a warning */
- HDfprintf (stderr, VERSION_MISMATCH_WARNING
- "'HDF5_DISABLE_VERSION_CHECK' "
+ /* Note that the warning message is embedded in the format string.*/
+ HDfprintf (stderr,
+ "%s'HDF5_DISABLE_VERSION_CHECK' "
"environment variable is set to %d, application will\n"
- "continue at your own risk.\n", disable_version_check);
+ "continue at your own risk.\n",
+ version_mismatch_warning, disable_version_check);
/* Mention the versions we are referring to */
HDfprintf (stderr, "Headers are %u.%u.%u, library is %u.%u.%u\n",
majnum, minnum, relnum,
(unsigned)H5_VERS_MAJOR, (unsigned)H5_VERS_MINOR, (unsigned)H5_VERS_RELEASE);
+ /* Show library settings if available */
+ HDfprintf (stderr, "%s", H5libhdf5_settings);
+ break;
+ default:
+ /* 2 or higer: continue silently */
break;
} /* end switch */
@@ -674,7 +696,7 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum)
*/
sprintf(lib_str, "HDF5 library version: %d.%d.%d",
H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE);
- if (*substr){
+ if(*substr) {
HDstrcat(lib_str, "-");
HDstrncat(lib_str, substr, (sizeof(lib_str) - HDstrlen(lib_str)) - 1);
} /* end if */
@@ -751,7 +773,7 @@ H5close(void)
* whole library just to release it all right away. It is safe to call
* this function for an uninitialized library.
*/
- FUNC_ENTER_API_NOINIT_NOFS(H5close)
+ FUNC_ENTER_API_NOINIT_NOERR_NOFS(H5close)
H5TRACE0("e","");
H5_term_library();
diff --git a/src/H5A.c b/src/H5A.c
index 9fc3781..c958bbd 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -176,7 +176,7 @@ H5A_term_interface(void)
if(H5_interface_initialize_g) {
if((n = H5I_nmembers(H5I_ATTR))>0) {
- (void)H5I_clear_type(H5I_ATTR, FALSE);
+ (void)H5I_clear_type(H5I_ATTR, FALSE, FALSE);
} else {
(void)H5I_dec_type_ref(H5I_ATTR);
H5_interface_initialize_g = 0;
@@ -345,7 +345,7 @@ done:
* Purpose:
* This is the guts of creating an attribute.
* Usage:
- * hid_t H5A_create (ent, name, type, space)
+ * hid_t H5A_create(ent, name, type, space)
* const H5G_entry_t *ent; IN: Pointer to symbol table entry for object to attribute
* const char *name; IN: Name of attribute
* H5T_t *type; IN: Datatype of attribute
@@ -363,7 +363,7 @@ hid_t
H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
const H5S_t *space, hid_t acpl_id, hid_t dxpl_id)
{
- H5A_t *attr = NULL;
+ H5A_t *attr = NULL; /* Attribute created */
hssize_t snelmts; /* elements in attribute */
size_t nelmts; /* elements in attribute */
htri_t tri_ret; /* htri_t return value */
@@ -392,7 +392,7 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace extent has not been set")
/* Build the attribute information */
- if((attr = H5FL_CALLOC(H5A_t)) == NULL)
+ if(NULL == (attr = H5FL_CALLOC(H5A_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for attribute info")
if(NULL == (attr->shared = H5FL_CALLOC(H5A_shared_t)))
@@ -415,10 +415,11 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
/* Copy the attribute name */
attr->shared->name = H5MM_xstrdup(name);
- /* Copy the attribute's datatype */
- attr->shared->dt = H5T_copy(type, H5T_COPY_ALL);
+ /* Copy datatype */
+ if(NULL == (attr->shared->dt = H5T_copy(type, H5T_COPY_ALL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared datatype info")
- /* Mark any datatypes as being on disk now */
+ /* Mark datatype as being on disk now */
if(H5T_set_loc(attr->shared->dt, loc->oloc->file, H5T_LOC_DISK) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
@@ -435,11 +436,8 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
if(H5S_set_latest_version(attr->shared->ds) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of dataspace")
- /* Mark it initially set to initialized */
- attr->shared->initialized = TRUE; /*for now, set to false later*/
-
/* Copy the object header information */
- if(H5O_loc_copy(&(attr->shared->oloc), loc->oloc, H5_COPY_DEEP) < 0)
+ if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
/* Deep copy of the group hierarchy path */
@@ -449,9 +447,9 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
/* Check if any of the pieces should be (or are already) shared in the
* SOHM table
*/
- if(H5SM_try_share(attr->shared->oloc.file, dxpl_id, NULL, H5O_DTYPE_ID, attr->shared->dt, NULL) < 0)
+ if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, H5O_DTYPE_ID, attr->shared->dt, NULL) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share datatype failed")
- if(H5SM_try_share(attr->shared->oloc.file, dxpl_id, NULL, H5O_SDSPACE_ID, attr->shared->ds, NULL) < 0)
+ if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, H5O_SDSPACE_ID, attr->shared->ds, NULL) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share dataspace failed")
/* Check whether datatype is committed & increment ref count
@@ -468,8 +466,8 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
* datatype and dataspace messages themselves, or the size of the "shared"
* messages if either or both of them are shared.
*/
- attr->shared->dt_size = H5O_msg_raw_size(attr->shared->oloc.file, H5O_DTYPE_ID, FALSE, attr->shared->dt);
- attr->shared->ds_size = H5O_msg_raw_size(attr->shared->oloc.file, H5O_SDSPACE_ID, FALSE, attr->shared->ds);
+ attr->shared->dt_size = H5O_msg_raw_size(attr->oloc.file, H5O_DTYPE_ID, FALSE, attr->shared->dt);
+ attr->shared->ds_size = H5O_msg_raw_size(attr->oloc.file, H5O_SDSPACE_ID, FALSE, attr->shared->ds);
/* Get # of elements for attribute's dataspace */
if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0)
@@ -478,28 +476,25 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
HDassert(attr->shared->dt_size > 0);
HDassert(attr->shared->ds_size > 0);
- attr->shared->data_size = nelmts * H5T_get_size(attr->shared->dt);
+ attr->shared->data_size = nelmts * H5T_GET_SIZE(attr->shared->dt);
/* Hold the symbol table entry (and file) open */
- if(H5O_open(&(attr->shared->oloc)) < 0)
+ if(H5O_open(&(attr->oloc)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open")
attr->obj_opened = TRUE;
/* Set the version to encode the attribute with */
- if(H5A_set_version(attr->shared->oloc.file, attr) < 0)
+ if(H5A_set_version(attr->oloc.file, attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "unable to update attribute version")
/* Insert the attribute into the object header */
- if(H5O_attr_create(&(attr->shared->oloc), dxpl_id, attr) < 0)
+ if(H5O_attr_create(&(attr->oloc), dxpl_id, attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to create attribute in object header")
/* Register the new attribute and get an ID for it */
- if((ret_value = H5I_register(H5I_ATTR, attr)) < 0)
+ if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
- /* Now it's safe to say it's uninitialized */
- attr->shared->initialized = FALSE;
-
done:
/* Cleanup on failure */
if(ret_value < 0 && attr && H5A_close(attr) < 0)
@@ -549,14 +544,13 @@ H5Aopen(hid_t loc_id, const char *attr_name, hid_t UNUSED aapl_id)
/* Read in attribute from object header */
if(NULL == (attr = H5O_attr_open_by_name(loc.oloc, attr_name, H5AC_ind_dxpl_id)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to load attribute info from object header")
- attr->shared->initialized = TRUE;
/* Finish initializing attribute */
if(H5A_open_common(&loc, attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to initialize attribute")
/* Register the attribute and get an ID for it */
- if((ret_value = H5I_register(H5I_ATTR, attr)) < 0)
+ if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
done:
@@ -621,7 +615,7 @@ H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *attr_name,
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
/* Register the attribute and get an ID for it */
- if((ret_value = H5I_register(H5I_ATTR, attr)) < 0)
+ if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
done:
@@ -692,7 +686,7 @@ H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open attribute")
/* Register the attribute and get an ID for it */
- if((ret_value = H5I_register(H5I_ATTR, attr)) < 0)
+ if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
done:
@@ -710,7 +704,7 @@ done:
*
* Purpose:
* Finishes initializing an attributes the open
- *
+ *
* Usage:
* herr_t H5A_open_common(loc, name, dxpl_id)
* const H5G_loc_t *loc; IN: Pointer to group location for object
@@ -736,7 +730,7 @@ H5A_open_common(const H5G_loc_t *loc, H5A_t *attr)
#if defined(H5_USING_MEMCHECKER) || !defined(NDEBUG)
/* Clear object location */
- if(H5O_loc_reset(&(attr->shared->oloc)) < 0)
+ if(H5O_loc_reset(&(attr->oloc)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to reset location")
#endif /* H5_USING_MEMCHECKER */
@@ -745,7 +739,7 @@ H5A_open_common(const H5G_loc_t *loc, H5A_t *attr)
HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path")
/* Deep copy of the symbol table entry */
- if(H5O_loc_copy(&(attr->shared->oloc), loc->oloc, H5_COPY_DEEP) < 0)
+ if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
/* Deep copy of the group hier. path */
@@ -753,7 +747,7 @@ H5A_open_common(const H5G_loc_t *loc, H5A_t *attr)
HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy entry")
/* Hold the symbol table entry (and file) open */
- if(H5O_open(&(attr->shared->oloc)) < 0)
+ if(H5O_open(&(attr->oloc)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open")
attr->obj_opened = TRUE;
@@ -804,7 +798,6 @@ H5A_open_by_idx(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type,
/* Read in attribute from object header */
if(NULL == (attr = H5O_attr_open_by_idx(obj_loc.oloc, idx_type, order, n, dxpl_id)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to load attribute info from object header")
- attr->shared->initialized = TRUE;
/* Finish initializing attribute */
if(H5A_open_common(&obj_loc, attr) < 0)
@@ -831,7 +824,7 @@ done:
* Function: H5A_open_by_name
*
* Purpose: Open an attribute in an object header, according to it's name
- *
+ *
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
@@ -870,7 +863,6 @@ H5A_open_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_na
/* Read in attribute from object header */
if(NULL == (attr = H5O_attr_open_by_name(obj_loc.oloc, attr_name, dxpl_id)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to load attribute info from object header")
- attr->shared->initialized = TRUE;
/* Finish initializing attribute */
if(H5A_open_common(loc, attr) < 0)
@@ -912,9 +904,9 @@ done:
herr_t
H5Awrite(hid_t attr_id, hid_t dtype_id, const void *buf)
{
- H5A_t *attr; /* Attribute object for ID */
- const H5T_t *mem_type = NULL;
- herr_t ret_value;
+ H5A_t *attr; /* Attribute object for ID */
+ H5T_t *mem_type; /* Memory datatype */
+ herr_t ret_value; /* Return value */
FUNC_ENTER_API(H5Awrite, FAIL)
H5TRACE3("e", "ii*x", attr_id, dtype_id, buf);
@@ -981,8 +973,8 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
/* If there's actually data elements for the attribute, make a copy of the data passed in */
if(nelmts > 0) {
/* Get the memory and file datatype sizes */
- src_type_size = H5T_get_size(mem_type);
- dst_type_size = H5T_get_size(attr->shared->dt);
+ src_type_size = H5T_GET_SIZE(mem_type);
+ dst_type_size = H5T_GET_SIZE(attr->shared->dt);
/* Convert memory buffer into disk buffer */
/* Set up type conversion function */
@@ -991,14 +983,16 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
/* Check for type conversion required */
if(!H5T_path_noop(tpath)) {
- if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL))) < 0 ||
- (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL))) < 0)
+ if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL), FALSE)) < 0 ||
+ (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL), FALSE)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
/* Get the maximum buffer size needed and allocate it */
buf_size = nelmts * MAX(src_type_size, dst_type_size);
- if(NULL == (tconv_buf = H5FL_BLK_MALLOC (attr_buf, buf_size)) || NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(NULL == (tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed")
+ if(NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed")
/* Copy the user's data into the buffer for conversion */
HDmemcpy(tconv_buf, buf, (src_type_size * nelmts));
@@ -1029,19 +1023,16 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
} /* end else */
/* Modify the attribute in the object header */
- if(H5O_attr_write(&(attr->shared->oloc), dxpl_id, attr) < 0)
+ if(H5O_attr_write(&(attr->oloc), dxpl_id, attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to modify attribute")
} /* end if */
- /* Indicate the the attribute doesn't need fill-values */
- attr->shared->initialized = TRUE;
-
done:
/* Release resources */
if(src_id >= 0)
- (void)H5I_dec_ref(src_id);
+ (void)H5I_dec_ref(src_id, FALSE);
if(dst_id >= 0)
- (void)H5I_dec_ref(dst_id);
+ (void)H5I_dec_ref(dst_id, FALSE);
if(tconv_buf && !tconv_owned)
tconv_buf = H5FL_BLK_FREE(attr_buf, tconv_buf);
if(bkg_buf)
@@ -1070,9 +1061,9 @@ done:
herr_t
H5Aread(hid_t attr_id, hid_t dtype_id, void *buf)
{
- H5A_t *attr; /* Attribute object for ID */
- const H5T_t *mem_type = NULL;
- herr_t ret_value;
+ H5A_t *attr; /* Attribute object for ID */
+ H5T_t *mem_type; /* Memory datatype */
+ herr_t ret_value; /* Return value */
FUNC_ENTER_API(H5Aread, FAIL)
H5TRACE3("e", "ii*x", attr_id, dtype_id, buf);
@@ -1137,11 +1128,11 @@ H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
if(nelmts > 0) {
/* Get the memory and file datatype sizes */
- src_type_size = H5T_get_size(attr->shared->dt);
- dst_type_size = H5T_get_size(mem_type);
+ src_type_size = H5T_GET_SIZE(attr->shared->dt);
+ dst_type_size = H5T_GET_SIZE(mem_type);
/* Check if the attribute has any data yet, if not, fill with zeroes */
- if(attr->obj_opened && !attr->shared->initialized)
+ if(attr->obj_opened && !attr->shared->data)
HDmemset(buf, 0, (dst_type_size * nelmts));
else { /* Attribute exists and has a value */
/* Convert memory buffer into disk buffer */
@@ -1151,14 +1142,16 @@ H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
/* Check for type conversion required */
if(!H5T_path_noop(tpath)) {
- if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL))) < 0 ||
- (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL))) < 0)
+ if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL), FALSE)) < 0 ||
+ (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL), FALSE)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
/* Get the maximum buffer size needed and allocate it */
buf_size = nelmts * MAX(src_type_size, dst_type_size);
- if(NULL == (tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size)) || NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(NULL == (tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size)))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size)))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Copy the attribute data into the buffer for conversion */
HDmemcpy(tconv_buf, attr->shared->data, (src_type_size * nelmts));
@@ -1183,9 +1176,9 @@ H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
done:
/* Release resources */
if(src_id >= 0)
- (void)H5I_dec_ref(src_id);
+ (void)H5I_dec_ref(src_id, FALSE);
if(dst_id >= 0)
- (void)H5I_dec_ref(dst_id);
+ (void)H5I_dec_ref(dst_id, FALSE);
if(tconv_buf)
tconv_buf = H5FL_BLK_FREE(attr_buf, tconv_buf);
if(bkg_buf)
@@ -1230,7 +1223,7 @@ H5Aget_space(hid_t attr_id)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy dataspace")
/* Atomize */
- if((ret_value = H5I_register(H5I_DATASPACE, ds)) < 0)
+ if((ret_value = H5I_register(H5I_DATASPACE, ds, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom")
done:
@@ -1262,7 +1255,7 @@ H5Aget_type(hid_t attr_id)
{
H5A_t *attr; /* Attribute object for ID */
H5T_t *dt = NULL; /* Copy of attribute's datatype */
- hid_t ret_value;
+ hid_t ret_value; /* Return value */
FUNC_ENTER_API(H5Aget_type, FAIL)
H5TRACE1("i", "i", attr_id);
@@ -1288,12 +1281,14 @@ H5Aget_type(hid_t attr_id)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient datatype")
/* Atomize */
- if((ret_value = H5I_register(H5I_DATATYPE, dt)) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype atom")
+ if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype ID")
done:
- if(ret_value < 0 && dt)
- (void)H5T_close(dt);
+ if(ret_value < 0) {
+ if(dt && H5T_close(dt) < 0)
+ HDONE_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to release datatype")
+ } /* end if */
FUNC_LEAVE_API(ret_value)
} /* H5Aget_type() */
@@ -1339,7 +1334,7 @@ H5Aget_create_plist(hid_t attr_id)
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get default ACPL")
/* Create the property list object to return */
- if((new_plist_id = H5P_copy_plist(plist)) < 0)
+ if((new_plist_id = H5P_copy_plist(plist, TRUE)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy attribute creation properties")
if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_plist_id)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get property list")
@@ -1404,7 +1399,7 @@ done:
NAME
H5A_get_name
PURPOSE
- Private function for H5Aget_name. Gets a copy of the name for an
+ Private function for H5Aget_name. Gets a copy of the name for an
attribute
RETURNS
This function returns the length of the attribute's name (which may be
@@ -2033,7 +2028,7 @@ H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
loc_found = TRUE;
/* Open the object */
- if((obj_loc_id = H5O_open_by_loc(&obj_loc, H5AC_ind_dxpl_id)) < 0)
+ if((obj_loc_id = H5O_open_by_loc(&obj_loc, lapl_id, H5AC_ind_dxpl_id, TRUE)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open object")
/* Build attribute operator info */
@@ -2052,7 +2047,7 @@ H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
done:
/* Release resources */
if(obj_loc_id > 0) {
- if(H5I_dec_ref(obj_loc_id) < 0)
+ if(H5I_dec_ref(obj_loc_id, TRUE) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "unable to close temporary object")
} /* end if */
else if(loc_found && H5G_loc_free(&obj_loc) < 0)
@@ -2276,7 +2271,7 @@ H5Aclose(hid_t attr_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
/* Decrement references to that atom (and close it) */
- if(H5I_dec_ref(attr_id) < 0)
+ if(H5I_dec_ref(attr_id, TRUE) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "can't close attribute")
done:
@@ -2390,7 +2385,7 @@ H5A_free(H5A_t *attr)
HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release dataspace info")
attr->shared->ds = NULL;
}
- if(attr->shared->data)
+ if(attr->shared->data)
attr->shared->data = H5FL_BLK_FREE(attr_buf, attr->shared->data);
done:
@@ -2425,10 +2420,10 @@ H5A_close(H5A_t *attr)
HDassert(attr->shared);
/* Close the object's symbol-table entry */
- if(attr->obj_opened && (H5O_close(&(attr->shared->oloc)) < 0))
+ if(attr->obj_opened && (H5O_close(&(attr->oloc)) < 0))
HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release object header info")
- /* Reference count can be 0. It only happens when H5A_create fails. */
+ /* Reference count can be 0. It only happens when H5A_create fails. */
if(1 >= attr->shared->nrefs) {
/* Free dynamicly allocated items */
if(H5A_free(attr) < 0)
@@ -2447,7 +2442,7 @@ H5A_close(H5A_t *attr)
HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path")
attr->shared = NULL;
- H5FL_FREE(H5A_t, attr);
+ (void)H5FL_FREE(H5A_t, attr);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -2479,7 +2474,7 @@ H5A_oloc(H5A_t *attr)
HDassert(attr);
/* Set return value */
- ret_value = &(attr->shared->oloc);
+ ret_value = &(attr->oloc);
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5AC.c b/src/H5AC.c
index fc4ea4d..cbe4dd0 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -193,6 +193,8 @@ static herr_t H5AC_receive_and_apply_clean_list(H5F_t * f,
static herr_t H5AC_log_renamed_entry(H5AC_t * cache_ptr,
haddr_t old_addr,
haddr_t new_addr);
+
+static herr_t H5AC_flush_entries(H5F_t *f);
#endif /* H5_HAVE_PARALLEL */
@@ -260,7 +262,7 @@ H5AC_init_interface(void)
HGOTO_ERROR(H5E_CACHE, H5E_BADATOM, FAIL, "can't get property list class")
/* Get an ID for the blocking, collective H5AC dxpl */
- if ((H5AC_dxpl_id=H5P_create_id(xfer_pclass)) < 0)
+ if ((H5AC_dxpl_id=H5P_create_id(xfer_pclass,FALSE)) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "unable to register property list")
/* Get the property list object */
@@ -282,7 +284,7 @@ H5AC_init_interface(void)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value")
/* Get an ID for the non-blocking, collective H5AC dxpl */
- if ((H5AC_noblock_dxpl_id=H5P_create_id(xfer_pclass)) < 0)
+ if ((H5AC_noblock_dxpl_id=H5P_create_id(xfer_pclass,FALSE)) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "unable to register property list")
/* Get the property list object */
@@ -304,7 +306,7 @@ H5AC_init_interface(void)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value")
/* Get an ID for the non-blocking, independent H5AC dxpl */
- if ((H5AC_ind_dxpl_id=H5P_create_id(xfer_pclass)) < 0)
+ if ((H5AC_ind_dxpl_id=H5P_create_id(xfer_pclass,FALSE)) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "unable to register property list")
/* Get the property list object */
@@ -374,9 +376,9 @@ H5AC_term_interface(void)
n = 1; /* H5I */
/* Close H5AC dxpl */
- if (H5I_dec_ref(H5AC_dxpl_id) < 0 ||
- H5I_dec_ref(H5AC_noblock_dxpl_id) < 0 ||
- H5I_dec_ref(H5AC_ind_dxpl_id) < 0)
+ if (H5I_dec_ref(H5AC_dxpl_id, FALSE) < 0 ||
+ H5I_dec_ref(H5AC_noblock_dxpl_id, FALSE) < 0 ||
+ H5I_dec_ref(H5AC_ind_dxpl_id, FALSE) < 0)
H5E_clear_stack(NULL); /*ignore error*/
else {
/* Reset static IDs */
@@ -491,6 +493,15 @@ static const char * H5AC_entry_type_names[H5AC_NTYPES] =
"free space sections",
"shared OH message master table",
"shared OH message index",
+ "extensible array headers",
+ "extensible array index blocks",
+ "extensible array super blocks",
+ "extensible array data blocks",
+ "extensible array data block pages",
+ "fixed array headers",
+ "fixed array data block",
+ "fixed array data block pages",
+ "superblock",
"test entry" /* for testing only -- not used for actual files */
};
@@ -584,7 +595,7 @@ H5AC_create(const H5F_t *f,
if ( mpi_rank == 0 ) {
aux_ptr->d_slist_ptr =
- H5SL_create(H5SL_TYPE_HADDR,0.5,(size_t)16);
+ H5SL_create(H5SL_TYPE_HADDR);
if ( aux_ptr->d_slist_ptr == NULL ) {
@@ -593,7 +604,7 @@ H5AC_create(const H5F_t *f,
}
aux_ptr->c_slist_ptr =
- H5SL_create(H5SL_TYPE_HADDR,0.5,(size_t)16);
+ H5SL_create(H5SL_TYPE_HADDR);
if ( aux_ptr->c_slist_ptr == NULL ) {
@@ -746,9 +757,9 @@ done:
* Added code to free the auxiliary structure and its
* associated slist if present.
* JRM - 6/28/05
- *
+ *
* Added code to close the trace file if it is present.
- *
+ *
* JRM - 6/8/06
*
*-------------------------------------------------------------------------
@@ -756,64 +767,52 @@ done:
herr_t
H5AC_dest(H5F_t *f, hid_t dxpl_id)
{
- H5AC_t *cache = NULL;
- herr_t ret_value=SUCCEED; /* Return value */
#ifdef H5_HAVE_PARALLEL
H5AC_aux_t * aux_ptr = NULL;
#endif /* H5_HAVE_PARALLEL */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5AC_dest, FAIL)
- assert(f);
- assert(f->shared->cache);
- cache = f->shared->cache;
-#ifdef H5_HAVE_PARALLEL
- aux_ptr = cache->aux_ptr;
-
- if ( aux_ptr != NULL ) {
-
- HDassert ( aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC );
- }
-#endif /* H5_HAVE_PARALLEL */
+ /* Sanity check */
+ HDassert(f);
+ HDassert(f->shared->cache);
#if H5AC__TRACE_FILE_ENABLED
- if ( H5AC_close_trace_file(cache) < 0 ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "H5AC_close_trace_file() failed.")
- }
+ if(H5AC_close_trace_file(f->shared->cache) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_close_trace_file() failed.")
#endif /* H5AC__TRACE_FILE_ENABLED */
- if ( H5C_dest(f, dxpl_id, H5AC_noblock_dxpl_id, cache) < 0 ) {
+#ifdef H5_HAVE_PARALLEL
+ aux_ptr = f->shared->cache->aux_ptr;
+ if(aux_ptr)
+ /* Sanity check */
+ HDassert(aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC);
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "can't destroy cache")
- }
+ /* Attempt to flush all entries from rank 0 & Bcast clean list to other ranks */
+ if(H5AC_flush_entries(f) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush.")
+#endif /* H5_HAVE_PARALLEL */
+ /* Destroy the cache */
+ if(H5C_dest(f, dxpl_id, H5AC_noblock_dxpl_id, f->shared->cache) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "can't destroy cache")
f->shared->cache = NULL;
#ifdef H5_HAVE_PARALLEL
- if ( aux_ptr != NULL ) {
-
- if ( aux_ptr->d_slist_ptr != NULL ) {
-
+ if(aux_ptr != NULL) {
+ if(aux_ptr->d_slist_ptr != NULL)
H5SL_close(aux_ptr->d_slist_ptr);
- }
-
- if ( aux_ptr->c_slist_ptr != NULL ) {
-
+ if(aux_ptr->c_slist_ptr != NULL)
H5SL_close(aux_ptr->c_slist_ptr);
- }
-
aux_ptr->magic = 0;
H5FL_FREE(H5AC_aux_t, aux_ptr);
aux_ptr = NULL;
- }
+ } /* end if */
#endif /* H5_HAVE_PARALLEL */
done:
-
FUNC_LEAVE_NOAPI(ret_value)
-
} /* H5AC_dest() */
@@ -830,24 +829,27 @@ done:
* 6/30/06
*
* Modifications:
- *
- * None.
+ *
+ * Added 'flags' paramater, to allow freeing file space
+ *
+ * QAK - 2/5/08
*
*-------------------------------------------------------------------------
*/
herr_t
-H5AC_expunge_entry(H5F_t *f,
- hid_t dxpl_id,
- const H5AC_class_t *type,
- haddr_t addr)
+H5AC_expunge_entry(H5F_t *f,
+ hid_t dxpl_id,
+ const H5AC_class_t *type,
+ haddr_t addr,
+ unsigned flags)
{
herr_t result;
- herr_t ret_value=SUCCEED; /* Return value */
H5AC_t * cache_ptr = NULL;
#if H5AC__TRACE_FILE_ENABLED
char trace[128] = "";
FILE * trace_file_ptr = NULL;
#endif /* H5AC__TRACE_FILE_ENABLED */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5AC_expunge_entry, FAIL)
@@ -862,8 +864,8 @@ H5AC_expunge_entry(H5F_t *f,
cache_ptr = f->shared->cache;
#if H5AC__TRACE_FILE_ENABLED
- /* For the expunge entry call, only the addr, and type id are really
- * necessary in the trace file. Write the return value to catch occult
+ /* For the expunge entry call, only the addr, and type id are really
+ * necessary in the trace file. Write the return value to catch occult
* errors.
*/
if ( ( cache_ptr != NULL ) &&
@@ -881,7 +883,8 @@ H5AC_expunge_entry(H5F_t *f,
H5AC_noblock_dxpl_id,
cache_ptr,
type,
- addr);
+ addr,
+ flags);
if ( result < 0 ) {
@@ -909,43 +912,11 @@ done:
* Purpose: Flush (and possibly destroy) the metadata cache associated
* with the specified file.
*
- * This is a re-write of an earlier version of the function
- * which was reputedly capable of flushing (and destroying
- * if requested) individual entries, individual entries if
- * they match the supplied type, all entries of a given type,
- * as well as all entries in the cache.
- *
- * As only this last capability is actually used at present,
- * I have not implemented the other capabilities in this
- * version of the function.
- *
- * The type and addr parameters are retained to avoid source
- * code changed, but values other than NULL and HADDR_UNDEF
- * respectively are errors. If all goes well, they should
- * be removed, and the function renamed to something more
- * descriptive -- perhaps H5AC_flush_cache.
- *
* If the cache contains protected entries, the function will
* fail, as protected entries cannot be flushed. However
* all unprotected entries should be flushed before the
* function returns failure.
*
- * For historical purposes, the original version of the
- * purpose section is reproduced below:
- *
- * ============ Original Version of "Purpose:" ============
- *
- * Flushes (and destroys if DESTROY is non-zero) the specified
- * entry from the cache. If the entry TYPE is CACHE_FREE and
- * ADDR is HADDR_UNDEF then all types of entries are
- * flushed. If TYPE is CACHE_FREE and ADDR is defined then
- * whatever is cached at ADDR is flushed. Otherwise the thing
- * at ADDR is flushed if it is the correct type.
- *
- * If there are protected objects they will not be flushed.
- * However, an attempt will be made to flush all non-protected
- * items before this function returns failure.
- *
* Return: Non-negative on success/Negative on failure if there was a
* request to flush all items and something was protected.
*
@@ -953,45 +924,16 @@ done:
* matzke@llnl.gov
* Jul 9 1997
*
- * Modifications:
- * Robb Matzke, 1999-07-27
- * The ADDR argument is passed by value.
- *
- * Complete re-write. See above for details. -- JRM 5/11/04
- *
- * Abstracted the guts of the function to H5C_flush_cache()
- * in H5C.c, and then re-wrote the function as a wrapper for
- * H5C_flush_cache().
- *
- * JRM - 6/7/04
- *
- * JRM - 7/5/05
- * Modified function as part of a fix for a cache coherency
- * bug in PHDF5. See the header comments on the H5AC_aux_t
- * structure for details.
- *
- * JRM -- 5/11/06
- * Added call to the write_done callback.
- *
- * JRM -- 6/6/06
- * Added trace file support.
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5AC_flush(H5F_t *f, hid_t dxpl_id, unsigned flags)
+H5AC_flush(H5F_t *f, hid_t dxpl_id)
{
- herr_t status;
- herr_t ret_value = SUCCEED; /* Return value */
-#ifdef H5_HAVE_PARALLEL
- H5AC_aux_t * aux_ptr = NULL;
- int mpi_code;
-#endif /* H5_HAVE_PARALLEL */
#if H5AC__TRACE_FILE_ENABLED
char trace[128] = "";
FILE * trace_file_ptr = NULL;
#endif /* H5AC__TRACE_FILE_ENABLED */
-
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5AC_flush, FAIL)
@@ -1002,108 +944,31 @@ H5AC_flush(H5F_t *f, hid_t dxpl_id, unsigned flags)
/* For the flush, only the flags are really necessary in the trace file.
* Write the result to catch occult errors.
*/
- if ( ( f != NULL ) &&
- ( f->shared != NULL ) &&
- ( f->shared->cache != NULL ) &&
- ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) &&
- ( trace_file_ptr != NULL ) ) {
-
- sprintf(trace, "H5AC_flush 0x%x", flags);
- }
+ if((f != NULL) &&
+ (f->shared != NULL) &&
+ (f->shared->cache != NULL) &&
+ (H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0) &&
+ (trace_file_ptr != NULL))
+ sprintf(trace, "H5AC_flush");
#endif /* H5AC__TRACE_FILE_ENABLED */
#ifdef H5_HAVE_PARALLEL
- aux_ptr = f->shared->cache->aux_ptr;
-
- if ( aux_ptr != NULL ) {
-
-#if H5AC_DEBUG_DIRTY_BYTES_CREATION
- HDfprintf(stdout,
- "%d::H5AC_flush: (u/uu/i/iu/r/ru) = %d/%d/%d/%d/%d/%d\n",
- (int)(aux_ptr->mpi_rank),
- (int)(aux_ptr->unprotect_dirty_bytes),
- (int)(aux_ptr->unprotect_dirty_bytes_updates),
- (int)(aux_ptr->insert_dirty_bytes),
- (int)(aux_ptr->insert_dirty_bytes_updates),
- (int)(aux_ptr->rename_dirty_bytes),
- (int)(aux_ptr->rename_dirty_bytes_updates));
-#endif /* H5AC_DEBUG_DIRTY_BYTES_CREATION */
-
- /* to prevent "messages from the future" we must synchronize all
- * processes before we start the flush. Hence the following
- * barrier.
- */
- if ( MPI_SUCCESS != (mpi_code = MPI_Barrier(aux_ptr->mpi_comm)) ) {
-
- HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code)
- }
-
- /* if the clear only flag is set, this flush will not involve any
- * disk I/O. In such cases, it is not necessary to let process 0
- * flush first.
- */
- if ( ( aux_ptr->mpi_rank == 0 ) &&
- ( (flags & H5AC__FLUSH_CLEAR_ONLY_FLAG) == 0 ) ) {
-
- unsigned init_flush_flags = H5AC__NO_FLAGS_SET;
-
- if ( ( (flags & H5AC__FLUSH_MARKED_ENTRIES_FLAG) != 0 ) &&
- ( (flags & H5AC__FLUSH_INVALIDATE_FLAG) == 0 ) ) {
-
- init_flush_flags |= H5AC__FLUSH_MARKED_ENTRIES_FLAG;
- }
-
- aux_ptr->write_permitted = TRUE;
-
- status = H5C_flush_cache(f,
- H5AC_noblock_dxpl_id,
- H5AC_noblock_dxpl_id,
- f->shared->cache,
- init_flush_flags);
-
- aux_ptr->write_permitted = FALSE;
-
- if ( status < 0 ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush.")
- }
-
- if ( aux_ptr->write_done != NULL ) {
-
- (aux_ptr->write_done)();
- }
-
- } /* end if ( aux_ptr->mpi_rank == 0 ) */
-
- status = H5AC_propagate_flushed_and_still_clean_entries_list(f,
- H5AC_noblock_dxpl_id,
- f->shared->cache,
- FALSE);
- } /* end if ( aux_ptr != NULL ) */
+ /* Attempt to flush all entries from rank 0 & Bcast clean list to other ranks */
+ if(H5AC_flush_entries(f) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush.")
#endif /* H5_HAVE_PARALLEL */
- status = H5C_flush_cache(f,
- dxpl_id,
- H5AC_noblock_dxpl_id,
- f->shared->cache,
- flags);
-
- if ( status < 0 ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush entry.")
- }
+ /* Flush the cache */
+ if(H5C_flush_cache(f, dxpl_id, H5AC_noblock_dxpl_id, f->shared->cache, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush cache.")
done:
-
#if H5AC__TRACE_FILE_ENABLED
- if ( trace_file_ptr != NULL ) {
-
+ if(trace_file_ptr != NULL)
HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value);
- }
#endif /* H5AC__TRACE_FILE_ENABLED */
FUNC_LEAVE_NOAPI(ret_value)
-
} /* H5AC_flush() */
@@ -1145,6 +1010,8 @@ H5AC_get_entry_status(H5F_t * f,
hbool_t is_dirty;
hbool_t is_protected;
hbool_t is_pinned;
+ hbool_t is_flush_dep_child;
+ hbool_t is_flush_dep_parent;
size_t entry_size;
unsigned status = 0;
@@ -1159,7 +1026,8 @@ H5AC_get_entry_status(H5F_t * f,
}
result = H5C_get_entry_status(cache_ptr, addr, &entry_size, &in_cache,
- &is_dirty, &is_protected, &is_pinned);
+ &is_dirty, &is_protected, &is_pinned, &is_flush_dep_parent,
+ &is_flush_dep_child);
if ( result < 0 ) {
@@ -1179,6 +1047,12 @@ H5AC_get_entry_status(H5F_t * f,
if ( is_pinned )
status |= H5AC_ES__IS_PINNED;
+
+ if ( is_flush_dep_parent )
+ status |= H5AC_ES__IS_FLUSH_DEP_PARENT;
+
+ if ( is_flush_dep_child )
+ status |= H5AC_ES__IS_FLUSH_DEP_CHILD;
}
*status_ptr = status;
@@ -1255,12 +1129,12 @@ done:
*/
herr_t
-H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void *thing, unsigned int flags)
+H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr,
+ void *thing, unsigned int flags)
{
herr_t result;
H5AC_info_t *info;
H5AC_t *cache;
- herr_t ret_value=SUCCEED; /* Return value */
#ifdef H5_HAVE_PARALLEL
H5AC_aux_t * aux_ptr = NULL;
#endif /* H5_HAVE_PARALLEL */
@@ -1269,6 +1143,7 @@ H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void *
size_t trace_entry_size = 0;
FILE * trace_file_ptr = NULL;
#endif /* H5AC__TRACE_FILE_ENABLED */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5AC_set, FAIL)
@@ -1280,9 +1155,13 @@ H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void *
HDassert(H5F_addr_defined(addr));
HDassert(thing);
+ /* Check for invalid access request */
+ if(0 == (f->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "no write intent on file")
+
#if H5AC__TRACE_FILE_ENABLED
- /* For the insert, only the addr, size, type id and flags are really
- * necessary in the trace file. Write the result to catch occult
+ /* For the insert, only the addr, size, type id and flags are really
+ * necessary in the trace file. Write the result to catch occult
* errors.
*
* Note that some data is not available right now -- put what we can
@@ -1369,8 +1248,8 @@ done:
#if H5AC__TRACE_FILE_ENABLED
if ( trace_file_ptr != NULL ) {
- HDfprintf(trace_file_ptr, "%s %d %d\n", trace,
- (int)trace_entry_size,
+ HDfprintf(trace_file_ptr, "%s %d %d\n", trace,
+ (int)trace_entry_size,
(int)ret_value);
}
#endif /* H5AC__TRACE_FILE_ENABLED */
@@ -1417,8 +1296,8 @@ H5AC_mark_pinned_entry_dirty(H5F_t * f,
FUNC_ENTER_NOAPI(H5AC_mark_pinned_entry_dirty, FAIL)
#if H5AC__TRACE_FILE_ENABLED
- /* For the mark pinned entry dirty call, only the addr, size_changed,
- * and new_size are really necessary in the trace file. Write the result
+ /* For the mark pinned entry dirty call, only the addr, size_changed,
+ * and new_size are really necessary in the trace file. Write the result
* to catch occult errors.
*/
if ( ( f != NULL ) &&
@@ -1539,7 +1418,7 @@ H5AC_mark_pinned_or_protected_entry_dirty(H5F_t * f,
#if H5AC__TRACE_FILE_ENABLED
/* For the mark pinned or protected entry dirty call, only the addr
- * is really necessary in the trace file. Write the result to catch
+ * is really necessary in the trace file. Write the result to catch
* occult errors.
*/
if ( ( f != NULL ) &&
@@ -1600,7 +1479,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5AC_mark_pinned_entry_dirty() */
+} /* H5AC_mark_pinned_or_protected_entry_dirty() */
/*-------------------------------------------------------------------------
@@ -1671,7 +1550,7 @@ H5AC_rename(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr, haddr_t new_ad
HDassert(H5F_addr_ne(old_addr, new_addr));
#if H5AC__TRACE_FILE_ENABLED
- /* For the rename call, only the old addr and new addr are really
+ /* For the rename call, only the old addr and new addr are really
* necessary in the trace file. Include the type id so we don't have to
* look it up. Also write the result to catch occult errors.
*/
@@ -1776,7 +1655,7 @@ H5AC_pin_protected_entry(H5F_t * f,
FUNC_ENTER_NOAPI(H5AC_pin_protected_entry, FAIL)
#if H5AC__TRACE_FILE_ENABLED
- /* For the pin protected entry call, only the addr is really necessary
+ /* For the pin protected entry call, only the addr is really necessary
* in the trace file. Also write the result to catch occult errors.
*/
if ( ( f != NULL ) &&
@@ -1813,6 +1692,59 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5AC_create_flush_dependency()
+ *
+ * Purpose: Create a flush dependency between two entries in the metadata
+ * cache.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * 3/24/09
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5AC_create_flush_dependency(H5F_t * f, void * parent_thing, void * child_thing)
+{
+ H5C_t *cache_ptr = f->shared->cache;
+#if H5AC__TRACE_FILE_ENABLED
+ char trace[128] = "";
+ FILE * trace_file_ptr = NULL;
+#endif /* H5AC__TRACE_FILE_ENABLED */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5AC_create_flush_dependency, FAIL)
+
+ /* Sanity check */
+ HDassert(cache_ptr);
+ HDassert(parent_thing);
+ HDassert(child_thing);
+
+#if H5AC__TRACE_FILE_ENABLED
+ if ( ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) &&
+ ( trace_file_ptr != NULL ) ) {
+ sprintf(trace, "%s %lx %lx",
+ FUNC,
+ (unsigned long)(((H5C_cache_entry_t *)parent_thing)->addr),
+ (unsigned long)(((H5C_cache_entry_t *)child_thing)->addr));
+ } /* end if */
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
+ if(H5C_create_flush_dependency(cache_ptr, parent_thing, child_thing) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "H5C_create_flush_dependency() failed.")
+
+done:
+#if H5AC__TRACE_FILE_ENABLED
+ if(trace_file_ptr != NULL)
+ HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value);
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5AC_create_flush_dependency() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5AC_protect
*
* Purpose: If the target entry is not in the cache, load it. If
@@ -1873,11 +1805,11 @@ done:
* Added trace file support.
*
* JRM - 3/18/07
- * Modified code to support the new flags parameter for
- * H5C_protect(). For now, that means passing in the
+ * Modified code to support the new flags parameter for
+ * H5C_protect(). For now, that means passing in the
* H5C_READ_ONLY_FLAG if rw == H5AC_READ.
*
- * Also updated the trace file output to save the
+ * Also updated the trace file output to save the
* rw parameter, since we are now doing something with it.
*
*-------------------------------------------------------------------------
@@ -1917,9 +1849,9 @@ H5AC_protect(H5F_t *f,
HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "no write intent on file")
#if H5AC__TRACE_FILE_ENABLED
- /* For the protect call, only the addr and type id is really necessary
- * in the trace file. Include the size of the entry protected as a
- * sanity check. Also indicate whether the call was successful to
+ /* For the protect call, only the addr and type id is really necessary
+ * in the trace file. Include the size of the entry protected as a
+ * sanity check. Also indicate whether the call was successful to
* catch occult errors.
*/
if ( ( f != NULL ) &&
@@ -1986,7 +1918,7 @@ done:
#if H5AC__TRACE_FILE_ENABLED
if ( trace_file_ptr != NULL ) {
- HDfprintf(trace_file_ptr, "%s %d %d\n", trace,
+ HDfprintf(trace_file_ptr, "%s %d %d\n", trace,
(int)trace_entry_size,
(int)(ret_value != NULL));
}
@@ -2030,8 +1962,8 @@ H5AC_resize_pinned_entry(H5F_t * f,
FUNC_ENTER_NOAPI(H5AC_resize_pinned_entry, FAIL)
#if H5AC__TRACE_FILE_ENABLED
- /* For the resize pinned entry call, only the addr, and new_size are
- * really necessary in the trace file. Write the result to catch
+ /* For the resize pinned entry call, only the addr, and new_size are
+ * really necessary in the trace file. Write the result to catch
* occult errors.
*/
if ( ( f != NULL ) &&
@@ -2141,7 +2073,7 @@ H5AC_unpin_entry(H5F_t * f,
FUNC_ENTER_NOAPI(H5AC_unpin_entry, FAIL)
#if H5AC__TRACE_FILE_ENABLED
- /* For the unpin entry call, only the addr is really necessary
+ /* For the unpin entry call, only the addr is really necessary
* in the trace file. Also write the result to catch occult errors.
*/
if ( ( f != NULL ) &&
@@ -2177,6 +2109,58 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5AC_destroy_flush_dependency()
+ *
+ * Purpose: Destroy a flush dependency between two entries.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * 3/24/09
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5AC_destroy_flush_dependency(H5F_t * f, void * parent_thing, void * child_thing)
+{
+ H5C_t *cache_ptr = f->shared->cache;
+#if H5AC__TRACE_FILE_ENABLED
+ char trace[128] = "";
+ FILE * trace_file_ptr = NULL;
+#endif /* H5AC__TRACE_FILE_ENABLED */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5AC_destroy_flush_dependency, FAIL)
+
+ /* Sanity check */
+ HDassert(cache_ptr);
+ HDassert(parent_thing);
+ HDassert(child_thing);
+
+#if H5AC__TRACE_FILE_ENABLED
+ if ( ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) &&
+ ( trace_file_ptr != NULL ) ) {
+ sprintf(trace, "%s %lx",
+ FUNC,
+ (unsigned long)(((H5C_cache_entry_t *)parent_thing)->addr),
+ (unsigned long)(((H5C_cache_entry_t *)child_thing)->addr));
+ } /* end if */
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
+ if(H5C_destroy_flush_dependency(cache_ptr, parent_thing, child_thing) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL, "H5C_destroy_flush_dependency() failed.")
+
+done:
+#if H5AC__TRACE_FILE_ENABLED
+ if( trace_file_ptr != NULL )
+ HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value);
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5AC_destroy_flush_dependency() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5AC_unprotect
*
* Purpose: Undo an H5AC_protect() call -- specifically, mark the
@@ -2275,10 +2259,10 @@ H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr,
{
herr_t result;
herr_t ret_value=SUCCEED; /* Return value */
- hbool_t size_changed = FALSE;
hbool_t dirtied;
size_t new_size = 0;
#ifdef H5_HAVE_PARALLEL
+ hbool_t size_changed = FALSE;
H5AC_aux_t * aux_ptr = NULL;
#endif /* H5_HAVE_PARALLEL */
#if H5AC__TRACE_FILE_ENABLED
@@ -2302,7 +2286,7 @@ H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr,
#if H5AC__TRACE_FILE_ENABLED
/* For the unprotect call, only the addr, type id, flags, and possible
- * new size are really necessary in the trace file. Write the return
+ * new size are really necessary in the trace file. Write the return
* value to catch occult errors.
*/
if ( ( f != NULL ) &&
@@ -2332,7 +2316,9 @@ H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr,
if ( ((H5AC_info_t *)thing)->size != new_size ) {
+#ifdef H5_HAVE_PARALLEL
size_changed = TRUE;
+#endif /* H5_HAVE_PARALLEL */
flags = flags | H5AC__SIZE_CHANGED_FLAG;
#if H5AC__TRACE_FILE_ENABLED
trace_flags = flags;
@@ -2413,8 +2399,8 @@ done:
#if H5AC__TRACE_FILE_ENABLED
if ( trace_file_ptr != NULL ) {
- HDfprintf(trace_file_ptr, "%s %d %x %d\n",
- trace,
+ HDfprintf(trace_file_ptr, "%s %d %x %d\n",
+ trace,
(int)trace_new_size,
(unsigned)trace_flags,
(int)ret_value);
@@ -2507,7 +2493,7 @@ H5AC_stats(const H5F_t *f)
HDassert(f->shared->cache);
/* at present, this can't fail */
- (void)H5C_stats(f->shared->cache, f->name, FALSE);
+ (void)H5C_stats(f->shared->cache, H5F_OPEN_NAME(f), FALSE);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -2539,11 +2525,11 @@ done:
*
* JRM - 7/28/07
* Added support for the new evictions enabled related fields.
- *
- * Observe that H5AC_get_cache_auto_resize_config() and
+ *
+ * Observe that H5AC_get_cache_auto_resize_config() and
* H5AC_set_cache_auto_resize_config() are becoming generic
- * metadata cache configuration routines as they gain
- * switches for functions that are only tenuously related
+ * metadata cache configuration routines as they gain
+ * switches for functions that are only tenuously related
* to auto resize configuration.
*
* JRM - 1/2/08
@@ -2808,7 +2794,7 @@ done:
* Updated for the addition of H5AC_cache_config_t.
*
* John Mainzer -- 10/25/05
- * Added support for the new dirty_bytes_threshold field of
+ * Added support for the new dirty_bytes_threshold field of
* both H5AC_cache_config_t and H5AC_aux_t.
*
* John Mainzer -- 6/7/06
@@ -2816,15 +2802,15 @@ done:
*
* John Mainzer -- 7/28/07
* Added support for the new evictions enabled related fields.
- *
- * Observe that H5AC_get_cache_auto_resize_config() and
+ *
+ * Observe that H5AC_get_cache_auto_resize_config() and
* H5AC_set_cache_auto_resize_config() are becoming generic
- * metadata cache configuration routines as they gain
- * switches for functions that are only tenuously related
+ * metadata cache configuration routines as they gain
+ * switches for functions that are only tenuously related
* to auto resize configuration.
*
* John Mainzer -- 1/3/07
- * Updated trace file code to record the new flash cache
+ * Updated trace file code to record the new flash cache
* size increase related fields.
*
*-------------------------------------------------------------------------
@@ -2971,16 +2957,16 @@ H5AC_set_cache_auto_resize_config(H5AC_t * cache_ptr,
done:
#if H5AC__TRACE_FILE_ENABLED
- /* For the set cache auto resize config call, only the contents
- * of the config is necessary in the trace file. Write the return
+ /* For the set cache auto resize config call, only the contents
+ * of the config is necessary in the trace file. Write the return
* value to catch occult errors.
*/
if ( ( cache_ptr != NULL ) &&
( H5C_get_trace_file_ptr(cache_ptr, &trace_file_ptr) >= 0 ) &&
( trace_file_ptr != NULL ) ) {
- HDfprintf(trace_file_ptr,
- "%s %d %d %d %d \"%s\" %d %d %d %f %d %d %ld %d %f %f %d %f %f %d %d %d %f %f %d %d %d %d %f %d %d\n",
+ HDfprintf(trace_file_ptr,
+ "%s %d %d %d %d \"%s\" %d %d %d %f %d %d %ld %d %f %f %d %f %f %d %d %d %f %f %d %d %d %d %f %d %d\n",
"H5AC_set_cache_auto_resize_config",
trace_config.version,
(int)(trace_config.rpt_fcn_enabled),
@@ -3048,9 +3034,9 @@ done:
* are applied.
* JRM - 5/15/06
*
- * - Added code testing the evictions enabled field. At
- * present this consists of verifying that if
- * evictions_enabled is FALSE, then automatic cache
+ * - Added code testing the evictions enabled field. At
+ * present this consists of verifying that if
+ * evictions_enabled is FALSE, then automatic cache
* resizing in disabled.
*
* JRM - 7/28/07
@@ -3103,7 +3089,7 @@ H5AC_validate_config(H5AC_cache_config_t * config_ptr)
/* don't bother to test trace_file_name unless open_trace_file is TRUE */
if ( config_ptr->open_trace_file ) {
- /* Can't really test the trace_file_name field without trying to
+ /* Can't really test the trace_file_name field without trying to
* open the file, so we will content ourselves with a couple of
* sanity checks on the length of the file name.
*/
@@ -3129,7 +3115,7 @@ H5AC_validate_config(H5AC_cache_config_t * config_ptr)
}
if ( ( config_ptr->evictions_enabled == FALSE ) &&
- ( ( config_ptr->incr_mode != H5C_incr__off ) ||
+ ( ( config_ptr->incr_mode != H5C_incr__off ) ||
( config_ptr->flash_incr_mode != H5C_flash_incr__off ) ||
( config_ptr->decr_mode != H5C_decr__off ) ) ) {
@@ -3651,7 +3637,8 @@ H5AC_ext_config_2_int_config(H5AC_cache_config_t * ext_conf_ptr,
if ( ( ext_conf_ptr == NULL ) ||
( ext_conf_ptr->version != H5AC__CURR_CACHE_CONFIG_VERSION ) ||
( int_conf_ptr == NULL ) ) {
-
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "Bad ext_conf_ptr or inf_conf_ptr on entry.")
}
int_conf_ptr->version = H5C__CURR_AUTO_SIZE_CTL_VER;
@@ -4301,7 +4288,7 @@ H5AC_log_renamed_entry(H5AC_t * cache_ptr,
/* get entry status, size, etc here */
if ( H5C_get_entry_status(cache_ptr, old_addr, &entry_size, &entry_in_cache,
- &entry_dirty, NULL, NULL) < 0 ) {
+ &entry_dirty, NULL, NULL, NULL, NULL) < 0 ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't get entry status.")
@@ -4751,5 +4738,89 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_receive_and_apply_clean_list() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5AC_flush_entries
+ *
+ * Purpose: Flush the metadata cache associated with the specified file,
+ * only writing from rank 0, but propagating the cleaned entries
+ * to all ranks.
+ *
+ * Return: Non-negative on success/Negative on failure if there was a
+ * request to flush all items and something was protected.
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 22 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5AC_flush_entries(H5F_t *f)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5AC_flush_entries)
+
+ HDassert(f);
+ HDassert(f->shared->cache);
+
+ /* Check if we have >1 ranks */
+ if(f->shared->cache->aux_ptr) {
+ H5AC_aux_t * aux_ptr = f->shared->cache->aux_ptr;
+ int mpi_code;
+
+#if H5AC_DEBUG_DIRTY_BYTES_CREATION
+ HDfprintf(stdout,
+ "%d::H5AC_flush: (u/uu/i/iu/r/ru) = %d/%d/%d/%d/%d/%d\n",
+ (int)(aux_ptr->mpi_rank),
+ (int)(aux_ptr->unprotect_dirty_bytes),
+ (int)(aux_ptr->unprotect_dirty_bytes_updates),
+ (int)(aux_ptr->insert_dirty_bytes),
+ (int)(aux_ptr->insert_dirty_bytes_updates),
+ (int)(aux_ptr->rename_dirty_bytes),
+ (int)(aux_ptr->rename_dirty_bytes_updates));
+#endif /* H5AC_DEBUG_DIRTY_BYTES_CREATION */
+
+ /* to prevent "messages from the future" we must synchronize all
+ * processes before we start the flush. Hence the following
+ * barrier.
+ */
+ if(MPI_SUCCESS != (mpi_code = MPI_Barrier(aux_ptr->mpi_comm)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code)
+
+ /* Flush data to disk, from rank 0 process */
+ if(aux_ptr->mpi_rank == 0 ) {
+ herr_t status;
+
+ aux_ptr->write_permitted = TRUE;
+
+ status = H5C_flush_cache(f,
+ H5AC_noblock_dxpl_id,
+ H5AC_noblock_dxpl_id,
+ f->shared->cache,
+ H5AC__NO_FLAGS_SET);
+
+ aux_ptr->write_permitted = FALSE;
+
+ if(status < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush.")
+
+ if(aux_ptr->write_done != NULL)
+ (aux_ptr->write_done)();
+ } /* end if ( aux_ptr->mpi_rank == 0 ) */
+
+ /* Propagate cleaned entries to other ranks */
+ if(H5AC_propagate_flushed_and_still_clean_entries_list(f,
+ H5AC_noblock_dxpl_id,
+ f->shared->cache,
+ FALSE) < 0 )
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't propagate clean entries list.")
+ } /* end if ( aux_ptr != NULL ) */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5AC_flush_entries() */
#endif /* H5_HAVE_PARALLEL */
diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h
index bbbcf11..d36069a 100644
--- a/src/H5ACprivate.h
+++ b/src/H5ACprivate.h
@@ -62,6 +62,15 @@ typedef enum {
H5AC_FSPACE_SINFO_ID,/*free space sections */
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_EARRAY_SBLOCK_ID, /*extensible array super block */
+ H5AC_EARRAY_DBLOCK_ID, /*extensible array data block */
+ H5AC_EARRAY_DBLK_PAGE_ID, /*extensible array data block page */
+ H5AC_FARRAY_HDR_ID, /*fixed array header */
+ H5AC_FARRAY_DBLOCK_ID, /*fixed array data block */
+ H5AC_FARRAY_DBLK_PAGE_ID, /*fixed array data block page */
+ H5AC_SUPERBLOCK_ID, /* file superblock */
H5AC_TEST_ID, /*test entry -- not used for actual files */
H5AC_NTYPES /* Number of types, must be last */
} H5AC_type_t;
@@ -113,6 +122,9 @@ typedef enum {
*
* CLEAR: Just marks object as non-dirty.
*
+ * NOTIFY: Notify client that an action on an entry has taken/will take
+ * place
+ *
* SIZE: Report the size (on disk) of the specified cache object.
* Note that the space allocated on disk may not be contiguous.
*/
@@ -121,10 +133,16 @@ typedef enum {
#define H5AC_CALLBACK__SIZE_CHANGED_FLAG H5C_CALLBACK__SIZE_CHANGED_FLAG
#define H5AC_CALLBACK__RENAMED_FLAG H5C_CALLBACK__RENAMED_FLAG
+/* Aliases for 'notify action' type & values */
+typedef H5C_notify_action_t H5AC_notify_action_t;
+#define H5AC_NOTIFY_ACTION_AFTER_INSERT H5C_NOTIFY_ACTION_AFTER_INSERT
+#define H5AC_NOTIFY_ACTION_BEFORE_EVICT H5C_NOTIFY_ACTION_BEFORE_EVICT
+
typedef H5C_load_func_t H5AC_load_func_t;
typedef H5C_flush_func_t H5AC_flush_func_t;
typedef H5C_dest_func_t H5AC_dest_func_t;
typedef H5C_clear_func_t H5AC_clear_func_t;
+typedef H5C_notify_func_t H5AC_notify_func_t;
typedef H5C_size_func_t H5AC_size_func_t;
typedef H5C_class_t H5AC_class_t;
@@ -194,6 +212,7 @@ extern hid_t H5AC_ind_dxpl_id;
/* Default cache configuration. */
+#ifdef H5_HAVE_PARALLEL
#define H5AC__DEFAULT_CACHE_CONFIG \
{ \
/* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, \
@@ -203,9 +222,9 @@ extern hid_t H5AC_ind_dxpl_id;
/* char trace_file_name[] = */ "", \
/* hbool_t evictions_enabled = */ TRUE, \
/* hbool_t set_initial_size = */ TRUE, \
- /* size_t initial_size = */ ( 1 * 1024 * 1024), \
- /* double min_clean_fraction = */ 0.5, \
- /* size_t max_size = */ (16 * 1024 * 1024), \
+ /* size_t initial_size = */ ( 2 * 1024 * 1024), \
+ /* double min_clean_fraction = */ 0.3, \
+ /* size_t max_size = */ (32 * 1024 * 1024), \
/* size_t min_size = */ ( 1 * 1024 * 1024), \
/* long int epoch_length = */ 50000, \
/* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, \
@@ -227,6 +246,41 @@ extern hid_t H5AC_ind_dxpl_id;
/* double empty_reserve = */ 0.1, \
/* int dirty_bytes_threshold = */ (256 * 1024) \
}
+#else /* H5_HAVE_PARALLEL */
+#define H5AC__DEFAULT_CACHE_CONFIG \
+{ \
+ /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, \
+ /* hbool_t rpt_fcn_enabled = */ FALSE, \
+ /* hbool_t open_trace_file = */ FALSE, \
+ /* hbool_t close_trace_file = */ FALSE, \
+ /* char trace_file_name[] = */ "", \
+ /* hbool_t evictions_enabled = */ TRUE, \
+ /* hbool_t set_initial_size = */ TRUE, \
+ /* size_t initial_size = */ ( 2 * 1024 * 1024), \
+ /* double min_clean_fraction = */ 0.01, \
+ /* size_t max_size = */ (32 * 1024 * 1024), \
+ /* size_t min_size = */ ( 1 * 1024 * 1024), \
+ /* long int epoch_length = */ 50000, \
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, \
+ /* double lower_hr_threshold = */ 0.9, \
+ /* double increment = */ 2.0, \
+ /* hbool_t apply_max_increment = */ TRUE, \
+ /* size_t max_increment = */ (4 * 1024 * 1024), \
+ /* enum H5C_cache_flash_incr_mode */ \
+ /* flash_incr_mode = */ H5C_flash_incr__add_space, \
+ /* double flash_multiple = */ 1.4, \
+ /* double flash_threshold = */ 0.25, \
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,\
+ /* double upper_hr_threshold = */ 0.999, \
+ /* double decrement = */ 0.9, \
+ /* hbool_t apply_max_decrement = */ TRUE, \
+ /* size_t max_decrement = */ (1 * 1024 * 1024), \
+ /* int epochs_before_eviction = */ 3, \
+ /* hbool_t apply_empty_reserve = */ TRUE, \
+ /* double empty_reserve = */ 0.1, \
+ /* int dirty_bytes_threshold = */ (256 * 1024) \
+}
+#endif /* H5_HAVE_PARALLEL */
/*
@@ -249,6 +303,8 @@ extern hid_t H5AC_ind_dxpl_id;
#define H5AC__FLUSH_CLEAR_ONLY_FLAG H5C__FLUSH_CLEAR_ONLY_FLAG
#define H5AC__FLUSH_MARKED_ENTRIES_FLAG H5C__FLUSH_MARKED_ENTRIES_FLAG
#define H5AC__FLUSH_IGNORE_PROTECTED_FLAG H5C__FLUSH_IGNORE_PROTECTED_FLAG
+#define H5AC__FREE_FILE_SPACE_FLAG H5C__FREE_FILE_SPACE_FLAG
+#define H5AC__TAKE_OWNERSHIP_FLAG H5C__TAKE_OWNERSHIP_FLAG
/* #defines of flags used to report entry status in the
@@ -259,6 +315,8 @@ extern hid_t H5AC_ind_dxpl_id;
#define H5AC_ES__IS_DIRTY 0x0002
#define H5AC_ES__IS_PROTECTED 0x0004
#define H5AC_ES__IS_PINNED 0x0008
+#define H5AC_ES__IS_FLUSH_DEP_PARENT 0x0010
+#define H5AC_ES__IS_FLUSH_DEP_CHILD 0x0020
/* external function declarations: */
@@ -268,8 +326,10 @@ H5_DLL herr_t H5AC_create(const H5F_t *f, H5AC_cache_config_t *config_ptr);
H5_DLL herr_t H5AC_get_entry_status(H5F_t * f, haddr_t addr,
unsigned * status_ptr);
H5_DLL herr_t H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type,
- haddr_t addr, void *thing, unsigned int flags);
+ haddr_t addr, void *thing, unsigned int flags);
H5_DLL herr_t H5AC_pin_protected_entry(H5F_t * f, void * thing);
+H5_DLL herr_t H5AC_create_flush_dependency(H5F_t *f, void *parent_thing,
+ void *child_thing);
H5_DLL void * H5AC_protect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type,
haddr_t addr, const void *udata1, void *udata2,
H5AC_protect_t rw);
@@ -278,10 +338,12 @@ H5_DLL herr_t H5AC_resize_pinned_entry(H5F_t * f,
size_t new_size);
H5_DLL herr_t H5AC_unpin_entry(H5F_t * f,
void * thing);
+H5_DLL herr_t H5AC_destroy_flush_dependency(H5F_t *f, void *parent_thing,
+ void *child_thing);
H5_DLL herr_t H5AC_unprotect(H5F_t *f, hid_t dxpl_id,
const H5AC_class_t *type, haddr_t addr,
void *thing, unsigned flags);
-H5_DLL herr_t H5AC_flush(H5F_t *f, hid_t dxpl_id, unsigned flags);
+H5_DLL herr_t H5AC_flush(H5F_t *f, hid_t dxpl_id);
H5_DLL herr_t H5AC_mark_pinned_entry_dirty(H5F_t * f,
void * thing,
hbool_t size_changed,
@@ -294,7 +356,8 @@ H5_DLL herr_t H5AC_rename(H5F_t *f, const H5AC_class_t *type,
H5_DLL herr_t H5AC_dest(H5F_t *f, hid_t dxpl_id);
H5_DLL herr_t H5AC_expunge_entry(H5F_t *f, hid_t dxpl_id,
- const H5AC_class_t *type, haddr_t addr);
+ const H5AC_class_t *type, haddr_t addr,
+ unsigned flags);
H5_DLL herr_t H5AC_set_write_done_callback(H5C_t * cache_ptr,
void (* write_done)(void));
diff --git a/src/H5ACpublic.h b/src/H5ACpublic.h
index 0e75117..3c62fbf 100644
--- a/src/H5ACpublic.h
+++ b/src/H5ACpublic.h
@@ -57,7 +57,7 @@ extern "C" {
* structure.
*
* Similarly, the open_trace_file, close_trace_file, and trace_file_name
- * fields do not appear in H5C_auto_size_ctl_t, as most trace file
+ * fields do not appear in H5C_auto_size_ctl_t, as most trace file
* issues are handled at the H5AC level. The one exception is storage of
* the pointer to the trace file, which is handled by H5C.
*
@@ -82,7 +82,7 @@ extern "C" {
*
* The trace file is a debuging feature that allow the capture of
* top level metadata cache requests for purposes of debugging and/or
- * optimization. This field should normally be set to FALSE, as
+ * optimization. This field should normally be set to FALSE, as
* trace file collection imposes considerable overhead.
*
* This field should only be set to TRUE when the trace_file_name
@@ -100,7 +100,7 @@ extern "C" {
* trace_file_name: Full path of the trace file to be opened if the
* open_trace_file field is TRUE.
*
- * In the parallel case, an ascii representation of the mpi rank of
+ * In the parallel case, an ascii representation of the mpi rank of
* the process will be appended to the file name to yield a unique
* trace file name for each process.
*
@@ -108,12 +108,12 @@ extern "C" {
* characters.
*
* evictions_enabled: Boolean field used to either report the current
- * evictions enabled status of the cache, or to set the cache's
+ * evictions enabled status of the cache, or to set the cache's
* evictions enabled status.
*
- * In general, the metadata cache should always be allowed to
- * evict entries. However, in some cases it is advantageous to
- * disable evictions briefly, and thereby postpone metadata
+ * In general, the metadata cache should always be allowed to
+ * evict entries. However, in some cases it is advantageous to
+ * disable evictions briefly, and thereby postpone metadata
* writes. However, this must be done with care, as the cache
* can grow quickly. If you do this, re-enable evictions as
* soon as possible and monitor cache size.
@@ -179,7 +179,7 @@ extern "C" {
* at its maximum size, or if the cache is not already using
* all available space.
*
- * Note that you must set decr_mode to H5C_incr__off if you
+ * Note that you must set decr_mode to H5C_incr__off if you
* disable metadata cache entry evictions.
*
* lower_hr_threshold: Lower hit rate threshold. If the increment mode
@@ -216,7 +216,7 @@ extern "C" {
* The addition of the flash increment mode was occasioned by performance
* problems that appear when a local heap is increased to a size in excess
* of the current cache size. While the existing re-size code dealt with
- * this eventually, performance was very bad for the remainder of the
+ * this eventually, performance was very bad for the remainder of the
* epoch.
*
* At present, there are two possible values for the flash_incr_mode:
@@ -241,20 +241,20 @@ extern "C" {
*
* With a little thought, it should be obvious that the above flash
* cache size increase algorithm is not sufficient for all circumstances --
- * for example, suppose the user round robins through
+ * for example, suppose the user round robins through
* (1/flash_threshold) +1 groups, adding one data set to each on each
* pass. Then all will increase in size at about the same time, requiring
* the max cache size to at least double to maintain acceptable
* performance, however the above flash increment algorithm will not be
* triggered.
*
- * Hopefully, the add space algorithms detailed above will be sufficient
- * for the performance problems encountered to date. However, we should
+ * Hopefully, the add space algorithms detailed above will be sufficient
+ * for the performance problems encountered to date. However, we should
* expect to revisit the issue.
*
* flash_multiple: Double containing the multiple described above in the
- * H5C_flash_incr__add_space section of the discussion of the
- * flash_incr_mode section. This field is ignored unless flash_incr_mode
+ * H5C_flash_incr__add_space section of the discussion of the
+ * flash_incr_mode section. This field is ignored unless flash_incr_mode
* is H5C_flash_incr__add_space.
*
* flash_threshold: Double containing the factor by which current max cache size
@@ -294,7 +294,7 @@ extern "C" {
* over the last epoch exceeds the value provided in the
* upper_hr_threshold field.
*
- * Note that you must set decr_mode to H5C_decr__off if you
+ * Note that you must set decr_mode to H5C_decr__off if you
* disable metadata cache entry evictions.
*
* upper_hr_threshold: Upper hit rate threshold. The use of this field
diff --git a/src/H5Abtree2.c b/src/H5Abtree2.c
index 07550da..eb2c741 100644
--- a/src/H5Abtree2.c
+++ b/src/H5Abtree2.c
@@ -80,23 +80,21 @@ typedef struct H5A_fh_ud_cmp_t {
/* v2 B-tree driver callbacks for 'creation order' index */
static herr_t H5A_dense_btree2_corder_store(void *native, const void *udata);
-static herr_t H5A_dense_btree2_corder_retrieve(void *udata, const void *native);
static herr_t H5A_dense_btree2_corder_compare(const void *rec1, const void *rec2);
-static herr_t H5A_dense_btree2_corder_encode(const H5F_t *f, uint8_t *raw,
- const void *native);
-static herr_t H5A_dense_btree2_corder_decode(const H5F_t *f, const uint8_t *raw,
- void *native);
+static herr_t H5A_dense_btree2_corder_encode(uint8_t *raw, const void *native,
+ void *ctx);
+static herr_t H5A_dense_btree2_corder_decode(const uint8_t *raw, void *native,
+ void *ctx);
static herr_t H5A_dense_btree2_corder_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
int indent, int fwidth, const void *record, const void *_udata);
/* v2 B-tree driver callbacks for 'name' index */
static herr_t H5A_dense_btree2_name_store(void *native, const void *udata);
-static herr_t H5A_dense_btree2_name_retrieve(void *udata, const void *native);
static herr_t H5A_dense_btree2_name_compare(const void *rec1, const void *rec2);
-static herr_t H5A_dense_btree2_name_encode(const H5F_t *f, uint8_t *raw,
- const void *native);
-static herr_t H5A_dense_btree2_name_decode(const H5F_t *f, const uint8_t *raw,
- void *native);
+static herr_t H5A_dense_btree2_name_encode(uint8_t *raw, const void *native,
+ void *ctx);
+static herr_t H5A_dense_btree2_name_decode(const uint8_t *raw, void *native,
+ void *ctx);
static herr_t H5A_dense_btree2_name_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
int indent, int fwidth, const void *record, const void *_udata);
@@ -109,26 +107,34 @@ static herr_t H5A_dense_fh_name_cmp(const void *obj, size_t obj_len, void *op_da
/*********************/
/* v2 B-tree class for indexing 'name' field of attributes */
const H5B2_class_t H5A_BT2_NAME[1]={{ /* B-tree class information */
- H5B2_ATTR_DENSE_NAME_ID, /* Type of B-tree */
+ H5B2_ATTR_DENSE_NAME_ID, /* Type of B-tree */
+ "H5B2_ATTR_DENSE_NAME_ID", /* Name of B-tree class */
sizeof(H5A_dense_bt2_name_rec_t), /* Size of native record */
+ NULL, /* Create client callback context */
+ NULL, /* Destroy client callback context */
H5A_dense_btree2_name_store, /* Record storage callback */
- H5A_dense_btree2_name_retrieve, /* Record retrieval callback */
H5A_dense_btree2_name_compare, /* Record comparison callback */
H5A_dense_btree2_name_encode, /* Record encoding callback */
H5A_dense_btree2_name_decode, /* Record decoding callback */
- H5A_dense_btree2_name_debug /* Record debugging callback */
+ H5A_dense_btree2_name_debug, /* Record debugging callback */
+ NULL, /* Create debugging context */
+ NULL /* Destroy debugging context */
}};
/* v2 B-tree class for indexing 'creation order' field of attributes */
-const H5B2_class_t H5A_BT2_CORDER[1]={{ /* B-tree class information */
- H5B2_ATTR_DENSE_CORDER_ID, /* Type of B-tree */
+const H5B2_class_t H5A_BT2_CORDER[1]={{ /* B-tree class information */
+ H5B2_ATTR_DENSE_CORDER_ID, /* Type of B-tree */
+ "H5B2_ATTR_DENSE_CORDER_ID", /* Name of B-tree class */
sizeof(H5A_dense_bt2_corder_rec_t),/* Size of native record */
+ NULL, /* Create client callback context */
+ NULL, /* Destroy client callback context */
H5A_dense_btree2_corder_store, /* Record storage callback */
- H5A_dense_btree2_corder_retrieve, /* Record retrieval callback */
H5A_dense_btree2_corder_compare, /* Record comparison callback */
H5A_dense_btree2_corder_encode, /* Record encoding callback */
H5A_dense_btree2_corder_decode, /* Record decoding callback */
- H5A_dense_btree2_corder_debug /* Record debugging callback */
+ H5A_dense_btree2_corder_debug, /* Record debugging callback */
+ NULL, /* Create debugging context */
+ NULL /* Destroy debugging context */
}};
@@ -168,7 +174,7 @@ H5A_dense_fh_name_cmp(const void *obj, size_t UNUSED obj_len, void *_udata)
FUNC_ENTER_NOAPI_NOINIT(H5A_dense_fh_name_cmp)
/* Decode attribute information */
- if(NULL == (attr = (H5A_t *)H5O_msg_decode(udata->f, udata->dxpl_id, H5O_ATTR_ID, (const unsigned char *)obj)))
+ if(NULL == (attr = (H5A_t *)H5O_msg_decode(udata->f, udata->dxpl_id, NULL, H5O_ATTR_ID, (const unsigned char *)obj)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "can't decode attribute")
/* Compare the string values */
@@ -229,30 +235,6 @@ H5A_dense_btree2_name_store(void *_nrecord, const void *_udata)
/*-------------------------------------------------------------------------
- * Function: H5A_dense_btree2_name_retrieve
- *
- * Purpose: Retrieve native information from record for v2 B-tree
- *
- * Return: Success: non-negative
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Monday, December 4, 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5A_dense_btree2_name_retrieve(void *udata, const void *nrecord)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_btree2_name_retrieve)
-
- *(H5A_dense_bt2_name_rec_t *)udata = *(const H5A_dense_bt2_name_rec_t *)nrecord;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5A_dense_btree2_name_retrieve() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5A_dense_btree2_name_compare
*
* Purpose: Compare two native information records, according to some key
@@ -337,7 +319,7 @@ H5A_dense_btree2_name_compare(const void *_bt2_udata, const void *_bt2_rec)
*-------------------------------------------------------------------------
*/
static herr_t
-H5A_dense_btree2_name_encode(const H5F_t UNUSED *f, uint8_t *raw, const void *_nrecord)
+H5A_dense_btree2_name_encode(uint8_t *raw, const void *_nrecord, void UNUSED *ctx)
{
const H5A_dense_bt2_name_rec_t *nrecord = (const H5A_dense_bt2_name_rec_t *)_nrecord;
@@ -367,7 +349,7 @@ H5A_dense_btree2_name_encode(const H5F_t UNUSED *f, uint8_t *raw, const void *_n
*-------------------------------------------------------------------------
*/
static herr_t
-H5A_dense_btree2_name_decode(const H5F_t UNUSED *f, const uint8_t *raw, void *_nrecord)
+H5A_dense_btree2_name_decode(const uint8_t *raw, void *_nrecord, void UNUSED *ctx)
{
H5A_dense_bt2_name_rec_t *nrecord = (H5A_dense_bt2_name_rec_t *)_nrecord;
@@ -443,30 +425,6 @@ H5A_dense_btree2_corder_store(void *_nrecord, const void *_udata)
/*-------------------------------------------------------------------------
- * Function: H5A_dense_btree2_corder_retrieve
- *
- * Purpose: Retrieve native information from record for v2 B-tree
- *
- * Return: Success: non-negative
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Tuesday, February 6, 2007
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5A_dense_btree2_corder_retrieve(void *udata, const void *nrecord)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_btree2_corder_retrieve)
-
- *(H5A_dense_bt2_corder_rec_t *)udata = *(const H5A_dense_bt2_corder_rec_t *)nrecord;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5A_dense_btree2_corder_retrieve() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5A_dense_btree2_corder_compare
*
* Purpose: Compare two native information records, according to some key
@@ -519,7 +477,7 @@ H5A_dense_btree2_corder_compare(const void *_bt2_udata, const void *_bt2_rec)
*-------------------------------------------------------------------------
*/
static herr_t
-H5A_dense_btree2_corder_encode(const H5F_t UNUSED *f, uint8_t *raw, const void *_nrecord)
+H5A_dense_btree2_corder_encode(uint8_t *raw, const void *_nrecord, void UNUSED *ctx)
{
const H5A_dense_bt2_corder_rec_t *nrecord = (const H5A_dense_bt2_corder_rec_t *)_nrecord;
@@ -548,7 +506,7 @@ H5A_dense_btree2_corder_encode(const H5F_t UNUSED *f, uint8_t *raw, const void *
*-------------------------------------------------------------------------
*/
static herr_t
-H5A_dense_btree2_corder_decode(const H5F_t UNUSED *f, const uint8_t *raw, void *_nrecord)
+H5A_dense_btree2_corder_decode(const uint8_t *raw, void *_nrecord, void UNUSED *ctx)
{
H5A_dense_bt2_corder_rec_t *nrecord = (H5A_dense_bt2_corder_rec_t *)_nrecord;
diff --git a/src/H5Adense.c b/src/H5Adense.c
index 79cd6fe..889889e 100644
--- a/src/H5Adense.c
+++ b/src/H5Adense.c
@@ -186,8 +186,10 @@ herr_t
H5A_dense_create(H5F_t *f, hid_t dxpl_id, H5O_ainfo_t *ainfo)
{
H5HF_create_t fheap_cparam; /* Fractal heap creation parameters */
- H5HF_t *fheap; /* Fractal heap handle */
- size_t bt2_rrec_size; /* v2 B-tree raw record size */
+ H5B2_create_t bt2_cparam; /* v2 B-tree creation parameters */
+ H5HF_t *fheap = NULL; /* Fractal heap handle */
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for names */
+ H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5A_dense_create, FAIL)
@@ -234,20 +236,22 @@ HDfprintf(stderr, "%s: fheap_id_len = %Zu\n", FUNC, fheap_id_len);
}
#endif /* NDEBUG */
- /* Close the fractal heap */
- if(H5HF_close(fheap, dxpl_id) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
-
/* Create the name index v2 B-tree */
- bt2_rrec_size = 4 + /* Name's hash value */
+ HDmemset(&bt2_cparam, 0, sizeof(bt2_cparam));
+ bt2_cparam.cls = H5A_BT2_NAME;
+ bt2_cparam.node_size = (size_t)H5A_NAME_BT2_NODE_SIZE;
+ bt2_cparam.rrec_size = 4 + /* Name's hash value */
4 + /* Creation order index */
1 + /* Message flags */
H5O_FHEAP_ID_LEN; /* Fractal heap ID */
- if(H5B2_create(f, dxpl_id, H5A_BT2_NAME,
- (size_t)H5A_NAME_BT2_NODE_SIZE, bt2_rrec_size,
- H5A_NAME_BT2_SPLIT_PERC, H5A_NAME_BT2_MERGE_PERC,
- &ainfo->name_bt2_addr) < 0)
+ bt2_cparam.split_percent = H5A_NAME_BT2_SPLIT_PERC;
+ bt2_cparam.merge_percent = H5A_NAME_BT2_MERGE_PERC;
+ if(NULL == (bt2_name = H5B2_create(f, dxpl_id, &bt2_cparam, NULL)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to create v2 B-tree for name index")
+
+ /* Retrieve the v2 B-tree's address in the file */
+ if(H5B2_get_addr(bt2_name, &ainfo->name_bt2_addr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get v2 B-tree address for name index")
#ifdef QAK
HDfprintf(stderr, "%s: ainfo->name_bt2_addr = %a\n", FUNC, ainfo->name_bt2_addr);
#endif /* QAK */
@@ -255,20 +259,34 @@ HDfprintf(stderr, "%s: ainfo->name_bt2_addr = %a\n", FUNC, ainfo->name_bt2_addr)
/* Check if we should create a creation order index v2 B-tree */
if(ainfo->index_corder) {
/* Create the creation order index v2 B-tree */
- bt2_rrec_size = 4 + /* Creation order index */
+ HDmemset(&bt2_cparam, 0, sizeof(bt2_cparam));
+ bt2_cparam.cls = H5A_BT2_CORDER;
+ bt2_cparam.node_size = (size_t)H5A_CORDER_BT2_NODE_SIZE;
+ bt2_cparam.rrec_size = 4 + /* Creation order index */
1 + /* Message flags */
H5O_FHEAP_ID_LEN; /* Fractal heap ID */
- if(H5B2_create(f, dxpl_id, H5A_BT2_CORDER,
- (size_t)H5A_CORDER_BT2_NODE_SIZE, bt2_rrec_size,
- H5A_CORDER_BT2_SPLIT_PERC, H5A_CORDER_BT2_MERGE_PERC,
- &ainfo->corder_bt2_addr) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to create v2 B-tree for name index")
+ bt2_cparam.split_percent = H5A_CORDER_BT2_SPLIT_PERC;
+ bt2_cparam.merge_percent = H5A_CORDER_BT2_MERGE_PERC;
+ if(NULL == (bt2_corder = H5B2_create(f, dxpl_id, &bt2_cparam, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to create v2 B-tree for creation order index")
+
+ /* Retrieve the v2 B-tree's address in the file */
+ if(H5B2_get_addr(bt2_corder, &ainfo->corder_bt2_addr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get v2 B-tree address for creation order index")
#ifdef QAK
HDfprintf(stderr, "%s: ainfo->corder_bt2_addr = %a\n", FUNC, ainfo->corder_bt2_addr);
#endif /* QAK */
} /* end if */
done:
+ /* Release resources */
+ if(fheap && H5HF_close(fheap, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index")
+ if(bt2_corder && H5B2_close(bt2_corder, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_create() */
@@ -326,7 +344,9 @@ H5A_dense_open(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *na
H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */
H5HF_t *fheap = NULL; /* Fractal heap handle */
H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
htri_t attr_sharable; /* Flag indicating attributes are sharable */
+ htri_t attr_exists; /* Attribute exists in v2 B-tree */
H5A_t *ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI(H5A_dense_open, NULL)
@@ -362,6 +382,10 @@ H5A_dense_open(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *na
} /* end if */
} /* end if */
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo->name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to open v2 B-tree for name index")
+
/* Create the "udata" information for v2 B-tree record find */
udata.f = f;
udata.dxpl_id = dxpl_id;
@@ -375,7 +399,9 @@ H5A_dense_open(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *na
udata.found_op_data = &ret_value;
/* Find & copy the attribute in the 'name' index */
- if(H5B2_find(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, &udata, NULL, NULL) < 0)
+ if((attr_exists = H5B2_find(bt2_name, dxpl_id, &udata, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "can't search for attribute in name index")
+ else if(attr_exists == FALSE)
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "can't locate attribute in name index")
done:
@@ -384,6 +410,8 @@ done:
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, NULL, "can't close fractal heap")
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, NULL, "can't close fractal heap")
+ if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, NULL, "can't close v2 B-tree for name index")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_open() */
@@ -408,6 +436,8 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr)
H5A_bt2_ud_ins_t udata; /* User data for v2 B-tree insertion */
H5HF_t *fheap = NULL; /* Fractal heap handle for attributes */
H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
+ H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */
H5WB_t *wb = NULL; /* Wrapped buffer for attribute data */
uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing message */
unsigned mesg_flags = 0; /* Flags for storing message */
@@ -497,6 +527,10 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to insert attribute into fractal heap")
} /* end else */
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo->name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
/* Create the callback information for v2 B-tree record insertion */
udata.common.f = f;
udata.common.dxpl_id = dxpl_id;
@@ -511,15 +545,19 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr)
/* udata.id already set */
/* Insert attribute into 'name' tracking v2 B-tree */
- if(H5B2_insert(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, &udata) < 0)
+ if(H5B2_insert(bt2_name, dxpl_id, &udata) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to insert record into v2 B-tree")
/* Check if we should create a creation order index v2 B-tree record */
if(ainfo->index_corder) {
- /* Insert the record into the creation order index v2 B-tree */
+ /* Open the creation order index v2 B-tree */
HDassert(H5F_addr_defined(ainfo->corder_bt2_addr));
- if(H5B2_insert(f, dxpl_id, H5A_BT2_CORDER, ainfo->corder_bt2_addr, &udata) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert record into v2 B-tree")
+ if(NULL == (bt2_corder = H5B2_open(f, dxpl_id, ainfo->corder_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index")
+
+ /* Insert the record into the creation order index v2 B-tree */
+ if(H5B2_insert(bt2_corder, dxpl_id, &udata) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to insert record into v2 B-tree")
} /* end if */
done:
@@ -528,6 +566,10 @@ done:
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index")
+ if(bt2_corder && H5B2_close(bt2_corder, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index")
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
@@ -591,6 +633,7 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed)
{
H5A_dense_bt2_name_rec_t *record = (H5A_dense_bt2_name_rec_t *)_record; /* Record from B-tree */
H5A_bt2_od_wrt_t *op_data = (H5A_bt2_od_wrt_t *)_op_data; /* "op data" from v2 B-tree modify */
+ H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */
H5WB_t *wb = NULL; /* Wrapped buffer for attribute data */
uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing attribute */
herr_t ret_value = SUCCEED; /* Return value */
@@ -616,6 +659,10 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed)
if(H5F_addr_defined(op_data->corder_bt2_addr)) {
H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */
+ /* Open the creation order index v2 B-tree */
+ if(NULL == (bt2_corder = H5B2_open(op_data->f, op_data->dxpl_id, op_data->corder_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index")
+
/* Create the "udata" information for v2 B-tree record modify */
udata.f = op_data->f;
udata.dxpl_id = op_data->dxpl_id;
@@ -629,7 +676,7 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed)
udata.found_op_data = NULL;
/* Modify record for creation order index */
- if(H5B2_modify(op_data->f, op_data->dxpl_id, H5A_BT2_CORDER, op_data->corder_bt2_addr, &udata, H5A_dense_write_bt2_cb2, &op_data->attr->sh_loc.u.heap_id) < 0)
+ if(H5B2_modify(bt2_corder, op_data->dxpl_id, &udata, H5A_dense_write_bt2_cb2, &op_data->attr->sh_loc.u.heap_id) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to modify record in v2 B-tree")
} /* end if */
@@ -674,6 +721,8 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed)
done:
/* Release resources */
+ if(bt2_corder && H5B2_close(bt2_corder, op_data->dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index")
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
@@ -701,6 +750,7 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr)
H5A_bt2_od_wrt_t op_data; /* "Op data" for v2 B-tree modify */
H5HF_t *fheap = NULL; /* Fractal heap handle */
H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
htri_t attr_sharable; /* Flag indicating attributes are sharable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -739,6 +789,10 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr)
if(NULL == (fheap = H5HF_open(f, dxpl_id, ainfo->fheap_addr)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo->name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
/* Create the "udata" information for v2 B-tree record modify */
udata.f = f;
udata.dxpl_id = dxpl_id;
@@ -760,7 +814,7 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr)
op_data.corder_bt2_addr = ainfo->corder_bt2_addr;
/* Modify attribute through 'name' tracking v2 B-tree */
- if(H5B2_modify(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, &udata, H5A_dense_write_bt2_cb, &op_data) < 0)
+ if(H5B2_modify(bt2_name, dxpl_id, &udata, H5A_dense_write_bt2_cb, &op_data) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to modify record in v2 B-tree")
done:
@@ -769,6 +823,8 @@ done:
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_write() */
@@ -803,7 +859,7 @@ H5A_dense_copy_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata)
* HDF5 routine, it could attempt to re-protect that direct block for the
* heap, causing the HDF5 routine called to fail)
*/
- if(NULL == (udata->attr = (H5A_t *)H5O_msg_decode(udata->f, udata->dxpl_id, H5O_ATTR_ID, (const unsigned char *)obj)))
+ if(NULL == (udata->attr = (H5A_t *)H5O_msg_decode(udata->f, udata->dxpl_id, NULL, H5O_ATTR_ID, (const unsigned char *)obj)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, FAIL, "can't decode attribute")
/* Set the creation order index for the attribute */
@@ -838,9 +894,11 @@ H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *
H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */
H5HF_t *fheap = NULL; /* Fractal heap handle */
H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
H5A_t *attr_copy = NULL; /* Copy of attribute to rename */
htri_t attr_sharable; /* Flag indicating attributes are sharable */
htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */
+ htri_t attr_exists; /* Attribute exists in v2 B-tree */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5A_dense_rename, FAIL)
@@ -877,6 +935,10 @@ H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *
if(NULL == (fheap = H5HF_open(f, dxpl_id, ainfo->fheap_addr)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo->name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
/* Create the "udata" information for v2 B-tree record modify */
udata.f = f;
udata.dxpl_id = dxpl_id;
@@ -890,8 +952,10 @@ H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *
udata.found_op_data = &attr_copy;
/* Get copy of attribute through 'name' tracking v2 B-tree */
- if(H5B2_find(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, &udata, NULL, NULL) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to find record in v2 B-tree")
+ if((attr_exists = H5B2_find(bt2_name, dxpl_id, &udata, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't search for attribute in name index")
+ else if(attr_exists == FALSE)
+ HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't locate attribute in name index")
HDassert(attr_copy);
/* Check if message is already shared */
@@ -956,6 +1020,8 @@ done:
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index")
if(attr_copy)
H5O_msg_free(H5O_ATTR_ID, attr_copy);
@@ -1081,7 +1147,7 @@ H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, const H5O_ainfo_t *ainf
H5HF_t *fheap = NULL; /* Fractal heap handle */
H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
H5A_attr_table_t atable = {0, NULL}; /* Table of attributes */
- const H5B2_class_t *bt2_class = NULL; /* Class of v2 B-tree */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */
herr_t ret_value; /* Return value */
@@ -1105,7 +1171,6 @@ H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, const H5O_ainfo_t *ainf
if(order == H5_ITER_NATIVE) {
HDassert(H5F_addr_defined(ainfo->name_bt2_addr));
bt2_addr = ainfo->name_bt2_addr;
- bt2_class = H5A_BT2_NAME;
} /* end if */
else
bt2_addr = HADDR_UNDEF;
@@ -1118,7 +1183,6 @@ H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, const H5O_ainfo_t *ainf
* the links, a table will be built.
*/
bt2_addr = ainfo->corder_bt2_addr;
- bt2_class = H5A_BT2_CORDER;
} /* end else */
/* Check on iteration order */
@@ -1150,6 +1214,10 @@ H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, const H5O_ainfo_t *ainf
} /* end if */
} /* end if */
+ /* Open the index v2 B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for index")
+
/* Construct the user data for v2 B-tree iterator callback */
udata.f = f;
udata.dxpl_id = dxpl_id;
@@ -1163,7 +1231,7 @@ H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, const H5O_ainfo_t *ainf
/* Iterate over the records in the v2 B-tree's "native" order */
/* (by hash of name) */
- if((ret_value = H5B2_iterate(f, dxpl_id, bt2_class, bt2_addr, H5A_dense_iterate_bt2_cb, &udata)) < 0)
+ if((ret_value = H5B2_iterate(bt2, dxpl_id, H5A_dense_iterate_bt2_cb, &udata)) < 0)
HERROR(H5E_ATTR, H5E_BADITER, "attribute iteration failed");
/* Update the last attribute examined, if requested */
@@ -1187,6 +1255,8 @@ done:
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for index")
if(atable.attrs && H5A_attr_release_table(&atable) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to release attribute table")
@@ -1213,18 +1283,23 @@ H5A_dense_remove_bt2_cb(const void *_record, void *_udata)
const H5A_dense_bt2_name_rec_t *record = (const H5A_dense_bt2_name_rec_t *)_record;
H5A_bt2_ud_rm_t *udata = (H5A_bt2_ud_rm_t *)_udata; /* User data for callback */
H5A_t *attr = *(H5A_t **)udata->common.found_op_data; /* Pointer to attribute to remove */
+ H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5A_dense_remove_bt2_cb)
/* Check for removing the link from the creation order index */
if(H5F_addr_defined(udata->corder_bt2_addr)) {
+ /* Open the creation order index v2 B-tree */
+ if(NULL == (bt2_corder = H5B2_open(udata->common.f, udata->common.dxpl_id, udata->corder_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index")
+
/* Set up the user data for the v2 B-tree 'record remove' callback */
udata->common.corder = attr->shared->crt_idx;
/* Remove the record from the creation order index v2 B-tree */
- if(H5B2_remove(udata->common.f, udata->common.dxpl_id, H5A_BT2_CORDER, udata->corder_bt2_addr, udata, NULL, NULL) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, FAIL, "unable to remove attribute from creation order index v2 B-tree")
+ if(H5B2_remove(bt2_corder, udata->common.dxpl_id, udata, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTREMOVE, FAIL, "unable to remove attribute from creation order index v2 B-tree")
} /* end if */
/* Check for removing shared attribute */
@@ -1245,6 +1320,10 @@ H5A_dense_remove_bt2_cb(const void *_record, void *_udata)
} /* end else */
done:
+ /* Release resources */
+ if(bt2_corder && H5B2_close(bt2_corder, udata->common.dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_remove_bt2_cb() */
@@ -1268,6 +1347,7 @@ H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *
H5A_bt2_ud_rm_t udata; /* User data for v2 B-tree record removal */
H5HF_t *fheap = NULL; /* Fractal heap handle */
H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
H5A_t *attr_copy = NULL; /* Copy of attribute to remove */
htri_t attr_sharable; /* Flag indicating attributes are sharable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1305,6 +1385,10 @@ H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *
} /* end if */
} /* end if */
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo->name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
/* Set up the user data for the v2 B-tree 'record remove' callback */
udata.common.f = f;
udata.common.dxpl_id = dxpl_id;
@@ -1317,7 +1401,7 @@ H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *
udata.corder_bt2_addr = ainfo->corder_bt2_addr;
/* Remove the record from the name index v2 B-tree */
- if(H5B2_remove(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, &udata, H5A_dense_remove_bt2_cb, &udata) < 0)
+ if(H5B2_remove(bt2_name, dxpl_id, &udata, H5A_dense_remove_bt2_cb, &udata) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTREMOVE, FAIL, "unable to remove attribute from name index v2 B-tree")
done:
@@ -1326,6 +1410,8 @@ done:
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index")
if(attr_copy)
H5O_msg_free_real(H5O_MSG_ATTR, attr_copy);
@@ -1350,6 +1436,7 @@ static herr_t
H5A_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata)
{
H5HF_t *fheap; /* Fractal heap handle */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
const H5A_dense_bt2_name_rec_t *record = (const H5A_dense_bt2_name_rec_t *)_record; /* v2 B-tree record */
H5A_bt2_ud_rmbi_t *bt2_udata = (H5A_bt2_ud_rmbi_t *)_bt2_udata; /* User data for callback */
H5A_fh_ud_cp_t fh_udata; /* User data for fractal heap 'op' callback */
@@ -1392,22 +1479,15 @@ H5A_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata)
/* Check for removing the link from the "other" index (creation order, when name used and vice versa) */
if(H5F_addr_defined(bt2_udata->other_bt2_addr)) {
H5A_bt2_ud_common_t other_bt2_udata; /* Info for B-tree callbacks */
- const H5B2_class_t *other_bt2_class; /* Class of "other" v2 B-tree */
/* Determine the index being used */
if(bt2_udata->idx_type == H5_INDEX_NAME) {
- /* Set the class of the "other" index */
- other_bt2_class = H5A_BT2_CORDER;
-
/* Set up the user data for the v2 B-tree 'record remove' callback */
other_bt2_udata.corder = fh_udata.attr->shared->crt_idx;
} /* end if */
else {
HDassert(bt2_udata->idx_type == H5_INDEX_CRT_ORDER);
- /* Set the class of the "other" index */
- other_bt2_class = H5A_BT2_NAME;
-
/* Set up the user data for the v2 B-tree 'record remove' callback */
other_bt2_udata.f = bt2_udata->f;
other_bt2_udata.dxpl_id = bt2_udata->dxpl_id;
@@ -1419,10 +1499,14 @@ H5A_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata)
other_bt2_udata.found_op_data = NULL;
} /* end else */
+ /* Open the index v2 B-tree */
+ if(NULL == (bt2 = H5B2_open(bt2_udata->f, bt2_udata->dxpl_id, bt2_udata->other_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for index")
+
/* Set the common information for the v2 B-tree remove operation */
/* Remove the record from the "other" index v2 B-tree */
- if(H5B2_remove(bt2_udata->f, bt2_udata->dxpl_id, other_bt2_class, bt2_udata->other_bt2_addr, &other_bt2_udata, NULL, NULL) < 0)
+ if(H5B2_remove(bt2, bt2_udata->dxpl_id, &other_bt2_udata, NULL, NULL) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTREMOVE, FAIL, "unable to remove record from 'other' index v2 B-tree")
} /* end if */
@@ -1453,6 +1537,8 @@ H5A_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata)
done:
/* Release resources */
+ if(bt2 && H5B2_close(bt2, bt2_udata->dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for index")
if(fh_udata.attr)
H5O_msg_free(H5O_ATTR_ID, fh_udata.attr);
@@ -1475,13 +1561,13 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5A_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo,
+H5A_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo,
H5_index_t idx_type, H5_iter_order_t order, hsize_t n)
{
H5HF_t *fheap = NULL; /* Fractal heap handle */
H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
H5A_attr_table_t atable = {0, NULL}; /* Table of attributes */
- const H5B2_class_t *bt2_class = NULL; /* Class of v2 B-tree */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
haddr_t bt2_addr; /* Address of v2 B-tree to use for operation */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1501,7 +1587,6 @@ H5A_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo,
*/
if(order == H5_ITER_NATIVE) {
bt2_addr = ainfo->name_bt2_addr;
- bt2_class = H5A_BT2_NAME;
HDassert(H5F_addr_defined(bt2_addr));
} /* end if */
else
@@ -1515,7 +1600,6 @@ H5A_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo,
* the links, a table will be built.
*/
bt2_addr = ainfo->corder_bt2_addr;
- bt2_class = H5A_BT2_CORDER;
} /* end else */
/* If there is an index defined for the field, use it */
@@ -1547,6 +1631,10 @@ H5A_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo,
} /* end if */
} /* end if */
+ /* Open the index v2 B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for index")
+
/* Set up the user data for the v2 B-tree 'record remove' callback */
udata.f = f;
udata.dxpl_id = dxpl_id;
@@ -1556,7 +1644,7 @@ H5A_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo,
udata.other_bt2_addr = idx_type == H5_INDEX_NAME ? ainfo->corder_bt2_addr : ainfo->name_bt2_addr;
/* Remove the record from the name index v2 B-tree */
- if(H5B2_remove_by_idx(f, dxpl_id, bt2_class, bt2_addr, order, n, H5A_dense_remove_by_idx_bt2_cb, &udata) < 0)
+ if(H5B2_remove_by_idx(bt2, dxpl_id, order, n, H5A_dense_remove_by_idx_bt2_cb, &udata) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTREMOVE, FAIL, "unable to remove attribute from v2 B-tree index")
} /* end if */
else {
@@ -1580,6 +1668,8 @@ done:
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for index")
if(atable.attrs && H5A_attr_release_table(&atable) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to release attribute table")
@@ -1607,6 +1697,7 @@ H5A_dense_exists(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *
H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */
H5HF_t *fheap = NULL; /* Fractal heap handle */
H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
htri_t attr_sharable; /* Flag indicating attributes are sharable */
htri_t ret_value = TRUE; /* Return value */
@@ -1643,6 +1734,10 @@ H5A_dense_exists(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *
} /* end if */
} /* end if */
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo->name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
/* Create the "udata" information for v2 B-tree record 'find' */
udata.f = f;
udata.dxpl_id = dxpl_id;
@@ -1656,12 +1751,8 @@ H5A_dense_exists(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *
udata.found_op_data = NULL;
/* Find the attribute in the 'name' index */
- if(H5B2_find(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, &udata, NULL, NULL) < 0) {
- /* Assume that the failure was just not finding the attribute & clear stack */
- H5E_clear_stack(NULL);
-
- ret_value = FALSE;
- } /* end if */
+ if((ret_value = H5B2_find(bt2_name, dxpl_id, &udata, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't search for attribute in name index")
done:
/* Release resources */
@@ -1669,6 +1760,8 @@ done:
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_exists() */
@@ -1783,7 +1876,7 @@ H5A_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_ainfo_t *ainfo)
udata.found_op_data = NULL;
/* Delete name index v2 B-tree */
- if(H5B2_delete(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, H5A_dense_delete_bt2_cb, &udata) < 0)
+ if(H5B2_delete(f, dxpl_id, ainfo->name_bt2_addr, NULL, H5A_dense_delete_bt2_cb, &udata) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree for name index")
ainfo->name_bt2_addr = HADDR_UNDEF;
@@ -1795,8 +1888,8 @@ H5A_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_ainfo_t *ainfo)
/* Check if we should delete the creation order index v2 B-tree */
if(H5F_addr_defined(ainfo->corder_bt2_addr)) {
/* Delete the creation order index, without adjusting the ref. count on the attributes */
- if(H5B2_delete(f, dxpl_id, H5A_BT2_CORDER, ainfo->corder_bt2_addr, NULL, NULL) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree for creation order index")
+ if(H5B2_delete(f, dxpl_id, ainfo->corder_bt2_addr, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree for creation order index")
ainfo->corder_bt2_addr = HADDR_UNDEF;
} /* end if */
diff --git a/src/H5Adeprec.c b/src/H5Adeprec.c
index 85cef2f..77f5736 100644
--- a/src/H5Adeprec.c
+++ b/src/H5Adeprec.c
@@ -214,7 +214,7 @@ H5Aopen_name(hid_t loc_id, const char *name)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
/* Register the attribute and get an ID for it */
- if((ret_value = H5I_register(H5I_ATTR, attr)) < 0)
+ if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
done:
@@ -270,7 +270,7 @@ H5Aopen_idx(hid_t loc_id, unsigned idx)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open attribute")
/* Register the attribute and get an ID for it */
- if((ret_value = H5I_register(H5I_ATTR, attr)) < 0)
+ if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
done:
diff --git a/src/H5Aint.c b/src/H5Aint.c
index 23a4e15..a89c1c9 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -37,9 +37,12 @@
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Apkg.h" /* Attributes */
+#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
+#include "H5SMprivate.h" /* Shared Object Header Messages */
/****************/
@@ -66,6 +69,17 @@ typedef struct {
size_t curr_attr; /* Current attribute to operate on */
} H5A_dense_bt_ud_t;
+/* Data exchange structure to use when copying an attribute from _SRC to _DST */
+typedef struct {
+ const H5O_ainfo_t *ainfo; /* dense information */
+ H5F_t *file; /* file */
+ hbool_t *recompute_size; /* Flag to indicate if size changed */
+ H5O_copy_t *cpy_info; /* Information on copying options */
+ hid_t dxpl_id; /* DXPL for operation */
+ const H5O_loc_t *oloc_src;
+ H5O_loc_t *oloc_dst;
+} H5A_dense_file_cp_ud_t;
+
/********************/
/* Package Typedefs */
@@ -136,32 +150,21 @@ H5A_compact_build_table_cb(H5O_t UNUSED *oh, H5O_mesg_t *mesg/*in,out*/,
/* Re-allocate the table if necessary */
if(udata->curr_attr == udata->atable->nattrs) {
- size_t i;
- size_t n = MAX(1, 2 * udata->atable->nattrs);
- H5A_t **table = (H5A_t **)H5FL_SEQ_CALLOC(H5A_t_ptr, n);
-
- /* Use attribute functions for operation */
- for(i=0; i<udata->atable->nattrs; i++) {
- table[i] = (H5A_t *)H5FL_CALLOC(H5A_t);
- if(NULL == H5A_copy(table[i], udata->atable->attrs[i]))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute")
- if(H5A_close(udata->atable->attrs[i]) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, H5_ITER_ERROR, "can't close attribute")
- }
+ H5A_t **new_table; /* New table for attributes */
+ size_t new_table_size; /* Number of attributes in new table */
- if(udata->atable->nattrs)
- udata->atable->attrs = (H5A_t **)H5FL_SEQ_FREE(H5A_t_ptr, udata->atable->attrs);
-
- if(!table)
+ /* Allocate larger table */
+ new_table_size = MAX(1, 2 * udata->atable->nattrs);
+ if(NULL == (new_table = (H5A_t **)H5FL_SEQ_REALLOC(H5A_t_ptr, udata->atable->attrs, new_table_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "unable to extend attribute table")
- udata->atable->attrs = table;
- udata->atable->nattrs = n;
+
+ /* Update table information in user data */
+ udata->atable->attrs = new_table;
+ udata->atable->nattrs = new_table_size;
} /* end if */
/* Copy attribute into table */
- udata->atable->attrs[udata->curr_attr] = (H5A_t *)H5FL_CALLOC(H5A_t);
-
- if(NULL == H5A_copy(udata->atable->attrs[udata->curr_attr], (const H5A_t *)mesg->native))
+ if(NULL == (udata->atable->attrs[udata->curr_attr] = H5A_copy(NULL, (const H5A_t *)mesg->native)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute")
/* Assign [somewhat arbitrary] creation order value, if requested */
@@ -300,6 +303,7 @@ herr_t
H5A_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo,
H5_index_t idx_type, H5_iter_order_t order, H5A_attr_table_t *atable)
{
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
hsize_t nrec; /* # of records in v2 B-tree */
herr_t ret_value = SUCCEED; /* Return value */
@@ -312,9 +316,13 @@ H5A_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo,
HDassert(H5F_addr_defined(ainfo->name_bt2_addr));
HDassert(atable);
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo->name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
/* Retrieve # of records in "name" B-tree */
/* (should be same # of records in all indices) */
- if(H5B2_get_nrec(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, &nrec) < 0)
+ if(H5B2_get_nrec(bt2_name, &nrec) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve # of records in index")
/* Set size of table */
@@ -357,6 +365,10 @@ H5A_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo,
atable->attrs = NULL;
done:
+ /* Release resources */
+ if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_build_table() */
@@ -384,8 +396,8 @@ H5A_attr_cmp_name_inc(const void *attr1, const void *attr2)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_attr_cmp_name_inc)
- FUNC_LEAVE_NOAPI(HDstrcmp((*(const H5A_t **)attr1)->shared->name,
- (*(const H5A_t **)attr2)->shared->name))
+ FUNC_LEAVE_NOAPI(HDstrcmp((*(const H5A_t * const *)attr1)->shared->name,
+ (*(const H5A_t * const *)attr2)->shared->name))
} /* end H5A_attr_cmp_name_inc() */
@@ -412,8 +424,8 @@ H5A_attr_cmp_name_dec(const void *attr1, const void *attr2)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_attr_cmp_name_dec)
- FUNC_LEAVE_NOAPI(HDstrcmp((*(const H5A_t **)attr2)->shared->name,
- (*(const H5A_t **)attr1)->shared->name))
+ FUNC_LEAVE_NOAPI(HDstrcmp((*(const H5A_t * const *)attr2)->shared->name,
+ (*(const H5A_t * const *)attr1)->shared->name))
} /* end H5A_attr_cmp_name_dec() */
@@ -441,9 +453,9 @@ H5A_attr_cmp_corder_inc(const void *attr1, const void *attr2)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_attr_cmp_corder_inc)
- if((*(const H5A_t **)attr1)->shared->crt_idx < (*(const H5A_t **)attr2)->shared->crt_idx)
+ if((*(const H5A_t * const *)attr1)->shared->crt_idx < (*(const H5A_t * const *)attr2)->shared->crt_idx)
ret_value = -1;
- else if((*(const H5A_t **)attr1)->shared->crt_idx > (*(const H5A_t **)attr2)->shared->crt_idx)
+ else if((*(const H5A_t * const *)attr1)->shared->crt_idx > (*(const H5A_t * const *)attr2)->shared->crt_idx)
ret_value = 1;
else
ret_value = 0;
@@ -476,9 +488,9 @@ H5A_attr_cmp_corder_dec(const void *attr1, const void *attr2)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_attr_cmp_corder_dec)
- if((*(const H5A_t **)attr1)->shared->crt_idx < (*(const H5A_t **)attr2)->shared->crt_idx)
+ if((*(const H5A_t * const *)attr1)->shared->crt_idx < (*(const H5A_t * const *)attr2)->shared->crt_idx)
ret_value = 1;
- else if((*(const H5A_t **)attr1)->shared->crt_idx > (*(const H5A_t **)attr2)->shared->crt_idx)
+ else if((*(const H5A_t * const *)attr1)->shared->crt_idx > (*(const H5A_t * const *)attr2)->shared->crt_idx)
ret_value = -1;
else
ret_value = 0;
@@ -666,8 +678,8 @@ done:
* Purpose: Retrieves the "attribute info" message for an object. Also
* sets the number of attributes correctly, if it isn't set up yet.
*
- * Return: Success: Ptr to message in native format.
- * Failure: NULL
+ * Return: Success: TRUE/FALSE whether message was found & retrieved
+ * Failure: FAIL if error occurred
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
@@ -675,37 +687,51 @@ done:
*
*-------------------------------------------------------------------------
*/
-H5O_ainfo_t *
+htri_t
H5A_get_ainfo(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_ainfo_t *ainfo)
{
- H5O_ainfo_t *ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5A_get_ainfo, NULL)
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5A_get_ainfo, FAIL)
/* check arguments */
HDassert(f);
HDassert(oh);
+ HDassert(ainfo);
+
+ /* Check if the "attribute info" message exists */
+ if((ret_value = H5O_msg_exists_oh(oh, H5O_AINFO_ID)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "unable to check object header")
+ if(ret_value > 0) {
+ /* Retrieve the "attribute info" structure */
+ if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_AINFO_ID, ainfo))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't read AINFO message")
- /* Retrieve the "attribute info" structure */
- if((ret_value = (H5O_ainfo_t *)H5O_msg_read_real(f, dxpl_id, oh, H5O_AINFO_ID, ainfo))) {
/* Check if we don't know how many attributes there are */
- if(ret_value->nattrs == HSIZET_MAX) {
+ if(ainfo->nattrs == HSIZET_MAX) {
/* Check if we are using "dense" attribute storage */
- if(H5F_addr_defined(ret_value->fheap_addr)) {
+ if(H5F_addr_defined(ainfo->fheap_addr)) {
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo->name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
/* Retrieve # of records in "name" B-tree */
/* (should be same # of records in all indices) */
- if(H5B2_get_nrec(f, dxpl_id, H5A_BT2_NAME, ret_value->name_bt2_addr, &ret_value->nattrs) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "can't retrieve # of records in index")
+ if(H5B2_get_nrec(bt2_name, &ainfo->nattrs) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve # of records in index")
} /* end if */
else
/* Retrieve # of attributes from object header */
- ret_value->nattrs = oh->attr_msgs_seen;
+ ainfo->nattrs = oh->attr_msgs_seen;
} /* end if */
} /* end if */
- else
- HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "attribute info message not present")
done:
+ /* Release resources */
+ if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_get_ainfo() */
@@ -731,7 +757,7 @@ H5A_set_version(const H5F_t *f, H5A_t *attr)
{
hbool_t type_shared, space_shared; /* Flags to indicate that shared messages are used for this attribute */
hbool_t use_latest_format; /* Flag indicating the newest file format should be used */
-
+
FUNC_ENTER_NOAPI_NOFUNC(H5A_set_version)
/* check arguments */
@@ -765,3 +791,523 @@ H5A_set_version(const H5F_t *f, H5A_t *attr)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5A_set_version() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_attr_copy_file
+ *
+ * Purpose: Copies a message from _MESG to _DEST in file
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * November 1, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+H5A_t *
+H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_size,
+ H5O_copy_t *cpy_info, hid_t dxpl_id)
+{
+ H5A_t *attr_dst = NULL;
+
+ /* for dataype conversion */
+ hid_t tid_src = -1; /* Datatype ID for source datatype */
+ hid_t tid_dst = -1; /* Datatype ID for destination datatype */
+ hid_t tid_mem = -1; /* Datatype ID for memory datatype */
+ void *buf = NULL; /* Buffer for copying data */
+ void *reclaim_buf = NULL; /* Buffer for reclaiming data */
+ hid_t buf_sid = -1; /* ID for buffer dataspace */
+
+ H5A_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5A_attr_copy_file)
+
+ /* check args */
+ HDassert(attr_src);
+ HDassert(file_dst);
+ HDassert(cpy_info);
+ HDassert(!cpy_info->copy_without_attr);
+
+ /* Allocate space for the destination message */
+ if(NULL == (attr_dst = H5FL_CALLOC(H5A_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Copy the top level of the attribute */
+ *attr_dst = *attr_src;
+
+ if(NULL == (attr_dst->shared = H5FL_CALLOC(H5A_shared_t)))
+ HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared attr structure")
+
+ /* Don't have an opened group location for copy */
+ H5O_loc_reset(&(attr_dst->oloc));
+ H5G_name_reset(&(attr_dst->path));
+ attr_dst->obj_opened = FALSE;
+
+ /* Reference count for the header message in the cache */
+ attr_dst->shared->nrefs = 1;
+
+ /* Copy attribute's name */
+ attr_dst->shared->name = H5MM_strdup(attr_src->shared->name);
+ HDassert(attr_dst->shared->name);
+
+ /* Copy attribute's datatype */
+ /* (Start destination datatype as transient, even if source is named) */
+ if(NULL == (attr_dst->shared->dt = H5T_copy(attr_src->shared->dt, H5T_COPY_ALL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "cannot copy datatype")
+
+ /* Set the location of the destination datatype */
+ if(H5T_set_loc(attr_dst->shared->dt, file_dst, H5T_LOC_DISK) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "cannot mark datatype on disk")
+
+ /* Check for named datatype being copied */
+ if(H5T_committed(attr_src->shared->dt)) {
+ H5O_loc_t *src_oloc; /* Pointer to source datatype's object location */
+ H5O_loc_t *dst_oloc; /* Pointer to dest. datatype's object location */
+
+ /* Get group entries for source & destination */
+ src_oloc = H5T_oloc(attr_src->shared->dt);
+ HDassert(src_oloc);
+ dst_oloc = H5T_oloc(attr_dst->shared->dt);
+ HDassert(dst_oloc);
+
+ /* Reset object location for new object */
+ H5O_loc_reset(dst_oloc);
+ dst_oloc->file = file_dst;
+
+ /* Copy the shared object from source to destination */
+ if(H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, cpy_info, FALSE) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object")
+
+ /* Update shared message info from named datatype info */
+ H5T_update_shared(attr_dst->shared->dt);
+ } /* end if */
+ else {
+ /* If the datatype is not named, it may have been shared in the
+ * source file's heap. Un-share it for now. We'll try to shared
+ * it in the destination file below.
+ */
+ if(H5O_msg_reset_share(H5O_DTYPE_ID, attr_dst->shared->dt) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to reset datatype sharing")
+ } /* end else */
+
+ /* Copy the dataspace for the attribute */
+ attr_dst->shared->ds = H5S_copy(attr_src->shared->ds, FALSE, FALSE);
+ HDassert(attr_dst->shared->ds);
+
+ /* Reset the dataspace's sharing in the source file before trying to share
+ * it in the destination.
+ */
+ if(H5O_msg_reset_share(H5O_SDSPACE_ID, attr_dst->shared->ds) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to reset dataspace sharing")
+
+
+ /* Try to share both the datatype and dataset. This does nothing if the
+ * datatype is committed or sharing is disabled.
+ */
+ if(H5SM_try_share(file_dst, dxpl_id, NULL, H5O_DTYPE_ID, attr_dst->shared->dt, NULL) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "can't share attribute datatype")
+ if(H5SM_try_share(file_dst, dxpl_id, NULL, H5O_SDSPACE_ID, attr_dst->shared->ds, NULL) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "can't share attribute dataspace")
+
+ /* Compute the sizes of the datatype and dataspace. This is their raw
+ * size unless they're shared.
+ */
+ attr_dst->shared->dt_size = H5O_msg_raw_size(file_dst, H5O_DTYPE_ID, FALSE, attr_dst->shared->dt);
+ HDassert(attr_dst->shared->dt_size > 0);
+ attr_dst->shared->ds_size = H5O_msg_raw_size(file_dst, H5O_SDSPACE_ID, FALSE, attr_dst->shared->ds);
+ HDassert(attr_dst->shared->ds_size > 0);
+
+ /* Check whether to recompute the size of the attribute */
+ /* (happens when the datatype or dataspace changes sharing status) */
+ if(attr_dst->shared->dt_size != attr_src->shared->dt_size || attr_dst->shared->ds_size != attr_src->shared->ds_size)
+ *recompute_size = TRUE;
+
+ /* Compute the size of the data */
+ H5_ASSIGN_OVERFLOW(attr_dst->shared->data_size, H5S_GET_EXTENT_NPOINTS(attr_dst->shared->ds) * H5T_get_size(attr_dst->shared->dt), hsize_t, size_t);
+
+ /* Copy (& convert) the data, if necessary */
+ if(attr_src->shared->data) {
+ if(NULL == (attr_dst->shared->data = H5FL_BLK_MALLOC(attr_buf, attr_dst->shared->data_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Check if we need to convert data */
+ if(H5T_detect_class(attr_src->shared->dt, H5T_VLEN, FALSE) > 0) {
+ H5T_path_t *tpath_src_mem, *tpath_mem_dst; /* Datatype conversion paths */
+ H5T_t *dt_mem; /* Memory datatype */
+ size_t src_dt_size; /* Source datatype size */
+ size_t tmp_dt_size; /* Temp. datatype size */
+ size_t max_dt_size; /* Max atatype size */
+ H5S_t *buf_space; /* Dataspace describing buffer */
+ hsize_t buf_dim; /* Dimension for buffer */
+ size_t nelmts; /* Number of elements in buffer */
+ size_t buf_size; /* Size of copy buffer */
+
+ /* Create datatype ID for src datatype */
+ if((tid_src = H5I_register(H5I_DATATYPE, attr_src->shared->dt, FALSE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register source file datatype")
+
+ /* create a memory copy of the variable-length datatype */
+ if(NULL == (dt_mem = H5T_copy(attr_src->shared->dt, H5T_COPY_TRANSIENT)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy")
+ if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem, FALSE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register memory datatype")
+
+ /* create variable-length datatype at the destinaton file */
+ if((tid_dst = H5I_register(H5I_DATATYPE, attr_dst->shared->dt, FALSE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register destination file datatype")
+
+ /* Set up the conversion functions */
+ if(NULL == (tpath_src_mem = H5T_path_find(attr_src->shared->dt, dt_mem, NULL, NULL, dxpl_id, FALSE)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to convert between src and mem datatypes")
+ if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, attr_dst->shared->dt, NULL, NULL, dxpl_id, FALSE)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to convert between mem and dst datatypes")
+
+ /* Determine largest datatype size */
+ if(0 == (src_dt_size = H5T_get_size(attr_src->shared->dt)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to determine datatype size")
+ if(0 == (tmp_dt_size = H5T_get_size(dt_mem)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to determine datatype size")
+ max_dt_size = MAX(src_dt_size, tmp_dt_size);
+ if(0 == (tmp_dt_size = H5T_get_size(attr_dst->shared->dt)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to determine datatype size")
+ max_dt_size = MAX(max_dt_size, tmp_dt_size);
+
+ /* Set number of whole elements that fit in buffer */
+ if(0 == (nelmts = attr_src->shared->data_size / src_dt_size))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "element size too large")
+
+ /* Set up number of bytes to copy, and initial buffer size */
+ buf_size = nelmts * max_dt_size;
+
+ /* Create dataspace for number of elements in buffer */
+ buf_dim = nelmts;
+
+ /* Create the space and set the initial extent */
+ if(NULL == (buf_space = H5S_create_simple((unsigned)1, &buf_dim, NULL)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, NULL, "can't create simple dataspace")
+
+ /* Atomize */
+ if((buf_sid = H5I_register(H5I_DATASPACE, buf_space, FALSE)) < 0) {
+ H5S_close(buf_space);
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, NULL, "unable to register dataspace ID")
+ } /* end if */
+
+ /* Allocate memory for recclaim buf */
+ if(NULL == (reclaim_buf = H5FL_BLK_MALLOC(attr_buf, buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation NULLed for raw data chunk")
+
+ /* Allocate memory for copying the chunk */
+ if(NULL == (buf = H5FL_BLK_MALLOC(attr_buf, buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation NULLed for raw data chunk")
+
+ HDmemcpy(buf, attr_src->shared->data, attr_src->shared->data_size);
+
+ /* Convert from source file to memory */
+ if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "datatype conversion NULLed")
+
+ HDmemcpy(reclaim_buf, buf, buf_size);
+
+ /* Convert from memory to destination file */
+ if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "datatype conversion NULLed")
+
+ HDmemcpy(attr_dst->shared->data, buf, attr_dst->shared->data_size);
+
+ if(H5D_vlen_reclaim(tid_mem, buf_space, H5P_DATASET_XFER_DEFAULT, reclaim_buf) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADITER, NULL, "unable to reclaim variable-length data")
+ } /* end if */
+ else {
+ HDassert(attr_dst->shared->data_size == attr_src->shared->data_size);
+ HDmemcpy(attr_dst->shared->data, attr_src->shared->data, attr_src->shared->data_size);
+ } /* end else */
+ } /* end if(attr_src->shared->data) */
+
+ /* Recompute the version to encode the destination attribute */
+ if(H5A_set_version(file_dst, attr_dst) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, NULL, "unable to update attribute version")
+
+ /* Set return value */
+ ret_value = attr_dst;
+
+done:
+ if(buf_sid > 0)
+ if(H5I_dec_ref(buf_sid, FALSE) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary dataspace ID")
+ if(tid_src > 0)
+ /* Don't decrement ID, we want to keep underlying datatype */
+ if(H5I_remove(tid_src) == NULL)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
+ if(tid_dst > 0)
+ /* Don't decrement ID, we want to keep underlying datatype */
+ if(H5I_remove(tid_dst) == NULL)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
+ if(tid_mem > 0)
+ /* Decrement the memory datatype ID, it's transient */
+ if(H5I_dec_ref(tid_mem, FALSE) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
+ if(buf)
+ buf = H5FL_BLK_FREE(attr_buf, buf);
+ if(reclaim_buf)
+ reclaim_buf = H5FL_BLK_FREE(attr_buf, reclaim_buf);
+
+ /* Release destination attribute information on failure */
+ if(!ret_value && attr_dst && H5A_close(attr_dst) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A_attr_copy_file() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_attr_post_copy_file
+ *
+ * Purpose: Finish copying a message from between files.
+ * We have to copy the values of a reference attribute in the
+ * post copy because H5O_post_copy_file() fails at the case that
+ * an object may have a reference attribute that points to the
+ * object itself.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Peter Cao
+ * March 6, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5A_attr_post_copy_file(const H5O_loc_t *src_oloc, const H5A_t UNUSED *attr_src,
+ H5O_loc_t *dst_oloc, const H5A_t *attr_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
+{
+ H5F_t *file_src = src_oloc->file;
+ H5F_t *file_dst = dst_oloc->file;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+
+ FUNC_ENTER_NOAPI_NOINIT(H5A_attr_post_copy_file)
+
+ /* check args */
+ HDassert(attr_dst);
+ HDassert(file_dst);
+
+
+ /* Only need to fix reference attribute with real data being copied to
+ * another file.
+ */
+ if((NULL != attr_dst->shared->data) && (H5T_get_class(attr_dst->shared->dt, FALSE) == H5T_REFERENCE) ) {
+
+ /* copy object pointed by reference. The current implementation does not
+ * deal with nested reference such as reference in a compound structure
+ */
+
+ /* Check for expanding references */
+ if(cpy_info->expand_ref) {
+ size_t ref_count;
+
+ /* Determine # of reference elements to copy */
+ ref_count = attr_dst->shared->data_size / H5T_get_size(attr_dst->shared->dt);
+
+ /* Copy objects referenced in source buffer to destination file and set destination elements */
+ if(H5O_copy_expand_ref(file_src, attr_dst->shared->data, dxpl_id,
+ file_dst, attr_dst->shared->data, ref_count, H5T_get_ref_type(attr_dst->shared->dt), cpy_info) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy reference attribute")
+ } /* end if */
+ else
+ /* Reset value to zero */
+ HDmemset(attr_dst->shared->data, 0, attr_dst->shared->data_size);
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A_attr_post_copy_file() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_dense_copy_file_cb
+ *
+ * Purpose: Callback routine for copying a dense attribute from SRC to DST.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Peter Cao
+ * xcao@hdfgroup.org
+ * July 20, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5A_dense_copy_file_cb(const H5A_t *attr_src, void *_udata)
+{
+ H5A_dense_file_cp_ud_t *udata = (H5A_dense_file_cp_ud_t *)_udata;
+ H5A_t *attr_dst = NULL;
+ herr_t ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5A_dense_copy_file_cb)
+
+ /* check arguments */
+ HDassert(attr_src);
+ HDassert(udata);
+ HDassert(udata->ainfo);
+ HDassert(udata->file);
+ HDassert(udata->cpy_info);
+
+ if ( NULL == (attr_dst=H5A_attr_copy_file(attr_src, udata->file,
+ udata->recompute_size, udata->cpy_info, udata->dxpl_id)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute")
+
+ /* Reset shared location information */
+ if(H5O_msg_reset_share(H5O_ATTR_ID, attr_dst) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to reset attribute sharing")
+
+ /* Insert attribute into dense storage */
+ if(H5A_dense_insert(udata->file, udata->dxpl_id, udata->ainfo, attr_dst) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, H5_ITER_ERROR, "unable to add to dense storage")
+
+done:
+ if (attr_dst) {
+ (void)H5A_free(attr_dst);
+ (void)H5FL_FREE(H5A_t, attr_dst);
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5A_dense_copy_file_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_dense_copy_file_all
+ *
+ * Purpose: Copy all dense attributes from SRC to DST.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Peter Cao
+ * xcao@hdfgroup.org
+ * July 20, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5A_dense_copy_file_all(H5F_t *file_src, H5O_ainfo_t *ainfo_src, H5F_t *file_dst,
+ const H5O_ainfo_t *ainfo_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, hid_t dxpl_id)
+{
+ H5A_dense_file_cp_ud_t udata; /* User data for iteration callback */
+ H5A_attr_iter_op_t attr_op; /* Attribute operator */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5A_dense_copy_file_all)
+
+ /* check arguments */
+ HDassert(ainfo_src);
+ HDassert(ainfo_dst);
+
+ udata.ainfo = ainfo_dst; /* Destination dense information */
+ udata.file = file_dst; /* Destination file */
+ udata.recompute_size = recompute_size; /* Flag to indicate if size changed */
+ udata.cpy_info = cpy_info; /* Information on copying options */
+ udata.dxpl_id = dxpl_id; /* DXPL for operation */
+
+ attr_op.op_type = H5A_ATTR_OP_LIB;
+ attr_op.u.lib_op = H5A_dense_copy_file_cb;
+
+ if(H5A_dense_iterate(file_src, dxpl_id, (hid_t)0, ainfo_src, H5_INDEX_NAME,
+ H5_ITER_NATIVE, (hsize_t)0, NULL, &attr_op, &udata) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "error building attribute table")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5A_dense_copy_file_all */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_dense_post_copy_file_cb
+ *
+ * Purpose: Callback routine to perfom post copy for a dense attribute.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Peter Cao
+ * xcao@hdfgroup.org
+ * July 25, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5A_dense_post_copy_file_cb(const H5A_t *attr_dst, void *_udata)
+{
+ H5A_dense_file_cp_ud_t *udata = (H5A_dense_file_cp_ud_t *)_udata;
+ herr_t ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5A_dense_post_copy_file_cb)
+
+ /* check arguments */
+ HDassert(attr_dst);
+ HDassert(udata);
+ HDassert(udata->ainfo);
+ HDassert(udata->file);
+ HDassert(udata->cpy_info);
+
+ if ( H5A_attr_post_copy_file(udata->oloc_src, NULL,
+ udata->oloc_dst, attr_dst, udata->dxpl_id, udata->cpy_info) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute")
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5A_dense_post_copy_file_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_dense_post_copy_file_all
+ *
+ * Purpose: Do post copy for all dense attributes.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Peter Cao
+ * xcao@hdfgroup.org
+ * July 25, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5A_dense_post_copy_file_all(const H5O_loc_t *src_oloc, const H5O_ainfo_t *ainfo_src,
+ H5O_loc_t *dst_oloc, H5O_ainfo_t *ainfo_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
+{
+ H5A_dense_file_cp_ud_t udata; /* User data for iteration callback */
+ H5A_attr_iter_op_t attr_op; /* Attribute operator */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5A_dense_post_copy_file_all)
+
+ /* check arguments */
+ HDassert(ainfo_src);
+ HDassert(ainfo_dst);
+ HDassert(src_oloc);
+ HDassert(dst_oloc);
+ HDassert(src_oloc->file);
+ HDassert(dst_oloc->file);
+
+ udata.ainfo = ainfo_src;
+ udata.file = src_oloc->file;
+ udata.cpy_info = cpy_info; /* Information on copying options */
+ udata.dxpl_id = dxpl_id; /* DXPL for operation */
+ udata.oloc_src = src_oloc;
+ udata.oloc_dst = dst_oloc;
+
+ attr_op.op_type = H5A_ATTR_OP_LIB;
+ attr_op.u.lib_op = H5A_dense_post_copy_file_cb;
+
+ if(H5A_dense_iterate(dst_oloc->file, dxpl_id, (hid_t)0, ainfo_dst, H5_INDEX_NAME,
+ H5_ITER_NATIVE, (hsize_t)0, NULL, &attr_op, &udata) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "error building attribute table")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
diff --git a/src/H5Apkg.h b/src/H5Apkg.h
index a1b5e62..de57e79 100644
--- a/src/H5Apkg.h
+++ b/src/H5Apkg.h
@@ -74,9 +74,7 @@
/****************************/
/* Define the shared attribute structure */
typedef struct H5A_shared_t {
- unsigned version; /* Version to encode attribute with */
- hbool_t initialized;/* Indicate whether the attribute has been modified */
- H5O_loc_t oloc; /* Object location for object attribute is on */
+ uint8_t version; /* Version to encode attribute with */
char *name; /* Attribute's name */
H5T_cset_t encoding; /* Character encoding of attribute name */
@@ -96,6 +94,7 @@ typedef struct H5A_shared_t {
/* Define the main attribute structure */
struct H5A_t {
H5O_shared_t sh_loc; /* Shared message info (must be first) */
+ H5O_loc_t oloc; /* Object location for object attribute is on */
hbool_t obj_opened; /* Object header entry opened? */
H5G_name_t path; /* Group hierarchy path */
H5A_shared_t *shared; /* Shared attribute information */
@@ -163,14 +162,16 @@ typedef struct {
typedef herr_t (*H5A_lib_iterate_t)(const H5A_t *attr, void *op_data);
/* Describe kind of callback to make for each attribute */
-struct H5A_attr_iter_op_t {
- enum {
+typedef enum H5A_attr_iter_op_type_t {
#ifndef H5_NO_DEPRECATED_SYMBOLS
- H5A_ATTR_OP_APP, /* Application callback */
+ H5A_ATTR_OP_APP, /* Application callback */
#endif /* H5_NO_DEPRECATED_SYMBOLS */
- H5A_ATTR_OP_APP2, /* Revised application callback */
- H5A_ATTR_OP_LIB /* Library internal callback */
- } op_type;
+ H5A_ATTR_OP_APP2, /* Revised application callback */
+ H5A_ATTR_OP_LIB /* Library internal callback */
+} H5A_attr_iter_op_type_t;
+
+typedef struct H5A_attr_iter_op_t {
+ H5A_attr_iter_op_type_t op_type;
union {
#ifndef H5_NO_DEPRECATED_SYMBOLS
H5A_operator1_t app_op; /* Application callback for each attribute */
@@ -178,7 +179,7 @@ struct H5A_attr_iter_op_t {
H5A_operator2_t app_op2; /* Revised application callback for each attribute */
H5A_lib_iterate_t lib_op; /* Library internal callback for each attribute */
} u;
-};
+} H5A_attr_iter_op_t;
/*****************************/
@@ -218,8 +219,7 @@ H5_DLL H5A_t *H5A_copy(H5A_t *new_attr, const H5A_t *old_attr);
H5_DLL herr_t H5A_get_info(const H5A_t *attr, H5A_info_t *ainfo);
H5_DLL herr_t H5A_free(H5A_t *attr);
H5_DLL herr_t H5A_close(H5A_t *attr);
-H5_DLL H5O_ainfo_t *H5A_get_ainfo(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
- H5O_ainfo_t *ainfo);
+H5_DLL htri_t H5A_get_ainfo(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_ainfo_t *ainfo);
H5_DLL herr_t H5A_set_version(const H5F_t *f, H5A_t *attr);
/* Attribute "dense" storage routines */
@@ -279,6 +279,15 @@ H5_DLL htri_t H5O_attr_exists(const H5O_loc_t *loc, const char *name, hid_t dxpl
#ifndef H5_NO_DEPRECATED_SYMBOLS
H5_DLL int H5O_attr_count(const H5O_loc_t *loc, hid_t dxpl_id);
#endif /* H5_NO_DEPRECATED_SYMBOLS */
+H5_DLL H5A_t *H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_size,
+ H5O_copy_t *cpy_info, hid_t dxpl_id);
+H5_DLL herr_t H5A_attr_post_copy_file(const H5O_loc_t *src_oloc, const H5A_t *mesg_src,
+ H5O_loc_t *dst_oloc, const H5A_t *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info);
+H5_DLL herr_t H5A_dense_copy_file_all(H5F_t *file_src, H5O_ainfo_t *ainfo_src, H5F_t *file_dst,
+ const H5O_ainfo_t *ainfo_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, hid_t dxpl_id);
+H5_DLL herr_t H5A_dense_post_copy_file_all(const H5O_loc_t *src_oloc, const H5O_ainfo_t * ainfo_src,
+ H5O_loc_t *dst_oloc, H5O_ainfo_t *ainfo_dst, hid_t dxpl_id, H5O_copy_t *cpy_info);
+
/* Testing functions */
#ifdef H5A_TESTING
diff --git a/src/H5Aprivate.h b/src/H5Aprivate.h
index d46e46b..0c0e519 100644
--- a/src/H5Aprivate.h
+++ b/src/H5Aprivate.h
@@ -37,7 +37,6 @@
/* Forward references of package typedefs */
typedef struct H5A_t H5A_t;
-typedef struct H5A_attr_iter_op_t H5A_attr_iter_op_t;
/*****************************/
diff --git a/src/H5Apublic.h b/src/H5Apublic.h
index 3586bad..99ca90e 100644
--- a/src/H5Apublic.h
+++ b/src/H5Apublic.h
@@ -48,7 +48,7 @@ H5_DLL hid_t H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char
H5_DLL hid_t H5Aopen(hid_t obj_id, const char *attr_name, hid_t aapl_id);
H5_DLL hid_t H5Aopen_by_name(hid_t loc_id, const char *obj_name,
const char *attr_name, hid_t aapl_id, hid_t lapl_id);
-H5_DLL hid_t H5Aopen_by_idx(hid_t loc_id, const char *obj_name,
+H5_DLL hid_t H5Aopen_by_idx(hid_t loc_id, const char *obj_name,
H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t aapl_id,
hid_t lapl_id);
H5_DLL herr_t H5Awrite(hid_t attr_id, hid_t type_id, const void *buf);
@@ -86,7 +86,7 @@ H5_DLL htri_t H5Aexists_by_name(hid_t obj_id, const char *obj_name,
const char *attr_name, hid_t lapl_id);
/* Symbols defined for compatibility with previous versions of the HDF5 API.
- *
+ *
* Use of these symbols is deprecated.
*/
#ifndef H5_NO_DEPRECATED_SYMBOLS
diff --git a/src/H5Atest.c b/src/H5Atest.c
index de03a25..df88472 100644
--- a/src/H5Atest.c
+++ b/src/H5Atest.c
@@ -139,7 +139,7 @@ H5A_get_shared_rc_test(hid_t attr_id, hsize_t *ref_count)
HDassert(H5O_msg_is_shared(H5O_ATTR_ID, attr));
/* Retrieve ref count for shared or shareable attribute */
- if(H5SM_get_refcount(attr->shared->oloc.file, H5AC_ind_dxpl_id, H5O_ATTR_ID,
+ if(H5SM_get_refcount(attr->oloc.file, H5AC_ind_dxpl_id, H5O_ATTR_ID,
&attr->sh_loc, ref_count) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve shared message ref count")
diff --git a/src/H5B.c b/src/H5B.c
index 0eeaf89..8981e96 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -98,31 +98,28 @@
/****************/
#define H5B_PACKAGE /*suppress error about including H5Bpkg */
-#define H5F_PACKAGE /*suppress error about including H5Fpkg */
/***********/
/* Headers */
/***********/
#include "H5private.h" /* Generic Functions */
-#include "H5ACprivate.h" /* Metadata cache */
#include "H5Bpkg.h" /* B-link trees */
#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
-#include "H5Fpkg.h" /* File access */
#include "H5Iprivate.h" /* IDs */
#include "H5MFprivate.h" /* File memory management */
-#include "H5MMprivate.h" /* Memory management */
#include "H5Pprivate.h" /* Property lists */
+
/****************/
/* Local Macros */
/****************/
#define H5B_SIZEOF_HDR(F) \
- (H5B_SIZEOF_MAGIC + /*magic number */ \
+ (H5_SIZEOF_MAGIC + /*magic number */ \
4 + /*type, level, num entries */ \
2*H5F_SIZEOF_ADDR(F)) /*left and right sibling addresses */
-#define H5B_NKEY(b,shared,idx) ((b)->native+(shared)->nkey[(idx)])
+
/******************/
/* Local Typedefs */
@@ -153,10 +150,7 @@ static herr_t H5B_split(H5F_t *f, hid_t dxpl_id, H5B_t *old_bt,
unsigned *old_bt_flags, haddr_t old_addr,
unsigned idx, void *udata, haddr_t *new_addr/*out*/);
static H5B_t * H5B_copy(const H5B_t *old_bt);
-#ifdef H5B_DEBUG
-static herr_t H5B_assert(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type,
- void *udata);
-#endif
+
/*********************/
/* Package Variables */
@@ -171,10 +165,12 @@ H5FL_BLK_DEFINE(native_block);
/* Declare a free list to manage the H5B_t struct */
H5FL_DEFINE(H5B_t);
+
/*****************************/
/* Library Private Variables */
/*****************************/
+
/*******************/
/* Local Variables */
/*******************/
@@ -294,9 +290,9 @@ done:
* pointers since it assumes that all nodes can be reached
* from the parent node.
*
- * Return: Non-negative on success (if found, values returned through the
- * UDATA argument). Negative on failure (if not found, UDATA is
- * undefined).
+ * Return: Non-negative (TRUE/FALSE) on success (if found, values returned
+ * through the UDATA argument). Negative on failure (if not found,
+ * UDATA is undefined).
*
* Programmer: Robb Matzke
* matzke@llnl.gov
@@ -307,85 +303,62 @@ done:
* The ADDR argument is passed by value.
*-------------------------------------------------------------------------
*/
-herr_t
+htri_t
H5B_find(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, void *udata)
{
H5B_t *bt = NULL;
- H5B_shared_t *shared; /* Pointer to shared B-tree info */
- unsigned idx=0, lt = 0, rt; /* Final, left & right key indices */
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
+ unsigned idx = 0, lt = 0, rt; /* Final, left & right key indices */
int cmp = 1; /* Key comparison value */
- int ret_value = SUCCEED; /* Return value */
+ htri_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5B_find, FAIL)
/*
* Check arguments.
*/
- assert(f);
- assert(type);
- assert(type->decode);
- assert(type->cmp3);
- assert(type->found);
- assert(H5F_addr_defined(addr));
+ HDassert(f);
+ HDassert(type);
+ HDassert(type->decode);
+ HDassert(type->cmp3);
+ HDassert(type->found);
+ HDassert(H5F_addr_defined(addr));
/*
* Perform a binary search to locate the child which contains
* the thing for which we're searching.
*/
- if (NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_READ)))
+ if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree node")
- shared=(H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
+ shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
HDassert(shared);
- rt = bt->nchildren;
- while (lt < rt && cmp) {
+ rt = bt->nchildren;
+ while(lt < rt && cmp) {
idx = (lt + rt) / 2;
/* compare */
- if ((cmp = (type->cmp3)(f, dxpl_id, H5B_NKEY(bt,shared,idx), udata, H5B_NKEY(bt,shared,idx+1))) < 0) {
+ if((cmp = (type->cmp3)(f, dxpl_id, H5B_NKEY(bt, shared, idx), udata, H5B_NKEY(bt, shared, (idx + 1)))) < 0)
rt = idx;
- } else {
- lt = idx+1;
- }
- }
- if (cmp)
- /* Note: don't push error on stack, leave that to next higher level,
- * since many times the B-tree is searched in order to determine
- * if an object exists in the B-tree or not. -QAK
- */
-#ifdef OLD_WAY
- HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "B-tree key not found")
-#else /* OLD_WAY */
- HGOTO_DONE(FAIL)
-#endif /* OLD_WAY */
+ else
+ lt = idx + 1;
+ } /* end while */
+ /* Check if not found */
+ if(cmp)
+ HGOTO_DONE(FALSE)
/*
* Follow the link to the subtree or to the data node.
*/
assert(idx < bt->nchildren);
- if (bt->level > 0) {
- if (H5B_find(f, dxpl_id, type, bt->child[idx], udata) < 0)
- /* Note: don't push error on stack, leave that to next higher level,
- * since many times the B-tree is searched in order to determine
- * if an object exists in the B-tree or not. -QAK
- */
-#ifdef OLD_WAY
- HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "key not found in subtree")
-#else /* OLD_WAY */
- HGOTO_DONE(FAIL)
-#endif /* OLD_WAY */
- } else {
- if ((type->found) (f, dxpl_id, bt->child[idx], H5B_NKEY(bt,shared,idx), udata) < 0)
- /* Note: don't push error on stack, leave that to next higher level,
- * since many times the B-tree is searched in order to determine
- * if an object exists in the B-tree or not. -QAK
- */
-#ifdef OLD_WAY
- HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "key not found in leaf node")
-#else /* OLD_WAY */
- HGOTO_DONE(FAIL)
-#endif /* OLD_WAY */
- }
+ if(bt->level > 0) {
+ if((ret_value = H5B_find(f, dxpl_id, type, bt->child[idx], udata)) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "can't lookup key in subtree")
+ } /* end if */
+ else {
+ if((ret_value = (type->found)(f, dxpl_id, bt->child[idx], H5B_NKEY(bt, shared, idx), udata)) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "can't lookup key in leaf node")
+ } /* end else */
done:
if(bt && H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0)
@@ -1308,7 +1281,7 @@ H5B_iterate(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr,
{
herr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5B_iterate, FAIL)
+ FUNC_ENTER_NOAPI_NOERR(H5B_iterate, -)
/*
* Check arguments.
@@ -1522,16 +1495,14 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
bt->left = HADDR_UNDEF;
bt->right = HADDR_UNDEF;
H5_CHECK_OVERFLOW(shared->sizeof_rnode,size_t,hsize_t);
- if (H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)shared->sizeof_rnode)<0
- || H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, bt_flags | H5C__DELETED_FLAG) < 0) {
+ if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, bt_flags | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) {
bt = NULL;
bt_flags = H5AC__NO_FLAGS_SET;
HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, H5B_INS_ERROR, "unable to free B-tree node")
- }
+ } /* end if */
bt = NULL;
bt_flags = H5AC__NO_FLAGS_SET;
- }
-
+ } /* end if */
} else if (H5B_INS_REMOVE==ret_value && 0==idx) {
/*
* The subtree is the left-most child of this node. We discard the
@@ -1754,12 +1725,8 @@ H5B_delete(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, void
} /* end if */
} /* end else */
- /* Delete this node from disk */
- if (H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)shared->sizeof_rnode)<0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free B-tree node")
-
done:
- if(bt && H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5C__DELETED_FLAG) < 0)
+ if(bt && H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0)
HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node in cache")
FUNC_LEAVE_NOAPI(ret_value)
@@ -1783,7 +1750,7 @@ done:
H5B_shared_t *
H5B_shared_new(const H5F_t *f, const H5B_class_t *type, size_t sizeof_rkey)
{
- H5B_shared_t *shared; /* New shared B-tree struct */
+ H5B_shared_t *shared = NULL; /* New shared B-tree struct */
size_t u; /* Local index variable */
H5B_shared_t *ret_value; /* Return value */
@@ -1795,8 +1762,8 @@ H5B_shared_new(const H5F_t *f, const H5B_class_t *type, size_t sizeof_rkey)
HDassert(type);
/* Allocate space for the shared structure */
- if(NULL == (shared = H5FL_MALLOC(H5B_shared_t)))
- HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "memory allocation failed for shared B-tree info")
+ if(NULL == (shared = H5FL_CALLOC(H5B_shared_t)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "memory allocation failed for shared B-tree info")
/* Set up the "global" information for this file's groups */
shared->type = type;
@@ -1811,21 +1778,30 @@ H5B_shared_new(const H5F_t *f, const H5B_class_t *type, size_t sizeof_rkey)
/* Allocate shared buffers */
if(NULL == (shared->page = H5FL_BLK_MALLOC(page, shared->sizeof_rnode)))
- HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree page")
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "memory allocation failed for B-tree page")
#ifdef H5_CLEAR_MEMORY
HDmemset(shared->page, 0, shared->sizeof_rnode);
#endif /* H5_CLEAR_MEMORY */
- if(NULL == (shared->nkey = H5FL_SEQ_MALLOC(size_t, (size_t)(2 * H5F_KVALUE(f, type) + 1))))
- HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree page")
+ if(NULL == (shared->nkey = H5FL_SEQ_MALLOC(size_t, (size_t)(shared->two_k + 1))))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "memory allocation failed for B-tree native keys")
/* Initialize the offsets into the native key buffer */
- for(u = 0; u < (2 * H5F_KVALUE(f, type) + 1); u++)
+ for(u = 0; u < (shared->two_k + 1); u++)
shared->nkey[u] = u * type->sizeof_nkey;
/* Set return value */
ret_value = shared;
done:
+ if(NULL == ret_value)
+ if(shared) {
+ if(shared->page)
+ shared->page = H5FL_BLK_FREE(page, shared->page);
+ if(shared->nkey)
+ shared->nkey = H5FL_SEQ_FREE(size_t, shared->nkey);
+ shared = H5FL_FREE(H5B_shared_t, shared);
+ } /* end if */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B_shared_new() */
@@ -1891,13 +1867,13 @@ H5B_copy(const H5B_t *old_bt)
/*
* Check arguments.
*/
- assert(old_bt);
- shared=(H5B_shared_t *)H5RC_GET_OBJ(old_bt->rc_shared);
+ HDassert(old_bt);
+ shared = (H5B_shared_t *)H5RC_GET_OBJ(old_bt->rc_shared);
HDassert(shared);
/* Allocate memory for the new H5B_t object */
- if (NULL==(new_node = H5FL_MALLOC(H5B_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree root node")
+ if(NULL == (new_node = H5FL_MALLOC(H5B_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree root node")
/* Copy the main structure */
HDmemcpy(new_node, old_bt, sizeof(H5B_t));
@@ -1905,22 +1881,22 @@ H5B_copy(const H5B_t *old_bt)
/* Reset cache info */
HDmemset(&new_node->cache_info, 0, sizeof(H5AC_info_t));
- if ( NULL==(new_node->native=H5FL_BLK_MALLOC(native_block,shared->sizeof_keys)) ||
- NULL==(new_node->child=H5FL_SEQ_MALLOC(haddr_t,(size_t)shared->two_k)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree root node")
+ if(NULL == (new_node->native = H5FL_BLK_MALLOC(native_block, shared->sizeof_keys)) ||
+ NULL == (new_node->child = H5FL_SEQ_MALLOC(haddr_t, (size_t)shared->two_k)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree root node")
/* Copy the other structures */
- HDmemcpy(new_node->native,old_bt->native,shared->sizeof_keys);
- HDmemcpy(new_node->child,old_bt->child,(sizeof(haddr_t)*shared->two_k));
+ HDmemcpy(new_node->native, old_bt->native, shared->sizeof_keys);
+ HDmemcpy(new_node->child, old_bt->child, (sizeof(haddr_t) * shared->two_k));
/* Increment the ref-count on the raw page */
H5RC_INC(new_node->rc_shared);
/* Set return value */
- ret_value=new_node;
+ ret_value = new_node;
done:
- if(ret_value==NULL) {
+ if(NULL == ret_value) {
if(new_node) {
new_node->native = H5FL_BLK_FREE(native_block, new_node->native);
new_node->child = H5FL_SEQ_FREE(haddr_t, new_node->child);
@@ -1929,7 +1905,7 @@ done:
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5B_copy */
+} /* end H5B_copy() */
/*-------------------------------------------------------------------------
@@ -2085,246 +2061,43 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5B_debug
+ * Function: H5B_valid
*
- * Purpose: Prints debugging info about a B-tree.
+ * Purpose: Attempt to load a b-tree node.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 4 1997
+ * Programmer: Neil Fortner
+ * March 17, 2009
*
- * Modifications:
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
*-------------------------------------------------------------------------
*/
-herr_t
-H5B_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth,
- const H5B_class_t *type, void *udata)
+htri_t
+H5B_valid(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr)
{
- H5B_t *bt = NULL;
- H5B_shared_t *shared; /* Pointer to shared B-tree info */
- unsigned u; /* Local index variable */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5B_t *bt = NULL; /* The btree */
+ htri_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5B_debug, FAIL)
+ FUNC_ENTER_NOAPI(H5B_valid, FAIL)
/*
* Check arguments.
*/
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(stream);
- assert(indent >= 0);
- assert(fwidth >= 0);
- assert(type);
-
- /*
- * Load the tree node.
- */
- if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree node")
- shared=(H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
- HDassert(shared);
+ HDassert(f);
+ HDassert(type);
- /*
- * Print the values.
- */
- HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
- "Tree type ID:",
- ((shared->type->id)==H5B_SNODE_ID ? "H5B_SNODE_ID" :
- ((shared->type->id)==H5B_ISTORE_ID ? "H5B_ISTORE_ID" : "Unknown!")));
- HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
- "Size of node:",
- shared->sizeof_rnode);
- HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
- "Size of raw (disk) key:",
- shared->sizeof_rkey);
- HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
- "Dirty flag:",
- bt->cache_info.is_dirty ? "True" : "False");
- HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Level:",
- bt->level);
-
- HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
- "Address of left sibling:",
- bt->left);
-
- HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
- "Address of right sibling:",
- bt->right);
-
- HDfprintf(stream, "%*s%-*s %u (%u)\n", indent, "", fwidth,
- "Number of children (max):",
- bt->nchildren, shared->two_k);
+ if(!H5F_addr_defined(addr))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "address is undefined")
- /*
- * Print the child addresses
- */
- for (u = 0; u < bt->nchildren; u++) {
- HDfprintf(stream, "%*sChild %d...\n", indent, "", u);
- HDfprintf(stream, "%*s%-*s %a\n", indent + 3, "", MAX(0, fwidth - 3),
- "Address:", bt->child[u]);
-
- /* If there is a key debugging routine, use it to display the left & right keys */
- if (type->debug_key) {
- /* Decode the 'left' key & print it */
- HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
- "Left Key:");
- assert(H5B_NKEY(bt,shared,u));
- (void)(type->debug_key)(stream, f, dxpl_id, indent+6, MAX (0, fwidth-6),
- H5B_NKEY(bt,shared,u), udata);
-
- /* Decode the 'right' key & print it */
- HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
- "Right Key:");
- assert(H5B_NKEY(bt,shared,u+1));
- (void)(type->debug_key)(stream, f, dxpl_id, indent+6, MAX (0, fwidth-6),
- H5B_NKEY(bt,shared,u+1), udata);
- }
- }
+ /* Protect the node */
+ if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree node")
done:
+ /* Release the node */
if(bt && H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node")
-
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5B_assert
- *
- * Purpose: Verifies that the tree is structured correctly.
- *
- * Return: Success: SUCCEED
- *
- * Failure: aborts if something is wrong.
- *
- * Programmer: Robb Matzke
- * Tuesday, November 4, 1997
- *
- * Modifications:
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
- *
- * John Mainzer, 6/8/05
- * Modified the function to use the new dirtied parameter of
- * of H5AC_unprotect() instead of modifying the is_dirty
- * field of the cache info.
- *
- *-------------------------------------------------------------------------
- */
-#ifdef H5B_DEBUG
-static herr_t
-H5B_assert(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type, void *udata)
-{
- H5B_t *bt = NULL;
- H5B_shared_t *shared; /* Pointer to shared B-tree info */
- int i, ncell, cmp;
- static int ncalls = 0;
- herr_t status;
- herr_t ret_value=SUCCEED; /* Return value */
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
- /* A queue of child data */
- struct child_t {
- haddr_t addr;
- unsigned level;
- struct child_t *next;
- } *head = NULL, *tail = NULL, *prev = NULL, *cur = NULL, *tmp = NULL;
-
- FUNC_ENTER_NOAPI(H5B_assert, FAIL)
-
- if (0==ncalls++) {
- if (H5DEBUG(B)) {
- fprintf(H5DEBUG(B), "H5B: debugging B-trees (expensive)\n");
- }
- }
- /* Initialize the queue */
- bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_READ);
- assert(bt);
- shared=(H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
- HDassert(shared);
- cur = H5MM_calloc(sizeof(struct child_t));
- assert (cur);
- cur->addr = addr;
- cur->level = bt->level;
- head = tail = cur;
-
- status = H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET);
- assert(status >= 0);
- bt=NULL; /* Make certain future references will be caught */
-
- /*
- * Do a breadth-first search of the tree. New nodes are added to the end
- * of the queue as the `cur' pointer is advanced toward the end. We don't
- * remove any nodes from the queue because we need them in the uniqueness
- * test.
- */
- for (ncell = 0; cur; ncell++) {
- bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, cur->addr, type, udata, H5AC_READ);
- assert(bt);
-
- /* Check node header */
- assert(bt->level == cur->level);
- if (cur->next && cur->next->level == bt->level) {
- assert(H5F_addr_eq(bt->right, cur->next->addr));
- } else {
- assert(!H5F_addr_defined(bt->right));
- }
- if (prev && prev->level == bt->level) {
- assert(H5F_addr_eq(bt->left, prev->addr));
- } else {
- assert(!H5F_addr_defined(bt->left));
- }
-
- if (cur->level > 0) {
- for (i = 0; i < bt->nchildren; i++) {
-
- /*
- * Check that child nodes haven't already been seen. If they
- * have then the tree has a cycle.
- */
- for (tmp = head; tmp; tmp = tmp->next) {
- assert(H5F_addr_ne(tmp->addr, bt->child[i]));
- }
-
- /* Add the child node to the end of the queue */
- tmp = H5MM_calloc(sizeof(struct child_t));
- assert (tmp);
- tmp->addr = bt->child[i];
- tmp->level = bt->level - 1;
- tail->next = tmp;
- tail = tmp;
-
- /* Check that the keys are monotonically increasing */
- cmp = (type->cmp2)(f, dxpl_id, H5B_NKEY(bt,shared,i), udata,
- H5B_NKEY(bt,shared,i+1));
- assert(cmp < 0);
- }
- }
- /* Release node */
- status = H5AC_unprotect(f, dxpl_id, H5AC_BT, cur->addr, bt, H5AC__NO_FLAGS_SET);
- assert(status >= 0);
- bt=NULL; /* Make certain future references will be caught */
-
- /* Advance current location in queue */
- prev = cur;
- cur = cur->next;
- }
-
- /* Free all entries from queue */
- while (head) {
- tmp = head->next;
- H5MM_xfree(head);
- head = tmp;
- }
-
-done:
FUNC_LEAVE_NOAPI(ret_value)
-}
-#endif /* H5B_DEBUG */
+} /* end H5B_valid() */
diff --git a/src/H5B2.c b/src/H5B2.c
index 070d3b3..5ab9e8a 100644
--- a/src/H5B2.c
+++ b/src/H5B2.c
@@ -41,7 +41,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5B2pkg.h" /* v2 B-trees */
#include "H5Eprivate.h" /* Error handling */
-#include "H5MFprivate.h" /* File memory management */
+
/****************/
/* Local Macros */
@@ -67,8 +67,35 @@
/* Package Variables */
/*********************/
-/* Declare a free list to manage the H5B2_t struct */
-H5FL_DEFINE(H5B2_t);
+/* v2 B-tree client ID to class mapping */
+
+/* Remember to add client ID to H5B2_subid_t in H5B2private.h when adding a new
+ * client class..
+ */
+extern const H5B2_class_t H5B2_TEST[1];
+extern const H5B2_class_t H5HF_HUGE_BT2_INDIR[1];
+extern const H5B2_class_t H5HF_HUGE_BT2_FILT_INDIR[1];
+extern const H5B2_class_t H5HF_HUGE_BT2_DIR[1];
+extern const H5B2_class_t H5HF_HUGE_BT2_FILT_DIR[1];
+extern const H5B2_class_t H5G_BT2_NAME[1];
+extern const H5B2_class_t H5G_BT2_CORDER[1];
+extern const H5B2_class_t H5SM_INDEX[1];
+extern const H5B2_class_t H5A_BT2_NAME[1];
+extern const H5B2_class_t H5A_BT2_CORDER[1];
+
+const H5B2_class_t *const H5B2_client_class_g[] = {
+ H5B2_TEST, /* 0 - H5B2_TEST_ID */
+ H5HF_HUGE_BT2_INDIR, /* 1 - H5B2_FHEAP_HUGE_INDIR_ID */
+ H5HF_HUGE_BT2_FILT_INDIR, /* 2 - H5B2_FHEAP_HUGE_FILT_INDIR_ID */
+ H5HF_HUGE_BT2_DIR, /* 3 - H5B2_FHEAP_HUGE_DIR_ID */
+ H5HF_HUGE_BT2_FILT_DIR, /* 4 - H5B2_FHEAP_HUGE_FILT_DIR_ID */
+ H5G_BT2_NAME, /* 5 - H5B2_GRP_DENSE_NAME_ID */
+ H5G_BT2_CORDER, /* 6 - H5B2_GRP_DENSE_CORDER_ID */
+ H5SM_INDEX, /* 7 - H5B2_SOHM_INDEX_ID */
+ H5A_BT2_NAME, /* 8 - H5B2_ATTR_DENSE_NAME_ID */
+ H5A_BT2_CORDER, /* 9 - H5B2_ATTR_DENSE_CORDER_ID */
+};
+
/*****************************/
/* Library Private Variables */
@@ -79,6 +106,10 @@ H5FL_DEFINE(H5B2_t);
/* Local Variables */
/*******************/
+/* Declare a free list to manage the H5B2_t struct */
+H5FL_DEFINE_STATIC(H5B2_t);
+
+
/*-------------------------------------------------------------------------
* Function: H5B2_create
@@ -94,63 +125,129 @@ H5FL_DEFINE(H5B2_t);
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- size_t node_size, size_t rrec_size,
- unsigned split_percent, unsigned merge_percent, haddr_t *addr_p)
+H5B2_t *
+H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam, void *ctx_udata)
{
- H5B2_t *bt2 = NULL; /* The new B-tree header information */
- herr_t ret_value = SUCCEED;
+ H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
+ H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
+ haddr_t hdr_addr; /* B-tree header address */
+ H5B2_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5B2_create, FAIL)
+ FUNC_ENTER_NOAPI(H5B2_create, NULL)
/*
* Check arguments.
*/
HDassert(f);
- HDassert(type);
- HDassert(node_size > 0);
- HDassert(rrec_size > 0);
- HDassert(merge_percent > 0 && merge_percent <= 100);
- HDassert(split_percent > 0 && split_percent <= 100);
- HDassert(merge_percent < (split_percent / 2));
- HDassert(addr_p);
+ HDassert(cparam);
- /*
- * Allocate file and memory data structures.
- */
+ /* H5B2 interface sanity check */
+ HDcompile_assert(H5B2_NUM_BTREE_ID == NELMTS(H5B2_client_class_g));
+
+ /* Create shared v2 B-tree header */
+ if(HADDR_UNDEF == (hdr_addr = H5B2_hdr_create(f, dxpl_id, cparam, ctx_udata)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, NULL, "can't create v2 B-tree header")
+
+ /* Create v2 B-tree wrapper */
if(NULL == (bt2 = H5FL_MALLOC(H5B2_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree header")
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "memory allocation failed for v2 B-tree info")
+
+ /* Look up the B-tree header */
+ if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, NULL, ctx_udata, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, NULL, "unable to load B-tree header")
- /* Assign internal information */
- HDmemset(&bt2->cache_info, 0, sizeof(H5AC_info_t));
- bt2->root.addr = HADDR_UNDEF;
- bt2->root.node_nrec = 0;
- bt2->root.all_nrec = 0;
+ /* Point v2 B-tree wrapper at header and bump it's ref count */
+ bt2->hdr = hdr;
+ if(H5B2_hdr_incr(bt2->hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment reference count on shared v2 B-tree header")
- /* Initialize shared B-tree info */
- if(H5B2_shared_init(f, bt2, type, 0, node_size, rrec_size, split_percent, merge_percent) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create shared B-tree info")
+ /* Increment # of files using this v2 B-tree header */
+ if(H5B2_hdr_fuse_incr(bt2->hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment file reference count on shared v2 B-tree header")
- /* Allocate space for the header on disk */
- if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)H5B2_HEADER_SIZE(f))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree header")
+ /* Set file pointer for this v2 B-tree open context */
+ bt2->f = f;
- /* Cache the new B-tree node */
- if(H5AC_set(f, dxpl_id, H5AC_BT2_HDR, *addr_p, bt2, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't add B-tree header to cache")
+ /* Set the return value */
+ ret_value = bt2;
done:
- if(ret_value < 0) {
- if(bt2)
- (void)H5B2_cache_hdr_dest(f, bt2);
- } /* end if */
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, NULL, "unable to release v2 B-tree header")
+ if(!ret_value && bt2)
+ if(H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, NULL, "unable to close v2 B-tree")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B2_create() */
/*-------------------------------------------------------------------------
+ * Function: H5B2_open
+ *
+ * Purpose: Opens an existing v2 B-tree in the file.
+ *
+ * Return: Pointer to v2 B-tree wrapper on success
+ * NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 15 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+H5B2_t *
+H5B2_open(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *ctx_udata)
+{
+ H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
+ H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
+ H5B2_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_open)
+
+ /* Check arguments. */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+
+ /* Look up the B-tree header */
+ if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, NULL, ctx_udata, H5AC_READ)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, NULL, "unable to load B-tree header")
+
+ /* Check for pending heap deletion */
+ if(hdr->pending_delete)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, NULL, "can't open v2 B-tree pending deletion")
+
+ /* Create v2 B-tree info */
+ if(NULL == (bt2 = H5FL_MALLOC(H5B2_t)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "memory allocation failed for v2 B-tree info")
+
+ /* Point v2 B-tree wrapper at header */
+ bt2->hdr = hdr;
+ if(H5B2_hdr_incr(bt2->hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment reference count on shared v2 B-tree header")
+
+ /* Increment # of files using this v2 B-tree header */
+ if(H5B2_hdr_fuse_incr(bt2->hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment file reference count on shared v2 B-tree header")
+
+ /* Set file pointer for this v2 B-tree open context */
+ bt2->f = f;
+
+ /* Set the return value */
+ ret_value = bt2;
+
+done:
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, NULL, "unable to release v2 B-tree header")
+ if(!ret_value && bt2)
+ if(H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, NULL, "unable to close v2 B-tree")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5B2_open() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5B2_insert
*
* Purpose: Adds a new record to the B-tree.
@@ -164,68 +261,87 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_insert(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- void *udata)
+H5B2_insert(H5B2_t *bt2, hid_t dxpl_id, void *udata)
{
- H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */
- unsigned bt2_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for B-tree header */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- herr_t ret_value = SUCCEED;
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_insert, FAIL)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
+ HDassert(bt2);
+ HDassert(udata);
- /* Look up the b-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Check if the root node is allocated yet */
- if(!H5F_addr_defined(bt2->root.addr)) {
+ if(!H5F_addr_defined(hdr->root.addr)) {
/* Create root node as leaf node in B-tree */
- if(H5B2_create_leaf(f, dxpl_id, bt2->shared, &(bt2->root)) < 0)
+ if(H5B2_create_leaf(hdr, dxpl_id, &(hdr->root)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to create root node")
-
- /* Mark B-tree header as dirty, since we updated the address of the root node */
- bt2_flags |= H5AC__DIRTIED_FLAG;
} /* end if */
/* Check if we need to split the root node (equiv. to a 1->2 node split) */
- else if(bt2->root.node_nrec == shared->node_info[shared->depth].split_nrec) {
+ else if(hdr->root.node_nrec == hdr->node_info[hdr->depth].split_nrec) {
/* Split root node */
- if(H5B2_split_root(f, dxpl_id, bt2, &bt2_flags) < 0)
+ if(H5B2_split_root(hdr, dxpl_id) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to split root node")
} /* end if */
/* Attempt to insert record into B-tree */
- if(shared->depth > 0) {
- if(H5B2_insert_internal(f, dxpl_id, bt2->shared, shared->depth, &bt2_flags, &bt2->root, udata) < 0)
+ if(hdr->depth > 0) {
+ if(H5B2_insert_internal(hdr, dxpl_id, hdr->depth, NULL, &hdr->root, udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree internal node")
} /* end if */
else {
- if(H5B2_insert_leaf(f, dxpl_id, bt2->shared, &bt2->root, udata) < 0)
+ if(H5B2_insert_leaf(hdr, dxpl_id, &hdr->root, udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree leaf node")
} /* end else */
- /* Mark parent node as dirty */
- bt2_flags |= H5AC__DIRTIED_FLAG;
+ /* Mark B-tree header as dirty */
+ if(H5B2_hdr_dirty(hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTMARKDIRTY, FAIL, "unable to mark B-tree header dirty")
done:
- /* Release the B-tree header info */
- if(bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, bt2_flags) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_insert() */
/*-------------------------------------------------------------------------
+ * Function: H5B2_get_addr
+ *
+ * Purpose: Get the address of a v2 B-tree
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Nov 5 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_get_addr(const H5B2_t *bt2, haddr_t *addr_p)
+{
+ FUNC_ENTER_NOAPI_NOFUNC(H5B2_get_addr)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(bt2);
+ HDassert(addr_p);
+
+ /* Retrieve the header address for this v2 B-tree */
+ *addr_p = bt2->hdr->addr;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5B2_get_addr() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5B2_iterate
*
* Purpose: Iterate over all the records in the B-tree, in "in-order"
@@ -243,61 +359,30 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_iterate(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- H5B2_operator_t op, void *op_data)
+H5B2_iterate(H5B2_t *bt2, hid_t dxpl_id, H5B2_operator_t op, void *op_data)
{
- H5B2_t *bt2=NULL; /* Pointer to the B-tree header */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- H5RC_t *bt2_shared=NULL; /* Pointer to ref-counter for shared B-tree info */
- hbool_t incr_rc=FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */
- H5B2_node_ptr_t root_ptr; /* Node pointer info for root node */
- unsigned depth; /* Current depth of the tree */
- herr_t ret_value = SUCCEED;
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5B2_iterate, FAIL)
+ FUNC_ENTER_NOAPI_NOERR(H5B2_iterate, -)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
+ HDassert(bt2);
HDassert(op);
- /* Look up the B-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
-
- /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */
- bt2_shared = bt2->shared;
- H5RC_INC(bt2_shared);
- incr_rc = TRUE;
-
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
-
- /* Make copy of the root node pointer */
- root_ptr = bt2->root;
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Current depth of the tree */
- depth = shared->depth;
-
- /* Release header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
- bt2 = NULL;
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Iterate through records */
- if(root_ptr.node_nrec > 0) {
+ if(hdr->root.node_nrec > 0) {
/* Iterate through nodes */
- if((ret_value = H5B2_iterate_node(f, dxpl_id, bt2_shared, depth, &root_ptr, op, op_data)) < 0)
+ if((ret_value = H5B2_iterate_node(hdr, dxpl_id, hdr->depth, &hdr->root, op, op_data)) < 0)
HERROR(H5E_BTREE, H5E_CANTLIST, "node iteration failed");
} /* end if */
-done:
- /* Check if we need to decrement the reference count for the B-tree's shared info */
- if(incr_rc)
- H5RC_DEC(bt2_shared);
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_iterate() */
@@ -314,10 +399,10 @@ done:
* OP_DATA pointer, to allow caller to return information about
* the record.
*
- * If 'OP' is NULL, then this routine just returns "SUCCEED" when
+ * If 'OP' is NULL, then this routine just returns "TRUE" when
* a record is present in the B-tree.
*
- * Return: Non-negative on success, negative on failure.
+ * Return: Non-negative (TRUE/FALSE) on success, negative on failure.
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
@@ -325,54 +410,37 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- void *udata, H5B2_found_t op, void *op_data)
+htri_t
+H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
+ void *op_data)
{
- H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */
- H5RC_t *bt2_shared = NULL; /* Pointer to ref-counter for shared B-tree info */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- hbool_t incr_rc = FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */
unsigned depth; /* Current depth of the tree */
int cmp; /* Comparison value of records */
unsigned idx; /* Location of record which matches key */
- herr_t ret_value = SUCCEED;
+ htri_t ret_value = TRUE; /* Return value */
FUNC_ENTER_NOAPI(H5B2_find, FAIL)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
-
- /* Look up the B-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
+ HDassert(bt2);
- /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */
- bt2_shared = bt2->shared;
- H5RC_INC(bt2_shared);
- incr_rc = TRUE;
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Make copy of the root node pointer to start search with */
- curr_node_ptr = bt2->root;
+ curr_node_ptr = hdr->root;
/* Current depth of the tree */
- depth = shared->depth;
-
- /* Release header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
- bt2 = NULL;
+ depth = hdr->depth;
/* Check for empty tree */
if(curr_node_ptr.node_nrec == 0)
- HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "B-tree has no records")
+ HGOTO_DONE(FALSE)
/* Walk down B-tree to find record or leaf node where record is located */
cmp = -1;
@@ -381,11 +449,11 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
H5B2_node_ptr_t next_node_ptr; /* Node pointer info for next node */
/* Lock B-tree current node */
- if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_READ)))
+ if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Locate node pointer for child */
- cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx);
+ cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx);
if(cmp > 0)
idx++;
@@ -394,7 +462,7 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
next_node_ptr=internal->node_ptrs[idx];
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
/* Set pointer to next node to load */
@@ -402,19 +470,20 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
} /* end if */
else {
/* Make callback for current record */
- if(op && (op)(H5B2_INT_NREC(internal, shared, idx), op_data) < 0) {
+ if(op && (op)(H5B2_INT_NREC(internal, hdr, idx), op_data) < 0) {
/* Unlock current node */
- if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation")
} /* end if */
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
- HGOTO_DONE(SUCCEED);
+ /* Indicate record found */
+ HGOTO_DONE(TRUE)
} /* end else */
/* Decrement depth we're at in B-tree */
@@ -425,32 +494,25 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
H5B2_leaf_t *leaf; /* Pointer to leaf node in B-tree */
/* Lock B-tree leaf node */
- if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), bt2_shared, H5AC_READ)))
+ if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), hdr, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Locate record */
- cmp = H5B2_locate_record(shared->type, leaf->nrec, shared->nat_off, leaf->leaf_native, udata, &idx);
+ cmp = H5B2_locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx);
if(cmp != 0) {
/* Unlock leaf node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
- /* Note: don't push error on stack, leave that to next higher level,
- * since many times the B-tree is searched in order to determine
- * if an object exists in the B-tree or not. -QAK
- */
-#ifdef OLD_WAY
- HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "key not found in leaf node")
-#else /* OLD_WAY */
- HGOTO_DONE(FAIL)
-#endif /* OLD_WAY */
+ /* Record not found */
+ HGOTO_DONE(FALSE)
} /* end if */
else {
/* Make callback for current record */
- if(op && (op)(H5B2_LEAF_NREC(leaf, shared, idx), op_data) < 0) {
+ if(op && (op)(H5B2_LEAF_NREC(leaf, hdr, idx), op_data) < 0) {
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation")
@@ -458,15 +520,11 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
} /* end else */
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
} /* end block */
done:
- /* Check if we need to decrement the reference count for the B-tree's shared info */
- if(incr_rc)
- H5RC_DEC(bt2_shared);
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_find() */
@@ -490,48 +548,31 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- H5_iter_order_t order, hsize_t idx, H5B2_found_t op, void *op_data)
+H5B2_index(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order, hsize_t idx,
+ H5B2_found_t op, void *op_data)
{
- H5B2_t *bt2=NULL; /* Pointer to the B-tree header */
- H5RC_t *bt2_shared=NULL; /* Pointer to ref-counter for shared B-tree info */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- hbool_t incr_rc=FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */
unsigned depth; /* Current depth of the tree */
- herr_t ret_value = SUCCEED;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_index, FAIL)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
+ HDassert(bt2);
HDassert(op);
- /* Look up the B-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
-
- /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */
- bt2_shared = bt2->shared;
- H5RC_INC(bt2_shared);
- incr_rc = TRUE;
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Make copy of the root node pointer to start search with */
- curr_node_ptr = bt2->root;
+ curr_node_ptr = hdr->root;
/* Current depth of the tree */
- depth = shared->depth;
-
- /* Release header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
- bt2 = NULL;
+ depth = hdr->depth;
/* Check for empty tree */
if(curr_node_ptr.node_nrec == 0)
@@ -552,7 +593,7 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
unsigned u; /* Local index variable */
/* Lock B-tree current node */
- if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_READ)))
+ if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Search for record with correct index */
@@ -563,7 +604,7 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
next_node_ptr = internal->node_ptrs[u];
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
/* Set pointer to next node to load */
@@ -576,16 +617,16 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
/* Check if record is in this node */
if(internal->node_ptrs[u].all_nrec == idx) {
/* Make callback for current record */
- if((op)(H5B2_INT_NREC(internal, shared, u), op_data) < 0) {
+ if((op)(H5B2_INT_NREC(internal, hdr, u), op_data) < 0) {
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation")
} /* end if */
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
HGOTO_DONE(SUCCEED);
@@ -605,7 +646,7 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
next_node_ptr = internal->node_ptrs[u];
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
/* Set pointer to next node to load */
@@ -624,31 +665,27 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
H5B2_leaf_t *leaf; /* Pointer to leaf node in B-tree */
/* Lock B-tree leaf node */
- if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), bt2_shared, H5AC_READ)))
+ if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), hdr, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Sanity check index */
HDassert(idx < leaf->nrec);
/* Make callback for correct record */
- if((op)(H5B2_LEAF_NREC(leaf, shared, idx), op_data) < 0) {
+ if((op)(H5B2_LEAF_NREC(leaf, hdr, idx), op_data) < 0) {
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation")
} /* end if */
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
} /* end block */
done:
- /* Check if we need to decrement the reference count for the B-tree's shared info */
- if(incr_rc)
- H5RC_DEC(bt2_shared);
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_index() */
@@ -667,70 +704,61 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_remove(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- void *udata, H5B2_remove_t op, void *op_data)
+H5B2_remove(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_remove_t op,
+ void *op_data)
{
- H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */
- unsigned bt2_flags = H5AC__NO_FLAGS_SET;
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- herr_t ret_value = SUCCEED;
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_remove, FAIL)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
+ HDassert(bt2);
- /* Look up the b-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Check for empty B-tree */
- if(bt2->root.all_nrec == 0)
+ if(0 == hdr->root.all_nrec)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "record is not in B-tree")
/* Attempt to remove record from B-tree */
- if(shared->depth > 0) {
+ if(hdr->depth > 0) {
hbool_t depth_decreased = FALSE; /* Flag to indicate whether the depth of the B-tree decreased */
- if(H5B2_remove_internal(f, dxpl_id, bt2->shared, &depth_decreased, NULL, shared->depth,
- &(bt2->cache_info), &bt2_flags, &bt2->root, udata, op, op_data) < 0)
+ if(H5B2_remove_internal(hdr, dxpl_id, &depth_decreased, NULL, hdr->depth,
+ &(hdr->cache_info), NULL, &hdr->root, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree internal node")
/* Check for decreasing the depth of the B-tree */
if(depth_decreased) {
/* Destroy free list factories for previous depth */
- if(shared->node_info[shared->depth].nat_rec_fac)
- if(H5FL_fac_term(shared->node_info[shared->depth].nat_rec_fac) < 0)
+ if(hdr->node_info[hdr->depth].nat_rec_fac)
+ if(H5FL_fac_term(hdr->node_info[hdr->depth].nat_rec_fac) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's native record block factory")
- if(shared->node_info[shared->depth].node_ptr_fac)
- if(H5FL_fac_term(shared->node_info[shared->depth].node_ptr_fac) < 0)
+ if(hdr->node_info[hdr->depth].node_ptr_fac)
+ if(H5FL_fac_term(hdr->node_info[hdr->depth].node_ptr_fac) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's node pointer block factory")
- shared->depth -= depth_decreased;
+ hdr->depth -= (uint16_t)depth_decreased;
} /* end for */
} /* end if */
else {
- if(H5B2_remove_leaf(f, dxpl_id, bt2->shared, &bt2->root, udata, op, op_data) < 0)
+ if(H5B2_remove_leaf(hdr, dxpl_id, &hdr->root, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree leaf node")
} /* end else */
/* Decrement # of records in B-tree */
- bt2->root.all_nrec--;
+ hdr->root.all_nrec--;
- /* Mark parent node as dirty */
- bt2_flags |= H5AC__DIRTIED_FLAG;
+ /* Mark B-tree header as dirty */
+ if(H5B2_hdr_dirty(hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTMARKDIRTY, FAIL, "unable to mark B-tree header dirty")
done:
- /* Release the B-tree header info */
- if (bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, bt2_flags) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_remove() */
@@ -749,79 +777,69 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, H5_iter_order_t order, hsize_t idx, H5B2_remove_t op,
- void *op_data)
+H5B2_remove_by_idx(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order,
+ hsize_t idx, H5B2_remove_t op, void *op_data)
{
- H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */
- unsigned bt2_flags = H5AC__NO_FLAGS_SET;
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- herr_t ret_value = SUCCEED;
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_remove_by_idx, FAIL)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
+ HDassert(bt2);
- /* Look up the b-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Check for empty B-tree */
- if(bt2->root.all_nrec == 0)
+ if(0 == hdr->root.all_nrec)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "record is not in B-tree")
/* Check for index greater than the number of records in the tree */
- if(idx >= bt2->root.all_nrec)
+ if(idx >= hdr->root.all_nrec)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "B-tree doesn't have that many records")
/* Check for reverse indexing and map requested index to appropriate forward index */
- if(order == H5_ITER_DEC)
- idx = bt2->root.all_nrec - (idx + 1);
+ if(H5_ITER_DEC == order)
+ idx = hdr->root.all_nrec - (idx + 1);
/* Attempt to remove record from B-tree */
- if(shared->depth > 0) {
+ if(hdr->depth > 0) {
hbool_t depth_decreased = FALSE; /* Flag to indicate whether the depth of the B-tree decreased */
- if(H5B2_remove_internal_by_idx(f, dxpl_id, bt2->shared, &depth_decreased, NULL, shared->depth,
- &(bt2->cache_info), &bt2_flags, &bt2->root, idx, op, op_data) < 0)
+ if(H5B2_remove_internal_by_idx(hdr, dxpl_id, &depth_decreased, NULL, hdr->depth,
+ &(hdr->cache_info), NULL, &hdr->root, idx, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree internal node")
/* Check for decreasing the depth of the B-tree */
if(depth_decreased) {
/* Destroy free list factories for previous depth */
- if(shared->node_info[shared->depth].nat_rec_fac)
- if(H5FL_fac_term(shared->node_info[shared->depth].nat_rec_fac) < 0)
+ if(hdr->node_info[hdr->depth].nat_rec_fac)
+ if(H5FL_fac_term(hdr->node_info[hdr->depth].nat_rec_fac) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's native record block factory")
- if(shared->node_info[shared->depth].node_ptr_fac)
- if(H5FL_fac_term(shared->node_info[shared->depth].node_ptr_fac) < 0)
+ if(hdr->node_info[hdr->depth].node_ptr_fac)
+ if(H5FL_fac_term(hdr->node_info[hdr->depth].node_ptr_fac) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's node pointer block factory")
- shared->depth -= depth_decreased;
+ hdr->depth -= (uint16_t)depth_decreased;
} /* end for */
} /* end if */
else {
- if(H5B2_remove_leaf_by_idx(f, dxpl_id, bt2->shared, &bt2->root, (unsigned)idx, op, op_data) < 0)
+ if(H5B2_remove_leaf_by_idx(hdr, dxpl_id, &hdr->root, (unsigned)idx, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree leaf node")
} /* end else */
/* Decrement # of records in B-tree */
- bt2->root.all_nrec--;
+ hdr->root.all_nrec--;
- /* Mark parent node as dirty */
- bt2_flags |= H5AC__DIRTIED_FLAG;
+ /* Mark B-tree header as dirty */
+ if(H5B2_hdr_dirty(hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTMARKDIRTY, FAIL, "unable to mark B-tree header dirty")
done:
- /* Release the B-tree header info */
- if (bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, bt2_flags) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_remove_by_idx() */
@@ -840,33 +858,18 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_get_nrec(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- hsize_t *nrec)
+H5B2_get_nrec(const H5B2_t *bt2, hsize_t *nrec)
{
- H5B2_t *bt2=NULL; /* Pointer to the B-tree header */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI(H5B2_get_nrec, FAIL)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_get_nrec)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
+ HDassert(bt2);
HDassert(nrec);
- /* Look up the B-tree header */
- if (NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
-
/* Get B-tree number of records */
- *nrec = bt2->root.all_nrec;
+ *nrec = bt2->hdr->root.all_nrec;
-done:
- /* Release B-tree header node */
- if (bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
-
- FUNC_LEAVE_NOAPI(ret_value)
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5B2_get_nrec() */
@@ -896,116 +899,44 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_neighbor(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- H5B2_compare_t range, void *udata, H5B2_found_t op, void *op_data)
+H5B2_neighbor(H5B2_t *bt2, hid_t dxpl_id, H5B2_compare_t range, void *udata,
+ H5B2_found_t op, void *op_data)
{
- H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- herr_t ret_value = SUCCEED;
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_neighbor, FAIL)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
+ HDassert(bt2);
HDassert(op);
- /* Look up the B-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Check for empty tree */
- if(!H5F_addr_defined(bt2->root.addr))
+ if(!H5F_addr_defined(hdr->root.addr))
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "B-tree has no records")
/* Attempt to find neighbor record in B-tree */
- if(shared->depth > 0) {
- if(H5B2_neighbor_internal(f, dxpl_id, bt2->shared, shared->depth, &bt2->root, NULL, range, udata, op, op_data)<0)
+ if(hdr->depth > 0) {
+ if(H5B2_neighbor_internal(hdr, dxpl_id, hdr->depth, &hdr->root, NULL, range, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "unable to find neighbor record in B-tree internal node")
} /* end if */
else {
- if(H5B2_neighbor_leaf(f, dxpl_id, bt2->shared, &bt2->root, NULL, range, udata, op, op_data)<0)
+ if(H5B2_neighbor_leaf(hdr, dxpl_id, &hdr->root, NULL, range, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "unable to find neighbor record in B-tree leaf node")
} /* end else */
done:
- /* Release the B-tree header info */
- if (bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_neighbor() */
/*-------------------------------------------------------------------------
- * Function: H5B2_delete
- *
- * Purpose: Delete an entire B-tree from a file.
- *
- * The 'OP' routine is called for each record and the
- * OP_DATA pointer, to allow caller to perform an operation as
- * each record is removed from the B-tree.
- *
- * If 'OP' is NULL, the records are just removed in the process
- * of deleting the B-tree.
- *
- * Note: The records are _not_ guaranteed to be visited in order.
- *
- * Return: Non-negative on success, negative on failure.
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Mar 9 2005
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5B2_delete(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- H5B2_remove_t op, void *op_data)
-{
- H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI(H5B2_delete, FAIL)
-
- /* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
-
- /* Look up the B-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
-
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
-
- /* Delete all nodes in B-tree */
- if(H5F_addr_defined(bt2->root.addr))
- if(H5B2_delete_node(f, dxpl_id, bt2->shared, shared->depth, &bt2->root, op, op_data) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete B-tree nodes")
-
- /* Release space for B-tree node on disk */
- if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)H5B2_HEADER_SIZE(f))<0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free B-tree header info")
-
-done:
- /* Release the B-tree header info */
- if(bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__DELETED_FLAG) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to delete B-tree header info")
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5B2_delete() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5B2_modify
*
* Purpose: Locate the specified information in a B-tree and modify it.
@@ -1026,54 +957,36 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- void *udata, H5B2_modify_t op, void *op_data)
+H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
+ void *op_data)
{
- H5B2_t *bt2=NULL; /* Pointer to the B-tree header */
- H5RC_t *bt2_shared=NULL; /* Pointer to ref-counter for shared B-tree info */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- hbool_t incr_rc=FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */
unsigned depth; /* Current depth of the tree */
int cmp; /* Comparison value of records */
unsigned idx; /* Location of record which matches key */
- herr_t ret_value = SUCCEED;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_modify, FAIL)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
+ HDassert(bt2);
HDassert(op);
- /* Look up the B-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
-
- /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */
- bt2_shared = bt2->shared;
- HDassert(bt2_shared);
- H5RC_INC(bt2_shared);
- incr_rc = TRUE;
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Get the pointer to the shared B-tree info */
- shared=(H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Make copy of the root node pointer to start search with */
- curr_node_ptr = bt2->root;
+ curr_node_ptr = hdr->root;
/* Current depth of the tree */
- depth = shared->depth;
-
- /* Release header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
- bt2 = NULL;
+ depth = hdr->depth;
/* Check for empty tree */
- if(curr_node_ptr.node_nrec==0)
+ if(0 == curr_node_ptr.node_nrec)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "B-tree has no records")
/* Walk down B-tree to find record or leaf node where record is located */
@@ -1084,20 +997,20 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
H5B2_node_ptr_t next_node_ptr; /* Node pointer info for next node */
/* Lock B-tree current node */
- if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_WRITE)))
+ if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Locate node pointer for child */
- cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx);
+ cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx);
if(cmp > 0)
idx++;
if(cmp != 0) {
/* Get node pointer for next node to search */
- next_node_ptr=internal->node_ptrs[idx];
+ next_node_ptr = internal->node_ptrs[idx];
/* Unlock current node */
- if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
/* Set pointer to next node to load */
@@ -1107,12 +1020,12 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
hbool_t changed; /* Whether the 'modify' callback changed the record */
/* Make callback for current record */
- if ( (op)(H5B2_INT_NREC(internal,shared,idx), op_data, &changed) <0) {
+ if((op)(H5B2_INT_NREC(internal, hdr, idx), op_data, &changed) < 0) {
/* Make certain that the callback didn't modify the value if it failed */
- HDassert(changed==FALSE);
+ HDassert(changed == FALSE);
/* Unlock current node */
- if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
HGOTO_ERROR(H5E_BTREE, H5E_CANTMODIFY, FAIL, "'modify' callback failed for B-tree find operation")
@@ -1122,7 +1035,7 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
internal_flags |= changed ? H5AC__DIRTIED_FLAG : 0;
/* Unlock current node */
- if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, internal_flags) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, internal_flags) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
HGOTO_DONE(SUCCEED);
@@ -1138,15 +1051,15 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
hbool_t changed = FALSE;/* Whether the 'modify' callback changed the record */
/* Lock B-tree leaf node */
- if (NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), bt2_shared, H5AC_WRITE)))
+ if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Locate record */
- cmp = H5B2_locate_record(shared->type, leaf->nrec, shared->nat_off, leaf->leaf_native, udata, &idx);
+ cmp = H5B2_locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx);
if(cmp != 0) {
/* Unlock leaf node */
- if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
/* Note: don't push error on stack, leave that to next higher level,
@@ -1161,12 +1074,12 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
} /* end if */
else {
/* Make callback for current record */
- if ((op)(H5B2_LEAF_NREC(leaf,shared,idx), op_data, &changed) <0) {
+ if((op)(H5B2_LEAF_NREC(leaf, hdr, idx), op_data, &changed) < 0) {
/* Make certain that the callback didn't modify the value if it failed */
- HDassert(changed==FALSE);
+ HDassert(changed == FALSE);
/* Unlock current node */
- if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
HGOTO_ERROR(H5E_BTREE, H5E_CANTMODIFY, FAIL, "'modify' callback failed for B-tree find operation")
@@ -1177,94 +1090,180 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
leaf_flags |= (changed ? H5AC__DIRTIED_FLAG : 0);
/* Unlock current node */
- if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, leaf_flags) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, leaf_flags) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
}
done:
- /* Check if we need to decrement the reference count for the B-tree's shared info */
- if(incr_rc)
- H5RC_DEC(bt2_shared);
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_modify() */
/*-------------------------------------------------------------------------
- * Function: H5B2_iterate_size
+ * Function: H5B2_close
*
- * Purpose: Iterate over all the records in the B-tree, collecting
- * storage info.
+ * Purpose: Close a v2 B-tree
*
- * Return: non-negative on success, negative on error
+ * Return: Non-negative on success/Negative on failure
*
- * Programmer: Vailin Choi
- * June 19 2007
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 15 2009
*
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_iterate_size(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, hsize_t *btree_size)
+H5B2_close(H5B2_t *bt2, hid_t dxpl_id)
{
- H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- H5RC_t *bt2_shared = NULL; /* Pointer to ref-counter for shared B-tree info */
- hbool_t incr_rc = FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */
- H5B2_node_ptr_t root_ptr; /* Node pointer info for root node */
- unsigned depth; /* Current depth of the tree */
- herr_t ret_value = SUCCEED;
+ haddr_t bt2_addr = HADDR_UNDEF; /* Address of v2 B-tree (for deletion) */
+ hbool_t pending_delete = FALSE; /* Whether the v2 B-tree is pending deletion */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5B2_iterate_size, FAIL)
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_close)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
- HDassert(btree_size);
+ HDassert(bt2);
+ HDassert(bt2->f);
+
+ /* Decrement file reference & check if this is the last open v2 B-tree using the shared B-tree header */
+ if(0 == H5B2_hdr_fuse_decr(bt2->hdr)) {
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
+
+ /* Check for pending B-tree deletion */
+ if(bt2->hdr->pending_delete) {
+ /* Set local info, so B-tree deletion can occur after decrementing the
+ * header's ref count
+ */
+ pending_delete = TRUE;
+ bt2_addr = bt2->hdr->addr;
+ } /* end if */
+ } /* end if */
- /* Look up the B-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
+ /* Check for pending v2 B-tree deletion */
+ if(pending_delete) {
+ H5B2_hdr_t *hdr; /* Another pointer to v2 B-tree header */
- /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */
- bt2_shared = bt2->shared;
- H5RC_INC(bt2_shared);
- incr_rc = TRUE;
+ /* Sanity check */
+ HDassert(H5F_addr_defined(bt2_addr));
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
+#ifndef NDEBUG
+{
+ unsigned hdr_status = 0; /* Header's status in the metadata cache */
+
+ /* Check the header's status in the metadata cache */
+ if(H5AC_get_entry_status(bt2->f, bt2_addr, &hdr_status) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "unable to check metadata cache status for v2 B-tree header, address = %llu", (unsigned long long)bt2_addr)
+
+ /* Sanity checks on header */
+ HDassert(hdr_status & H5AC_ES__IN_CACHE);
+ HDassert(hdr_status & H5AC_ES__IS_PINNED);
+ HDassert(!(hdr_status & H5AC_ES__IS_PROTECTED));
+}
+#endif /* NDEBUG */
+
+ /* Lock the v2 B-tree header into memory */
+ /* (OK to pass in NULL for callback context, since we know the header must be in the cache) */
+ if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(bt2->f, dxpl_id, H5AC_BT2_HDR, bt2_addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load v2 B-tree header")
+
+ /* Set the shared v2 B-tree header's file context for this operation */
+ hdr->f = bt2->f;
+
+ /* Decrement the reference count on the B-tree header */
+ /* (don't put in H5B2_hdr_fuse_decr() as the B-tree header may be evicted
+ * immediately -QAK)
+ */
+ if(H5B2_hdr_decr(bt2->hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTDEC, FAIL, "can't decrement reference count on shared v2 B-tree header")
+
+ /* Delete v2 B-tree, starting with header (unprotects header) */
+ if(H5B2_hdr_delete(hdr, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree")
+ } /* end if */
+ else {
+ /* Decrement the reference count on the B-tree header */
+ /* (don't put in H5B2_hdr_fuse_decr() as the B-tree header may be evicted
+ * immediately -QAK)
+ */
+ if(H5B2_hdr_decr(bt2->hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTDEC, FAIL, "can't decrement reference count on shared v2 B-tree header")
- /* Add size of header to B-tree metadata total */
- *btree_size += H5B2_HEADER_SIZE(f);
+ } /* end else */
- /* Make copy of the root node pointer */
- root_ptr = bt2->root;
+ /* Release the v2 B-tree wrapper */
+ bt2 = H5FL_FREE(H5B2_t, bt2);
- /* Current depth of the tree */
- depth = shared->depth;
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5B2_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_delete
+ *
+ * Purpose: Delete an entire B-tree from a file.
+ *
+ * The 'OP' routine is called for each record and the
+ * OP_DATA pointer, to allow caller to perform an operation as
+ * each record is removed from the B-tree.
+ *
+ * If 'OP' is NULL, the records are just removed in the process
+ * of deleting the B-tree.
+ *
+ * Note: The records are _not_ guaranteed to be visited in order.
+ *
+ * Return: Non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Mar 9 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *ctx_udata,
+ H5B2_remove_t op, void *op_data)
+{
+ H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Release header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
- bt2 = NULL;
+ FUNC_ENTER_NOAPI(H5B2_delete, FAIL)
- /* Iterate through records */
- if(root_ptr.node_nrec > 0) {
- /* Check for root node being a leaf */
- if(depth == 0)
- *btree_size += shared->node_size;
- else
- /* Iterate through nodes */
- if(H5B2_iterate_size_node(f, dxpl_id, bt2_shared, depth, &root_ptr, btree_size) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "node iteration failed");
+ /* Check arguments. */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+
+ /* Lock the v2 B-tree header into memory */
+#ifdef QAK
+HDfprintf(stderr, "%s: addr = %a\n", FUNC, addr);
+#endif /* QAK */
+ if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, NULL, ctx_udata, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect v2 B-tree header")
+
+ /* Remember the callback & context for later */
+ hdr->remove_op = op;
+ hdr->remove_op_data = op_data;
+
+ /* Check for files using shared v2 B-tree header */
+ if(hdr->file_rc)
+ hdr->pending_delete = TRUE;
+ else {
+ /* Set the shared v2 B-tree header's file context for this operation */
+ hdr->f = f;
+
+ /* Delete v2 B-tree now, starting with header (unprotects header) */
+ if(H5B2_hdr_delete(hdr, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree")
+ hdr = NULL;
} /* end if */
done:
- /* Check if we need to decrement the reference count for the B-tree's shared info */
- if(incr_rc)
- H5RC_DEC(bt2_shared);
+ /* Unprotect the header, if an error occurred */
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release v2 B-tree header")
+
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5B2_iterate_size() */
+} /* H5B2_delete() */
diff --git a/src/H5B2cache.c b/src/H5B2cache.c
index 3c96fa5..1d795ec 100644
--- a/src/H5B2cache.c
+++ b/src/H5B2cache.c
@@ -30,12 +30,14 @@
#define H5B2_PACKAGE /*suppress error about including H5B2pkg */
+
/***********/
/* Headers */
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5B2pkg.h" /* v2 B-trees */
#include "H5Eprivate.h" /* Error handling */
+#include "H5MFprivate.h" /* File memory management */
#include "H5WBprivate.h" /* Wrapped Buffers */
@@ -67,19 +69,20 @@
/********************/
/* Metadata cache callbacks */
-static H5B2_t *H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata);
-static herr_t H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_t *b, unsigned UNUSED * flags_ptr);
-static herr_t H5B2_cache_hdr_clear(H5F_t *f, H5B2_t *b, hbool_t destroy);
-static herr_t H5B2_cache_hdr_size(const H5F_t *f, const H5B2_t *bt, size_t *size_ptr);
-static H5B2_internal_t *H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, void *_shared);
+static H5B2_hdr_t *H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata);
+static herr_t H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_hdr_t *hdr, unsigned UNUSED * flags_ptr);
+static herr_t H5B2_cache_hdr_clear(H5F_t *f, H5B2_hdr_t *hdr, hbool_t destroy);
+static herr_t H5B2_cache_hdr_size(const H5F_t *f, const H5B2_hdr_t *hdr, size_t *size_ptr);
+static H5B2_internal_t *H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, void *udata2);
static herr_t H5B2_cache_internal_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_internal_t *i, unsigned UNUSED * flags_ptr);
static herr_t H5B2_cache_internal_clear(H5F_t *f, H5B2_internal_t *i, hbool_t destroy);
static herr_t H5B2_cache_internal_size(const H5F_t *f, const H5B2_internal_t *i, size_t *size_ptr);
-static H5B2_leaf_t *H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, void *_shared);
+static H5B2_leaf_t *H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, void *_hdr);
static herr_t H5B2_cache_leaf_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_leaf_t *l, unsigned UNUSED * flags_ptr);
static herr_t H5B2_cache_leaf_clear(H5F_t *f, H5B2_leaf_t *l, hbool_t destroy);
static herr_t H5B2_cache_leaf_size(const H5F_t *f, const H5B2_leaf_t *l, size_t *size_ptr);
+
/*********************/
/* Package Variables */
/*********************/
@@ -91,6 +94,7 @@ const H5AC_class_t H5AC_BT2_HDR[1] = {{
(H5AC_flush_func_t)H5B2_cache_hdr_flush,
(H5AC_dest_func_t)H5B2_cache_hdr_dest,
(H5AC_clear_func_t)H5B2_cache_hdr_clear,
+ (H5AC_notify_func_t)NULL,
(H5AC_size_func_t)H5B2_cache_hdr_size,
}};
@@ -101,6 +105,7 @@ const H5AC_class_t H5AC_BT2_INT[1] = {{
(H5AC_flush_func_t)H5B2_cache_internal_flush,
(H5AC_dest_func_t)H5B2_cache_internal_dest,
(H5AC_clear_func_t)H5B2_cache_internal_clear,
+ (H5AC_notify_func_t)NULL,
(H5AC_size_func_t)H5B2_cache_internal_size,
}};
@@ -111,9 +116,11 @@ const H5AC_class_t H5AC_BT2_LEAF[1] = {{
(H5AC_flush_func_t)H5B2_cache_leaf_flush,
(H5AC_dest_func_t)H5B2_cache_leaf_dest,
(H5AC_clear_func_t)H5B2_cache_leaf_clear,
+ (H5AC_notify_func_t)NULL,
(H5AC_size_func_t)H5B2_cache_leaf_size,
}};
+
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -131,7 +138,6 @@ const H5AC_class_t H5AC_BT2_LEAF[1] = {{
* Purpose: Loads a B-tree header from the disk.
*
* Return: Success: Pointer to a new B-tree.
- *
* Failure: NULL
*
* Programmer: Quincey Koziol
@@ -140,110 +146,114 @@ const H5AC_class_t H5AC_BT2_LEAF[1] = {{
*
*-------------------------------------------------------------------------
*/
-static H5B2_t *
-H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void UNUSED *udata)
+static H5B2_hdr_t *
+H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1,
+ void *ctx_udata)
{
- const H5B2_class_t *type = (const H5B2_class_t *) _type; /* Type of B-tree */
- unsigned depth; /* Depth of B-tree */
- size_t node_size, rrec_size; /* Size info for B-tree */
- uint8_t split_percent, merge_percent; /* Split & merge %s for B-tree */
- H5B2_t *bt2 = NULL; /* B-tree info */
+ H5B2_create_t cparam; /* B-tree creation parameters */
+ H5B2_subid_t id; /* ID of B-tree class, as found in file */
+ uint16_t depth; /* Depth of B-tree */
+ H5B2_hdr_t *hdr = NULL; /* B-tree header */
size_t size; /* Header size */
uint32_t stored_chksum; /* Stored metadata checksum value */
uint32_t computed_chksum; /* Computed metadata checksum value */
H5WB_t *wb = NULL; /* Wrapped buffer for header data */
uint8_t hdr_buf[H5B2_HDR_BUF_SIZE]; /* Buffer for header */
- uint8_t *hdr; /* Pointer to header buffer */
+ uint8_t *buf; /* Pointer to header buffer */
const uint8_t *p; /* Pointer into raw data buffer */
- H5B2_t *ret_value; /* Return value */
+ H5B2_hdr_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5B2_cache_hdr_load)
/* Check arguments */
HDassert(f);
HDassert(H5F_addr_defined(addr));
- HDassert(type);
- /* Allocate space for the B-tree data structure */
- if(NULL == (bt2 = H5FL_MALLOC(H5B2_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- HDmemset(&bt2->cache_info, 0, sizeof(H5AC_info_t));
+ /* Allocate new B-tree header and reset cache info */
+ if(NULL == (hdr = H5B2_hdr_alloc(f)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "allocation failed for B-tree header")
/* Wrap the local buffer for serialized header info */
if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, NULL, "can't wrap buffer")
/* Compute the size of the serialized B-tree header on disk */
- size = H5B2_HEADER_SIZE(f);
+ size = H5B2_HEADER_SIZE(hdr);
/* Get a pointer to a buffer that's large enough for header */
- if(NULL == (hdr = (uint8_t *)H5WB_actual(wb, size)))
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read header from disk */
- if(H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, hdr) < 0)
+ if(H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree header")
/* Get temporary pointer to serialized header */
- p = hdr;
+ p = buf;
/* Magic number */
- if(HDmemcmp(p, H5B2_HDR_MAGIC, (size_t)H5B2_SIZEOF_MAGIC))
+ if(HDmemcmp(p, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree header signature")
- p += H5B2_SIZEOF_MAGIC;
+ p += H5_SIZEOF_MAGIC;
/* Version */
if(*p++ != H5B2_HDR_VERSION)
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree header version")
- /* B-tree type */
- if(*p++ != (uint8_t)type->id)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "incorrect B-tree type")
+ /* B-tree class */
+ id = *p++;
+ if(id >= H5B2_NUM_BTREE_ID)
+ HGOTO_ERROR(H5E_BTREE, H5E_BADTYPE, NULL, "invalid B-tree type")
/* Node size (in bytes) */
- UINT32DECODE(p, node_size);
+ UINT32DECODE(p, cparam.node_size);
/* Raw key size (in bytes) */
- UINT16DECODE(p, rrec_size);
+ UINT16DECODE(p, cparam.rrec_size);
/* Depth of tree */
UINT16DECODE(p, depth);
/* Split & merge %s */
- split_percent = *p++;
- merge_percent = *p++;
+ cparam.split_percent = *p++;
+ cparam.merge_percent = *p++;
/* Root node pointer */
- H5F_addr_decode(f, (const uint8_t **)&p, &(bt2->root.addr));
- UINT16DECODE(p, bt2->root.node_nrec);
- H5F_DECODE_LENGTH(f, p, bt2->root.all_nrec);
+ H5F_addr_decode(f, (const uint8_t **)&p, &(hdr->root.addr));
+ UINT16DECODE(p, hdr->root.node_nrec);
+ H5F_DECODE_LENGTH(f, p, hdr->root.all_nrec);
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
/* Sanity check */
- HDassert((size_t)(p - (const uint8_t *)hdr) == size);
+ HDassert((size_t)(p - (const uint8_t *)buf) == size);
/* Compute checksum on entire header */
- computed_chksum = H5_checksum_metadata(hdr, (size - H5B2_SIZEOF_CHKSUM), 0);
+ computed_chksum = H5_checksum_metadata(buf, (size - H5B2_SIZEOF_CHKSUM), 0);
/* Verify checksum */
if(stored_chksum != computed_chksum)
HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "incorrect metadata checksum for v2 B-tree header")
- /* Initialize shared B-tree info */
- if(H5B2_shared_init(f, bt2, type, depth, node_size, rrec_size, split_percent, merge_percent) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't create shared B-tree info")
+ /* Initialize B-tree header info */
+ cparam.cls = H5B2_client_class_g[id];
+ if(H5B2_hdr_init(f, hdr, &cparam, ctx_udata, depth) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, NULL, "can't initialize B-tree header info")
+
+ /* Set the B-tree header's address */
+ hdr->addr = addr;
/* Set return value */
- ret_value = bt2;
+ ret_value = hdr;
done:
/* Release resources */
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
- if(!ret_value && bt2)
- (void)H5B2_cache_hdr_dest(f, bt2);
+ if(!ret_value && hdr)
+ if(H5B2_hdr_free(hdr) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTRELEASE, NULL, "can't release v2 B-tree header")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B2_cache_hdr_load() */ /*lint !e818 Can't make udata a pointer to const */
@@ -263,7 +273,8 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_t *bt2, unsigned UNUSED * flags_ptr)
+H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
+ H5B2_hdr_t *hdr, unsigned UNUSED * flags_ptr)
{
H5WB_t *wb = NULL; /* Wrapped buffer for header data */
uint8_t hdr_buf[H5B2_HDR_BUF_SIZE]; /* Buffer for header */
@@ -274,79 +285,77 @@ H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B
/* check arguments */
HDassert(f);
HDassert(H5F_addr_defined(addr));
- HDassert(bt2);
+ HDassert(hdr);
- if (bt2->cache_info.is_dirty) {
- H5B2_shared_t *shared; /* Shared B-tree information */
- uint8_t *hdr; /* Pointer to header buffer */
+ if(hdr->cache_info.is_dirty) {
+ uint8_t *buf; /* Pointer to header buffer */
uint8_t *p; /* Pointer into raw data buffer */
size_t size; /* Header size on disk */
uint32_t metadata_chksum; /* Computed metadata checksum value */
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
+ /* Set the B-tree header's file context for this operation */
+ hdr->f = f;
/* Wrap the local buffer for serialized header info */
if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't wrap buffer")
/* Compute the size of the serialized B-tree header on disk */
- size = H5B2_HEADER_SIZE(f);
+ size = H5B2_HEADER_SIZE(hdr);
/* Get a pointer to a buffer that's large enough for header */
- if(NULL == (hdr = (uint8_t *)H5WB_actual(wb, size)))
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Get temporary pointer to serialized header */
- p = hdr;
+ p = buf;
/* Magic number */
- HDmemcpy(p, H5B2_HDR_MAGIC, (size_t)H5B2_SIZEOF_MAGIC);
- p += H5B2_SIZEOF_MAGIC;
+ HDmemcpy(p, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
/* Version # */
*p++ = H5B2_HDR_VERSION;
/* B-tree type */
- *p++ = shared->type->id;
+ *p++ = hdr->cls->id;
/* Node size (in bytes) */
- UINT32ENCODE(p, shared->node_size);
+ UINT32ENCODE(p, hdr->node_size);
/* Raw key size (in bytes) */
- UINT16ENCODE(p, shared->rrec_size);
+ UINT16ENCODE(p, hdr->rrec_size);
/* Depth of tree */
- UINT16ENCODE(p, shared->depth);
+ UINT16ENCODE(p, hdr->depth);
/* Split & merge %s */
- H5_CHECK_OVERFLOW(shared->split_percent, /* From: */ unsigned, /* To: */ uint8_t);
- *p++ = (uint8_t)shared->split_percent;
- H5_CHECK_OVERFLOW(shared->merge_percent, /* From: */ unsigned, /* To: */ uint8_t);
- *p++ = (uint8_t)shared->merge_percent;
+ H5_CHECK_OVERFLOW(hdr->split_percent, /* From: */ unsigned, /* To: */ uint8_t);
+ *p++ = (uint8_t)hdr->split_percent;
+ H5_CHECK_OVERFLOW(hdr->merge_percent, /* From: */ unsigned, /* To: */ uint8_t);
+ *p++ = (uint8_t)hdr->merge_percent;
/* Root node pointer */
- H5F_addr_encode(f, &p, bt2->root.addr);
- UINT16ENCODE(p, bt2->root.node_nrec);
- H5F_ENCODE_LENGTH(f, p, bt2->root.all_nrec);
+ H5F_addr_encode(f, &p, hdr->root.addr);
+ UINT16ENCODE(p, hdr->root.node_nrec);
+ H5F_ENCODE_LENGTH(f, p, hdr->root.all_nrec);
/* Compute metadata checksum */
- metadata_chksum = H5_checksum_metadata(hdr, (size - H5B2_SIZEOF_CHKSUM), 0);
+ metadata_chksum = H5_checksum_metadata(buf, (size - H5B2_SIZEOF_CHKSUM), 0);
/* Metadata checksum */
UINT32ENCODE(p, metadata_chksum);
/* Write the B-tree header. */
- HDassert((size_t)(p - hdr) == size);
- if(H5F_block_write(f, H5FD_MEM_BTREE, addr, size, dxpl_id, hdr) < 0)
+ HDassert((size_t)(p - buf) == size);
+ if(H5F_block_write(f, H5FD_MEM_BTREE, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree header to disk")
- bt2->cache_info.is_dirty = FALSE;
+ hdr->cache_info.is_dirty = FALSE;
} /* end if */
if(destroy)
- if(H5B2_cache_hdr_dest(f, bt2) < 0)
+ if(H5B2_cache_hdr_dest(f, hdr) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree header")
done:
@@ -371,25 +380,36 @@ done:
*
*-------------------------------------------------------------------------
*/
-/* ARGSUSED */
herr_t
-H5B2_cache_hdr_dest(H5F_t UNUSED *f, H5B2_t *bt2)
+H5B2_cache_hdr_dest(H5F_t *f, H5B2_hdr_t *hdr)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_cache_hdr_dest)
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_cache_hdr_dest)
/*
* Check arguments.
*/
- HDassert(bt2);
-
- /* Decrement reference count on shared B-tree info */
- if(bt2->shared)
- H5RC_DEC(bt2->shared);
+ HDassert(hdr);
+ HDassert(hdr->rc == 0);
+
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!hdr->cache_info.free_file_space_on_destroy || H5F_addr_defined(hdr->cache_info.addr));
+
+ /* Check for freeing file space for B-tree header */
+ if(hdr->cache_info.free_file_space_on_destroy) {
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, hdr->cache_info.addr, (hsize_t)H5B2_HEADER_SIZE(hdr)) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree header")
+ } /* end if */
- /* Free B-tree header info */
- H5FL_FREE(H5B2_t, bt2);
+ /* Release B-tree header info */
+ if(H5B2_hdr_free(hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree header info")
- FUNC_LEAVE_NOAPI(SUCCEED)
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B2_cache_hdr_dest() */
@@ -407,7 +427,7 @@ H5B2_cache_hdr_dest(H5F_t UNUSED *f, H5B2_t *bt2)
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_cache_hdr_clear(H5F_t *f, H5B2_t *bt2, hbool_t destroy)
+H5B2_cache_hdr_clear(H5F_t *f, H5B2_hdr_t *hdr, hbool_t destroy)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -416,13 +436,13 @@ H5B2_cache_hdr_clear(H5F_t *f, H5B2_t *bt2, hbool_t destroy)
/*
* Check arguments.
*/
- HDassert(bt2);
+ HDassert(hdr);
/* Reset the dirty flag. */
- bt2->cache_info.is_dirty = FALSE;
+ hdr->cache_info.is_dirty = FALSE;
if(destroy)
- if(H5B2_cache_hdr_dest(f, bt2) < 0)
+ if(H5B2_cache_hdr_dest(f, hdr) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree header")
done:
@@ -446,7 +466,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_cache_hdr_size(const H5F_t *f, const H5B2_t UNUSED *bt2, size_t *size_ptr)
+H5B2_cache_hdr_size(const H5F_t UNUSED *f, const H5B2_hdr_t *hdr, size_t *size_ptr)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_cache_hdr_size)
@@ -455,7 +475,7 @@ H5B2_cache_hdr_size(const H5F_t *f, const H5B2_t UNUSED *bt2, size_t *size_ptr)
HDassert(size_ptr);
/* Set size value */
- *size_ptr = H5B2_HEADER_SIZE(f);
+ *size_ptr = H5B2_HEADER_SIZE(hdr);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5B2_cache_hdr_size() */
@@ -479,7 +499,6 @@ static H5B2_internal_t *
H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata, void UNUSED *udata2)
{
const H5B2_int_load_ud1_t *udata = (const H5B2_int_load_ud1_t *)_udata; /* Pointer to user data */
- H5B2_shared_t *shared; /* Shared B-tree information */
H5B2_internal_t *internal = NULL; /* Internal node read */
const uint8_t *p; /* Pointer into raw data buffer */
uint8_t *native; /* Pointer to native record info */
@@ -501,39 +520,41 @@ H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_uda
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
HDmemset(&internal->cache_info, 0, sizeof(H5AC_info_t));
- /* Share common B-tree information */
- internal->shared = udata->bt2_shared;
- H5RC_INC(internal->shared);
+ /* Set the B-tree header's file context for this operation */
+ udata->hdr->f = f;
- /* Get the pointer to the shared B-tree info */
- shared=(H5B2_shared_t *)H5RC_GET_OBJ(internal->shared);
- HDassert(shared);
+ /* Increment ref. count on B-tree header */
+ if(H5B2_hdr_incr(udata->hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment ref. count on B-tree header")
+
+ /* Share B-tree information */
+ internal->hdr = udata->hdr;
/* Read header from disk */
- if(H5F_block_read(f, H5FD_MEM_BTREE, addr, shared->node_size, dxpl_id, shared->page)<0)
+ if(H5F_block_read(f, H5FD_MEM_BTREE, addr, udata->hdr->node_size, dxpl_id, udata->hdr->page) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree internal node")
- p = shared->page;
+ p = udata->hdr->page;
/* Magic number */
- if(HDmemcmp(p, H5B2_INT_MAGIC, (size_t)H5B2_SIZEOF_MAGIC))
+ if(HDmemcmp(p, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree internal node signature")
- p += H5B2_SIZEOF_MAGIC;
+ p += H5_SIZEOF_MAGIC;
/* Version */
if(*p++ != H5B2_INT_VERSION)
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree internal node version")
/* B-tree type */
- if (*p++ != (uint8_t)shared->type->id)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "incorrect B-tree type")
+ if(*p++ != (uint8_t)udata->hdr->cls->id)
+ HGOTO_ERROR(H5E_BTREE, H5E_BADTYPE, NULL, "incorrect B-tree type")
/* Allocate space for the native keys in memory */
- if((internal->int_native = (uint8_t *)H5FL_FAC_MALLOC(shared->node_info[udata->depth].nat_rec_fac)) == NULL)
+ if(NULL == (internal->int_native = (uint8_t *)H5FL_FAC_MALLOC(udata->hdr->node_info[udata->depth].nat_rec_fac)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree internal native keys")
/* Allocate space for the node pointers in memory */
- if((internal->node_ptrs = (H5B2_node_ptr_t *)H5FL_FAC_MALLOC(shared->node_info[udata->depth].node_ptr_fac)) == NULL)
+ if(NULL == (internal->node_ptrs = (H5B2_node_ptr_t *)H5FL_FAC_MALLOC(udata->hdr->node_info[udata->depth].node_ptr_fac)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree internal node pointers")
/* Set the number of records in the leaf & it's depth */
@@ -544,22 +565,22 @@ H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_uda
native = internal->int_native;
for(u = 0; u < internal->nrec; u++) {
/* Decode record */
- if((shared->type->decode)(f, p, native) < 0)
+ if((udata->hdr->cls->decode)(p, native, udata->hdr->cb_ctx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, NULL, "unable to decode B-tree record")
/* Move to next record */
- p += shared->rrec_size;
- native += shared->type->nrec_size;
+ p += udata->hdr->rrec_size;
+ native += udata->hdr->cls->nrec_size;
} /* end for */
/* Deserialize node pointers for internal node */
int_node_ptr = internal->node_ptrs;
- for(u = 0; u < internal->nrec + 1; u++) {
+ for(u = 0; u < (unsigned)(internal->nrec + 1); u++) {
/* Decode node pointer */
H5F_addr_decode(f, (const uint8_t **)&p, &(int_node_ptr->addr));
- UINT64DECODE_VAR(p, int_node_ptr->node_nrec, shared->max_nrec_size);
+ UINT64DECODE_VAR(p, int_node_ptr->node_nrec, udata->hdr->max_nrec_size);
if(udata->depth > 1)
- UINT64DECODE_VAR(p, int_node_ptr->all_nrec, shared->node_info[udata->depth - 1].cum_max_nrec_size)
+ UINT64DECODE_VAR(p, int_node_ptr->all_nrec, udata->hdr->node_info[udata->depth - 1].cum_max_nrec_size)
else
int_node_ptr->all_nrec = int_node_ptr->node_nrec;
@@ -568,13 +589,13 @@ H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_uda
} /* end for */
/* Compute checksum on internal node */
- computed_chksum = H5_checksum_metadata(shared->page, (size_t)(p - (const uint8_t *)shared->page), 0);
+ computed_chksum = H5_checksum_metadata(udata->hdr->page, (size_t)(p - (const uint8_t *)udata->hdr->page), 0);
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
/* Sanity check parsing */
- HDassert((size_t)(p - (const uint8_t *)shared->page) <= shared->node_size);
+ HDassert((size_t)(p - (const uint8_t *)udata->hdr->page) <= udata->hdr->node_size);
/* Verify checksum */
if(stored_chksum != computed_chksum)
@@ -615,66 +636,65 @@ H5B2_cache_internal_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr
HDassert(f);
HDassert(H5F_addr_defined(addr));
HDassert(internal);
+ HDassert(internal->hdr);
if(internal->cache_info.is_dirty) {
- H5B2_shared_t *shared; /* Shared B-tree information */
uint8_t *p; /* Pointer into raw data buffer */
uint8_t *native; /* Pointer to native record info */
H5B2_node_ptr_t *int_node_ptr; /* Pointer to node pointer info */
uint32_t metadata_chksum; /* Computed metadata checksum value */
unsigned u; /* Local index variable */
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(internal->shared);
- HDassert(shared);
+ /* Set the B-tree header's file context for this operation */
+ internal->hdr->f = f;
- p = shared->page;
+ p = internal->hdr->page;
/* Magic number */
- HDmemcpy(p, H5B2_INT_MAGIC, (size_t)H5B2_SIZEOF_MAGIC);
- p += H5B2_SIZEOF_MAGIC;
+ HDmemcpy(p, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
/* Version # */
*p++ = H5B2_INT_VERSION;
/* B-tree type */
- *p++ = shared->type->id;
- HDassert((size_t)(p - shared->page) == (H5B2_INT_PREFIX_SIZE - H5B2_SIZEOF_CHKSUM));
+ *p++ = internal->hdr->cls->id;
+ HDassert((size_t)(p - internal->hdr->page) == (H5B2_INT_PREFIX_SIZE - H5B2_SIZEOF_CHKSUM));
/* Serialize records for internal node */
native = internal->int_native;
for(u = 0; u < internal->nrec; u++) {
/* Encode record */
- if((shared->type->encode)(f, p, native) < 0)
+ if((internal->hdr->cls->encode)(p, native, internal->hdr->cb_ctx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree record")
/* Move to next record */
- p += shared->rrec_size;
- native += shared->type->nrec_size;
+ p += internal->hdr->rrec_size;
+ native += internal->hdr->cls->nrec_size;
} /* end for */
/* Serialize node pointers for internal node */
int_node_ptr = internal->node_ptrs;
- for(u = 0; u < internal->nrec + 1; u++) {
+ for(u = 0; u < (unsigned)(internal->nrec + 1); u++) {
/* Encode node pointer */
H5F_addr_encode(f, &p, int_node_ptr->addr);
- UINT64ENCODE_VAR(p, int_node_ptr->node_nrec, shared->max_nrec_size);
+ UINT64ENCODE_VAR(p, int_node_ptr->node_nrec, internal->hdr->max_nrec_size);
if(internal->depth > 1)
- UINT64ENCODE_VAR(p, int_node_ptr->all_nrec, shared->node_info[internal->depth - 1].cum_max_nrec_size);
+ UINT64ENCODE_VAR(p, int_node_ptr->all_nrec, internal->hdr->node_info[internal->depth - 1].cum_max_nrec_size);
/* Move to next node pointer */
int_node_ptr++;
} /* end for */
/* Compute metadata checksum */
- metadata_chksum = H5_checksum_metadata(shared->page, (size_t)(p - shared->page), 0);
+ metadata_chksum = H5_checksum_metadata(internal->hdr->page, (size_t)(p - internal->hdr->page), 0);
/* Metadata checksum */
UINT32ENCODE(p, metadata_chksum);
/* Write the B-tree internal node */
- HDassert((size_t)(p - shared->page) <= shared->node_size);
- if(H5F_block_write(f, H5FD_MEM_BTREE, addr, shared->node_size, dxpl_id, shared->page) < 0)
+ HDassert((size_t)(p - internal->hdr->page) <= internal->hdr->node_size);
+ if(H5F_block_write(f, H5FD_MEM_BTREE, addr, internal->hdr->node_size, dxpl_id, internal->hdr->page) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree internal node to disk")
internal->cache_info.is_dirty = FALSE;
@@ -702,39 +722,51 @@ done:
*
*-------------------------------------------------------------------------
*/
-/* ARGSUSED */
herr_t
-H5B2_cache_internal_dest(H5F_t UNUSED *f, H5B2_internal_t *internal)
+H5B2_cache_internal_dest(H5F_t *f, H5B2_internal_t *internal)
{
- H5B2_shared_t *shared; /* Shared B-tree information */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_cache_internal_dest)
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_cache_internal_dest)
/*
* Check arguments.
*/
+ HDassert(f);
HDassert(internal);
+ HDassert(internal->hdr);
+
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!internal->cache_info.free_file_space_on_destroy || H5F_addr_defined(internal->cache_info.addr));
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(internal->shared);
- HDassert(shared);
+ /* Check for freeing file space for B-tree internal node */
+ if(internal->cache_info.free_file_space_on_destroy) {
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, internal->cache_info.addr, (hsize_t)internal->hdr->node_size) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree internal node")
+ } /* end if */
+
+ /* Set the B-tree header's file context for this operation */
+ internal->hdr->f = f;
/* Release internal node's native key buffer */
if(internal->int_native)
- H5FL_FAC_FREE(shared->node_info[internal->depth].nat_rec_fac, internal->int_native);
+ H5FL_FAC_FREE(internal->hdr->node_info[internal->depth].nat_rec_fac, internal->int_native);
/* Release internal node's node pointer buffer */
if(internal->node_ptrs)
- H5FL_FAC_FREE(shared->node_info[internal->depth].node_ptr_fac, internal->node_ptrs);
+ H5FL_FAC_FREE(internal->hdr->node_info[internal->depth].node_ptr_fac, internal->node_ptrs);
- /* Decrement reference count on shared B-tree info */
- if(internal->shared)
- H5RC_DEC(internal->shared);
+ /* Decrement ref. count on B-tree header */
+ if(H5B2_hdr_decr(internal->hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTDEC, FAIL, "can't decrement ref. count on B-tree header")
/* Free B-tree internal node info */
- H5FL_FREE(H5B2_internal_t, internal);
+ internal = H5FL_FREE(H5B2_internal_t, internal);
- FUNC_LEAVE_NOAPI(SUCCEED)
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B2_cache_internal_dest() */
@@ -793,20 +825,15 @@ done:
static herr_t
H5B2_cache_internal_size(const H5F_t UNUSED *f, const H5B2_internal_t *internal, size_t *size_ptr)
{
- H5B2_shared_t *shared; /* Shared B-tree information */
-
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_cache_internal_size)
/* check arguments */
HDassert(internal);
+ HDassert(internal->hdr);
HDassert(size_ptr);
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(internal->shared);
- HDassert(shared);
-
/* Set size value */
- *size_ptr = shared->node_size;
+ *size_ptr = internal->hdr->node_size;
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5B2_cache_internal_size() */
@@ -827,11 +854,10 @@ H5B2_cache_internal_size(const H5F_t UNUSED *f, const H5B2_internal_t *internal,
*-------------------------------------------------------------------------
*/
static H5B2_leaf_t *
-H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, void *_bt2_shared)
+H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, void *_hdr)
{
- const unsigned *nrec = (const unsigned *)_nrec;
- H5RC_t *bt2_shared = (H5RC_t *)_bt2_shared; /* Shared B-tree information */
- H5B2_shared_t *shared; /* Shared B-tree information */
+ const uint16_t *nrec = (const uint16_t *)_nrec;
+ H5B2_hdr_t *hdr = (H5B2_hdr_t *)_hdr; /* B-tree header information */
H5B2_leaf_t *leaf = NULL; /* Pointer to lead node loaded */
const uint8_t *p; /* Pointer into raw data buffer */
uint8_t *native; /* Pointer to native keys */
@@ -845,42 +871,45 @@ H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, v
/* Check arguments */
HDassert(f);
HDassert(H5F_addr_defined(addr));
- HDassert(bt2_shared);
+ HDassert(hdr);
+ /* Allocate new leaf node and reset cache info */
if(NULL == (leaf = H5FL_MALLOC(H5B2_leaf_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
HDmemset(&leaf->cache_info, 0, sizeof(H5AC_info_t));
- /* Share common B-tree information */
- leaf->shared = bt2_shared;
- H5RC_INC(leaf->shared);
+ /* Set the B-tree header's file context for this operation */
+ hdr->f = f;
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(leaf->shared);
- HDassert(shared);
+ /* Increment ref. count on B-tree header */
+ if(H5B2_hdr_incr(hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment ref. count on B-tree header")
+
+ /* Share B-tree header information */
+ leaf->hdr = hdr;
/* Read header from disk */
- if(H5F_block_read(f, H5FD_MEM_BTREE, addr, shared->node_size, dxpl_id, shared->page) < 0)
+ if(H5F_block_read(f, H5FD_MEM_BTREE, addr, hdr->node_size, dxpl_id, hdr->page) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree leaf node")
- p = shared->page;
+ p = hdr->page;
/* Magic number */
- if(HDmemcmp(p, H5B2_LEAF_MAGIC, (size_t)H5B2_SIZEOF_MAGIC))
+ if(HDmemcmp(p, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree leaf node signature")
- p += H5B2_SIZEOF_MAGIC;
+ p += H5_SIZEOF_MAGIC;
/* Version */
if(*p++ != H5B2_LEAF_VERSION)
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree leaf node version")
/* B-tree type */
- if(*p++ != (uint8_t)shared->type->id)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "incorrect B-tree type")
+ if(*p++ != (uint8_t)hdr->cls->id)
+ HGOTO_ERROR(H5E_BTREE, H5E_BADTYPE, NULL, "incorrect B-tree type")
/* Allocate space for the native keys in memory */
- if((leaf->leaf_native = (uint8_t *)H5FL_FAC_MALLOC(shared->node_info[0].nat_rec_fac)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree leaf native keys")
+ if(NULL == (leaf->leaf_native = (uint8_t *)H5FL_FAC_MALLOC(hdr->node_info[0].nat_rec_fac)))
+ HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree leaf native keys")
/* Set the number of records in the leaf */
leaf->nrec = *nrec;
@@ -889,22 +918,22 @@ H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, v
native = leaf->leaf_native;
for(u = 0; u < leaf->nrec; u++) {
/* Decode record */
- if((shared->type->decode)(f, p, native) < 0)
+ if((hdr->cls->decode)(p, native, hdr->cb_ctx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, NULL, "unable to decode B-tree record")
/* Move to next record */
- p += shared->rrec_size;
- native += shared->type->nrec_size;
+ p += hdr->rrec_size;
+ native += hdr->cls->nrec_size;
} /* end for */
/* Compute checksum on internal node */
- computed_chksum = H5_checksum_metadata(shared->page, (size_t)(p - (const uint8_t *)shared->page), 0);
+ computed_chksum = H5_checksum_metadata(hdr->page, (size_t)(p - (const uint8_t *)hdr->page), 0);
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
/* Sanity check parsing */
- HDassert((size_t)(p - (const uint8_t *)shared->page) <= shared->node_size);
+ HDassert((size_t)(p - (const uint8_t *)hdr->page) <= hdr->node_size);
/* Verify checksum */
if(stored_chksum != computed_chksum)
@@ -915,7 +944,7 @@ H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, v
done:
if(!ret_value && leaf)
- (void)H5B2_cache_leaf_dest(f,leaf);
+ (void)H5B2_cache_leaf_dest(f, leaf);
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_cache_leaf_load() */ /*lint !e818 Can't make udata a pointer to const */
@@ -945,52 +974,51 @@ H5B2_cache_leaf_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5
HDassert(f);
HDassert(H5F_addr_defined(addr));
HDassert(leaf);
+ HDassert(leaf->hdr);
if(leaf->cache_info.is_dirty) {
- H5B2_shared_t *shared; /* Shared B-tree information */
uint8_t *p; /* Pointer into raw data buffer */
uint8_t *native; /* Pointer to native keys */
uint32_t metadata_chksum; /* Computed metadata checksum value */
unsigned u; /* Local index variable */
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(leaf->shared);
- HDassert(shared);
+ /* Set the B-tree header's file context for this operation */
+ leaf->hdr->f = f;
- p = shared->page;
+ p = leaf->hdr->page;
/* magic number */
- HDmemcpy(p, H5B2_LEAF_MAGIC, (size_t)H5B2_SIZEOF_MAGIC);
- p += H5B2_SIZEOF_MAGIC;
+ HDmemcpy(p, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
/* version # */
*p++ = H5B2_LEAF_VERSION;
/* b-tree type */
- *p++ = shared->type->id;
- HDassert((size_t)(p - shared->page) == (H5B2_LEAF_PREFIX_SIZE - H5B2_SIZEOF_CHKSUM));
+ *p++ = leaf->hdr->cls->id;
+ HDassert((size_t)(p - leaf->hdr->page) == (H5B2_LEAF_PREFIX_SIZE - H5B2_SIZEOF_CHKSUM));
/* Serialize records for leaf node */
native = leaf->leaf_native;
for(u = 0; u < leaf->nrec; u++) {
/* Encode record */
- if((shared->type->encode)(f, p, native) < 0)
+ if((leaf->hdr->cls->encode)(p, native, leaf->hdr->cb_ctx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree record")
/* Move to next record */
- p += shared->rrec_size;
- native += shared->type->nrec_size;
+ p += leaf->hdr->rrec_size;
+ native += leaf->hdr->cls->nrec_size;
} /* end for */
/* Compute metadata checksum */
- metadata_chksum = H5_checksum_metadata(shared->page, (size_t)(p - shared->page), 0);
+ metadata_chksum = H5_checksum_metadata(leaf->hdr->page, (size_t)(p - leaf->hdr->page), 0);
/* Metadata checksum */
UINT32ENCODE(p, metadata_chksum);
/* Write the B-tree leaf node */
- HDassert((size_t)(p - shared->page) <= shared->node_size);
- if(H5F_block_write(f, H5FD_MEM_BTREE, addr, shared->node_size, dxpl_id, shared->page) < 0)
+ HDassert((size_t)(p - leaf->hdr->page) <= leaf->hdr->node_size);
+ if(H5F_block_write(f, H5FD_MEM_BTREE, addr, leaf->hdr->node_size, dxpl_id, leaf->hdr->page) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree leaf node to disk")
leaf->cache_info.is_dirty = FALSE;
@@ -1018,35 +1046,47 @@ done:
*
*-------------------------------------------------------------------------
*/
-/* ARGSUSED */
herr_t
-H5B2_cache_leaf_dest(H5F_t UNUSED *f, H5B2_leaf_t *leaf)
+H5B2_cache_leaf_dest(H5F_t *f, H5B2_leaf_t *leaf)
{
- H5B2_shared_t *shared; /* Shared B-tree information */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_cache_leaf_dest)
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_cache_leaf_dest)
/*
* Check arguments.
*/
+ HDassert(f);
HDassert(leaf);
+ HDassert(leaf->hdr);
+
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!leaf->cache_info.free_file_space_on_destroy || H5F_addr_defined(leaf->cache_info.addr));
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(leaf->shared);
- HDassert(shared);
+ /* Check for freeing file space for B-tree leaf node */
+ if(leaf->cache_info.free_file_space_on_destroy) {
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, leaf->cache_info.addr, (hsize_t)leaf->hdr->node_size) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree leaf node")
+ } /* end if */
+
+ /* Set the B-tree header's file context for this operation */
+ leaf->hdr->f = f;
/* Release leaf's native key buffer */
if(leaf->leaf_native)
- H5FL_FAC_FREE(shared->node_info[0].nat_rec_fac, leaf->leaf_native);
+ H5FL_FAC_FREE(leaf->hdr->node_info[0].nat_rec_fac, leaf->leaf_native);
- /* Decrement reference count on shared B-tree info */
- if(leaf->shared)
- H5RC_DEC(leaf->shared);
+ /* Decrement ref. count on B-tree header */
+ if(H5B2_hdr_decr(leaf->hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTDEC, FAIL, "can't decrement ref. count on B-tree header")
/* Free B-tree leaf node info */
- H5FL_FREE(H5B2_leaf_t,leaf);
+ leaf = H5FL_FREE(H5B2_leaf_t, leaf);
- FUNC_LEAVE_NOAPI(SUCCEED)
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B2_cache_leaf_dest() */
@@ -1105,20 +1145,15 @@ done:
static herr_t
H5B2_cache_leaf_size(const H5F_t UNUSED *f, const H5B2_leaf_t *leaf, size_t *size_ptr)
{
- H5B2_shared_t *shared; /* Shared B-tree information */
-
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_cache_leaf_size)
/* check arguments */
HDassert(leaf);
+ HDassert(leaf->hdr);
HDassert(size_ptr);
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(leaf->shared);
- HDassert(shared);
-
/* Set size value */
- *size_ptr = shared->node_size;
+ *size_ptr = leaf->hdr->node_size;
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5B2_cache_leaf_size() */
diff --git a/src/H5B2dbg.c b/src/H5B2dbg.c
index 836486e..f8a1fc9 100644
--- a/src/H5B2dbg.c
+++ b/src/H5B2dbg.c
@@ -90,10 +90,10 @@ herr_t
H5B2_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth,
const H5B2_class_t *type)
{
- H5B2_t *bt2 = NULL; /* B-tree header info */
- H5B2_shared_t *shared; /* Shared B-tree information */
+ H5B2_hdr_t *hdr = NULL; /* B-tree header info */
+ void *dbg_ctx = NULL; /* v2 B-tree debugging context */
unsigned u; /* Local index variable */
- char temp_str[128]; /* Temporary string, for formatting */
+ char temp_str[128]; /* Temporary string, for formatting */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_hdr_debug, FAIL)
@@ -107,16 +107,24 @@ H5B2_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
HDassert(indent >= 0);
HDassert(fwidth >= 0);
HDassert(type);
+ HDassert((type->crt_dbg_ctx && type->dst_dbg_ctx) ||
+ (NULL == type->crt_dbg_ctx && NULL == type->dst_dbg_ctx));
+
+ /* Check for debugging context callback available */
+ if(type->crt_dbg_ctx) {
+ /* Create debugging context */
+ if(NULL == (dbg_ctx = (type->crt_dbg_ctx)(f, dxpl_id, addr)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "unable to create v2 B-tree debugging context")
+ } /* end if */
/*
* Load the B-tree header.
*/
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
+ if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, dbg_ctx, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree header")
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
+ /* Set file pointer for this B-tree operation */
+ hdr->f = f;
/* Print opening message */
HDfprintf(stream, "%*sv2 B-tree Header...\n", indent, "");
@@ -124,59 +132,53 @@ H5B2_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
/*
* Print the values.
*/
- HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
- "Tree type ID:",
- (shared->type->id == H5B2_TEST_ID ? "H5B2_TEST_ID" :
- (shared->type->id == H5B2_FHEAP_HUGE_INDIR_ID ? "H5B2_FHEAP_HUGE_INDIR_ID" :
- (shared->type->id == H5B2_FHEAP_HUGE_FILT_INDIR_ID ? "H5B2_FHEAP_HUGE_FILT_INDIR_ID" :
- (shared->type->id == H5B2_FHEAP_HUGE_DIR_ID ? "H5B2_FHEAP_HUGE_DIR_ID" :
- (shared->type->id == H5B2_FHEAP_HUGE_FILT_DIR_ID ? "H5B2_FHEAP_HUGE_FILT_DIR_ID" :
- (shared->type->id == H5B2_GRP_DENSE_NAME_ID ? "H5B2_GRP_DENSE_NAME_ID" :
- (shared->type->id == H5B2_GRP_DENSE_CORDER_ID ? "H5B2_GRP_DENSE_CORDER_ID" :
- (shared->type->id == H5B2_SOHM_INDEX_ID ? "H5B2_SOHM_INDEX_ID" :
- (shared->type->id == H5B2_ATTR_DENSE_NAME_ID ? "H5B2_ATTR_DENSE_NAME_ID" :
- (shared->type->id == H5B2_ATTR_DENSE_CORDER_ID ? "H5B2_ATTR_DENSE_CORDER_ID" :
- "Unknown!")))))))))));
+ HDfprintf(stream, "%*s%-*s %s (%u)\n", indent, "", fwidth,
+ "Tree type ID:", hdr->cls->name, (unsigned)hdr->cls->id);
HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
"Size of node:",
- shared->node_size);
+ hdr->node_size);
HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
"Size of raw (disk) record:",
- shared->rrec_size);
+ hdr->rrec_size);
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
"Dirty flag:",
- bt2->cache_info.is_dirty ? "True" : "False");
+ hdr->cache_info.is_dirty ? "True" : "False");
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Depth:",
- shared->depth);
+ hdr->depth);
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
"Number of records in tree:",
- bt2->root.all_nrec);
+ hdr->root.all_nrec);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Number of records in root node:",
- bt2->root.node_nrec);
+ hdr->root.node_nrec);
HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
"Address of root node:",
- bt2->root.addr);
+ hdr->root.addr);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Split percent:",
- shared->split_percent);
+ hdr->split_percent);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Merge percent:",
- shared->merge_percent);
+ hdr->merge_percent);
/* Print relevant node info */
HDfprintf(stream, "%*sNode Info: (max_nrec/split_nrec/merge_nrec)\n", indent, "");
- for(u = 0; u < (shared->depth + 1); u++) {
+ for(u = 0; u < (unsigned)(hdr->depth + 1); u++) {
sprintf(temp_str, "Depth %u:", u);
HDfprintf(stream, "%*s%-*s (%u/%u/%u)\n", indent + 3, "", MAX(0, fwidth - 3),
temp_str,
- shared->node_info[u].max_nrec, shared->node_info[u].split_nrec, shared->node_info[u].merge_nrec);
+ hdr->node_info[u].max_nrec, hdr->node_info[u].split_nrec, hdr->node_info[u].merge_nrec);
} /* end for */
done:
- if(bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree header")
+ if(dbg_ctx && (type->dst_dbg_ctx)(dbg_ctx) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTRELEASE, FAIL, "unable to release v2 B-tree debugging context")
+ if(hdr) {
+ hdr->f = NULL;
+ if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree header")
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B2_hdr_debug() */
@@ -199,11 +201,11 @@ herr_t
H5B2_int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth,
const H5B2_class_t *type, haddr_t hdr_addr, unsigned nrec, unsigned depth)
{
- H5B2_t *bt2 = NULL;
- H5B2_internal_t *internal = NULL;
- H5B2_shared_t *shared; /* Shared B-tree information */
- unsigned u; /* Local index variable */
- char temp_str[128]; /* Temporary string, for formatting */
+ H5B2_hdr_t *hdr = NULL; /* B-tree header */
+ H5B2_internal_t *internal = NULL; /* B-tree internal node */
+ void *dbg_ctx = NULL; /* v2 B-tree debugging context */
+ unsigned u; /* Local index variable */
+ char temp_str[128]; /* Temporary string, for formatting */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_int_debug, FAIL)
@@ -217,30 +219,33 @@ H5B2_int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
HDassert(indent >= 0);
HDassert(fwidth >= 0);
HDassert(type);
+ HDassert((type->crt_dbg_ctx && type->dst_dbg_ctx) ||
+ (NULL == type->crt_dbg_ctx && NULL == type->dst_dbg_ctx));
HDassert(H5F_addr_defined(hdr_addr));
HDassert(nrec > 0);
+ /* Check for debugging context callback available */
+ if(type->crt_dbg_ctx) {
+ /* Create debugging context */
+ if(NULL == (dbg_ctx = (type->crt_dbg_ctx)(f, dxpl_id, addr)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "unable to create v2 B-tree debugging context")
+ } /* end if */
+
/*
* Load the B-tree header.
*/
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, type, NULL, H5AC_READ)))
+ if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, type, dbg_ctx, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree header")
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
+ /* Set file pointer for this B-tree operation */
+ hdr->f = f;
/*
* Load the B-tree internal node
*/
- if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2->shared, addr, nrec, depth, H5AC_READ)))
+ if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, addr, nrec, depth, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree internal node")
- /* Release the B-tree header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree header")
- bt2 = NULL;
-
/* Print opening message */
if(internal->depth == 1)
HDfprintf(stream, "%*sv2 B-tree Internal 'Leaf' Node...\n", indent, "");
@@ -250,25 +255,14 @@ H5B2_int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
/*
* Print the values.
*/
- HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
- "Tree type ID:",
- (shared->type->id == H5B2_TEST_ID ? "H5B2_TEST_ID" :
- (shared->type->id == H5B2_FHEAP_HUGE_INDIR_ID ? "H5B2_FHEAP_HUGE_INDIR_ID" :
- (shared->type->id == H5B2_FHEAP_HUGE_FILT_INDIR_ID ? "H5B2_FHEAP_HUGE_FILT_INDIR_ID" :
- (shared->type->id == H5B2_FHEAP_HUGE_DIR_ID ? "H5B2_FHEAP_HUGE_DIR_ID" :
- (shared->type->id == H5B2_FHEAP_HUGE_FILT_DIR_ID ? "H5B2_FHEAP_HUGE_FILT_DIR_ID" :
- (shared->type->id == H5B2_GRP_DENSE_NAME_ID ? "H5B2_GRP_DENSE_NAME_ID" :
- (shared->type->id == H5B2_GRP_DENSE_CORDER_ID ? "H5B2_GRP_DENSE_CORDER_ID" :
- (shared->type->id == H5B2_SOHM_INDEX_ID ? "H5B2_SOHM_INDEX_ID" :
- (shared->type->id == H5B2_ATTR_DENSE_NAME_ID ? "H5B2_ATTR_DENSE_NAME_ID" :
- (shared->type->id == H5B2_ATTR_DENSE_CORDER_ID ? "H5B2_ATTR_DENSE_CORDER_ID" :
- "Unknown!")))))))))));
+ HDfprintf(stream, "%*s%-*s %s (%u)\n", indent, "", fwidth,
+ "Tree type ID:", hdr->cls->name, (unsigned)hdr->cls->id);
HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
"Size of node:",
- shared->node_size);
+ hdr->node_size);
HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
"Size of raw (disk) record:",
- shared->rrec_size);
+ hdr->rrec_size);
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
"Dirty flag:",
internal->cache_info.is_dirty ? "True" : "False");
@@ -290,9 +284,9 @@ H5B2_int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
sprintf(temp_str, "Record #%u:", u);
HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
temp_str);
- HDassert(H5B2_INT_NREC(internal, shared, u));
+ HDassert(H5B2_INT_NREC(internal, hdr, u));
(void)(type->debug)(stream, f, dxpl_id, indent + 6, MAX (0, fwidth-6),
- H5B2_INT_NREC(internal,shared,u), NULL);
+ H5B2_INT_NREC(internal, hdr, u), NULL);
} /* end for */
/* Print final node pointer */
@@ -304,6 +298,13 @@ H5B2_int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
internal->node_ptrs[u].addr);
done:
+ if(dbg_ctx && (type->dst_dbg_ctx)(dbg_ctx) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTRELEASE, FAIL, "unable to release v2 B-tree debugging context")
+ if(hdr) {
+ hdr->f = NULL;
+ if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree header")
+ } /* end if */
if(internal && H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, addr, internal, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree internal node")
@@ -328,12 +329,12 @@ herr_t
H5B2_leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth,
const H5B2_class_t *type, haddr_t hdr_addr, unsigned nrec)
{
- H5B2_t *bt2 = NULL;
- H5B2_leaf_t *leaf = NULL;
- H5B2_shared_t *shared; /* Shared B-tree information */
- unsigned u; /* Local index variable */
- char temp_str[128]; /* Temporary string, for formatting */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5B2_hdr_t *hdr = NULL; /* B-tree header */
+ H5B2_leaf_t *leaf = NULL; /* B-tree leaf node */
+ void *dbg_ctx = NULL; /* v2 B-tree debugging context */
+ unsigned u; /* Local index variable */
+ char temp_str[128]; /* Temporary string, for formatting */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_leaf_debug, FAIL)
@@ -346,55 +347,47 @@ H5B2_leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
HDassert(indent >= 0);
HDassert(fwidth >= 0);
HDassert(type);
+ HDassert((type->crt_dbg_ctx && type->dst_dbg_ctx) ||
+ (NULL == type->crt_dbg_ctx && NULL == type->dst_dbg_ctx));
HDassert(H5F_addr_defined(hdr_addr));
HDassert(nrec > 0);
+ /* Check for debugging context callback available */
+ if(type->crt_dbg_ctx) {
+ /* Create debugging context */
+ if(NULL == (dbg_ctx = (type->crt_dbg_ctx)(f, dxpl_id, addr)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "unable to create v2 B-tree debugging context")
+ } /* end if */
+
/*
* Load the B-tree header.
*/
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, type, NULL, H5AC_READ)))
+ if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, type, dbg_ctx, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree header")
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
+ /* Set file pointer for this B-tree operation */
+ hdr->f = f;
/*
* Load the B-tree leaf node
*/
- if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, addr, &nrec, bt2->shared, H5AC_READ)))
+ if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, addr, &nrec, hdr, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree leaf node")
- /* Release the B-tree header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree header")
- bt2 = NULL;
-
/* Print opening message */
HDfprintf(stream, "%*sv2 B-tree Leaf Node...\n", indent, "");
/*
* Print the values.
*/
- HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
- "Tree type ID:",
- (shared->type->id == H5B2_TEST_ID ? "H5B2_TEST_ID" :
- (shared->type->id == H5B2_FHEAP_HUGE_INDIR_ID ? "H5B2_FHEAP_HUGE_INDIR_ID" :
- (shared->type->id == H5B2_FHEAP_HUGE_FILT_INDIR_ID ? "H5B2_FHEAP_HUGE_FILT_INDIR_ID" :
- (shared->type->id == H5B2_FHEAP_HUGE_DIR_ID ? "H5B2_FHEAP_HUGE_DIR_ID" :
- (shared->type->id == H5B2_FHEAP_HUGE_FILT_DIR_ID ? "H5B2_FHEAP_HUGE_FILT_DIR_ID" :
- (shared->type->id == H5B2_GRP_DENSE_NAME_ID ? "H5B2_GRP_DENSE_NAME_ID" :
- (shared->type->id == H5B2_GRP_DENSE_CORDER_ID ? "H5B2_GRP_DENSE_CORDER_ID" :
- (shared->type->id == H5B2_SOHM_INDEX_ID ? "H5B2_SOHM_INDEX_ID" :
- (shared->type->id == H5B2_ATTR_DENSE_NAME_ID ? "H5B2_ATTR_DENSE_NAME_ID" :
- (shared->type->id == H5B2_ATTR_DENSE_CORDER_ID ? "H5B2_ATTR_DENSE_CORDER_ID" :
- "Unknown!")))))))))));
+ HDfprintf(stream, "%*s%-*s %s (%u)\n", indent, "", fwidth,
+ "Tree type ID:", hdr->cls->name, (unsigned)hdr->cls->id);
HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
"Size of node:",
- shared->node_size);
+ hdr->node_size);
HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
"Size of raw (disk) record:",
- shared->rrec_size);
+ hdr->rrec_size);
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
"Dirty flag:",
leaf->cache_info.is_dirty ? "True" : "False");
@@ -408,12 +401,19 @@ H5B2_leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
sprintf(temp_str, "Record #%u:", u);
HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
temp_str);
- HDassert(H5B2_LEAF_NREC(leaf, shared, u));
- (void)(type->debug)(stream, f, dxpl_id, indent+6, MAX (0, fwidth-6),
- H5B2_LEAF_NREC(leaf,shared,u), NULL);
+ HDassert(H5B2_LEAF_NREC(leaf, hdr, u));
+ (void)(type->debug)(stream, f, dxpl_id, indent + 6, MAX (0, fwidth-6),
+ H5B2_LEAF_NREC(leaf, hdr, u), NULL);
} /* end for */
done:
+ if(dbg_ctx && (type->dst_dbg_ctx)(dbg_ctx) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTRELEASE, FAIL, "unable to release v2 B-tree debugging context")
+ if(hdr) {
+ hdr->f = NULL;
+ if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree header")
+ } /* end if */
if(leaf && H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree leaf node")
diff --git a/src/H5B2hdr.c b/src/H5B2hdr.c
new file mode 100644
index 0000000..f1d5d84
--- /dev/null
+++ b/src/H5B2hdr.c
@@ -0,0 +1,613 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5B2int.c
+ * Feb 27 2006
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: Internal routines for managing v2 B-trees.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5B2_PACKAGE /*suppress error about including H5B2pkg */
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5B2pkg.h" /* v2 B-trees */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5MFprivate.h" /* File memory management */
+#include "H5Vprivate.h" /* Vectors and arrays */
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* Number of records that fit into leaf node */
+#define H5B2_NUM_LEAF_REC(n, r) \
+ (((n) - H5B2_LEAF_PREFIX_SIZE) / (r))
+
+/* Uncomment this macro to enable extra sanity checking */
+/* #define H5B2_DEBUG */
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5B2_hdr_t struct */
+H5FL_DEFINE_STATIC(H5B2_hdr_t);
+
+/* Declare a free list to manage B-tree node pages to/from disk */
+H5FL_BLK_DEFINE_STATIC(node_page);
+
+/* Declare a free list to manage the 'size_t' sequence information */
+H5FL_SEQ_DEFINE_STATIC(size_t);
+
+/* Declare a free list to manage the 'H5B2_node_info_t' sequence information */
+H5FL_SEQ_DEFINE(H5B2_node_info_t);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_hdr_init
+ *
+ * Purpose: Allocate & initialize B-tree header info
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Feb 2 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_hdr_init(H5F_t *f, H5B2_hdr_t *hdr, const H5B2_create_t *cparam,
+ void *ctx_udata, uint16_t depth)
+{
+ size_t sz_max_nrec; /* Temporary variable for range checking */
+ unsigned u_max_nrec_size; /* Temporary variable for range checking */
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_init)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(hdr);
+ HDassert(cparam);
+ HDassert(cparam->cls);
+ HDassert((cparam->cls->crt_context && cparam->cls->dst_context) ||
+ (NULL == cparam->cls->crt_context && NULL == cparam->cls->dst_context));
+ HDassert(cparam->node_size > 0);
+ HDassert(cparam->rrec_size > 0);
+ HDassert(cparam->merge_percent > 0 && cparam->merge_percent <= 100);
+ HDassert(cparam->split_percent > 0 && cparam->split_percent <= 100);
+ HDassert(cparam->merge_percent < (cparam->split_percent / 2));
+
+ /* Initialize basic information */
+ hdr->f = f;
+ hdr->rc = 0;
+ hdr->pending_delete = FALSE;
+
+ /* Assign dynamic information */
+ hdr->depth = depth;
+
+ /* Assign user's information */
+ hdr->split_percent = cparam->split_percent;
+ hdr->merge_percent = cparam->merge_percent;
+ hdr->node_size = cparam->node_size;
+ hdr->rrec_size = cparam->rrec_size;
+
+ /* Assign common type information */
+ hdr->cls = cparam->cls;
+
+ /* Allocate "page" for node I/O */
+ if(NULL == (hdr->page = H5FL_BLK_MALLOC(node_page, hdr->node_size)))
+ HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, FAIL, "memory allocation failed")
+#ifdef H5_CLEAR_MEMORY
+HDmemset(hdr->page, 0, hdr->node_size);
+#endif /* H5_CLEAR_MEMORY */
+
+ /* Allocate array of node info structs */
+ if(NULL == (hdr->node_info = H5FL_SEQ_MALLOC(H5B2_node_info_t, (size_t)(hdr->depth + 1))))
+ HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Initialize leaf node info */
+ sz_max_nrec = H5B2_NUM_LEAF_REC(hdr->node_size, hdr->rrec_size);
+ H5_ASSIGN_OVERFLOW(/* To: */ hdr->node_info[0].max_nrec, /* From: */ sz_max_nrec, /* From: */ size_t, /* To: */ unsigned)
+ hdr->node_info[0].split_nrec = (hdr->node_info[0].max_nrec * hdr->split_percent) / 100;
+ hdr->node_info[0].merge_nrec = (hdr->node_info[0].max_nrec * hdr->merge_percent) / 100;
+ hdr->node_info[0].cum_max_nrec = hdr->node_info[0].max_nrec;
+ hdr->node_info[0].cum_max_nrec_size = 0;
+ if(NULL == (hdr->node_info[0].nat_rec_fac = H5FL_fac_init(hdr->cls->nrec_size * hdr->node_info[0].max_nrec)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't create node native key block factory")
+ hdr->node_info[0].node_ptr_fac = NULL;
+
+ /* Allocate array of pointers to internal node native keys */
+ /* (uses leaf # of records because its the largest) */
+ if(NULL == (hdr->nat_off = H5FL_SEQ_MALLOC(size_t, (size_t)hdr->node_info[0].max_nrec)))
+ HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Initialize offsets in native key block */
+ /* (uses leaf # of records because its the largest) */
+ for(u = 0; u < hdr->node_info[0].max_nrec; u++)
+ hdr->nat_off[u] = hdr->cls->nrec_size * u;
+
+ /* Compute size to store # of records in each node */
+ /* (uses leaf # of records because its the largest) */
+ u_max_nrec_size = H5V_limit_enc_size((uint64_t)hdr->node_info[0].max_nrec);
+ H5_ASSIGN_OVERFLOW(/* To: */ hdr->max_nrec_size, /* From: */ u_max_nrec_size, /* From: */ unsigned, /* To: */ uint8_t)
+ HDassert(hdr->max_nrec_size <= H5B2_SIZEOF_RECORDS_PER_NODE);
+
+ /* Initialize internal node info */
+ if(depth > 0) {
+ for(u = 1; u < (unsigned)(depth + 1); u++) {
+ sz_max_nrec = H5B2_NUM_INT_REC(hdr, u);
+ H5_ASSIGN_OVERFLOW(/* To: */ hdr->node_info[u].max_nrec, /* From: */ sz_max_nrec, /* From: */ size_t, /* To: */ unsigned)
+ HDassert(hdr->node_info[u].max_nrec <= hdr->node_info[u - 1].max_nrec);
+
+ hdr->node_info[u].split_nrec = (hdr->node_info[u].max_nrec * hdr->split_percent) / 100;
+ hdr->node_info[u].merge_nrec = (hdr->node_info[u].max_nrec * hdr->merge_percent) / 100;
+
+ hdr->node_info[u].cum_max_nrec = ((hdr->node_info[u].max_nrec + 1) *
+ hdr->node_info[u - 1].cum_max_nrec) + hdr->node_info[u].max_nrec;
+ u_max_nrec_size = H5V_limit_enc_size((uint64_t)hdr->node_info[u].cum_max_nrec);
+ H5_ASSIGN_OVERFLOW(/* To: */ hdr->node_info[u].cum_max_nrec_size, /* From: */ u_max_nrec_size, /* From: */ unsigned, /* To: */ uint8_t)
+
+ if(NULL == (hdr->node_info[u].nat_rec_fac = H5FL_fac_init(hdr->cls->nrec_size * hdr->node_info[u].max_nrec)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't create node native key block factory")
+ if(NULL == (hdr->node_info[u].node_ptr_fac = H5FL_fac_init(sizeof(H5B2_node_ptr_t) * (hdr->node_info[u].max_nrec + 1))))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't create internal 'branch' node node pointer block factory")
+ } /* end for */
+ } /* end if */
+
+ /* Create the callback context, if the callback exists */
+ if(hdr->cls->crt_context) {
+ if(NULL == (hdr->cb_ctx = (*hdr->cls->crt_context)(ctx_udata)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTCREATE, FAIL, "unable to create v2 B-tree client callback context")
+ } /* end if */
+
+done:
+ if(ret_value < 0)
+ if(H5B2_hdr_free(hdr) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free shared v2 B-tree info")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B2_hdr_init() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_hdr_alloc
+ *
+ * Purpose: Allocate B-tree header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 27 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+H5B2_hdr_t *
+H5B2_hdr_alloc(H5F_t *f)
+{
+ H5B2_hdr_t *hdr = NULL; /* v2 B-tree header */
+ H5B2_hdr_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_alloc)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+
+ /* Allocate space for the shared information */
+ if(NULL == (hdr = H5FL_CALLOC(H5B2_hdr_t)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "memory allocation failed for B-tree header")
+
+ /* Assign non-zero information */
+ hdr->f = f;
+ hdr->sizeof_addr = H5F_SIZEOF_ADDR(f);
+ hdr->sizeof_size = H5F_SIZEOF_SIZE(f);
+ hdr->root.addr = HADDR_UNDEF;
+
+ /* Set return value */
+ ret_value = hdr;
+
+done:
+ if(!ret_value && hdr)
+ if(H5B2_hdr_free(hdr) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, NULL, "unable to free shared v2 B-tree info")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B2_hdr_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_hdr_create
+ *
+ * Purpose: Create new fractal heap header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Mar 21 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+haddr_t
+H5B2_hdr_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam,
+ void *ctx_udata)
+{
+ H5B2_hdr_t *hdr = NULL; /* The new v2 B-tree header information */
+ haddr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_create)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(cparam);
+
+ /* Allocate v2 B-tree header */
+ if(NULL == (hdr = H5B2_hdr_alloc(f)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, HADDR_UNDEF, "allocation failed for B-tree header")
+
+ /* Initialize shared B-tree info */
+ if(H5B2_hdr_init(f, hdr, cparam, ctx_udata, (uint16_t)0) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, HADDR_UNDEF, "can't create shared B-tree info")
+
+ /* Allocate space for the header on disk */
+ if(HADDR_UNDEF == (hdr->addr = H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)H5B2_HEADER_SIZE(hdr))))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, HADDR_UNDEF, "file allocation failed for B-tree header")
+
+ /* Cache the new B-tree node */
+ if(H5AC_set(f, dxpl_id, H5AC_BT2_HDR, hdr->addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, HADDR_UNDEF, "can't add B-tree header to cache")
+
+ /* Set address of v2 B-tree header to return */
+ ret_value = hdr->addr;
+
+done:
+ if(!H5F_addr_defined(ret_value) && hdr)
+ if(H5B2_hdr_free(hdr) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTRELEASE, HADDR_UNDEF, "unable to release v2 B-tree header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B2_hdr_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_hdr_incr
+ *
+ * Purpose: Increment reference count on B-tree header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 13 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_hdr_incr(H5B2_hdr_t *hdr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_incr)
+
+ /* Sanity checks */
+ HDassert(hdr);
+ HDassert(hdr->f);
+
+ /* Mark header as un-evictable when a B-tree node is depending on it */
+ if(hdr->rc == 0)
+ if(H5AC_pin_protected_entry(hdr->f, hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTPIN, FAIL, "unable to pin v2 B-tree header")
+
+ /* Increment reference count on B-tree header */
+ hdr->rc++;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B2_incr_hdr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_hdr_decr
+ *
+ * Purpose: Decrement reference count on B-tree header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 13 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_hdr_decr(H5B2_hdr_t *hdr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_decr)
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(hdr->f);
+ HDassert(hdr->rc > 0);
+
+ /* Decrement reference count on B-tree header */
+ hdr->rc--;
+
+ /* Mark header as evictable again when no nodes depend on it */
+ if(hdr->rc == 0)
+ if(H5AC_unpin_entry(hdr->f, hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPIN, FAIL, "unable to unpin v2 B-tree header")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B2_hdr_decr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_hdr_fuse_incr
+ *
+ * Purpose: Increment file reference count on shared v2 B-tree header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 27 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_hdr_fuse_incr(H5B2_hdr_t *hdr)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_hdr_fuse_incr)
+
+ /* Sanity check */
+ HDassert(hdr);
+
+ /* Increment file reference count on shared header */
+ hdr->file_rc++;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5B2_hdr_fuse_incr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_hdr_fuse_decr
+ *
+ * Purpose: Decrement file reference count on shared v2 B-tree header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 27 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5B2_hdr_fuse_decr(H5B2_hdr_t *hdr)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_hdr_fuse_decr)
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(hdr->file_rc);
+
+ /* Decrement file reference count on shared header */
+ hdr->file_rc--;
+
+ FUNC_LEAVE_NOAPI(hdr->file_rc)
+} /* end H5B2_hdr_fuse_decr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_hdr_dirty
+ *
+ * Purpose: Mark B-tree header as dirty
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 13 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_hdr_dirty(H5B2_hdr_t *hdr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_dirty)
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(hdr->f);
+
+ /* Mark B-tree header as dirty in cache */
+ if(H5AC_mark_pinned_or_protected_entry_dirty(hdr->f, hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTMARKDIRTY, FAIL, "unable to mark v2 B-tree header as dirty")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B2_hdr_dirty() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_hdr_free
+ *
+ * Purpose: Free B-tree header info
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Feb 2 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_hdr_free(H5B2_hdr_t *hdr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_free)
+
+ /* Sanity check */
+ HDassert(hdr);
+
+ /* Destroy the callback context */
+ if(hdr->cb_ctx) {
+ if((*hdr->cls->dst_context)(hdr->cb_ctx) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTRELEASE, FAIL, "can't destroy v2 B-tree client callback context")
+ hdr->cb_ctx = NULL;
+ } /* end if */
+
+ /* Free the B-tree node buffer */
+ if(hdr->page)
+ (void)H5FL_BLK_FREE(node_page, hdr->page);
+
+ /* Free the array of offsets into the native key block */
+ if(hdr->nat_off)
+ hdr->nat_off = H5FL_SEQ_FREE(size_t, hdr->nat_off);
+
+ /* Release the node info */
+ if(hdr->node_info) {
+ unsigned u; /* Local index variable */
+
+ /* Destroy free list factories */
+ for(u = 0; u < (unsigned)(hdr->depth + 1); u++) {
+ if(hdr->node_info[u].nat_rec_fac)
+ if(H5FL_fac_term(hdr->node_info[u].nat_rec_fac) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTRELEASE, FAIL, "can't destroy node's native record block factory")
+ if(hdr->node_info[u].node_ptr_fac)
+ if(H5FL_fac_term(hdr->node_info[u].node_ptr_fac) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTRELEASE, FAIL, "can't destroy node's node pointer block factory")
+ } /* end for */
+
+ /* Free the array of node info structs */
+ hdr->node_info = H5FL_SEQ_FREE(H5B2_node_info_t, hdr->node_info);
+ } /* end if */
+
+ /* Free B-tree header info */
+ (void)H5FL_FREE(H5B2_hdr_t, hdr);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B2_hdr_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_hdr_delete
+ *
+ * Purpose: Delete a v2 B-tree, starting with the header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 15 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_hdr_delete(H5B2_hdr_t *hdr, hid_t dxpl_id)
+{
+ unsigned cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting v2 B-tree header */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5B2_hdr_delete, FAIL)
+
+ /* Sanity check */
+ HDassert(hdr);
+
+#ifndef NDEBUG
+{
+ unsigned hdr_status = 0; /* v2 B-tree header's status in the metadata cache */
+
+ /* Check the v2 B-tree header's status in the metadata cache */
+ if(H5AC_get_entry_status(hdr->f, hdr->addr, &hdr_status) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "unable to check metadata cache status for v2 B-tree header")
+
+ /* Sanity checks on v2 B-tree header */
+ HDassert(hdr_status & H5AC_ES__IN_CACHE);
+ HDassert(hdr_status & H5AC_ES__IS_PROTECTED);
+} /* end block */
+#endif /* NDEBUG */
+
+ /* Delete all nodes in B-tree */
+ if(H5F_addr_defined(hdr->root.addr))
+ if(H5B2_delete_node(hdr, dxpl_id, hdr->depth, &hdr->root, hdr->remove_op, hdr->remove_op_data) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete B-tree nodes")
+
+ /* Indicate that the heap header should be deleted & file space freed */
+ cache_flags |= H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG;
+
+done:
+ /* Unprotect the header with appropriate flags */
+ if(hdr && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_HDR, hdr->addr, hdr, cache_flags) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header")
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5B2_hdr_delete() */
+
diff --git a/src/H5B2int.c b/src/H5B2int.c
index c192c65..f7312a5 100644
--- a/src/H5B2int.c
+++ b/src/H5B2int.c
@@ -43,15 +43,6 @@
/* Local Macros */
/****************/
-/* Number of records that fit into internal node */
-/* (accounts for extra node pointer by counting it in with the prefix bytes) */
-#define H5B2_NUM_INT_REC(f, s, d) \
- (((s)->node_size - (H5B2_INT_PREFIX_SIZE + H5B2_INT_POINTER_SIZE(f, s, d))) / ((s)->rrec_size + H5B2_INT_POINTER_SIZE(f, s, d)))
-
-/* Number of records that fit into leaf node */
-#define H5B2_NUM_LEAF_REC(n, r) \
- (((n) - H5B2_LEAF_PREFIX_SIZE) / (r))
-
/* Uncomment this macro to enable extra sanity checking */
/* #define H5B2_DEBUG */
@@ -70,30 +61,29 @@
/********************/
/* Helper functions */
-static herr_t H5B2_shared_free(void *_shared);
-static herr_t H5B2_create_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
+static herr_t H5B2_create_internal(H5B2_hdr_t *hdr, hid_t dxpl_id,
H5B2_node_ptr_t *node_ptr, unsigned depth);
-static herr_t H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth,
+static herr_t H5B2_split1(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
H5B2_node_ptr_t *curr_node_ptr, unsigned *parent_cache_info_flags_ptr,
H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx);
-static herr_t H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth,
+static herr_t H5B2_redistribute2(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
H5B2_internal_t *internal, unsigned idx);
-static herr_t H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth,
+static herr_t H5B2_redistribute3(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx);
-static herr_t H5B2_merge2(H5F_t *f, hid_t dxpl_id, unsigned depth,
+static herr_t H5B2_merge2(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
H5B2_node_ptr_t *curr_node_ptr, unsigned *parent_cache_info_flags_ptr,
H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx);
-static herr_t H5B2_merge3(H5F_t *f, hid_t dxpl_id, unsigned depth,
+static herr_t H5B2_merge3(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
H5B2_node_ptr_t *curr_node_ptr, unsigned *parent_cache_info_flags_ptr,
H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx);
-static herr_t H5B2_swap_leaf(H5F_t *f, hid_t dxpl_id, unsigned depth,
+static herr_t H5B2_swap_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
H5B2_internal_t *internal, unsigned *internal_flags_ptr,
unsigned idx, void *swap_loc);
#ifdef H5B2_DEBUG
-static herr_t H5B2_assert_leaf(H5B2_shared_t *shared, H5B2_leaf_t *leaf);
-static herr_t H5B2_assert_leaf2(H5B2_shared_t *shared, H5B2_leaf_t *leaf, H5B2_leaf_t *leaf2);
-static herr_t H5B2_assert_internal(hsize_t parent_all_nrec, H5B2_shared_t *shared, H5B2_internal_t *internal);
-static herr_t H5B2_assert_internal2(hsize_t parent_all_nrec, H5B2_shared_t *shared, H5B2_internal_t *internal, H5B2_internal_t *internal2);
+static herr_t H5B2_assert_leaf(H5B2_hdr_t *hdr, H5B2_leaf_t *leaf);
+static herr_t H5B2_assert_leaf2(H5B2_hdr_t *hdr, H5B2_leaf_t *leaf, H5B2_leaf_t *leaf2);
+static herr_t H5B2_assert_internal(hsize_t parent_all_nrec, H5B2_hdr_t *hdr, H5B2_internal_t *internal);
+static herr_t H5B2_assert_internal2(hsize_t parent_all_nrec, H5B2_hdr_t *hdr, H5B2_internal_t *internal, H5B2_internal_t *internal2);
#endif /* H5B2_DEBUG */
/*********************/
@@ -116,194 +106,12 @@ H5FL_DEFINE(H5B2_leaf_t);
/* Local Variables */
/*******************/
-/* Declare a free list to manage B-tree node pages to/from disk */
-H5FL_BLK_DEFINE_STATIC(node_page);
-
-/* Declare a free list to manage the 'size_t' sequence information */
-H5FL_SEQ_DEFINE_STATIC(size_t);
-
/* Declare a free list to manage the 'H5B2_node_info_t' sequence information */
-H5FL_SEQ_DEFINE_STATIC(H5B2_node_info_t);
-
-/* Declare a free list to manage the H5B2_shared_t struct */
-H5FL_DEFINE_STATIC(H5B2_shared_t);
+H5FL_SEQ_EXTERN(H5B2_node_info_t);
/*-------------------------------------------------------------------------
- * Function: H5B2_shared_init
- *
- * Purpose: Allocate & initialize shared B-tree info
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Feb 2 2005
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5B2_shared_init (H5F_t *f, H5B2_t *bt2, const H5B2_class_t *type,
- unsigned depth, size_t node_size, size_t rrec_size,
- unsigned split_percent, unsigned merge_percent)
-{
- H5B2_shared_t *shared = NULL; /* Shared B-tree information */
- size_t sz_max_nrec; /* Temporary variable for range checking */
- unsigned u_max_nrec_size; /* Temporary variable for range checking */
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5B2_shared_init)
-
- /* Allocate space for the shared information */
- if(NULL == (shared = H5FL_CALLOC(H5B2_shared_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree shared information")
-
- /* Assign dynamic information */
- shared->depth = depth;
-
- /* Assign user's information */
- shared->split_percent = split_percent;
- shared->merge_percent = merge_percent;
- shared->node_size = node_size;
- shared->rrec_size = rrec_size;
-
- /* Assign common type information */
- shared->type = type;
-
- /* Allocate "page" for node I/O */
- if((shared->page = H5FL_BLK_MALLOC(node_page, shared->node_size)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
-#ifdef H5_CLEAR_MEMORY
-HDmemset(shared->page, 0, shared->node_size);
-#endif /* H5_CLEAR_MEMORY */
-
- /* Allocate array of node info structs */
- if((shared->node_info = H5FL_SEQ_MALLOC(H5B2_node_info_t, (size_t)(shared->depth + 1))) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
-
- /* Initialize leaf node info */
- sz_max_nrec = H5B2_NUM_LEAF_REC(shared->node_size, shared->rrec_size);
- H5_ASSIGN_OVERFLOW(/* To: */ shared->node_info[0].max_nrec, /* From: */ sz_max_nrec, /* From: */ size_t, /* To: */ unsigned)
- shared->node_info[0].split_nrec = (shared->node_info[0].max_nrec * shared->split_percent) / 100;
- shared->node_info[0].merge_nrec = (shared->node_info[0].max_nrec * shared->merge_percent) / 100;
- shared->node_info[0].cum_max_nrec = shared->node_info[0].max_nrec;
- shared->node_info[0].cum_max_nrec_size = 0;
- if((shared->node_info[0].nat_rec_fac = H5FL_fac_init(type->nrec_size * shared->node_info[0].max_nrec)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create node native key block factory")
- shared->node_info[0].node_ptr_fac = NULL;
-
- /* Allocate array of pointers to internal node native keys */
- /* (uses leaf # of records because its the largest) */
- if((shared->nat_off = H5FL_SEQ_MALLOC(size_t, (size_t)shared->node_info[0].max_nrec)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
-
- /* Initialize offsets in native key block */
- /* (uses leaf # of records because its the largest) */
- for(u = 0; u < shared->node_info[0].max_nrec; u++)
- shared->nat_off[u] = type->nrec_size * u;
-
- /* Compute size to store # of records in each node */
- /* (uses leaf # of records because its the largest) */
- u_max_nrec_size = H5V_limit_enc_size((uint64_t)shared->node_info[0].max_nrec);
- H5_ASSIGN_OVERFLOW(/* To: */ shared->max_nrec_size, /* From: */ u_max_nrec_size, /* From: */ unsigned, /* To: */ unsigned char)
- HDassert(shared->max_nrec_size <= H5B2_SIZEOF_RECORDS_PER_NODE);
-
- /* Initialize internal node info */
- if(depth > 0) {
- for(u = 1; u < (depth + 1); u++) {
- sz_max_nrec = H5B2_NUM_INT_REC(f, shared, u);
- H5_ASSIGN_OVERFLOW(/* To: */ shared->node_info[u].max_nrec, /* From: */ sz_max_nrec, /* From: */ size_t, /* To: */ unsigned)
- HDassert(shared->node_info[u].max_nrec <= shared->node_info[u - 1].max_nrec);
-
- shared->node_info[u].split_nrec = (shared->node_info[u].max_nrec * shared->split_percent) / 100;
- shared->node_info[u].merge_nrec = (shared->node_info[u].max_nrec * shared->merge_percent) / 100;
-
- shared->node_info[u].cum_max_nrec = ((shared->node_info[u].max_nrec + 1) *
- shared->node_info[u - 1].cum_max_nrec) + shared->node_info[u].max_nrec;
- u_max_nrec_size = H5V_limit_enc_size((uint64_t)shared->node_info[u].cum_max_nrec);
- H5_ASSIGN_OVERFLOW(/* To: */ shared->node_info[u].cum_max_nrec_size, /* From: */ u_max_nrec_size, /* From: */ unsigned, /* To: */ unsigned char)
-
- if((shared->node_info[u].nat_rec_fac = H5FL_fac_init(shared->type->nrec_size * shared->node_info[u].max_nrec)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create node native key block factory")
- if((shared->node_info[u].node_ptr_fac = H5FL_fac_init(sizeof(H5B2_node_ptr_t) * (shared->node_info[u].max_nrec + 1))) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create internal 'branch' node node pointer block factory")
- } /* end for */
- } /* end if */
-
- /* Make shared B-tree info reference counted */
- if(NULL == (bt2->shared = H5RC_create(shared, H5B2_shared_free)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared B-tree info")
-
-done:
- if(ret_value < 0)
- if(shared)
- H5B2_shared_free(shared);
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5B2_shared_init() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5B2_shared_free
- *
- * Purpose: Free shared B-tree info
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Feb 2 2005
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5B2_shared_free(void *_shared)
-{
- H5B2_shared_t *shared = (H5B2_shared_t *)_shared;
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI_NOINIT(H5B2_shared_free)
-
- /* Sanity check */
- HDassert(shared);
-
- /* Free the B-tree node buffer */
- if(shared->page)
- (void)H5FL_BLK_FREE(node_page, shared->page);
-
- /* Free the array of offsets into the native key block */
- if(shared->nat_off)
- H5FL_SEQ_FREE(size_t, shared->nat_off);
-
- /* Release the node info */
- if(shared->node_info) {
- unsigned u; /* Local index variable */
-
- /* Destroy free list factories */
- for(u = 0; u < (shared->depth + 1); u++) {
- if(shared->node_info[u].nat_rec_fac)
- if(H5FL_fac_term(shared->node_info[u].nat_rec_fac) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's native record block factory")
- if(shared->node_info[u].node_ptr_fac)
- if(H5FL_fac_term(shared->node_info[u].node_ptr_fac) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's node pointer block factory")
- } /* end for */
-
- /* Free the array of node info structs */
- H5FL_SEQ_FREE(H5B2_node_info_t, shared->node_info);
- } /* end if */
-
- /* Free the shared B-tree info itself */
- H5FL_FREE(H5B2_shared_t, shared);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5B2_shared_free() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5B2_locate_record
*
* Purpose: Performs a binary search to locate a record in a sorted
@@ -345,7 +153,7 @@ H5B2_locate_record(const H5B2_class_t *type, unsigned nrec, size_t *rec_off,
*idx = my_idx;
- FUNC_LEAVE_NOAPI(cmp);
+ FUNC_LEAVE_NOAPI(cmp)
} /* end H5B2_locate_record */
@@ -364,35 +172,30 @@ H5B2_locate_record(const H5B2_class_t *type, unsigned nrec, size_t *rec_off,
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ptr,
+H5B2_split1(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ptr,
unsigned *parent_cache_info_flags_ptr, H5B2_internal_t *internal,
unsigned *internal_flags_ptr, unsigned idx)
{
const H5AC_class_t *child_class; /* Pointer to child node's class info */
haddr_t left_addr, right_addr; /* Addresses of left & right child nodes */
void *left_child, *right_child; /* Pointers to child nodes */
- unsigned *left_nrec, *right_nrec; /* Pointers to child # of records */
+ uint16_t *left_nrec, *right_nrec; /* Pointers to child # of records */
uint8_t *left_native, *right_native;/* Pointers to childs' native records */
- H5B2_node_ptr_t *left_node_ptrs=NULL, *right_node_ptrs=NULL;/* Pointers to childs' node pointer info */
- H5B2_shared_t *shared; /* B-tree's shared info */
- unsigned mid_record; /* Index of "middle" record in current node */
- unsigned old_node_nrec; /* Number of records in internal node split */
+ H5B2_node_ptr_t *left_node_ptrs = NULL, *right_node_ptrs = NULL;/* Pointers to childs' node pointer info */
+ uint16_t mid_record; /* Index of "middle" record in current node */
+ uint16_t old_node_nrec; /* Number of records in internal node split */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5B2_split1)
- HDassert(f);
- HDassert(parent_cache_info_flags_ptr);
+ /* Check arguments. */
+ HDassert(hdr);
HDassert(internal);
HDassert(internal_flags_ptr);
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(internal->shared);
- HDassert(shared);
-
/* Slide records in parent node up one space, to make room for promoted record */
if(idx < internal->nrec) {
- HDmemmove(H5B2_INT_NREC(internal, shared, idx + 1), H5B2_INT_NREC(internal, shared, idx), shared->type->nrec_size * (internal->nrec - idx));
+ HDmemmove(H5B2_INT_NREC(internal, hdr, idx + 1), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size * (internal->nrec - idx));
HDmemmove(&(internal->node_ptrs[idx + 2]), &(internal->node_ptrs[idx + 1]), sizeof(H5B2_node_ptr_t) * (internal->nrec - idx));
} /* end if */
@@ -402,7 +205,7 @@ H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_
/* Create new internal node */
internal->node_ptrs[idx + 1].all_nrec = internal->node_ptrs[idx + 1].node_nrec = 0;
- if(H5B2_create_internal(f, dxpl_id, internal->shared, &(internal->node_ptrs[idx + 1]), (depth - 1)) < 0)
+ if(H5B2_create_internal(hdr, dxpl_id, &(internal->node_ptrs[idx + 1]), (depth - 1)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to create new internal node")
/* Setup information for unlocking child nodes */
@@ -411,9 +214,9 @@ H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_
right_addr = internal->node_ptrs[idx + 1].addr;
/* Protect both leafs */
- if(NULL == (left_int = H5B2_protect_internal(f, dxpl_id, internal->shared, left_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE)))
+ if(NULL == (left_int = H5B2_protect_internal(hdr, dxpl_id, left_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
- if(NULL == (right_int = H5B2_protect_internal(f, dxpl_id, internal->shared, right_addr, internal->node_ptrs[idx + 1].node_nrec, (depth - 1), H5AC_WRITE)))
+ if(NULL == (right_int = H5B2_protect_internal(hdr, dxpl_id, right_addr, internal->node_ptrs[idx + 1].node_nrec, (depth - 1), H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* More setup for child nodes */
@@ -431,7 +234,7 @@ H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_
/* Create new leaf node */
internal->node_ptrs[idx + 1].all_nrec = internal->node_ptrs[idx + 1].node_nrec = 0;
- if(H5B2_create_leaf(f, dxpl_id, internal->shared, &(internal->node_ptrs[idx + 1])) < 0)
+ if(H5B2_create_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx + 1])) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to create new leaf node")
/* Setup information for unlocking child nodes */
@@ -440,9 +243,9 @@ H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_
right_addr = internal->node_ptrs[idx + 1].addr;
/* Protect both leafs */
- if(NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx].node_nrec), internal->shared, H5AC_WRITE)))
+ if(NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx].node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
- if(NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx + 1].node_nrec), internal->shared, H5AC_WRITE)))
+ if(NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx + 1].node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
/* More setup for child nodes */
@@ -461,21 +264,21 @@ H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_
mid_record = old_node_nrec / 2;
/* Copy "upper half" of records to new child */
- HDmemcpy(H5B2_NAT_NREC(right_native, shared, 0),
- H5B2_NAT_NREC(left_native, shared, mid_record + 1),
- shared->type->nrec_size * (old_node_nrec - (mid_record + 1)));
+ HDmemcpy(H5B2_NAT_NREC(right_native, hdr, 0),
+ H5B2_NAT_NREC(left_native, hdr, mid_record + (unsigned)1),
+ hdr->cls->nrec_size * (old_node_nrec - (mid_record + (unsigned)1)));
/* Copy "upper half" of node pointers, if the node is an internal node */
if(depth > 1)
- HDmemcpy(&(right_node_ptrs[0]), &(left_node_ptrs[mid_record + 1]),
+ HDmemcpy(&(right_node_ptrs[0]), &(left_node_ptrs[mid_record + (unsigned)1]),
sizeof(H5B2_node_ptr_t) * (old_node_nrec - mid_record));
/* Copy "middle" record to internal node */
- HDmemcpy(H5B2_INT_NREC(internal, shared, idx), H5B2_NAT_NREC(left_native, shared, mid_record), shared->type->nrec_size);
+ HDmemcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(left_native, hdr, mid_record), hdr->cls->nrec_size);
/* Update record counts in child nodes */
internal->node_ptrs[idx].node_nrec = *left_nrec = mid_record;
- internal->node_ptrs[idx + 1].node_nrec = *right_nrec = old_node_nrec - (mid_record + 1);
+ internal->node_ptrs[idx + 1].node_nrec = *right_nrec = old_node_nrec - (mid_record + (unsigned)1);
/* Determine total number of records in new child nodes */
if(depth > 1) {
@@ -485,11 +288,11 @@ H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_
/* Compute total of all records in each child node */
new_left_all_nrec = internal->node_ptrs[idx].node_nrec;
- for(u = 0; u < (*left_nrec + 1); u++)
+ for(u = 0; u < (*left_nrec + (unsigned)1); u++)
new_left_all_nrec += left_node_ptrs[u].all_nrec;
new_right_all_nrec = internal->node_ptrs[idx + 1].node_nrec;
- for(u = 0; u < (*right_nrec + 1); u++)
+ for(u = 0; u < (*right_nrec + (unsigned)1); u++)
new_right_all_nrec += right_node_ptrs[u].all_nrec;
internal->node_ptrs[idx].all_nrec = new_left_all_nrec;
@@ -509,29 +312,30 @@ H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_
/* Update grandparent info */
curr_node_ptr->node_nrec++;
- /* Mark grandparent as dirty */
- *parent_cache_info_flags_ptr |= H5AC__DIRTIED_FLAG;
+ /* Mark grandparent as dirty, if given */
+ if(parent_cache_info_flags_ptr)
+ *parent_cache_info_flags_ptr |= H5AC__DIRTIED_FLAG;
#ifdef H5B2_DEBUG
- H5B2_assert_internal((hsize_t)0,shared,internal);
+ H5B2_assert_internal((hsize_t)0, hdr, internal);
if(depth > 1) {
- H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec, shared, left_child, right_child);
- H5B2_assert_internal2(internal->node_ptrs[idx + 1].all_nrec, shared, right_child, left_child);
+ H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec, hdr, left_child, right_child);
+ H5B2_assert_internal2(internal->node_ptrs[idx + 1].all_nrec, hdr, right_child, left_child);
} /* end if */
else {
- H5B2_assert_leaf2(shared, left_child, right_child);
- H5B2_assert_leaf(shared, right_child);
+ H5B2_assert_leaf2(hdr, left_child, right_child);
+ H5B2_assert_leaf(hdr, right_child);
} /* end else */
#endif /* H5B2_DEBUG */
/* Release child nodes (marked as dirty) */
- if(H5AC_unprotect(f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree leaf node")
- if(H5AC_unprotect(f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree leaf node")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B2_split1 */
@@ -541,7 +345,6 @@ done:
* Purpose: Split the root node
*
* Return: Success: Non-negative
- *
* Failure: Negative
*
* Programmer: Quincey Koziol
@@ -551,10 +354,9 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_split_root(H5F_t *f, hid_t dxpl_id, H5B2_t *bt2, unsigned *bt2_flags_ptr)
+H5B2_split_root(H5B2_hdr_t *hdr, hid_t dxpl_id)
{
H5B2_internal_t *new_root; /* Pointer to new root node */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
unsigned new_root_flags = H5AC__NO_FLAGS_SET; /* Cache flags for new root node */
H5B2_node_ptr_t old_root_ptr; /* Old node pointer to root node in B-tree */
size_t sz_max_nrec; /* Temporary variable for range checking */
@@ -563,61 +365,56 @@ H5B2_split_root(H5F_t *f, hid_t dxpl_id, H5B2_t *bt2, unsigned *bt2_flags_ptr)
FUNC_ENTER_NOAPI_NOINIT(H5B2_split_root)
- HDassert(f);
- HDassert(bt2);
- HDassert(bt2_flags_ptr);
-
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
+ /* Check arguments. */
+ HDassert(hdr);
/* Update depth of B-tree */
- shared->depth++;
+ hdr->depth++;
/* Re-allocate array of node info structs */
- if((shared->node_info = H5FL_SEQ_REALLOC(H5B2_node_info_t, shared->node_info, (size_t)(shared->depth + 1))) == NULL)
+ if(NULL == (hdr->node_info = H5FL_SEQ_REALLOC(H5B2_node_info_t, hdr->node_info, (size_t)(hdr->depth + 1))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Update node info for new depth of tree */
- sz_max_nrec = H5B2_NUM_INT_REC(f, shared, shared->depth);
- H5_ASSIGN_OVERFLOW(/* To: */ shared->node_info[shared->depth].max_nrec, /* From: */ sz_max_nrec, /* From: */ size_t, /* To: */ unsigned)
- shared->node_info[shared->depth].split_nrec = (shared->node_info[shared->depth].max_nrec * shared->split_percent) / 100;
- shared->node_info[shared->depth].merge_nrec = (shared->node_info[shared->depth].max_nrec * shared->merge_percent) / 100;
- shared->node_info[shared->depth].cum_max_nrec = ((shared->node_info[shared->depth].max_nrec + 1) *
- shared->node_info[shared->depth - 1].cum_max_nrec) + shared->node_info[shared->depth].max_nrec;
- u_max_nrec_size = H5V_limit_enc_size((uint64_t)shared->node_info[shared->depth].cum_max_nrec);
- H5_ASSIGN_OVERFLOW(/* To: */ shared->node_info[shared->depth].cum_max_nrec_size, /* From: */ u_max_nrec_size, /* From: */ unsigned, /* To: */ unsigned char)
- if((shared->node_info[shared->depth].nat_rec_fac = H5FL_fac_init(shared->type->nrec_size * shared->node_info[shared->depth].max_nrec)) == NULL)
+ sz_max_nrec = H5B2_NUM_INT_REC(hdr, hdr->depth);
+ H5_ASSIGN_OVERFLOW(/* To: */ hdr->node_info[hdr->depth].max_nrec, /* From: */ sz_max_nrec, /* From: */ size_t, /* To: */ unsigned)
+ hdr->node_info[hdr->depth].split_nrec = (hdr->node_info[hdr->depth].max_nrec * hdr->split_percent) / 100;
+ hdr->node_info[hdr->depth].merge_nrec = (hdr->node_info[hdr->depth].max_nrec * hdr->merge_percent) / 100;
+ hdr->node_info[hdr->depth].cum_max_nrec = ((hdr->node_info[hdr->depth].max_nrec + 1) *
+ hdr->node_info[hdr->depth - 1].cum_max_nrec) + hdr->node_info[hdr->depth].max_nrec;
+ u_max_nrec_size = H5V_limit_enc_size((uint64_t)hdr->node_info[hdr->depth].cum_max_nrec);
+ H5_ASSIGN_OVERFLOW(/* To: */ hdr->node_info[hdr->depth].cum_max_nrec_size, /* From: */ u_max_nrec_size, /* From: */ unsigned, /* To: */ uint8_t)
+ if(NULL == (hdr->node_info[hdr->depth].nat_rec_fac = H5FL_fac_init(hdr->cls->nrec_size * hdr->node_info[hdr->depth].max_nrec)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create node native key block factory")
- if((shared->node_info[shared->depth].node_ptr_fac = H5FL_fac_init(sizeof(H5B2_node_ptr_t) * (shared->node_info[shared->depth].max_nrec + 1))) == NULL)
+ if(NULL == (hdr->node_info[hdr->depth].node_ptr_fac = H5FL_fac_init(sizeof(H5B2_node_ptr_t) * (hdr->node_info[hdr->depth].max_nrec + 1))))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create internal 'branch' node node pointer block factory")
/* Keep old root node pointer info */
- old_root_ptr = bt2->root;
+ old_root_ptr = hdr->root;
/* Create new internal node to use as root */
- bt2->root.node_nrec = 0;
- if(H5B2_create_internal(f, dxpl_id, bt2->shared, &(bt2->root), shared->depth) < 0)
+ hdr->root.node_nrec = 0;
+ if(H5B2_create_internal(hdr, dxpl_id, &(hdr->root), hdr->depth) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to create new internal node")
/* Protect new root node */
- if(NULL == (new_root = H5B2_protect_internal(f, dxpl_id, bt2->shared, bt2->root.addr, bt2->root.node_nrec, shared->depth, H5AC_WRITE)))
+ if(NULL == (new_root = H5B2_protect_internal(hdr, dxpl_id, hdr->root.addr, hdr->root.node_nrec, hdr->depth, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Set first node pointer in root node to old root node pointer info */
new_root->node_ptrs[0] = old_root_ptr;
/* Split original root node */
- if(H5B2_split1(f, dxpl_id, shared->depth, &(bt2->root), bt2_flags_ptr, new_root, &new_root_flags, 0) < 0)
+ if(H5B2_split1(hdr, dxpl_id, hdr->depth, &(hdr->root), NULL, new_root, &new_root_flags, 0) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to split old root node")
/* Release new root node (marked as dirty) */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, bt2->root.addr, new_root, new_root_flags) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, hdr->root.addr, new_root, new_root_flags) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree internal node")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5B2_split_root */
+} /* end H5B2_split_root() */
/*-------------------------------------------------------------------------
@@ -626,7 +423,6 @@ done:
* Purpose: Redistribute records between two nodes
*
* Return: Success: Non-negative
- *
* Failure: Negative
*
* Programmer: Quincey Koziol
@@ -636,27 +432,24 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_internal_t *internal, unsigned idx)
+H5B2_redistribute2(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
+ H5B2_internal_t *internal, unsigned idx)
{
const H5AC_class_t *child_class; /* Pointer to child node's class info */
haddr_t left_addr, right_addr; /* Addresses of left & right child nodes */
void *left_child, *right_child; /* Pointers to child nodes */
- unsigned *left_nrec, *right_nrec; /* Pointers to child # of records */
+ uint16_t *left_nrec, *right_nrec; /* Pointers to child # of records */
uint8_t *left_native, *right_native; /* Pointers to childs' native records */
- H5B2_node_ptr_t *left_node_ptrs=NULL, *right_node_ptrs=NULL;/* Pointers to childs' node pointer info */
- H5B2_shared_t *shared; /* B-tree's shared info */
- hssize_t left_moved_nrec=0, right_moved_nrec=0; /* Number of records moved, for internal redistrib */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5B2_node_ptr_t *left_node_ptrs = NULL, *right_node_ptrs = NULL;/* Pointers to childs' node pointer info */
+ hssize_t left_moved_nrec = 0, right_moved_nrec = 0; /* Number of records moved, for internal redistrib */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5B2_redistribute2)
- HDassert(f);
+ /* Check arguments. */
+ HDassert(hdr);
HDassert(internal);
- /* Get the pointer to the shared B-tree info */
- shared=(H5B2_shared_t *)H5RC_GET_OBJ(internal->shared);
- HDassert(shared);
-
/* Check for the kind of B-tree node to redistribute */
if(depth > 1) {
H5B2_internal_t *left_internal; /* Pointer to left internal node */
@@ -665,12 +458,12 @@ H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_internal_t *int
/* Setup information for unlocking child nodes */
child_class = H5AC_BT2_INT;
left_addr = internal->node_ptrs[idx].addr;
- right_addr = internal->node_ptrs[idx+1].addr;
+ right_addr = internal->node_ptrs[idx + 1].addr;
/* Lock left & right B-tree child nodes */
- if (NULL == (left_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, left_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE)))
+ if(NULL == (left_internal = H5B2_protect_internal(hdr, dxpl_id, left_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
- if (NULL == (right_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, right_addr, internal->node_ptrs[idx+1].node_nrec, (depth - 1), H5AC_WRITE)))
+ if(NULL == (right_internal = H5B2_protect_internal(hdr, dxpl_id, right_addr, internal->node_ptrs[idx + 1].node_nrec, (depth - 1), H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
/* More setup for child nodes */
@@ -690,12 +483,12 @@ H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_internal_t *int
/* Setup information for unlocking child nodes */
child_class = H5AC_BT2_LEAF;
left_addr = internal->node_ptrs[idx].addr;
- right_addr = internal->node_ptrs[idx+1].addr;
+ right_addr = internal->node_ptrs[idx + 1].addr;
/* Lock left & right B-tree child nodes */
- if (NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx].node_nrec), internal->shared, H5AC_WRITE)))
+ if(NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx].node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
- if (NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx+1].node_nrec), internal->shared, H5AC_WRITE)))
+ if(NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx + 1].node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
/* More setup for child nodes */
@@ -708,14 +501,14 @@ H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_internal_t *int
} /* end else */
#ifdef H5B2_DEBUG
- H5B2_assert_internal((hsize_t)0,shared,internal);
- if(depth>1) {
- H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec,shared,left_child,right_child);
- H5B2_assert_internal2(internal->node_ptrs[idx+1].all_nrec,shared,right_child,left_child);
+ H5B2_assert_internal((hsize_t)0, hdr, internal);
+ if(depth > 1) {
+ H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec, hdr, left_child, right_child);
+ H5B2_assert_internal2(internal->node_ptrs[idx + 1].all_nrec, hdr, right_child, left_child);
} /* end if */
else {
- H5B2_assert_leaf2(shared,left_child,right_child);
- H5B2_assert_leaf(shared,right_child);
+ H5B2_assert_leaf2(hdr, left_child, right_child);
+ H5B2_assert_leaf(hdr, right_child);
} /* end else */
#endif /* H5B2_DEBUG */
@@ -723,24 +516,24 @@ H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_internal_t *int
if(*left_nrec < *right_nrec) {
/* Moving record from right node to left */
- unsigned new_right_nrec = (*left_nrec + *right_nrec) / 2; /* New number of records for right child */
- unsigned move_nrec = *right_nrec - new_right_nrec; /* Number of records to move from right node to left */
+ uint16_t new_right_nrec = (*left_nrec + *right_nrec) / 2; /* New number of records for right child */
+ uint16_t move_nrec = *right_nrec - new_right_nrec; /* Number of records to move from right node to left */
/* Copy record from parent node down into left child */
- HDmemcpy(H5B2_NAT_NREC(left_native,shared,*left_nrec),H5B2_INT_NREC(internal,shared,idx),shared->type->nrec_size);
+ HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size);
/* See if we need to move records from right node */
- if(move_nrec>1)
- HDmemcpy(H5B2_NAT_NREC(left_native,shared,(*left_nrec+1)),H5B2_NAT_NREC(right_native,shared,0),shared->type->nrec_size*(move_nrec-1));
+ if(move_nrec > 1)
+ HDmemcpy(H5B2_NAT_NREC(left_native, hdr, (*left_nrec + 1)), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (move_nrec - 1));
/* Move record from right node into parent node */
- HDmemcpy(H5B2_INT_NREC(internal,shared,idx),H5B2_NAT_NREC(right_native,shared,(move_nrec-1)),shared->type->nrec_size);
+ HDmemcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(right_native, hdr, (move_nrec - 1)), hdr->cls->nrec_size);
/* Slide records in right node down */
- HDmemmove(H5B2_NAT_NREC(right_native,shared,0),H5B2_NAT_NREC(right_native,shared,move_nrec),shared->type->nrec_size*new_right_nrec);
+ HDmemmove(H5B2_NAT_NREC(right_native, hdr, 0), H5B2_NAT_NREC(right_native, hdr, move_nrec), hdr->cls->nrec_size * new_right_nrec);
/* Handle node pointers, if we have an internal node */
- if(depth>1) {
+ if(depth > 1) {
hsize_t moved_nrec = move_nrec; /* Total number of records moved, for internal redistrib */
unsigned u; /* Local index variable */
@@ -754,7 +547,7 @@ H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_internal_t *int
HDmemcpy(&(left_node_ptrs[*left_nrec + 1]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * move_nrec);
/* Slide node pointers in right node down */
- HDmemmove(&(right_node_ptrs[0]), &(right_node_ptrs[move_nrec]), sizeof(H5B2_node_ptr_t) * (new_right_nrec + 1));
+ HDmemmove(&(right_node_ptrs[0]), &(right_node_ptrs[move_nrec]), sizeof(H5B2_node_ptr_t) * (new_right_nrec + (unsigned)1));
} /* end if */
/* Update number of records in child nodes */
@@ -764,37 +557,37 @@ H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_internal_t *int
else {
/* Moving record from left node to right */
- unsigned new_left_nrec = (*left_nrec + *right_nrec) / 2; /* New number of records for left child */
- unsigned move_nrec = *left_nrec - new_left_nrec; /* Number of records to move from left node to right */
+ uint16_t new_left_nrec = (*left_nrec + *right_nrec) / 2; /* New number of records for left child */
+ uint16_t move_nrec = *left_nrec - new_left_nrec; /* Number of records to move from left node to right */
/* Slide records in right node up */
- HDmemmove(H5B2_NAT_NREC(right_native,shared,move_nrec),
- H5B2_NAT_NREC(right_native,shared,0),
- shared->type->nrec_size*(*right_nrec));
+ HDmemmove(H5B2_NAT_NREC(right_native, hdr, move_nrec),
+ H5B2_NAT_NREC(right_native, hdr, 0),
+ hdr->cls->nrec_size * (*right_nrec));
/* Copy record from parent node down into right child */
- HDmemcpy(H5B2_NAT_NREC(right_native,shared,(move_nrec-1)),H5B2_INT_NREC(internal,shared,idx),shared->type->nrec_size);
+ HDmemcpy(H5B2_NAT_NREC(right_native, hdr, (move_nrec - 1)), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size);
/* See if we need to move records from left node */
- if(move_nrec>1)
- HDmemcpy(H5B2_NAT_NREC(right_native,shared,0),H5B2_NAT_NREC(left_native,shared,((*left_nrec-move_nrec)+1)),shared->type->nrec_size*(move_nrec-1));
+ if(move_nrec > 1)
+ HDmemcpy(H5B2_NAT_NREC(right_native, hdr, 0), H5B2_NAT_NREC(left_native, hdr, ((*left_nrec - move_nrec) + 1)), hdr->cls->nrec_size * (move_nrec - 1));
/* Move record from left node into parent node */
- HDmemcpy(H5B2_INT_NREC(internal,shared,idx),H5B2_NAT_NREC(left_native,shared,(*left_nrec-move_nrec)),shared->type->nrec_size);
+ HDmemcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(left_native, hdr, (*left_nrec - move_nrec)), hdr->cls->nrec_size);
/* Handle node pointers, if we have an internal node */
- if(depth>1) {
- hsize_t moved_nrec=move_nrec; /* Total number of records moved, for internal redistrib */
+ if(depth > 1) {
+ hsize_t moved_nrec = move_nrec; /* Total number of records moved, for internal redistrib */
unsigned u; /* Local index variable */
/* Slide node pointers in right node up */
- HDmemmove(&(right_node_ptrs[move_nrec]),&(right_node_ptrs[0]),sizeof(H5B2_node_ptr_t)*(*right_nrec+1));
+ HDmemmove(&(right_node_ptrs[move_nrec]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (*right_nrec + 1));
/* Copy node pointers from left node to right */
- HDmemcpy(&(right_node_ptrs[0]),&(left_node_ptrs[new_left_nrec+1]),sizeof(H5B2_node_ptr_t)*move_nrec);
+ HDmemcpy(&(right_node_ptrs[0]), &(left_node_ptrs[new_left_nrec + 1]), sizeof(H5B2_node_ptr_t) * move_nrec);
/* Count the number of records being moved */
- for(u=0; u<move_nrec; u++)
+ for(u = 0; u < move_nrec; u++)
moved_nrec += right_node_ptrs[u].all_nrec;
left_moved_nrec -= (hssize_t)moved_nrec;
H5_ASSIGN_OVERFLOW(/* To: */ right_moved_nrec, /* From: */ moved_nrec, /* From: */ hsize_t, /* To: */ hssize_t)
@@ -807,38 +600,38 @@ H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_internal_t *int
/* Update # of records in child nodes */
internal->node_ptrs[idx].node_nrec = *left_nrec;
- internal->node_ptrs[idx+1].node_nrec = *right_nrec;
+ internal->node_ptrs[idx + 1].node_nrec = *right_nrec;
/* Update total # of records in child B-trees */
- if(depth>1) {
+ if(depth > 1) {
internal->node_ptrs[idx].all_nrec += left_moved_nrec;
- internal->node_ptrs[idx+1].all_nrec += right_moved_nrec;
+ internal->node_ptrs[idx + 1].all_nrec += right_moved_nrec;
} /* end if */
else {
internal->node_ptrs[idx].all_nrec = internal->node_ptrs[idx].node_nrec;
- internal->node_ptrs[idx+1].all_nrec = internal->node_ptrs[idx+1].node_nrec;
+ internal->node_ptrs[idx + 1].all_nrec = internal->node_ptrs[idx + 1].node_nrec;
} /* end else */
#ifdef H5B2_DEBUG
- H5B2_assert_internal((hsize_t)0,shared,internal);
- if(depth>1) {
- H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec,shared,left_child,right_child);
- H5B2_assert_internal2(internal->node_ptrs[idx+1].all_nrec,shared,right_child,left_child);
+ H5B2_assert_internal((hsize_t)0, hdr, internal);
+ if(depth > 1) {
+ H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec, hdr, left_child, right_child);
+ H5B2_assert_internal2(internal->node_ptrs[idx + 1].all_nrec, hdr, right_child, left_child);
} /* end if */
else {
- H5B2_assert_leaf2(shared,left_child,right_child);
- H5B2_assert_leaf(shared,right_child);
+ H5B2_assert_leaf2(hdr, left_child, right_child);
+ H5B2_assert_leaf(hdr, right_child);
} /* end else */
#endif /* H5B2_DEBUG */
/* Release child nodes (marked as dirty) */
- if (H5AC_unprotect(f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node")
- if (H5AC_unprotect(f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B2_redistribute2 */
@@ -848,7 +641,6 @@ done:
* Purpose: Redistribute records between three nodes
*
* Return: Success: Non-negative
- *
* Failure: Negative
*
* Programmer: Quincey Koziol
@@ -858,7 +650,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth,
+H5B2_redistribute3(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx)
{
const H5AC_class_t *child_class; /* Pointer to child node's class info */
@@ -866,27 +658,23 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth,
haddr_t middle_addr; /* Address of middle child node */
void *left_child, *right_child; /* Pointers to child nodes */
void *middle_child; /* Pointers to middle child node */
- unsigned *left_nrec, *right_nrec; /* Pointers to child # of records */
- unsigned *middle_nrec; /* Pointers to middle child # of records */
+ uint16_t *left_nrec, *right_nrec; /* Pointers to child # of records */
+ uint16_t *middle_nrec; /* Pointers to middle child # of records */
uint8_t *left_native, *right_native; /* Pointers to childs' native records */
uint8_t *middle_native; /* Pointers to middle child's native records */
- H5B2_shared_t *shared; /* B-tree's shared info */
- H5B2_node_ptr_t *left_node_ptrs=NULL, *right_node_ptrs=NULL;/* Pointers to childs' node pointer info */
- H5B2_node_ptr_t *middle_node_ptrs=NULL;/* Pointers to childs' node pointer info */
- hssize_t left_moved_nrec=0, right_moved_nrec=0; /* Number of records moved, for internal split */
- hssize_t middle_moved_nrec=0; /* Number of records moved, for internal split */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5B2_node_ptr_t *left_node_ptrs = NULL, *right_node_ptrs = NULL; /* Pointers to childs' node pointer info */
+ H5B2_node_ptr_t *middle_node_ptrs = NULL; /* Pointers to childs' node pointer info */
+ hssize_t left_moved_nrec = 0, right_moved_nrec = 0; /* Number of records moved, for internal split */
+ hssize_t middle_moved_nrec = 0; /* Number of records moved, for internal split */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5B2_redistribute3)
- HDassert(f);
+ /* Check arguments. */
+ HDassert(hdr);
HDassert(internal);
HDassert(internal_flags_ptr);
- /* Get the pointer to the shared B-tree info */
- shared=(H5B2_shared_t *)H5RC_GET_OBJ(internal->shared);
- HDassert(shared);
-
/* Check for the kind of B-tree node to redistribute */
if(depth > 1) {
H5B2_internal_t *left_internal; /* Pointer to left internal node */
@@ -895,16 +683,16 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth,
/* Setup information for unlocking child nodes */
child_class = H5AC_BT2_INT;
- left_addr = internal->node_ptrs[idx-1].addr;
+ left_addr = internal->node_ptrs[idx - 1].addr;
middle_addr = internal->node_ptrs[idx].addr;
- right_addr = internal->node_ptrs[idx+1].addr;
+ right_addr = internal->node_ptrs[idx + 1].addr;
/* Lock B-tree child nodes */
- if (NULL == (left_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, left_addr, internal->node_ptrs[idx-1].node_nrec, (depth - 1), H5AC_WRITE)))
+ if(NULL == (left_internal = H5B2_protect_internal(hdr, dxpl_id, left_addr, internal->node_ptrs[idx - 1].node_nrec, (depth - 1), H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
- if (NULL == (middle_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, middle_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE)))
+ if(NULL == (middle_internal = H5B2_protect_internal(hdr, dxpl_id, middle_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
- if (NULL == (right_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, right_addr, internal->node_ptrs[idx+1].node_nrec, (depth - 1), H5AC_WRITE)))
+ if(NULL == (right_internal = H5B2_protect_internal(hdr, dxpl_id, right_addr, internal->node_ptrs[idx + 1].node_nrec, (depth - 1), H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* More setup for child nodes */
@@ -928,16 +716,16 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth,
/* Setup information for unlocking child nodes */
child_class = H5AC_BT2_LEAF;
- left_addr = internal->node_ptrs[idx-1].addr;
+ left_addr = internal->node_ptrs[idx - 1].addr;
middle_addr = internal->node_ptrs[idx].addr;
- right_addr = internal->node_ptrs[idx+1].addr;
+ right_addr = internal->node_ptrs[idx + 1].addr;
/* Lock B-tree child nodes */
- if (NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx-1].node_nrec), internal->shared, H5AC_WRITE)))
+ if(NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx - 1].node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
- if (NULL == (middle_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, middle_addr, &(internal->node_ptrs[idx].node_nrec), internal->shared, H5AC_WRITE)))
+ if(NULL == (middle_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, middle_addr, &(internal->node_ptrs[idx].node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
- if (NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx+1].node_nrec), internal->shared, H5AC_WRITE)))
+ if(NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx + 1].node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
/* More setup for child nodes */
@@ -956,10 +744,10 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth,
{
/* Compute new # of records in each node */
unsigned total_nrec = *left_nrec + *middle_nrec + *right_nrec + 2;
- unsigned new_middle_nrec = (total_nrec - 2) / 3;
- unsigned new_left_nrec = ((total_nrec - 2) - new_middle_nrec) / 2;
- unsigned new_right_nrec = (total_nrec - 2) - (new_left_nrec + new_middle_nrec);
- unsigned curr_middle_nrec = *middle_nrec;
+ uint16_t new_middle_nrec = (total_nrec - 2) / 3;
+ uint16_t new_left_nrec = ((total_nrec - 2) - new_middle_nrec) / 2;
+ uint16_t new_right_nrec = (total_nrec - 2) - (new_left_nrec + new_middle_nrec);
+ uint16_t curr_middle_nrec = *middle_nrec;
/* Sanity check rounding */
HDassert(new_middle_nrec <= new_left_nrec);
@@ -967,42 +755,42 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth,
/* Move records into left node */
if(new_left_nrec > *left_nrec) {
- unsigned moved_middle_nrec = 0; /* Number of records moved into left node */
+ uint16_t moved_middle_nrec = 0; /* Number of records moved into left node */
/* Move left parent record down to left node */
- HDmemcpy(H5B2_NAT_NREC(left_native,shared,*left_nrec),H5B2_INT_NREC(internal,shared,idx-1),shared->type->nrec_size);
+ HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec), H5B2_INT_NREC(internal, hdr, idx - 1), hdr->cls->nrec_size);
/* Move records from middle node into left node */
if((new_left_nrec - 1) > *left_nrec) {
- moved_middle_nrec = new_left_nrec-(*left_nrec + 1);
- HDmemcpy(H5B2_NAT_NREC(left_native, shared, *left_nrec + 1),H5B2_NAT_NREC(middle_native, shared, 0), shared->type->nrec_size * moved_middle_nrec);
+ moved_middle_nrec = new_left_nrec - (*left_nrec + 1);
+ HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec + 1), H5B2_NAT_NREC(middle_native, hdr, 0), hdr->cls->nrec_size * moved_middle_nrec);
} /* end if */
/* Move record from middle node up to parent node */
- HDmemcpy(H5B2_INT_NREC(internal,shared,idx-1),H5B2_NAT_NREC(middle_native,shared,moved_middle_nrec),shared->type->nrec_size);
+ HDmemcpy(H5B2_INT_NREC(internal, hdr, idx - 1), H5B2_NAT_NREC(middle_native, hdr, moved_middle_nrec), hdr->cls->nrec_size);
moved_middle_nrec++;
/* Slide records in middle node down */
- HDmemmove(H5B2_NAT_NREC(middle_native,shared,0),H5B2_NAT_NREC(middle_native,shared,moved_middle_nrec),shared->type->nrec_size*(*middle_nrec-moved_middle_nrec));
+ HDmemmove(H5B2_NAT_NREC(middle_native, hdr, 0), H5B2_NAT_NREC(middle_native, hdr, moved_middle_nrec), hdr->cls->nrec_size * (*middle_nrec - moved_middle_nrec));
/* Move node pointers also if this is an internal node */
- if(depth>1) {
+ if(depth > 1) {
hsize_t moved_nrec; /* Total number of records moved, for internal redistrib */
unsigned move_nptrs; /* Number of node pointers to move */
unsigned u; /* Local index variable */
/* Move middle node pointers into left node */
move_nptrs = new_left_nrec - *left_nrec;
- HDmemcpy(&(left_node_ptrs[*left_nrec+1]),&(middle_node_ptrs[0]),sizeof(H5B2_node_ptr_t)*move_nptrs);
+ HDmemcpy(&(left_node_ptrs[*left_nrec + 1]), &(middle_node_ptrs[0]), sizeof(H5B2_node_ptr_t)*move_nptrs);
/* Count the number of records being moved into the left node */
- for(u=0, moved_nrec=0; u<move_nptrs; u++)
+ for(u = 0, moved_nrec = 0; u < move_nptrs; u++)
moved_nrec += middle_node_ptrs[u].all_nrec;
- left_moved_nrec = moved_nrec+move_nptrs;
- middle_moved_nrec -= moved_nrec+move_nptrs;
+ left_moved_nrec = moved_nrec + move_nptrs;
+ middle_moved_nrec -= moved_nrec + move_nptrs;
/* Slide the node pointers in middle node down */
- HDmemmove(&(middle_node_ptrs[0]),&(middle_node_ptrs[move_nptrs]),sizeof(H5B2_node_ptr_t)*((*middle_nrec-move_nptrs)+1));
+ HDmemmove(&(middle_node_ptrs[0]), &(middle_node_ptrs[move_nptrs]), sizeof(H5B2_node_ptr_t) * ((*middle_nrec - move_nptrs) + 1));
} /* end if */
/* Update the current number of records in middle node */
@@ -1010,38 +798,38 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth,
} /* end if */
/* Move records into right node */
- if(new_right_nrec>*right_nrec) {
- unsigned right_nrec_move = new_right_nrec-*right_nrec; /* Number of records to move out of right node */
+ if(new_right_nrec > *right_nrec) {
+ unsigned right_nrec_move = new_right_nrec - *right_nrec; /* Number of records to move out of right node */
/* Slide records in right node up */
- HDmemmove(H5B2_NAT_NREC(right_native,shared,right_nrec_move),H5B2_NAT_NREC(right_native,shared,0),shared->type->nrec_size*(*right_nrec));
+ HDmemmove(H5B2_NAT_NREC(right_native, hdr, right_nrec_move), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (*right_nrec));
/* Move right parent record down to right node */
- HDmemcpy(H5B2_NAT_NREC(right_native,shared,right_nrec_move-1),H5B2_INT_NREC(internal,shared,idx),shared->type->nrec_size);
+ HDmemcpy(H5B2_NAT_NREC(right_native, hdr, right_nrec_move - 1), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size);
/* Move records from middle node into right node */
- if(right_nrec_move>1)
- HDmemcpy(H5B2_NAT_NREC(right_native,shared,0),H5B2_NAT_NREC(middle_native,shared,((curr_middle_nrec-right_nrec_move)+1)),shared->type->nrec_size*(right_nrec_move-1));
+ if(right_nrec_move > 1)
+ HDmemcpy(H5B2_NAT_NREC(right_native, hdr, 0), H5B2_NAT_NREC(middle_native, hdr, ((curr_middle_nrec - right_nrec_move) + 1)), hdr->cls->nrec_size * (right_nrec_move - 1));
/* Move record from middle node up to parent node */
- HDmemcpy(H5B2_INT_NREC(internal,shared,idx),H5B2_NAT_NREC(middle_native,shared,(curr_middle_nrec-right_nrec_move)),shared->type->nrec_size);
+ HDmemcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(middle_native, hdr, (curr_middle_nrec - right_nrec_move)), hdr->cls->nrec_size);
/* Move node pointers also if this is an internal node */
- if(depth>1) {
+ if(depth > 1) {
hsize_t moved_nrec; /* Total number of records moved, for internal redistrib */
unsigned u; /* Local index variable */
/* Slide the node pointers in right node up */
- HDmemmove(&(right_node_ptrs[right_nrec_move]),&(right_node_ptrs[0]),sizeof(H5B2_node_ptr_t)*(*right_nrec+1));
+ HDmemmove(&(right_node_ptrs[right_nrec_move]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (*right_nrec + 1));
/* Move middle node pointers into right node */
- HDmemcpy(&(right_node_ptrs[0]),&(middle_node_ptrs[(curr_middle_nrec-right_nrec_move)+1]),sizeof(H5B2_node_ptr_t)*right_nrec_move);
+ HDmemcpy(&(right_node_ptrs[0]), &(middle_node_ptrs[(curr_middle_nrec - right_nrec_move) + 1]), sizeof(H5B2_node_ptr_t) * right_nrec_move);
/* Count the number of records being moved into the right node */
- for(u=0, moved_nrec=0; u<right_nrec_move; u++)
+ for(u = 0, moved_nrec = 0; u < right_nrec_move; u++)
moved_nrec += right_node_ptrs[u].all_nrec;
- right_moved_nrec = moved_nrec+right_nrec_move;
- middle_moved_nrec -= moved_nrec+right_nrec_move;
+ right_moved_nrec = moved_nrec + right_nrec_move;
+ middle_moved_nrec -= moved_nrec + right_nrec_move;
} /* end if */
/* Update the current number of records in middle node */
@@ -1049,38 +837,38 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth,
} /* end if */
/* Move records out of left node */
- if(new_left_nrec<*left_nrec) {
- unsigned left_nrec_move = *left_nrec-new_left_nrec; /* Number of records to move out of left node */
+ if(new_left_nrec < *left_nrec) {
+ unsigned left_nrec_move = *left_nrec - new_left_nrec; /* Number of records to move out of left node */
/* Slide middle records up */
- HDmemmove(H5B2_NAT_NREC(middle_native,shared,left_nrec_move),H5B2_NAT_NREC(middle_native,shared,0),shared->type->nrec_size*curr_middle_nrec);
+ HDmemmove(H5B2_NAT_NREC(middle_native, hdr, left_nrec_move), H5B2_NAT_NREC(middle_native, hdr, 0), hdr->cls->nrec_size * curr_middle_nrec);
/* Move left parent record down to middle node */
- HDmemcpy(H5B2_NAT_NREC(middle_native,shared,left_nrec_move-1),H5B2_INT_NREC(internal,shared,idx-1),shared->type->nrec_size);
+ HDmemcpy(H5B2_NAT_NREC(middle_native, hdr, left_nrec_move - 1), H5B2_INT_NREC(internal, hdr, idx - 1), hdr->cls->nrec_size);
/* Move left records to middle node */
- if(left_nrec_move>1)
- HDmemmove(H5B2_NAT_NREC(middle_native,shared,0),H5B2_NAT_NREC(left_native,shared,new_left_nrec+1),shared->type->nrec_size*(left_nrec_move-1));
+ if(left_nrec_move > 1)
+ HDmemmove(H5B2_NAT_NREC(middle_native, hdr, 0), H5B2_NAT_NREC(left_native, hdr, new_left_nrec + 1), hdr->cls->nrec_size * (left_nrec_move - 1));
/* Move left parent record up from left node */
- HDmemcpy(H5B2_INT_NREC(internal,shared,idx-1),H5B2_NAT_NREC(left_native,shared,new_left_nrec),shared->type->nrec_size);
+ HDmemcpy(H5B2_INT_NREC(internal, hdr, idx - 1), H5B2_NAT_NREC(left_native, hdr, new_left_nrec), hdr->cls->nrec_size);
/* Move node pointers also if this is an internal node */
- if(depth>1) {
+ if(depth > 1) {
hsize_t moved_nrec; /* Total number of records moved, for internal redistrib */
unsigned u; /* Local index variable */
/* Slide the node pointers in middle node up */
- HDmemmove(&(middle_node_ptrs[left_nrec_move]),&(middle_node_ptrs[0]),sizeof(H5B2_node_ptr_t)*(curr_middle_nrec+1));
+ HDmemmove(&(middle_node_ptrs[left_nrec_move]), &(middle_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (curr_middle_nrec + 1));
/* Move left node pointers into middle node */
- HDmemcpy(&(middle_node_ptrs[0]),&(left_node_ptrs[new_left_nrec+1]),sizeof(H5B2_node_ptr_t)*left_nrec_move);
+ HDmemcpy(&(middle_node_ptrs[0]), &(left_node_ptrs[new_left_nrec + 1]), sizeof(H5B2_node_ptr_t) * left_nrec_move);
/* Count the number of records being moved into the left node */
- for(u=0, moved_nrec=0; u<left_nrec_move; u++)
+ for(u = 0, moved_nrec = 0; u < left_nrec_move; u++)
moved_nrec += middle_node_ptrs[u].all_nrec;
- left_moved_nrec -= moved_nrec+left_nrec_move;
- middle_moved_nrec += moved_nrec+left_nrec_move;
+ left_moved_nrec -= moved_nrec + left_nrec_move;
+ middle_moved_nrec += moved_nrec + left_nrec_move;
} /* end if */
/* Update the current number of records in middle node */
@@ -1088,37 +876,37 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth,
} /* end if */
/* Move records out of right node */
- if(new_right_nrec<*right_nrec) {
- unsigned right_nrec_move = *right_nrec-new_right_nrec; /* Number of records to move out of right node */
+ if(new_right_nrec < *right_nrec) {
+ unsigned right_nrec_move = *right_nrec - new_right_nrec; /* Number of records to move out of right node */
/* Move right parent record down to middle node */
- HDmemcpy(H5B2_NAT_NREC(middle_native,shared,curr_middle_nrec),H5B2_INT_NREC(internal,shared,idx),shared->type->nrec_size);
+ HDmemcpy(H5B2_NAT_NREC(middle_native, hdr, curr_middle_nrec), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size);
/* Move right records to middle node */
- HDmemmove(H5B2_NAT_NREC(middle_native,shared,(curr_middle_nrec+1)),H5B2_NAT_NREC(right_native,shared,0),shared->type->nrec_size*(right_nrec_move-1));
+ HDmemmove(H5B2_NAT_NREC(middle_native, hdr, (curr_middle_nrec + 1)), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (right_nrec_move - 1));
/* Move right parent record up from right node */
- HDmemcpy(H5B2_INT_NREC(internal,shared,idx),H5B2_NAT_NREC(right_native,shared,right_nrec_move-1),shared->type->nrec_size);
+ HDmemcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(right_native, hdr, right_nrec_move - 1), hdr->cls->nrec_size);
/* Slide right records down */
- HDmemmove(H5B2_NAT_NREC(right_native,shared,0),H5B2_NAT_NREC(right_native,shared,right_nrec_move),shared->type->nrec_size*new_right_nrec);
+ HDmemmove(H5B2_NAT_NREC(right_native, hdr, 0), H5B2_NAT_NREC(right_native, hdr, right_nrec_move), hdr->cls->nrec_size * new_right_nrec);
/* Move node pointers also if this is an internal node */
- if(depth>1) {
+ if(depth > 1) {
hsize_t moved_nrec; /* Total number of records moved, for internal redistrib */
unsigned u; /* Local index variable */
/* Move right node pointers into middle node */
- HDmemcpy(&(middle_node_ptrs[curr_middle_nrec+1]),&(right_node_ptrs[0]),sizeof(H5B2_node_ptr_t)*right_nrec_move);
+ HDmemcpy(&(middle_node_ptrs[curr_middle_nrec + 1]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * right_nrec_move);
/* Count the number of records being moved into the right node */
- for(u=0, moved_nrec=0; u<right_nrec_move; u++)
+ for(u = 0, moved_nrec = 0; u < right_nrec_move; u++)
moved_nrec += right_node_ptrs[u].all_nrec;
- right_moved_nrec -= moved_nrec+right_nrec_move;
- middle_moved_nrec += moved_nrec+right_nrec_move;
+ right_moved_nrec -= moved_nrec + right_nrec_move;
+ middle_moved_nrec += moved_nrec + right_nrec_move;
/* Slide the node pointers in right node down */
- HDmemmove(&(right_node_ptrs[0]),&(right_node_ptrs[right_nrec_move]),sizeof(H5B2_node_ptr_t)*(new_right_nrec+1));
+ HDmemmove(&(right_node_ptrs[0]), &(right_node_ptrs[right_nrec_move]), sizeof(H5B2_node_ptr_t) * (new_right_nrec + 1));
} /* end if */
} /* end if */
@@ -1129,20 +917,20 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth,
} /* end block */
/* Update # of records in child nodes */
- internal->node_ptrs[idx-1].node_nrec = *left_nrec;
+ internal->node_ptrs[idx - 1].node_nrec = *left_nrec;
internal->node_ptrs[idx].node_nrec = *middle_nrec;
- internal->node_ptrs[idx+1].node_nrec = *right_nrec;
+ internal->node_ptrs[idx + 1].node_nrec = *right_nrec;
/* Update total # of records in child B-trees */
- if(depth>1) {
- internal->node_ptrs[idx-1].all_nrec += left_moved_nrec;
+ if(depth > 1) {
+ internal->node_ptrs[idx - 1].all_nrec += left_moved_nrec;
internal->node_ptrs[idx].all_nrec += middle_moved_nrec;
- internal->node_ptrs[idx+1].all_nrec += right_moved_nrec;
+ internal->node_ptrs[idx + 1].all_nrec += right_moved_nrec;
} /* end if */
else {
- internal->node_ptrs[idx-1].all_nrec = internal->node_ptrs[idx-1].node_nrec;
+ internal->node_ptrs[idx - 1].all_nrec = internal->node_ptrs[idx - 1].node_nrec;
internal->node_ptrs[idx].all_nrec = internal->node_ptrs[idx].node_nrec;
- internal->node_ptrs[idx+1].all_nrec = internal->node_ptrs[idx+1].node_nrec;
+ internal->node_ptrs[idx + 1].all_nrec = internal->node_ptrs[idx + 1].node_nrec;
} /* end else */
/* Mark parent as dirty */
@@ -1152,67 +940,67 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth,
{
unsigned u;
- HDfprintf(stderr,"%s: Internal records:\n",FUNC);
- for(u=0; u<internal->nrec; u++) {
- HDfprintf(stderr,"%s: u=%u\n",FUNC,u);
- (shared->type->debug)(stderr,f,dxpl_id,3,4,H5B2_INT_NREC(internal,shared,u),NULL);
+ HDfprintf(stderr, "%s: Internal records:\n", FUNC);
+ for(u = 0; u < internal->nrec; u++) {
+ HDfprintf(stderr, "%s: u = %u\n", FUNC, u);
+ (hdr->cls->debug)(stderr, hdr->f, dxpl_id, 3, 4, H5B2_INT_NREC(internal, hdr, u), NULL);
} /* end for */
- HDfprintf(stderr,"%s: Left Child records:\n",FUNC);
- for(u=0; u<*left_nrec; u++) {
- HDfprintf(stderr,"%s: u=%u\n",FUNC,u);
- (shared->type->debug)(stderr,f,dxpl_id,3,4,H5B2_NAT_NREC(left_native,shared,u),NULL);
+ HDfprintf(stderr, "%s: Left Child records:\n", FUNC);
+ for(u = 0; u < *left_nrec; u++) {
+ HDfprintf(stderr, "%s: u = %u\n", FUNC, u);
+ (hdr->cls->debug)(stderr, hdr->f, dxpl_id, 3, 4, H5B2_NAT_NREC(left_native, hdr, u), NULL);
} /* end for */
- HDfprintf(stderr,"%s: Middle Child records:\n",FUNC);
- for(u=0; u<*middle_nrec; u++) {
- HDfprintf(stderr,"%s: u=%u\n",FUNC,u);
- (shared->type->debug)(stderr,f,dxpl_id,3,4,H5B2_NAT_NREC(middle_native,shared,u),NULL);
+ HDfprintf(stderr, "%s: Middle Child records:\n", FUNC);
+ for(u = 0; u < *middle_nrec; u++) {
+ HDfprintf(stderr, "%s: u = %u\n", FUNC, u);
+ (hdr->cls->debug)(stderr, hdr->f, dxpl_id, 3, 4, H5B2_NAT_NREC(middle_native, hdr, u), NULL);
} /* end for */
- HDfprintf(stderr,"%s: Right Child records:\n",FUNC);
- for(u=0; u<*right_nrec; u++) {
- HDfprintf(stderr,"%s: u=%u\n",FUNC,u);
- (shared->type->debug)(stderr,f,dxpl_id,3,4,H5B2_NAT_NREC(right_native,shared,u),NULL);
+ HDfprintf(stderr, "%s: Right Child records:\n", FUNC);
+ for(u = 0; u < *right_nrec; u++) {
+ HDfprintf(stderr, "%s: u = %u\n", FUNC, u);
+ (hdr->cls->debug)(stderr, hdr->f, dxpl_id, 3, 4, H5B2_NAT_NREC(right_native, hdr, u), NULL);
} /* end for */
- for(u=0; u<internal->nrec+1; u++)
- HDfprintf(stderr,"%s: internal->node_ptrs[%u]=(%Hu/%u/%a)\n",FUNC,u,internal->node_ptrs[u].all_nrec,internal->node_ptrs[u].node_nrec,internal->node_ptrs[u].addr);
- if(depth>1) {
- for(u=0; u<*left_nrec+1; u++)
- HDfprintf(stderr,"%s: left_node_ptr[%u]=(%Hu/%u/%a)\n",FUNC,u,left_node_ptrs[u].all_nrec,left_node_ptrs[u].node_nrec,left_node_ptrs[u].addr);
- for(u=0; u<*middle_nrec+1; u++)
- HDfprintf(stderr,"%s: middle_node_ptr[%u]=(%Hu/%u/%a)\n",FUNC,u,middle_node_ptrs[u].all_nrec,middle_node_ptrs[u].node_nrec,middle_node_ptrs[u].addr);
- for(u=0; u<*right_nrec+1; u++)
- HDfprintf(stderr,"%s: right_node_ptr[%u]=(%Hu/%u/%a)\n",FUNC,u,right_node_ptrs[u].all_nrec,right_node_ptrs[u].node_nrec,right_node_ptrs[u].addr);
+ for(u = 0; u < internal->nrec + 1; u++)
+ HDfprintf(stderr, "%s: internal->node_ptrs[%u] = (%Hu/%u/%a)\n", FUNC, u, internal->node_ptrs[u].all_nrec, internal->node_ptrs[u].node_nrec, internal->node_ptrs[u].addr);
+ if(depth > 1) {
+ for(u = 0; u < *left_nrec + 1; u++)
+ HDfprintf(stderr, "%s: left_node_ptr[%u] = (%Hu/%u/%a)\n", FUNC, u, left_node_ptrs[u].all_nrec, left_node_ptrs[u].node_nrec, left_node_ptrs[u].addr);
+ for(u = 0; u < *middle_nrec + 1; u++)
+ HDfprintf(stderr, "%s: middle_node_ptr[%u] = (%Hu/%u/%a)\n", FUNC, u, middle_node_ptrs[u].all_nrec, middle_node_ptrs[u].node_nrec, middle_node_ptrs[u].addr);
+ for(u = 0; u < *right_nrec + 1; u++)
+ HDfprintf(stderr, "%s: right_node_ptr[%u] = (%Hu/%u/%a)\n", FUNC, u, right_node_ptrs[u].all_nrec, right_node_ptrs[u].node_nrec, right_node_ptrs[u].addr);
} /* end if */
}
#endif /* QAK */
#ifdef H5B2_DEBUG
- H5B2_assert_internal((hsize_t)0,shared,internal);
- if(depth>1) {
- H5B2_assert_internal2(internal->node_ptrs[idx-1].all_nrec,shared,left_child,middle_child);
- H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec,shared,middle_child,left_child);
- H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec,shared,middle_child,right_child);
- H5B2_assert_internal2(internal->node_ptrs[idx+1].all_nrec,shared,right_child,middle_child);
+ H5B2_assert_internal((hsize_t)0, hdr, internal);
+ if(depth > 1) {
+ H5B2_assert_internal2(internal->node_ptrs[idx - 1].all_nrec, hdr, left_child, middle_child);
+ H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec, hdr, middle_child, left_child);
+ H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec, hdr, middle_child, right_child);
+ H5B2_assert_internal2(internal->node_ptrs[idx + 1].all_nrec, hdr, right_child, middle_child);
} /* end if */
else {
- H5B2_assert_leaf2(shared,left_child,middle_child);
- H5B2_assert_leaf2(shared,middle_child,right_child);
- H5B2_assert_leaf(shared,right_child);
+ H5B2_assert_leaf2(hdr, left_child, middle_child);
+ H5B2_assert_leaf2(hdr, middle_child, right_child);
+ H5B2_assert_leaf(hdr, right_child);
} /* end else */
#endif /* H5B2_DEBUG */
/* Unlock child nodes (marked as dirty) */
- if (H5AC_unprotect(f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node")
- if (H5AC_unprotect(f, dxpl_id, child_class, middle_addr, middle_child, H5AC__DIRTIED_FLAG) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, child_class, middle_addr, middle_child, H5AC__DIRTIED_FLAG) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node")
- if (H5AC_unprotect(f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B2_redistribute3 */
@@ -1232,31 +1020,26 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_merge2(H5F_t *f, hid_t dxpl_id, unsigned depth,
+H5B2_merge2(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
H5B2_node_ptr_t *curr_node_ptr, unsigned *parent_cache_info_flags_ptr,
H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx)
{
const H5AC_class_t *child_class; /* Pointer to child node's class info */
haddr_t left_addr, right_addr; /* Addresses of left & right child nodes */
void *left_child, *right_child; /* Pointers to left & right child nodes */
- unsigned *left_nrec, *right_nrec; /* Pointers to left & right child # of records */
+ uint16_t *left_nrec, *right_nrec; /* Pointers to left & right child # of records */
uint8_t *left_native, *right_native; /* Pointers to left & right children's native records */
- H5B2_node_ptr_t *left_node_ptrs=NULL, *right_node_ptrs=NULL;/* Pointers to childs' node pointer info */
- H5B2_shared_t *shared; /* B-tree's shared info */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5B2_node_ptr_t *left_node_ptrs = NULL, *right_node_ptrs = NULL;/* Pointers to childs' node pointer info */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5B2_merge2)
- HDassert(f);
+ /* Check arguments. */
+ HDassert(hdr);
HDassert(curr_node_ptr);
- HDassert(parent_cache_info_flags_ptr);
HDassert(internal);
HDassert(internal_flags_ptr);
- /* Get the pointer to the shared B-tree info */
- shared=(H5B2_shared_t *)H5RC_GET_OBJ(internal->shared);
- HDassert(shared);
-
/* Check for the kind of B-tree node to split */
if(depth > 1) {
H5B2_internal_t *left_internal; /* Pointer to left internal node */
@@ -1265,12 +1048,12 @@ H5B2_merge2(H5F_t *f, hid_t dxpl_id, unsigned depth,
/* Setup information for unlocking child nodes */
child_class = H5AC_BT2_INT;
left_addr = internal->node_ptrs[idx].addr;
- right_addr = internal->node_ptrs[idx+1].addr;
+ right_addr = internal->node_ptrs[idx + 1].addr;
/* Lock left & right B-tree child nodes */
- if(NULL == (left_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, left_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE)))
+ if(NULL == (left_internal = H5B2_protect_internal(hdr, dxpl_id, left_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
- if(NULL == (right_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, right_addr, internal->node_ptrs[idx+1].node_nrec, (depth - 1), H5AC_WRITE)))
+ if(NULL == (right_internal = H5B2_protect_internal(hdr, dxpl_id, right_addr, internal->node_ptrs[idx + 1].node_nrec, (depth - 1), H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* More setup for accessing child node information */
@@ -1290,12 +1073,12 @@ H5B2_merge2(H5F_t *f, hid_t dxpl_id, unsigned depth,
/* Setup information for unlocking child nodes */
child_class = H5AC_BT2_LEAF;
left_addr = internal->node_ptrs[idx].addr;
- right_addr = internal->node_ptrs[idx+1].addr;
+ right_addr = internal->node_ptrs[idx + 1].addr;
/* Lock left & right B-tree child nodes */
- if(NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx].node_nrec), internal->shared, H5AC_WRITE)))
+ if(NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx].node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
- if(NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx+1].node_nrec), internal->shared, H5AC_WRITE)))
+ if(NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx + 1].node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
/* More setup for accessing child node information */
@@ -1310,14 +1093,14 @@ H5B2_merge2(H5F_t *f, hid_t dxpl_id, unsigned depth,
/* Redistribute records into left node */
{
/* Copy record from parent node to proper location */
- HDmemcpy(H5B2_NAT_NREC(left_native,shared,*left_nrec),H5B2_INT_NREC(internal,shared,idx),shared->type->nrec_size);
+ HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size);
/* Copy records from right node to left node */
- HDmemcpy(H5B2_NAT_NREC(left_native,shared,*left_nrec+1),H5B2_NAT_NREC(right_native,shared,0),shared->type->nrec_size*(*right_nrec));
+ HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec + 1), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (*right_nrec));
/* Copy node pointers from right node into left node */
- if(depth>1)
- HDmemcpy(&(left_node_ptrs[*left_nrec+1]),&(right_node_ptrs[0]),sizeof(H5B2_node_ptr_t)*(*right_nrec+1));
+ if(depth > 1)
+ HDmemcpy(&(left_node_ptrs[*left_nrec + 1]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (*right_nrec + 1));
/* Update # of records in left node */
*left_nrec += *right_nrec + 1;
@@ -1327,12 +1110,12 @@ H5B2_merge2(H5F_t *f, hid_t dxpl_id, unsigned depth,
internal->node_ptrs[idx].node_nrec = *left_nrec;
/* Update total # of records in child B-trees */
- internal->node_ptrs[idx].all_nrec += internal->node_ptrs[idx+1].all_nrec + 1;
+ internal->node_ptrs[idx].all_nrec += internal->node_ptrs[idx + 1].all_nrec + 1;
/* Slide records in parent node down, to eliminate demoted record */
- if((idx+1) < internal->nrec) {
- HDmemmove(H5B2_INT_NREC(internal,shared,idx),H5B2_INT_NREC(internal,shared,idx+1),shared->type->nrec_size*(internal->nrec-(idx+1)));
- HDmemmove(&(internal->node_ptrs[idx+1]),&(internal->node_ptrs[idx+2]),sizeof(H5B2_node_ptr_t)*(internal->nrec-(idx+1)));
+ if((idx + 1) < internal->nrec) {
+ HDmemmove(H5B2_INT_NREC(internal, hdr, idx), H5B2_INT_NREC(internal, hdr, idx + 1), hdr->cls->nrec_size * (internal->nrec - (idx + 1)));
+ HDmemmove(&(internal->node_ptrs[idx + 1]), &(internal->node_ptrs[idx + 2]), sizeof(H5B2_node_ptr_t) * (internal->nrec - (idx + 1)));
} /* end if */
/* Update # of records in parent node */
@@ -1344,30 +1127,29 @@ H5B2_merge2(H5F_t *f, hid_t dxpl_id, unsigned depth,
/* Update grandparent info */
curr_node_ptr->node_nrec--;
- /* Mark grandparent as dirty */
- *parent_cache_info_flags_ptr |= H5AC__DIRTIED_FLAG;
+ /* Mark grandparent as dirty, if given */
+ if(parent_cache_info_flags_ptr)
+ *parent_cache_info_flags_ptr |= H5AC__DIRTIED_FLAG;
#ifdef H5B2_DEBUG
- H5B2_assert_internal((hsize_t)0,shared,internal);
- if(depth>1)
- H5B2_assert_internal(internal->node_ptrs[idx].all_nrec,shared,left_child);
+ H5B2_assert_internal((hsize_t)0, hdr, internal);
+ if(depth > 1)
+ H5B2_assert_internal(internal->node_ptrs[idx].all_nrec, hdr, left_child);
else
- H5B2_assert_leaf(shared,left_child);
+ H5B2_assert_leaf(hdr, left_child);
#endif /* H5B2_DEBUG */
/* Unlock left node (marked as dirty) */
- if(H5AC_unprotect(f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node")
/* Delete right node & remove from cache (marked as dirty) */
- if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, right_addr, (hsize_t)shared->node_size) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free B-tree leaf node")
- if(H5AC_unprotect(f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG|H5AC__DELETED_FLAG) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node")
done:
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5B2_merge2 */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B2_merge2() */
/*-------------------------------------------------------------------------
@@ -1386,7 +1168,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_merge3(H5F_t *f, hid_t dxpl_id, unsigned depth,
+H5B2_merge3(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
H5B2_node_ptr_t *curr_node_ptr, unsigned *parent_cache_info_flags_ptr,
H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx)
{
@@ -1395,28 +1177,23 @@ H5B2_merge3(H5F_t *f, hid_t dxpl_id, unsigned depth,
haddr_t middle_addr; /* Address of middle child node */
void *left_child, *right_child; /* Pointers to left & right child nodes */
void *middle_child; /* Pointer to middle child node */
- unsigned *left_nrec, *right_nrec; /* Pointers to left & right child # of records */
- unsigned *middle_nrec; /* Pointer to middle child # of records */
+ uint16_t *left_nrec, *right_nrec; /* Pointers to left & right child # of records */
+ uint16_t *middle_nrec; /* Pointer to middle child # of records */
uint8_t *left_native, *right_native; /* Pointers to left & right children's native records */
uint8_t *middle_native; /* Pointer to middle child's native records */
- H5B2_node_ptr_t *left_node_ptrs=NULL, *right_node_ptrs=NULL;/* Pointers to childs' node pointer info */
- H5B2_node_ptr_t *middle_node_ptrs=NULL;/* Pointer to child's node pointer info */
- H5B2_shared_t *shared; /* B-tree's shared info */
+ H5B2_node_ptr_t *left_node_ptrs = NULL, *right_node_ptrs = NULL;/* Pointers to childs' node pointer info */
+ H5B2_node_ptr_t *middle_node_ptrs = NULL;/* Pointer to child's node pointer info */
hsize_t middle_moved_nrec; /* Number of records moved, for internal split */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5B2_merge3)
- HDassert(f);
+ /* Check arguments. */
+ HDassert(hdr);
HDassert(curr_node_ptr);
- HDassert(parent_cache_info_flags_ptr);
HDassert(internal);
HDassert(internal_flags_ptr);
- /* Get the pointer to the shared B-tree info */
- shared=(H5B2_shared_t *)H5RC_GET_OBJ(internal->shared);
- HDassert(shared);
-
/* Check for the kind of B-tree node to split */
if(depth > 1) {
H5B2_internal_t *left_internal; /* Pointer to left internal node */
@@ -1425,16 +1202,16 @@ H5B2_merge3(H5F_t *f, hid_t dxpl_id, unsigned depth,
/* Setup information for unlocking child nodes */
child_class = H5AC_BT2_INT;
- left_addr = internal->node_ptrs[idx-1].addr;
+ left_addr = internal->node_ptrs[idx - 1].addr;
middle_addr = internal->node_ptrs[idx].addr;
- right_addr = internal->node_ptrs[idx+1].addr;
+ right_addr = internal->node_ptrs[idx + 1].addr;
/* Lock B-tree child nodes */
- if (NULL == (left_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, left_addr, internal->node_ptrs[idx-1].node_nrec, (depth - 1), H5AC_WRITE)))
+ if(NULL == (left_internal = H5B2_protect_internal(hdr, dxpl_id, left_addr, internal->node_ptrs[idx - 1].node_nrec, (depth - 1), H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
- if (NULL == (middle_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, middle_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE)))
+ if(NULL == (middle_internal = H5B2_protect_internal(hdr, dxpl_id, middle_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
- if (NULL == (right_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, right_addr, internal->node_ptrs[idx+1].node_nrec, (depth - 1), H5AC_WRITE)))
+ if(NULL == (right_internal = H5B2_protect_internal(hdr, dxpl_id, right_addr, internal->node_ptrs[idx + 1].node_nrec, (depth - 1), H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* More setup for accessing child node information */
@@ -1458,16 +1235,16 @@ H5B2_merge3(H5F_t *f, hid_t dxpl_id, unsigned depth,
/* Setup information for unlocking child nodes */
child_class = H5AC_BT2_LEAF;
- left_addr = internal->node_ptrs[idx-1].addr;
+ left_addr = internal->node_ptrs[idx - 1].addr;
middle_addr = internal->node_ptrs[idx].addr;
- right_addr = internal->node_ptrs[idx+1].addr;
+ right_addr = internal->node_ptrs[idx + 1].addr;
/* Lock B-tree child nodes */
- if (NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx-1].node_nrec), internal->shared, H5AC_WRITE)))
+ if(NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx - 1].node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
- if (NULL == (middle_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, middle_addr, &(internal->node_ptrs[idx].node_nrec), internal->shared, H5AC_WRITE)))
+ if(NULL == (middle_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, middle_addr, &(internal->node_ptrs[idx].node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
- if (NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx+1].node_nrec), internal->shared, H5AC_WRITE)))
+ if(NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx + 1].node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
/* More setup for accessing child node information */
@@ -1491,30 +1268,30 @@ H5B2_merge3(H5F_t *f, hid_t dxpl_id, unsigned depth,
middle_moved_nrec = middle_nrec_move;
/* Copy record from parent node to proper location in left node */
- HDmemcpy(H5B2_NAT_NREC(left_native,shared,*left_nrec),H5B2_INT_NREC(internal,shared,idx-1),shared->type->nrec_size);
+ HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec), H5B2_INT_NREC(internal, hdr, idx - 1), hdr->cls->nrec_size);
/* Copy records from middle node to left node */
- HDmemcpy(H5B2_NAT_NREC(left_native,shared,*left_nrec+1),H5B2_NAT_NREC(middle_native,shared,0),shared->type->nrec_size*(middle_nrec_move-1));
+ HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec + 1), H5B2_NAT_NREC(middle_native, hdr, 0), hdr->cls->nrec_size * (middle_nrec_move - 1));
/* Copy record from middle node to proper location in parent node */
- HDmemcpy(H5B2_INT_NREC(internal,shared,idx-1),H5B2_NAT_NREC(middle_native,shared,(middle_nrec_move-1)),shared->type->nrec_size);
+ HDmemcpy(H5B2_INT_NREC(internal, hdr, idx - 1), H5B2_NAT_NREC(middle_native, hdr, (middle_nrec_move - 1)), hdr->cls->nrec_size);
/* Slide records in middle node down */
- HDmemmove(H5B2_NAT_NREC(middle_native,shared,0),H5B2_NAT_NREC(middle_native,shared,middle_nrec_move),shared->type->nrec_size*(*middle_nrec-middle_nrec_move));
+ HDmemmove(H5B2_NAT_NREC(middle_native, hdr, 0), H5B2_NAT_NREC(middle_native, hdr, middle_nrec_move), hdr->cls->nrec_size * (*middle_nrec - middle_nrec_move));
/* Move node pointers also if this is an internal node */
- if(depth>1) {
+ if(depth > 1) {
unsigned u; /* Local index variable */
/* Copy node pointers from middle node into left node */
- HDmemcpy(&(left_node_ptrs[*left_nrec+1]),&(middle_node_ptrs[0]),sizeof(H5B2_node_ptr_t)*middle_nrec_move);
+ HDmemcpy(&(left_node_ptrs[*left_nrec + 1]), &(middle_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * middle_nrec_move);
/* Count the number of records being moved into the left node */
- for(u=0; u<middle_nrec_move; u++)
+ for(u = 0; u < middle_nrec_move; u++)
middle_moved_nrec += middle_node_ptrs[u].all_nrec;
/* Slide the node pointers in right node down */
- HDmemmove(&(middle_node_ptrs[0]),&(middle_node_ptrs[middle_nrec_move]),sizeof(H5B2_node_ptr_t)*((*middle_nrec+1)-middle_nrec_move));
+ HDmemmove(&(middle_node_ptrs[0]), &(middle_node_ptrs[middle_nrec_move]), sizeof(H5B2_node_ptr_t) * ((*middle_nrec + 1) - middle_nrec_move));
} /* end if */
/* Update # of records in left & middle nodes */
@@ -1525,32 +1302,32 @@ H5B2_merge3(H5F_t *f, hid_t dxpl_id, unsigned depth,
/* Redistribute records into middle node */
{
/* Copy record from parent node to proper location in middle node */
- HDmemcpy(H5B2_NAT_NREC(middle_native,shared,*middle_nrec),H5B2_INT_NREC(internal,shared,idx),shared->type->nrec_size);
+ HDmemcpy(H5B2_NAT_NREC(middle_native, hdr, *middle_nrec), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size);
/* Copy records from right node to middle node */
- HDmemcpy(H5B2_NAT_NREC(middle_native,shared,*middle_nrec+1),H5B2_NAT_NREC(right_native,shared,0),shared->type->nrec_size*(*right_nrec));
+ HDmemcpy(H5B2_NAT_NREC(middle_native, hdr, *middle_nrec + 1), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (*right_nrec));
/* Move node pointers also if this is an internal node */
- if(depth>1)
+ if(depth > 1)
/* Copy node pointers from middle node into left node */
- HDmemcpy(&(middle_node_ptrs[*middle_nrec+1]),&(right_node_ptrs[0]),sizeof(H5B2_node_ptr_t)*(*right_nrec+1));
+ HDmemcpy(&(middle_node_ptrs[*middle_nrec + 1]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (*right_nrec + 1));
/* Update # of records in middle node */
*middle_nrec += *right_nrec + 1;
} /* end block */
/* Update # of records in child nodes */
- internal->node_ptrs[idx-1].node_nrec = *left_nrec;
+ internal->node_ptrs[idx - 1].node_nrec = *left_nrec;
internal->node_ptrs[idx].node_nrec = *middle_nrec;
/* Update total # of records in child B-trees */
- internal->node_ptrs[idx-1].all_nrec += middle_moved_nrec;
- internal->node_ptrs[idx].all_nrec += (internal->node_ptrs[idx+1].all_nrec + 1) - middle_moved_nrec;
+ internal->node_ptrs[idx - 1].all_nrec += middle_moved_nrec;
+ internal->node_ptrs[idx].all_nrec += (internal->node_ptrs[idx + 1].all_nrec + 1) - middle_moved_nrec;
/* Slide records in parent node down, to eliminate demoted record */
- if((idx+1) < internal->nrec) {
- HDmemmove(H5B2_INT_NREC(internal,shared,idx),H5B2_INT_NREC(internal,shared,idx+1),shared->type->nrec_size*(internal->nrec-(idx+1)));
- HDmemmove(&(internal->node_ptrs[idx+1]),&(internal->node_ptrs[idx+2]),sizeof(H5B2_node_ptr_t)*(internal->nrec-(idx+1)));
+ if((idx + 1) < internal->nrec) {
+ HDmemmove(H5B2_INT_NREC(internal, hdr, idx), H5B2_INT_NREC(internal, hdr, idx + 1), hdr->cls->nrec_size * (internal->nrec - (idx + 1)));
+ HDmemmove(&(internal->node_ptrs[idx + 1]), &(internal->node_ptrs[idx + 2]), sizeof(H5B2_node_ptr_t) * (internal->nrec - (idx + 1)));
} /* end if */
/* Update # of records in parent node */
@@ -1562,36 +1339,35 @@ H5B2_merge3(H5F_t *f, hid_t dxpl_id, unsigned depth,
/* Update grandparent info */
curr_node_ptr->node_nrec--;
- /* Mark grandparent as dirty */
- *parent_cache_info_flags_ptr |= H5AC__DIRTIED_FLAG;
+ /* Mark grandparent as dirty, if given */
+ if(parent_cache_info_flags_ptr)
+ *parent_cache_info_flags_ptr |= H5AC__DIRTIED_FLAG;
#ifdef H5B2_DEBUG
- H5B2_assert_internal((hsize_t)0,shared,internal);
- if(depth>1) {
- H5B2_assert_internal2(internal->node_ptrs[idx-1].all_nrec,shared,left_child,middle_child);
- H5B2_assert_internal(internal->node_ptrs[idx].all_nrec,shared,middle_child);
+ H5B2_assert_internal((hsize_t)0, hdr, internal);
+ if(depth > 1) {
+ H5B2_assert_internal2(internal->node_ptrs[idx - 1].all_nrec, hdr, left_child, middle_child);
+ H5B2_assert_internal(internal->node_ptrs[idx].all_nrec, hdr, middle_child);
} /* end if */
else {
- H5B2_assert_leaf2(shared,left_child,middle_child);
- H5B2_assert_leaf(shared,middle_child);
+ H5B2_assert_leaf2(hdr, left_child, middle_child);
+ H5B2_assert_leaf(hdr, middle_child);
} /* end else */
#endif /* H5B2_DEBUG */
/* Unlock left & middle nodes (marked as dirty) */
- if (H5AC_unprotect(f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node")
- if (H5AC_unprotect(f, dxpl_id, child_class, middle_addr, middle_child, H5AC__DIRTIED_FLAG) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, child_class, middle_addr, middle_child, H5AC__DIRTIED_FLAG) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node")
/* Delete right node & remove from cache (marked as dirty) */
- if (H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, right_addr, (hsize_t)shared->node_size) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free B-tree leaf node")
- if (H5AC_unprotect(f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG|H5AC__DELETED_FLAG) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node")
done:
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5B2_merge3 */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B2_merge3() */
/*-------------------------------------------------------------------------
@@ -1610,7 +1386,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_swap_leaf(H5F_t *f, hid_t dxpl_id, unsigned depth,
+H5B2_swap_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
H5B2_internal_t *internal, unsigned *internal_flags_ptr,
unsigned idx, void *swap_loc)
{
@@ -1618,20 +1394,16 @@ H5B2_swap_leaf(H5F_t *f, hid_t dxpl_id, unsigned depth,
haddr_t child_addr; /* Address of child node */
void *child; /* Pointer to child node */
uint8_t *child_native; /* Pointer to child's native records */
- H5B2_shared_t *shared; /* B-tree's shared info */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5B2_swap_leaf)
- HDassert(f);
+ /* Check arguments. */
+ HDassert(hdr);
HDassert(internal);
HDassert(internal_flags_ptr);
HDassert(idx <= internal->nrec);
- /* Get the pointer to the shared B-tree info */
- shared=(H5B2_shared_t *)H5RC_GET_OBJ(internal->shared);
- HDassert(shared);
-
/* Check for the kind of B-tree node to swap */
if(depth > 1) {
H5B2_internal_t *child_internal; /* Pointer to internal node */
@@ -1641,7 +1413,7 @@ H5B2_swap_leaf(H5F_t *f, hid_t dxpl_id, unsigned depth,
child_addr = internal->node_ptrs[idx].addr;
/* Lock B-tree child nodes */
- if(NULL == (child_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, child_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE)))
+ if(NULL == (child_internal = H5B2_protect_internal(hdr, dxpl_id, child_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* More setup for accessing child node information */
@@ -1656,7 +1428,7 @@ H5B2_swap_leaf(H5F_t *f, hid_t dxpl_id, unsigned depth,
child_addr = internal->node_ptrs[idx].addr;
/* Lock B-tree child node */
- if (NULL == (child_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, child_addr, &(internal->node_ptrs[idx].node_nrec), internal->shared, H5AC_WRITE)))
+ if(NULL == (child_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, child_addr, &(internal->node_ptrs[idx].node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
/* More setup for accessing child node information */
@@ -1665,27 +1437,27 @@ H5B2_swap_leaf(H5F_t *f, hid_t dxpl_id, unsigned depth,
} /* end else */
/* Swap records (use disk page as temporary buffer) */
- HDmemcpy(shared->page, H5B2_NAT_NREC(child_native,shared,0), shared->type->nrec_size);
- HDmemcpy(H5B2_NAT_NREC(child_native,shared,0), swap_loc, shared->type->nrec_size);
- HDmemcpy(swap_loc, shared->page, shared->type->nrec_size);
+ HDmemcpy(hdr->page, H5B2_NAT_NREC(child_native, hdr, 0), hdr->cls->nrec_size);
+ HDmemcpy(H5B2_NAT_NREC(child_native, hdr, 0), swap_loc, hdr->cls->nrec_size);
+ HDmemcpy(swap_loc, hdr->page, hdr->cls->nrec_size);
/* Mark parent as dirty */
*internal_flags_ptr |= H5AC__DIRTIED_FLAG;
#ifdef H5B2_DEBUG
- H5B2_assert_internal((hsize_t)0,shared,internal);
- if(depth>1)
- H5B2_assert_internal(internal->node_ptrs[idx].all_nrec,shared,child);
+ H5B2_assert_internal((hsize_t)0, hdr, internal);
+ if(depth > 1)
+ H5B2_assert_internal(internal->node_ptrs[idx].all_nrec, hdr, child);
else
- H5B2_assert_leaf(shared,child);
+ H5B2_assert_leaf(hdr, child);
#endif /* H5B2_DEBUG */
/* Unlock child node */
- if (H5AC_unprotect(f, dxpl_id, child_class, child_addr, child, H5AC__DIRTIED_FLAG) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, child_class, child_addr, child, H5AC__DIRTIED_FLAG) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B2_swap_leaf */
@@ -1703,11 +1475,10 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_insert_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
- H5B2_node_ptr_t *curr_node_ptr, void *udata)
+H5B2_insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr,
+ void *udata)
{
H5B2_leaf_t *leaf; /* Pointer to leaf node */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
int cmp; /* Comparison value of records */
unsigned idx; /* Location of record which matches key */
herr_t ret_value = SUCCEED;
@@ -1715,21 +1486,16 @@ H5B2_insert_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
FUNC_ENTER_NOAPI_NOINIT(H5B2_insert_leaf)
/* Check arguments. */
- HDassert(f);
- HDassert(bt2_shared);
+ HDassert(hdr);
HDassert(curr_node_ptr);
HDassert(H5F_addr_defined(curr_node_ptr->addr));
/* Lock current B-tree node */
- if (NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, &(curr_node_ptr->node_nrec), bt2_shared, H5AC_WRITE)))
+ if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, &(curr_node_ptr->node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
- /* Get the pointer to the shared B-tree info */
- shared=(H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
-
/* Must have a leaf node with enough space to insert a record now */
- HDassert(curr_node_ptr->node_nrec < shared->node_info[0].max_nrec);
+ HDassert(curr_node_ptr->node_nrec < hdr->node_info[0].max_nrec);
/* Sanity check number of records */
HDassert(curr_node_ptr->all_nrec == curr_node_ptr->node_nrec);
@@ -1740,18 +1506,18 @@ H5B2_insert_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
idx = 0;
else {
/* Find correct location to insert this record */
- if((cmp = H5B2_locate_record(shared->type, leaf->nrec, shared->nat_off, leaf->leaf_native, udata, &idx)) == 0)
+ if((cmp = H5B2_locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx)) == 0)
HGOTO_ERROR(H5E_BTREE, H5E_EXISTS, FAIL, "record is already in B-tree")
if(cmp > 0)
idx++;
/* Make room for new record */
if(idx < leaf->nrec)
- HDmemmove(H5B2_LEAF_NREC(leaf, shared, idx + 1), H5B2_LEAF_NREC(leaf, shared, idx), shared->type->nrec_size * (leaf->nrec-idx));
+ HDmemmove(H5B2_LEAF_NREC(leaf, hdr, idx + 1), H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size * (leaf->nrec - idx));
} /* end else */
/* Make callback to store record in native form */
- if((shared->type->store)(H5B2_LEAF_NREC(leaf, shared, idx), udata) < 0)
+ if((hdr->cls->store)(H5B2_LEAF_NREC(leaf, hdr, idx), udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into leaf node")
/* Update record count for node pointer to current node */
@@ -1763,7 +1529,7 @@ H5B2_insert_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
done:
/* Release the B-tree leaf node (marked as dirty) */
- if(leaf && H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, leaf, H5AC__DIRTIED_FLAG) < 0)
+ if(leaf && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, leaf, H5AC__DIRTIED_FLAG) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release leaf B-tree node")
FUNC_LEAVE_NOAPI(ret_value)
@@ -1784,34 +1550,27 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
- unsigned depth, unsigned *parent_cache_info_flags_ptr,
- H5B2_node_ptr_t *curr_node_ptr, void *udata)
+H5B2_insert_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
+ unsigned *parent_cache_info_flags_ptr, H5B2_node_ptr_t *curr_node_ptr,
+ void *udata)
{
H5B2_internal_t *internal; /* Pointer to internal node */
unsigned internal_flags = H5AC__NO_FLAGS_SET;
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
unsigned idx; /* Location of record which matches key */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5B2_insert_internal)
/* Check arguments. */
- HDassert(f);
- HDassert(bt2_shared);
+ HDassert(hdr);
HDassert(depth > 0);
- HDassert(parent_cache_info_flags_ptr);
HDassert(curr_node_ptr);
HDassert(H5F_addr_defined(curr_node_ptr->addr));
/* Lock current B-tree node */
- if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node_ptr->addr, curr_node_ptr->node_nrec, depth, H5AC_WRITE)))
+ if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node_ptr->addr, curr_node_ptr->node_nrec, depth, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
- /* Get the pointer to the shared B-tree info */
- shared=(H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
-
/* Split or redistribute child node pointers, if necessary */
{
int cmp; /* Comparison value of records */
@@ -1819,7 +1578,7 @@ H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
size_t split_nrec; /* Number of records to split node at */
/* Locate node pointer for child */
- if((cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx)) == 0)
+ if((cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx)) == 0)
HGOTO_ERROR(H5E_BTREE, H5E_EXISTS, FAIL, "record is already in B-tree")
if(cmp > 0)
idx++;
@@ -1833,29 +1592,29 @@ H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
retries = 2;
/* Determine the correct number of records to split child node at */
- split_nrec = shared->node_info[depth - 1].split_nrec;
+ split_nrec = hdr->node_info[depth - 1].split_nrec;
/* Preemptively split/redistribute a node we will enter */
while(internal->node_ptrs[idx].node_nrec == split_nrec) {
/* Attempt to redistribute records among children */
if(idx == 0) { /* Left-most child */
- if(retries > 0 && (internal->node_ptrs[idx+1].node_nrec < split_nrec)) {
- if(H5B2_redistribute2(f, dxpl_id, depth, internal, idx) < 0)
+ if(retries > 0 && (internal->node_ptrs[idx + 1].node_nrec < split_nrec)) {
+ if(H5B2_redistribute2(hdr, dxpl_id, depth, internal, idx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records")
} /* end if */
else {
- if(H5B2_split1(f, dxpl_id, depth, curr_node_ptr,
+ if(H5B2_split1(hdr, dxpl_id, depth, curr_node_ptr,
parent_cache_info_flags_ptr, internal, &internal_flags, idx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to split child node")
} /* end else */
} /* end if */
else if(idx == internal->nrec) { /* Right-most child */
if(retries > 0 && (internal->node_ptrs[idx - 1].node_nrec < split_nrec)) {
- if(H5B2_redistribute2(f, dxpl_id, depth, internal, (idx - 1)) < 0)
+ if(H5B2_redistribute2(hdr, dxpl_id, depth, internal, (idx - 1)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records")
} /* end if */
else {
- if(H5B2_split1(f, dxpl_id, depth, curr_node_ptr,
+ if(H5B2_split1(hdr, dxpl_id, depth, curr_node_ptr,
parent_cache_info_flags_ptr, internal, &internal_flags, idx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to split child node")
} /* end else */
@@ -1863,11 +1622,11 @@ H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
else { /* Middle child */
if(retries > 0 && ((internal->node_ptrs[idx + 1].node_nrec < split_nrec) ||
(internal->node_ptrs[idx - 1].node_nrec < split_nrec))) {
- if(H5B2_redistribute3(f, dxpl_id, depth, internal, &internal_flags, idx) < 0)
+ if(H5B2_redistribute3(hdr, dxpl_id, depth, internal, &internal_flags, idx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records")
} /* end if */
else {
- if(H5B2_split1(f, dxpl_id, depth, curr_node_ptr,
+ if(H5B2_split1(hdr, dxpl_id, depth, curr_node_ptr,
parent_cache_info_flags_ptr, internal, &internal_flags, idx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to split child node")
} /* end else */
@@ -1875,7 +1634,7 @@ H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
/* Locate node pointer for child (after split/redistribute) */
/* Actually, this can be easily updated (for 2-node redistrib.) and shouldn't require re-searching */
- if((cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx)) == 0)
+ if((cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx)) == 0)
HGOTO_ERROR(H5E_BTREE, H5E_EXISTS, FAIL, "record is already in B-tree")
if(cmp > 0)
idx++;
@@ -1887,11 +1646,11 @@ H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
/* Attempt to insert node */
if(depth > 1) {
- if(H5B2_insert_internal(f, dxpl_id, bt2_shared, (depth - 1), &internal_flags, &internal->node_ptrs[idx], udata) < 0)
+ if(H5B2_insert_internal(hdr, dxpl_id, (depth - 1), &internal_flags, &internal->node_ptrs[idx], udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree internal node")
} /* end if */
else {
- if(H5B2_insert_leaf(f, dxpl_id, bt2_shared, &internal->node_ptrs[idx], udata) < 0)
+ if(H5B2_insert_leaf(hdr, dxpl_id, &internal->node_ptrs[idx], udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree leaf node")
} /* end else */
@@ -1903,7 +1662,7 @@ H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
done:
/* Release the B-tree internal node */
- if (internal && H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr->addr, internal, internal_flags) < 0)
+ if(internal && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr->addr, internal, internal_flags) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release internal B-tree node")
FUNC_LEAVE_NOAPI(ret_value)
@@ -1925,56 +1684,53 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_create_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, H5B2_node_ptr_t *node_ptr)
+H5B2_create_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *node_ptr)
{
H5B2_leaf_t *leaf = NULL; /* Pointer to new leaf node created */
- H5B2_shared_t *shared; /* Shared B-tree information */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5B2_create_leaf)
/* Check arguments. */
- HDassert(f);
- HDassert(bt2_shared);
+ HDassert(hdr);
HDassert(node_ptr);
/* Allocate memory for leaf information */
if(NULL == (leaf = H5FL_MALLOC(H5B2_leaf_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree leaf info")
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree leaf info")
/* Set metadata cache info */
HDmemset(&leaf->cache_info, 0, sizeof(H5AC_info_t));
- /* Share common B-tree information */
- leaf->shared = bt2_shared;
- H5RC_INC(leaf->shared);
+ /* Increment ref. count on B-tree header */
+ if(H5B2_hdr_incr(hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, FAIL, "can't increment ref. count on B-tree header")
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(leaf->shared);
- HDassert(shared);
+ /* Share B-tree header information */
+ leaf->hdr = hdr;
/* Allocate space for the native keys in memory */
- if((leaf->leaf_native = (uint8_t *)H5FL_FAC_MALLOC(shared->node_info[0].nat_rec_fac)) == NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree leaf native keys")
+ if(NULL == (leaf->leaf_native = (uint8_t *)H5FL_FAC_MALLOC(hdr->node_info[0].nat_rec_fac)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree leaf native keys")
#ifdef H5_CLEAR_MEMORY
-HDmemset(leaf->leaf_native, 0, shared->type->nrec_size * shared->node_info[0].max_nrec);
+HDmemset(leaf->leaf_native, 0, hdr->cls->nrec_size * hdr->node_info[0].max_nrec);
#endif /* H5_CLEAR_MEMORY */
/* Set number of records */
leaf->nrec = 0;
/* Allocate space on disk for the leaf */
- if(HADDR_UNDEF == (node_ptr->addr=H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)shared->node_size)))
+ if(HADDR_UNDEF == (node_ptr->addr = H5MF_alloc(hdr->f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)hdr->node_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree leaf node")
/* Cache the new B-tree node */
- if(H5AC_set(f, dxpl_id, H5AC_BT2_LEAF, node_ptr->addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_set(hdr->f, dxpl_id, H5AC_BT2_LEAF, node_ptr->addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't add B-tree leaf to cache")
done:
if(ret_value < 0) {
if(leaf)
- (void)H5B2_cache_leaf_dest(f,leaf);
+ (void)H5B2_cache_leaf_dest(hdr->f, leaf);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -1996,18 +1752,16 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_create_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
- H5B2_node_ptr_t *node_ptr, unsigned depth)
+H5B2_create_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *node_ptr,
+ unsigned depth)
{
- H5B2_internal_t *internal=NULL; /* Pointer to new internal node created */
- H5B2_shared_t *shared; /* Shared B-tree information */
+ H5B2_internal_t *internal = NULL; /* Pointer to new internal node created */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5B2_create_internal)
/* Check arguments. */
- HDassert(f);
- HDassert(bt2_shared);
+ HDassert(hdr);
HDassert(node_ptr);
HDassert(depth > 0);
@@ -2018,26 +1772,25 @@ H5B2_create_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
/* Set metadata cache info */
HDmemset(&internal->cache_info, 0, sizeof(H5AC_info_t));
- /* Share common B-tree information */
- internal->shared = bt2_shared;
- H5RC_INC(internal->shared);
+ /* Increment ref. count on B-tree header */
+ if(H5B2_hdr_incr(hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, FAIL, "can't increment ref. count on B-tree header")
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(internal->shared);
- HDassert(shared);
+ /* Share B-tree header information */
+ internal->hdr = hdr;
/* Allocate space for the native keys in memory */
- if((internal->int_native = (uint8_t *)H5FL_FAC_MALLOC(shared->node_info[depth].nat_rec_fac)) == NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal native keys")
+ if(NULL == (internal->int_native = (uint8_t *)H5FL_FAC_MALLOC(hdr->node_info[depth].nat_rec_fac)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal native keys")
#ifdef H5_CLEAR_MEMORY
-HDmemset(internal->int_native, 0, shared->type->nrec_size * shared->node_info[depth].max_nrec);
+HDmemset(internal->int_native, 0, hdr->cls->nrec_size * hdr->node_info[depth].max_nrec);
#endif /* H5_CLEAR_MEMORY */
/* Allocate space for the node pointers in memory */
- if((internal->node_ptrs = (H5B2_node_ptr_t *)H5FL_FAC_MALLOC(shared->node_info[depth].node_ptr_fac)) == NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal node pointers")
+ if(NULL == (internal->node_ptrs = (H5B2_node_ptr_t *)H5FL_FAC_MALLOC(hdr->node_info[depth].node_ptr_fac)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal node pointers")
#ifdef H5_CLEAR_MEMORY
-HDmemset(internal->node_ptrs, 0, sizeof(H5B2_node_ptr_t) * (shared->node_info[depth].max_nrec + 1));
+HDmemset(internal->node_ptrs, 0, sizeof(H5B2_node_ptr_t) * (hdr->node_info[depth].max_nrec + 1));
#endif /* H5_CLEAR_MEMORY */
/* Set number of records & depth of the node */
@@ -2045,17 +1798,17 @@ HDmemset(internal->node_ptrs, 0, sizeof(H5B2_node_ptr_t) * (shared->node_info[de
internal->depth = depth;
/* Allocate space on disk for the internal node */
- if(HADDR_UNDEF == (node_ptr->addr = H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)shared->node_size)))
+ if(HADDR_UNDEF == (node_ptr->addr = H5MF_alloc(hdr->f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)hdr->node_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree internal node")
/* Cache the new B-tree node */
- if(H5AC_set(f, dxpl_id, H5AC_BT2_INT, node_ptr->addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_set(hdr->f, dxpl_id, H5AC_BT2_INT, node_ptr->addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't add B-tree internal node to cache")
done:
if(ret_value < 0) {
if(internal)
- (void)H5B2_cache_internal_dest(f,internal);
+ (void)H5B2_cache_internal_dest(hdr->f, internal);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -2076,7 +1829,7 @@ done:
*-------------------------------------------------------------------------
*/
H5B2_internal_t *
-H5B2_protect_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, haddr_t addr,
+H5B2_protect_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, haddr_t addr,
unsigned nrec, unsigned depth, H5AC_protect_t rw)
{
H5B2_int_load_ud1_t udata; /* User data to pass through to cache 'load' callback */
@@ -2085,18 +1838,17 @@ H5B2_protect_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, haddr_t addr,
FUNC_ENTER_NOAPI_NOINIT(H5B2_protect_internal)
/* Check arguments. */
- HDassert(f);
- HDassert(bt2_shared);
+ HDassert(hdr);
HDassert(H5F_addr_defined(addr));
HDassert(depth > 0);
/* Set up user data for callback */
- udata.bt2_shared = bt2_shared;
+ udata.hdr = hdr;
udata.nrec = nrec;
udata.depth = depth;
/* Protect the internal node */
- if(NULL == (ret_value = (H5B2_internal_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_INT, addr, &udata, NULL, rw)))
+ if(NULL == (ret_value = (H5B2_internal_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_INT, addr, &udata, NULL, rw)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, NULL, "unable to load B-tree internal node")
done:
@@ -2122,10 +1874,9 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_iterate_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth,
+H5B2_iterate_node(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
const H5B2_node_ptr_t *curr_node, H5B2_operator_t op, void *op_data)
{
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
const H5AC_class_t *curr_node_class = NULL; /* Pointer to current node's class info */
void *node = NULL; /* Pointers to current node */
uint8_t *node_native; /* Pointers to node's native records */
@@ -2137,21 +1888,16 @@ H5B2_iterate_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth,
FUNC_ENTER_NOAPI_NOINIT(H5B2_iterate_node)
/* Check arguments. */
- HDassert(f);
- HDassert(bt2_shared);
+ HDassert(hdr);
HDassert(curr_node);
HDassert(op);
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
-
/* Protect current node & set up variables */
if(depth > 0) {
H5B2_internal_t *internal; /* Pointer to internal node */
/* Lock the current B-tree node */
- if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node->addr, curr_node->node_nrec, depth, H5AC_READ)))
+ if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node->addr, curr_node->node_nrec, depth, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Set up information about current node */
@@ -2160,8 +1906,8 @@ H5B2_iterate_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth,
node_native = internal->int_native;
/* Allocate space for the node pointers in memory */
- if((node_ptrs = (H5B2_node_ptr_t *)H5FL_FAC_MALLOC(shared->node_info[depth].node_ptr_fac)) == NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal node pointers")
+ if(NULL == (node_ptrs = (H5B2_node_ptr_t *)H5FL_FAC_MALLOC(hdr->node_info[depth].node_ptr_fac)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal node pointers")
/* Copy the node pointers */
HDmemcpy(node_ptrs, internal->node_ptrs, (sizeof(H5B2_node_ptr_t) * (curr_node->node_nrec + 1)));
@@ -2170,7 +1916,7 @@ H5B2_iterate_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth,
H5B2_leaf_t *leaf; /* Pointer to leaf node */
/* Lock the current B-tree node */
- if (NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node->addr, &(curr_node->node_nrec), bt2_shared, H5AC_READ)))
+ if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node->addr, &(curr_node->node_nrec), hdr, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
/* Set up information about current node */
@@ -2180,14 +1926,14 @@ H5B2_iterate_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth,
} /* end else */
/* Allocate space for the native keys in memory */
- if((native = (uint8_t *)H5FL_FAC_MALLOC(shared->node_info[depth].nat_rec_fac)) == NULL)
+ if(NULL == (native = (uint8_t *)H5FL_FAC_MALLOC(hdr->node_info[depth].nat_rec_fac)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal native keys")
/* Copy the native keys */
- HDmemcpy(native, node_native, (shared->type->nrec_size * curr_node->node_nrec));
+ HDmemcpy(native, node_native, (hdr->cls->nrec_size * curr_node->node_nrec));
/* Unlock the node */
- if(H5AC_unprotect(f, dxpl_id, curr_node_class, curr_node->addr, node, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, curr_node_class, curr_node->addr, node, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
node = NULL;
@@ -2195,29 +1941,29 @@ H5B2_iterate_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth,
for(u = 0; u < curr_node->node_nrec && !ret_value; u++) {
/* Descend into child node, if current node is an internal node */
if(depth > 0) {
- if((ret_value = H5B2_iterate_node(f, dxpl_id, bt2_shared, (depth - 1), &(node_ptrs[u]), op, op_data)) < 0)
+ if((ret_value = H5B2_iterate_node(hdr, dxpl_id, (depth - 1), &(node_ptrs[u]), op, op_data)) < 0)
HERROR(H5E_BTREE, H5E_CANTLIST, "node iteration failed");
} /* end if */
/* Make callback for current record */
if(!ret_value) {
- if((ret_value = (op)(H5B2_NAT_NREC(native, shared, u), op_data)) < 0)
+ if((ret_value = (op)(H5B2_NAT_NREC(native, hdr, u), op_data)) < 0)
HERROR(H5E_BTREE, H5E_CANTLIST, "iterator function failed");
} /* end if */
} /* end for */
/* Descend into last child node, if current node is an internal node */
if(!ret_value && depth > 0) {
- if((ret_value = H5B2_iterate_node(f, dxpl_id, bt2_shared, (depth - 1), &(node_ptrs[u]), op, op_data)) < 0)
+ if((ret_value = H5B2_iterate_node(hdr, dxpl_id, (depth - 1), &(node_ptrs[u]), op, op_data)) < 0)
HERROR(H5E_BTREE, H5E_CANTLIST, "node iteration failed");
} /* end if */
done:
/* Release the node pointers & native records, if they were copied */
if(node_ptrs)
- H5FL_FAC_FREE(shared->node_info[depth].node_ptr_fac, node_ptrs);
+ H5FL_FAC_FREE(hdr->node_info[depth].node_ptr_fac, node_ptrs);
if(native)
- H5FL_FAC_FREE(shared->node_info[depth].nat_rec_fac, native);
+ H5FL_FAC_FREE(hdr->node_info[depth].nat_rec_fac, native);
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_iterate_node() */
@@ -2237,45 +1983,38 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_remove_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
- H5B2_node_ptr_t *curr_node_ptr, void *udata, H5B2_remove_t op,
- void *op_data)
+H5B2_remove_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr,
+ void *udata, H5B2_remove_t op, void *op_data)
{
H5B2_leaf_t *leaf; /* Pointer to leaf node */
haddr_t leaf_addr = HADDR_UNDEF; /* Leaf address on disk */
unsigned leaf_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting leaf node */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
unsigned idx; /* Location of record which matches key */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5B2_remove_leaf)
/* Check arguments. */
- HDassert(f);
- HDassert(bt2_shared);
+ HDassert(hdr);
HDassert(curr_node_ptr);
HDassert(H5F_addr_defined(curr_node_ptr->addr));
/* Lock current B-tree node */
leaf_addr = curr_node_ptr->addr;
- if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, leaf_addr, &(curr_node_ptr->node_nrec), bt2_shared, H5AC_WRITE)))
+ if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, leaf_addr, &(curr_node_ptr->node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
-
/* Sanity check number of records */
HDassert(curr_node_ptr->all_nrec == curr_node_ptr->node_nrec);
HDassert(leaf->nrec == curr_node_ptr->node_nrec);
/* Find correct location to remove this record */
- if(H5B2_locate_record(shared->type, leaf->nrec, shared->nat_off, leaf->leaf_native, udata, &idx) != 0)
+ if(H5B2_locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx) != 0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "record is not in B-tree")
/* Make 'remove' callback if there is one */
if(op)
- if((op)(H5B2_LEAF_NREC(leaf, shared, idx), op_data) < 0)
+ if((op)(H5B2_LEAF_NREC(leaf, hdr, idx), op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record into leaf node")
/* Update number of records in node */
@@ -2287,15 +2026,11 @@ H5B2_remove_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
if(leaf->nrec > 0) {
/* Pack record out of leaf */
if(idx < leaf->nrec)
- HDmemmove(H5B2_LEAF_NREC(leaf, shared, idx), H5B2_LEAF_NREC(leaf, shared, (idx + 1)), shared->type->nrec_size * (leaf->nrec-idx));
+ HDmemmove(H5B2_LEAF_NREC(leaf, hdr, idx), H5B2_LEAF_NREC(leaf, hdr, (idx + 1)), hdr->cls->nrec_size * (leaf->nrec - idx));
} /* end if */
else {
- /* Release space for B-tree node on disk */
- if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, leaf_addr, (hsize_t)shared->node_size) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free B-tree leaf node")
-
/* Let the cache know that the object is deleted */
- leaf_flags |= H5AC__DELETED_FLAG;
+ leaf_flags |= H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG;
/* Reset address of parent node pointer */
curr_node_ptr->addr = HADDR_UNDEF;
@@ -2306,7 +2041,7 @@ H5B2_remove_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
done:
/* Release the B-tree leaf node */
- if(leaf && H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, leaf_addr, leaf, leaf_flags) < 0)
+ if(leaf && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, leaf_addr, leaf, leaf_flags) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release leaf B-tree node")
FUNC_LEAVE_NOAPI(ret_value)
@@ -2327,11 +2062,10 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
- hbool_t *depth_decreased, void *swap_loc, unsigned depth,
- H5AC_info_t *parent_cache_info, unsigned *parent_cache_info_flags_ptr,
- H5B2_node_ptr_t *curr_node_ptr, void *udata, H5B2_remove_t op,
- void *op_data)
+H5B2_remove_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, hbool_t *depth_decreased,
+ void *swap_loc, unsigned depth, H5AC_info_t *parent_cache_info,
+ unsigned *parent_cache_info_flags_ptr, H5B2_node_ptr_t *curr_node_ptr,
+ void *udata, H5B2_remove_t op, void *op_data)
{
H5AC_info_t *new_cache_info; /* Pointer to new cache info */
unsigned *new_cache_info_flags_ptr = NULL;
@@ -2339,7 +2073,6 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
H5B2_internal_t *internal; /* Pointer to internal node */
unsigned internal_flags = H5AC__NO_FLAGS_SET;
haddr_t internal_addr; /* Address of internal node */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
size_t merge_nrec; /* Number of records to merge node at */
hbool_t collapsed_root = FALSE; /* Whether the root was collapsed */
herr_t ret_value = SUCCEED;
@@ -2347,25 +2080,19 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
FUNC_ENTER_NOAPI_NOINIT(H5B2_remove_internal)
/* Check arguments. */
- HDassert(f);
- HDassert(bt2_shared);
+ HDassert(hdr);
HDassert(depth > 0);
HDassert(parent_cache_info);
- HDassert(parent_cache_info_flags_ptr);
HDassert(curr_node_ptr);
HDassert(H5F_addr_defined(curr_node_ptr->addr));
/* Lock current B-tree node */
internal_addr = curr_node_ptr->addr;
- if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, internal_addr, curr_node_ptr->node_nrec, depth, H5AC_WRITE)))
+ if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, internal_addr, curr_node_ptr->node_nrec, depth, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
-
/* Determine the correct number of records to merge at */
- merge_nrec = shared->node_info[depth - 1].merge_nrec;
+ merge_nrec = hdr->node_info[depth - 1].merge_nrec;
/* Check for needing to collapse the root node */
/* (The root node is the only internal node allowed to have 1 record) */
@@ -2373,16 +2100,12 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
((internal->node_ptrs[0].node_nrec + internal->node_ptrs[1].node_nrec) <= ((merge_nrec * 2) + 1))) {
/* Merge children of root node */
- if(H5B2_merge2(f, dxpl_id, depth, curr_node_ptr,
+ if(H5B2_merge2(hdr, dxpl_id, depth, curr_node_ptr,
parent_cache_info_flags_ptr, internal, &internal_flags, 0) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to merge child node")
- /* Release space for root B-tree node on disk */
- if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, internal_addr, (hsize_t)shared->node_size) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free B-tree leaf node")
-
/* Let the cache know that the object is deleted */
- internal_flags |= H5AC__DELETED_FLAG;
+ internal_flags |= H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG;
/* Reset information in header's root node pointer */
curr_node_ptr->addr = internal->node_ptrs[0].addr;
@@ -2409,7 +2132,7 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
if(swap_loc)
idx = 0;
else {
- cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx);
+ cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx);
if(cmp >= 0)
idx++;
} /* end else */
@@ -2433,22 +2156,22 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
*/
if(idx == 0) { /* Left-most child */
if(retries > 0 && (internal->node_ptrs[idx + 1].node_nrec > merge_nrec)) {
- if(H5B2_redistribute2(f, dxpl_id, depth, internal, idx) < 0)
+ if(H5B2_redistribute2(hdr, dxpl_id, depth, internal, idx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records")
} /* end if */
else {
- if(H5B2_merge2(f, dxpl_id, depth, curr_node_ptr,
+ if(H5B2_merge2(hdr, dxpl_id, depth, curr_node_ptr,
parent_cache_info_flags_ptr, internal, &internal_flags, idx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to merge child node")
} /* end else */
} /* end if */
else if(idx == internal->nrec) { /* Right-most child */
if(retries > 0 && (internal->node_ptrs[idx - 1].node_nrec > merge_nrec)) {
- if(H5B2_redistribute2(f, dxpl_id, depth, internal, (idx - 1)) < 0)
+ if(H5B2_redistribute2(hdr, dxpl_id, depth, internal, (idx - 1)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records")
} /* end if */
else {
- if(H5B2_merge2(f, dxpl_id, depth, curr_node_ptr,
+ if(H5B2_merge2(hdr, dxpl_id, depth, curr_node_ptr,
parent_cache_info_flags_ptr, internal, &internal_flags, (idx - 1)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to merge child node")
} /* end else */
@@ -2456,11 +2179,11 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
else { /* Middle child */
if(retries > 0 && ((internal->node_ptrs[idx + 1].node_nrec > merge_nrec) ||
(internal->node_ptrs[idx - 1].node_nrec > merge_nrec))) {
- if(H5B2_redistribute3(f, dxpl_id, depth, internal, &internal_flags, idx) < 0)
+ if(H5B2_redistribute3(hdr, dxpl_id, depth, internal, &internal_flags, idx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records")
} /* end if */
else {
- if(H5B2_merge3(f, dxpl_id, depth, curr_node_ptr,
+ if(H5B2_merge3(hdr, dxpl_id, depth, curr_node_ptr,
parent_cache_info_flags_ptr, internal, &internal_flags, idx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to merge child node")
} /* end else */
@@ -2471,7 +2194,7 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
idx = 0;
else {
/* Actually, this can be easily updated (for 2-node redistrib.) and shouldn't require re-searching */
- cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx);
+ cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx);
if(cmp >= 0)
idx++;
} /* end else */
@@ -2482,11 +2205,11 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
/* Handle deleting a record from an internal node */
if(!swap_loc && cmp == 0)
- swap_loc = H5B2_INT_NREC(internal, shared, idx - 1);
+ swap_loc = H5B2_INT_NREC(internal, hdr, idx - 1);
/* Swap record to delete with record from leaf, if we are the last internal node */
if(swap_loc && depth == 1)
- if(H5B2_swap_leaf(f, dxpl_id, depth, internal, &internal_flags, idx, swap_loc) < 0)
+ if(H5B2_swap_leaf(hdr, dxpl_id, depth, internal, &internal_flags, idx, swap_loc) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSWAP, FAIL, "Can't swap records in B-tree")
/* Set pointers for advancing to child node */
@@ -2497,12 +2220,12 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
/* Attempt to remove record from child node */
if(depth > 1) {
- if(H5B2_remove_internal(f, dxpl_id, bt2_shared, depth_decreased, swap_loc, depth - 1,
+ if(H5B2_remove_internal(hdr, dxpl_id, depth_decreased, swap_loc, depth - 1,
new_cache_info, new_cache_info_flags_ptr, new_node_ptr, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree internal node")
} /* end if */
else {
- if(H5B2_remove_leaf(f, dxpl_id, bt2_shared, new_node_ptr, udata, op, op_data) < 0)
+ if(H5B2_remove_leaf(hdr, dxpl_id, new_node_ptr, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree leaf node")
} /* end else */
@@ -2514,12 +2237,12 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
internal_flags |= H5AC__DIRTIED_FLAG;
#ifdef H5B2_DEBUG
- H5B2_assert_internal((!collapsed_root ? (curr_node_ptr->all_nrec-1) : new_node_ptr->all_nrec),shared,internal);
+ H5B2_assert_internal((!collapsed_root ? (curr_node_ptr->all_nrec - 1) : new_node_ptr->all_nrec), hdr, internal);
#endif /* H5B2_DEBUG */
done:
/* Release the B-tree internal node */
- if(internal && H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, internal_addr, internal, internal_flags) < 0)
+ if(internal && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, internal_addr, internal, internal_flags) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release internal B-tree node")
FUNC_LEAVE_NOAPI(ret_value)
@@ -2541,33 +2264,27 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_remove_leaf_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
+H5B2_remove_leaf_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id,
H5B2_node_ptr_t *curr_node_ptr, unsigned idx, H5B2_remove_t op,
void *op_data)
{
H5B2_leaf_t *leaf; /* Pointer to leaf node */
haddr_t leaf_addr = HADDR_UNDEF; /* Leaf address on disk */
unsigned leaf_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting leaf node */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5B2_remove_leaf_by_idx)
/* Check arguments. */
- HDassert(f);
- HDassert(bt2_shared);
+ HDassert(hdr);
HDassert(curr_node_ptr);
HDassert(H5F_addr_defined(curr_node_ptr->addr));
/* Lock B-tree leaf node */
leaf_addr = curr_node_ptr->addr;
- if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, leaf_addr, &(curr_node_ptr->node_nrec), bt2_shared, H5AC_WRITE)))
+ if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, leaf_addr, &(curr_node_ptr->node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
-
/* Sanity check number of records */
HDassert(curr_node_ptr->all_nrec == curr_node_ptr->node_nrec);
HDassert(leaf->nrec == curr_node_ptr->node_nrec);
@@ -2575,7 +2292,7 @@ H5B2_remove_leaf_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
/* Make 'remove' callback if there is one */
if(op)
- if((op)(H5B2_LEAF_NREC(leaf, shared, idx), op_data) < 0)
+ if((op)(H5B2_LEAF_NREC(leaf, hdr, idx), op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record into leaf node")
/* Update number of records in node */
@@ -2587,15 +2304,11 @@ H5B2_remove_leaf_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
if(leaf->nrec > 0) {
/* Pack record out of leaf */
if(idx < leaf->nrec)
- HDmemmove(H5B2_LEAF_NREC(leaf, shared, idx), H5B2_LEAF_NREC(leaf, shared, (idx + 1)), shared->type->nrec_size * (leaf->nrec-idx));
+ HDmemmove(H5B2_LEAF_NREC(leaf, hdr, idx), H5B2_LEAF_NREC(leaf, hdr, (idx + 1)), hdr->cls->nrec_size * (leaf->nrec - idx));
} /* end if */
else {
- /* Release space for B-tree node on disk */
- if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, leaf_addr, (hsize_t)shared->node_size) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free B-tree leaf node")
-
/* Let the cache know that the object is deleted */
- leaf_flags |= H5AC__DELETED_FLAG;
+ leaf_flags |= H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG;
/* Reset address of parent node pointer */
curr_node_ptr->addr = HADDR_UNDEF;
@@ -2606,7 +2319,7 @@ H5B2_remove_leaf_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
done:
/* Release the B-tree leaf node */
- if(leaf && H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, leaf_addr, leaf, leaf_flags) < 0)
+ if(leaf && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, leaf_addr, leaf, leaf_flags) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release leaf B-tree node")
FUNC_LEAVE_NOAPI(ret_value)
@@ -2628,7 +2341,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
+H5B2_remove_internal_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id,
hbool_t *depth_decreased, void *swap_loc, unsigned depth,
H5AC_info_t *parent_cache_info, unsigned *parent_cache_info_flags_ptr,
H5B2_node_ptr_t *curr_node_ptr, hsize_t n, H5B2_remove_t op,
@@ -2640,7 +2353,6 @@ H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
H5B2_internal_t *internal; /* Pointer to internal node */
unsigned internal_flags = H5AC__NO_FLAGS_SET;
haddr_t internal_addr; /* Address of internal node */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
size_t merge_nrec; /* Number of records to merge node at */
hbool_t collapsed_root = FALSE; /* Whether the root was collapsed */
herr_t ret_value = SUCCEED;
@@ -2648,45 +2360,35 @@ H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
FUNC_ENTER_NOAPI_NOINIT(H5B2_remove_internal_by_idx)
/* Check arguments. */
- HDassert(f);
- HDassert(bt2_shared);
+ HDassert(hdr);
HDassert(depth > 0);
HDassert(parent_cache_info);
- HDassert(parent_cache_info_flags_ptr);
HDassert(curr_node_ptr);
HDassert(H5F_addr_defined(curr_node_ptr->addr));
/* Lock current B-tree node */
internal_addr = curr_node_ptr->addr;
- if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, internal_addr, curr_node_ptr->node_nrec, depth, H5AC_WRITE)))
+ if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, internal_addr, curr_node_ptr->node_nrec, depth, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
HDassert(internal->nrec == curr_node_ptr->node_nrec);
-
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
- HDassert(depth == shared->depth || internal->nrec > 1);
+ HDassert(depth == hdr->depth || internal->nrec > 1);
/* Determine the correct number of records to merge at */
- merge_nrec = shared->node_info[depth - 1].merge_nrec;
+ merge_nrec = hdr->node_info[depth - 1].merge_nrec;
/* Check for needing to collapse the root node */
/* (The root node is the only internal node allowed to have 1 record) */
if(internal->nrec == 1 &&
((internal->node_ptrs[0].node_nrec + internal->node_ptrs[1].node_nrec) <= ((merge_nrec * 2) + 1))) {
- HDassert(depth == shared->depth);
+ HDassert(depth == hdr->depth);
/* Merge children of root node */
- if(H5B2_merge2(f, dxpl_id, depth, curr_node_ptr,
+ if(H5B2_merge2(hdr, dxpl_id, depth, curr_node_ptr,
parent_cache_info_flags_ptr, internal, &internal_flags, 0) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to merge child node")
- /* Release space for root B-tree node on disk */
- if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, internal_addr, (hsize_t)shared->node_size) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free B-tree leaf node")
-
/* Let the cache know that the object is deleted */
- internal_flags |= H5AC__DELETED_FLAG;
+ internal_flags |= H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG;
/* Reset information in header's root node pointer */
curr_node_ptr->addr = internal->node_ptrs[0].addr;
@@ -2760,22 +2462,22 @@ H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
*/
if(idx == 0) { /* Left-most child */
if(retries > 0 && (internal->node_ptrs[idx + 1].node_nrec > merge_nrec)) {
- if(H5B2_redistribute2(f, dxpl_id, depth, internal, idx) < 0)
+ if(H5B2_redistribute2(hdr, dxpl_id, depth, internal, idx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records")
} /* end if */
else {
- if(H5B2_merge2(f, dxpl_id, depth, curr_node_ptr,
+ if(H5B2_merge2(hdr, dxpl_id, depth, curr_node_ptr,
parent_cache_info_flags_ptr, internal, &internal_flags, idx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to merge child node")
} /* end else */
} /* end if */
else if(idx == internal->nrec) { /* Right-most child */
if(retries > 0 && (internal->node_ptrs[idx - 1].node_nrec > merge_nrec)) {
- if(H5B2_redistribute2(f, dxpl_id, depth, internal, (idx - 1)) < 0)
+ if(H5B2_redistribute2(hdr, dxpl_id, depth, internal, (idx - 1)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records")
} /* end if */
else {
- if(H5B2_merge2(f, dxpl_id, depth, curr_node_ptr,
+ if(H5B2_merge2(hdr, dxpl_id, depth, curr_node_ptr,
parent_cache_info_flags_ptr, internal, &internal_flags, (idx - 1)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to merge child node")
} /* end else */
@@ -2783,11 +2485,11 @@ H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
else { /* Middle child */
if(retries > 0 && ((internal->node_ptrs[idx + 1].node_nrec > merge_nrec) ||
(internal->node_ptrs[idx - 1].node_nrec > merge_nrec))) {
- if(H5B2_redistribute3(f, dxpl_id, depth, internal, &internal_flags, idx) < 0)
+ if(H5B2_redistribute3(hdr, dxpl_id, depth, internal, &internal_flags, idx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records")
} /* end if */
else {
- if(H5B2_merge3(f, dxpl_id, depth, curr_node_ptr,
+ if(H5B2_merge3(hdr, dxpl_id, depth, curr_node_ptr,
parent_cache_info_flags_ptr, internal, &internal_flags, idx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to merge child node")
} /* end else */
@@ -2838,11 +2540,11 @@ H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
/* Handle deleting a record from an internal node */
if(!swap_loc && found)
- swap_loc = H5B2_INT_NREC(internal, shared, idx - 1);
+ swap_loc = H5B2_INT_NREC(internal, hdr, idx - 1);
/* Swap record to delete with record from leaf, if we are the last internal node */
if(swap_loc && depth == 1)
- if(H5B2_swap_leaf(f, dxpl_id, depth, internal, &internal_flags, idx, swap_loc) < 0)
+ if(H5B2_swap_leaf(hdr, dxpl_id, depth, internal, &internal_flags, idx, swap_loc) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSWAP, FAIL, "can't swap records in B-tree")
/* Set pointers for advancing to child node */
@@ -2853,12 +2555,12 @@ H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
/* Attempt to remove record from child node */
if(depth > 1) {
- if(H5B2_remove_internal_by_idx(f, dxpl_id, bt2_shared, depth_decreased, swap_loc, depth - 1,
+ if(H5B2_remove_internal_by_idx(hdr, dxpl_id, depth_decreased, swap_loc, depth - 1,
new_cache_info, new_cache_info_flags_ptr, new_node_ptr, n, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree internal node")
} /* end if */
else {
- if(H5B2_remove_leaf_by_idx(f, dxpl_id, bt2_shared, new_node_ptr, (unsigned)n, op, op_data) < 0)
+ if(H5B2_remove_leaf_by_idx(hdr, dxpl_id, new_node_ptr, (unsigned)n, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree leaf node")
} /* end else */
@@ -2870,12 +2572,12 @@ H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
internal_flags |= H5AC__DIRTIED_FLAG;
#ifdef H5B2_DEBUG
- H5B2_assert_internal((!collapsed_root ? (curr_node_ptr->all_nrec-1) : new_node_ptr->all_nrec),shared,internal);
+ H5B2_assert_internal((!collapsed_root ? (curr_node_ptr->all_nrec - 1) : new_node_ptr->all_nrec), hdr, internal);
#endif /* H5B2_DEBUG */
done:
/* Release the B-tree internal node */
- if(internal && H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, internal_addr, internal, internal_flags) < 0)
+ if(internal && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, internal_addr, internal, internal_flags) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release internal B-tree node")
FUNC_LEAVE_NOAPI(ret_value)
@@ -2909,36 +2611,29 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_neighbor_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
- H5B2_node_ptr_t *curr_node_ptr, void *neighbor_loc,
- H5B2_compare_t comp, void *udata, H5B2_found_t op, void *op_data)
+H5B2_neighbor_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr,
+ void *neighbor_loc, H5B2_compare_t comp, void *udata, H5B2_found_t op,
+ void *op_data)
{
H5B2_leaf_t *leaf; /* Pointer to leaf node */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
unsigned idx; /* Location of record which matches key */
- int cmp=0; /* Comparison value of records */
+ int cmp = 0; /* Comparison value of records */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5B2_neighbor_leaf)
/* Check arguments. */
- HDassert(f);
- HDassert(bt2_shared);
+ HDassert(hdr);
HDassert(curr_node_ptr);
HDassert(H5F_addr_defined(curr_node_ptr->addr));
HDassert(op);
/* Lock current B-tree node */
- if (NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, &(curr_node_ptr->node_nrec), bt2_shared, H5AC_READ)))
+ if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, &(curr_node_ptr->node_nrec), hdr, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
- /* Get the pointer to the shared B-tree info */
- shared=(H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
-
-
/* Locate node pointer for child */
- cmp = H5B2_locate_record(shared->type, leaf->nrec, shared->nat_off, leaf->leaf_native, udata, &idx);
+ cmp = H5B2_locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx);
if(cmp > 0)
idx++;
else
@@ -2948,19 +2643,19 @@ H5B2_neighbor_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
/* Set the neighbor location, if appropriate */
if(comp == H5B2_COMPARE_LESS) {
if(idx > 0)
- neighbor_loc = H5B2_LEAF_NREC(leaf,shared,idx-1);
+ neighbor_loc = H5B2_LEAF_NREC(leaf, hdr, idx - 1);
} /* end if */
else {
HDassert(comp == H5B2_COMPARE_GREATER);
if(idx < leaf->nrec)
- neighbor_loc = H5B2_LEAF_NREC(leaf,shared,idx);
+ neighbor_loc = H5B2_LEAF_NREC(leaf, hdr, idx);
} /* end else */
/* Make callback if neighbor record has been found */
if(neighbor_loc) {
/* Make callback for current record */
- if ((op)(neighbor_loc, op_data) < 0)
+ if((op)(neighbor_loc, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree neighbor operation")
} /* end if */
else
@@ -2968,7 +2663,7 @@ H5B2_neighbor_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
done:
/* Release the B-tree internal node */
- if (leaf && H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(leaf && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree leaf node")
FUNC_LEAVE_NOAPI(ret_value)
@@ -3002,64 +2697,58 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_neighbor_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
- unsigned depth, H5B2_node_ptr_t *curr_node_ptr, void *neighbor_loc,
- H5B2_compare_t comp, void *udata, H5B2_found_t op, void *op_data)
+H5B2_neighbor_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
+ H5B2_node_ptr_t *curr_node_ptr, void *neighbor_loc, H5B2_compare_t comp,
+ void *udata, H5B2_found_t op, void *op_data)
{
H5B2_internal_t *internal; /* Pointer to internal node */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
unsigned idx; /* Location of record which matches key */
- int cmp=0; /* Comparison value of records */
+ int cmp = 0; /* Comparison value of records */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5B2_neighbor_internal)
/* Check arguments. */
- HDassert(f);
- HDassert(bt2_shared);
- HDassert(depth>0);
+ HDassert(hdr);
+ HDassert(depth > 0);
HDassert(curr_node_ptr);
HDassert(H5F_addr_defined(curr_node_ptr->addr));
HDassert(op);
/* Lock current B-tree node */
- if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node_ptr->addr, curr_node_ptr->node_nrec, depth, H5AC_READ)))
+ if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node_ptr->addr, curr_node_ptr->node_nrec, depth, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
-
/* Locate node pointer for child */
- cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx);
+ cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx);
if(cmp > 0)
idx++;
/* Set the neighbor location, if appropriate */
if(comp == H5B2_COMPARE_LESS) {
if(idx > 0)
- neighbor_loc = H5B2_INT_NREC(internal,shared,idx-1);
+ neighbor_loc = H5B2_INT_NREC(internal, hdr, idx - 1);
} /* end if */
else {
HDassert(comp == H5B2_COMPARE_GREATER);
if(idx < internal->nrec)
- neighbor_loc = H5B2_INT_NREC(internal,shared,idx);
+ neighbor_loc = H5B2_INT_NREC(internal, hdr, idx);
} /* end else */
/* Attempt to find neighboring record */
- if(depth>1) {
- if(H5B2_neighbor_internal(f, dxpl_id, bt2_shared, depth-1, &internal->node_ptrs[idx], neighbor_loc, comp, udata, op, op_data) < 0)
+ if(depth > 1) {
+ if(H5B2_neighbor_internal(hdr, dxpl_id, depth - 1, &internal->node_ptrs[idx], neighbor_loc, comp, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "unable to find neighbor record in B-tree internal node")
} /* end if */
else {
- if(H5B2_neighbor_leaf(f, dxpl_id, bt2_shared, &internal->node_ptrs[idx], neighbor_loc, comp, udata, op, op_data) < 0)
+ if(H5B2_neighbor_leaf(hdr, dxpl_id, &internal->node_ptrs[idx], neighbor_loc, comp, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "unable to find neighbor record in B-tree leaf node")
} /* end else */
done:
/* Release the B-tree internal node */
- if (internal && H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr->addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(internal && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr->addr, internal, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release internal B-tree node")
FUNC_LEAVE_NOAPI(ret_value)
@@ -3081,32 +2770,26 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_delete_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth,
+H5B2_delete_node(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
const H5B2_node_ptr_t *curr_node, H5B2_remove_t op, void *op_data)
{
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- const H5AC_class_t *curr_node_class=NULL; /* Pointer to current node's class info */
- void *node=NULL; /* Pointers to current node */
+ const H5AC_class_t *curr_node_class = NULL; /* Pointer to current node's class info */
+ void *node = NULL; /* Pointers to current node */
uint8_t *native; /* Pointers to node's native records */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5B2_delete_node)
/* Check arguments. */
- HDassert(f);
- HDassert(bt2_shared);
+ HDassert(hdr);
HDassert(curr_node);
- /* Get the pointer to the shared B-tree info */
- shared=(H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
-
- if(depth>0) {
+ if(depth > 0) {
H5B2_internal_t *internal; /* Pointer to internal node */
unsigned u; /* Local index */
/* Lock the current B-tree node */
- if (NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node->addr, curr_node->node_nrec, depth, H5AC_WRITE)))
+ if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node->addr, curr_node->node_nrec, depth, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Set up information about current node */
@@ -3115,15 +2798,15 @@ H5B2_delete_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth,
native = internal->int_native;
/* Descend into children */
- for(u=0; u<internal->nrec+1; u++)
- if(H5B2_delete_node(f, dxpl_id, bt2_shared, depth-1, &(internal->node_ptrs[u]), op, op_data) < 0)
+ for(u = 0; u < internal->nrec + 1; u++)
+ if(H5B2_delete_node(hdr, dxpl_id, depth - 1, &(internal->node_ptrs[u]), op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "node descent failed")
} /* end if */
else {
H5B2_leaf_t *leaf; /* Pointer to leaf node */
/* Lock the current B-tree node */
- if (NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node->addr, &(curr_node->node_nrec), bt2_shared, H5AC_WRITE)))
+ if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node->addr, &(curr_node->node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node")
/* Set up information about current node */
@@ -3139,61 +2822,50 @@ H5B2_delete_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth,
/* Iterate through records in this node */
for(u = 0; u < curr_node->node_nrec; u++) {
/* Make callback for each record */
- if((op)(H5B2_NAT_NREC(native, shared, u), op_data) < 0)
+ if((op)(H5B2_NAT_NREC(native, hdr, u), op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "iterator function failed")
} /* end for */
} /* end if */
- /* Release space for current B-tree node on disk */
- if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, curr_node->addr, (hsize_t)shared->node_size) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free B-tree node")
-
done:
/* Unlock & delete current node */
- if(node)
- if(H5AC_unprotect(f, dxpl_id, curr_node_class, curr_node->addr, node, H5AC__DELETED_FLAG) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
+ if(node && H5AC_unprotect(hdr->f, dxpl_id, curr_node_class, curr_node->addr, node, H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_delete_node() */
/*-------------------------------------------------------------------------
- * Function: H5B2_iterate_size_node
- *
+ * Function: H5B2_node_size
+ *
* Purpose: Iterate over all the records from a B-tree node, collecting
* btree storage info.
- *
+ *
* Return: non-negative on success, negative on error
- *
+ *
* Programmer: Vailin Choi
* July 12 2007
- *
+ *
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_iterate_size_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth,
+H5B2_node_size(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
const H5B2_node_ptr_t *curr_node, hsize_t *btree_size)
{
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
H5B2_internal_t *internal = NULL; /* Pointer to internal node */
herr_t ret_value = SUCCEED; /* Iterator return value */
- FUNC_ENTER_NOAPI(H5B2_iterate_size_node, FAIL)
+ FUNC_ENTER_NOAPI(H5B2_node_size, FAIL)
/* Check arguments. */
- HDassert(f);
- HDassert(bt2_shared);
+ HDassert(hdr);
HDassert(curr_node);
HDassert(btree_size);
HDassert(depth > 0);
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
-
/* Lock the current B-tree node */
- if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node->addr, curr_node->node_nrec, depth, H5AC_READ)))
+ if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node->addr, curr_node->node_nrec, depth, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Recursively descend into child nodes, if we are above the "twig" level in the B-tree */
@@ -3202,21 +2874,21 @@ H5B2_iterate_size_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned dep
/* Descend into children */
for(u = 0; u < internal->nrec + 1; u++)
- if(H5B2_iterate_size_node(f, dxpl_id, bt2_shared, (depth - 1), &(internal->node_ptrs[u]), btree_size) < 0)
+ if(H5B2_node_size(hdr, dxpl_id, (depth - 1), &(internal->node_ptrs[u]), btree_size) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "node iteration failed")
} /* end if */
else /* depth is 1: count all the leaf nodes from this node */
- *btree_size += (internal->nrec + 1) * shared->node_size;
+ *btree_size += (internal->nrec + 1) * hdr->node_size;
/* Count this node */
- *btree_size += shared->node_size;
+ *btree_size += hdr->node_size;
done:
- if(internal && H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node->addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(internal && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node->addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5B2_iterate_size_node() */
+} /* H5B2_node_size() */
#ifdef H5B2_DEBUG
@@ -3234,17 +2906,10 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_assert_leaf(H5B2_shared_t *shared, H5B2_leaf_t *leaf)
+H5B2_assert_leaf(H5B2_hdr_t *hdr, H5B2_leaf_t *leaf)
{
- unsigned u,v; /* Local index variables */
-
/* General sanity checking on node */
- HDassert(leaf->nrec<=shared->split_leaf_nrec);
-
- /* Sanity checking on records */
- for(u=0; u<leaf->nrec; u++)
- for(v=0; v<u; v++)
- HDassert((shared->type->compare)(H5B2_LEAF_NREC(leaf,shared,u), H5B2_LEAF_NREC(leaf,shared,v))>0);
+ HDassert(leaf->nrec <= hdr->node_info->split_nrec);
return(0);
} /* end H5B2_assert_leaf() */
@@ -3264,19 +2929,10 @@ H5B2_assert_leaf(H5B2_shared_t *shared, H5B2_leaf_t *leaf)
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_assert_leaf2(H5B2_shared_t *shared, H5B2_leaf_t *leaf, H5B2_leaf_t *leaf2)
+H5B2_assert_leaf2(H5B2_hdr_t *hdr, H5B2_leaf_t *leaf, H5B2_leaf_t *leaf2)
{
- unsigned u,v; /* Local index variables */
-
/* General sanity checking on node */
- HDassert(leaf->nrec<=shared->split_leaf_nrec);
-
- /* Sanity checking on records */
- for(u=0; u<leaf->nrec; u++) {
- HDassert((shared->type->compare)(H5B2_LEAF_NREC(leaf2,shared,0), H5B2_LEAF_NREC(leaf,shared,u))>0);
- for(v=0; v<u; v++)
- HDassert((shared->type->compare)(H5B2_LEAF_NREC(leaf,shared,u), H5B2_LEAF_NREC(leaf,shared,v))>0);
- } /* end for */
+ HDassert(leaf->nrec <= hdr->node_info->split_nrec);
return(0);
} /* end H5B2_assert_leaf() */
@@ -3296,32 +2952,27 @@ H5B2_assert_leaf2(H5B2_shared_t *shared, H5B2_leaf_t *leaf, H5B2_leaf_t *leaf2)
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_assert_internal(hsize_t parent_all_nrec, H5B2_shared_t *shared, H5B2_internal_t *internal)
+H5B2_assert_internal(hsize_t parent_all_nrec, H5B2_hdr_t *hdr, H5B2_internal_t *internal)
{
hsize_t tot_all_nrec; /* Total number of records at or below this node */
- unsigned u,v; /* Local index variables */
+ unsigned u, v; /* Local index variables */
/* General sanity checking on node */
- HDassert(internal->nrec<=shared->split_int_nrec);
-
- /* Sanity checking on records */
- for(u=0; u<internal->nrec; u++)
- for(v=0; v<u; v++)
- HDassert((shared->type->compare)(H5B2_INT_NREC(internal,shared,u), H5B2_INT_NREC(internal,shared,v))>0);
+ HDassert(internal->nrec <= hdr->node_info->split_nrec);
/* Sanity checking on node pointers */
- tot_all_nrec=internal->nrec;
- for(u=0; u<internal->nrec+1; u++) {
+ tot_all_nrec = internal->nrec;
+ for(u = 0; u < internal->nrec + 1; u++) {
tot_all_nrec += internal->node_ptrs[u].all_nrec;
HDassert(H5F_addr_defined(internal->node_ptrs[u].addr));
- HDassert(internal->node_ptrs[u].addr>0);
- for(v=0; v<u; v++)
- HDassert(internal->node_ptrs[u].addr!=internal->node_ptrs[v].addr);
+ HDassert(internal->node_ptrs[u].addr > 0);
+ for(v = 0; v < u; v++)
+ HDassert(internal->node_ptrs[u].addr != internal->node_ptrs[v].addr);
} /* end for */
/* Sanity check all_nrec total in parent */
- if(parent_all_nrec>0)
+ if(parent_all_nrec > 0)
HDassert(tot_all_nrec == parent_all_nrec);
return(0);
@@ -3342,34 +2993,29 @@ H5B2_assert_internal(hsize_t parent_all_nrec, H5B2_shared_t *shared, H5B2_intern
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_assert_internal2(hsize_t parent_all_nrec, H5B2_shared_t *shared, H5B2_internal_t *internal, H5B2_internal_t *internal2)
+H5B2_assert_internal2(hsize_t parent_all_nrec, H5B2_hdr_t *hdr, H5B2_internal_t *internal, H5B2_internal_t *internal2)
{
hsize_t tot_all_nrec; /* Total number of records at or below this node */
- unsigned u,v; /* Local index variables */
+ unsigned u, v; /* Local index variables */
/* General sanity checking on node */
- HDassert(internal->nrec<=shared->split_int_nrec);
-
- /* Sanity checking on records */
- for(u=0; u<internal->nrec; u++)
- for(v=0; v<u; v++)
- HDassert((shared->type->compare)(H5B2_INT_NREC(internal,shared,u), H5B2_INT_NREC(internal,shared,v))>0);
+ HDassert(internal->nrec <= hdr->node_info->split_nrec);
/* Sanity checking on node pointers */
- tot_all_nrec=internal->nrec;
- for(u=0; u<internal->nrec+1; u++) {
+ tot_all_nrec =internal->nrec;
+ for(u =0; u < internal->nrec + 1; u++) {
tot_all_nrec += internal->node_ptrs[u].all_nrec;
HDassert(H5F_addr_defined(internal->node_ptrs[u].addr));
- HDassert(internal->node_ptrs[u].addr>0);
- for(v=0; v<u; v++)
- HDassert(internal->node_ptrs[u].addr!=internal->node_ptrs[v].addr);
- for(v=0; v<internal2->nrec+1; v++)
- HDassert(internal->node_ptrs[u].addr!=internal2->node_ptrs[v].addr);
+ HDassert(internal->node_ptrs[u].addr > 0);
+ for(v = 0; v < u; v++)
+ HDassert(internal->node_ptrs[u].addr != internal->node_ptrs[v].addr);
+ for(v = 0; v < internal2->nrec + 1; v++)
+ HDassert(internal->node_ptrs[u].addr != internal2->node_ptrs[v].addr);
} /* end for */
/* Sanity check all_nrec total in parent */
- if(parent_all_nrec>0)
+ if(parent_all_nrec > 0)
HDassert(tot_all_nrec == parent_all_nrec);
return(0);
diff --git a/src/H5B2pkg.h b/src/H5B2pkg.h
index 43fab1f..c336227 100644
--- a/src/H5B2pkg.h
+++ b/src/H5B2pkg.h
@@ -34,32 +34,28 @@
/* Other private headers needed by this file */
#include "H5ACprivate.h" /* Metadata cache */
#include "H5FLprivate.h" /* Free Lists */
-#include "H5RCprivate.h" /* Reference counted object functions */
+
/**************************/
/* Package Private Macros */
/**************************/
-/* Size of signature information (on disk) */
-#define H5B2_SIZEOF_MAGIC 4
-
-/* B-tree signatures */
-#define H5B2_HDR_MAGIC "BTHD" /* Header */
-#define H5B2_INT_MAGIC "BTIN" /* Internal node */
-#define H5B2_LEAF_MAGIC "BTLF" /* Leaf node */
-
/* Size of storage for number of records per node (on disk) */
-#define H5B2_SIZEOF_RECORDS_PER_NODE 2
+#define H5B2_SIZEOF_RECORDS_PER_NODE (unsigned)2
/* Size of a "tree pointer" (on disk) */
/* (essentially, the largest internal pointer allowed) */
-#define H5B2_TREE_POINTER_SIZE(f) (H5F_SIZEOF_ADDR(f)+H5B2_SIZEOF_RECORDS_PER_NODE+H5F_SIZEOF_SIZE(f))
+#define H5B2_TREE_POINTER_SIZE(h) ( \
+ (h)->sizeof_addr + \
+ H5B2_SIZEOF_RECORDS_PER_NODE + \
+ (h)->sizeof_size \
+ )
/* Size of a internal node pointer (on disk) */
-#define H5B2_INT_POINTER_SIZE(f, s, d) ( \
- H5F_SIZEOF_ADDR(f) /* Address of child node */ \
- + (s)->max_nrec_size /* # of records in child node */ \
- + (s)->node_info[(d) - 1].cum_max_nrec_size /* Total # of records in child & below */ \
+#define H5B2_INT_POINTER_SIZE(h, d) ( \
+ (h)->sizeof_addr /* Address of child node */ \
+ + (h)->max_nrec_size /* # of records in child node */ \
+ + (h)->node_info[(d) - 1].cum_max_nrec_size /* Total # of records in child & below */ \
)
/* Size of checksum information (on disk) */
@@ -67,24 +63,24 @@
/* Format overhead for all v2 B-tree metadata in the file */
#define H5B2_METADATA_PREFIX_SIZE ( \
- H5B2_SIZEOF_MAGIC /* Signature */ \
- + 1 /* Version */ \
- + 1 /* Tree type */ \
- + H5B2_SIZEOF_CHKSUM /* Metadata checksum */ \
+ (unsigned)H5_SIZEOF_MAGIC /* Signature */ \
+ + (unsigned)1 /* Version */ \
+ + (unsigned)1 /* Tree type */ \
+ + (unsigned)H5B2_SIZEOF_CHKSUM /* Metadata checksum */ \
)
/* Size of the v2 B-tree header on disk */
-#define H5B2_HEADER_SIZE(f) ( \
+#define H5B2_HEADER_SIZE(h) ( \
/* General metadata fields */ \
H5B2_METADATA_PREFIX_SIZE \
\
/* Header specific fields */ \
- + 4 /* Node size, in bytes */ \
- + 2 /* Record size, in bytes */ \
- + 2 /* Depth of tree */ \
- + 1 /* Split % of full (as integer, ie. "98" means 98%) */ \
- + 1 /* Merge % of full (as integer, ie. "98" means 98%) */ \
- + H5B2_TREE_POINTER_SIZE(f) /* Node pointer to root node in tree */ \
+ + (unsigned)4 /* Node size, in bytes */ \
+ + (unsigned)2 /* Record size, in bytes */ \
+ + (unsigned)2 /* Depth of tree */ \
+ + (unsigned)1 /* Split % of full (as integer, ie. "98" means 98%) */ \
+ + (unsigned)1 /* Merge % of full (as integer, ie. "98" means 98%) */ \
+ + H5B2_TREE_POINTER_SIZE(h) /* Node pointer to root node in tree */ \
)
/* Size of the v2 B-tree internal node prefix */
@@ -106,13 +102,18 @@
)
/* Macro to retrieve pointer to i'th native record for native record buffer */
-#define H5B2_NAT_NREC(b, shared, idx) ((b) + (shared)->nat_off[(idx)])
+#define H5B2_NAT_NREC(b, hdr, idx) ((b) + (hdr)->nat_off[(idx)])
/* Macro to retrieve pointer to i'th native record for internal node */
-#define H5B2_INT_NREC(i, shared, idx) H5B2_NAT_NREC((i)->int_native, (shared), (idx))
+#define H5B2_INT_NREC(i, hdr, idx) H5B2_NAT_NREC((i)->int_native, (hdr), (idx))
/* Macro to retrieve pointer to i'th native record for leaf node */
-#define H5B2_LEAF_NREC(l, shared, idx) H5B2_NAT_NREC((l)->leaf_native, (shared), (idx))
+#define H5B2_LEAF_NREC(l, hdr, idx) H5B2_NAT_NREC((l)->leaf_native, (hdr), (idx))
+
+/* Number of records that fit into internal node */
+/* (accounts for extra node pointer by counting it in with the prefix bytes) */
+#define H5B2_NUM_INT_REC(h, d) \
+ (((h)->node_size - (H5B2_INT_PREFIX_SIZE + H5B2_INT_POINTER_SIZE(h, d))) / ((h)->rrec_size + H5B2_INT_POINTER_SIZE(h, d)))
/****************************/
@@ -122,7 +123,7 @@
/* A "node pointer" to another B-tree node */
typedef struct {
haddr_t addr; /* Address of other node */
- unsigned node_nrec; /* Number of records used in node pointed to */
+ uint16_t node_nrec; /* Number of records used in node pointed to */
hsize_t all_nrec; /* Number of records in node pointed to and all it's children */
} H5B2_node_ptr_t;
@@ -132,43 +133,49 @@ typedef struct {
unsigned split_nrec; /* Number of records to split node at */
unsigned merge_nrec; /* Number of records to merge node at */
hsize_t cum_max_nrec; /* Cumulative max. # of records below this node's depth */
- unsigned char cum_max_nrec_size; /* Size to store cumulative max. # of records for this node (in bytes) */
+ uint8_t cum_max_nrec_size; /* Size to store cumulative max. # of records for this node (in bytes) */
H5FL_fac_head_t *nat_rec_fac; /* Factory for native record blocks */
H5FL_fac_head_t *node_ptr_fac; /* Factory for node pointer blocks */
} H5B2_node_info_t;
-/* Each B-tree has certain information that can be shared across all
- * the instances of nodes in that B-tree.
- */
-typedef struct H5B2_shared_t {
- /* Shared internal data structures */
- const H5B2_class_t *type; /* Type of tree */
- uint8_t *page; /* Common disk page for I/O */
- size_t *nat_off; /* Array of offsets of native records */
- H5B2_node_info_t *node_info; /* Table of node info structs for current depth of B-tree */
-
- /* Information set by user (stored) */
- unsigned split_percent; /* Percent full at which to split the node, when inserting */
- unsigned merge_percent; /* Percent full at which to merge the node, when deleting */
- size_t node_size; /* Size of B-tree nodes, in bytes */
- size_t rrec_size; /* Size of "raw" (on disk) record, in bytes */
-
- /* Dynamic information (stored) */
- unsigned depth; /* B-tree's overall depth */
-
- /* Derived information from user's information */
- unsigned char max_nrec_size; /* Size to store max. # of records in any node (in bytes) */
-} H5B2_shared_t;
-
-/* The B-tree information */
-typedef struct H5B2_t {
+/* The B-tree header information */
+typedef struct H5B2_hdr_t {
/* Information for H5AC cache functions, _must_ be first field in structure */
H5AC_info_t cache_info;
- /* Internal B-tree information */
+ /* Internal B-tree information (stored) */
H5B2_node_ptr_t root; /* Node pointer to root node in B-tree */
- H5RC_t *shared; /* Ref-counted shared info */
-} H5B2_t;
+
+ /* Information set by user (stored) */
+ uint8_t split_percent; /* Percent full at which to split the node, when inserting */
+ uint8_t merge_percent; /* Percent full at which to merge the node, when deleting */
+ uint32_t node_size; /* Size of B-tree nodes, in bytes */
+ uint32_t rrec_size; /* Size of "raw" (on disk) record, in bytes */
+
+ /* Dynamic information (stored) */
+ uint16_t depth; /* B-tree's overall depth */
+
+ /* Derived information from user's information (not stored) */
+ uint8_t max_nrec_size; /* Size to store max. # of records in any node (in bytes) */
+
+ /* Shared internal data structures (not stored) */
+ H5F_t *f; /* Pointer to the file that the B-tree is in */
+ haddr_t addr; /* Address of B-tree header in the file */
+ size_t rc; /* Reference count of nodes using this header */
+ size_t file_rc; /* Reference count of files using this header */
+ hbool_t pending_delete; /* B-tree is pending deletion */
+ uint8_t sizeof_size; /* Size of file sizes */
+ uint8_t sizeof_addr; /* Size of file addresses */
+ H5B2_remove_t remove_op; /* Callback operator for deleting B-tree */
+ void *remove_op_data;/* B-tree deletion callback's context */
+ uint8_t *page; /* Common disk page for I/O */
+ size_t *nat_off; /* Array of offsets of native records */
+ H5B2_node_info_t *node_info; /* Table of node info structs for current depth of B-tree */
+
+ /* Client information (not stored) */
+ const H5B2_class_t *cls; /* Class of B-tree client */
+ void *cb_ctx; /* Client callback context */
+} H5B2_hdr_t;
/* B-tree leaf node information */
typedef struct H5B2_leaf_t {
@@ -176,9 +183,9 @@ typedef struct H5B2_leaf_t {
H5AC_info_t cache_info;
/* Internal B-tree information */
- H5RC_t *shared; /* Ref-counted shared info */
+ H5B2_hdr_t *hdr; /* Pointer to the [pinned] v2 B-tree header */
uint8_t *leaf_native; /* Pointer to native records */
- unsigned nrec; /* Number of records in node */
+ uint16_t nrec; /* Number of records in node */
} H5B2_leaf_t;
/* B-tree internal node information */
@@ -187,18 +194,24 @@ typedef struct H5B2_internal_t {
H5AC_info_t cache_info;
/* Internal B-tree information */
- H5RC_t *shared; /* Ref-counted shared info */
+ H5B2_hdr_t *hdr; /* Pointer to the [pinned] v2 B-tree header */
uint8_t *int_native; /* Pointer to native records */
H5B2_node_ptr_t *node_ptrs; /* Pointer to node pointers */
- unsigned nrec; /* Number of records in node */
- unsigned depth; /* Depth of this node in the B-tree */
+ uint16_t nrec; /* Number of records in node */
+ uint16_t depth; /* Depth of this node in the B-tree */
} H5B2_internal_t;
+/* v2 B-tree */
+struct H5B2_t {
+ H5B2_hdr_t *hdr; /* Pointer to internal v2 B-tree header info */
+ H5F_t *f; /* Pointer to file for v2 B-tree */
+};
+
/* User data for metadata cache 'load' callback */
typedef struct {
- H5RC_t *bt2_shared; /* Ref counter for shared B-tree info */
- unsigned nrec; /* Number of records in node to load */
- unsigned depth; /* Depth of node to load */
+ H5B2_hdr_t *hdr; /* Pointer to the [pinned] v2 B-tree header */
+ uint16_t nrec; /* Number of records in node to load */
+ uint16_t depth; /* Depth of node to load */
} H5B2_int_load_ud1_t;
#ifdef H5B2_TESTING
@@ -223,9 +236,6 @@ H5_DLLVAR const H5AC_class_t H5AC_BT2_INT[1];
/* H5B2 leaf node inherits cache-like properties from H5AC */
H5_DLLVAR const H5AC_class_t H5AC_BT2_LEAF[1];
-/* Declare a free list to manage the H5B2_t struct */
-H5FL_EXTERN(H5B2_t);
-
/* Declare a free list to manage the H5B2_internal_t struct */
H5FL_EXTERN(H5B2_internal_t);
@@ -237,74 +247,82 @@ H5FL_EXTERN(H5B2_leaf_t);
H5_DLLVAR const H5B2_class_t H5B2_TEST[1];
#endif /* H5B2_TESTING */
+/* Array of v2 B-tree client ID -> client class mappings */
+extern const H5B2_class_t *const H5B2_client_class_g[];
+
/******************************/
/* Package Private Prototypes */
/******************************/
-/* Routines for managing shared B-tree info */
-H5_DLL herr_t H5B2_shared_init(H5F_t *f, H5B2_t *bt2, const H5B2_class_t *type,
- unsigned depth, size_t node_size, size_t rrec_size,
- unsigned split_percent, unsigned merge_percent);
+/* Routines for managing B-tree header info */
+H5_DLL H5B2_hdr_t *H5B2_hdr_alloc(H5F_t *f);
+H5_DLL haddr_t H5B2_hdr_create(H5F_t *f, hid_t dxpl_id,
+ const H5B2_create_t *cparam, void *ctx_udata);
+H5_DLL herr_t H5B2_hdr_init(H5F_t *f, H5B2_hdr_t *hdr,
+ const H5B2_create_t *cparam, void *ctx_udata, uint16_t depth);
+H5_DLL herr_t H5B2_hdr_incr(H5B2_hdr_t *hdr);
+H5_DLL herr_t H5B2_hdr_decr(H5B2_hdr_t *hdr);
+H5_DLL herr_t H5B2_hdr_fuse_incr(H5B2_hdr_t *hdr);
+H5_DLL size_t H5B2_hdr_fuse_decr(H5B2_hdr_t *hdr);
+H5_DLL herr_t H5B2_hdr_dirty(H5B2_hdr_t *hdr);
+H5_DLL herr_t H5B2_hdr_free(H5B2_hdr_t *hdr);
+H5_DLL herr_t H5B2_hdr_delete(H5B2_hdr_t *hdr, hid_t dxpl_id);
/* Routines for operating on internal nodes */
-H5_DLL H5B2_internal_t *H5B2_protect_internal(H5F_t *f, hid_t dxpl_id,
- H5RC_t *bt2_shared, haddr_t addr, unsigned nrec, unsigned depth,
- H5AC_protect_t rw);
+H5_DLL H5B2_internal_t *H5B2_protect_internal(H5B2_hdr_t *hdr, hid_t dxpl_id,
+ haddr_t addr, unsigned nrec, unsigned depth, H5AC_protect_t rw);
/* Routines for allocating nodes */
-H5_DLL herr_t H5B2_split_root(H5F_t *f, hid_t dxpl_id, H5B2_t *bt2,
- unsigned *bt2_flags_ptr);
-H5_DLL herr_t H5B2_create_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
+H5_DLL herr_t H5B2_split_root(H5B2_hdr_t *hdr, hid_t dxpl_id);
+H5_DLL herr_t H5B2_create_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id,
H5B2_node_ptr_t *node_ptr);
/* Routines for inserting records */
-H5_DLL herr_t H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
+H5_DLL herr_t H5B2_insert_internal(H5B2_hdr_t *hdr, hid_t dxpl_id,
unsigned depth, unsigned *parent_cache_info_flags_ptr,
H5B2_node_ptr_t *curr_node_ptr, void *udata);
-H5_DLL herr_t H5B2_insert_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
+H5_DLL herr_t H5B2_insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id,
H5B2_node_ptr_t *curr_node_ptr, void *udata);
/* Routines for iterating over nodes/records */
-H5_DLL herr_t H5B2_iterate_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
- unsigned depth, const H5B2_node_ptr_t *curr_node, H5B2_operator_t op,
- void *op_data);
-H5_DLL herr_t H5B2_iterate_size_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
+H5_DLL herr_t H5B2_iterate_node(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
+ const H5B2_node_ptr_t *curr_node, H5B2_operator_t op, void *op_data);
+H5_DLL herr_t H5B2_node_size(H5B2_hdr_t *hdr, hid_t dxpl_id,
unsigned depth, const H5B2_node_ptr_t *curr_node, hsize_t *op_data);
/* Routines for locating records */
H5_DLL int H5B2_locate_record(const H5B2_class_t *type, unsigned nrec,
size_t *rec_off, const uint8_t *native, const void *udata, unsigned *idx);
-H5_DLL herr_t H5B2_neighbor_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
+H5_DLL herr_t H5B2_neighbor_internal(H5B2_hdr_t *hdr, hid_t dxpl_id,
unsigned depth, H5B2_node_ptr_t *curr_node_ptr, void *neighbor_loc,
H5B2_compare_t comp, void *udata, H5B2_found_t op, void *op_data);
-H5_DLL herr_t H5B2_neighbor_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
+H5_DLL herr_t H5B2_neighbor_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id,
H5B2_node_ptr_t *curr_node_ptr, void *neighbor_loc,
H5B2_compare_t comp, void *udata, H5B2_found_t op, void *op_data);
/* Routines for removing records */
-H5_DLL herr_t H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
+H5_DLL herr_t H5B2_remove_internal(H5B2_hdr_t *hdr, hid_t dxpl_id,
hbool_t *depth_decreased, void *swap_loc, unsigned depth, H5AC_info_t *parent_cache_info,
hbool_t * parent_cache_info_dirtied_ptr, H5B2_node_ptr_t *curr_node_ptr, void *udata,
H5B2_remove_t op, void *op_data);
-H5_DLL herr_t H5B2_remove_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
+H5_DLL herr_t H5B2_remove_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id,
H5B2_node_ptr_t *curr_node_ptr, void *udata, H5B2_remove_t op,
void *op_data);
-H5_DLL herr_t H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
+H5_DLL herr_t H5B2_remove_internal_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id,
hbool_t *depth_decreased, void *swap_loc, unsigned depth, H5AC_info_t *parent_cache_info,
hbool_t * parent_cache_info_dirtied_ptr, H5B2_node_ptr_t *curr_node_ptr, hsize_t idx,
H5B2_remove_t op, void *op_data);
-H5_DLL herr_t H5B2_remove_leaf_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
+H5_DLL herr_t H5B2_remove_leaf_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id,
H5B2_node_ptr_t *curr_node_ptr, unsigned idx, H5B2_remove_t op,
void *op_data);
/* Routines for deleting nodes */
-H5_DLL herr_t H5B2_delete_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
- unsigned depth, const H5B2_node_ptr_t *curr_node, H5B2_remove_t op,
- void *op_data);
+H5_DLL herr_t H5B2_delete_node(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
+ const H5B2_node_ptr_t *curr_node, H5B2_remove_t op, void *op_data);
/* Metadata cache callbacks */
-H5_DLL herr_t H5B2_cache_hdr_dest(H5F_t *f, H5B2_t *b);
+H5_DLL herr_t H5B2_cache_hdr_dest(H5F_t *f, H5B2_hdr_t *b);
H5_DLL herr_t H5B2_cache_leaf_dest(H5F_t *f, H5B2_leaf_t *l);
H5_DLL herr_t H5B2_cache_internal_dest(H5F_t *f, H5B2_internal_t *i);
@@ -320,13 +338,10 @@ H5_DLL herr_t H5B2_leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
/* Testing routines */
#ifdef H5B2_TESTING
-H5_DLL herr_t H5B2_get_root_addr_test(H5F_t *f, hid_t dxpl_id,
- const H5B2_class_t *type, haddr_t addr, haddr_t *root_addr);
-H5_DLL int H5B2_get_node_depth_test(H5F_t *f, hid_t dxpl_id,
- const H5B2_class_t *type, haddr_t addr, void *udata);
-H5_DLL herr_t H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id,
- const H5B2_class_t *type, haddr_t addr, void *udata,
- H5B2_node_info_test_t *ninfo);
+H5_DLL herr_t H5B2_get_root_addr_test(H5B2_t *bt2, haddr_t *root_addr);
+H5_DLL int H5B2_get_node_depth_test(H5B2_t *bt2, hid_t dxpl_id, void *udata);
+H5_DLL herr_t H5B2_get_node_info_test(H5B2_t *bt2, hid_t dxpl_id,
+ void *udata, H5B2_node_info_test_t *ninfo);
#endif /* H5B2_TESTING */
#endif /* _H5B2pkg_H */
diff --git a/src/H5B2private.h b/src/H5B2private.h
index 6d8172c..4880ab2 100644
--- a/src/H5B2private.h
+++ b/src/H5B2private.h
@@ -82,71 +82,77 @@ typedef enum H5B2_compare_t {
typedef struct H5B2_class_t H5B2_class_t;
struct H5B2_class_t {
H5B2_subid_t id; /* ID of B-tree class, as found in file */
+ const char *name; /* Name of B-tree class, for debugging */
size_t nrec_size; /* Size of native (memory) record */
- /* Store & retrieve record from application to B-tree 'native' form */
- herr_t (*store)(void *nrecord, const void *udata); /* Store record in native record table */
- herr_t (*retrieve)(void *udata, const void *nrecord); /* Retrieve record in native record table */
-
- /* Compare records, according to a key */
- herr_t (*compare)(const void *rec1, const void *rec2); /* Compare two native records */
-
- /* Encode & decode record values */
- herr_t (*encode)(const H5F_t *f, uint8_t *raw, const void *record); /* Encode record from native form to disk storage form */
- herr_t (*decode)(const H5F_t *f, const uint8_t *raw, void *record); /* Decode record from disk storage form to native form */
-
- /* Debug record values */
- herr_t (*debug)(FILE *stream, const H5F_t *f, hid_t dxpl_id, /* Print a record for debugging */
- int indent, int fwidth, const void *record,
- const void *udata);
+ /* Extensible array client callback methods */
+ void *(*crt_context)(void *udata); /* Create context for other client callbacks */
+ herr_t (*dst_context)(void *ctx); /* Destroy client callback context */
+ herr_t (*store)(void *nrecord, const void *udata); /* Store application record in native record table */
+ herr_t (*compare)(const void *rec1, const void *rec2); /* Compare two native records */
+ herr_t (*encode)(uint8_t *raw, const void *record, void *ctx); /* Encode record from native form to disk storage form */
+ herr_t (*decode)(const uint8_t *raw, void *record, void *ctx); /* Decode record from disk storage form to native form */
+ herr_t (*debug)(FILE *stream, const H5F_t *f, hid_t dxpl_id, /* Print a record for debugging */
+ int indent, int fwidth, const void *record, const void *udata);
+ void *(*crt_dbg_ctx)(H5F_t *f, hid_t dxpl_id, haddr_t obj_addr); /* Create debugging context */
+ herr_t (*dst_dbg_ctx)(void *dbg_ctx); /* Destroy debugging context */
};
+/* v2 B-tree creation parameters */
+typedef struct H5B2_create_t {
+ const H5B2_class_t *cls; /* v2 B-tree client class */
+ uint32_t node_size; /* Size of each node (in bytes) */
+ uint32_t rrec_size; /* Size of raw record (in bytes) */
+ uint8_t split_percent; /* % full to split nodes */
+ uint8_t merge_percent; /* % full to merge nodes */
+} H5B2_create_t;
+
/* v2 B-tree metadata statistics info */
typedef struct H5B2_stat_t {
unsigned depth; /* Depth of B-tree */
hsize_t nrecords; /* Number of records */
} H5B2_stat_t;
+/* v2 B-tree info (forward decl - defined in H5B2pkg.h) */
+typedef struct H5B2_t H5B2_t;
+
+
/*****************************/
/* Library-private Variables */
/*****************************/
+
/***************************************/
/* Library-private Function Prototypes */
/***************************************/
-H5_DLL herr_t H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- size_t node_size, size_t rrec_size,
- unsigned split_percent, unsigned merge_percent,
- haddr_t *addr_p);
-H5_DLL herr_t H5B2_insert(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, void *udata);
-H5_DLL herr_t H5B2_iterate(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, H5B2_operator_t op, void *op_data);
-H5_DLL herr_t H5B2_iterate_size(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, hsize_t *op_data);
-H5_DLL herr_t H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, void *udata, H5B2_found_t op, void *op_data);
-H5_DLL herr_t H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, H5_iter_order_t order, hsize_t idx, H5B2_found_t op,
- void *op_data);
-H5_DLL herr_t H5B2_neighbor(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, H5B2_compare_t comp, void *udata, H5B2_found_t op,
- void *op_data);
-H5_DLL herr_t H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, void *udata, H5B2_modify_t op, void *op_data);
-H5_DLL herr_t H5B2_remove(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, void *udata, H5B2_remove_t op, void *op_data);
-H5_DLL herr_t H5B2_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, H5_iter_order_t order, hsize_t idx, H5B2_remove_t op,
+H5_DLL H5B2_t *H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam,
+ void *ctx_udata);
+H5_DLL H5B2_t *H5B2_open(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *ctx_udata);
+H5_DLL herr_t H5B2_get_addr(const H5B2_t *bt2, haddr_t *addr/*out*/);
+H5_DLL herr_t H5B2_insert(H5B2_t *bt2, hid_t dxpl_id, void *udata);
+H5_DLL herr_t H5B2_iterate(H5B2_t *bt2, hid_t dxpl_id, H5B2_operator_t op,
void *op_data);
-H5_DLL herr_t H5B2_get_nrec(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, hsize_t *nrec);
-H5_DLL herr_t H5B2_delete(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, H5B2_remove_t op, void *op_data);
+H5_DLL htri_t H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata,
+ H5B2_found_t op, void *op_data);
+H5_DLL herr_t H5B2_index(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order,
+ hsize_t idx, H5B2_found_t op, void *op_data);
+H5_DLL herr_t H5B2_neighbor(H5B2_t *bt2, hid_t dxpl_id, H5B2_compare_t range,
+ void *udata, H5B2_found_t op, void *op_data);
+H5_DLL herr_t H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata,
+ H5B2_modify_t op, void *op_data);
+H5_DLL herr_t H5B2_remove(H5B2_t *b2, hid_t dxpl_id, void *udata,
+ H5B2_remove_t op, void *op_data);
+H5_DLL herr_t H5B2_remove_by_idx(H5B2_t *bt2, hid_t dxpl_id,
+ H5_iter_order_t order, hsize_t idx, H5B2_remove_t op, void *op_data);
+H5_DLL herr_t H5B2_get_nrec(const H5B2_t *bt2, hsize_t *nrec);
+H5_DLL herr_t H5B2_size(H5B2_t *bt2, hid_t dxpl_id,
+ hsize_t *btree_size);
+H5_DLL herr_t H5B2_close(H5B2_t *bt2, hid_t dxpl_id);
+H5_DLL herr_t H5B2_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ void *ctx_udata, H5B2_remove_t op, void *op_data);
/* Statistics routines */
-H5_DLL herr_t H5B2_stat_info(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, H5B2_stat_t *info);
+H5_DLL herr_t H5B2_stat_info(H5B2_t *bt2, H5B2_stat_t *info);
#endif /* _H5B2private_H */
diff --git a/src/H5B2stat.c b/src/H5B2stat.c
index 899bb8a..0ee404e 100644
--- a/src/H5B2stat.c
+++ b/src/H5B2stat.c
@@ -26,6 +26,7 @@
#define H5B2_PACKAGE /*suppress error about including H5B2pkg */
+
/***********/
/* Headers */
/***********/
@@ -33,6 +34,7 @@
#include "H5B2pkg.h" /* v2 B-trees */
#include "H5Eprivate.h" /* Error handling */
+
/****************/
/* Local Macros */
/****************/
@@ -74,7 +76,6 @@
* Purpose: Retrieve metadata statistics for a v2 B-tree
*
* Return: Success: non-negative
- *
* Failure: negative
*
* Programmer: Quincey Koziol
@@ -83,37 +84,75 @@
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_stat_info(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, H5B2_stat_t *info)
+H5B2_stat_info(H5B2_t *bt2, H5B2_stat_t *info)
{
- H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
- FUNC_ENTER_NOAPI_NOINIT(H5B2_stat_info)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_stat_info)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
HDassert(info);
- /* Look up the B-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Get pointer to reference counted shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Get information about the B-tree */
- info->depth = shared->depth;
- info->nrecords = bt2->root.all_nrec;
+ info->depth = hdr->depth;
+ info->nrecords = hdr->root.all_nrec;
-done:
- /* Release B-tree header node */
- if(bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5B2_stat_info() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_size
+ *
+ * Purpose: Iterate over all the records in the B-tree, collecting
+ * storage info.
+ *
+ * Return: non-negative on success, negative on error
+ *
+ * Programmer: Vailin Choi
+ * June 19 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_size(H5B2_t *bt2, hid_t dxpl_id, hsize_t *btree_size)
+{
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5B2_size, FAIL)
+
+ /* Check arguments. */
+ HDassert(bt2);
+ HDassert(btree_size);
+
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
+
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
+
+ /* Add size of header to B-tree metadata total */
+ *btree_size += H5B2_HEADER_SIZE(hdr);
+
+ /* Iterate through records */
+ if(hdr->root.node_nrec > 0) {
+ /* Check for root node being a leaf */
+ if(hdr->depth == 0)
+ *btree_size += hdr->node_size;
+ else
+ /* Iterate through nodes */
+ if(H5B2_node_size(hdr, dxpl_id, hdr->depth, &hdr->root, btree_size) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "node iteration failed")
+ } /* end if */
+
+done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5B2_stat_info() */
+} /* H5B2_size() */
diff --git a/src/H5B2test.c b/src/H5B2test.c
index f2cf79d..72eb793 100644
--- a/src/H5B2test.c
+++ b/src/H5B2test.c
@@ -20,6 +20,7 @@
*
*/
+
/****************/
/* Module Setup */
/****************/
@@ -27,6 +28,7 @@
#define H5B2_PACKAGE /*suppress error about including H5B2pkg */
#define H5B2_TESTING /*suppress warning about H5B2 testing funcs*/
+
/***********/
/* Headers */
/***********/
@@ -34,6 +36,7 @@
#include "H5B2pkg.h" /* v2 B-trees */
#include "H5Eprivate.h" /* Error handling */
+
/****************/
/* Local Macros */
/****************/
@@ -43,6 +46,11 @@
/* Local Typedefs */
/******************/
+/* v2 B-tree client callback context */
+typedef struct H5B2_test_ctx_t {
+ uint8_t sizeof_size; /* Size of file sizes */
+} H5B2_test_ctx_t;
+
/********************/
/* Package Typedefs */
@@ -52,30 +60,38 @@
/********************/
/* Local Prototypes */
/********************/
+
+static void *H5B2_test_crt_context(void *udata);
+static herr_t H5B2_test_dst_context(void *ctx);
static herr_t H5B2_test_store(void *nrecord, const void *udata);
-static herr_t H5B2_test_retrieve(void *udata, const void *nrecord);
static herr_t H5B2_test_compare(const void *rec1, const void *rec2);
-static herr_t H5B2_test_encode(const H5F_t *f, uint8_t *raw,
- const void *nrecord);
-static herr_t H5B2_test_decode(const H5F_t *f, const uint8_t *raw,
- void *nrecord);
+static herr_t H5B2_test_encode(uint8_t *raw, const void *nrecord, void *ctx);
+static herr_t H5B2_test_decode(const uint8_t *raw, void *nrecord, void *ctx);
static herr_t H5B2_test_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
int indent, int fwidth, const void *record, const void *_udata);
+static void *H5B2_test_crt_dbg_context(H5F_t *f, hid_t dxpl_id, haddr_t addr);
+
/*********************/
/* Package Variables */
/*********************/
+
const H5B2_class_t H5B2_TEST[1]={{ /* B-tree class information */
H5B2_TEST_ID, /* Type of B-tree */
+ "H5B2_TEST_ID", /* Name of B-tree class */
sizeof(hsize_t), /* Size of native record */
+ H5B2_test_crt_context, /* Create client callback context */
+ H5B2_test_dst_context, /* Destroy client callback context */
H5B2_test_store, /* Record storage callback */
- H5B2_test_retrieve, /* Record retrieval callback */
H5B2_test_compare, /* Record comparison callback */
H5B2_test_encode, /* Record encoding callback */
H5B2_test_decode, /* Record decoding callback */
- H5B2_test_debug /* Record debugging callback */
+ H5B2_test_debug, /* Record debugging callback */
+ H5B2_test_crt_dbg_context, /* Create debugging context */
+ H5B2_test_dst_context /* Destroy debugging context */
}};
+
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -85,55 +101,103 @@ const H5B2_class_t H5B2_TEST[1]={{ /* B-tree class information */
/* Local Variables */
/*******************/
+
+/* Declare a free list to manage the H5B2_test_ctx_t struct */
+H5FL_DEFINE_STATIC(H5B2_test_ctx_t);
+
/*-------------------------------------------------------------------------
- * Function: H5B2_test_store
+ * Function: H5B2_test_crt_context
*
- * Purpose: Store native information into record for B-tree
+ * Purpose: Create client callback context
*
- * Return: Success: non-negative
+ * Return: Success: non-NULL
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, November 26, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5B2_test_crt_context(void *_f)
+{
+ H5F_t *f = (H5F_t *)_f; /* User data for building callback context */
+ H5B2_test_ctx_t *ctx; /* Callback context structure */
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_test_crt_context)
+
+ /* Sanity check */
+ HDassert(f);
+
+ /* Allocate callback context */
+ if(NULL == (ctx = H5FL_MALLOC(H5B2_test_ctx_t)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "can't allocate callback context")
+
+ /* Determine the size of lengths in the file */
+ ctx->sizeof_size = H5F_SIZEOF_SIZE(f);
+
+ /* Set return value */
+ ret_value = ctx;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5B2_test_crt_context() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_test_dst_context
+ *
+ * Purpose: Destroy client callback context
*
+ * Return: Success: non-negative
* Failure: negative
*
* Programmer: Quincey Koziol
- * Thursday, February 3, 2005
+ * Thursday, November 26, 2009
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_test_store(void *nrecord, const void *udata)
+H5B2_test_dst_context(void *_ctx)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_test_store)
+ H5B2_test_ctx_t *ctx = (H5B2_test_ctx_t *)_ctx; /* Callback context structure */
- *(hsize_t *)nrecord = *(const hsize_t *)udata;
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_test_dst_context)
+
+ /* Sanity check */
+ HDassert(ctx);
+
+ /* Release callback context */
+ ctx = H5FL_FREE(H5B2_test_ctx_t, ctx);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5B2_test_store() */
+} /* H5B2_test_dst_context() */
/*-------------------------------------------------------------------------
- * Function: H5B2_test_retrieve
+ * Function: H5B2_test_store
*
- * Purpose: Retrieve native information from record for B-tree
+ * Purpose: Store native information into record for B-tree
*
* Return: Success: non-negative
- *
* Failure: negative
*
* Programmer: Quincey Koziol
- * Friday, February 25, 2005
+ * Thursday, February 3, 2005
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_test_retrieve(void *udata, const void *nrecord)
+H5B2_test_store(void *nrecord, const void *udata)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_test_retrieve)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_test_store)
- *(hsize_t *)udata = *(const hsize_t *)nrecord;
+ *(hsize_t *)nrecord = *(const hsize_t *)udata;
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5B2_test_retrieve() */
+} /* H5B2_test_store() */
/*-------------------------------------------------------------------------
@@ -155,7 +219,7 @@ H5B2_test_compare(const void *rec1, const void *rec2)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_test_compare)
- FUNC_LEAVE_NOAPI((herr_t)(*(const hssize_t *)rec1-*(const hssize_t *)rec2))
+ FUNC_LEAVE_NOAPI((herr_t)(*(const hssize_t *)rec1 - *(const hssize_t *)rec2))
} /* H5B2_test_compare() */
@@ -165,7 +229,6 @@ H5B2_test_compare(const void *rec1, const void *rec2)
* Purpose: Encode native information into raw form for storing on disk
*
* Return: Success: non-negative
- *
* Failure: negative
*
* Programmer: Quincey Koziol
@@ -174,11 +237,16 @@ H5B2_test_compare(const void *rec1, const void *rec2)
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_test_encode(const H5F_t *f, uint8_t *raw, const void *nrecord)
+H5B2_test_encode(uint8_t *raw, const void *nrecord, void *_ctx)
{
+ H5B2_test_ctx_t *ctx = (H5B2_test_ctx_t *)_ctx; /* Callback context structure */
+
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_test_encode)
- H5F_ENCODE_LENGTH(f, raw, *(const hsize_t *)nrecord);
+ /* Sanity check */
+ HDassert(ctx);
+
+ H5F_ENCODE_LENGTH_LEN(raw, *(const hsize_t *)nrecord, ctx->sizeof_size);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5B2_test_encode() */
@@ -190,7 +258,6 @@ H5B2_test_encode(const H5F_t *f, uint8_t *raw, const void *nrecord)
* Purpose: Decode raw disk form of record into native form
*
* Return: Success: non-negative
- *
* Failure: negative
*
* Programmer: Quincey Koziol
@@ -199,11 +266,16 @@ H5B2_test_encode(const H5F_t *f, uint8_t *raw, const void *nrecord)
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_test_decode(const H5F_t *f, const uint8_t *raw, void *nrecord)
+H5B2_test_decode(const uint8_t *raw, void *nrecord, void *_ctx)
{
+ H5B2_test_ctx_t *ctx = (H5B2_test_ctx_t *)_ctx; /* Callback context structure */
+
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_test_decode)
- H5F_DECODE_LENGTH(f, raw, *(hsize_t *)nrecord);
+ /* Sanity check */
+ HDassert(ctx);
+
+ H5F_DECODE_LENGTH_LEN(raw, *(hsize_t *)nrecord, ctx->sizeof_size);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5B2_test_decode() */
@@ -215,7 +287,6 @@ H5B2_test_decode(const H5F_t *f, const uint8_t *raw, void *nrecord)
* Purpose: Debug native form of record
*
* Return: Success: non-negative
- *
* Failure: negative
*
* Programmer: Quincey Koziol
@@ -240,12 +311,51 @@ H5B2_test_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
/*-------------------------------------------------------------------------
+ * Function: H5B2_test_crt_dbg_context
+ *
+ * Purpose: Create context for debugging callback
+ *
+ * Return: Success: non-NULL
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, December 1, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5B2_test_crt_dbg_context(H5F_t *f, hid_t UNUSED dxpl_id, haddr_t UNUSED addr)
+{
+ H5B2_test_ctx_t *ctx; /* Callback context structure */
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_test_crt_dbg_context)
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+
+ /* Allocate callback context */
+ if(NULL == (ctx = H5FL_MALLOC(H5B2_test_ctx_t)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "can't allocate callback context")
+
+ /* Determine the size of addresses & lengths in the file */
+ ctx->sizeof_size = H5F_SIZEOF_SIZE(f);
+
+ /* Set return value */
+ ret_value = ctx;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5B2_test_crt_dbg_context() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5B2_get_root_addr_test
*
* Purpose: Retrieve the root node's address
*
* Return: Success: non-negative
- *
* Failure: negative
*
* Programmer: Quincey Koziol
@@ -254,33 +364,18 @@ H5B2_test_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_get_root_addr_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, haddr_t *root_addr)
+H5B2_get_root_addr_test(H5B2_t *bt2, haddr_t *root_addr)
{
- H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5B2_get_root_addr_test)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_get_root_addr_test)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
+ HDassert(bt2);
HDassert(root_addr);
- /* Look up the B-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
-
/* Get B-tree root addr */
- *root_addr = bt2->root.addr;
+ *root_addr = bt2->hdr->root.addr;
-done:
- /* Release B-tree header node */
- if(bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
-
- FUNC_LEAVE_NOAPI(ret_value)
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5B2_get_root_addr_test() */
@@ -298,13 +393,10 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- void *udata, H5B2_node_info_test_t *ninfo)
+H5B2_get_node_info_test(H5B2_t *bt2, hid_t dxpl_id, void *udata,
+ H5B2_node_info_test_t *ninfo)
{
- H5B2_t *bt2=NULL; /* Pointer to the B-tree header */
- H5RC_t *bt2_shared=NULL; /* Pointer to ref-counter for shared B-tree info */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- hbool_t incr_rc=FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */
unsigned depth; /* Current depth of the tree */
int cmp; /* Comparison value of records */
@@ -314,36 +406,22 @@ H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr
FUNC_ENTER_NOAPI(H5B2_get_node_info_test, FAIL)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
+ HDassert(bt2);
- /* Look up the B-tree header */
- if (NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */
- bt2_shared=bt2->shared;
- H5RC_INC(bt2_shared);
- incr_rc=TRUE;
-
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Make copy of the root node pointer to start search with */
- curr_node_ptr = bt2->root;
+ curr_node_ptr = hdr->root;
/* Current depth of the tree */
- depth = shared->depth;
-
- /* Release header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
- bt2 = NULL;
+ depth = hdr->depth;
/* Check for empty tree */
- if(curr_node_ptr.node_nrec==0)
+ if(0 == curr_node_ptr.node_nrec)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "B-tree has no records")
/* Walk down B-tree to find record or leaf node where record is located */
@@ -353,11 +431,11 @@ H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr
H5B2_node_ptr_t next_node_ptr; /* Node pointer info for next node */
/* Lock B-tree current node */
- if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_READ)))
+ if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Locate node pointer for child */
- cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx);
+ cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx);
if(cmp > 0)
idx++;
@@ -366,7 +444,7 @@ H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr
next_node_ptr = internal->node_ptrs[idx];
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
/* Set pointer to next node to load */
@@ -374,7 +452,7 @@ H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr
} /* end if */
else {
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
/* Fill in information about the node */
@@ -393,14 +471,14 @@ H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr
H5B2_leaf_t *leaf; /* Pointer to leaf node in B-tree */
/* Lock B-tree leaf node */
- if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), bt2_shared, H5AC_READ)))
+ if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), hdr, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Locate record */
- cmp = H5B2_locate_record(shared->type, leaf->nrec, shared->nat_off, leaf->leaf_native, udata, &idx);
+ cmp = H5B2_locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx);
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
/* Indicate the depth that the record was found */
@@ -413,10 +491,6 @@ H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr
ninfo->nrec = curr_node_ptr.node_nrec;
done:
- /* Check if we need to decrement the reference count for the B-tree's shared info */
- if(incr_rc)
- H5RC_DEC(bt2_shared);
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_get_node_info_test() */
@@ -438,8 +512,7 @@ done:
*-------------------------------------------------------------------------
*/
int
-H5B2_get_node_depth_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- void *udata)
+H5B2_get_node_depth_test(H5B2_t *bt2, hid_t dxpl_id, void *udata)
{
H5B2_node_info_test_t ninfo; /* Node information */
int ret_value; /* Return information */
@@ -447,16 +520,14 @@ H5B2_get_node_depth_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, hadd
FUNC_ENTER_NOAPI(H5B2_get_node_depth_test, FAIL)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
+ HDassert(bt2);
/* Get information abou the node */
- if(H5B2_get_node_info_test(f, dxpl_id, type, addr, udata, &ninfo) < 0)
+ if(H5B2_get_node_info_test(bt2, dxpl_id, udata, &ninfo) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "error looking up node info")
/* Set return value */
- ret_value = ninfo.depth;
+ ret_value = (int)ninfo.depth;
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Bcache.c b/src/H5Bcache.c
index 9f7444b..dc60f9d 100644
--- a/src/H5Bcache.c
+++ b/src/H5Bcache.c
@@ -37,6 +37,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5Bpkg.h" /* B-link trees */
#include "H5Eprivate.h" /* Error handling */
+#include "H5MFprivate.h" /* File memory management */
/****************/
@@ -74,6 +75,7 @@ const H5AC_class_t H5AC_BT[1] = {{
(H5AC_flush_func_t)H5B_flush,
(H5AC_dest_func_t)H5B_dest,
(H5AC_clear_func_t)H5B_clear,
+ (H5AC_notify_func_t)NULL,
(H5AC_size_func_t)H5B_compute_size,
}};
@@ -111,13 +113,13 @@ H5B_serialize(const H5F_t *f, const H5B_t *bt)
HDassert(f);
HDassert(bt);
HDassert(bt->rc_shared);
- shared=(H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
+ shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
HDassert(shared);
p = shared->page;
/* magic number */
- HDmemcpy(p, H5B_MAGIC, (size_t)H5B_SIZEOF_MAGIC);
+ HDmemcpy(p, H5B_MAGIC, (size_t)H5_SIZEOF_MAGIC);
p += 4;
/* node type and level */
@@ -133,10 +135,10 @@ H5B_serialize(const H5F_t *f, const H5B_t *bt)
H5F_addr_encode(f, &p, bt->right);
/* child keys and pointers */
- native=bt->native;
- for (u = 0; u < bt->nchildren; ++u) {
+ native = bt->native;
+ for(u = 0; u < bt->nchildren; ++u) {
/* encode the key */
- if (shared->type->encode(f, bt, p, native) < 0)
+ if(shared->type->encode(f, bt, p, native) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree key")
p += shared->sizeof_rkey;
native += shared->type->sizeof_nkey;
@@ -144,9 +146,9 @@ H5B_serialize(const H5F_t *f, const H5B_t *bt)
/* encode the child address */
H5F_addr_encode(f, &p, bt->child[u]);
} /* end for */
- if(bt->nchildren>0) {
+ if(bt->nchildren > 0) {
/* Encode the final key */
- if (shared->type->encode(f, bt, p, native) < 0)
+ if(shared->type->encode(f, bt, p, native) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree key")
} /* end if */
@@ -188,21 +190,20 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata)
HDassert(type);
HDassert(type->get_shared);
- /* Allocate the B-tree node in memory */
if(NULL == (bt = H5FL_MALLOC(H5B_t)))
- HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "can't allocate B-tree struct")
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "can't allocate B-tree struct")
HDmemset(&bt->cache_info, 0, sizeof(H5AC_info_t));
- if(NULL == (bt->rc_shared=(type->get_shared)(f, udata)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't retrieve B-tree node buffer")
+ if(NULL == (bt->rc_shared = (type->get_shared)(f, udata)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "can't retrieve B-tree node buffer")
shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
HDassert(shared);
/* Allocate space for the native keys and child addresses */
if(NULL == (bt->native = H5FL_BLK_MALLOC(native_block, shared->sizeof_keys)))
- HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "can't allocate buffer for native keys")
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "can't allocate buffer for native keys")
if(NULL == (bt->child = H5FL_SEQ_MALLOC(haddr_t, (size_t)shared->two_k)))
- HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "can't allocate buffer for child addresses")
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "can't allocate buffer for child addresses")
if(H5F_block_read(f, H5FD_MEM_BTREE, addr, shared->sizeof_rnode, dxpl_id, shared->page) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree node")
@@ -211,7 +212,7 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata)
p = shared->page;
/* magic number */
- if(HDmemcmp(p, H5B_MAGIC, (size_t)H5B_SIZEOF_MAGIC))
+ if(HDmemcmp(p, H5B_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree signature")
p += 4;
@@ -297,7 +298,7 @@ H5B_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B_t *bt, uns
* bother writing data for the child entries that don't exist or
* for the final unchanged children.
*/
- if (H5F_block_write(f, H5FD_MEM_BTREE, addr, shared->sizeof_rnode, dxpl_id, shared->page) < 0)
+ if(H5F_block_write(f, H5FD_MEM_BTREE, addr, shared->sizeof_rnode, dxpl_id, shared->page) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree node to disk")
bt->cache_info.is_dirty = FALSE;
@@ -325,24 +326,45 @@ done:
*
*-------------------------------------------------------------------------
*/
-/* ARGSUSED */
herr_t
-H5B_dest(H5F_t UNUSED *f, H5B_t *bt)
+H5B_dest(H5F_t *f, H5B_t *bt)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B_dest)
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B_dest)
/*
* Check arguments.
*/
+ HDassert(f);
HDassert(bt);
HDassert(bt->rc_shared);
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!bt->cache_info.free_file_space_on_destroy || H5F_addr_defined(bt->cache_info.addr));
+
+ /* Check for freeing file space for B-tree node */
+ if(bt->cache_info.free_file_space_on_destroy) {
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
+
+ /* Get the pointer to the shared B-tree info */
+ shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
+
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, bt->cache_info.addr, (hsize_t)shared->sizeof_rnode) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free B-tree node")
+ } /* end if */
+
+ /* Release resources for B-tree node */
bt->child = H5FL_SEQ_FREE(haddr_t, bt->child);
bt->native = H5FL_BLK_FREE(native_block, bt->native);
H5RC_DEC(bt->rc_shared);
bt = H5FL_FREE(H5B_t, bt);
- FUNC_LEAVE_NOAPI(SUCCEED)
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B_dest() */
@@ -408,7 +430,7 @@ H5B_compute_size(const H5F_t UNUSED *f, const H5B_t *bt, size_t *size_ptr)
HDassert(f);
HDassert(bt);
HDassert(bt->rc_shared);
- shared=(H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
+ shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
HDassert(shared);
HDassert(shared->type);
HDassert(size_ptr);
@@ -418,3 +440,4 @@ H5B_compute_size(const H5F_t UNUSED *f, const H5B_t *bt, size_t *size_ptr)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5B_compute_size() */
+
diff --git a/src/H5Bdbg.c b/src/H5Bdbg.c
new file mode 100644
index 0000000..1549693
--- /dev/null
+++ b/src/H5Bdbg.c
@@ -0,0 +1,284 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Bdbg.c
+ * Dec 11 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Debugging routines for B-link tree package.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5B_PACKAGE /*suppress error about including H5Bpkg */
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Bpkg.h" /* B-link trees */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5MMprivate.h" /* Memory management */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B_debug
+ *
+ * Purpose: Prints debugging info about a B-tree.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 4 1997
+ *
+ * Modifications:
+ * Robb Matzke, 1999-07-28
+ * The ADDR argument is passed by value.
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth,
+ const H5B_class_t *type, void *udata)
+{
+ H5B_t *bt = NULL;
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
+ unsigned u; /* Local index variable */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5B_debug, FAIL)
+
+ /*
+ * Check arguments.
+ */
+ assert(f);
+ assert(H5F_addr_defined(addr));
+ assert(stream);
+ assert(indent >= 0);
+ assert(fwidth >= 0);
+ assert(type);
+
+ /*
+ * Load the tree node.
+ */
+ if (NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_READ)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree node")
+ shared=(H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
+
+ /*
+ * Print the values.
+ */
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Tree type ID:",
+ ((shared->type->id)==H5B_SNODE_ID ? "H5B_SNODE_ID" :
+ ((shared->type->id)==H5B_CHUNK_ID ? "H5B_CHUNK_ID" : "Unknown!")));
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "Size of node:",
+ shared->sizeof_rnode);
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "Size of raw (disk) key:",
+ shared->sizeof_rkey);
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Dirty flag:",
+ bt->cache_info.is_dirty ? "True" : "False");
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Level:",
+ bt->level);
+
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
+ "Address of left sibling:",
+ bt->left);
+
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
+ "Address of right sibling:",
+ bt->right);
+
+ HDfprintf(stream, "%*s%-*s %u (%u)\n", indent, "", fwidth,
+ "Number of children (max):",
+ bt->nchildren, shared->two_k);
+
+ /*
+ * Print the child addresses
+ */
+ for (u = 0; u < bt->nchildren; u++) {
+ HDfprintf(stream, "%*sChild %d...\n", indent, "", u);
+ HDfprintf(stream, "%*s%-*s %a\n", indent + 3, "", MAX(0, fwidth - 3),
+ "Address:", bt->child[u]);
+
+ /* If there is a key debugging routine, use it to display the left & right keys */
+ if (type->debug_key) {
+ /* Decode the 'left' key & print it */
+ HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
+ "Left Key:");
+ assert(H5B_NKEY(bt,shared,u));
+ (void)(type->debug_key)(stream, f, dxpl_id, indent+6, MAX (0, fwidth-6),
+ H5B_NKEY(bt,shared,u), udata);
+
+ /* Decode the 'right' key & print it */
+ HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
+ "Right Key:");
+ assert(H5B_NKEY(bt,shared,u+1));
+ (void)(type->debug_key)(stream, f, dxpl_id, indent+6, MAX (0, fwidth-6),
+ H5B_NKEY(bt,shared,u+1), udata);
+ }
+ }
+
+done:
+ if (bt && H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B_assert
+ *
+ * Purpose: Verifies that the tree is structured correctly.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: aborts if something is wrong.
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, November 4, 1997
+ *
+ * Modifications:
+ * Robb Matzke, 1999-07-28
+ * The ADDR argument is passed by value.
+ *
+ * John Mainzer, 6/8/05
+ * Modified the function to use the new dirtied parameter of
+ * of H5AC_unprotect() instead of modifying the is_dirty
+ * field of the cache info.
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifdef H5B_DEBUG
+herr_t
+H5B_assert(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type, void *udata)
+{
+ H5B_t *bt = NULL;
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
+ int i, ncell, cmp;
+ static int ncalls = 0;
+ herr_t status;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ /* A queue of child data */
+ struct child_t {
+ haddr_t addr;
+ unsigned level;
+ struct child_t *next;
+ } *head = NULL, *tail = NULL, *prev = NULL, *cur = NULL, *tmp = NULL;
+
+ FUNC_ENTER_NOAPI_NOFUNC(H5B_assert)
+
+ if (0==ncalls++) {
+ if (H5DEBUG(B)) {
+ fprintf(H5DEBUG(B), "H5B: debugging B-trees (expensive)\n");
+ }
+ }
+ /* Initialize the queue */
+ bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_READ);
+ assert(bt);
+ shared=(H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
+ cur = H5MM_calloc(sizeof(struct child_t));
+ assert (cur);
+ cur->addr = addr;
+ cur->level = bt->level;
+ head = tail = cur;
+
+ status = H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET);
+ assert(status >= 0);
+ bt=NULL; /* Make certain future references will be caught */
+
+ /*
+ * Do a breadth-first search of the tree. New nodes are added to the end
+ * of the queue as the `cur' pointer is advanced toward the end. We don't
+ * remove any nodes from the queue because we need them in the uniqueness
+ * test.
+ */
+ for (ncell = 0; cur; ncell++) {
+ bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, cur->addr, type, udata, H5AC_READ);
+ assert(bt);
+
+ /* Check node header */
+ assert(bt->level == cur->level);
+ if (cur->next && cur->next->level == bt->level) {
+ assert(H5F_addr_eq(bt->right, cur->next->addr));
+ } else {
+ assert(!H5F_addr_defined(bt->right));
+ }
+ if (prev && prev->level == bt->level) {
+ assert(H5F_addr_eq(bt->left, prev->addr));
+ } else {
+ assert(!H5F_addr_defined(bt->left));
+ }
+
+ if (cur->level > 0) {
+ for (i = 0; i < bt->nchildren; i++) {
+
+ /*
+ * Check that child nodes haven't already been seen. If they
+ * have then the tree has a cycle.
+ */
+ for (tmp = head; tmp; tmp = tmp->next) {
+ assert(H5F_addr_ne(tmp->addr, bt->child[i]));
+ }
+
+ /* Add the child node to the end of the queue */
+ tmp = H5MM_calloc(sizeof(struct child_t));
+ assert (tmp);
+ tmp->addr = bt->child[i];
+ tmp->level = bt->level - 1;
+ tail->next = tmp;
+ tail = tmp;
+
+ /* Check that the keys are monotonically increasing */
+ cmp = (type->cmp2)(f, dxpl_id, H5B_NKEY(bt, shared, i), udata,
+ H5B_NKEY(bt, shared, i + 1));
+ assert(cmp < 0);
+ }
+ }
+ /* Release node */
+ status = H5AC_unprotect(f, dxpl_id, H5AC_BT, cur->addr, bt, H5AC__NO_FLAGS_SET);
+ assert(status >= 0);
+ bt=NULL; /* Make certain future references will be caught */
+
+ /* Advance current location in queue */
+ prev = cur;
+ cur = cur->next;
+ }
+
+ /* Free all entries from queue */
+ while (head) {
+ tmp = head->next;
+ H5MM_xfree(head);
+ head = tmp;
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+#endif /* H5B_DEBUG */
+
diff --git a/src/H5Bpkg.h b/src/H5Bpkg.h
index 755488c..ddabf52 100644
--- a/src/H5Bpkg.h
+++ b/src/H5Bpkg.h
@@ -32,12 +32,14 @@
#include "H5Bprivate.h"
/* Other private headers needed by this file */
-#include "H5RCprivate.h" /* Reference counted objects */
/**************************/
/* Package Private Macros */
/**************************/
+/* Get the native key at a given index */
+#define H5B_NKEY(b, shared, idx) ((b)->native + (shared)->nkey[(idx)])
+
/****************************/
/* Package Private Typedefs */
@@ -76,6 +78,10 @@ H5FL_EXTERN(H5B_t);
/* Package Private Prototypes */
/******************************/
H5_DLL herr_t H5B_dest(H5F_t *f, H5B_t *b);
+#ifdef H5B_DEBUG
+herr_t H5B_assert(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type,
+ void *udata);
+#endif
#endif /*_H5Bpkg_H*/
diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h
index 18a2c71..716b608 100644
--- a/src/H5Bprivate.h
+++ b/src/H5Bprivate.h
@@ -51,13 +51,22 @@
#ifdef NDEBUG
# undef H5B_DEBUG
#endif
-#define H5B_MAGIC "TREE" /*tree node magic number */
-#define H5B_SIZEOF_MAGIC 4 /*size of magic number */
+
/****************************/
/* Library Private Typedefs */
/****************************/
+/* B-tree IDs for various internal things. */
+/* Note - if more of these are added, any 'K' values (for internal or leaf
+ * nodes) they use will need to be stored in the file somewhere. -QAK
+ */
+typedef enum H5B_subid_t {
+ H5B_SNODE_ID = 0, /*B-tree is for symbol table nodes */
+ H5B_CHUNK_ID = 1, /*B-tree is for chunked dataset storage */
+ H5B_NUM_BTREE_ID /* Number of B-tree key IDs (must be last) */
+} H5B_subid_t;
+
/* Define return values from B-tree insertion callbacks */
typedef enum H5B_ins_t {
H5B_INS_ERROR = -1, /*error return value */
@@ -104,7 +113,7 @@ typedef struct H5B_class_t {
herr_t (*new_node)(H5F_t*, hid_t, H5B_ins_t, void*, void*, void*, haddr_t*);
int (*cmp2)(H5F_t*, hid_t, void*, void*, void*); /*compare 2 keys */
int (*cmp3)(H5F_t*, hid_t, void*, void*, void*); /*compare 3 keys */
- herr_t (*found)(H5F_t*, hid_t, haddr_t, const void*, void*);
+ htri_t (*found)(H5F_t*, hid_t, haddr_t, const void*, void*);
/* insert new data */
H5B_ins_t (*insert)(H5F_t*, hid_t, haddr_t, void*, hbool_t*, void*, void*,
@@ -159,5 +168,7 @@ H5_DLL H5B_shared_t *H5B_shared_new(const H5F_t *f, const H5B_class_t *type,
H5_DLL herr_t H5B_shared_free(void *_shared);
H5_DLL herr_t H5B_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream,
int indent, int fwidth, const H5B_class_t *type, void *udata);
+H5_DLL htri_t H5B_valid(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type,
+ haddr_t addr);
#endif /* _H5Bprivate_H */
diff --git a/src/H5Bpublic.h b/src/H5Bpublic.h
index df3861f..0016996 100644
--- a/src/H5Bpublic.h
+++ b/src/H5Bpublic.h
@@ -31,17 +31,6 @@
/* Public headers needed by this file */
#include "H5public.h"
-/* B-tree IDs for various internal things. */
-/* Not really a "public" symbol, but that should be OK -QAK */
-/* Note - if more of these are added, any 'K' values (for internal or leaf
- * nodes) they use will need to be stored in the file somewhere. -QAK
- */
-typedef enum H5B_subid_t {
- H5B_SNODE_ID = 0, /*B-tree is for symbol table nodes */
- H5B_ISTORE_ID = 1, /*B-tree is for indexed object storage */
- H5B_NUM_BTREE_ID /* Number of B-tree key IDs (must be last) */
-} H5B_subid_t;
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/src/H5C.c b/src/H5C.c
index daa5c8b..ef58012 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -538,9 +538,14 @@ if ( ( (entry_ptr) == NULL ) || \
* More pinned entry stats related updates.
*
* JRM -- 3/31/07
- * Updated H5C__UPDATE_STATS_FOR_PROTECT() to keep stats on
+ * Updated H5C__UPDATE_STATS_FOR_PROTECT() to keep stats on
* read and write protects.
*
+ * MAM -- 1/15/09
+ * Created H5C__UPDATE_MAX_INDEX_SIZE_STATS to contain
+ * common code within macros that update the maximum
+ * index, clean_index, and dirty_index statistics fields.
+ *
***********************************************************************/
#define H5C__UPDATE_CACHE_HIT_RATE_STATS(cache_ptr, hit) \
@@ -551,6 +556,18 @@ if ( ( (entry_ptr) == NULL ) || \
#if H5C_COLLECT_CACHE_STATS
+#define H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \
+ if ( (cache_ptr)->index_size > (cache_ptr)->max_index_size ) \
+ (cache_ptr)->max_index_size = (cache_ptr)->index_size; \
+ if ( (cache_ptr)->clean_index_size > \
+ (cache_ptr)->max_clean_index_size ) \
+ (cache_ptr)->max_clean_index_size = \
+ (cache_ptr)->clean_index_size; \
+ if ( (cache_ptr)->dirty_index_size > \
+ (cache_ptr)->max_dirty_index_size ) \
+ (cache_ptr)->max_dirty_index_size = \
+ (cache_ptr)->dirty_index_size;
+
#define H5C__UPDATE_STATS_FOR_DIRTY_PIN(cache_ptr, entry_ptr) \
(((cache_ptr)->dirty_pins)[(entry_ptr)->type->id])++;
@@ -582,8 +599,7 @@ if ( ( (entry_ptr) == NULL ) || \
} \
if ( (entry_ptr)->size < (new_size) ) { \
((cache_ptr)->size_increases[(entry_ptr)->type->id])++; \
- if ( (cache_ptr)->index_size > (cache_ptr)->max_index_size ) \
- (cache_ptr)->max_index_size = (cache_ptr)->index_size; \
+ H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \
if ( (cache_ptr)->slist_size > (cache_ptr)->max_slist_size ) \
(cache_ptr)->max_slist_size = (cache_ptr)->slist_size; \
if ( (cache_ptr)->pl_size > (cache_ptr)->max_pl_size ) \
@@ -678,8 +694,7 @@ if ( ( (entry_ptr) == NULL ) || \
} \
if ( (cache_ptr)->index_len > (cache_ptr)->max_index_len ) \
(cache_ptr)->max_index_len = (cache_ptr)->index_len; \
- if ( (cache_ptr)->index_size > (cache_ptr)->max_index_size ) \
- (cache_ptr)->max_index_size = (cache_ptr)->index_size; \
+ H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \
if ( (cache_ptr)->slist_len > (cache_ptr)->max_slist_len ) \
(cache_ptr)->max_slist_len = (cache_ptr)->slist_len; \
if ( (cache_ptr)->slist_size > (cache_ptr)->max_slist_size ) \
@@ -707,8 +722,7 @@ if ( ( (entry_ptr) == NULL ) || \
} \
if ( (cache_ptr)->index_len > (cache_ptr)->max_index_len ) \
(cache_ptr)->max_index_len = (cache_ptr)->index_len; \
- if ( (cache_ptr)->index_size > (cache_ptr)->max_index_size ) \
- (cache_ptr)->max_index_size = (cache_ptr)->index_size; \
+ H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \
if ( (cache_ptr)->pl_len > (cache_ptr)->max_pl_len ) \
(cache_ptr)->max_pl_len = (cache_ptr)->pl_len; \
if ( (cache_ptr)->pl_size > (cache_ptr)->max_pl_size ) \
@@ -759,8 +773,7 @@ if ( ( (entry_ptr) == NULL ) || \
} \
if ( (cache_ptr)->index_len > (cache_ptr)->max_index_len ) \
(cache_ptr)->max_index_len = (cache_ptr)->index_len; \
- if ( (cache_ptr)->index_size > (cache_ptr)->max_index_size ) \
- (cache_ptr)->max_index_size = (cache_ptr)->index_size; \
+ H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \
if ( (cache_ptr)->slist_len > (cache_ptr)->max_slist_len ) \
(cache_ptr)->max_slist_len = (cache_ptr)->slist_len; \
if ( (cache_ptr)->slist_size > (cache_ptr)->max_slist_size ) \
@@ -783,8 +796,7 @@ if ( ( (entry_ptr) == NULL ) || \
} \
if ( (cache_ptr)->index_len > (cache_ptr)->max_index_len ) \
(cache_ptr)->max_index_len = (cache_ptr)->index_len; \
- if ( (cache_ptr)->index_size > (cache_ptr)->max_index_size ) \
- (cache_ptr)->max_index_size = (cache_ptr)->index_size; \
+ H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \
if ( (cache_ptr)->pl_len > (cache_ptr)->max_pl_len ) \
(cache_ptr)->max_pl_len = (cache_ptr)->pl_len; \
if ( (cache_ptr)->pl_size > (cache_ptr)->max_pl_size ) \
@@ -830,6 +842,14 @@ if ( ( (entry_ptr) == NULL ) || \
* When modifying these macros, remember to modify the similar macros
* in tst/cache.c
*
+ * Changes:
+ *
+ * - Updated existing index macros and sanity check macros to maintain
+ * the clean_index_size and dirty_index_size fields of H5C_t. Also
+ * added macros to allow us to track entry cleans and dirties.
+ *
+ * JRM -- 11/5/08
+ *
***********************************************************************/
/* H5C__HASH_TABLE_LEN is defined in H5Cpkg.h. It mut be a power of two. */
@@ -849,7 +869,10 @@ if ( ( (cache_ptr) == NULL ) || \
( (entry_ptr)->ht_prev != NULL ) || \
( (entry_ptr)->size <= 0 ) || \
( (k = H5C__HASH_FCN((entry_ptr)->addr)) < 0 ) || \
- ( k >= H5C__HASH_TABLE_LEN ) ) { \
+ ( k >= H5C__HASH_TABLE_LEN ) || \
+ ( (cache_ptr)->index_size != \
+ ((cache_ptr)->clean_index_size + \
+ (cache_ptr)->dirty_index_size) ) ) { \
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, \
"Pre HT insert SC failed") \
}
@@ -871,13 +894,18 @@ if ( ( (cache_ptr) == NULL ) || \
( (entry_ptr)->ht_prev == NULL ) ) || \
( ( ((cache_ptr)->index)[(H5C__HASH_FCN((entry_ptr)->addr))] == \
(entry_ptr) ) && \
- ( (entry_ptr)->ht_prev != NULL ) ) ) { \
+ ( (entry_ptr)->ht_prev != NULL ) ) || \
+ ( (cache_ptr)->index_size != \
+ ((cache_ptr)->clean_index_size + \
+ (cache_ptr)->dirty_index_size) ) ) { \
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Pre HT remove SC failed") \
}
#define H5C__PRE_HT_SEARCH_SC(cache_ptr, Addr, fail_val) \
if ( ( (cache_ptr) == NULL ) || \
( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \
+ ( (cache_ptr)->index_size != \
+ ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) || \
( ! H5F_addr_defined(Addr) ) || \
( H5C__HASH_FCN(Addr) < 0 ) || \
( H5C__HASH_FCN(Addr) >= H5C__HASH_TABLE_LEN ) ) { \
@@ -890,6 +918,8 @@ if ( ( (cache_ptr) == NULL ) || \
( (cache_ptr)->index_len < 1 ) || \
( (entry_ptr) == NULL ) || \
( (cache_ptr)->index_size < (entry_ptr)->size ) || \
+ ( (cache_ptr)->index_size != \
+ ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) || \
( H5F_addr_ne((entry_ptr)->addr, (Addr)) ) || \
( (entry_ptr)->size <= 0 ) || \
( ((cache_ptr)->index)[k] == NULL ) || \
@@ -913,7 +943,8 @@ if ( ( (cache_ptr) == NULL ) || \
"Post HT shift to front SC failed") \
}
-#define H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size) \
+#define H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \
+ entry_ptr, was_clean) \
if ( ( (cache_ptr) == NULL ) || \
( (cache_ptr)->index_len <= 0 ) || \
( (cache_ptr)->index_size <= 0 ) || \
@@ -921,20 +952,81 @@ if ( ( (cache_ptr) == NULL ) || \
( (old_size) > (cache_ptr)->index_size ) || \
( (new_size) <= 0 ) || \
( ( (cache_ptr)->index_len == 1 ) && \
- ( (cache_ptr)->index_size != (old_size) ) ) ) { \
+ ( (cache_ptr)->index_size != (old_size) ) ) || \
+ ( (cache_ptr)->index_size != \
+ ((cache_ptr)->clean_index_size + \
+ (cache_ptr)->dirty_index_size) ) || \
+ ( (entry_ptr == NULL) ) || \
+ ( ( !( was_clean ) || \
+ ( (cache_ptr)->clean_index_size < (old_size) ) ) && \
+ ( ( (was_clean) ) || \
+ ( (cache_ptr)->dirty_index_size < (old_size) ) ) ) \
+ ( (entry_ptr) == NULL ) ) { \
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"Pre HT entry size change SC failed") \
+}
+
+#define H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \
+ entry_ptr) \
+if ( ( (cache_ptr) == NULL ) || \
+ ( (cache_ptr)->index_len <= 0 ) || \
+ ( (cache_ptr)->index_size <= 0 ) || \
+ ( (new_size) > (cache_ptr)->index_size ) || \
+ ( (cache_ptr)->index_size != \
+ ((cache_ptr)->clean_index_size + \
+ (cache_ptr)->dirty_index_size) ) || \
+ ( ( !((entry_ptr)->is_dirty ) || \
+ ( (cache_ptr)->dirty_index_size < (new_size) ) ) && \
+ ( ( ((entry_ptr)->is_dirty) ) || \
+ ( (cache_ptr)->clean_index_size < (new_size) ) ) ) \
+ ( ( (cache_ptr)->index_len == 1 ) && \
+ ( (cache_ptr)->index_size != (new_size) ) ) ) { \
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "Post HT entry size change SC failed") \
+}
+
+#define H5C__PRE_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr) \
+if ( \
+ ( (cache_ptr) == NULL ) || \
+ ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \
+ ( (cache_ptr)->index_len <= 0 ) || \
+ ( (entry_ptr) == NULL ) || \
+ ( (entry_ptr)->is_dirty != FALSE ) || \
+ ( (cache_ptr)->index_size < (entry_ptr)->size ) || \
+ ( (cache_ptr)->dirty_index_size < (entry_ptr)->size ) || \
+ ( (cache_ptr)->index_size != \
+ ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) ) { \
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "Pre HT update for entry clean SC failed") \
+}
+
+#define H5C__PRE_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr) \
+if ( \
+ ( (cache_ptr) == NULL ) || \
+ ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \
+ ( (cache_ptr)->index_len <= 0 ) || \
+ ( (entry_ptr) == NULL ) || \
+ ( (entry_ptr)->is_dirty != TRUE ) || \
+ ( (cache_ptr)->index_size < (entry_ptr)->size ) || \
+ ( (cache_ptr)->clean_index_size < (entry_ptr)->size ) || \
+ ( (cache_ptr)->index_size != \
+ ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) ) { \
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "Pre HT update for entry dirty SC failed") \
}
-#define H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size) \
-if ( ( (cache_ptr) == NULL ) || \
- ( (cache_ptr)->index_len <= 0 ) || \
- ( (cache_ptr)->index_size <= 0 ) || \
- ( (new_size) > (cache_ptr)->index_size ) || \
- ( ( (cache_ptr)->index_len == 1 ) && \
- ( (cache_ptr)->index_size != (new_size) ) ) ) { \
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "Post HT entry size change SC failed") \
+#define H5C__POST_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr) \
+if ( (cache_ptr)->index_size != \
+ ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) { \
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "Post HT update for entry clean SC failed") \
+}
+
+#define H5C__POST_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr) \
+if ( (cache_ptr)->index_size != \
+ ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) { \
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "Post HT update for entry dirty SC failed") \
}
#else /* H5C_DO_SANITY_CHECKS */
@@ -944,8 +1036,14 @@ if ( ( (cache_ptr) == NULL ) || \
#define H5C__PRE_HT_SEARCH_SC(cache_ptr, Addr, fail_val)
#define H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, Addr, k, fail_val)
#define H5C__POST_HT_SHIFT_TO_FRONT(cache_ptr, entry_ptr, k, fail_val)
-#define H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size)
-#define H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size)
+#define H5C__PRE_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr)
+#define H5C__PRE_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr)
+#define H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \
+ entry_ptr, was_clean)
+#define H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \
+ entry_ptr)
+#define H5C__POST_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr)
+#define H5C__POST_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr)
#endif /* H5C_DO_SANITY_CHECKS */
@@ -967,6 +1065,11 @@ if ( ( (cache_ptr) == NULL ) || \
} \
(cache_ptr)->index_len++; \
(cache_ptr)->index_size += (entry_ptr)->size; \
+ if ( (entry_ptr)->is_dirty ) { \
+ (cache_ptr)->dirty_index_size += (entry_ptr)->size; \
+ } else { \
+ (cache_ptr)->clean_index_size += (entry_ptr)->size; \
+ } \
H5C__UPDATE_STATS_FOR_HT_INSERTION(cache_ptr) \
}
@@ -991,6 +1094,11 @@ if ( ( (cache_ptr) == NULL ) || \
(entry_ptr)->ht_prev = NULL; \
(cache_ptr)->index_len--; \
(cache_ptr)->index_size -= (entry_ptr)->size; \
+ if ( (entry_ptr)->is_dirty ) { \
+ (cache_ptr)->dirty_index_size -= (entry_ptr)->size; \
+ } else { \
+ (cache_ptr)->clean_index_size -= (entry_ptr)->size; \
+ } \
H5C__UPDATE_STATS_FOR_HT_DELETION(cache_ptr) \
}
@@ -1059,12 +1167,40 @@ if ( ( (cache_ptr) == NULL ) || \
} \
}
-#define H5C__UPDATE_INDEX_FOR_SIZE_CHANGE(cache_ptr, old_size, new_size) \
-{ \
- H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size) \
- (cache_ptr)->index_size -= old_size; \
- (cache_ptr)->index_size += new_size; \
- H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size) \
+#define H5C__UPDATE_INDEX_FOR_ENTRY_CLEAN(cache_ptr, entry_ptr) \
+{ \
+ H5C__PRE_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr); \
+ (cache_ptr)->dirty_index_size -= (entry_ptr)->size; \
+ (cache_ptr)->clean_index_size += (entry_ptr)->size; \
+ H5C__POST_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr); \
+}
+
+#define H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY(cache_ptr, entry_ptr) \
+{ \
+ H5C__PRE_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr); \
+ (cache_ptr)->clean_index_size -= (entry_ptr)->size; \
+ (cache_ptr)->dirty_index_size += (entry_ptr)->size; \
+ H5C__POST_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr); \
+}
+
+#define H5C__UPDATE_INDEX_FOR_SIZE_CHANGE(cache_ptr, old_size, new_size, \
+ entry_ptr, was_clean) \
+{ \
+ H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \
+ entry_ptr, was_clean) \
+ (cache_ptr)->index_size -= (old_size); \
+ (cache_ptr)->index_size += (new_size); \
+ if ( was_clean ) { \
+ (cache_ptr)->clean_index_size -= (old_size); \
+ } else { \
+ (cache_ptr)->dirty_index_size -= (old_size); \
+ } \
+ if ( (entry_ptr)->is_dirty ) { \
+ (cache_ptr)->dirty_index_size += (new_size); \
+ } else { \
+ (cache_ptr)->clean_index_size += (new_size); \
+ } \
+ H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, entry_ptr) \
}
@@ -1117,12 +1253,12 @@ if ( ( (cache_ptr) == NULL ) || \
* JRM -- 8/25/06
* Added the H5C_DO_SANITY_CHECKS version of the macro.
*
- * This version maintains the slist_len_increase and
+ * This version maintains the slist_len_increase and
* slist_size_increase fields that are used in sanity
* checks in the flush routines.
*
- * All this is needed as the fractal heap needs to be
- * able to dirty, resize and/or rename entries during the
+ * All this is needed as the fractal heap needs to be
+ * able to dirty, resize and/or rename entries during the
* flush.
*
*-------------------------------------------------------------------------
@@ -1209,7 +1345,7 @@ if ( ( (cache_ptr) == NULL ) || \
* Switched over to using skip list routines.
*
* JRM -- 3/28/07
- * Updated sanity checks for the new is_read_only and
+ * Updated sanity checks for the new is_read_only and
* ro_ref_count fields in H5C_cache_entry_t.
*
*-------------------------------------------------------------------------
@@ -1257,11 +1393,11 @@ if ( ( (cache_ptr) == NULL ) || \
* JRM -- 8/27/06
* Added the H5C_DO_SANITY_CHECKS version of the macro.
*
- * This version maintains the slist_size_increase field
+ * This version maintains the slist_size_increase field
* that are used in sanity checks in the flush routines.
*
- * All this is needed as the fractal heap needs to be
- * able to dirty, resize and/or rename entries during the
+ * All this is needed as the fractal heap needs to be
+ * able to dirty, resize and/or rename entries during the
* flush.
*
*-------------------------------------------------------------------------
@@ -1352,7 +1488,7 @@ if ( ( (cache_ptr) == NULL ) || \
* to do if called for such an entry.
*
* JRM -- 3/28/07
- * Added sanity checks using the new is_read_only and
+ * Added sanity checks using the new is_read_only and
* ro_ref_count fields of struct H5C_cache_entry_t.
*
*-------------------------------------------------------------------------
@@ -1494,7 +1630,7 @@ if ( ( (cache_ptr) == NULL ) || \
* be called on a pinned entry. Added assert to verify this.
*
* JRM -- 3/28/07
- * Added sanity checks for the new is_read_only and
+ * Added sanity checks for the new is_read_only and
* ro_ref_count fields of struct H5C_cache_entry_t.
*
*-------------------------------------------------------------------------
@@ -1749,7 +1885,7 @@ if ( ( (cache_ptr) == NULL ) || \
* Inserted an assert to verify this.
*
* JRM - 8/9/06
- * Not any more. We must now allow insertion of pinned
+ * Not any more. We must now allow insertion of pinned
* entries. Updated macro to support this.
*
* JRM - 3/28/07
@@ -1888,7 +2024,7 @@ if ( ( (cache_ptr) == NULL ) || \
* maintained by the replacement policy.
*
* JRM - 3/28/07
- * Added sanity checks based on the new is_read_only and
+ * Added sanity checks based on the new is_read_only and
* ro_ref_count fields of struct H5C_cache_entry_t.
*
*-------------------------------------------------------------------------
@@ -1912,6 +2048,7 @@ if ( ( (cache_ptr) == NULL ) || \
(cache_ptr)->pel_tail_ptr, \
(cache_ptr)->pel_len, \
(cache_ptr)->pel_size, (fail_val)) \
+ HDassert( (cache_ptr)->pel_len >= 0 ); \
\
} else { \
\
@@ -1974,6 +2111,7 @@ if ( ( (cache_ptr) == NULL ) || \
(cache_ptr)->pel_tail_ptr, \
(cache_ptr)->pel_len, \
(cache_ptr)->pel_size, (fail_val)) \
+ HDassert( (cache_ptr)->pel_len >= 0 ); \
\
} else { \
\
@@ -2052,7 +2190,7 @@ if ( ( (cache_ptr) == NULL ) || \
* nothing to be done.
*
* JRM - 3/28/07
- * Added sanity checks using the new is_read_only and
+ * Added sanity checks using the new is_read_only and
* ro_ref_count fields of struct H5C_cache_entry_t.
*
*-------------------------------------------------------------------------
@@ -2174,7 +2312,7 @@ if ( ( (cache_ptr) == NULL ) || \
* To do this, determine if the entry is pinned. If it is,
* update the size of the pinned entry list.
*
- * If it isn't pinned, the entry must handled by the
+ * If it isn't pinned, the entry must handled by the
* replacement policy. Update the appropriate replacement
* policy data structures.
*
@@ -2190,7 +2328,7 @@ if ( ( (cache_ptr) == NULL ) || \
* Modifications:
*
* JRM -- 3/28/07
- * Added sanity checks based on the new is_read_only and
+ * Added sanity checks based on the new is_read_only and
* ro_ref_count fields of struct H5C_cache_entry_t.
*
*-------------------------------------------------------------------------
@@ -2314,7 +2452,7 @@ if ( ( (cache_ptr) == NULL ) || \
* Modifications:
*
* JRM -- 3/28/07
- * Added sanity checks based on the new is_read_only and
+ * Added sanity checks based on the new is_read_only and
* ro_ref_count fields of struct H5C_cache_entry_t.
*
*-------------------------------------------------------------------------
@@ -2339,6 +2477,7 @@ if ( ( (cache_ptr) == NULL ) || \
H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pel_head_ptr, \
(cache_ptr)->pel_tail_ptr, (cache_ptr)->pel_len, \
(cache_ptr)->pel_size, (fail_val)) \
+ HDassert( (cache_ptr)->pel_len >= 0 ); \
\
/* modified LRU specific code */ \
\
@@ -2391,6 +2530,7 @@ if ( ( (cache_ptr) == NULL ) || \
H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pel_head_ptr, \
(cache_ptr)->pel_tail_ptr, (cache_ptr)->pel_len, \
(cache_ptr)->pel_size, (fail_val)) \
+ HDassert( (cache_ptr)->pel_len >= 0 ); \
\
/* modified LRU specific code */ \
\
@@ -2658,10 +2798,11 @@ static herr_t H5C_verify_not_in_index(H5C_t * cache_ptr,
static void *H5C_epoch_marker_load(H5F_t *f, hid_t dxpl_id, haddr_t addr,
const void *udata1, void *udata2);
static herr_t H5C_epoch_marker_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest,
- haddr_t addr, void *thing,
+ haddr_t addr, void *thing,
unsigned *flags_ptr);
static herr_t H5C_epoch_marker_dest(H5F_t *f, void *thing);
static herr_t H5C_epoch_marker_clear(H5F_t *f, void *thing, hbool_t dest);
+static herr_t H5C_epoch_marker_notify(H5C_notify_action_t action, void *thing);
static herr_t H5C_epoch_marker_size(const H5F_t *f, const void *thing, size_t *size_ptr);
const H5C_class_t epoch_marker_class =
@@ -2671,6 +2812,7 @@ const H5C_class_t epoch_marker_class =
/* flush = */ &H5C_epoch_marker_flush,
/* dest = */ &H5C_epoch_marker_dest,
/* clear = */ &H5C_epoch_marker_clear,
+ /* notify = */&H5C_epoch_marker_notify,
/* size = */ &H5C_epoch_marker_size
};
@@ -2752,6 +2894,20 @@ done:
}
static herr_t
+H5C_epoch_marker_notify(H5C_notify_action_t UNUSED action,
+ void UNUSED * thing)
+{
+ herr_t ret_value = FAIL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5C_epoch_marker_notify)
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "called unreachable fcn.")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+static herr_t
H5C_epoch_marker_size(const H5F_t UNUSED * f,
const void UNUSED * thing,
size_t UNUSED * size_ptr)
@@ -2831,22 +2987,26 @@ done:
*
* JRM -- 8/25/06
* Added initialization for the slist_len_increase and
- * slist_size_increase fields. These fields are used
+ * slist_size_increase fields. These fields are used
* for sanity checking in the flush process, and are not
* compiled in unless H5C_DO_SANITY_CHECKS is TRUE.
*
* JRM -- 3/28/07
- * Added initialization for the new is_read_only and
+ * Added initialization for the new is_read_only and
* ro_ref_count fields.
*
* JRM -- 7/27/07
- * Added initialization for the new evictions_enabled
+ * Added initialization for the new evictions_enabled
* field of H5C_t.
*
* JRM -- 12/31/07
* Added initialization for the new flash cache size increase
* related fields of H5C_t.
*
+ * JRM -- 11/5/08
+ * Added initialization for the new clean_index_size and
+ * dirty_index_size fields of H5C_t.
+ *
*-------------------------------------------------------------------------
*/
@@ -2889,8 +3049,7 @@ H5C_create(size_t max_cache_size,
"memory allocation failed")
}
- if ( (cache_ptr->slist_ptr = H5SL_create(H5SL_TYPE_HADDR,0.5,(size_t)16))
- == NULL ) {
+ if ( (cache_ptr->slist_ptr = H5SL_create(H5SL_TYPE_HADDR)) == NULL ) {
HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, NULL, "can't create skip list.")
}
@@ -2922,6 +3081,8 @@ H5C_create(size_t max_cache_size,
cache_ptr->index_len = 0;
cache_ptr->index_size = (size_t)0;
+ cache_ptr->clean_index_size = (size_t)0;
+ cache_ptr->dirty_index_size = (size_t)0;
cache_ptr->slist_len = 0;
cache_ptr->slist_size = (size_t)0;
@@ -3005,6 +3166,10 @@ H5C_create(size_t max_cache_size,
cache_ptr->epoch_marker_ringbuf_last = 0;
cache_ptr->epoch_marker_ringbuf_size = 0;
+ /* Initialize all epoch marker entries' fields to zero/FALSE/NULL */
+ HDmemset(cache_ptr->epoch_markers, 0, sizeof(cache_ptr->epoch_markers));
+
+ /* Set non-zero/FALSE/NULL fields for epoch markers */
for ( i = 0; i < H5C__MAX_EPOCH_MARKERS; i++ )
{
(cache_ptr->epoch_marker_active)[i] = FALSE;
@@ -3013,27 +3178,7 @@ H5C_create(size_t max_cache_size,
H5C__H5C_CACHE_ENTRY_T_MAGIC;
#endif /* NDEBUG */
((cache_ptr->epoch_markers)[i]).addr = (haddr_t)i;
- ((cache_ptr->epoch_markers)[i]).size = (size_t)0;
((cache_ptr->epoch_markers)[i]).type = &epoch_marker_class;
- ((cache_ptr->epoch_markers)[i]).is_dirty = FALSE;
- ((cache_ptr->epoch_markers)[i]).dirtied = FALSE;
- ((cache_ptr->epoch_markers)[i]).is_protected = FALSE;
- ((cache_ptr->epoch_markers)[i]).is_read_only = FALSE;
- ((cache_ptr->epoch_markers)[i]).ro_ref_count = 0;
- ((cache_ptr->epoch_markers)[i]).is_pinned = FALSE;
- ((cache_ptr->epoch_markers)[i]).in_slist = FALSE;
- ((cache_ptr->epoch_markers)[i]).ht_next = NULL;
- ((cache_ptr->epoch_markers)[i]).ht_prev = NULL;
- ((cache_ptr->epoch_markers)[i]).next = NULL;
- ((cache_ptr->epoch_markers)[i]).prev = NULL;
- ((cache_ptr->epoch_markers)[i]).aux_next = NULL;
- ((cache_ptr->epoch_markers)[i]).aux_prev = NULL;
-#if H5C_COLLECT_CACHE_ENTRY_STATS
- ((cache_ptr->epoch_markers)[i]).accesses = 0;
- ((cache_ptr->epoch_markers)[i]).clears = 0;
- ((cache_ptr->epoch_markers)[i]).flushes = 0;
- ((cache_ptr->epoch_markers)[i]).pins = 0;
-#endif /* H5C_COLLECT_CACHE_ENTRY_STATS */
}
if ( H5C_reset_cache_hit_rate_stats(cache_ptr) != SUCCEED ) {
@@ -3062,7 +3207,7 @@ done:
H5SL_close(cache_ptr->slist_ptr);
cache_ptr->magic = 0;
- H5FL_FREE(H5C_t, cache_ptr);
+ (void)H5FL_FREE(H5C_t, cache_ptr);
cache_ptr = NULL;
} /* end if */
@@ -3151,9 +3296,9 @@ H5C_def_auto_resize_rpt_fcn(H5C_t * cache_ptr,
HDfprintf(stdout,
"%sflash cache resize(%d) -- size threshold = %Zu.\n",
- cache_ptr->prefix,
+ cache_ptr->prefix,
(int)((cache_ptr->resize_ctl).flash_incr_mode),
- cache_ptr->flash_size_increase_threshold);
+ cache_ptr->flash_size_increase_threshold);
HDfprintf(stdout,
"%s cache size increased from (%Zu/%Zu) to (%Zu/%Zu).\n",
@@ -3289,10 +3434,6 @@ H5C_def_auto_resize_rpt_fcn(H5C_t * cache_ptr,
* Programmer: John Mainzer
* 6/2/04
*
- * Modifications:
- *
- * None.
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -3305,93 +3446,36 @@ H5C_dest(H5F_t * f,
FUNC_ENTER_NOAPI(H5C_dest, FAIL)
- HDassert( cache_ptr );
- HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
- HDassert( cache_ptr->skip_file_checks || f );
-
- if ( H5C_flush_cache(f, primary_dxpl_id, secondary_dxpl_id,
- cache_ptr, H5C__FLUSH_INVALIDATE_FLAG) < 0 ) {
+ /* Sanity check */
+ HDassert(cache_ptr);
+ HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
+ HDassert(cache_ptr->skip_file_checks || f);
+ /* Flush and invalidate all cache entries */
+ if(H5C_flush_invalidate_cache(f, primary_dxpl_id, secondary_dxpl_id,
+ cache_ptr, H5C__NO_FLAGS_SET) < 0 )
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache")
- }
-
- if ( cache_ptr->slist_ptr != NULL ) {
+ if(cache_ptr->slist_ptr != NULL) {
H5SL_close(cache_ptr->slist_ptr);
cache_ptr->slist_ptr = NULL;
- }
+ } /* end if */
cache_ptr->magic = 0;
- H5FL_FREE(H5C_t, cache_ptr);
+ (void)H5FL_FREE(H5C_t, cache_ptr);
done:
FUNC_LEAVE_NOAPI(ret_value)
-
} /* H5C_dest() */
/*-------------------------------------------------------------------------
- * Function: H5C_dest_empty
- *
- * Purpose: Destroy an empty cache.
- *
- * This function fails if the cache is not empty on entry.
- *
- * Note that *cache_ptr has been freed upon successful return.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: John Mainzer
- * 6/2/04
- *
- * Modifications:
- *
- * None.
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5C_dest_empty(H5C_t * cache_ptr)
-{
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5C_dest_empty, FAIL)
-
- /* This would normally be an assert, but we need to use an HGOTO_ERROR
- * call to shut up the compiler.
- */
- if ( ( ! cache_ptr ) ||
- ( cache_ptr->magic != H5C__H5C_T_MAGIC ) ||
- ( cache_ptr->index_len != 0 ) ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "Bad cache_ptr or non-empty cache on entry.")
- }
-
-
- if ( cache_ptr->slist_ptr != NULL ) {
-
- H5SL_close(cache_ptr->slist_ptr);
- cache_ptr->slist_ptr = NULL;
- }
-
- cache_ptr->magic = 0;
-
- H5FL_FREE(H5C_t, cache_ptr);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-
-} /* H5C_dest_empty() */
-
-
-/*-------------------------------------------------------------------------
*
* Function: H5C_expunge_entry
*
- * Purpose: Use this function to tell the cache to expunge an entry
- * from the cache without writing it to disk even if it is
+ * Purpose: Use this function to tell the cache to expunge an entry
+ * from the cache without writing it to disk even if it is
* dirty. The entry may not be either pinned or protected.
*
* Return: Non-negative on success/Negative on failure
@@ -3412,15 +3496,19 @@ H5C_expunge_entry(H5F_t * f,
hid_t secondary_dxpl_id,
H5C_t * cache_ptr,
const H5C_class_t * type,
- haddr_t addr)
+ haddr_t addr,
+ unsigned flags)
{
herr_t result;
- herr_t ret_value = SUCCEED; /* Return value */
hbool_t first_flush = TRUE;
+ hbool_t free_file_space;
H5C_cache_entry_t * entry_ptr = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5C_expunge_entry, FAIL)
+ free_file_space = ( (flags & H5C__FREE_FILE_SPACE_FLAG) != 0 );
+
HDassert( H5F_addr_defined(addr) );
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
@@ -3459,7 +3547,12 @@ H5C_expunge_entry(H5F_t * f,
"Target entry is pinned.")
}
- /* If we get this far, call H5C_flush_single_entry() with the
+ /* Pass along 'free file space' flag to cache client */
+
+ entry_ptr->free_file_space_on_destroy = free_file_space;
+
+
+ /* If we get this far, call H5C_flush_single_entry() with the
* H5C__FLUSH_INVALIDATE_FLAG and the H5C__FLUSH_CLEAR_ONLY_FLAG.
* This will clear the entry, and then delete it from the cache.
*/
@@ -3470,7 +3563,7 @@ H5C_expunge_entry(H5F_t * f,
cache_ptr,
entry_ptr->type,
entry_ptr->addr,
- H5C__FLUSH_INVALIDATE_FLAG |
+ H5C__FLUSH_INVALIDATE_FLAG |
H5C__FLUSH_CLEAR_ONLY_FLAG,
&first_flush,
TRUE);
@@ -3568,12 +3661,12 @@ done:
* Updated function to handle pinned entries.
*
* JRM -- 8/19/06
- * Added code managing the new flush_in_progress field of
+ * Added code managing the new flush_in_progress field of
* H5C_t.
*
* Also reworked function to allow for the possibility that
* entries will be dirtied, resized, or renamed during flush
- * callbacks. As a result, we may have to make multiple
+ * callbacks. As a result, we may have to make multiple
* passes through the skip list before the cache is flushed.
*
* JRM -- 10/13/07
@@ -3587,8 +3680,8 @@ done:
*
* Note that this is a pretty bad scenario if it ever
* happens. The code I have added should allow us to
- * handle the situation under all but the worst conditions,
- * but one can argue that I should just scream and die if I
+ * handle the situation under all but the worst conditions,
+ * but one can argue that I should just scream and die if I
* ever detect the condidtion.
*
*-------------------------------------------------------------------------
@@ -3673,227 +3766,245 @@ H5C_flush_cache(H5F_t * f,
( protected_entries == 0 ) &&
( flushed_entries_last_pass ) )
{
- flushed_entries_last_pass = FALSE;
- node_ptr = H5SL_first(cache_ptr->slist_ptr);
+ unsigned curr_flush_dep_height = 0;
+ unsigned flush_dep_passes = 0;
- if ( node_ptr != NULL ) {
+ flushed_entries_last_pass = FALSE;
- next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
+ /* Loop over all flush dependency heights of entries */
+ while((curr_flush_dep_height <= H5C__NUM_FLUSH_DEP_HEIGHTS) &&
+ (cache_ptr->slist_len != 0) &&
+ (flush_dep_passes < H5C__MAX_PASSES_ON_FLUSH) )
+ {
+ hbool_t flushed_during_dep_loop = FALSE;
- if ( next_entry_ptr == NULL ) {
+ /* Start at beginning of skip list each time */
+ node_ptr = H5SL_first(cache_ptr->slist_ptr);
+ HDassert( node_ptr != NULL );
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "next_entry_ptr == NULL 1 ?!?!");
- }
-#ifndef NDEBUG
- HDassert( next_entry_ptr->magic ==
- H5C__H5C_CACHE_ENTRY_T_MAGIC );
-#endif /* NDEBUG */
- HDassert( next_entry_ptr->is_dirty );
+ /* Get cache entry for this node */
+ next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
+ if ( NULL == next_entry_ptr )
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "next_entry_ptr == NULL ?!?!")
+ HDassert( next_entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC );
+ HDassert( next_entry_ptr->is_dirty );
HDassert( next_entry_ptr->in_slist );
- } else {
-
- next_entry_ptr = NULL;
-
- }
-
- HDassert( node_ptr != NULL );
-
#if H5C_DO_SANITY_CHECKS
- /* For sanity checking, try to verify that the skip list has
- * the expected size and number of entries at the end of each
- * internal while loop (see below).
- *
- * Doing this get a bit tricky, as depending on flags, we may
- * or may not flush all the entries in the slist.
- *
- * To make things more entertaining, with the advent of the
- * fractal heap, the entry flush callback can cause entries
- * to be dirtied, resized, and/or renamed.
- *
- * To deal with this, we first make note of the initial
- * skip list length and size:
- */
- initial_slist_len = cache_ptr->slist_len;
- initial_slist_size = cache_ptr->slist_size;
+ /* For sanity checking, try to verify that the skip list has
+ * the expected size and number of entries at the end of each
+ * internal while loop (see below).
+ *
+ * Doing this get a bit tricky, as depending on flags, we may
+ * or may not flush all the entries in the slist.
+ *
+ * To make things more entertaining, with the advent of the
+ * fractal heap, the entry flush callback can cause entries
+ * to be dirtied, resized, and/or renamed.
+ *
+ * To deal with this, we first make note of the initial
+ * skip list length and size:
+ */
+ initial_slist_len = cache_ptr->slist_len;
+ initial_slist_size = cache_ptr->slist_size;
- /* We then zero counters that we use to track the number
- * and total size of entries flushed:
- */
- flushed_entries_count = 0;
- flushed_entries_size = 0;
-
- /* As mentioned above, there is the possibility that
- * entries will be dirtied, resized, and/or flushed during
- * our pass through the skip list. To capture the number
- * of entries added, and the skip list size delta,
- * zero the slist_len_increase and slist_size_increase of
- * the cache's instance of H5C_t. These fields will be
- * updated elsewhere to account for slist insertions and/or
- * dirty entry size changes.
- */
- cache_ptr->slist_len_increase = 0;
- cache_ptr->slist_size_increase = 0;
+ /* We then zero counters that we use to track the number
+ * and total size of entries flushed:
+ */
+ flushed_entries_count = 0;
+ flushed_entries_size = 0;
+
+ /* As mentioned above, there is the possibility that
+ * entries will be dirtied, resized, and/or flushed during
+ * our pass through the skip list. To capture the number
+ * of entries added, and the skip list size delta,
+ * zero the slist_len_increase and slist_size_increase of
+ * the cache's instance of H5C_t. These fields will be
+ * updated elsewhere to account for slist insertions and/or
+ * dirty entry size changes.
+ */
+ cache_ptr->slist_len_increase = 0;
+ cache_ptr->slist_size_increase = 0;
- /* at the end of the loop, use these values to compute the
- * expected slist length and size and compare this with the
- * value recorded in the cache's instance of H5C_t.
- */
+ /* at the end of the loop, use these values to compute the
+ * expected slist length and size and compare this with the
+ * value recorded in the cache's instance of H5C_t.
+ */
#endif /* H5C_DO_SANITY_CHECKS */
- while ( node_ptr != NULL )
- {
- entry_ptr = next_entry_ptr;
-
- /* With the advent of the fractal heap, it is possible
- * that the flush callback will dirty and/or resize
- * other entries in the cache. In particular, while
- * Quincey has promised me that this will never happen,
- * it is possible that the flush callback for an
- * entry may protect an entry that is not in the cache,
- * perhaps causing the cache to flush and possibly
- * evict the entry associated with node_ptr to make
- * space for the new entry.
- *
- * Thus we do a bit of extra sanity checking on entry_ptr,
- * and break out of this scan of the skip list if we
- * detect minor problems. We have a bit of leaway on the
- * number of passes though the skip list, so this shouldn't
- * be an issue in the flush in and of itself, as it should
- * be all but impossible for this to happen more than once
- * in any flush.
- *
- * Observe that that breaking out of the scan early
- * shouldn't break the sanity checks just after the end
- * of this while loop.
- *
- * If an entry has merely been marked clean and removed from
- * the s-list, we simply break out of the scan.
- *
- * If the entry has been evicted, we flag an error and
- * exit.
- */
+ while ( node_ptr != NULL )
+ {
+ entry_ptr = next_entry_ptr;
+
+ /* With the advent of the fractal heap, it is possible
+ * that the flush callback will dirty and/or resize
+ * other entries in the cache. In particular, while
+ * Quincey has promised me that this will never happen,
+ * it is possible that the flush callback for an
+ * entry may protect an entry that is not in the cache,
+ * perhaps causing the cache to flush and possibly
+ * evict the entry associated with node_ptr to make
+ * space for the new entry.
+ *
+ * Thus we do a bit of extra sanity checking on entry_ptr,
+ * and break out of this scan of the skip list if we
+ * detect minor problems. We have a bit of leaway on the
+ * number of passes though the skip list, so this shouldn't
+ * be an issue in the flush in and of itself, as it should
+ * be all but impossible for this to happen more than once
+ * in any flush.
+ *
+ * Observe that that breaking out of the scan early
+ * shouldn't break the sanity checks just after the end
+ * of this while loop.
+ *
+ * If an entry has merely been marked clean and removed from
+ * the s-list, we simply break out of the scan.
+ *
+ * If the entry has been evicted, we flag an error and
+ * exit.
+ */
#ifndef NDEBUG
- if ( entry_ptr->magic != H5C__H5C_CACHE_ENTRY_T_MAGIC ) {
+ if ( entry_ptr->magic != H5C__H5C_CACHE_ENTRY_T_MAGIC ) {
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "entry_ptr->magic invalid ?!?!");
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "entry_ptr->magic is invalid ?!?!")
- } else
+ } else
#endif /* NDEBUG */
- if ( ( ! entry_ptr->is_dirty ) ||
- ( ! entry_ptr->in_slist ) ) {
+ if ( ( ! entry_ptr->is_dirty ) ||
+ ( ! entry_ptr->in_slist ) ) {
- /* the s-list has been modified out from under us.
- * set node_ptr to NULL and break out of the loop.
- */
- node_ptr = NULL;
- break;
- }
-
- /* increment node pointer now, before we delete its target
- * from the slist.
- */
- node_ptr = H5SL_next(node_ptr);
-
- if ( node_ptr != NULL ) {
- next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
+ /* the s-list has been modified out from under us.
+ * break out of the loop.
+ */
+ goto end_of_inner_loop;;
+ }
- if ( next_entry_ptr == NULL ) {
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "next_entry_ptr == NULL 2 ?!?!");
+ /* increment node pointer now, before we delete its target
+ * from the slist.
+ */
+ node_ptr = H5SL_next(node_ptr);
+
+ if ( node_ptr != NULL ) {
+ next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
+ if ( NULL == next_entry_ptr )
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "next_entry_ptr == NULL ?!?!")
+ HDassert( next_entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC );
+ HDassert( next_entry_ptr->is_dirty );
+ HDassert( next_entry_ptr->in_slist );
+ } else {
+ next_entry_ptr = NULL;
}
-#ifndef NDEBUG
- HDassert( next_entry_ptr->magic ==
- H5C__H5C_CACHE_ENTRY_T_MAGIC );
-#endif /* NDEBUG */
- HDassert( next_entry_ptr->is_dirty );
- HDassert( next_entry_ptr->in_slist );
- } else {
- next_entry_ptr = NULL;
- }
- HDassert( entry_ptr != NULL );
- HDassert( entry_ptr->in_slist );
+ HDassert( entry_ptr != NULL );
+ HDassert( entry_ptr->in_slist );
- if ( ( ! flush_marked_entries ) ||
- ( entry_ptr->flush_marker ) ) {
+ if ( ( ! flush_marked_entries ) ||
+ ( entry_ptr->flush_marker ) ) {
- if ( entry_ptr->is_protected ) {
+ if ( entry_ptr->is_protected ) {
- /* we probably have major problems -- but lets flush
- * everything we can before we decide whether to flag
- * an error.
- */
- tried_to_flush_protected_entry = TRUE;
- protected_entries++;
-
- } else if ( entry_ptr->is_pinned ) {
- /* Test to see if we are can flush the entry now.
- * If we can, go ahead and flush. Note that we
- * aren't trying to do a destroy here, so that
- * is not an issue.
- */
- if ( TRUE ) { /* When we get to multithreaded cache,
- * we will need either locking code,
- * and/or a test to see if the entry
- * is in flushable condition here.
- */
+ /* we probably have major problems -- but lets flush
+ * everything we can before we decide whether to flag
+ * an error.
+ */
+ tried_to_flush_protected_entry = TRUE;
+ protected_entries++;
+
+ } else if ( entry_ptr->is_pinned ) {
+ /* Test to see if we are can flush the entry now.
+ * If we can, go ahead and flush. Note that we
+ * aren't trying to do a destroy here, so that
+ * is not an issue.
+ */
+ if(entry_ptr->flush_dep_height == curr_flush_dep_height ) {
#if H5C_DO_SANITY_CHECKS
- flushed_entries_count++;
- flushed_entries_size += entry_ptr->size;
+ flushed_entries_count++;
+ flushed_entries_size += entry_ptr->size;
#endif /* H5C_DO_SANITY_CHECKS */
- status = H5C_flush_single_entry(f,
- primary_dxpl_id,
- secondary_dxpl_id,
- cache_ptr,
- NULL,
- entry_ptr->addr,
- flags,
- &first_flush,
- FALSE);
- if ( status < 0 ) {
-
- /* This shouldn't happen -- if it does, we are
- * toast so just scream and die.
- */
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "dirty pinned entry flush failed.")
- }
- flushed_entries_last_pass = TRUE;
- }
- } else {
+ status = H5C_flush_single_entry(f,
+ primary_dxpl_id,
+ secondary_dxpl_id,
+ cache_ptr,
+ NULL,
+ entry_ptr->addr,
+ flags,
+ &first_flush,
+ FALSE);
+ if ( status < 0 ) {
+
+ /* This shouldn't happen -- if it does, we are toast
+ * so just scream and die.
+ */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
+ "dirty pinned entry flush failed.")
+ } /* end if */
+ flushed_during_dep_loop = TRUE;
+ } /* end if */
+ else if(entry_ptr->flush_dep_height < curr_flush_dep_height)
+ /* This shouldn't happen -- if it does, just scream and die. */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry below current flush dep. height.")
+ } /* end if */
+ else {
+ /* Test to see if we are can flush the entry now.
+ * If we can, go ahead and flush. Note that we
+ * aren't trying to do a destroy here, so that
+ * is not an issue.
+ */
+ if(entry_ptr->flush_dep_height == curr_flush_dep_height ){
#if H5C_DO_SANITY_CHECKS
- flushed_entries_count++;
- flushed_entries_size += entry_ptr->size;
+ flushed_entries_count++;
+ flushed_entries_size += entry_ptr->size;
#endif /* H5C_DO_SANITY_CHECKS */
- status = H5C_flush_single_entry(f,
- primary_dxpl_id,
- secondary_dxpl_id,
- cache_ptr,
- NULL,
- entry_ptr->addr,
- flags,
- &first_flush,
- FALSE);
- if ( status < 0 ) {
+ status = H5C_flush_single_entry(f,
+ primary_dxpl_id,
+ secondary_dxpl_id,
+ cache_ptr,
+ NULL,
+ entry_ptr->addr,
+ flags,
+ &first_flush,
+ FALSE);
+ if ( status < 0 ) {
+
+ /* This shouldn't happen -- if it does, we are
+ * toast so just scream and die.
+ */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
+ "Can't flush entry.")
+ }
+ flushed_during_dep_loop = TRUE;
+ } /* end if */
+ else if(entry_ptr->flush_dep_height < curr_flush_dep_height)
+ /* This shouldn't happen -- if it does, just scream and die. */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry below current flush dep. height.")
+ } /* end else */
+ } /* end if */
+ } /* while ( node_ptr != NULL ) */
+
+ /* Check for incrementing flush dependency height */
+ if(flushed_during_dep_loop) {
+ /* If we flushed an entry at this flush dependency height
+ * start over at the bottom level of the flush dependencies
+ */
+ curr_flush_dep_height = 0;
- /* This shouldn't happen -- if it does, we are
- * toast so just scream and die.
- */
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "Can't flush entry.")
- }
- flushed_entries_last_pass = TRUE;
- }
- }
- } /* while ( node_ptr != NULL ) */
+ /* Make certain we don't get stuck in an infinite loop */
+ flush_dep_passes++;
+
+ /* Set flag for outer loop */
+ flushed_entries_last_pass = TRUE;
+ } /* end if */
+ else
+ curr_flush_dep_height++;
+
+ } /* while ( curr_flush_dep_height <= H5C__NUM_FLUSH_DEP_HEIGHTS) */
+end_of_inner_loop:
#if H5C_DO_SANITY_CHECKS
/* Verify that the slist size and length are as expected. */
- HDassert( (initial_slist_len + cache_ptr->slist_len_increase -
+ HDassert( (initial_slist_len + cache_ptr->slist_len_increase -
flushed_entries_count) == cache_ptr->slist_len );
HDassert( (initial_slist_size + cache_ptr->slist_size_increase -
flushed_entries_size) == cache_ptr->slist_size );
@@ -3984,7 +4095,7 @@ done:
* find a case where it helps, lets get rid of it.
*
*
- * Added some sanity checks to the change which verify the
+ * Added some sanity checks to the change which verify the
* expected values of the new is_read_only and ro_ref_count
* fields.
* JRM - 3/29/07
@@ -4378,10 +4489,12 @@ H5C_get_entry_status(H5C_t * cache_ptr,
hbool_t * in_cache_ptr,
hbool_t * is_dirty_ptr,
hbool_t * is_protected_ptr,
- hbool_t * is_pinned_ptr)
+ hbool_t * is_pinned_ptr,
+ hbool_t * is_flush_dep_parent_ptr,
+ hbool_t * is_flush_dep_child_ptr)
{
- herr_t ret_value = SUCCEED; /* Return value */
H5C_cache_entry_t * entry_ptr = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5C_get_entry_status, FAIL)
@@ -4430,6 +4543,16 @@ H5C_get_entry_status(H5C_t * cache_ptr,
*is_pinned_ptr = entry_ptr->is_pinned;
}
+
+ if ( is_flush_dep_parent_ptr != NULL ) {
+
+ *is_flush_dep_parent_ptr = (entry_ptr->flush_dep_height > 0);
+ }
+
+ if ( is_flush_dep_child_ptr != NULL ) {
+
+ *is_flush_dep_child_ptr = (entry_ptr->flush_dep_parent != NULL);
+ }
}
done:
@@ -4491,7 +4614,7 @@ done:
* Purpose: Get the trace_file_ptr field from the cache.
*
* This field will either be NULL (which indicates that trace
- * file logging is turned off), or contain a pointer to the
+ * file logging is turned off), or contain a pointer to the
* open file to which trace file data is to be written.
*
* Return: Non-negative on success/Negative on failure
@@ -4601,16 +4724,43 @@ done:
* destroy_in_progress fields.
*
* JRM -- 3/29/07
- * Added initialization for the new is_read_only and
+ * Added initialization for the new is_read_only and
* ro_ref_count fields.
*
* JRM -- 8/1/07
- * Added code to disable evictions when the new
+ * Added code to disable evictions when the new
* evictions_enabled field is FALSE.
*
* JRM -- 12/31/07
* Added code supporting flash cache size increases.
*
+ * QAK -- 1/31/08
+ * Added initialization for the new free_file_space_on_destroy
+ * field.
+ *
+ * JRM -- 11/13/08
+ * Moved test to see if we already have an entry with the
+ * specified address in the cache. This was necessary as
+ * we used to modify some fields in the entry to be inserted
+ * priort to this test, which got the cache confused if the
+ * insertion failed because the entry was already present.
+ *
+ * Also revised the function to call H5C_make_space_in_cache()
+ * if the min_clean_size is not met at present, not just if
+ * there is insufficient space in the cache for the new
+ * entry.
+ *
+ * The purpose of this modification is to avoid "metadata
+ * blizzards" in the write only case. In such instances,
+ * the cache was allowed to fill with dirty metadata. When
+ * we finally needed to evict an entry to make space, we had
+ * to flush out a whole cache full of metadata -- which has
+ * interesting performance effects. We hope to avoid (or
+ * perhaps more accurately hide) this effect by maintaining
+ * the min_clean_size, which should force us to start flushing
+ * entries long before we actually have to evict something
+ * to make space.
+ *
*-------------------------------------------------------------------------
*/
@@ -4624,15 +4774,16 @@ H5C_insert_entry(H5F_t * f,
void * thing,
unsigned int flags)
{
- /* const char * fcn_name = "H5C_insert_entry()"; */
herr_t result;
- herr_t ret_value = SUCCEED; /* Return value */
hbool_t first_flush = TRUE;
hbool_t insert_pinned;
hbool_t set_flush_marker;
hbool_t write_permitted = TRUE;
+ size_t empty_space;
H5C_cache_entry_t * entry_ptr;
H5C_cache_entry_t * test_entry_ptr;
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5C_insert_entry, FAIL)
@@ -4664,12 +4815,40 @@ H5C_insert_entry(H5F_t * f,
insert_pinned = ( (flags & H5C__PIN_ENTRY_FLAG) != 0 );
entry_ptr = (H5C_cache_entry_t *)thing;
+
+ /* verify that the new entry isn't already in the hash table -- scream
+ * and die if it is.
+ */
+
+ H5C__SEARCH_INDEX(cache_ptr, addr, test_entry_ptr, FAIL)
+
+ if ( test_entry_ptr != NULL ) {
+
+ if ( test_entry_ptr == entry_ptr ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, \
+ "entry already in cache.")
+
+ } else {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, \
+ "duplicate entry in cache.")
+ }
+ }
+
#ifndef NDEBUG
entry_ptr->magic = H5C__H5C_CACHE_ENTRY_T_MAGIC;
#endif /* NDEBUG */
entry_ptr->addr = addr;
entry_ptr->type = type;
+ entry_ptr->is_protected = FALSE;
+ entry_ptr->is_read_only = FALSE;
+ entry_ptr->ro_ref_count = 0;
+
+ entry_ptr->is_pinned = insert_pinned;
+ entry_ptr->pinned_from_client = insert_pinned;
+
/* newly inserted entries are assumed to be dirty */
entry_ptr->is_dirty = TRUE;
@@ -4692,6 +4871,13 @@ H5C_insert_entry(H5F_t * f,
entry_ptr->flush_in_progress = FALSE;
entry_ptr->destroy_in_progress = FALSE;
+ entry_ptr->free_file_space_on_destroy = FALSE;
+
+ /* Initialize flush dependency height fields */
+ entry_ptr->flush_dep_parent = NULL;
+ for(u = 0; u < H5C__NUM_FLUSH_DEP_HEIGHTS; u++)
+ entry_ptr->child_flush_dep_height_rc[u] = 0;
+ entry_ptr->flush_dep_height = 0;
entry_ptr->ht_next = NULL;
entry_ptr->ht_prev = NULL;
@@ -4716,13 +4902,35 @@ H5C_insert_entry(H5F_t * f,
}
}
- if ( ( cache_ptr->evictions_enabled ) &&
- ( (cache_ptr->index_size + entry_ptr->size) >
- cache_ptr->max_cache_size ) ) {
+ if ( cache_ptr->index_size >= cache_ptr->max_cache_size ) {
+
+ empty_space = 0;
+
+ } else {
+
+ empty_space = cache_ptr->max_cache_size - cache_ptr->index_size;
+
+ }
+
+ if ( ( cache_ptr->evictions_enabled )
+ &&
+ ( ( (cache_ptr->index_size + entry_ptr->size) >
+ cache_ptr->max_cache_size
+ )
+ ||
+ (
+ ( ( empty_space + cache_ptr->clean_index_size ) <
+ cache_ptr->min_clean_size )
+ )
+ )
+ ) {
size_t space_needed;
- cache_ptr->cache_full = TRUE;
+ if ( empty_space <= entry_ptr->size ) {
+
+ cache_ptr->cache_full = TRUE;
+ }
if ( cache_ptr->check_write_permitted != NULL ) {
@@ -4789,38 +4997,6 @@ H5C_insert_entry(H5F_t * f,
}
}
- /* verify that the new entry isn't already in the hash table -- scream
- * and die if it is.
- */
-
- H5C__SEARCH_INDEX(cache_ptr, addr, test_entry_ptr, FAIL)
-
- if ( test_entry_ptr != NULL ) {
-
- if ( test_entry_ptr == entry_ptr ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, \
- "entry already in cache.")
-
- } else {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, \
- "duplicate entry in cache.")
- }
- }
-
- /* we don't initialize the protected field until here as it is
- * possible that the entry is already in the cache, and already
- * protected. If it is, we don't want to make things worse by
- * marking it unprotected.
- */
-
- entry_ptr->is_protected = FALSE;
- entry_ptr->is_read_only = FALSE;
- entry_ptr->ro_ref_count = 0;
-
- entry_ptr->is_pinned = insert_pinned;
-
H5C__INSERT_IN_INDEX(cache_ptr, entry_ptr, FAIL)
/* New entries are presumed to be dirty, so this if statement is
@@ -4847,6 +5023,13 @@ H5C_insert_entry(H5F_t * f,
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
+ /* If the entry's type has a 'notify' callback send a 'after insertion'
+ * notice now that the entry is fully integrated into the cache.
+ */
+ if(entry_ptr->type->notify &&
+ (entry_ptr->type->notify)(H5C_NOTIFY_ACTION_AFTER_INSERT, entry_ptr) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, "can't notify client about entry inserted into cache")
+
H5C__UPDATE_STATS_FOR_INSERTION(cache_ptr, entry_ptr)
done:
@@ -5191,10 +5374,23 @@ done:
*
* Modifications:
*
- * Added code to do a flash cache size increase if
+ * Added code to do a flash cache size increase if
* appropriate.
* JRM -- 1/11/08
*
+ *
+ * Added code to update the clean_index_size and
+ * dirty_index_size fields of H5C_t in cases where the
+ * the entry was clean on protect, was marked dirty in
+ * this call, and did not change its size. Do this via
+ * a call to H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY().
+ *
+ * If the size changed, this case is already dealt with by
+ * by the pre-existing call to
+ * H5C__UPDATE_INDEX_FOR_SIZE_CHANGE().
+ *
+ * JRM -- 11/5/08
+ *
*-------------------------------------------------------------------------
*/
herr_t
@@ -5205,6 +5401,7 @@ H5C_mark_pinned_entry_dirty(H5C_t * cache_ptr,
{
herr_t ret_value = SUCCEED; /* Return value */
herr_t result;
+ hbool_t was_clean;
size_t size_increase;
H5C_cache_entry_t * entry_ptr;
@@ -5229,6 +5426,9 @@ H5C_mark_pinned_entry_dirty(H5C_t * cache_ptr,
"Entry is protected??")
}
+ /* make note of whether the entry was dirty to begin with */
+ was_clean = ! ( entry_ptr->is_dirty );
+
/* mark the entry as dirty if it isn't already */
entry_ptr->is_dirty = TRUE;
@@ -5242,7 +5442,7 @@ H5C_mark_pinned_entry_dirty(H5C_t * cache_ptr,
size_increase = new_size - entry_ptr->size;
- if ( size_increase >=
+ if ( size_increase >=
cache_ptr->flash_size_increase_threshold ) {
result = H5C__flash_increase_cache_size(cache_ptr,
@@ -5264,8 +5464,8 @@ H5C_mark_pinned_entry_dirty(H5C_t * cache_ptr,
(entry_ptr->size), (new_size));
/* update the hash table */
- H5C__UPDATE_INDEX_FOR_SIZE_CHANGE((cache_ptr), (entry_ptr->size),\
- (new_size));
+ H5C__UPDATE_INDEX_FOR_SIZE_CHANGE((cache_ptr), (entry_ptr->size), \
+ (new_size), (entry_ptr), (was_clean));
/* if the entry is in the skip list, update that too */
if ( entry_ptr->in_slist ) {
@@ -5280,6 +5480,10 @@ H5C_mark_pinned_entry_dirty(H5C_t * cache_ptr,
/* finally, update the entry size proper */
entry_ptr->size = new_size;
+
+ } else if ( ( was_clean ) && ( entry_ptr->is_dirty ) ) {
+
+ H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY(cache_ptr, entry_ptr)
}
if ( ! (entry_ptr->in_slist) ) {
@@ -5327,6 +5531,12 @@ done:
* it once we deal with the problem of entries being protected
* read only, and then dirtied.
*
+ * JRM -- 11/5/08
+ * Added call to H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY() to
+ * update the new clean_index_size and dirty_index_size
+ * fields of H5C_t in the case that the entry was clean
+ * prior to this call, and is pinned and not protected.
+ *
*-------------------------------------------------------------------------
*/
herr_t
@@ -5334,6 +5544,7 @@ H5C_mark_pinned_or_protected_entry_dirty(H5C_t * cache_ptr,
void * thing)
{
herr_t ret_value = SUCCEED; /* Return value */
+ hbool_t was_pinned_unprotected_and_clean;
H5C_cache_entry_t * entry_ptr;
FUNC_ENTER_NOAPI(H5C_mark_pinned_or_protected_entry_dirty, FAIL)
@@ -5353,9 +5564,15 @@ H5C_mark_pinned_or_protected_entry_dirty(H5C_t * cache_ptr,
} else if ( entry_ptr->is_pinned ) {
+ was_pinned_unprotected_and_clean = ! ( entry_ptr->is_dirty );
+
/* mark the entry as dirty if it isn't already */
entry_ptr->is_dirty = TRUE;
+ if ( was_pinned_unprotected_and_clean ) {
+
+ H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY(cache_ptr, entry_ptr);
+ }
if ( ! (entry_ptr->in_slist) ) {
@@ -5415,6 +5632,11 @@ done:
* Note that in this case H5C_flush_single_entry() will handle
* all these details for us.
*
+ * JRM -- 11/5/08
+ * On review this function looks like no change is needed to
+ * support the new clean_index_size and dirty_index_size
+ * fields of H5C_t.
+ *
*-------------------------------------------------------------------------
*/
@@ -5494,7 +5716,7 @@ H5C_rename_entry(H5C_t * cache_ptr,
* Since this is a simple re-name, cache size should be unaffected.
*
* Check to see if the target entry is in the process of being destroyed
- * before we delete from the index, etc. If it is, all we do is
+ * before we delete from the index, etc. If it is, all we do is
* change the addr. If the entry is only in the process of being flushed,
* don't mark it as dirty either, lest we confuse the flush call back.
*/
@@ -5538,7 +5760,7 @@ H5C_rename_entry(H5C_t * cache_ptr,
if ( removed_entry_from_slist ) {
- /* we just removed the entry from the slist. Thus we
+ /* we just removed the entry from the slist. Thus we
* must touch up cache_ptr->slist_len_increase and
* cache_ptr->slist_size_increase to keep from skewing
* the sanity checks.
@@ -5577,10 +5799,10 @@ done:
* Function: H5C_resize_pinned_entry
*
* Purpose: Resize a pinned entry. The target entry MUST be
- * be pinned, and MUST not be unprotected.
+ * be pinned, and MUST be unprotected.
*
- * Resizing an entry dirties it, so if the entry is not
- * already dirty, the function places the entry on the
+ * Resizing an entry dirties it, so if the entry is not
+ * already dirty, the function places the entry on the
* skip list.
*
* Return: Non-negative on success/Negative on failure
@@ -5590,10 +5812,23 @@ done:
*
* Modifications:
*
- * Added code to apply a flash cache size increment if
+ * Added code to apply a flash cache size increment if
* appropriate.
* JRM -- 1/11/08
*
+ * Added code to update the clean_index_size and
+ * dirty_index_size fields of H5C_t in cases where the
+ * the entry was clean prior to this call, was marked dirty,
+ * and did not change its size. Do this via a call to
+ * H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY().
+ *
+ * If the size changed, this case is already dealt with by
+ * by the pre-existing call to
+ * H5C__UPDATE_INDEX_FOR_SIZE_CHANGE().
+ *
+ * JRM -- 11/5/08
+ *
+ *
*-------------------------------------------------------------------------
*/
herr_t
@@ -5604,6 +5839,7 @@ H5C_resize_pinned_entry(H5C_t * cache_ptr,
/* const char * fcn_name = "H5C_resize_pinned_entry()"; */
herr_t ret_value = SUCCEED; /* Return value */
herr_t result;
+ hbool_t was_clean;
H5C_cache_entry_t * entry_ptr;
size_t size_increase;
@@ -5633,8 +5869,11 @@ H5C_resize_pinned_entry(H5C_t * cache_ptr,
"Entry is protected??")
}
- /* resizing dirties entries -- mark the entry as dirty if it
- * isn't already
+ /* make note of whether the entry was clean to begin with */
+ was_clean = ! ( entry_ptr->is_dirty );
+
+ /* resizing dirties entries -- mark the entry as dirty if it
+ * isn't already
*/
entry_ptr->is_dirty = TRUE;
@@ -5648,7 +5887,7 @@ H5C_resize_pinned_entry(H5C_t * cache_ptr,
size_increase = new_size - entry_ptr->size;
- if ( size_increase >=
+ if ( size_increase >=
cache_ptr->flash_size_increase_threshold ) {
result = H5C__flash_increase_cache_size(cache_ptr,
@@ -5671,7 +5910,7 @@ H5C_resize_pinned_entry(H5C_t * cache_ptr,
/* update the hash table */
H5C__UPDATE_INDEX_FOR_SIZE_CHANGE((cache_ptr), (entry_ptr->size),\
- (new_size));
+ (new_size), (entry_ptr), (was_clean));
/* if the entry is in the skip list, update that too */
if ( entry_ptr->in_slist ) {
@@ -5686,8 +5925,13 @@ H5C_resize_pinned_entry(H5C_t * cache_ptr,
/* finally, update the entry size proper */
entry_ptr->size = new_size;
+
+ } else if ( was_clean ) {
+
+ H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY(cache_ptr, entry_ptr)
}
+
if ( ! (entry_ptr->in_slist) ) {
H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, FAIL)
@@ -5703,6 +5947,56 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5C_pin_entry_from_client()
+ *
+ * Purpose: Internal routine to pin a cache entry from a client action.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * 3/26/09
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef NDEBUG
+static herr_t
+H5C_pin_entry_from_client(H5C_t * cache_ptr,
+ H5C_cache_entry_t * entry_ptr)
+#else
+static herr_t
+H5C_pin_entry_from_client(H5C_t UNUSED * cache_ptr,
+ H5C_cache_entry_t * entry_ptr)
+#endif
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5C_pin_entry_from_client)
+
+ /* Sanity checks */
+ HDassert( cache_ptr );
+ HDassert( entry_ptr );
+
+ /* Check if the entry is already pinned */
+ if(entry_ptr->is_pinned) {
+ /* Check if the entry was pinned through an explicit pin from a client */
+ if(entry_ptr->pinned_from_client)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "Entry is already pinned")
+ } /* end if */
+ else {
+ entry_ptr->is_pinned = TRUE;
+
+ H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr)
+ } /* end else */
+
+ /* Mark that the entry was pinned through an explicit pin from a client */
+ entry_ptr->pinned_from_client = TRUE;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5C_pin_entry_from_client() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5C_pin_protected_entry()
*
* Purpose: Pin a protected cache entry. The entry must be protected
@@ -5720,57 +6014,42 @@ done:
* entries.
*
* JRM -- 2/16/07
- * Added conditional compile to avoid unused parameter
+ * Added conditional compile to avoid unused parameter
* warning in production compile.
*
* JRM -- 4/4/07
- * Fixed typo -- canged macro call to
- * H5C__UPDATE_STATS_FOR_UNPIN to call to
+ * Fixed typo -- canged macro call to
+ * H5C__UPDATE_STATS_FOR_UNPIN to call to
* H5C__UPDATE_STATS_FOR_PIN.
*
*-------------------------------------------------------------------------
*/
-#ifndef NDEBUG
herr_t
H5C_pin_protected_entry(H5C_t * cache_ptr,
void * thing)
-#else
-herr_t
-H5C_pin_protected_entry(H5C_t UNUSED * cache_ptr,
- void * thing)
-#endif
{
+ H5C_cache_entry_t * entry_ptr; /* Pointer to entry to pin */
herr_t ret_value = SUCCEED; /* Return value */
- H5C_cache_entry_t * entry_ptr;
FUNC_ENTER_NOAPI(H5C_pin_protected_entry, FAIL)
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
HDassert( thing );
-
entry_ptr = (H5C_cache_entry_t *)thing;
-
+ HDassert( entry_ptr );
HDassert( H5F_addr_defined(entry_ptr->addr) );
- if ( ! ( entry_ptr->is_protected ) ) {
-
+ /* Only protected entries can be pinned */
+ if(!entry_ptr->is_protected)
HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "Entry isn't protected")
- }
-
- if ( entry_ptr->is_pinned ) {
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "Entry is already pinned")
- }
-
- entry_ptr->is_pinned = TRUE;
-
- H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr)
+ /* Pin the entry from a client */
+ if(H5C_pin_entry_from_client(cache_ptr, entry_ptr) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "Can't pin entry by client")
done:
-
FUNC_LEAVE_NOAPI(ret_value)
-
} /* H5C_pin_protected_entry() */
@@ -5839,12 +6118,12 @@ done:
*
* JRM -- 6/23/06
* Modified code to allow dirty entries to be loaded from
- * disk. This is necessary as a bug fix in the object
+ * disk. This is necessary as a bug fix in the object
* header code requires us to modify a header as it is read.
*
* JRM -- 3/28/07
* Added the flags parameter and supporting code. At least
- * for now, this parameter is used to allow the entry to
+ * for now, this parameter is used to allow the entry to
* be protected read only, thus allowing multiple protects.
*
* Also added code to allow multiple read only protects
@@ -5855,9 +6134,25 @@ done:
* in H5C_t.
*
* JRM -- 1/3/08
- * Added to do a flash cache size increase if appropriate
+ * Added to do a flash cache size increase if appropriate
* when a large entry is loaded.
*
+ * JRM -- 11/13/08
+ * Modified function to call H5C_make_space_in_cache() when
+ * the min_clean_size is violated, not just when there isn't
+ * enough space for and entry that has just been loaded.
+ *
+ * The purpose of this modification is to avoid "metadata
+ * blizzards" in the write only case. In such instances,
+ * the cache was allowed to fill with dirty metadata. When
+ * we finally needed to evict an entry to make space, we had
+ * to flush out a whole cache full of metadata -- which has
+ * interesting performance effects. We hope to avoid (or
+ * perhaps more accurately hide) this effect by maintaining
+ * the min_clean_size, which should force us to start flushing
+ * entries long before we actually have to evict something
+ * to make space.
+ *
*-------------------------------------------------------------------------
*/
@@ -5879,6 +6174,7 @@ H5C_protect(H5F_t * f,
hbool_t read_only = FALSE;
hbool_t write_permitted;
herr_t result;
+ size_t empty_space;
void * thing;
H5C_cache_entry_t * entry_ptr;
void * ret_value; /* Return value */
@@ -5913,6 +6209,10 @@ H5C_protect(H5F_t * f,
if ( entry_ptr != NULL ) {
+ /* Check for trying to load the wrong type of entry from an address */
+ if(entry_ptr->type != type)
+ HGOTO_ERROR(H5E_CACHE, H5E_BADTYPE, NULL, "incorrect cache entry type")
+
hit = TRUE;
thing = (void *)entry_ptr;
@@ -5936,7 +6236,7 @@ H5C_protect(H5F_t * f,
if ( ( cache_ptr->flash_size_increase_possible ) &&
( entry_ptr->size > cache_ptr->flash_size_increase_threshold ) ) {
- result = H5C__flash_increase_cache_size(cache_ptr, 0,
+ result = H5C__flash_increase_cache_size(cache_ptr, 0,
entry_ptr->size);
if ( result < 0 ) {
@@ -5946,16 +6246,41 @@ H5C_protect(H5F_t * f,
}
}
- /* try to free up some space if necessary and if evictions are
- * permitted
+ if ( cache_ptr->index_size >= cache_ptr->max_cache_size ) {
+
+ empty_space = 0;
+
+ } else {
+
+ empty_space = cache_ptr->max_cache_size - cache_ptr->index_size;
+
+ }
+
+ /* try to free up if necceary and if evictions are permitted. Note
+ * that if evictions are enabled, we will call H5C_make_space_in_cache()
+ * regardless if the min_free_space requirement is not met.
*/
- if ( ( cache_ptr->evictions_enabled ) &&
- ( (cache_ptr->index_size + entry_ptr->size) >
- cache_ptr->max_cache_size ) ) {
+
+ if ( ( cache_ptr->evictions_enabled )
+ &&
+ ( ( (cache_ptr->index_size + entry_ptr->size) >
+ cache_ptr->max_cache_size
+ )
+ ||
+ (
+ ( ( empty_space + cache_ptr->clean_index_size ) <
+ cache_ptr->min_clean_size )
+ )
+ )
+ ) {
size_t space_needed;
- cache_ptr->cache_full = TRUE;
+ if ( empty_space <= entry_ptr->size ) {
+
+ cache_ptr->cache_full = TRUE;
+
+ }
if ( cache_ptr->check_write_permitted != NULL ) {
@@ -6048,6 +6373,13 @@ H5C_protect(H5F_t * f,
* code. If we do this often enough, we may want to optimize this.
*/
H5C__UPDATE_RP_FOR_INSERTION(cache_ptr, entry_ptr, NULL)
+
+ /* If the entry's type has a 'notify' callback send a 'after insertion'
+ * notice now that the entry is fully integrated into the cache.
+ */
+ if(entry_ptr->type->notify &&
+ (entry_ptr->type->notify)(H5C_NOTIFY_ACTION_AFTER_INSERT, entry_ptr) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, NULL, "can't notify client about entry inserted into cache")
}
HDassert( entry_ptr->addr == addr );
@@ -6056,7 +6388,7 @@ H5C_protect(H5F_t * f,
if ( entry_ptr->is_protected ) {
if ( ( read_only ) && ( entry_ptr->is_read_only ) ) {
-
+
HDassert( entry_ptr->ro_ref_count > 0 );
(entry_ptr->ro_ref_count)++;
@@ -6146,10 +6478,31 @@ H5C_protect(H5F_t * f,
/* check to see if the cache is now oversized due to the cache
* size reduction. If it is, try to evict enough entries to
* bring the cache size down to the current maximum cache size.
+ *
+ * Also, if the min_clean_size requirement is not met, we
+ * should also call H5C_make_space_in_cache() to bring us
+ * into complience.
*/
- if ( cache_ptr->index_size > cache_ptr->max_cache_size ) {
- cache_ptr->cache_full = TRUE;
+ if ( cache_ptr->index_size >= cache_ptr->max_cache_size ) {
+
+ empty_space = 0;
+
+ } else {
+
+ empty_space = cache_ptr->max_cache_size - cache_ptr->index_size;
+
+ }
+
+ if ( ( cache_ptr->index_size > cache_ptr->max_cache_size )
+ ||
+ ( ( empty_space + cache_ptr->clean_index_size ) <
+ cache_ptr->min_clean_size) ) {
+
+ if ( cache_ptr->index_size > cache_ptr->max_cache_size ) {
+
+ cache_ptr->cache_full = TRUE;
+ }
result = H5C_make_space_in_cache(f, primary_dxpl_id,
secondary_dxpl_id, cache_ptr,
@@ -6316,8 +6669,8 @@ H5C_set_cache_auto_resize_config(H5C_t * cache_ptr,
/* will set the increase possible fields to FALSE later if needed */
cache_ptr->size_increase_possible = TRUE;
- cache_ptr->flash_size_increase_possible = TRUE;
- cache_ptr->size_decrease_possible = TRUE;
+ cache_ptr->flash_size_increase_possible = TRUE;
+ cache_ptr->size_decrease_possible = TRUE;
switch ( config_ptr->incr_mode )
{
@@ -6340,7 +6693,7 @@ H5C_set_cache_auto_resize_config(H5C_t * cache_ptr,
}
/* logically, this is were configuration for flash cache size increases
- * should go. However, this configuration depends on max_cache_size, so
+ * should go. However, this configuration depends on max_cache_size, so
* we wait until the end of the function, when this field is set.
*/
@@ -6388,7 +6741,7 @@ H5C_set_cache_auto_resize_config(H5C_t * cache_ptr,
if ( config_ptr->max_size == config_ptr->min_size ) {
cache_ptr->size_increase_possible = FALSE;
- cache_ptr->flash_size_increase_possible = FALSE;
+ cache_ptr->flash_size_increase_possible = FALSE;
cache_ptr->size_decrease_possible = FALSE;
}
@@ -6483,7 +6836,7 @@ H5C_set_cache_auto_resize_config(H5C_t * cache_ptr,
}
/* configure flash size increase facility. We wait until the
- * end of the function, as we need the max_cache_size set before
+ * end of the function, as we need the max_cache_size set before
* we start to keep things simple.
*
* If we haven't already ruled out flash cache size increases above,
@@ -6495,12 +6848,12 @@ H5C_set_cache_auto_resize_config(H5C_t * cache_ptr,
switch ( config_ptr->flash_incr_mode )
{
case H5C_flash_incr__off:
- cache_ptr->flash_size_increase_possible = FALSE;
+ cache_ptr->flash_size_increase_possible = FALSE;
break;
case H5C_flash_incr__add_space:
- cache_ptr->flash_size_increase_possible = TRUE;
- cache_ptr->flash_size_increase_threshold =
+ cache_ptr->flash_size_increase_possible = TRUE;
+ cache_ptr->flash_size_increase_threshold =
(size_t)
(((double)(cache_ptr->max_cache_size)) *
((cache_ptr->resize_ctl).flash_threshold));
@@ -6511,7 +6864,7 @@ H5C_set_cache_auto_resize_config(H5C_t * cache_ptr,
"Unknown flash_incr_mode?!?!?.")
break;
}
- }
+ }
done:
@@ -6523,7 +6876,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5C_set_evictions_enabled()
*
- * Purpose: Set cache_ptr->evictions_enabled to the value of the
+ * Purpose: Set cache_ptr->evictions_enabled to the value of the
* evictions enabled parameter.
*
* Return: SUCCEED on success, and FAIL on failure.
@@ -6557,9 +6910,9 @@ H5C_set_evictions_enabled(H5C_t * cache_ptr,
"Bad evictions_enabled on entry.")
}
- /* There is no fundamental reason why we should not permit
+ /* There is no fundamental reason why we should not permit
* evictions to be disabled while automatic resize is enabled.
- * However, I can't think of any good reason why one would
+ * However, I can't think of any good reason why one would
* want to, and allowing it would greatly complicate testing
* the feature. Hence the following:
*/
@@ -6743,10 +7096,19 @@ done:
* JRM -- 8/23/06
* Added code supporting new flush related statistics.
*
- * JRM -- 3/31/07
- * Added code supporting the new write_protects,
+ * JRM -- 3/31/07
+ * Added code supporting the new write_protects,
* read_protects, and max_read_protects fields.
*
+ * JRM -- 11/13/08
+ * Added code displaying the max_clean_index_size and
+ * max_dirty_index_size.
+ *
+ * MAM -- 01/06/09
+ * Added code displaying the calls_to_msic,
+ * total_entries_skipped_in_msic, total_entries_scanned_in_msic,
+ * and max_entries_skipped_in_msic fields.
+ *
*-------------------------------------------------------------------------
*/
@@ -6794,6 +7156,8 @@ H5C_stats(H5C_t * cache_ptr,
double hit_rate;
double average_successful_search_depth = 0.0;
double average_failed_search_depth = 0.0;
+ double average_entries_skipped_per_calls_to_msic = 0.0;
+ double average_entries_scanned_per_calls_to_msic = 0.0;
#endif /* H5C_COLLECT_CACHE_STATS */
FUNC_ENTER_NOAPI(H5C_stats, FAIL)
@@ -6831,9 +7195,9 @@ H5C_stats(H5C_t * cache_ptr,
+= cache_ptr->cache_flush_renames[i];
total_size_increases += cache_ptr->size_increases[i];
total_size_decreases += cache_ptr->size_decreases[i];
- total_entry_flush_size_changes
+ total_entry_flush_size_changes
+= cache_ptr->entry_flush_size_changes[i];
- total_cache_flush_size_changes
+ total_cache_flush_size_changes
+= cache_ptr->cache_flush_size_changes[i];
total_pins += cache_ptr->pins[i];
total_unpins += cache_ptr->unpins[i];
@@ -6913,6 +7277,14 @@ H5C_stats(H5C_t * cache_ptr,
(long)(cache_ptr->max_index_len));
HDfprintf(stdout,
+ "%s current (max) clean/dirty idx size = %ld (%ld) / %ld (%ld)\n",
+ cache_ptr->prefix,
+ (long)(cache_ptr->clean_index_size),
+ (long)(cache_ptr->max_clean_index_size),
+ (long)(cache_ptr->dirty_index_size),
+ (long)(cache_ptr->max_dirty_index_size));
+
+ HDfprintf(stdout,
"%s current (max) slist size / length = %ld (%ld) / %ld (%ld)\n",
cache_ptr->prefix,
(long)(cache_ptr->slist_size),
@@ -6975,14 +7347,14 @@ H5C_stats(H5C_t * cache_ptr,
(long)total_flushes,
(long)total_evictions);
- HDfprintf(stdout,
+ HDfprintf(stdout,
"%s Total insertions(pinned) / renames = %ld(%ld) / %ld\n",
cache_ptr->prefix,
(long)total_insertions,
(long)total_pinned_insertions,
(long)total_renames);
- HDfprintf(stdout,
+ HDfprintf(stdout,
"%s Total entry / cache flush renames = %ld / %ld\n",
cache_ptr->prefix,
(long)total_entry_flush_renames,
@@ -7010,6 +7382,41 @@ H5C_stats(H5C_t * cache_ptr,
(long)total_pinned_flushes,
(long)total_pinned_clears);
+ HDfprintf(stdout, "%s MSIC: (make space in cache) calls = %lld\n",
+ cache_ptr->prefix,
+ (long long)(cache_ptr->calls_to_msic));
+
+ if (cache_ptr->calls_to_msic > 0) {
+ average_entries_skipped_per_calls_to_msic =
+ (((double)(cache_ptr->total_entries_skipped_in_msic)) /
+ ((double)(cache_ptr->calls_to_msic)));
+ }
+
+ HDfprintf(stdout, "%s MSIC: Average/max entries skipped = %lf / %ld\n",
+ cache_ptr->prefix,
+ (float)average_entries_skipped_per_calls_to_msic,
+ (long)(cache_ptr->max_entries_skipped_in_msic));
+
+ if (cache_ptr->calls_to_msic > 0) {
+ average_entries_scanned_per_calls_to_msic =
+ (((double)(cache_ptr->total_entries_scanned_in_msic)) /
+ ((double)(cache_ptr->calls_to_msic)));
+ }
+
+ HDfprintf(stdout, "%s MSIC: Average/max entries scanned = %lf / %ld\n",
+ cache_ptr->prefix,
+ (float)average_entries_scanned_per_calls_to_msic,
+ (long)(cache_ptr->max_entries_scanned_in_msic));
+
+ HDfprintf(stdout, "%s MSIC: Scanned to make space(evict) = %lld\n",
+ cache_ptr->prefix,
+ (long long)(cache_ptr->entries_scanned_to_make_space));
+
+ HDfprintf(stdout, "%s MSIC: Scanned to satisfy min_clean = %lld\n",
+ cache_ptr->prefix,
+ (long long)(cache_ptr->total_entries_scanned_in_msic -
+ cache_ptr->entries_scanned_to_make_space));
+
#if H5C_COLLECT_CACHE_ENTRY_STATS
HDfprintf(stdout, "%s aggregate max / min accesses = %d / %d\n",
@@ -7164,7 +7571,7 @@ done:
* JRM - 3/20/06
* Updated for pin / unpin related statistics.
*
- * JRM - 8/9/06
+ * JRM - 8/9/06
* Further updates for pin related statistics.
*
* JRM 8/23/06
@@ -7175,9 +7582,18 @@ done:
* warning in the production build.
*
* JRM 3/31/07
- * Added initialization for the new write_protects,
+ * Added initialization for the new write_protects,
* read_protects, and max_read_protects fields.
*
+ * JRM 11/13/08
+ * Added initialization for the new max_clean_index_size and
+ * max_dirty_index_size fields.
+ *
+ * MAM -- 01/06/09
+ * Added code to initalize the calls_to_msic,
+ * total_entries_skipped_in_msic, total_entries_scanned_in_msic,
+ * and max_entries_skipped_in_msic fields.
+ *
*-------------------------------------------------------------------------
*/
@@ -7235,6 +7651,8 @@ H5C_stats__reset(H5C_t UNUSED * cache_ptr)
cache_ptr->max_index_len = 0;
cache_ptr->max_index_size = (size_t)0;
+ cache_ptr->max_clean_index_size = (size_t)0;
+ cache_ptr->max_dirty_index_size = (size_t)0;
cache_ptr->max_slist_len = 0;
cache_ptr->max_slist_size = (size_t)0;
@@ -7245,6 +7663,13 @@ H5C_stats__reset(H5C_t UNUSED * cache_ptr)
cache_ptr->max_pel_len = 0;
cache_ptr->max_pel_size = (size_t)0;
+ cache_ptr->calls_to_msic = 0;
+ cache_ptr->total_entries_skipped_in_msic = 0;
+ cache_ptr->total_entries_scanned_in_msic = 0;
+ cache_ptr->max_entries_skipped_in_msic = 0;
+ cache_ptr->max_entries_scanned_in_msic = 0;
+ cache_ptr->entries_scanned_to_make_space = 0;
+
#if H5C_COLLECT_CACHE_ENTRY_STATS
for ( i = 0; i <= cache_ptr->max_type_id; i++ )
@@ -7266,57 +7691,92 @@ H5C_stats__reset(H5C_t UNUSED * cache_ptr)
/*-------------------------------------------------------------------------
+ * Function: H5C_unpin_entry_from_client()
+ *
+ * Purpose: Internal routine to unpin a cache entry from a client action.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * 3/24/09
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5C_unpin_entry_from_client(H5C_t * cache_ptr,
+ H5C_cache_entry_t * entry_ptr,
+ hbool_t update_rp)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5C_unpin_entry_from_client)
+
+ /* Sanity checking */
+ HDassert( cache_ptr );
+ HDassert( entry_ptr );
+
+ /* Error checking (should be sanity checks?) */
+ if(!entry_ptr->is_pinned)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "Entry isn't pinned")
+ if(!entry_ptr->pinned_from_client)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "Entry wasn't pinned by cache client")
+
+ /* Check if the entry is not pinned from a flush dependency */
+ if(!entry_ptr->pinned_from_cache) {
+ /* If requested, update the replacement policy if the entry is not protected */
+ if(update_rp && !entry_ptr->is_protected)
+ H5C__UPDATE_RP_FOR_UNPIN(cache_ptr, entry_ptr, FAIL)
+
+ /* Unpin the entry now */
+ entry_ptr->is_pinned = FALSE;
+
+ /* Update the stats for an unpin operation */
+ H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, entry_ptr)
+ } /* end if */
+
+ /* Mark the entry as explicitly unpinned by the client */
+ entry_ptr->pinned_from_client = FALSE;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5C_unpin_entry_from_client() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5C_unpin_entry()
*
- * Purpose: Unpin a cache entry. The entry must be unprotected at
- * the time of call, and must be pinned.
+ * Purpose: Unpin a cache entry. The entry can be either protected or
+ * unprotected at the time of call, but must be pinned.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: John Mainzer
* 3/22/06
*
- * Modifications:
- *
- * JRM -- 4/26/06
- * Modified routine to allow it to operate on protected
- * entries.
- *
*-------------------------------------------------------------------------
*/
herr_t
H5C_unpin_entry(H5C_t * cache_ptr,
void * thing)
{
+ H5C_cache_entry_t * entry_ptr; /* Pointer to entry to unpin */
herr_t ret_value = SUCCEED; /* Return value */
- H5C_cache_entry_t * entry_ptr;
FUNC_ENTER_NOAPI(H5C_unpin_entry, FAIL)
+ /* Sanity checking */
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
HDassert( thing );
-
entry_ptr = (H5C_cache_entry_t *)thing;
+ HDassert( entry_ptr );
- if ( ! ( entry_ptr->is_pinned ) ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "Entry isn't pinned")
- }
-
- if ( ! ( entry_ptr->is_protected ) ) {
-
- H5C__UPDATE_RP_FOR_UNPIN(cache_ptr, entry_ptr, FAIL)
- }
-
- entry_ptr->is_pinned = FALSE;
-
- H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, entry_ptr)
+ /* Unpin the entry */
+ if(H5C_unpin_entry_from_client(cache_ptr, entry_ptr, TRUE) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "Can't unpin entry from client")
done:
-
FUNC_LEAVE_NOAPI(ret_value)
-
} /* H5C_unpin_entry() */
@@ -7406,14 +7866,33 @@ done:
* equivalent of setting the H5C__DIRTIED_FLAG.
*
* JRM -- 3/29/07
- * Modified function to allow a entry to be protected
+ * Modified function to allow a entry to be protected
* more than once if the entry is protected read only.
*
* Also added sanity checks using the new is_read_only and
* ro_ref_count parameters.
*
* JRM -- 12/31/07
- * Modified funtion to support flash cache resizes.
+ * Modified function to support flash cache resizes.
+ *
+ * QAK -- 1/31/08
+ * Modified function to support freeing file space in client's
+ * 'dest' callback routine.
+ *
+ * QAK -- 2/07/08
+ * Separated "destroy entry" concept from "remove entry from
+ * cache" concept, by adding the 'take_ownership' flag.
+ *
+ * JRM -- 11/5/08
+ * Added code to update the clean_index_size and
+ * dirty_index_size fields of H5C_t in cases where the
+ * the entry was clean on protect, was marked dirty on
+ * unprotect, and did not change its size. Do this via
+ * a call to H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY().
+ *
+ * If the size changed, this case is already dealt with by
+ * by the pre-existing call to
+ * H5C__UPDATE_INDEX_FOR_SIZE_CHANGE().
*
*-------------------------------------------------------------------------
*/
@@ -7428,13 +7907,15 @@ H5C_unprotect(H5F_t * f,
unsigned int flags,
size_t new_size)
{
- /* const char * fcn_name = "H5C_unprotect()"; */
hbool_t deleted;
hbool_t dirtied;
hbool_t set_flush_marker;
hbool_t size_changed;
hbool_t pin_entry;
hbool_t unpin_entry;
+ hbool_t free_file_space;
+ hbool_t take_ownership;
+ hbool_t was_clean;
#ifdef H5_HAVE_PARALLEL
hbool_t clear_entry = FALSE;
#endif /* H5_HAVE_PARALLEL */
@@ -7452,6 +7933,8 @@ H5C_unprotect(H5F_t * f,
size_changed = ( (flags & H5C__SIZE_CHANGED_FLAG) != 0 );
pin_entry = ( (flags & H5C__PIN_ENTRY_FLAG) != 0 );
unpin_entry = ( (flags & H5C__UNPIN_ENTRY_FLAG) != 0 );
+ free_file_space = ( (flags & H5C__FREE_FILE_SPACE_FLAG) != 0 );
+ take_ownership = ( (flags & H5C__TAKE_OWNERSHIP_FLAG) != 0 );
/* Changing the size of an entry dirties it. Thus, set the
* dirtied flag if the size_changed flag is set.
@@ -7471,6 +7954,9 @@ H5C_unprotect(H5F_t * f,
HDassert( ( ! size_changed ) || ( dirtied ) );
HDassert( ( ! size_changed ) || ( new_size > 0 ) );
HDassert( ! ( pin_entry && unpin_entry ) );
+ HDassert( ( ! free_file_space ) || ( deleted ) ); /* deleted flag must accompany free_file_space */
+ HDassert( ( ! take_ownership ) || ( deleted ) ); /* deleted flag must accompany take_ownership */
+ HDassert( ! ( free_file_space && take_ownership ) ); /* can't have both free_file_space & take_ownership */
entry_ptr = (H5C_cache_entry_t *)thing;
@@ -7481,6 +7967,7 @@ H5C_unprotect(H5F_t * f,
* the entry.
*/
dirtied |= entry_ptr->dirtied;
+ was_clean = ! ( entry_ptr->is_dirty );
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
@@ -7511,23 +7998,15 @@ H5C_unprotect(H5F_t * f,
/* Pin or unpin the entry as requested. */
if ( pin_entry ) {
- if ( entry_ptr->is_pinned ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, \
- "Entry already pinned???")
- }
- entry_ptr->is_pinned = TRUE;
- H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr)
+ /* Pin the entry from a client */
+ if(H5C_pin_entry_from_client(cache_ptr, entry_ptr) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "Can't pin entry by client")
} else if ( unpin_entry ) {
- if ( ! ( entry_ptr->is_pinned ) ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, \
- "Entry already unpinned???")
- }
- entry_ptr->is_pinned = FALSE;
- H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, entry_ptr)
+ /* Unpin the entry from a client */
+ if(H5C_unpin_entry_from_client(cache_ptr, entry_ptr, FALSE) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "Can't unpin entry by client")
}
@@ -7595,10 +8074,10 @@ H5C_unprotect(H5F_t * f,
size_increase = new_size - entry_ptr->size;
- if ( size_increase >=
+ if ( size_increase >=
cache_ptr->flash_size_increase_threshold ) {
- result = H5C__flash_increase_cache_size(cache_ptr,
+ result = H5C__flash_increase_cache_size(cache_ptr,
entry_ptr->size,
new_size);
@@ -7617,8 +8096,9 @@ H5C_unprotect(H5F_t * f,
(entry_ptr->size), (new_size));
/* update the hash table */
- H5C__UPDATE_INDEX_FOR_SIZE_CHANGE((cache_ptr), (entry_ptr->size),\
- (new_size));
+ H5C__UPDATE_INDEX_FOR_SIZE_CHANGE((cache_ptr), (entry_ptr->size), \
+ (new_size), (entry_ptr), \
+ (was_clean));
/* if the entry is in the skip list, update that too */
if ( entry_ptr->in_slist ) {
@@ -7634,28 +8114,24 @@ H5C_unprotect(H5F_t * f,
/* finally, update the entry size proper */
entry_ptr->size = new_size;
- }
+
+ } else if ( ( was_clean ) && ( entry_ptr->is_dirty ) ) {
+
+ H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY(cache_ptr, entry_ptr)
+ }
/* Pin or unpin the entry as requested. */
if ( pin_entry ) {
- if ( entry_ptr->is_pinned ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, \
- "Entry already pinned???")
- }
- entry_ptr->is_pinned = TRUE;
- H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr)
+ /* Pin the entry from a client */
+ if(H5C_pin_entry_from_client(cache_ptr, entry_ptr) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "Can't pin entry by client")
} else if ( unpin_entry ) {
- if ( ! ( entry_ptr->is_pinned ) ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, \
- "Entry already unpinned???")
- }
- entry_ptr->is_pinned = FALSE;
- H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, entry_ptr)
+ /* Unpin the entry from a client */
+ if(H5C_unpin_entry_from_client(cache_ptr, entry_ptr, FALSE) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "Can't unpin entry by client")
}
@@ -7696,7 +8172,9 @@ H5C_unprotect(H5F_t * f,
* H5C__FLUSH_CLEAR_ONLY_FLAG and H5C__FLUSH_INVALIDATE_FLAG flags.
* However, it is needed for the function call.
*/
- hbool_t dummy_first_flush = TRUE;
+ hbool_t dummy_first_flush = TRUE;
+ unsigned flush_flags = (H5C__FLUSH_CLEAR_ONLY_FLAG |
+ H5C__FLUSH_INVALIDATE_FLAG);
/* we can't delete a pinned entry */
HDassert ( ! (entry_ptr->is_pinned ) );
@@ -7716,14 +8194,23 @@ H5C_unprotect(H5F_t * f,
"hash table contains multiple entries for addr?!?.")
}
+ /* Pass along 'free file space' flag to cache client */
+
+ entry_ptr->free_file_space_on_destroy = free_file_space;
+
+ /* Set the "take ownership" flag for the flush, if needed */
+ if ( take_ownership) {
+
+ flush_flags |= H5C__TAKE_OWNERSHIP_FLAG;
+ }
+
if ( H5C_flush_single_entry(f,
primary_dxpl_id,
secondary_dxpl_id,
cache_ptr,
type,
addr,
- (H5C__FLUSH_CLEAR_ONLY_FLAG |
- H5C__FLUSH_INVALIDATE_FLAG),
+ flush_flags,
&dummy_first_flush,
TRUE) < 0 ) {
@@ -7734,8 +8221,8 @@ H5C_unprotect(H5F_t * f,
else if ( clear_entry ) {
/* the following first flush flag will never be used as we are
- * calling H5C_flush_single_entry with the
- * H5C__FLUSH_CLEAR_ONLY_FLAG flag. However, it is needed for
+ * calling H5C_flush_single_entry with the
+ * H5C__FLUSH_CLEAR_ONLY_FLAG flag. However, it is needed for
* the function call.
*/
hbool_t dummy_first_flush = TRUE;
@@ -8053,6 +8540,354 @@ done:
} /* H5C_validate_resize_config() */
+/*-------------------------------------------------------------------------
+ * Function: H5C_adjust_flush_dependency_rc()
+ *
+ * Purpose: "Atomicly" adjust flush dependency ref. counts for an entry,
+ * as a result of a flush dependency child's height changing.
+ *
+ * Note: Entry will remain in flush dependency relationship with its
+ * child entry (i.e. it's not going to get unpinned as a result
+ * of this change), but change could trickle upward, if this
+ * entry's height changes and it has a flush dependency parent.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * 3/05/09
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+H5C_adjust_flush_dependency_rc(H5C_cache_entry_t * cache_entry,
+ unsigned old_child_height, unsigned new_child_height)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5C_adjust_flush_dependency_rc)
+
+ /* Sanity checks */
+ HDassert(cache_entry);
+ HDassert(cache_entry->is_pinned);
+ HDassert(cache_entry->flush_dep_height > 0);
+ HDassert(cache_entry->flush_dep_height < H5C__NUM_FLUSH_DEP_HEIGHTS);
+ HDassert(cache_entry->child_flush_dep_height_rc[old_child_height] > 0);
+ HDassert(old_child_height < H5C__NUM_FLUSH_DEP_HEIGHTS);
+ HDassert(old_child_height != new_child_height);
+ HDassert(new_child_height < H5C__NUM_FLUSH_DEP_HEIGHTS);
+
+ /* Adjust ref. counts for entry's flush dependency children heights */
+ cache_entry->child_flush_dep_height_rc[new_child_height]++;
+ cache_entry->child_flush_dep_height_rc[old_child_height]--;
+
+ /* Check for flush dependency height of entry increasing */
+ if((new_child_height + 1) > cache_entry->flush_dep_height) {
+
+ /* Check if entry has _its_ own parent flush dependency entry */
+ if(NULL != cache_entry->flush_dep_parent) {
+ /* Adjust flush dependency ref. counts on entry's parent */
+ H5C_adjust_flush_dependency_rc(cache_entry->flush_dep_parent, cache_entry->flush_dep_height, new_child_height + 1);
+ } /* end if */
+
+ /* Set new flush dependency height of entry */
+ cache_entry->flush_dep_height = new_child_height + 1;
+ } /* end if */
+ else {
+ /* Check for child's flush dep. height decreasing and ref. count of
+ * old child height going to zero, it could mean the parent's
+ * flush dependency height dropped.
+ */
+ if((new_child_height < old_child_height)
+ && ((old_child_height + 1) == cache_entry->flush_dep_height)
+ && (0 == cache_entry->child_flush_dep_height_rc[old_child_height])) {
+ int i; /* Local index variable */
+
+ /* Re-scan child flush dependency height ref. counts to determine
+ * this entry's height.
+ */
+#ifndef NDEBUG
+ for(i = (H5C__NUM_FLUSH_DEP_HEIGHTS - 1); i > (int)new_child_height; i--)
+ HDassert(0 == cache_entry->child_flush_dep_height_rc[i]);
+#endif /* NDEBUG */
+ for(i = (int)new_child_height; i >= 0; i--)
+ /* Check for child flush dependencies of this height */
+ if(cache_entry->child_flush_dep_height_rc[i] > 0)
+ break;
+
+ /* Sanity checks */
+ HDassert((unsigned)(i + 1) < cache_entry->flush_dep_height);
+
+ /* Check if entry has _its_ own parent flush dependency entry */
+ if(NULL != cache_entry->flush_dep_parent) {
+ /* Adjust flush dependency ref. counts on entry's parent */
+ H5C_adjust_flush_dependency_rc(cache_entry->flush_dep_parent, cache_entry->flush_dep_height, (unsigned)(i + 1));
+ } /* end if */
+
+ /* Set new flush dependency height of entry */
+ cache_entry->flush_dep_height = (unsigned)(i + 1);
+ } /* end if */
+ } /* end else */
+
+
+ /* Post-conditions, for successful operation */
+ HDassert(cache_entry->is_pinned);
+ HDassert(cache_entry->flush_dep_height > 0);
+ HDassert(cache_entry->flush_dep_height <= H5C__NUM_FLUSH_DEP_HEIGHTS);
+ HDassert(cache_entry->child_flush_dep_height_rc[new_child_height] > 0);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* H5C_adjust_flush_dependency_rc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5C_create_flush_dependency()
+ *
+ * Purpose: Initiates a parent<->child entry flush dependency. The parent
+ * entry must be protected at the time of call, and must have all
+ * dependencies removed before the cache can shut down.
+ *
+ * Note: Flush dependencies in the cache indicate that a child entry
+ * must be flushed to the file before its parent. (This is
+ * currently used to implement Single-Writer/Multiple-Reader (SWMR)
+ * I/O access for data structures in the file).
+ *
+ * Each child entry can have only one parent entry, but parent
+ * entries can have >1 child entries. The flush dependency
+ * height of a parent entry is one greater than the max. flush
+ * dependency height of its children.
+ *
+ * Creating a flush dependency between two entries will also pin
+ * the parent entry. (The parent entry must _not_ be pinned
+ * through some other mechanism)
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * 3/05/09
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef NDEBUG
+herr_t
+H5C_create_flush_dependency(H5C_t * cache_ptr, void * parent_thing,
+ void * child_thing)
+#else
+herr_t
+H5C_create_flush_dependency(H5C_t UNUSED * cache_ptr, void * parent_thing,
+ void * child_thing)
+#endif
+{
+ H5C_cache_entry_t * parent_entry = (H5C_cache_entry_t *)parent_thing; /* Ptr to parent thing's entry */
+ H5C_cache_entry_t * child_entry = (H5C_cache_entry_t *)child_thing; /* Ptr to child thing's entry */
+#ifndef NDEBUG
+ unsigned prev_flush_dep_height = parent_entry->flush_dep_height; /* Previous flush height for parent entry */
+#endif /* NDEBUG */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5C_create_flush_dependency, FAIL)
+
+ /* Sanity checks */
+ HDassert(cache_ptr);
+ HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
+ HDassert(parent_entry);
+ HDassert(parent_entry->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
+ HDassert(parent_entry->flush_dep_height <= H5C__NUM_FLUSH_DEP_HEIGHTS);
+ HDassert(H5F_addr_defined(parent_entry->addr));
+ HDassert(child_entry);
+ HDassert(child_entry->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
+ HDassert(H5F_addr_defined(child_entry->addr));
+ HDassert(child_entry->flush_dep_height <= H5C__NUM_FLUSH_DEP_HEIGHTS);
+
+ /* More sanity checks */
+ if(child_entry == parent_entry)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "Child entry flush dependency parent can't be itself")
+ if(!(parent_entry->is_protected || parent_entry->is_pinned))
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "Parent entry isn't pinned or protected")
+ if(NULL != child_entry->flush_dep_parent)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "Child entry already has flush dependency parent")
+ {
+ H5C_cache_entry_t *tmp_entry = parent_entry; /* Temporary cache entry in flush dependency chain */
+ unsigned tmp_flush_height = 0; /* Different in heights of parent entry */
+
+ /* Find the top entry in the flush dependency list */
+ while(NULL != tmp_entry->flush_dep_parent) {
+ tmp_flush_height++;
+ tmp_entry = tmp_entry->flush_dep_parent;
+ } /* end while */
+
+ /* Check if we will make the dependency chain too long */
+ if((tmp_flush_height + child_entry->flush_dep_height + 1)
+ > H5C__NUM_FLUSH_DEP_HEIGHTS)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "Combined flush dependency height too large")
+ }
+
+ /* Check for parent not pinned */
+ if(!parent_entry->is_pinned) {
+ /* Sanity check */
+ HDassert(parent_entry->flush_dep_height == 0);
+ HDassert(!parent_entry->pinned_from_client);
+ HDassert(!parent_entry->pinned_from_cache);
+
+ /* Pin the parent entry */
+ parent_entry->is_pinned = TRUE;
+ H5C__UPDATE_STATS_FOR_PIN(cache_ptr, parent_entry)
+ } /* end else */
+
+ /* Mark the entry as pinned from the cache's action (possibly redundantly) */
+ parent_entry->pinned_from_cache = TRUE;
+
+ /* Increment ref. count for parent's flush dependency children heights */
+ parent_entry->child_flush_dep_height_rc[child_entry->flush_dep_height]++;
+
+ /* Check for increasing parent flush dependency height */
+ if((child_entry->flush_dep_height + 1) > parent_entry->flush_dep_height) {
+
+ /* Check if parent entry has _its_ own parent flush dependency entry */
+ if(NULL != parent_entry->flush_dep_parent) {
+ /* Adjust flush dependency ref. counts on parent entry's parent */
+ H5C_adjust_flush_dependency_rc(parent_entry->flush_dep_parent, parent_entry->flush_dep_height, (child_entry->flush_dep_height + 1));
+ } /* end if */
+
+ /* Increase flush dependency height of parent entry */
+ parent_entry->flush_dep_height = child_entry->flush_dep_height + 1;
+ } /* end if */
+
+ /* Set parent for child entry */
+ child_entry->flush_dep_parent = parent_entry;
+
+
+ /* Post-conditions, for successful operation */
+ HDassert(parent_entry->is_pinned);
+ HDassert(parent_entry->flush_dep_height > 0);
+ HDassert(parent_entry->flush_dep_height < H5C__NUM_FLUSH_DEP_HEIGHTS);
+ HDassert(prev_flush_dep_height <= parent_entry->flush_dep_height);
+ HDassert(parent_entry->child_flush_dep_height_rc[child_entry->flush_dep_height] > 0);
+ HDassert(NULL != child_entry->flush_dep_parent);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5C_create_flush_dependency() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5C_destroy_flush_dependency()
+ *
+ * Purpose: Terminates a parent<-> child entry flush dependency. The
+ * parent entry must be pinned and have a positive flush
+ * dependency height (which could go to zero as a result of
+ * this operation).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * 3/05/09
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C_destroy_flush_dependency(H5C_t * cache_ptr, void *parent_thing,
+ void * child_thing)
+{
+ H5C_cache_entry_t * parent_entry = (H5C_cache_entry_t *)parent_thing; /* Ptr to parent entry */
+ H5C_cache_entry_t * child_entry = (H5C_cache_entry_t *)child_thing; /* Ptr to child entry */
+#ifndef NDEBUG
+ unsigned prev_flush_dep_height = parent_entry->flush_dep_height; /* Previous flush height for parent entry */
+#endif /* NDEBUG */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5C_destroy_flush_dependency, FAIL)
+
+ /* Sanity checks */
+ HDassert(cache_ptr);
+ HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
+ HDassert(parent_entry);
+ HDassert(parent_entry->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
+ HDassert(H5F_addr_defined(parent_entry->addr));
+ HDassert(parent_entry->flush_dep_height <= H5C__NUM_FLUSH_DEP_HEIGHTS);
+ HDassert(child_entry);
+ HDassert(child_entry->flush_dep_parent != child_entry);
+ HDassert(child_entry->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
+ HDassert(H5F_addr_defined(child_entry->addr));
+
+ /* Usage checks */
+ if(!parent_entry->is_pinned)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL, "Parent entry isn't pinned")
+ if(0 == parent_entry->flush_dep_height)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL, "Parent entry isn't a flush dependency parent")
+ if(NULL == child_entry->flush_dep_parent)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL, "Child entry doesn't have a flush dependency parent")
+ if(0 == parent_entry->child_flush_dep_height_rc[child_entry->flush_dep_height])
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL, "Parent entry flush dependency ref. count has no child entries of this height")
+ if(child_entry->flush_dep_parent != parent_entry)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL, "Parent entry isn't flush dependency parent for child entry")
+
+ /* Decrement the ref. count for flush dependency height of children for parent entry */
+ parent_entry->child_flush_dep_height_rc[child_entry->flush_dep_height]--;
+
+ /* Check for flush dependency ref. count at this height going to zero and
+ * parent entry flush dependency height dropping
+ */
+ if(((child_entry->flush_dep_height + 1) == parent_entry->flush_dep_height) &&
+ 0 == parent_entry->child_flush_dep_height_rc[child_entry->flush_dep_height]) {
+ int i; /* Local index variable */
+
+ /* Reverse scan for new flush dependency height of parent */
+#ifndef NDEBUG
+ for(i = (H5C__NUM_FLUSH_DEP_HEIGHTS - 1); i > (int)child_entry->flush_dep_height; i--)
+ HDassert(0 == parent_entry->child_flush_dep_height_rc[i]);
+#endif /* NDEBUG */
+ for(i = (int)child_entry->flush_dep_height; i >= 0; i--)
+ /* Check for child flush dependencies of this height */
+ if(parent_entry->child_flush_dep_height_rc[i] > 0)
+ break;
+
+ /* Sanity check */
+ HDassert((unsigned)(i + 1) < parent_entry->flush_dep_height);
+
+ /* Check if parent entry is a child in another flush dependency relationship */
+ if(NULL != parent_entry->flush_dep_parent) {
+ /* Change flush dependency ref. counts of parent's parent */
+ H5C_adjust_flush_dependency_rc(parent_entry->flush_dep_parent, parent_entry->flush_dep_height, (unsigned)(i + 1));
+ } /* end if */
+
+ /* Increase flush dependency height of parent entry */
+ parent_entry->flush_dep_height = (unsigned)(i + 1);
+
+ /* Check for height of parent dropping to zero (i.e. no longer a
+ * parent of _any_ child flush dependencies).
+ */
+ if(0 == parent_entry->flush_dep_height) {
+ /* Sanity check */
+ HDassert(parent_entry->pinned_from_cache);
+
+ /* Check if we should unpin parent entry now */
+ if(!parent_entry->pinned_from_client) {
+ /* Update the replacement policy if the entry is not protected */
+ if(!parent_entry->is_protected)
+ H5C__UPDATE_RP_FOR_UNPIN(cache_ptr, parent_entry, FAIL)
+
+ /* Unpin the entry now */
+ parent_entry->is_pinned = FALSE;
+
+ /* Update the stats for an unpin operation */
+ H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, parent_entry)
+ } /* end if */
+
+ /* Mark the entry as unpinned from the cache's action */
+ parent_entry->pinned_from_cache = FALSE;
+ } /* end if */
+ } /* end if */
+
+ /* Reset parent of child entry */
+ child_entry->flush_dep_parent = NULL;
+
+ /* Post-conditions, for successful operation */
+ HDassert(prev_flush_dep_height >= parent_entry->flush_dep_height);
+ HDassert(NULL == child_entry->flush_dep_parent);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5C_destroy_flush_dependency() */
+
+
/*************************************************************************/
/**************************** Private Functions: *************************/
/*************************************************************************/
@@ -8721,8 +9556,8 @@ done:
*
* Note that this is a pretty bad scenario if it ever
* happens. The code I have added should allow us to
- * handle the situation under all but the worst conditions,
- * but one can argue that I should just scream and die if I
+ * handle the situation under all but the worst conditions,
+ * but one can argue that I should just scream and die if I
* ever detect the condidtion.
*
*-------------------------------------------------------------------------
@@ -8825,7 +9660,7 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t * f,
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"*prev_ptr corrupt")
- } else
+ } else
#endif /* NDEBUG */
if ( ( prev_ptr->is_dirty != prev_is_dirty )
||
@@ -8979,12 +9814,8 @@ H5C__autoadjust__ageout__insert_new_marker(H5C_t * cache_ptr)
i++;
}
- HDassert( i < H5C__MAX_EPOCH_MARKERS );
-
- if ( (cache_ptr->epoch_marker_active)[i] != FALSE ) {
-
+ if(i >= H5C__MAX_EPOCH_MARKERS)
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't find unused marker.")
- }
HDassert( ((cache_ptr->epoch_markers)[i]).addr == (haddr_t)i );
HDassert( ((cache_ptr->epoch_markers)[i]).next == NULL );
@@ -9202,9 +10033,9 @@ done:
* Function: H5C__flash_increase_cache_size
*
* Purpose: If there is not at least new_entry_size - old_entry_size
- * bytes of free space in the cache and the current
- * max_cache_size is less than (cache_ptr->resize_ctl).max_size,
- * perform a flash increase in the cache size and then reset
+ * bytes of free space in the cache and the current
+ * max_cache_size is less than (cache_ptr->resize_ctl).max_size,
+ * perform a flash increase in the cache size and then reset
* the full cache hit rate statistics, and exit.
*
* Return: Non-negative on success/Negative on failure.
@@ -9248,13 +10079,13 @@ H5C__flash_increase_cache_size(H5C_t * cache_ptr,
space_needed = new_entry_size - old_entry_size;
- if ( ( (cache_ptr->index_size + space_needed) >
+ if ( ( (cache_ptr->index_size + space_needed) >
cache_ptr->max_cache_size ) &&
( cache_ptr->max_cache_size < (cache_ptr->resize_ctl).max_size ) ) {
/* we have work to do */
- switch ( (cache_ptr->resize_ctl).flash_incr_mode )
+ switch ( (cache_ptr->resize_ctl).flash_incr_mode )
{
case H5C_flash_incr__off:
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
@@ -9263,13 +10094,13 @@ H5C__flash_increase_cache_size(H5C_t * cache_ptr,
case H5C_flash_incr__add_space:
if ( cache_ptr->index_size < cache_ptr->max_cache_size ) {
-
+
HDassert( (cache_ptr->max_cache_size - cache_ptr->index_size)
< space_needed );
space_needed -= cache_ptr->max_cache_size - cache_ptr->index_size;
}
- space_needed =
- (size_t)(((double)space_needed) *
+ space_needed =
+ (size_t)(((double)space_needed) *
(cache_ptr->resize_ctl).flash_multiple);
new_max_cache_size = cache_ptr->max_cache_size + space_needed;
@@ -9324,7 +10155,7 @@ H5C__flash_increase_cache_size(H5C_t * cache_ptr,
break;
}
- /* note that we don't cycle the epoch markers. We can
+ /* note that we don't cycle the epoch markers. We can
* argue either way as to whether we should, but for now
* we don't.
*/
@@ -9418,8 +10249,8 @@ done:
*
* Note that this is a pretty bad scenario if it ever
* happens. The code I have added should allow us to
- * handle the situation under all but the worst conditions,
- * but one can argue that I should just scream and die if I
+ * handle the situation under all but the worst conditions,
+ * but one can argue that I should just scream and die if I
* ever detect the condidtion.
*
* -- JRM 10/13/07
@@ -9435,10 +10266,7 @@ H5C_flush_invalidate_cache(H5F_t * f,
{
herr_t status;
herr_t ret_value = SUCCEED;
- hbool_t done = FALSE;
hbool_t first_flush = TRUE;
- hbool_t first_pass = TRUE;
- hbool_t have_pinned_entries;
int32_t protected_entries = 0;
int32_t i;
int32_t cur_pel_len;
@@ -9481,29 +10309,29 @@ H5C_flush_invalidate_cache(H5F_t * f,
/* The flush proceedure here is a bit strange.
*
- * In the outer while loop we make at least one pass through the
+ * In the outer while loop we make at least one pass through the
* cache, and then repeat until either all the pinned entries
* unpin themselves, or until the number of pinned entries stops
* declining. In this later case, we scream and die.
*
* Since the fractal heap can dirty, resize, and/or rename entries
* in is flush callback, it is possible that the cache will still
- * contain dirty entries at this point. If so, we must make up to
- * H5C__MAX_PASSES_ON_FLUSH more passes through the skip list
+ * contain dirty entries at this point. If so, we must make up to
+ * H5C__MAX_PASSES_ON_FLUSH more passes through the skip list
* to allow it to empty. If is is not empty at this point, we again
* scream and die.
*
- * Further, since clean entries can be dirtied, resized, and/or renamed
+ * Further, since clean entries can be dirtied, resized, and/or renamed
* as the result of a flush call back (either the entries own, or that
- * for some other cache entry), we can no longer promise to flush
+ * for some other cache entry), we can no longer promise to flush
* the cache entries in increasing address order.
*
* Instead, we just do the best we can -- making a pass through
- * the skip list, and then a pass through the "clean" entries, and
- * then repeating as needed. Thus it is quite possible that an
+ * the skip list, and then a pass through the "clean" entries, and
+ * then repeating as needed. Thus it is quite possible that an
* entry will be evicted from the cache only to be re-loaded later
- * in the flush process (From what Quincey tells me, the pin
- * mechanism makes this impossible, but even it it is true now,
+ * in the flush process (From what Quincey tells me, the pin
+ * mechanism makes this impossible, but even it it is true now,
* we shouldn't count on it in the future.)
*
* The bottom line is that entries will probably be flushed in close
@@ -9513,349 +10341,366 @@ H5C_flush_invalidate_cache(H5F_t * f,
cur_pel_len = cache_ptr->pel_len;
old_pel_len = cache_ptr->pel_len;
- while ( ! done )
+ while ( cache_ptr->index_len > 0 )
{
- first_pass = FALSE;
-
- have_pinned_entries = ( cur_pel_len > 0 );
-
- /* first, try to flush-destroy any dirty entries. Do this by
- * making a scan through the slist. Note that new dirty entries
- * may be created by the flush call backs. Thus it is possible
- * that the slist will not be empty after we finish the scan.
- */
+ unsigned curr_flush_dep_height = 0;
+ unsigned flush_dep_passes = 0;
- if ( cache_ptr->slist_len == 0 ) {
+ /* Loop over all flush dependency heights of entries */
+ while((curr_flush_dep_height <= H5C__NUM_FLUSH_DEP_HEIGHTS) &&
+ (cache_ptr->index_len > 0 ) &&
+ (flush_dep_passes < H5C__MAX_PASSES_ON_FLUSH) )
+ {
+ hbool_t flushed_during_dep_loop = FALSE;
- node_ptr = NULL;
- HDassert( cache_ptr->slist_size == 0 );
+ /* first, try to flush-destroy any dirty entries. Do this by
+ * making a scan through the slist. Note that new dirty entries
+ * may be created by the flush call backs. Thus it is possible
+ * that the slist will not be empty after we finish the scan.
+ */
- } else {
+ if ( cache_ptr->slist_len == 0 ) {
- node_ptr = H5SL_first(cache_ptr->slist_ptr);
+ node_ptr = NULL;
+ HDassert( cache_ptr->slist_size == 0 );
- if ( node_ptr == NULL ) {
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "slist_len != 0 && node_ptr == NULL");
- }
+ } else {
- next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
+ /* Start at beginning of skip list each time */
+ node_ptr = H5SL_first(cache_ptr->slist_ptr);
+ HDassert( node_ptr != NULL );
- if ( next_entry_ptr == NULL ) {
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "next_entry_ptr == NULL 1 ?!?!");
+ /* Get cache entry for this node */
+ next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
+ if ( NULL == next_entry_ptr )
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "next_entry_ptr == NULL ?!?!")
+ HDassert( next_entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC );
+ HDassert( next_entry_ptr->is_dirty );
+ HDassert( next_entry_ptr->in_slist );
}
-#ifndef NDEBUG
- HDassert( next_entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC );
-#endif /* NDEBUG */
- HDassert( next_entry_ptr->is_dirty );
- HDassert( next_entry_ptr->in_slist );
- }
#if H5C_DO_SANITY_CHECKS
- /* Depending on circumstances, H5C_flush_single_entry() will
- * remove dirty entries from the slist as it flushes them.
- * Thus for sanity checks we must make note of the initial
- * slist length and size before we do any flushes.
- */
- initial_slist_len = cache_ptr->slist_len;
- initial_slist_size = cache_ptr->slist_size;
-
- /* There is also the possibility that entries will be
- * dirtied, resized, and/or renamed as the result of
- * calls to the flush callbacks. We use the slist_len_increase
- * and slist_size_increase increase fields in struct H5C_t
- * to track these changes for purpose of sanity checking.
- * To this end, we must zero these fields before we start
- * the pass through the slist.
- */
- cache_ptr->slist_len_increase = 0;
- cache_ptr->slist_size_increase = 0;
-
- /* Finally, reset the actual_slist_len and actual_slist_size
- * fields to zero, as these fields are used to accumulate
- * the slist lenght and size that we see as we scan through
- * the slist.
- */
- actual_slist_len = 0;
- actual_slist_size = 0;
-#endif /* H5C_DO_SANITY_CHECKS */
+ /* Depending on circumstances, H5C_flush_single_entry() will
+ * remove dirty entries from the slist as it flushes them.
+ * Thus for sanity checks we must make note of the initial
+ * slist length and size before we do any flushes.
+ */
+ initial_slist_len = cache_ptr->slist_len;
+ initial_slist_size = cache_ptr->slist_size;
- while ( node_ptr != NULL )
- {
- entry_ptr = next_entry_ptr;
-
- /* With the advent of the fractal heap, it is possible
- * that the flush callback will dirty and/or resize
- * other entries in the cache. In particular, while
- * Quincey has promised me that this will never happen,
- * it is possible that the flush callback for an
- * entry may protect an entry that is not in the cache,
- * perhaps causing the cache to flush and possibly
- * evict the entry associated with node_ptr to make
- * space for the new entry.
- *
- * Thus we do a bit of extra sanity checking on entry_ptr,
- * and break out of this scan of the skip list if we
- * detect major problems. We have a bit of leaway on the
- * number of passes though the skip list, so this shouldn't
- * be an issue in the flush in and of itself, as it should
- * be all but impossible for this to happen more than once
- * in any flush.
- *
- * Observe that that breaking out of the scan early
- * shouldn't break the sanity checks just after the end
- * of this while loop.
- *
- * If an entry has merely been marked clean and removed from
- * the s-list, we simply break out of the scan.
- *
- * If the entry has been evicted, we flag an error and
- * exit.
+ /* There is also the possibility that entries will be
+ * dirtied, resized, and/or renamed as the result of
+ * calls to the flush callbacks. We use the slist_len_increase
+ * and slist_size_increase increase fields in struct H5C_t
+ * to track these changes for purpose of sanity checking.
+ * To this end, we must zero these fields before we start
+ * the pass through the slist.
*/
-#ifndef NDEBUG
- if ( entry_ptr->magic != H5C__H5C_CACHE_ENTRY_T_MAGIC ) {
+ cache_ptr->slist_len_increase = 0;
+ cache_ptr->slist_size_increase = 0;
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "entry_ptr->magic is invalid ?!?!");
+ /* Finally, reset the actual_slist_len and actual_slist_size
+ * fields to zero, as these fields are used to accumulate
+ * the slist lenght and size that we see as we scan through
+ * the slist.
+ */
+ actual_slist_len = 0;
+ actual_slist_size = 0;
+#endif /* H5C_DO_SANITY_CHECKS */
- } else
-#endif /* NDEBUG */
- if ( ( ! entry_ptr->is_dirty ) ||
- ( ! entry_ptr->in_slist ) ) {
+ while ( node_ptr != NULL )
+ {
+ entry_ptr = next_entry_ptr;
- /* the s-list has been modified out from under us.
- * break out of the loop.
+ /* With the advent of the fractal heap, it is possible
+ * that the flush callback will dirty and/or resize
+ * other entries in the cache. In particular, while
+ * Quincey has promised me that this will never happen,
+ * it is possible that the flush callback for an
+ * entry may protect an entry that is not in the cache,
+ * perhaps causing the cache to flush and possibly
+ * evict the entry associated with node_ptr to make
+ * space for the new entry.
+ *
+ * Thus we do a bit of extra sanity checking on entry_ptr,
+ * and break out of this scan of the skip list if we
+ * detect major problems. We have a bit of leaway on the
+ * number of passes though the skip list, so this shouldn't
+ * be an issue in the flush in and of itself, as it should
+ * be all but impossible for this to happen more than once
+ * in any flush.
+ *
+ * Observe that that breaking out of the scan early
+ * shouldn't break the sanity checks just after the end
+ * of this while loop.
+ *
+ * If an entry has merely been marked clean and removed from
+ * the s-list, we simply break out of the scan.
+ *
+ * If the entry has been evicted, we flag an error and
+ * exit.
*/
- break;
- }
-
- /* increment node pointer now, before we delete its target
- * from the slist.
- */
+#ifndef NDEBUG
+ if ( entry_ptr->magic != H5C__H5C_CACHE_ENTRY_T_MAGIC ) {
- node_ptr = H5SL_next(node_ptr);
- if ( node_ptr != NULL ) {
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "entry_ptr->magic is invalid ?!?!")
- next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
+ } else
+#endif /* NDEBUG */
+ if ( ( ! entry_ptr->is_dirty ) ||
+ ( ! entry_ptr->in_slist ) ) {
- if ( next_entry_ptr == NULL ) {
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "next_entry_ptr == NULL 2 ?!?!");
+ /* the s-list has been modified out from under us.
+ * break out of the loop.
+ */
+ goto end_of_inner_loop;;
}
-#ifndef NDEBUG
- HDassert( next_entry_ptr->magic ==
- H5C__H5C_CACHE_ENTRY_T_MAGIC );
-#endif /* NDEBUG */
- HDassert( next_entry_ptr->is_dirty );
- HDassert( next_entry_ptr->in_slist );
- } else {
+ /* increment node pointer now, before we delete its target
+ * from the slist.
+ */
- next_entry_ptr = NULL;
- }
+ node_ptr = H5SL_next(node_ptr);
+ if ( node_ptr != NULL ) {
+ next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
+ if ( NULL == next_entry_ptr )
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "next_entry_ptr == NULL ?!?!")
+ HDassert( next_entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC );
+ HDassert( next_entry_ptr->is_dirty );
+ HDassert( next_entry_ptr->in_slist );
+ } else {
+ next_entry_ptr = NULL;
+ }
- /* Note that we now remove nodes from the slist as we flush
- * the associated entries, instead of leaving them there
- * until we are done, and then destroying all nodes in
- * the slist.
- *
- * While this optimization used to be easy, with the possibility
- * of new entries being added to the slist in the midst of the
- * flush, we must keep the slist in cannonical form at all
- * times.
- */
+ /* Note that we now remove nodes from the slist as we flush
+ * the associated entries, instead of leaving them there
+ * until we are done, and then destroying all nodes in
+ * the slist.
+ *
+ * While this optimization used to be easy, with the possibility
+ * of new entries being added to the slist in the midst of the
+ * flush, we must keep the slist in cannonical form at all
+ * times.
+ */
- HDassert( entry_ptr != NULL );
- HDassert( entry_ptr->in_slist );
+ HDassert( entry_ptr != NULL );
+ HDassert( entry_ptr->in_slist );
#if H5C_DO_SANITY_CHECKS
- /* update actual_slist_len & actual_slist_size before
- * the flush. Note that the entry will be removed
- * from the slist after the flush, and thus may be
- * resized by the flush callback. This is OK, as
- * we will catch the size delta in
- * cache_ptr->slist_size_increase.
- *
- * Note that we include pinned entries in this count, even
- * though we will not actually flush them.
- */
- actual_slist_len++;
- actual_slist_size += entry_ptr->size;
+ /* update actual_slist_len & actual_slist_size before
+ * the flush. Note that the entry will be removed
+ * from the slist after the flush, and thus may be
+ * resized by the flush callback. This is OK, as
+ * we will catch the size delta in
+ * cache_ptr->slist_size_increase.
+ *
+ * Note that we include pinned entries in this count, even
+ * though we will not actually flush them.
+ */
+ actual_slist_len++;
+ actual_slist_size += entry_ptr->size;
#endif /* H5C_DO_SANITY_CHECKS */
- if ( entry_ptr->is_protected ) {
-
- /* we have major problems -- but lets flush
- * everything we can before we flag an error.
- */
- protected_entries++;
+ if ( entry_ptr->is_protected ) {
- } else if ( entry_ptr->is_pinned ) {
+ /* we have major problems -- but lets flush
+ * everything we can before we flag an error.
+ */
+ protected_entries++;
- /* Test to see if we are can flush the entry now.
- * If we can, go ahead and flush, but don't tell
- * H5C_flush_single_entry() to destroy the entry
- * as pinned entries can't be evicted.
- */
- if ( TRUE ) { /* When we get to multithreaded cache,
- * we will need either locking code, and/or
- * a test to see if the entry is in flushable
- * condition here.
- */
+ } else if ( entry_ptr->is_pinned ) {
- status = H5C_flush_single_entry(f,
- primary_dxpl_id,
- secondary_dxpl_id,
- cache_ptr,
- NULL,
- entry_ptr->addr,
- H5C__NO_FLAGS_SET,
- &first_flush,
- FALSE);
- if ( status < 0 ) {
+ /* Test to see if we are can flush the entry now.
+ * If we can, go ahead and flush, but don't tell
+ * H5C_flush_single_entry() to destroy the entry
+ * as pinned entries can't be evicted.
+ */
+ if(entry_ptr->flush_dep_height == curr_flush_dep_height ) {
+ status = H5C_flush_single_entry(f,
+ primary_dxpl_id,
+ secondary_dxpl_id,
+ cache_ptr,
+ NULL,
+ entry_ptr->addr,
+ H5C__NO_FLAGS_SET,
+ &first_flush,
+ FALSE);
+ if ( status < 0 ) {
- /* This shouldn't happen -- if it does, we are toast
- * so just scream and die.
- */
+ /* This shouldn't happen -- if it does, we are toast
+ * so just scream and die.
+ */
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "dirty pinned entry flush failed.")
- }
- }
- } else {
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
+ "dirty pinned entry flush failed.")
+ } /* end if */
+ flushed_during_dep_loop = TRUE;
+ } /* end if */
+ else if(entry_ptr->flush_dep_height < curr_flush_dep_height)
+ /* This shouldn't happen -- if it does, just scream and die. */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry below current flush dep. height.")
+ } /* end if */
+ else {
+ if(entry_ptr->flush_dep_height == curr_flush_dep_height ){
- status = H5C_flush_single_entry(f,
- primary_dxpl_id,
- secondary_dxpl_id,
- cache_ptr,
- NULL,
- entry_ptr->addr,
- (cooked_flags |
- H5C__FLUSH_INVALIDATE_FLAG),
- &first_flush,
- TRUE);
- if ( status < 0 ) {
+ status = H5C_flush_single_entry(f,
+ primary_dxpl_id,
+ secondary_dxpl_id,
+ cache_ptr,
+ NULL,
+ entry_ptr->addr,
+ (cooked_flags |
+ H5C__FLUSH_INVALIDATE_FLAG),
+ &first_flush,
+ TRUE);
+ if ( status < 0 ) {
- /* This shouldn't happen -- if it does, we are toast so
- * just scream and die.
- */
+ /* This shouldn't happen -- if it does, we are toast so
+ * just scream and die.
+ */
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "dirty entry flush destroy failed.")
- }
- }
- } /* end while loop scanning skip list */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
+ "dirty entry flush destroy failed.")
+ } /* end if */
+ flushed_during_dep_loop = TRUE;
+ } /* end if */
+ else if(entry_ptr->flush_dep_height < curr_flush_dep_height)
+ /* This shouldn't happen -- if it does, just scream and die. */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry below current flush dep. height.")
+ } /* end else */
+ } /* end while loop scanning skip list */
#if H5C_DO_SANITY_CHECKS
- /* It is possible that entries were added to the slist during
- * the scan, either before or after scan pointer. The following
- * asserts take this into account.
- *
- * Don't bother with the sanity checks if node_ptr != NULL, as
- * in this case we broke out of the loop because it got changed
- * out from under us.
- */
+ /* It is possible that entries were added to the slist during
+ * the scan, either before or after scan pointer. The following
+ * asserts take this into account.
+ *
+ * Don't bother with the sanity checks if node_ptr != NULL, as
+ * in this case we broke out of the loop because it got changed
+ * out from under us.
+ */
- if ( node_ptr == NULL ) {
+ if ( node_ptr == NULL ) {
- HDassert( (actual_slist_len + cache_ptr->slist_len) ==
- (initial_slist_len + cache_ptr->slist_len_increase) );
- HDassert( (actual_slist_size + cache_ptr->slist_size) ==
- (initial_slist_size + cache_ptr->slist_size_increase) );
- }
+ HDassert( (actual_slist_len + cache_ptr->slist_len) ==
+ (initial_slist_len + cache_ptr->slist_len_increase) );
+ HDassert( (actual_slist_size + cache_ptr->slist_size) ==
+ (initial_slist_size + cache_ptr->slist_size_increase) );
+ }
#endif /* H5C_DO_SANITY_CHECKS */
- /* Since we are doing a destroy, we must make a pass through
- * the hash table and try to flush - destroy all entries that
- * remain.
- *
- * It used to be that all entries remaining in the cache at
- * this point had to be clean, but with the fractal heap mods
- * this may not be the case. If so, we will flush entries out
- * of increasing address order.
- *
- * Writes to disk are possible here.
- */
- for ( i = 0; i < H5C__HASH_TABLE_LEN; i++ )
- {
- next_entry_ptr = cache_ptr->index[i];
-
- while ( next_entry_ptr != NULL )
+ /* Since we are doing a destroy, we must make a pass through
+ * the hash table and try to flush - destroy all entries that
+ * remain.
+ *
+ * It used to be that all entries remaining in the cache at
+ * this point had to be clean, but with the fractal heap mods
+ * this may not be the case. If so, we will flush entries out
+ * of increasing address order.
+ *
+ * Writes to disk are possible here.
+ */
+ for ( i = 0; i < H5C__HASH_TABLE_LEN; i++ )
{
- entry_ptr = next_entry_ptr;
+ next_entry_ptr = cache_ptr->index[i];
- next_entry_ptr = entry_ptr->ht_next;
-#ifndef NDEBUG
- HDassert ( ( next_entry_ptr == NULL ) ||
- ( next_entry_ptr->magic ==
- H5C__H5C_CACHE_ENTRY_T_MAGIC ) );
-#endif /* NDEBUG */
- if ( entry_ptr->is_protected ) {
+ while ( next_entry_ptr != NULL )
+ {
+ entry_ptr = next_entry_ptr;
- /* we have major problems -- but lets flush and destroy
- * everything we can before we flag an error.
- */
- protected_entries++;
+ next_entry_ptr = entry_ptr->ht_next;
+ HDassert ( ( next_entry_ptr == NULL ) ||
+ ( next_entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC ) );
+ if ( entry_ptr->is_protected ) {
- if ( ! entry_ptr->in_slist ) {
+ /* we have major problems -- but lets flush and destroy
+ * everything we can before we flag an error.
+ */
+ protected_entries++;
- HDassert( !(entry_ptr->is_dirty) );
- }
- } else if ( ! ( entry_ptr->is_pinned ) ) {
+ if ( ! entry_ptr->in_slist ) {
- status = H5C_flush_single_entry(f,
- primary_dxpl_id,
- secondary_dxpl_id,
- cache_ptr,
- NULL,
- entry_ptr->addr,
- (cooked_flags |
- H5C__FLUSH_INVALIDATE_FLAG),
- &first_flush,
- TRUE);
- if ( status < 0 ) {
+ HDassert( !(entry_ptr->is_dirty) );
+ }
+ } else if ( ! ( entry_ptr->is_pinned ) ) {
- /* This shouldn't happen -- if it does, we are toast so
- * just scream and die.
+ /* Test to see if we are can flush the entry now.
+ * If we can, go ahead and flush.
*/
+ if(entry_ptr->flush_dep_height == curr_flush_dep_height ){
+ status = H5C_flush_single_entry(f,
+ primary_dxpl_id,
+ secondary_dxpl_id,
+ cache_ptr,
+ NULL,
+ entry_ptr->addr,
+ (cooked_flags |
+ H5C__FLUSH_INVALIDATE_FLAG),
+ &first_flush,
+ TRUE);
+ if ( status < 0 ) {
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "Entry flush destroy failed.")
- }
- }
- /* We can't do anything if the entry is pinned. The
- * hope is that the entry will be unpinned as the
- * result of destroys of entries that reference it.
- *
- * We detect this by noting the change in the number
- * of pinned entries from pass to pass. If it stops
- * shrinking before it hits zero, we scream and die.
- */
- /* if the flush function on the entry we last evicted
- * loaded an entry into cache (as Quincey has promised me
- * it never will), and if the cache was full, it is
- * possible that *next_entry_ptr was flushed or evicted.
- *
- * Test to see if this happened here. Note that if this
- * test is triggred, we are accessing a deallocated piece
- * of dynamically allocated memory, so we just scream and
- * die.
- */
-#ifndef NDEBUG
- if ( ( next_entry_ptr != NULL ) &&
- ( next_entry_ptr->magic !=
- H5C__H5C_CACHE_ENTRY_T_MAGIC ) ) {
+ /* This shouldn't happen -- if it does, we are toast so
+ * just scream and die.
+ */
- /* Something horrible has happened to
- * *next_entry_ptr -- scream and die.
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
+ "Entry flush destroy failed.")
+ }
+ flushed_during_dep_loop = TRUE;
+ } /* end if */
+ else if(entry_ptr->flush_dep_height < curr_flush_dep_height)
+ /* This shouldn't happen -- if it does, just scream and die. */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry below current flush dep. height.")
+ } /* end if */
+ /* We can't do anything if the entry is pinned. The
+ * hope is that the entry will be unpinned as the
+ * result of destroys of entries that reference it.
+ *
+ * We detect this by noting the change in the number
+ * of pinned entries from pass to pass. If it stops
+ * shrinking before it hits zero, we scream and die.
*/
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "next_entry_ptr->magic is invalid?!?!?.")
- }
+ /* if the flush function on the entry we last evicted
+ * loaded an entry into cache (as Quincey has promised me
+ * it never will), and if the cache was full, it is
+ * possible that *next_entry_ptr was flushed or evicted.
+ *
+ * Test to see if this happened here. Note that if this
+ * test is triggred, we are accessing a deallocated piece
+ * of dynamically allocated memory, so we just scream and
+ * die.
+ */
+#ifndef NDEBUG
+ if ( ( next_entry_ptr != NULL ) &&
+ ( next_entry_ptr->magic !=
+ H5C__H5C_CACHE_ENTRY_T_MAGIC ) ) {
+
+ /* Something horrible has happened to
+ * *next_entry_ptr -- scream and die.
+ */
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "next_entry_ptr->magic is invalid?!?!?.")
+ }
#endif /* NDEBUG */
- } /* end while loop scanning hash table bin */
- } /* end for loop scanning hash table */
+ } /* end while loop scanning hash table bin */
+ } /* end for loop scanning hash table */
+
+ /* Check for incrementing flush dependency height */
+ if(flushed_during_dep_loop) {
+ /* If we flushed an entry at this flush dependency height
+ * start over at the bottom level of the flush dependencies
+ */
+ curr_flush_dep_height = 0;
+
+ /* Make certain we don't get stuck in an infinite loop */
+ flush_dep_passes++;
+ } /* end if */
+ else
+ curr_flush_dep_height++;
+
+ } /* end while loop over flush dependency heights */
+end_of_inner_loop:
old_pel_len = cur_pel_len;
cur_pel_len = cache_ptr->pel_len;
@@ -9867,12 +10712,12 @@ H5C_flush_invalidate_cache(H5F_t * f,
*/
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "Can't unpin all pinned entries 1.")
+ "Pinned entry count not decreasing.")
} else if ( ( cur_pel_len == 0 ) && ( old_pel_len == 0 ) ) {
/* increment the pass count */
- passes++;
+ passes++;
}
if ( passes >= H5C__MAX_PASSES_ON_FLUSH ) {
@@ -9884,22 +10729,21 @@ H5C_flush_invalidate_cache(H5F_t * f,
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
"Maximum passes on flush exceeded.")
}
-
- if ( cache_ptr->index_len <= 0 ) {
-
- done = TRUE;
- HDassert( cache_ptr->index_size == 0 );
- HDassert( cache_ptr->slist_len == 0 );
- HDassert( cache_ptr->slist_size == 0 );
- HDassert( cache_ptr->pel_len == 0 );
- HDassert( cache_ptr->pel_size == 0 );
- HDassert( cache_ptr->pl_len == 0 );
- HDassert( cache_ptr->pl_size == 0 );
- HDassert( cache_ptr->LRU_list_len == 0 );
- HDassert( cache_ptr->LRU_list_size == 0 );
- }
} /* main while loop */
+ /* Invariants, after destroying all entries in the hash table */
+ HDassert( cache_ptr->index_size == 0 );
+ HDassert( cache_ptr->clean_index_size == 0 );
+ HDassert( cache_ptr->dirty_index_size == 0 );
+ HDassert( cache_ptr->slist_len == 0 );
+ HDassert( cache_ptr->slist_size == 0 );
+ HDassert( cache_ptr->pel_len == 0 );
+ HDassert( cache_ptr->pel_size == 0 );
+ HDassert( cache_ptr->pl_len == 0 );
+ HDassert( cache_ptr->pl_size == 0 );
+ HDassert( cache_ptr->LRU_list_len == 0 );
+ HDassert( cache_ptr->LRU_list_size == 0 );
+
HDassert( protected_entries <= cache_ptr->pl_len );
@@ -9911,7 +10755,7 @@ H5C_flush_invalidate_cache(H5F_t * f,
} else if ( cur_pel_len > 0 ) {
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "Can't unpin all pinned entries 2.")
+ "Can't unpin all pinned entries.")
}
@@ -9994,21 +10838,30 @@ done:
* as there is no write to file in this case.
*
* JRM -- 8/21/06
- * Added code maintaining the flush_in_progress and
- * destroy_in_progress fields in H5C_cache_entry_t.
- *
- * Also added flush_flags parameter to the call to
- * type_ptr->flush() so that the flush routine can report
- * whether the entry has been resized or renamed. Added
- * code using the flush_flags variable to detect the case
- * in which the target entry is resized during flush, and
+ * Added code maintaining the flush_in_progress and
+ * destroy_in_progress fields in H5C_cache_entry_t.
+ *
+ * Also added flush_flags parameter to the call to
+ * type_ptr->flush() so that the flush routine can report
+ * whether the entry has been resized or renamed. Added
+ * code using the flush_flags variable to detect the case
+ * in which the target entry is resized during flush, and
* update the caches data structures accordingly.
*
- *
* JRM -- 3/29/07
- * Added sanity checks on the new is_read_only and
+ * Added sanity checks on the new is_read_only and
* ro_ref_count fields.
*
+ * QAK -- 2/07/08
+ * Separated "destroy entry" concept from "remove entry from
+ * cache" concept, by adding the 'take_ownership' flag and
+ * the "destroy_entry" variable.
+ *
+ * JRM -- 11/5/08
+ * Added call to H5C__UPDATE_INDEX_FOR_ENTRY_CLEAN() to
+ * maintain the new clean_index_size and clean_index_size
+ * fields of H5C_t.
+ *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -10024,12 +10877,14 @@ H5C_flush_single_entry(H5F_t * f,
{
hbool_t destroy;
hbool_t clear_only;
+ hbool_t take_ownership;
hbool_t was_dirty;
- herr_t ret_value = SUCCEED; /* Return value */
+ hbool_t destroy_entry;
herr_t status;
int type_id;
unsigned flush_flags = H5C_CALLBACK__NO_FLAGS_SET;
H5C_cache_entry_t * entry_ptr = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5C_flush_single_entry)
@@ -10042,6 +10897,15 @@ H5C_flush_single_entry(H5F_t * f,
destroy = ( (flags & H5C__FLUSH_INVALIDATE_FLAG) != 0 );
clear_only = ( (flags & H5C__FLUSH_CLEAR_ONLY_FLAG) != 0);
+ take_ownership = ( (flags & H5C__TAKE_OWNERSHIP_FLAG) != 0);
+
+ /* Set the flag for destroying the entry, based on the 'take ownership'
+ * and 'destroy' flags
+ */
+ if(take_ownership)
+ destroy_entry = FALSE;
+ else
+ destroy_entry = destroy;
/* attempt to find the target entry in the hash table */
H5C__SEARCH_INDEX(cache_ptr, addr, entry_ptr, FAIL)
@@ -10126,7 +10990,7 @@ H5C_flush_single_entry(H5F_t * f,
if ( NULL == (dxpl = H5I_object(primary_dxpl_id)) ) {
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, \
- "not a dataset creation property list")
+ "not a dataset transfer property list")
}
/* Get the transfer mode property */
@@ -10158,6 +11022,16 @@ H5C_flush_single_entry(H5F_t * f,
H5C__UPDATE_STATS_FOR_EVICTION(cache_ptr, entry_ptr)
}
+ /* If the entry's type has a 'notify' callback and the entry is about
+ * to be removed from the cache, send a 'before eviction' notice while
+ * the entry is still fully integrated in the cache.
+ */
+ if(destroy) {
+ if(entry_ptr->type->notify &&
+ (entry_ptr->type->notify)(H5C_NOTIFY_ACTION_BEFORE_EVICT, entry_ptr) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, "can't notify client about entry to evict")
+ } /* end if */
+
/* Always remove the entry from the hash table on a destroy. On a
* flush with destroy, it is cheaper to discard the skip list all at
* once rather than remove the entries one by one, so we only delete
@@ -10167,8 +11041,8 @@ H5C_flush_single_entry(H5F_t * f,
* entry if destroy is true.
*
* Note that it is possible that the entry will be renamed during
- * its call to flush. This will upset H5C_rename_entry() if we
- * don't tell it that it doesn't have to worry about updating the
+ * its call to flush. This will upset H5C_rename_entry() if we
+ * don't tell it that it doesn't have to worry about updating the
* index and SLIST. Use the destroy_in_progress field for this
* purpose.
*/
@@ -10298,7 +11172,7 @@ H5C_flush_single_entry(H5F_t * f,
#ifndef NDEBUG
if ( destroy ) {
- /* we are about to call the clear callback with the
+ /* we are about to call the clear callback with the
* destroy flag set -- this will result in *entry_ptr
* being freed. Set the magic field to bad magic
* so we can detect a freed cache entry if we see
@@ -10308,7 +11182,7 @@ H5C_flush_single_entry(H5F_t * f,
}
#endif /* NDEBUG */
/* Call the callback routine to clear all dirty flags for object */
- if ( (entry_ptr->type->clear)(f, entry_ptr, destroy) < 0 ) {
+ if ( (entry_ptr->type->clear)(f, entry_ptr, destroy_entry) < 0 ) {
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "can't clear entry")
}
@@ -10326,7 +11200,7 @@ H5C_flush_single_entry(H5F_t * f,
#ifndef NDEBUG
if ( destroy ) {
- /* we are about to call the flush callback with the
+ /* we are about to call the flush callback with the
* destroy flag set -- this will result in *entry_ptr
* being freed. Set the magic field to bad magic
* so we can detect a freed cache entry if we see
@@ -10341,7 +11215,7 @@ H5C_flush_single_entry(H5F_t * f,
if ( *first_flush_ptr && entry_ptr->is_dirty ) {
- status = (entry_ptr->type->flush)(f, primary_dxpl_id, destroy,
+ status = (entry_ptr->type->flush)(f, primary_dxpl_id, destroy_entry,
entry_ptr->addr, entry_ptr,
&flush_flags);
*first_flush_ptr = FALSE;
@@ -10349,7 +11223,7 @@ H5C_flush_single_entry(H5F_t * f,
} else {
status = (entry_ptr->type->flush)(f, secondary_dxpl_id,
- destroy, entry_ptr->addr,
+ destroy_entry, entry_ptr->addr,
entry_ptr, &flush_flags);
}
@@ -10358,6 +11232,7 @@ H5C_flush_single_entry(H5F_t * f,
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
"unable to flush entry")
}
+
#ifdef H5_HAVE_PARALLEL
if ( flush_flags != H5C_CALLBACK__NO_FLAGS_SET ) {
@@ -10366,21 +11241,21 @@ H5C_flush_single_entry(H5F_t * f,
* die.
*
* At present, in the parallel case, the aux_ptr
- * will only be set if there is more than one
- * process. Thus we can use this to detect
+ * will only be set if there is more than one
+ * process. Thus we can use this to detect
* the parallel case.
*
- * This works for now, but if we start using the
- * aux_ptr for other purposes, we will have to
+ * This works for now, but if we start using the
+ * aux_ptr for other purposes, we will have to
* change this test accordingly.
*
* NB: While this test detects entryies that attempt
* to resize or rename themselves during a flush
* in the parallel case, it will not detect an
- * entry that dirties, resizes, and/or renames
+ * entry that dirties, resizes, and/or renames
* other entries during its flush.
*
- * From what Quincey tells me, this test is
+ * From what Quincey tells me, this test is
* sufficient for now, as any flush routine that
* does the latter will also do the former.
*
@@ -10400,6 +11275,12 @@ H5C_flush_single_entry(H5F_t * f,
if ( ( ! destroy ) && ( entry_ptr->in_slist ) ) {
H5C__REMOVE_ENTRY_FROM_SLIST(cache_ptr, entry_ptr)
+
+ }
+
+ if ( ( ! destroy ) && ( was_dirty ) ) {
+
+ H5C__UPDATE_INDEX_FOR_ENTRY_CLEAN(cache_ptr, entry_ptr);
}
if ( ! destroy ) { /* i.e. if the entry still exists */
@@ -10415,7 +11296,7 @@ H5C_flush_single_entry(H5F_t * f,
/* The entry size changed as a result of the flush.
*
- * Most likely, the entry was compressed, and the
+ * Most likely, the entry was compressed, and the
* new version is of a different size than the old.
*
* In any case, we must update entry and cache size
@@ -10423,7 +11304,7 @@ H5C_flush_single_entry(H5F_t * f,
*/
size_t new_size;
- if ( (entry_ptr->type->size)(f, (void *)entry_ptr, &new_size)
+ if ( (entry_ptr->type->size)(f, (void *)entry_ptr, &new_size)
< 0 ) {
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGETSIZE, FAIL, \
@@ -10434,20 +11315,28 @@ H5C_flush_single_entry(H5F_t * f,
HDassert( entry_ptr->size < H5C_MAX_ENTRY_SIZE );
- /* update the hash table for the size change*/
+ /* update the hash table for the size change
+ * We pass TRUE as the was_clean parameter, as we
+ * have already updated the clean and dirty index
+ * size fields for the fact that the entry has
+ * been flushed. (See above call to
+ * H5C__UPDATE_INDEX_FOR_ENTRY_CLEAN()).
+ */
H5C__UPDATE_INDEX_FOR_SIZE_CHANGE((cache_ptr), \
(entry_ptr->size),\
- (new_size));
+ (new_size), \
+ (entry_ptr), \
+ (TRUE));
/* The entry can't be protected since we just flushed it.
- * Thus we must update the replacement policy data
- * structures for the size change. The macro deals
+ * Thus we must update the replacement policy data
+ * structures for the size change. The macro deals
* with the pinned case.
*/
H5C__UPDATE_RP_FOR_SIZE_CHANGE(cache_ptr, entry_ptr, \
new_size)
- /* The entry can't be in the slist, so no need to update
+ /* The entry can't be in the slist, so no need to update
* the slist for the size change.
*/
@@ -10465,12 +11354,12 @@ H5C_flush_single_entry(H5F_t * f,
/* The entry was renamed as the result of the flush.
*
- * Most likely, the entry was compressed, and the
- * new version is larger than the old and thus had
+ * Most likely, the entry was compressed, and the
+ * new version is larger than the old and thus had
* to be relocated.
*
- * At preset, all processing for this case is
- * handled elsewhere. But lets keep the if statement
+ * At preset, all processing for this case is
+ * handled elsewhere. But lets keep the if statement
* around just in case.
*/
@@ -10522,7 +11411,7 @@ done:
*
* JRM - 6/23/06
* Deleted assertion that verified that a newly loaded
- * entry is clean. Due to a bug fix, this need not be
+ * entry is clean. Due to a bug fix, this need not be
* the case, as our code will attempt to repair errors
* on load.
*
@@ -10531,9 +11420,13 @@ done:
* destroy in progress fields.
*
* JRM - 3/29/07
- * Added initialization for the new is_read_only and
+ * Added initialization for the new is_read_only and
* ro_ref_count fields.
*
+ * QAK -- 1/31/08
+ * Added initialization for the new free_file_space_on_destroy
+ * field.
+ *
*-------------------------------------------------------------------------
*/
@@ -10551,8 +11444,9 @@ H5C_load_entry(H5F_t * f,
#endif /* NDEBUG */
{
void * thing = NULL;
- void * ret_value = NULL;
H5C_cache_entry_t * entry_ptr = NULL;
+ unsigned u; /* Local index variable */
+ void * ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5C_load_entry)
@@ -10571,10 +11465,10 @@ H5C_load_entry(H5F_t * f,
entry_ptr = (H5C_cache_entry_t *)thing;
/* In general, an entry should be clean just after it is loaded.
- *
+ *
* However, when this code is used in the metadata cache, it is
- * possible that object headers will be dirty at this point, as
- * the load function will alter object headers if necessary to
+ * possible that object headers will be dirty at this point, as
+ * the load function will alter object headers if necessary to
* fix an old bug.
*
* To support this bug fix, I have replace the old assert:
@@ -10588,7 +11482,7 @@ H5C_load_entry(H5F_t * f,
* Note that type id 4 is associated with object headers in the metadata
* cache.
*
- * When we get to using H5C for other purposes, we may wish to
+ * When we get to using H5C for other purposes, we may wish to
* tighten up the assert so that the loophole only applies to the
* metadata cache.
*/
@@ -10609,6 +11503,7 @@ H5C_load_entry(H5F_t * f,
#endif /* H5_HAVE_PARALLEL */
entry_ptr->flush_in_progress = FALSE;
entry_ptr->destroy_in_progress = FALSE;
+ entry_ptr->free_file_space_on_destroy = FALSE;
if ( (type->size)(f, thing, &(entry_ptr->size)) < 0 ) {
@@ -10618,6 +11513,12 @@ H5C_load_entry(H5F_t * f,
HDassert( entry_ptr->size < H5C_MAX_ENTRY_SIZE );
+ /* Initialize flush dependency height fields */
+ entry_ptr->flush_dep_parent = NULL;
+ for(u = 0; u < H5C__NUM_FLUSH_DEP_HEIGHTS; u++)
+ entry_ptr->child_flush_dep_height_rc[u] = 0;
+ entry_ptr->flush_dep_height = 0;
+
entry_ptr->ht_next = NULL;
entry_ptr->ht_prev = NULL;
@@ -10691,7 +11592,7 @@ done:
* min clean size before the cache has filled.
*
* JRM -- 3/29/07
- * Added sanity checks using the new is_read_only and
+ * Added sanity checks using the new is_read_only and
* ro_ref_count fields.
*
* JRM -- 10/13/07
@@ -10705,10 +11606,31 @@ done:
*
* Note that this is a pretty bad scenario if it ever
* happens. The code I have added should allow us to
- * handle the situation under all but the worst conditions,
- * but one can argue that I should just scream and die if I
+ * handle the situation under all but the worst conditions,
+ * but one can argue that I should just scream and die if I
* ever detect the condidtion.
*
+ * JRM -- 11/13/08
+ * Modified function to always observe the min_clean_size
+ * whether we are maintaining the clean and dirt LRU lists
+ * or not. To do this, we had to add the new clean_index_size
+ * and dirty_index_size fields to H5C_t, and supporting code
+ * as needed throughout the cache.
+ *
+ * The purpose of this modification is to avoid "metadata
+ * blizzards" in the write only case. In such instances,
+ * the cache was allowed to fill with dirty metadata. When
+ * we finally needed to evict an entry to make space, we had
+ * to flush out a whole cache full of metadata -- which has
+ * interesting performance effects. We hope to avoid (or
+ * perhaps more accurately hide) this effect by maintaining
+ * the min_clean_size, which should force us to start flushing
+ * entries long before we actually have to evict something
+ * to make space.
+ *
+ * MAM -- 01/06/09
+ * Added code to maintain clean_entries_skipped and total_entries
+ * scanned statistics.
*-------------------------------------------------------------------------
*/
@@ -10723,13 +11645,15 @@ H5C_make_space_in_cache(H5F_t * f,
{
herr_t ret_value = SUCCEED; /* Return value */
herr_t result;
+#if H5C_COLLECT_CACHE_STATS
+ int32_t clean_entries_skipped = 0;
+ int32_t total_entries_scanned = 0;
+#endif /* H5C_COLLECT_CACHE_STATS */
int32_t entries_examined = 0;
int32_t initial_list_len;
-#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS
size_t empty_space;
-#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */
hbool_t prev_is_dirty = FALSE;
- hbool_t entry_is_epoch_maker = FALSE;
+ hbool_t didnt_flush_entry = FALSE;
H5C_cache_entry_t * entry_ptr;
H5C_cache_entry_t * next_ptr;
H5C_cache_entry_t * prev_ptr;
@@ -10740,16 +11664,36 @@ H5C_make_space_in_cache(H5F_t * f,
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
HDassert( first_flush_ptr != NULL );
HDassert( ( *first_flush_ptr == TRUE ) || ( *first_flush_ptr == FALSE ) );
+ HDassert( cache_ptr->index_size ==
+ (cache_ptr->clean_index_size + cache_ptr->dirty_index_size) );
if ( write_permitted ) {
initial_list_len = cache_ptr->LRU_list_len;
+
entry_ptr = cache_ptr->LRU_tail_ptr;
- while ( ( (cache_ptr->index_size + space_needed)
- >
- cache_ptr->max_cache_size
- )
+ if ( cache_ptr->index_size >= cache_ptr->max_cache_size ) {
+
+ empty_space = 0;
+
+ } else {
+
+ empty_space = cache_ptr->max_cache_size - cache_ptr->index_size;
+
+ }
+
+ while ( ( ( (cache_ptr->index_size + space_needed)
+ >
+ cache_ptr->max_cache_size
+ )
+ ||
+ (
+ ( empty_space + cache_ptr->clean_index_size )
+ <
+ ( cache_ptr->min_clean_size )
+ )
+ )
&&
( entries_examined <= (2 * initial_list_len) )
&&
@@ -10770,10 +11714,18 @@ H5C_make_space_in_cache(H5F_t * f,
if ( (entry_ptr->type)->id != H5C__EPOCH_MARKER_TYPE ) {
- entry_is_epoch_maker = FALSE;
+ didnt_flush_entry = FALSE;
if ( entry_ptr->is_dirty ) {
+#if H5C_COLLECT_CACHE_STATS
+ if ( (cache_ptr->index_size + space_needed)
+ >
+ cache_ptr->max_cache_size ) {
+
+ cache_ptr->entries_scanned_to_make_space++;
+ }
+#endif /* H5C_COLLECT_CACHE_STATS */
result = H5C_flush_single_entry(f,
primary_dxpl_id,
secondary_dxpl_id,
@@ -10783,7 +11735,12 @@ H5C_make_space_in_cache(H5F_t * f,
H5C__NO_FLAGS_SET,
first_flush_ptr,
FALSE);
- } else {
+ } else if ( (cache_ptr->index_size + space_needed)
+ >
+ cache_ptr->max_cache_size ) {
+#if H5C_COLLECT_CACHE_STATS
+ cache_ptr->entries_scanned_to_make_space++;
+#endif /* H5C_COLLECT_CACHE_STATS */
result = H5C_flush_single_entry(f,
primary_dxpl_id,
@@ -10794,13 +11751,31 @@ H5C_make_space_in_cache(H5F_t * f,
H5C__FLUSH_INVALIDATE_FLAG,
first_flush_ptr,
TRUE);
+ } else {
+
+ /* We have enough space so don't flush clean entry.
+ * Set result to SUCCEED to avoid triggering the error
+ * code below.
+ */
+#if H5C_COLLECT_CACHE_STATS
+ clean_entries_skipped++;
+#endif /* H5C_COLLECT_CACHE_STATS */
+ didnt_flush_entry = TRUE;
+ result = SUCCEED;
+
}
+
+#if H5C_COLLECT_CACHE_STATS
+ total_entries_scanned++;
+#endif /* H5C_COLLECT_CACHE_STATS */
+
+
} else {
/* Skip epoch markers. Set result to SUCCEED to avoid
* triggering the error code below.
*/
- entry_is_epoch_maker = TRUE;
+ didnt_flush_entry = TRUE;
result = SUCCEED;
}
@@ -10822,8 +11797,8 @@ H5C_make_space_in_cache(H5F_t * f,
}
#endif /* NDEBUG */
- if ( entry_is_epoch_maker ) {
-
+ if ( didnt_flush_entry ) {
+
entry_ptr = prev_ptr;
} else if ( ( prev_ptr->is_dirty != prev_is_dirty )
@@ -10853,121 +11828,52 @@ H5C_make_space_in_cache(H5F_t * f,
entries_examined++;
- }
-
-#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS
-
- entries_examined = 0;
- initial_list_len = cache_ptr->dLRU_list_len;
- entry_ptr = cache_ptr->dLRU_tail_ptr;
-
- if ( cache_ptr->index_size < cache_ptr->max_cache_size ) {
-
- empty_space = cache_ptr->max_cache_size - cache_ptr->index_size;
-
- } else {
-
- empty_space = 0;
- }
+ if ( cache_ptr->index_size >= cache_ptr->max_cache_size ) {
- while ( ( (cache_ptr->cLRU_list_size + empty_space)
- < cache_ptr->min_clean_size ) &&
- ( entries_examined <= initial_list_len ) &&
- ( entry_ptr != NULL )
- )
- {
- HDassert( ! (entry_ptr->is_protected) );
- HDassert( ! (entry_ptr->is_read_only) );
- HDassert( (entry_ptr->ro_ref_count) == 0 );
- HDassert( entry_ptr->is_dirty );
- HDassert( entry_ptr->in_slist );
-
- prev_ptr = entry_ptr->aux_prev;
-
- next_ptr = entry_ptr->aux_next;
-
- if ( prev_ptr != NULL ) {
+ empty_space = 0;
- HDassert( prev_ptr->is_dirty );
- }
-
- result = H5C_flush_single_entry(f,
- primary_dxpl_id,
- secondary_dxpl_id,
- cache_ptr,
- entry_ptr->type,
- entry_ptr->addr,
- H5C__NO_FLAGS_SET,
- first_flush_ptr,
- FALSE);
+ } else {
- if ( result < 0 ) {
+ empty_space = cache_ptr->max_cache_size - cache_ptr->index_size;
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "unable to flush entry")
- }
+ }
+
+ HDassert( cache_ptr->index_size ==
+ (cache_ptr->clean_index_size +
+ cache_ptr->dirty_index_size) );
- if ( prev_ptr != NULL ) {
-#ifndef NDEBUG
- if (prev_ptr->magic != H5C__H5C_CACHE_ENTRY_T_MAGIC) {
+ }
- /* something horrible has happened to *prev_ptr --
- * scream and die.
- */
+#if H5C_COLLECT_CACHE_STATS
+ cache_ptr->calls_to_msic++;
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "*prev_ptr corrupt 2")
-
- } else
-#endif /* #ifndef NDEBUG */
- if ( ( ! ( prev_ptr->is_dirty ) )
- ||
- ( prev_ptr->aux_next != next_ptr )
- ||
- ( prev_ptr->is_protected )
- ||
- ( prev_ptr->is_pinned ) ) {
-
- /* something has happened to the dirty LRU -- start over
- * from the tail.
- */
-#if 0 /* This debuging code may be useful in the future -- keep it for now. */
- if ( ! ( prev_ptr->is_dirty ) ) {
- HDfprintf(stdout, "%s: ! prev_ptr->is_dirty\n",
- fcn_name);
- }
- if ( prev_ptr->aux_next != next_ptr ) {
- HDfprintf(stdout, "%s: prev_ptr->next != next_ptr\n",
- fcn_name);
- }
- if ( prev_ptr->is_protected ) {
- HDfprintf(stdout, "%s: prev_ptr->is_protected\n",
- fcn_name);
- }
- if ( prev_ptr->is_pinned ) {
- HDfprintf(stdout, "%s:prev_ptr->is_pinned\n",
- fcn_name);
- }
+ cache_ptr->total_entries_skipped_in_msic += clean_entries_skipped;
+ cache_ptr->total_entries_scanned_in_msic += total_entries_scanned;
- HDfprintf(stdout, "%s: re-starting scan of dirty list\n",
- fcn_name);
-#endif /* JRM */
- entry_ptr = cache_ptr->dLRU_tail_ptr;
+ if ( clean_entries_skipped > cache_ptr->max_entries_skipped_in_msic ) {
- } else {
+ cache_ptr->max_entries_skipped_in_msic = clean_entries_skipped;
+ }
- entry_ptr = prev_ptr;
+ if ( total_entries_scanned > cache_ptr->max_entries_scanned_in_msic ) {
- }
- } else {
+ cache_ptr->max_entries_scanned_in_msic = total_entries_scanned;
+ }
+#endif /* H5C_COLLECT_CACHE_STATS */
- entry_ptr = NULL;
+ HDassert( ( entries_examined > (2 * initial_list_len) ) ||
+ ( (cache_ptr->pl_size + cache_ptr->min_clean_size) >
+ cache_ptr->max_cache_size ) ||
+ ( ( cache_ptr->clean_index_size + empty_space )
+ >= cache_ptr->min_clean_size ) );
- }
+#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS
- entries_examined++;
- }
+ HDassert( ( entries_examined > (2 * initial_list_len) ) ||
+ ( cache_ptr->cLRU_list_size <= cache_ptr->clean_index_size ) );
+ HDassert( ( entries_examined > (2 * initial_list_len) ) ||
+ ( cache_ptr->dLRU_list_size <= cache_ptr->dirty_index_size ) );
#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */
diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h
index 7c04ea2..4bc105d 100644
--- a/src/H5Cpkg.h
+++ b/src/H5Cpkg.h
@@ -43,12 +43,12 @@
/* Get needed headers */
#include "H5SLprivate.h" /* Skip lists */
-/* With the introduction of the fractal heap, it is now possible for
+/* With the introduction of the fractal heap, it is now possible for
* entries to be dirtied, resized, and/or renamed in the flush callbacks.
* As a result, on flushes, it may be necessary to make multiple passes
* through the slist before it is empty. The H5C__MAX_PASSES_ON_FLUSH
* #define is used to set an upper limit on the number of passes.
- * The current value was obtained via personal communication with
+ * The current value was obtained via personal communication with
* Quincey. I have applied a fudge factor of 2.
*/
@@ -99,7 +99,7 @@
* magic: Unsigned 32 bit integer always set to H5C__H5C_T_MAGIC. This
* field is used to validate pointers to instances of H5C_t.
*
- * flush_in_progress: Boolean flag indicating whether a flush is in
+ * flush_in_progress: Boolean flag indicating whether a flush is in
* progress.
*
* trace_file_ptr: File pointer pointing to the trace file, which is used
@@ -108,7 +108,7 @@
* no trace file should be recorded.
*
* Since much of the code supporting the parallel metadata
- * cache is in H5AC, we don't write the trace file from
+ * cache is in H5AC, we don't write the trace file from
* H5C. Instead, H5AC reads the trace_file_ptr as needed.
*
* When we get to using H5C in other places, we may add
@@ -181,10 +181,10 @@
* writes. The following field is used to implement this.
*
* evictions_enabled: Boolean flag that is initialized to TRUE. When
- * this flag is set to FALSE, the metadata cache will not
+ * this flag is set to FALSE, the metadata cache will not
* attempt to evict entries to make space for newly protected
* entries, and instead the will grow without limit.
- *
+ *
* Needless to say, this feature must be used with care.
*
*
@@ -203,6 +203,38 @@
* index_size by two should yield a conservative estimate
* of the cache's memory footprint.
*
+ * clean_index_size: Number of bytes of clean entries currently stored in
+ * the hash table. Note that the index_size field (above)
+ * is also the sum of the sizes of all entries in the cache.
+ * Thus we should have the invarient that clean_index_size +
+ * dirty_index_size == index_size.
+ *
+ * WARNING:
+ *
+ * 1) The clean_index_size field is not maintained by the
+ * index macros, as the hash table doesn't care whether
+ * the entry is clean or dirty. Instead the field is
+ * maintained in the H5C__UPDATE_RP macros.
+ *
+ * 2) The value of the clean_index_size must not be mistaken
+ * for the current clean size of the cache. Rather, the
+ * clean size of the cache is the current value of
+ * clean_index_size plus the amount of empty space (if any)
+ * in the cache.
+ *
+ * dirty_index_size: Number of bytes of dirty entries currently stored in
+ * the hash table. Note that the index_size field (above)
+ * is also the sum of the sizes of all entries in the cache.
+ * Thus we should have the invarient that clean_index_size +
+ * dirty_index_size == index_size.
+ *
+ * WARNING:
+ *
+ * 1) The dirty_index_size field is not maintained by the
+ * index macros, as the hash table doesn't care whether
+ * the entry is clean or dirty. Instead the field is
+ * maintained in the H5C__UPDATE_RP macros.
+ *
* index: Array of pointer to H5C_cache_entry_t of size
* H5C__HASH_TABLE_LEN. At present, this value is a power
* of two, not the usual prime number.
@@ -255,7 +287,7 @@
* following two fields have been added. They are only compiled in when
* H5C_DO_SANITY_CHECKS is TRUE.
*
- * slist_len_increase: Number of entries that have been added to the
+ * slist_len_increase: Number of entries that have been added to the
* slist since the last time this field was set to zero.
*
* slist_size_increase: Total size of all entries that have been added
@@ -468,13 +500,13 @@
* flash_size_increase_possible: Depending on the configuration data given
* in the resize_ctl field, it may or may not be possible
* for a flash size increase to occur. We set this flag
- * whenever we receive a new configuration so as to avoid
+ * whenever we receive a new configuration so as to avoid
* repeated calculations.
*
* flash_size_increase_threshold: If a flash cache size increase is possible,
* this field is used to store the minimum size of a new entry
- * or size increase needed to trigger a flash cache size
- * increase. Note that this field must be updated whenever
+ * or size increase needed to trigger a flash cache size
+ * increase. Note that this field must be updated whenever
* the size of the cache is changed.
*
* size_decrease_possible: Depending on the configuration data given
@@ -592,9 +624,9 @@
* equal to the array index has not been in cache when
* requested in the current epoch.
*
- * write_protects: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1. The
- * cells are used to record the number of times an entry with
- * type id equal to the array index has been write protected
+ * write_protects: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1. The
+ * cells are used to record the number of times an entry with
+ * type id equal to the array index has been write protected
* in the current epoch.
*
* Observe that (hits + misses) = (write_protects + read_protects).
@@ -606,9 +638,9 @@
*
* Observe that (hits + misses) = (write_protects + read_protects).
*
- * max_read_protects: Array of int32 of length H5C__MAX_NUM_TYPE_IDS + 1.
- * The cells are used to maximum number of simultaneous read
- * protects on any entry with type id equal to the array index
+ * max_read_protects: Array of int32 of length H5C__MAX_NUM_TYPE_IDS + 1.
+ * The cells are used to maximum number of simultaneous read
+ * protects on any entry with type id equal to the array index
* in the current epoch.
*
* insertions: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1. The cells
@@ -616,9 +648,9 @@
* id equal to the array index has been inserted into the
* cache in the current epoch.
*
- * pinned_insertions: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1.
- * The cells are used to record the number of times an entry
- * with type id equal to the array index has been inserted
+ * pinned_insertions: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1.
+ * The cells are used to record the number of times an entry
+ * with type id equal to the array index has been inserted
* pinned into the cache in the current epoch.
*
* clears: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1. The cells
@@ -641,13 +673,13 @@
* id equal to the array index has been renamed in the current
* epoch.
*
- * entry_flush_renames: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1.
- * The cells are used to record the number of times an entry
+ * entry_flush_renames: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1.
+ * The cells are used to record the number of times an entry
* with type id equal to the array index has been renamed
* during its flush callback in the current epoch.
*
- * cache_flush_renames: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1.
- * The cells are used to record the number of times an entry
+ * cache_flush_renames: Array of int64 of length H5C__MAX_NUM_TYPE_IDS + 1.
+ * The cells are used to record the number of times an entry
* with type id equal to the array index has been renamed
* during a cache flush in the current epoch.
*
@@ -686,14 +718,14 @@
* with type id equal to the array index has decreased in
* size in the current epoch.
*
- * entry_flush_size_changes: Array of int64 of length
- * H5C__MAX_NUM_TYPE_IDS + 1. The cells are used to record
- * the number of times an entry with type id equal to the
+ * entry_flush_size_changes: Array of int64 of length
+ * H5C__MAX_NUM_TYPE_IDS + 1. The cells are used to record
+ * the number of times an entry with type id equal to the
* array index has changed size while in its flush callback.
*
- * cache_flush_size_changes: Array of int64 of length
- * H5C__MAX_NUM_TYPE_IDS + 1. The cells are used to record
- * the number of times an entry with type id equal to the
+ * cache_flush_size_changes: Array of int64 of length
+ * H5C__MAX_NUM_TYPE_IDS + 1. The cells are used to record
+ * the number of times an entry with type id equal to the
* array index has changed size during a cache flush
*
* total_ht_insertions: Number of times entries have been inserted into the
@@ -722,6 +754,12 @@
* max_index_size: Largest value attained by the index_size field in the
* current epoch.
*
+ * max_clean_index_size: Largest value attained by the clean_index_size field
+ * in the current epoch.
+ *
+ * max_dirty_index_size: Largest value attained by the dirty_index_size field
+ * in the current epoch.
+ *
* max_slist_len: Largest value attained by the slist_len field in the
* current epoch.
*
@@ -740,6 +778,23 @@
* max_pel_size: Largest value attained by the pel_size field in the
* current epoch.
*
+ * calls_to_msic: Total number of calls to H5C_make_space_in_cache
+ *
+ * total_entries_skipped_in_msic: Number of clean entries skipped while
+ * enforcing the min_clean_fraction in H5C_make_space_in_cache().
+ *
+ * total_entries_scanned_in_msic: Number of clean entries skipped while
+ * enforcing the min_clean_fraction in H5C_make_space_in_cache().
+ *
+ * max_entries_skipped_in_msic: Maximum number of clean entries skipped
+ * in any one call to H5C_make_space_in_cache().
+ *
+ * max_entries_scanned_in_msic: Maximum number of entries scanned over
+ * in any one call to H5C_make_space_in_cache().
+ *
+ * entries_scanned_to_make_space: Number of entries scanned only when looking
+ * for entries to evict in order to make space in cache.
+
* The remaining stats are collected only when both H5C_COLLECT_CACHE_STATS
* and H5C_COLLECT_CACHE_ENTRY_STATS are true.
*
@@ -802,7 +857,7 @@
****************************************************************************/
#define H5C__H5C_T_MAGIC 0x005CAC0E
-#define H5C__MAX_NUM_TYPE_IDS 16
+#define H5C__MAX_NUM_TYPE_IDS 25
#define H5C__PREFIX_LEN 32
struct H5C_t
@@ -830,6 +885,8 @@ struct H5C_t
int32_t index_len;
size_t index_size;
+ size_t clean_index_size;
+ size_t dirty_index_size;
H5C_cache_entry_t * (index[H5C__HASH_TABLE_LEN]);
@@ -868,7 +925,7 @@ struct H5C_t
hbool_t size_increase_possible;
hbool_t flash_size_increase_possible;
- size_t flash_size_increase_threshold;
+ size_t flash_size_increase_threshold;
hbool_t size_decrease_possible;
hbool_t resize_enabled;
hbool_t cache_full;
@@ -923,6 +980,8 @@ struct H5C_t
int32_t max_index_len;
size_t max_index_size;
+ size_t max_clean_index_size;
+ size_t max_dirty_index_size;
int32_t max_slist_len;
size_t max_slist_size;
@@ -933,6 +992,13 @@ struct H5C_t
int32_t max_pel_len;
size_t max_pel_size;
+ int64_t calls_to_msic;
+ int64_t total_entries_skipped_in_msic;
+ int64_t total_entries_scanned_in_msic;
+ int32_t max_entries_skipped_in_msic;
+ int32_t max_entries_scanned_in_msic;
+ int64_t entries_scanned_to_make_space;
+
#if H5C_COLLECT_CACHE_ENTRY_STATS
int32_t max_accesses[H5C__MAX_NUM_TYPE_IDS + 1];
diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h
index 53dcf0d..5c7fe9f 100644
--- a/src/H5Cprivate.h
+++ b/src/H5Cprivate.h
@@ -32,7 +32,7 @@
#include "H5Cpublic.h" /*public prototypes */
-/* Pivate headers needed by this header */
+/* Private headers needed by this header */
#include "H5private.h" /* Generic Functions */
#include "H5Fprivate.h" /* File access */
@@ -46,7 +46,7 @@
*
* JRM - 5/17/04
*/
-#define H5C_MAX_ENTRY_SIZE ((size_t)(10 * 1024 * 1024))
+#define H5C_MAX_ENTRY_SIZE ((size_t)(32 * 1024 * 1024))
/* H5C_COLLECT_CACHE_STATS controls overall collection of statistics
* on cache activity. In general, this #define should be set to 0.
@@ -113,6 +113,9 @@ typedef struct H5C_t H5C_t;
*
* CLEAR: Just marks object as non-dirty.
*
+ * NOTIFY: Notify client that an action on an entry has taken/will take
+ * place
+ *
* SIZE: Report the size (on disk) of the specified cache object.
* Note that the space allocated on disk may not be contiguous.
*/
@@ -121,6 +124,16 @@ typedef struct H5C_t H5C_t;
#define H5C_CALLBACK__SIZE_CHANGED_FLAG 0x1
#define H5C_CALLBACK__RENAMED_FLAG 0x2
+/* Actions that can be reported to 'notify' client callback */
+typedef enum H5C_notify_action_t {
+ H5C_NOTIFY_ACTION_AFTER_INSERT, /* Entry has been added to the cache */
+ /* (could be loaded from file with
+ * 'protect' call, or inserted
+ * with 'set' call)
+ */
+ H5C_NOTIFY_ACTION_BEFORE_EVICT /* Entry is about to be evicted from cache */
+} H5C_notify_action_t;
+
typedef void *(*H5C_load_func_t)(H5F_t *f,
hid_t dxpl_id,
haddr_t addr,
@@ -137,6 +150,8 @@ typedef herr_t (*H5C_dest_func_t)(H5F_t *f,
typedef herr_t (*H5C_clear_func_t)(H5F_t *f,
void *thing,
hbool_t dest);
+typedef herr_t (*H5C_notify_func_t)(H5C_notify_action_t action,
+ void *thing);
typedef herr_t (*H5C_size_func_t)(const H5F_t *f,
const void *thing,
size_t *size_ptr);
@@ -147,6 +162,7 @@ typedef struct H5C_class_t {
H5C_flush_func_t flush;
H5C_dest_func_t dest;
H5C_clear_func_t clear;
+ H5C_notify_func_t notify;
H5C_size_func_t size;
} H5C_class_t;
@@ -183,6 +199,16 @@ typedef herr_t (*H5C_log_flush_func_t)(H5C_t * cache_ptr,
#define H5C__DEFAULT_MAX_CACHE_SIZE ((size_t)(4 * 1024 * 1024))
#define H5C__DEFAULT_MIN_CLEAN_SIZE ((size_t)(2 * 1024 * 1024))
+/* Maximum height of flush dependency relationships between entries. This is
+ * currently tuned to the extensible array (H5EA) data structure, which only
+ * requires 6 levels of dependency (i.e. heights 0-6) (actually, the extensible
+ * array needs 4 levels, plus another 2 levels are needed: one for the layer
+ * under the extensible array and one for the layer above it).
+ */
+
+#define H5C__NUM_FLUSH_DEP_HEIGHTS 6
+
+
/****************************************************************************
*
@@ -222,7 +248,7 @@ typedef herr_t (*H5C_log_flush_func_t)(H5C_t * cache_ptr,
* of the LRU when this situation occurs.
*
* This field is only compiled in debug mode.
- *
+ *
* addr: Base address of the cache entry on disk.
*
* size: Length of the cache entry on disk. Note that unlike normal
@@ -286,20 +312,20 @@ typedef herr_t (*H5C_log_flush_func_t)(H5C_t * cache_ptr,
* Note that protected entries are removed from the LRU lists
* and inserted on the protected list.
*
- * is_read_only: Boolean flag that is only meaningful if is_protected is
- * TRUE. In this circumstance, it indicates whether the
+ * is_read_only: Boolean flag that is only meaningful if is_protected is
+ * TRUE. In this circumstance, it indicates whether the
* entry has been protected read only, or read/write.
*
* If the entry has been protected read only (i.e. is_protected
- * and is_read_only are both TRUE), we allow the entry to be
+ * and is_read_only are both TRUE), we allow the entry to be
* protected more than once.
*
- * In this case, the number of readers is maintained in the
+ * In this case, the number of readers is maintained in the
* ro_ref_count field (see below), and unprotect calls simply
* decrement that field until it drops to zero, at which point
* the entry is actually unprotected.
*
- * ro_ref_count: Integer field used to maintain a count of the number of
+ * ro_ref_count: Integer field used to maintain a count of the number of
* outstanding read only protects on this entry. This field
* must be zero whenever either is_protected or is_read_only
* are TRUE.
@@ -361,9 +387,45 @@ typedef herr_t (*H5C_log_flush_func_t)(H5C_t * cache_ptr,
* is in the process of being flushed. This allows the cache
* to detect when a call is the result of a flush callback.
*
- * destroy_in_progress: Boolean flag that is set to true iff the entry
+ * destroy_in_progress: Boolean flag that is set to true iff the entry
* is in the process of being flushed and destroyed.
*
+ * free_file_space_on_destroy: Boolean flag that is set to true iff the entry
+ * is in the process of being flushed and destroyed and the file
+ * space used by the object should be freed by the cache client's
+ * 'dest' callback routine.
+ *
+ *
+ * Fields supporting the 'flush dependency' feature:
+ *
+ * Entries in the cache may have a 'flush dependency' on another entry in the
+ * cache. A flush dependency requires that all dirty child entries be flushed
+ * to the file before a dirty parent entry (of those child entries) can be
+ * flushed to the file. This can be used by cache clients to create data
+ * structures that allow Single-Writer/Multiple-Reader (SWMR) access for the
+ * data structure.
+ *
+ * The leaf child entry will have a "height" of 0, with any parent entries
+ * having a height of 1 greater than the maximum height of any of their child
+ * entries (flush dependencies are allowed to create asymmetric trees of
+ * relationships).
+ *
+ * flush_dep_parent: Pointer to the parent entry for an entry in a flush
+ * dependency relationship.
+ *
+ * child_flush_dep_height_rc: An array of reference counts for child entries,
+ * where the number of children of each height is tracked.
+ *
+ * flush_dep_height: The height of the entry, which is one greater than the
+ * maximum height of any of its child entries..
+ *
+ * pinned_from_client: Whether the entry was pinned by an explicit pin request
+ * from a cache client.
+ *
+ * pinned_from_cache: Whether the entry was pinned implicitly as a
+ * request of being a parent entry in a flush dependency
+ * relationship.
+ *
*
* Fields supporting the hash table:
*
@@ -489,6 +551,15 @@ typedef struct H5C_cache_entry_t
#endif /* H5_HAVE_PARALLEL */
hbool_t flush_in_progress;
hbool_t destroy_in_progress;
+ hbool_t free_file_space_on_destroy;
+
+ /* fields supporting the 'flush dependency' feature: */
+
+ struct H5C_cache_entry_t * flush_dep_parent;
+ uint64_t child_flush_dep_height_rc[H5C__NUM_FLUSH_DEP_HEIGHTS];
+ unsigned flush_dep_height;
+ hbool_t pinned_from_client;
+ hbool_t pinned_from_cache;
/* fields supporting the hash table: */
@@ -623,21 +694,21 @@ typedef struct H5C_cache_entry_t
*
* The addition of the flash increment mode was occasioned by performance
* problems that appear when a local heap is increased to a size in excess
- * of the current cache size. While the existing re-size code dealt with
- * this eventually, performance was very bad for the remainder of the
+ * of the current cache size. While the existing re-size code dealt with
+ * this eventually, performance was very bad for the remainder of the
* epoch.
- *
+ *
* At present, there are two possible values for the flash_incr_mode:
*
- * H5C_flash_incr__off: Don't perform flash increases in the size of
- * the cache.
+ * H5C_flash_incr__off: Don't perform flash increases in the size of
+ * the cache.
*
- * H5C_flash_incr__add_space: Let x be either the size of a newly
- * newly inserted entry, or the number of bytes by which the
+ * H5C_flash_incr__add_space: Let x be either the size of a newly
+ * newly inserted entry, or the number of bytes by which the
* size of an existing entry has been increased.
*
- * If
- * x > flash_threshold * current max cache size,
+ * If
+ * x > flash_threshold * current max cache size,
*
* increase the current maximum cache size by x * flash_multiple
* less any free space in the cache, and start a new epoch. For
@@ -646,28 +717,28 @@ typedef struct H5C_cache_entry_t
*
* With a little thought, it should be obvious that the above flash
* cache size increase algorithm is not sufficient for all circumstances --
- * for example, suppose the user round robins through
- * (1/flash_threshold) +1 groups, adding one data set to each on each
- * pass. Then all will increase in size at about the same time, requiring
- * the max cache size to at least double to maintain acceptable
- * performance, however the above flash increment algorithm will not be
+ * for example, suppose the user round robins through
+ * (1/flash_threshold) +1 groups, adding one data set to each on each
+ * pass. Then all will increase in size at about the same time, requiring
+ * the max cache size to at least double to maintain acceptable
+ * performance, however the above flash increment algorithm will not be
* triggered.
*
- * Hopefully, the add space algorithm detailed above will be sufficient
- * for the performance problems encountered to date. However, we should
+ * Hopefully, the add space algorithm detailed above will be sufficient
+ * for the performance problems encountered to date. However, we should
* expect to revisit the issue.
*
- * flash_multiple: Double containing the multiple described above in the
- * H5C_flash_incr__add_space section of the discussion of the
- * flash_incr_mode section. This field is ignored unless flash_incr_mode
+ * flash_multiple: Double containing the multiple described above in the
+ * H5C_flash_incr__add_space section of the discussion of the
+ * flash_incr_mode section. This field is ignored unless flash_incr_mode
* is H5C_flash_incr__add_space.
*
* flash_threshold: Double containing the factor by which current max cache size
- * is multiplied to obtain the size threshold for the add_space flash
- * increment algorithm. The field is ignored unless flash_incr_mode is
+ * is multiplied to obtain the size threshold for the add_space flash
+ * increment algorithm. The field is ignored unless flash_incr_mode is
* H5C_flash_incr__add_space.
*
- *
+ *
* Cache size decrease control fields:
*
* decr_mode: Instance of the H5C_cache_decr_mode enumerated type whose
@@ -893,7 +964,12 @@ typedef struct H5C_auto_size_ctl_t
* H5C__SIZE_CHANGED_FLAG
* H5C__PIN_ENTRY_FLAG
* H5C__UNPIN_ENTRY_FLAG
+ * H5C__FREE_FILE_SPACE_FLAG
+ * H5C__TAKE_OWNERSHIP_FLAG
+ *
+ * These flags apply to H5C_expunge_entry():
*
+ * H5C__FREE_FILE_SPACE_FLAG
*
* These flags apply to H5C_flush_cache():
*
@@ -908,6 +984,7 @@ typedef struct H5C_auto_size_ctl_t
* H5C__FLUSH_INVALIDATE_FLAG
* H5C__FLUSH_CLEAR_ONLY_FLAG
* H5C__FLUSH_MARKED_ENTRIES_FLAG
+ * H5C__TAKE_OWNERSHIP_FLAG
*/
#define H5C__NO_FLAGS_SET 0x0000
@@ -922,6 +999,8 @@ typedef struct H5C_auto_size_ctl_t
#define H5C__FLUSH_MARKED_ENTRIES_FLAG 0x0100
#define H5C__FLUSH_IGNORE_PROTECTED_FLAG 0x0200
#define H5C__READ_ONLY_FLAG 0x0400
+#define H5C__FREE_FILE_SPACE_FLAG 0x0800
+#define H5C__TAKE_OWNERSHIP_FLAG 0x1000
H5_DLL H5C_t * H5C_create(size_t max_cache_size,
@@ -947,14 +1026,13 @@ H5_DLL herr_t H5C_dest(H5F_t * f,
hid_t secondary_dxpl_id,
H5C_t * cache_ptr);
-H5_DLL herr_t H5C_dest_empty(H5C_t * cache_ptr);
-
H5_DLL herr_t H5C_expunge_entry(H5F_t * f,
hid_t primary_dxpl_id,
hid_t secondary_dxpl_id,
H5C_t * cache_ptr,
const H5C_class_t * type,
- haddr_t addr);
+ haddr_t addr,
+ unsigned flags);
H5_DLL herr_t H5C_flush_cache(H5F_t * f,
hid_t primary_dxpl_id,
@@ -985,7 +1063,9 @@ H5_DLL herr_t H5C_get_entry_status(H5C_t * cache_ptr,
hbool_t * in_cache_ptr,
hbool_t * is_dirty_ptr,
hbool_t * is_protected_ptr,
- hbool_t * is_pinned_ptr);
+ hbool_t * is_pinned_ptr,
+ hbool_t * is_flush_dep_parent_ptr,
+ hbool_t * is_flush_dep_child_ptr);
H5_DLL herr_t H5C_get_evictions_enabled(H5C_t * cache_ptr,
hbool_t * evictions_enabled_ptr);
@@ -1025,6 +1105,9 @@ H5_DLL herr_t H5C_rename_entry(H5C_t * cache_ptr,
H5_DLL herr_t H5C_pin_protected_entry(H5C_t * cache_ptr,
void * thing);
+H5_DLL herr_t H5C_create_flush_dependency(H5C_t *cache_ptr, void *parent_thing,
+ void *child_thing);
+
H5_DLL void * H5C_protect(H5F_t * f,
hid_t primary_dxpl_id,
hid_t secondary_dxpl_id,
@@ -1064,6 +1147,9 @@ H5_DLL void H5C_stats__reset(H5C_t * cache_ptr);
H5_DLL herr_t H5C_unpin_entry(H5C_t * cache_ptr, void * thing);
+H5_DLL herr_t H5C_destroy_flush_dependency(H5C_t *cache_ptr, void *parent_thing,
+ void *child_thing);
+
H5_DLL herr_t H5C_unprotect(H5F_t * f,
hid_t primary_dxpl_id,
hid_t secondary_dxpl_id,
diff --git a/src/H5D.c b/src/H5D.c
index 81140eb..bb5e772 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -169,7 +169,7 @@ H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
if(NULL == (dset = H5D_create_named(&loc, name, type_id, space, lcpl_id,
dcpl_id, dapl_id, H5AC_dxpl_id)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset")
- if((ret_value = H5I_register(H5I_DATASET, dset)) < 0)
+ if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset")
done:
@@ -249,11 +249,11 @@ H5Dcreate_anon(hid_t loc_id, hid_t type_id, hid_t space_id, hid_t dcpl_id,
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list")
/* build and open the new dataset */
- if(NULL == (dset = H5D_create(loc.oloc->file, type_id, space, dcpl_id, H5AC_dxpl_id)))
+ if(NULL == (dset = H5D_create(loc.oloc->file, type_id, space, dcpl_id, dapl_id, H5AC_dxpl_id)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset")
/* Register the new dataset to get an ID for it */
- if((ret_value = H5I_register(H5I_DATASET, dset)) < 0)
+ if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset")
done:
@@ -328,11 +328,11 @@ H5Dopen2(hid_t loc_id, const char *name, hid_t dapl_id)
HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataset")
/* Open the dataset */
- if((dset = H5D_open(&dset_loc, dxpl_id)) == NULL)
+ if((dset = H5D_open(&dset_loc, dapl_id, dxpl_id)) == NULL)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open dataset")
/* Register an atom for the dataset */
- if((ret_value = H5I_register(H5I_DATASET, dset)) < 0)
+ if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "can't register dataset atom")
done:
@@ -368,21 +368,20 @@ done:
herr_t
H5Dclose(hid_t dset_id)
{
- H5D_t *dset; /* Dataset object to release */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Dclose, FAIL)
H5TRACE1("e", "i", dset_id);
/* Check args */
- if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
+ if(NULL == H5I_object_verify(dset_id, H5I_DATASET))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
/*
* Decrement the counter on the dataset. It will be freed if the count
* reaches zero.
*/
- if(H5I_dec_ref(dset_id) < 0)
+ if(H5I_dec_ref(dset_id, TRUE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't free")
done:
@@ -425,7 +424,7 @@ H5Dget_space(hid_t dset_id)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get data space")
/* Create an atom */
- if((ret_value = H5I_register (H5I_DATASPACE, space)) < 0)
+ if((ret_value = H5I_register (H5I_DATASPACE, space, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register data space")
done:
@@ -496,43 +495,41 @@ hid_t
H5Dget_type(hid_t dset_id)
{
- H5D_t *dset = NULL;
- H5T_t *copied_type = NULL;
- hid_t ret_value = FAIL;
+ H5D_t *dset; /* Dataset */
+ H5T_t *dt = NULL; /* Datatype to return */
+ hid_t ret_value; /* Return value */
FUNC_ENTER_API(H5Dget_type, FAIL)
H5TRACE1("i", "i", dset_id);
/* Check args */
- if(NULL==(dset=(H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
+ if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
- /* Copy the datatype and mark it read-only */
- if(NULL==(copied_type=H5T_copy (dset->shared->type, H5T_COPY_REOPEN)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy the datatype")
+ /* Copy the dataset's datatype */
+ if(NULL == (dt = H5T_copy(dset->shared->type, H5T_COPY_REOPEN)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy datatype")
/* Mark any datatypes as being in memory now */
- if(H5T_set_loc(copied_type, NULL, H5T_LOC_MEMORY) < 0)
+ if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
/* Lock copied type */
- if(H5T_lock (copied_type, FALSE) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient datatype")
+ if(H5T_lock(dt, FALSE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to lock transient datatype")
/* Create an atom */
- if((ret_value=H5I_register (H5I_DATATYPE, copied_type)) < 0)
+ if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype")
done:
if(ret_value < 0) {
- if(copied_type!=NULL) {
- if(H5T_close (copied_type) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype")
- } /* end if */
+ if(dt && H5T_close(dt) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype")
} /* end if */
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Dget_type() */
/*-------------------------------------------------------------------------
@@ -571,7 +568,7 @@ H5Dget_create_plist(hid_t dset_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
/* Copy the creation property list */
- if((new_dcpl_id = H5P_copy_plist(dcpl_plist)) < 0)
+ if((new_dcpl_id = H5P_copy_plist(dcpl_plist, TRUE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to copy the creation property list")
if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_dcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
@@ -603,35 +600,35 @@ H5Dget_create_plist(hid_t dset_id)
size_t bkg_size; /* Size of background buffer */
/* Wrap copies of types to convert */
- dst_id = H5I_register(H5I_DATATYPE, H5T_copy(copied_fill.type, H5T_COPY_TRANSIENT));
+ dst_id = H5I_register(H5I_DATATYPE, H5T_copy(copied_fill.type, H5T_COPY_TRANSIENT), FALSE);
if(dst_id < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register datatype")
- src_id = H5I_register(H5I_DATATYPE, H5T_copy(dset->shared->type, H5T_COPY_ALL));
+ src_id = H5I_register(H5I_DATATYPE, H5T_copy(dset->shared->type, H5T_COPY_ALL), FALSE);
if(src_id < 0) {
- H5I_dec_ref(dst_id);
+ H5I_dec_ref(dst_id, FALSE);
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register datatype")
} /* end if */
/* Allocate a background buffer */
- bkg_size = MAX(H5T_get_size(copied_fill.type), H5T_get_size(dset->shared->type));
+ bkg_size = MAX(H5T_GET_SIZE(copied_fill.type), H5T_GET_SIZE(dset->shared->type));
if(H5T_path_bkg(tpath) && NULL == (bkg_buf = H5FL_BLK_CALLOC(type_conv, bkg_size))) {
- H5I_dec_ref(src_id);
- H5I_dec_ref(dst_id);
+ H5I_dec_ref(src_id, FALSE);
+ H5I_dec_ref(dst_id, FALSE);
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
} /* end if */
/* Convert fill value */
if(H5T_convert(tpath, src_id, dst_id, (size_t)1, (size_t)0, (size_t)0, copied_fill.buf, bkg_buf, H5AC_ind_dxpl_id) < 0) {
- H5I_dec_ref(src_id);
- H5I_dec_ref(dst_id);
+ H5I_dec_ref(src_id, FALSE);
+ H5I_dec_ref(dst_id, FALSE);
if(bkg_buf)
(void)H5FL_BLK_FREE(type_conv, bkg_buf);
HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "datatype conversion failed")
} /* end if */
/* Release local resources */
- H5I_dec_ref(src_id);
- H5I_dec_ref(dst_id);
+ H5I_dec_ref(src_id, FALSE);
+ H5I_dec_ref(dst_id, FALSE);
if(bkg_buf)
(void)H5FL_BLK_FREE(type_conv, bkg_buf);
} /* end if */
@@ -647,13 +644,92 @@ H5Dget_create_plist(hid_t dset_id)
done:
if(ret_value < 0)
if(new_dcpl_id > 0)
- (void)H5I_dec_ref(new_dcpl_id);
+ (void)H5I_dec_ref(new_dcpl_id, TRUE);
FUNC_LEAVE_API(ret_value)
} /* end H5Dget_create_plist() */
/*-------------------------------------------------------------------------
+ * Function: H5Dget_access_plist
+ *
+ * Purpose: Returns a copy of the dataset creation property list.
+ *
+ * Description: H5Dget_access_plist returns the dataset access property
+ * list identifier of the specified dataset.
+ *
+ * The chunk cache parameters in the returned property lists will be
+ * those used by the dataset. If the properties in the file access
+ * property list were used to determine the dataset’s chunk cache
+ * configuration, then those properties will be present in the
+ * returned dataset access property list. If the dataset does not
+ * use a chunked layout, then the chunk cache properties will be set
+ * to the default. The chunk cache properties in the returned list
+ * are considered to be “set”, and any use of this list will override
+ * the corresponding properties in the file’s file access property
+ * list.
+ *
+ * All link access properties in the returned list will be set to the
+ * default values.
+ *
+ * Return: Success: ID for a copy of the dataset access
+ * property list. The template should be
+ * released by calling H5Pclose().
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Neil Fortner
+ * Wednesday, October 29, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Dget_access_plist(hid_t dset_id)
+{
+ H5D_t *dset; /* Dataset structure */
+ H5P_genplist_t *old_plist; /* Default DAPL */
+ H5P_genplist_t *new_plist; /* New DAPL */
+ hid_t new_dapl_id = FAIL;
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Dget_access_plist, FAIL)
+ H5TRACE1("i", "i", dset_id);
+
+ /* Check args */
+ if (NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+
+ /* Make a copy of the default dataset access property list */
+ if (NULL == (old_plist = (H5P_genplist_t *)H5I_object(H5P_LST_DATASET_ACCESS_g)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
+ if ((new_dapl_id = H5P_copy_plist(old_plist, TRUE)) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "can't copy dataset access property list")
+ if (NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_dapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
+
+ /* If the dataset is chunked then copy the rdcc parameters */
+ if (dset->shared->layout.type == H5D_CHUNKED) {
+ if (H5P_set(new_plist, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(dset->shared->cache.chunk.nslots)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache number of slots")
+ if (H5P_set(new_plist, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(dset->shared->cache.chunk.nbytes_max)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache byte size")
+ if (H5P_set(new_plist, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, &(dset->shared->cache.chunk.w0)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set preempt read chunks")
+ } /* end if */
+
+ /* Set the return value */
+ ret_value = new_dapl_id;
+
+done:
+ if(ret_value < 0)
+ if(new_dapl_id >= 0)
+ (void)H5I_dec_ref(new_dapl_id, TRUE);
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Dget_access_plist() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Dget_storage_size
*
* Purpose: Returns the amount of storage that is required for the
@@ -674,22 +750,22 @@ done:
hsize_t
H5Dget_storage_size(hid_t dset_id)
{
- H5D_t *dset=NULL;
+ H5D_t *dset; /* Dataset to query */
hsize_t ret_value; /* Return value */
FUNC_ENTER_API(H5Dget_storage_size, 0)
H5TRACE1("h", "i", dset_id);
/* Check args */
- if(NULL==(dset=(H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
+ if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a dataset")
/* Set return value */
- ret_value = H5D_get_storage_size(dset,H5AC_ind_dxpl_id);
+ ret_value = H5D_get_storage_size(dset, H5AC_ind_dxpl_id);
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Dget_storage_size() */
/*-------------------------------------------------------------------------
@@ -709,14 +785,14 @@ done:
haddr_t
H5Dget_offset(hid_t dset_id)
{
- H5D_t *dset=NULL;
+ H5D_t *dset; /* Dataset to query */
haddr_t ret_value; /* Return value */
FUNC_ENTER_API(H5Dget_offset, HADDR_UNDEF)
H5TRACE1("a", "i", dset_id);
/* Check args */
- if(NULL==(dset=(H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
+ if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "not a dataset")
/* Set return value */
@@ -724,7 +800,7 @@ H5Dget_offset(hid_t dset_id)
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Dget_offset() */
/*-------------------------------------------------------------------------
@@ -790,22 +866,22 @@ herr_t
H5Diterate(void *buf, hid_t type_id, hid_t space_id, H5D_operator_t op,
void *operator_data)
{
- H5S_t *space = NULL;
- herr_t ret_value;
+ H5S_t *space; /* Dataspace for iteration */
+ herr_t ret_value; /* Return value */
FUNC_ENTER_API(H5Diterate, FAIL)
H5TRACE5("e", "*xiix*x", buf, type_id, space_id, op, operator_data);
/* Check args */
- if(NULL==op)
+ if(NULL == op)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid operator")
- if(buf==NULL)
+ if(NULL == buf)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer")
if(H5I_DATATYPE != H5I_get_type(type_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid datatype")
if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace")
- if(!(H5S_has_extent(space)) )
+ if(!(H5S_has_extent(space)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set")
ret_value = H5D_iterate(buf, type_id, space, op, operator_data);
@@ -833,8 +909,8 @@ done:
herr_t
H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf)
{
- H5S_t *space = NULL;
- herr_t ret_value;
+ H5S_t *space; /* Dataspace for iteration */
+ herr_t ret_value; /* Return value */
FUNC_ENTER_API(H5Dvlen_reclaim, FAIL)
H5TRACE4("e", "iii*x", type_id, space_id, plist_id, buf);
@@ -891,18 +967,18 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id,
hsize_t *size)
{
H5D_vlen_bufsize_t vlen_bufsize = {0, 0, 0, 0, 0, 0, 0};
- char bogus; /* bogus value to pass to H5Diterate() */
- H5S_t *space = NULL;
+ char bogus; /* bogus value to pass to H5Diterate() */
+ H5S_t *space; /* Dataspace for iteration */
H5P_genclass_t *pclass; /* Property class */
H5P_genplist_t *plist; /* Property list */
- herr_t ret_value=FAIL;
+ herr_t ret_value; /* Return value */
FUNC_ENTER_API(H5Dvlen_get_buf_size, FAIL)
H5TRACE4("e", "iii*h", dataset_id, type_id, space_id, size);
/* Check args */
- if(H5I_DATASET!=H5I_get_type(dataset_id) ||
- H5I_DATATYPE!=H5I_get_type(type_id) || size==NULL)
+ if(H5I_DATASET != H5I_get_type(dataset_id) ||
+ H5I_DATATYPE != H5I_get_type(type_id) || size == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument")
if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace")
@@ -910,10 +986,10 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id,
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set")
/* Save the dataset ID */
- vlen_bufsize.dataset_id=dataset_id;
+ vlen_bufsize.dataset_id = dataset_id;
/* Get a copy of the dataspace ID */
- if((vlen_bufsize.fspace_id=H5Dget_space(dataset_id)) < 0)
+ if((vlen_bufsize.fspace_id = H5Dget_space(dataset_id)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy dataspace")
/* Create a scalar for the memory dataspace */
@@ -921,9 +997,9 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id,
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't create dataspace")
/* Grab the temporary buffers required */
- if((vlen_bufsize.fl_tbuf = H5FL_BLK_MALLOC(vlen_fl_buf, (size_t)1)) == NULL)
+ if(NULL == (vlen_bufsize.fl_tbuf = H5FL_BLK_MALLOC(vlen_fl_buf, (size_t)1)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "no temporary buffers available")
- if((vlen_bufsize.vl_tbuf = H5FL_BLK_MALLOC(vlen_vl_buf, (size_t)1)) == NULL)
+ if(NULL == (vlen_bufsize.vl_tbuf = H5FL_BLK_MALLOC(vlen_vl_buf, (size_t)1)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "no temporary buffers available")
/* Get the pointer to the dataset transfer class */
@@ -931,7 +1007,7 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id,
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class")
/* Change to the custom memory allocation routines for reading VL data */
- if((vlen_bufsize.xfer_pid=H5P_create_id(pclass)) < 0)
+ if((vlen_bufsize.xfer_pid = H5P_create_id(pclass, FALSE)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "no dataset xfer plists available")
/* Get the property list struct */
@@ -943,7 +1019,7 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id,
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set VL data allocation routine")
/* Set the initial number of bytes required */
- vlen_bufsize.size=0;
+ vlen_bufsize.size = 0;
/* Call H5D_iterate with args, etc. */
ret_value = H5D_iterate(&bogus, type_id, space, H5D_vlen_get_buf_size, &vlen_bufsize);
@@ -954,11 +1030,11 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id,
done:
if(vlen_bufsize.fspace_id > 0) {
- if(H5I_dec_ref(vlen_bufsize.fspace_id) < 0)
+ if(H5I_dec_ref(vlen_bufsize.fspace_id, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace")
} /* end if */
if(vlen_bufsize.mspace_id > 0) {
- if(H5I_dec_ref(vlen_bufsize.mspace_id) < 0)
+ if(H5I_dec_ref(vlen_bufsize.mspace_id, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace")
} /* end if */
if(vlen_bufsize.fl_tbuf != NULL)
@@ -966,7 +1042,7 @@ done:
if(vlen_bufsize.vl_tbuf != NULL)
(void)H5FL_BLK_FREE(vlen_vl_buf, vlen_bufsize.vl_tbuf);
if(vlen_bufsize.xfer_pid > 0) {
- if(H5I_dec_ref(vlen_bufsize.xfer_pid) < 0)
+ if(H5I_dec_ref(vlen_bufsize.xfer_pid, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to decrement ref count on property list")
} /* end if */
@@ -992,21 +1068,21 @@ H5Dset_extent(hid_t dset_id, const hsize_t size[])
{
H5D_t *dset; /* Dataset for this operation */
herr_t ret_value = SUCCEED; /* Return value */
-
+
FUNC_ENTER_API(H5Dset_extent, FAIL)
H5TRACE2("e", "i*h", dset_id, size);
-
+
/* Check args */
if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
if(!size)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no size specified")
-
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no size specified")
+
/* Private function */
if(H5D_set_extent(dset, size, H5AC_dxpl_id) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extend dataset")
-
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extend dataset")
+
done:
- FUNC_LEAVE_API(ret_value)
+ FUNC_LEAVE_API(ret_value)
} /* end H5Dset_extent() */
diff --git a/src/H5Distore.c b/src/H5Dbtree.c
index f12364e..c12865f 100644
--- a/src/H5Distore.c
+++ b/src/H5Dbtree.c
@@ -16,29 +16,10 @@
/* Programmer: Robb Matzke <matzke@llnl.gov>
* Wednesday, October 8, 1997
*
- * Purpose: Indexed (chunked) I/O functions. The logical
- * multi-dimensional data space is regularly partitioned into
- * same-sized "chunks", the first of which is aligned with the
- * logical origin. The chunks are given a multi-dimensional
- * index which is used as a lookup key in a B-tree that maps
- * chunk index to disk address. Each chunk can be compressed
- * independently and the chunks may move around in the file as
- * their storage requirements change.
- *
- * Cache: Disk I/O is performed in units of chunks and H5MF_alloc()
- * contains code to optionally align chunks on disk block
- * boundaries for performance.
- *
- * The chunk cache is an extendible hash indexed by a function
- * of storage B-tree address and chunk N-dimensional offset
- * within the dataset. Collisions are not resolved -- one of
- * the two chunks competing for the hash slot must be preempted
- * from the cache. All entries in the hash also participate in
- * a doubly-linked list and entries are penalized by moving them
- * toward the front of the list. When a new chunk is about to
- * be added to the cache the heap is pruned by preempting
- * entries near the front of the list to make room for the new
- * entry which is added to the end of the list.
+ * Purpose: v1 B-tree indexed (chunked) I/O functions. The chunks are
+ * given a multi-dimensional index which is used as a lookup key
+ * in a B-tree that maps chunk index to disk address.
+ *
*/
/****************/
@@ -76,7 +57,7 @@
* Given a B-tree node return the dimensionality of the chunks pointed to by
* that node.
*/
-#define H5D_ISTORE_NDIMS(X) (((X)->sizeof_rkey-8)/8)
+#define H5D_BTREE_NDIMS(X) (((X)->sizeof_rkey-8)/8)
/******************/
/* Local Typedefs */
@@ -96,86 +77,78 @@
*
* The chunk's file address is part of the B-tree and not part of the key.
*/
-typedef struct H5D_istore_key_t {
+typedef struct H5D_btree_key_t {
uint32_t nbytes; /*size of stored data */
hsize_t offset[H5O_LAYOUT_NDIMS]; /*logical offset to start*/
unsigned filter_mask; /*excluded filters */
-} H5D_istore_key_t;
-
-/*
- * Data exchange structure for indexed storage nodes. This structure is
- * passed through the B-link tree layer to the methods for the objects
- * to which the B-link tree points for operations which require no
- * additional information.
- *
- * (Just an alias for the "common" info).
- */
-typedef H5D_chunk_common_ud_t H5D_istore_ud0_t;
+} H5D_btree_key_t;
/* B-tree callback info for iteration over chunks */
-typedef struct H5D_istore_it_ud_t {
+typedef struct H5D_btree_it_ud_t {
H5D_chunk_common_ud_t common; /* Common info for B-tree user data (must be first) */
H5D_chunk_cb_func_t cb; /* Chunk callback routine */
void *udata; /* User data for chunk callback routine */
-} H5D_istore_it_ud_t;
+} H5D_btree_it_ud_t;
/********************/
/* Local Prototypes */
/********************/
-static herr_t H5D_istore_shared_create(const H5F_t *f, H5O_layout_t *layout);
+static herr_t H5D_btree_shared_create(const H5F_t *f, H5O_storage_chunk_t *store,
+ unsigned ndims);
/* B-tree iterator callbacks */
-static int H5D_istore_idx_iterate_cb(H5F_t *f, hid_t dxpl_id, const void *left_key,
+static int H5D_btree_idx_iterate_cb(H5F_t *f, hid_t dxpl_id, const void *left_key,
haddr_t addr, const void *right_key, void *_udata);
/* B-tree callbacks */
-static H5RC_t *H5D_istore_get_shared(const H5F_t *f, const void *_udata);
-static herr_t H5D_istore_new_node(H5F_t *f, hid_t dxpl_id, H5B_ins_t, void *_lt_key,
- void *_udata, void *_rt_key,
- haddr_t *addr_p /*out*/);
-static int H5D_istore_cmp2(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata,
- void *_rt_key);
-static int H5D_istore_cmp3(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata,
- void *_rt_key);
-static herr_t H5D_istore_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_lt_key,
- void *_udata);
-static H5B_ins_t H5D_istore_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
- hbool_t *lt_key_changed, void *_md_key,
- void *_udata, void *_rt_key,
- hbool_t *rt_key_changed,
- haddr_t *new_node/*out*/);
-static H5B_ins_t H5D_istore_remove( H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
- hbool_t *lt_key_changed, void *_udata, void *_rt_key,
- hbool_t *rt_key_changed);
-static herr_t H5D_istore_decode_key(const H5F_t *f, const H5B_t *bt, const uint8_t *raw,
- void *_key);
-static herr_t H5D_istore_encode_key(const H5F_t *f, const H5B_t *bt, uint8_t *raw,
- void *_key);
-static herr_t H5D_istore_debug_key(FILE *stream, H5F_t *f, hid_t dxpl_id,
- int indent, int fwidth, const void *key,
- const void *udata);
+static H5RC_t *H5D_btree_get_shared(const H5F_t *f, const void *_udata);
+static herr_t H5D_btree_new_node(H5F_t *f, hid_t dxpl_id, H5B_ins_t, void *_lt_key,
+ void *_udata, void *_rt_key, haddr_t *addr_p /*out*/);
+static int H5D_btree_cmp2(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata,
+ void *_rt_key);
+static int H5D_btree_cmp3(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata,
+ void *_rt_key);
+static htri_t H5D_btree_found(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ const void *_lt_key, void *_udata);
+static H5B_ins_t H5D_btree_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ void *_lt_key, hbool_t *lt_key_changed, void *_md_key, void *_udata,
+ void *_rt_key, hbool_t *rt_key_changed, haddr_t *new_node/*out*/);
+static H5B_ins_t H5D_btree_remove( H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ void *_lt_key, hbool_t *lt_key_changed, void *_udata, void *_rt_key,
+ hbool_t *rt_key_changed);
+static herr_t H5D_btree_decode_key(const H5F_t *f, const H5B_t *bt,
+ const uint8_t *raw, void *_key);
+static herr_t H5D_btree_encode_key(const H5F_t *f, const H5B_t *bt,
+ uint8_t *raw, void *_key);
+static herr_t H5D_btree_debug_key(FILE *stream, H5F_t *f, hid_t dxpl_id,
+ int indent, int fwidth, const void *key, const void *udata);
/* Chunked layout indexing callbacks */
-static herr_t H5D_istore_idx_init(const H5D_chk_idx_info_t *idx_info);
-static herr_t H5D_istore_idx_create(const H5D_chk_idx_info_t *idx_info);
-static herr_t H5D_istore_idx_insert(const H5D_chk_idx_info_t *idx_info,
+static herr_t H5D_btree_idx_init(const H5D_chk_idx_info_t *idx_info,
+ const H5S_t *space, haddr_t dset_ohdr_addr);
+static herr_t H5D_btree_idx_create(const H5D_chk_idx_info_t *idx_info);
+static hbool_t H5D_btree_idx_is_space_alloc(const H5O_storage_chunk_t *storage);
+static herr_t H5D_btree_idx_insert(const H5D_chk_idx_info_t *idx_info,
H5D_chunk_ud_t *udata);
-static haddr_t H5D_istore_idx_get_addr(const H5D_chk_idx_info_t *idx_info,
+static herr_t H5D_btree_idx_get_addr(const H5D_chk_idx_info_t *idx_info,
H5D_chunk_ud_t *udata);
-static int H5D_istore_idx_iterate(const H5D_chk_idx_info_t *idx_info,
+static int H5D_btree_idx_iterate(const H5D_chk_idx_info_t *idx_info,
H5D_chunk_cb_func_t chunk_cb, void *chunk_udata);
-static herr_t H5D_istore_idx_remove(const H5D_chk_idx_info_t *idx_info,
+static herr_t H5D_btree_idx_remove(const H5D_chk_idx_info_t *idx_info,
H5D_chunk_common_ud_t *udata);
-static herr_t H5D_istore_idx_delete(const H5D_chk_idx_info_t *idx_info);
-static herr_t H5D_istore_idx_copy_setup(const H5D_chk_idx_info_t *idx_info_src,
+static herr_t H5D_btree_idx_delete(const H5D_chk_idx_info_t *idx_info);
+static herr_t H5D_btree_idx_copy_setup(const H5D_chk_idx_info_t *idx_info_src,
const H5D_chk_idx_info_t *idx_info_dst);
-static herr_t H5D_istore_idx_copy_shutdown(H5O_layout_t *layout_src,
- H5O_layout_t *layout_dst);
-static herr_t H5D_istore_idx_size(const H5D_chk_idx_info_t *idx_info,
+static herr_t H5D_btree_idx_copy_shutdown(H5O_storage_chunk_t *storage_src,
+ H5O_storage_chunk_t *storage_dst, hid_t dxpl_id);
+static herr_t H5D_btree_idx_size(const H5D_chk_idx_info_t *idx_info,
hsize_t *size);
-static herr_t H5D_istore_idx_dest(const H5D_chk_idx_info_t *idx_info);
+static herr_t H5D_btree_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr);
+static herr_t H5D_btree_idx_dump(const H5O_storage_chunk_t *storage,
+ FILE *stream);
+static herr_t H5D_btree_idx_dest(const H5D_chk_idx_info_t *idx_info);
/*********************/
@@ -183,18 +156,22 @@ static herr_t H5D_istore_idx_dest(const H5D_chk_idx_info_t *idx_info);
/*********************/
/* v1 B-tree indexed chunk I/O ops */
-const H5D_chunk_ops_t H5D_COPS_ISTORE[1] = {{
- H5D_istore_idx_init,
- H5D_istore_idx_create,
- H5D_istore_idx_insert,
- H5D_istore_idx_get_addr,
- H5D_istore_idx_iterate,
- H5D_istore_idx_remove,
- H5D_istore_idx_delete,
- H5D_istore_idx_copy_setup,
- H5D_istore_idx_copy_shutdown,
- H5D_istore_idx_size,
- H5D_istore_idx_dest
+const H5D_chunk_ops_t H5D_COPS_BTREE[1] = {{
+ H5D_btree_idx_init,
+ H5D_btree_idx_create,
+ H5D_btree_idx_is_space_alloc,
+ H5D_btree_idx_insert,
+ H5D_btree_idx_get_addr,
+ NULL,
+ H5D_btree_idx_iterate,
+ H5D_btree_idx_remove,
+ H5D_btree_idx_delete,
+ H5D_btree_idx_copy_setup,
+ H5D_btree_idx_copy_shutdown,
+ H5D_btree_idx_size,
+ H5D_btree_idx_reset,
+ H5D_btree_idx_dump,
+ H5D_btree_idx_dest
}};
@@ -203,21 +180,21 @@ const H5D_chunk_ops_t H5D_COPS_ISTORE[1] = {{
/*****************************/
/* inherits B-tree like properties from H5B */
-H5B_class_t H5B_ISTORE[1] = {{
- H5B_ISTORE_ID, /*id */
- sizeof(H5D_istore_key_t), /*sizeof_nkey */
- H5D_istore_get_shared, /*get_shared */
- H5D_istore_new_node, /*new */
- H5D_istore_cmp2, /*cmp2 */
- H5D_istore_cmp3, /*cmp3 */
- H5D_istore_found, /*found */
- H5D_istore_insert, /*insert */
+H5B_class_t H5B_BTREE[1] = {{
+ H5B_CHUNK_ID, /*id */
+ sizeof(H5D_btree_key_t), /*sizeof_nkey */
+ H5D_btree_get_shared, /*get_shared */
+ H5D_btree_new_node, /*new */
+ H5D_btree_cmp2, /*cmp2 */
+ H5D_btree_cmp3, /*cmp3 */
+ H5D_btree_found, /*found */
+ H5D_btree_insert, /*insert */
FALSE, /*follow min branch? */
FALSE, /*follow max branch? */
- H5D_istore_remove, /*remove */
- H5D_istore_decode_key, /*decode */
- H5D_istore_encode_key, /*encode */
- H5D_istore_debug_key, /*debug */
+ H5D_btree_remove, /*remove */
+ H5D_btree_decode_key, /*decode */
+ H5D_btree_encode_key, /*encode */
+ H5D_btree_debug_key, /*debug */
}};
@@ -227,7 +204,7 @@ H5B_class_t H5B_ISTORE[1] = {{
/*-------------------------------------------------------------------------
- * Function: H5D_istore_get_shared
+ * Function: H5D_btree_get_shared
*
* Purpose: Returns the shared B-tree info for the specified UDATA.
*
@@ -242,146 +219,101 @@ H5B_class_t H5B_ISTORE[1] = {{
*/
/* ARGSUSED */
static H5RC_t *
-H5D_istore_get_shared(const H5F_t UNUSED *f, const void *_udata)
+H5D_btree_get_shared(const H5F_t UNUSED *f, const void *_udata)
{
- const H5D_istore_ud0_t *udata = (const H5D_istore_ud0_t *) _udata;
+ const H5D_chunk_common_ud_t *udata = (const H5D_chunk_common_ud_t *) _udata;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_get_shared)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_btree_get_shared)
HDassert(udata);
- HDassert(udata->mesg);
- HDassert(udata->mesg->u.chunk.btree_shared);
+ HDassert(udata->storage);
+ HDassert(udata->storage->idx_type == H5D_CHUNK_BTREE);
+ HDassert(udata->storage->u.btree.shared);
/* Increment reference count on B-tree info */
- H5RC_INC(udata->mesg->u.chunk.btree_shared);
+ H5RC_INC(udata->storage->u.btree.shared);
/* Return the pointer to the ref-count object */
- FUNC_LEAVE_NOAPI(udata->mesg->u.chunk.btree_shared)
-} /* end H5D_istore_get_shared() */
+ FUNC_LEAVE_NOAPI(udata->storage->u.btree.shared)
+} /* end H5D_btree_get_shared() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_decode_key
- *
- * Purpose: Decodes a raw key into a native key for the B-tree
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * Friday, October 10, 1997
+ * Function: H5D_btree_new_node
*
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5D_istore_decode_key(const H5F_t UNUSED *f, const H5B_t *bt, const uint8_t *raw, void *_key)
-{
- H5D_istore_key_t *key = (H5D_istore_key_t *) _key;
- H5B_shared_t *shared; /* Pointer to shared B-tree info */
- size_t ndims;
- unsigned u;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_decode_key)
-
- /* check args */
- HDassert(f);
- HDassert(bt);
- shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
- HDassert(shared);
- HDassert(raw);
- HDassert(key);
- ndims = H5D_ISTORE_NDIMS(shared);
- HDassert(ndims <= H5O_LAYOUT_NDIMS);
-
- /* decode */
- UINT32DECODE(raw, key->nbytes);
- UINT32DECODE(raw, key->filter_mask);
- for(u = 0; u < ndims; u++)
- UINT64DECODE(raw, key->offset[u]);
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5D_istore_decode_key() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5D_istore_encode_key
+ * Purpose: Adds a new entry to an i-storage B-tree. We can assume that
+ * the domain represented by UDATA doesn't intersect the domain
+ * already represented by the B-tree.
*
- * Purpose: Encode a key from native format to raw format.
+ * Return: Success: Non-negative. The address of leaf is returned
+ * through the ADDR argument. It is also added
+ * to the UDATA.
*
- * Return: Non-negative on success/Negative on failure
+ * Failure: Negative
*
* Programmer: Robb Matzke
- * Friday, October 10, 1997
+ * Tuesday, October 14, 1997
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_istore_encode_key(const H5F_t UNUSED *f, const H5B_t *bt, uint8_t *raw, void *_key)
+H5D_btree_new_node(H5F_t *f, hid_t dxpl_id, H5B_ins_t op,
+ void *_lt_key, void *_udata, void *_rt_key,
+ haddr_t *addr_p/*out*/)
{
- H5D_istore_key_t *key = (H5D_istore_key_t *) _key;
- H5B_shared_t *shared; /* Pointer to shared B-tree info */
- size_t ndims;
+ H5D_btree_key_t *lt_key = (H5D_btree_key_t *) _lt_key;
+ H5D_btree_key_t *rt_key = (H5D_btree_key_t *) _rt_key;
+ H5D_chunk_ud_t *udata = (H5D_chunk_ud_t *) _udata;
unsigned u;
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_encode_key)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_new_node)
/* check args */
HDassert(f);
- HDassert(bt);
- shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
- HDassert(shared);
- HDassert(raw);
- HDassert(key);
- ndims = H5D_ISTORE_NDIMS(shared);
- HDassert(ndims <= H5O_LAYOUT_NDIMS);
-
- /* encode */
- UINT32ENCODE(raw, key->nbytes);
- UINT32ENCODE(raw, key->filter_mask);
- for(u = 0; u < ndims; u++)
- UINT64ENCODE(raw, key->offset[u]);
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5D_istore_encode_key() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5D_istore_debug_key
- *
- * Purpose: Prints a key.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * Thursday, April 16, 1998
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static herr_t
-H5D_istore_debug_key(FILE *stream, H5F_t UNUSED *f, hid_t UNUSED dxpl_id, int indent, int fwidth, const void *_key,
- const void *_udata)
-{
- const H5D_istore_key_t *key = (const H5D_istore_key_t *)_key;
- const H5D_istore_ud0_t *udata = (const H5D_istore_ud0_t *)_udata;
- unsigned u;
+ HDassert(lt_key);
+ HDassert(rt_key);
+ HDassert(udata);
+ HDassert(udata->common.layout->ndims > 0 && udata->common.layout->ndims < H5O_LAYOUT_NDIMS);
+ HDassert(addr_p);
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_debug_key)
+ /* Allocate new storage */
+ HDassert(udata->nbytes > 0);
+ H5_CHECK_OVERFLOW(udata->nbytes, uint32_t, hsize_t);
+ if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->nbytes)))
+ HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "couldn't allocate new file storage")
+ udata->addr = *addr_p;
- HDassert(key);
+ /*
+ * The left key describes the storage of the UDATA chunk being
+ * inserted into the tree.
+ */
+ lt_key->nbytes = udata->nbytes;
+ lt_key->filter_mask = udata->filter_mask;
+ for(u = 0; u < udata->common.layout->ndims; u++)
+ lt_key->offset[u] = udata->common.offset[u];
- HDfprintf(stream, "%*s%-*s %u bytes\n", indent, "", fwidth, "Chunk size:", (unsigned)key->nbytes);
- HDfprintf(stream, "%*s%-*s 0x%08x\n", indent, "", fwidth, "Filter mask:", key->filter_mask);
- HDfprintf(stream, "%*s%-*s {", indent, "", fwidth, "Logical offset:");
- for(u = 0; u < udata->mesg->u.chunk.ndims; u++)
- HDfprintf(stream, "%s%Hd", u?", ":"", key->offset[u]);
- HDfputs("}\n", stream);
+ /*
+ * The right key might already be present. If not, then add a zero-width
+ * chunk.
+ */
+ if(H5B_INS_LEFT != op) {
+ rt_key->nbytes = 0;
+ rt_key->filter_mask = 0;
+ for(u = 0; u < udata->common.layout->ndims; u++) {
+ HDassert(udata->common.offset[u] + udata->common.layout->dim[u] >
+ udata->common.offset[u]);
+ rt_key->offset[u] = udata->common.offset[u] + udata->common.layout->dim[u];
+ } /* end if */
+ } /* end if */
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5D_istore_debug_key() */
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_btree_new_node() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_cmp2
+ * Function: H5D_btree_cmp2
*
* Purpose: Compares two keys sort of like strcmp(). The UDATA pointer
* is only to supply extra information not carried in the keys
@@ -401,29 +333,30 @@ H5D_istore_debug_key(FILE *stream, H5F_t UNUSED *f, hid_t UNUSED dxpl_id, int in
*/
/* ARGSUSED */
static int
-H5D_istore_cmp2(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_udata, void *_rt_key)
+H5D_btree_cmp2(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_udata,
+ void *_rt_key)
{
- H5D_istore_key_t *lt_key = (H5D_istore_key_t *) _lt_key;
- H5D_istore_key_t *rt_key = (H5D_istore_key_t *) _rt_key;
- H5D_istore_ud0_t *udata = (H5D_istore_ud0_t *) _udata;
+ H5D_btree_key_t *lt_key = (H5D_btree_key_t *) _lt_key;
+ H5D_btree_key_t *rt_key = (H5D_btree_key_t *) _rt_key;
+ H5D_chunk_common_ud_t *udata = (H5D_chunk_common_ud_t *) _udata;
int ret_value;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_cmp2)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_btree_cmp2)
HDassert(lt_key);
HDassert(rt_key);
HDassert(udata);
- HDassert(udata->mesg->u.chunk.ndims > 0 && udata->mesg->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
+ HDassert(udata->layout->ndims > 0 && udata->layout->ndims <= H5O_LAYOUT_NDIMS);
/* Compare the offsets but ignore the other fields */
- ret_value = H5V_vector_cmp_u(udata->mesg->u.chunk.ndims, lt_key->offset, rt_key->offset);
+ ret_value = H5V_vector_cmp_u(udata->layout->ndims, lt_key->offset, rt_key->offset);
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_cmp2() */
+} /* end H5D_btree_cmp2() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_cmp3
+ * Function: H5D_btree_cmp3
*
* Purpose: Compare the requested datum UDATA with the left and right
* keys of the B-tree.
@@ -451,19 +384,20 @@ H5D_istore_cmp2(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_uda
*/
/* ARGSUSED */
static int
-H5D_istore_cmp3(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_udata, void *_rt_key)
+H5D_btree_cmp3(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_udata,
+ void *_rt_key)
{
- H5D_istore_key_t *lt_key = (H5D_istore_key_t *) _lt_key;
- H5D_istore_key_t *rt_key = (H5D_istore_key_t *) _rt_key;
- H5D_istore_ud0_t *udata = (H5D_istore_ud0_t *) _udata;
+ H5D_btree_key_t *lt_key = (H5D_btree_key_t *) _lt_key;
+ H5D_btree_key_t *rt_key = (H5D_btree_key_t *) _rt_key;
+ H5D_chunk_common_ud_t *udata = (H5D_chunk_common_ud_t *) _udata;
int ret_value = 0;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_cmp3)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_btree_cmp3)
HDassert(lt_key);
HDassert(rt_key);
HDassert(udata);
- HDassert(udata->mesg->u.chunk.ndims > 0 && udata->mesg->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
+ HDassert(udata->layout->ndims > 0 && udata->layout->ndims <= H5O_LAYOUT_NDIMS);
/* Special case for faster checks on 1-D chunks */
/* (Checking for ndims==2 because last dimension is the datatype size) */
@@ -471,7 +405,7 @@ H5D_istore_cmp3(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_uda
/* slightly odd way the library initializes the right-most node in the */
/* indexed storage B-tree... */
/* (Dump the B-tree with h5debug to look at it) -QAK */
- if(udata->mesg->u.chunk.ndims == 2) {
+ if(udata->layout->ndims == 2) {
if(udata->offset[0] > rt_key->offset[0])
ret_value = 1;
else if(udata->offset[0] == rt_key->offset[0] &&
@@ -481,92 +415,18 @@ H5D_istore_cmp3(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_uda
ret_value = (-1);
} /* end if */
else {
- if(H5V_vector_ge_u(udata->mesg->u.chunk.ndims, udata->offset, rt_key->offset))
+ if(H5V_vector_ge_u(udata->layout->ndims, udata->offset, rt_key->offset))
ret_value = 1;
- else if(H5V_vector_lt_u(udata->mesg->u.chunk.ndims, udata->offset, lt_key->offset))
+ else if(H5V_vector_lt_u(udata->layout->ndims, udata->offset, lt_key->offset))
ret_value = (-1);
} /* end else */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_cmp3() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5D_istore_new_node
- *
- * Purpose: Adds a new entry to an i-storage B-tree. We can assume that
- * the domain represented by UDATA doesn't intersect the domain
- * already represented by the B-tree.
- *
- * Return: Success: Non-negative. The address of leaf is returned
- * through the ADDR argument. It is also added
- * to the UDATA.
- *
- * Failure: Negative
- *
- * Programmer: Robb Matzke
- * Tuesday, October 14, 1997
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5D_istore_new_node(H5F_t *f, hid_t dxpl_id, H5B_ins_t op,
- void *_lt_key, void *_udata, void *_rt_key,
- haddr_t *addr_p/*out*/)
-{
- H5D_istore_key_t *lt_key = (H5D_istore_key_t *) _lt_key;
- H5D_istore_key_t *rt_key = (H5D_istore_key_t *) _rt_key;
- H5D_chunk_ud_t *udata = (H5D_chunk_ud_t *) _udata;
- unsigned u;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5D_istore_new_node)
-
- /* check args */
- HDassert(f);
- HDassert(lt_key);
- HDassert(rt_key);
- HDassert(udata);
- HDassert(udata->common.mesg->u.chunk.ndims > 0 && udata->common.mesg->u.chunk.ndims < H5O_LAYOUT_NDIMS);
- HDassert(addr_p);
-
- /* Allocate new storage */
- HDassert(udata->nbytes > 0);
- H5_CHECK_OVERFLOW(udata->nbytes, uint32_t, hsize_t);
- if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->nbytes)))
- HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "couldn't allocate new file storage")
- udata->addr = *addr_p;
-
- /*
- * The left key describes the storage of the UDATA chunk being
- * inserted into the tree.
- */
- lt_key->nbytes = udata->nbytes;
- lt_key->filter_mask = udata->filter_mask;
- for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++)
- lt_key->offset[u] = udata->common.offset[u];
-
- /*
- * The right key might already be present. If not, then add a zero-width
- * chunk.
- */
- if(H5B_INS_LEFT != op) {
- rt_key->nbytes = 0;
- rt_key->filter_mask = 0;
- for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++) {
- HDassert(udata->common.offset[u] + udata->common.mesg->u.chunk.dim[u] >
- udata->common.offset[u]);
- rt_key->offset[u] = udata->common.offset[u] + udata->common.mesg->u.chunk.dim[u];
- } /* end if */
- } /* end if */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_new_node() */
+} /* end H5D_btree_cmp3() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_found
+ * Function: H5D_btree_found
*
* Purpose: This function is called when the B-tree search engine has
* found the leaf entry that points to a chunk of storage that
@@ -581,8 +441,8 @@ done:
* called with the maximum stored chunk indices less than the
* requested chunk indices.
*
- * Return: Non-negative on success with information about the chunk
- * returned through the UDATA argument. Negative on failure.
+ * Return: Non-negative (TRUE/FALSE) on success with information about the
+ * chunk returned through the UDATA argument. Negative on failure.
*
* Programmer: Robb Matzke
* Thursday, October 9, 1997
@@ -590,16 +450,16 @@ done:
*-------------------------------------------------------------------------
*/
/* ARGSUSED */
-static herr_t
-H5D_istore_found(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, haddr_t addr, const void *_lt_key,
+static htri_t
+H5D_btree_found(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, haddr_t addr, const void *_lt_key,
void *_udata)
{
H5D_chunk_ud_t *udata = (H5D_chunk_ud_t *) _udata;
- const H5D_istore_key_t *lt_key = (const H5D_istore_key_t *) _lt_key;
+ const H5D_btree_key_t *lt_key = (const H5D_btree_key_t *) _lt_key;
unsigned u;
- herr_t ret_value = SUCCEED; /* Return value */
+ htri_t ret_value = TRUE; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_found)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_btree_found)
/* Check arguments */
HDassert(f);
@@ -608,9 +468,9 @@ H5D_istore_found(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, haddr_t addr, const void
HDassert(lt_key);
/* Is this *really* the requested chunk? */
- for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++)
- if(udata->common.offset[u] >= lt_key->offset[u] + udata->common.mesg->u.chunk.dim[u])
- HGOTO_DONE(FAIL)
+ for(u = 0; u < udata->common.layout->ndims; u++)
+ if(udata->common.offset[u] >= lt_key->offset[u] + udata->common.layout->dim[u])
+ HGOTO_DONE(FALSE)
/* Initialize return values */
HDassert(lt_key->nbytes > 0);
@@ -620,11 +480,11 @@ H5D_istore_found(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, haddr_t addr, const void
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_found() */
+} /* end H5D_btree_found() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_insert
+ * Function: H5D_btree_insert
*
* Purpose: This function is called when the B-tree insert engine finds
* the node to use to insert new data. The UDATA argument
@@ -653,21 +513,21 @@ done:
*/
/* ARGSUSED */
static H5B_ins_t
-H5D_istore_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
+H5D_btree_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
hbool_t *lt_key_changed,
void *_md_key, void *_udata, void *_rt_key,
hbool_t UNUSED *rt_key_changed,
haddr_t *new_node_p/*out*/)
{
- H5D_istore_key_t *lt_key = (H5D_istore_key_t *) _lt_key;
- H5D_istore_key_t *md_key = (H5D_istore_key_t *) _md_key;
- H5D_istore_key_t *rt_key = (H5D_istore_key_t *) _rt_key;
+ H5D_btree_key_t *lt_key = (H5D_btree_key_t *) _lt_key;
+ H5D_btree_key_t *md_key = (H5D_btree_key_t *) _md_key;
+ H5D_btree_key_t *rt_key = (H5D_btree_key_t *) _rt_key;
H5D_chunk_ud_t *udata = (H5D_chunk_ud_t *) _udata;
int cmp;
unsigned u;
H5B_ins_t ret_value;
- FUNC_ENTER_NOAPI_NOINIT(H5D_istore_insert)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_insert)
/* check args */
HDassert(f);
@@ -679,14 +539,14 @@ H5D_istore_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
HDassert(rt_key);
HDassert(new_node_p);
- cmp = H5D_istore_cmp3(f, dxpl_id, lt_key, udata, rt_key);
+ cmp = H5D_btree_cmp3(f, dxpl_id, lt_key, udata, rt_key);
HDassert(cmp <= 0);
if(cmp < 0) {
/* Negative indices not supported yet */
HGOTO_ERROR(H5E_STORAGE, H5E_UNSUPPORTED, H5B_INS_ERROR, "internal error")
- } else if(H5V_vector_eq_u(udata->common.mesg->u.chunk.ndims,
+ } else if(H5V_vector_eq_u(udata->common.layout->ndims,
udata->common.offset, lt_key->offset) &&
lt_key->nbytes > 0) {
/*
@@ -725,20 +585,20 @@ H5D_istore_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
ret_value = H5B_INS_NOOP;
}
- } else if (H5V_hyper_disjointp(udata->common.mesg->u.chunk.ndims,
- lt_key->offset, udata->common.mesg->u.chunk.dim,
- udata->common.offset, udata->common.mesg->u.chunk.dim)) {
- HDassert(H5V_hyper_disjointp(udata->common.mesg->u.chunk.ndims,
- rt_key->offset, udata->common.mesg->u.chunk.dim,
- udata->common.offset, udata->common.mesg->u.chunk.dim));
+ } else if (H5V_hyper_disjointp(udata->common.layout->ndims,
+ lt_key->offset, udata->common.layout->dim,
+ udata->common.offset, udata->common.layout->dim)) {
+ HDassert(H5V_hyper_disjointp(udata->common.layout->ndims,
+ rt_key->offset, udata->common.layout->dim,
+ udata->common.offset, udata->common.layout->dim));
/*
* Split this node, inserting the new new node to the right of the
* current node. The MD_KEY is where the split occurs.
*/
md_key->nbytes = udata->nbytes;
md_key->filter_mask = udata->filter_mask;
- for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++) {
- HDassert(0 == udata->common.offset[u] % udata->common.mesg->u.chunk.dim[u]);
+ for(u = 0; u < udata->common.layout->ndims; u++) {
+ HDassert(0 == udata->common.offset[u] % udata->common.layout->dim[u]);
md_key->offset[u] = udata->common.offset[u];
} /* end for */
@@ -757,11 +617,11 @@ H5D_istore_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_insert() */
+} /* end H5D_btree_insert() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_remove
+ * Function: H5D_btree_remove
*
* Purpose: Removes chunks that are no longer necessary in the B-tree.
*
@@ -775,16 +635,16 @@ done:
*/
/* ARGSUSED */
static H5B_ins_t
-H5D_istore_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key /*in,out */ ,
+H5D_btree_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key /*in,out */ ,
hbool_t *lt_key_changed /*out */ ,
void UNUSED * _udata /*in,out */ ,
void UNUSED * _rt_key /*in,out */ ,
hbool_t *rt_key_changed /*out */ )
{
- H5D_istore_key_t *lt_key = (H5D_istore_key_t *)_lt_key;
+ H5D_btree_key_t *lt_key = (H5D_btree_key_t *)_lt_key;
H5B_ins_t ret_value=H5B_INS_REMOVE; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_istore_remove)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_remove)
/* Remove raw data chunk from file */
H5_CHECK_OVERFLOW(lt_key->nbytes, uint32_t, hsize_t);
@@ -797,11 +657,131 @@ H5D_istore_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key /*in,out
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_remove() */
+} /* end H5D_btree_remove() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_btree_decode_key
+ *
+ * Purpose: Decodes a raw key into a native key for the B-tree
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 10, 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_btree_decode_key(const H5F_t UNUSED *f, const H5B_t *bt, const uint8_t *raw, void *_key)
+{
+ H5D_btree_key_t *key = (H5D_btree_key_t *) _key;
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
+ size_t ndims;
+ unsigned u;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_btree_decode_key)
+
+ /* check args */
+ HDassert(f);
+ HDassert(bt);
+ shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
+ HDassert(raw);
+ HDassert(key);
+ ndims = H5D_BTREE_NDIMS(shared);
+ HDassert(ndims <= H5O_LAYOUT_NDIMS);
+
+ /* decode */
+ UINT32DECODE(raw, key->nbytes);
+ UINT32DECODE(raw, key->filter_mask);
+ for(u = 0; u < ndims; u++)
+ UINT64DECODE(raw, key->offset[u]);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5D_btree_decode_key() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_btree_encode_key
+ *
+ * Purpose: Encode a key from native format to raw format.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 10, 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_btree_encode_key(const H5F_t UNUSED *f, const H5B_t *bt, uint8_t *raw, void *_key)
+{
+ H5D_btree_key_t *key = (H5D_btree_key_t *) _key;
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
+ size_t ndims;
+ unsigned u;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_btree_encode_key)
+
+ /* check args */
+ HDassert(f);
+ HDassert(bt);
+ shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
+ HDassert(raw);
+ HDassert(key);
+ ndims = H5D_BTREE_NDIMS(shared);
+ HDassert(ndims <= H5O_LAYOUT_NDIMS);
+
+ /* encode */
+ UINT32ENCODE(raw, key->nbytes);
+ UINT32ENCODE(raw, key->filter_mask);
+ for(u = 0; u < ndims; u++)
+ UINT64ENCODE(raw, key->offset[u]);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5D_btree_encode_key() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_btree_debug_key
+ *
+ * Purpose: Prints a key.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Thursday, April 16, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static herr_t
+H5D_btree_debug_key(FILE *stream, H5F_t UNUSED *f, hid_t UNUSED dxpl_id, int indent,
+ int fwidth, const void *_key, const void *_udata)
+{
+ const H5D_btree_key_t *key = (const H5D_btree_key_t *)_key;
+ const unsigned *ndims = (const unsigned *)_udata;
+ unsigned u;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_btree_debug_key)
+
+ HDassert(key);
+
+ HDfprintf(stream, "%*s%-*s %u bytes\n", indent, "", fwidth, "Chunk size:", (unsigned)key->nbytes);
+ HDfprintf(stream, "%*s%-*s 0x%08x\n", indent, "", fwidth, "Filter mask:", key->filter_mask);
+ HDfprintf(stream, "%*s%-*s {", indent, "", fwidth, "Logical offset:");
+ for(u = 0; u < *ndims; u++)
+ HDfprintf(stream, "%s%Hd", u?", ":"", key->offset[u]);
+ HDfputs("}\n", stream);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5D_btree_debug_key() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_shared_create
+ * Function: H5D_btree_shared_create
*
* Purpose: Create & initialize B-tree shared info
*
@@ -813,37 +793,37 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_istore_shared_create(const H5F_t *f, H5O_layout_t *layout)
+H5D_btree_shared_create(const H5F_t *f, H5O_storage_chunk_t *store, unsigned ndims)
{
H5B_shared_t *shared; /* Shared B-tree node info */
size_t sizeof_rkey; /* Size of raw (disk) key */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_istore_shared_create)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_shared_create)
/* Set the raw key size */
- sizeof_rkey = 4 + /*storage size */
- 4 + /*filter mask */
- layout->u.chunk.ndims * 8; /*dimension indices */
+ sizeof_rkey = 4 + /*storage size */
+ 4 + /*filter mask */
+ ndims * 8; /*dimension indices */
/* Allocate & initialize global info for the shared structure */
- if(NULL == (shared = H5B_shared_new(f, H5B_ISTORE, sizeof_rkey)))
+ if(NULL == (shared = H5B_shared_new(f, H5B_BTREE, sizeof_rkey)))
HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, FAIL, "memory allocation failed for shared B-tree info")
/* Set up the "local" information for this dataset's chunks */
/* <none> */
/* Make shared B-tree info reference counted */
- if(NULL == (layout->u.chunk.btree_shared = H5RC_create(shared, H5B_shared_free)))
+ if(NULL == (store->u.btree.shared = H5RC_create(shared, H5B_shared_free)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared B-tree info")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_shared_create() */
+} /* end H5D_btree_shared_create() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_idx_init
+ * Function: H5D_btree_idx_init
*
* Purpose: Initialize the indexing information for a dataset.
*
@@ -855,28 +835,32 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_istore_idx_init(const H5D_chk_idx_info_t *idx_info)
+H5D_btree_idx_init(const H5D_chk_idx_info_t *idx_info, const H5S_t UNUSED *space,
+ haddr_t UNUSED dset_ohdr_addr)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_istore_idx_init)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_init)
/* Check args */
HDassert(idx_info);
HDassert(idx_info->f);
+ HDassert(idx_info->pline);
HDassert(idx_info->layout);
+ HDassert(idx_info->storage);
+ HDassert(H5F_addr_defined(dset_ohdr_addr));
/* Allocate the shared structure */
- if(H5D_istore_shared_create(idx_info->f, idx_info->layout) < 0)
+ if(H5D_btree_shared_create(idx_info->f, idx_info->storage, idx_info->layout->ndims) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_idx_init() */
+} /* end H5D_btree_idx_init() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_idx_create
+ * Function: H5D_btree_idx_create
*
* Purpose: Creates a new indexed-storage B-tree and initializes the
* layout struct with information about the storage. The
@@ -894,32 +878,65 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_istore_idx_create(const H5D_chk_idx_info_t *idx_info)
+H5D_btree_idx_create(const H5D_chk_idx_info_t *idx_info)
{
- H5D_istore_ud0_t udata; /* User data for B-tree callback */
+ H5D_chunk_common_ud_t udata; /* User data for B-tree callback */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_istore_idx_create)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_create)
/* Check args */
HDassert(idx_info);
HDassert(idx_info->f);
+ HDassert(idx_info->pline);
HDassert(idx_info->layout);
+ HDassert(idx_info->storage);
+ HDassert(!H5F_addr_defined(idx_info->storage->idx_addr));
/* Initialize "user" data for B-tree callbacks, etc. */
- udata.mesg = idx_info->layout;
+ udata.layout = idx_info->layout;
+ udata.storage = idx_info->storage;
/* Create the v1 B-tree for the chunk index */
- if(H5B_create(idx_info->f, idx_info->dxpl_id, H5B_ISTORE, &udata, &(idx_info->layout->u.chunk.addr)/*out*/) < 0)
+ if(H5B_create(idx_info->f, idx_info->dxpl_id, H5B_BTREE, &udata, &(idx_info->storage->idx_addr)/*out*/) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't create B-tree")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_idx_create() */
+} /* end H5D_btree_idx_create() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_idx_insert
+ * Function: H5D_btree_idx_is_space_alloc
+ *
+ * Purpose: Query if space is allocated for index method
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, January 15, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+H5D_btree_idx_is_space_alloc(const H5O_storage_chunk_t *storage)
+{
+ hbool_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_btree_idx_is_space_alloc)
+
+ /* Check args */
+ HDassert(storage);
+
+ /* Set return value */
+ ret_value = (hbool_t)H5F_addr_defined(storage->idx_addr);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_btree_idx_is_space_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_btree_idx_insert
*
* Purpose: Create the chunk it if it doesn't exist, or reallocate the
* chunk if its size changed.
@@ -932,31 +949,34 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_istore_idx_insert(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata)
+H5D_btree_idx_insert(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_istore_idx_insert)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_insert)
HDassert(idx_info);
HDassert(idx_info->f);
+ HDassert(idx_info->pline);
HDassert(idx_info->layout);
+ HDassert(idx_info->storage);
+ HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
HDassert(udata);
/*
* Create the chunk it if it doesn't exist, or reallocate the chunk if
* its size changed.
*/
- if(H5B_insert(idx_info->f, idx_info->dxpl_id, H5B_ISTORE, idx_info->layout->u.chunk.addr, udata) < 0)
+ if(H5B_insert(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr, udata) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to allocate chunk")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5D_istore_idx_insert() */
+} /* H5D_btree_idx_insert() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_idx_get_addr
+ * Function: H5D_btree_idx_get_addr
*
* Purpose: Get the file address of a chunk if file space has been
* assigned. Save the retrieved information in the udata
@@ -969,44 +989,33 @@ done:
*
*-------------------------------------------------------------------------
*/
-static haddr_t
-H5D_istore_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata)
+static herr_t
+H5D_btree_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata)
{
- haddr_t ret_value; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_idx_get_addr)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_get_addr)
HDassert(idx_info);
HDassert(idx_info->f);
+ HDassert(idx_info->pline);
HDassert(idx_info->layout);
- HDassert(idx_info->layout->u.chunk.ndims > 0);
+ HDassert(idx_info->layout->ndims > 0);
+ HDassert(idx_info->storage);
+ HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
HDassert(udata);
- /* Go get the chunk information */
- if(H5B_find(idx_info->f, idx_info->dxpl_id, H5B_ISTORE, idx_info->layout->u.chunk.addr, udata) < 0) {
- /* Note: don't push error on stack, leave that to next higher level,
- * since many times the B-tree is searched in order to determine
- * if a chunk exists in the B-tree or not. -QAK
- */
-#ifdef OLD_WAY
- H5E_clear_stack(NULL);
-
- HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, HADDR_UNDEF, "Can't locate chunk info")
-#else /* OLD_WAY */
- HGOTO_DONE(HADDR_UNDEF)
-#endif /* OLD_WAY */
- } /* end if */
-
- /* Success! Set the return value */
- ret_value = udata->addr;
+ /* Go get the chunk information from the B-tree */
+ if(H5B_find(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr, udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk info")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5D_istore_idx_get_addr() */
+} /* H5D_btree_idx_get_addr() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_idx_iterate_cb
+ * Function: H5D_btree_idx_iterate_cb
*
* Purpose: Translate the B-tree specific chunk record into a generic
* form and make the callback to the generic chunk callback
@@ -1022,23 +1031,23 @@ done:
*/
/* ARGSUSED */
static int
-H5D_istore_idx_iterate_cb(H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
+H5D_btree_idx_iterate_cb(H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
const void *_lt_key, haddr_t addr, const void UNUSED *_rt_key,
void *_udata)
{
- H5D_istore_it_ud_t *udata = (H5D_istore_it_ud_t *)_udata; /* User data */
- const H5D_istore_key_t *lt_key = (const H5D_istore_key_t *)_lt_key; /* B-tree key for chunk */
+ H5D_btree_it_ud_t *udata = (H5D_btree_it_ud_t *)_udata; /* User data */
+ const H5D_btree_key_t *lt_key = (const H5D_btree_key_t *)_lt_key; /* B-tree key for chunk */
H5D_chunk_rec_t chunk_rec; /* Generic chunk record for callback */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_istore_idx_iterate_cb)
+ FUNC_ENTER_NOAPI_NOINIT_NOERR(H5D_btree_idx_iterate_cb)
/* Sanity check for memcpy() */
- HDcompile_assert(offsetof(H5D_chunk_rec_t, nbytes) == offsetof(H5D_istore_key_t, nbytes));
+ HDcompile_assert(offsetof(H5D_chunk_rec_t, nbytes) == offsetof(H5D_btree_key_t, nbytes));
HDcompile_assert(sizeof(chunk_rec.nbytes) == sizeof(lt_key->nbytes));
- HDcompile_assert(offsetof(H5D_chunk_rec_t, offset) == offsetof(H5D_istore_key_t, offset));
+ HDcompile_assert(offsetof(H5D_chunk_rec_t, offset) == offsetof(H5D_btree_key_t, offset));
HDcompile_assert(sizeof(chunk_rec.offset) == sizeof(lt_key->offset));
- HDcompile_assert(offsetof(H5D_chunk_rec_t, filter_mask) == offsetof(H5D_istore_key_t, filter_mask));
+ HDcompile_assert(offsetof(H5D_chunk_rec_t, filter_mask) == offsetof(H5D_btree_key_t, filter_mask));
HDcompile_assert(sizeof(chunk_rec.filter_mask) == sizeof(lt_key->filter_mask));
/* Compose generic chunk record for callback */
@@ -1050,13 +1059,13 @@ H5D_istore_idx_iterate_cb(H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
HERROR(H5E_DATASET, H5E_CALLBACK, "failure in generic chunk iterator callback");
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5D_istore_idx_iterate_cb() */
+} /* H5D_btree_idx_iterate_cb() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_idx_iterate
+ * Function: H5D_btree_idx_iterate
*
- * Purpose: Iterate over the chunks in the B-tree index, making a callback
+ * Purpose: Iterate over the chunks in an index, making a callback
* for each one.
*
* Return: Non-negative on success/Negative on failure
@@ -1067,38 +1076,42 @@ H5D_istore_idx_iterate_cb(H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
*-------------------------------------------------------------------------
*/
static int
-H5D_istore_idx_iterate(const H5D_chk_idx_info_t *idx_info,
+H5D_btree_idx_iterate(const H5D_chk_idx_info_t *idx_info,
H5D_chunk_cb_func_t chunk_cb, void *chunk_udata)
{
- H5D_istore_it_ud_t udata; /* User data for B-tree iterator callback */
+ H5D_btree_it_ud_t udata; /* User data for B-tree iterator callback */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_istore_idx_iterate)
+ FUNC_ENTER_NOAPI_NOINIT_NOERR(H5D_btree_idx_iterate)
HDassert(idx_info);
HDassert(idx_info->f);
+ HDassert(idx_info->pline);
HDassert(idx_info->layout);
+ HDassert(idx_info->storage);
+ HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
HDassert(chunk_cb);
HDassert(chunk_udata);
/* Initialize userdata */
HDmemset(&udata, 0, sizeof udata);
- udata.common.mesg = idx_info->layout;
+ udata.common.layout = idx_info->layout;
+ udata.common.storage = idx_info->storage;
udata.cb = chunk_cb;
udata.udata = chunk_udata;
/* Iterate over existing chunks */
- if((ret_value = H5B_iterate(idx_info->f, idx_info->dxpl_id, H5B_ISTORE, idx_info->layout->u.chunk.addr, H5D_istore_idx_iterate_cb, &udata)) < 0)
+ if((ret_value = H5B_iterate(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr, H5D_btree_idx_iterate_cb, &udata)) < 0)
HERROR(H5E_DATASET, H5E_BADITER, "unable to iterate over chunk B-tree");
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_idx_iterate() */
+} /* end H5D_btree_idx_iterate() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_idx_remove
+ * Function: H5D_btree_idx_remove
*
- * Purpose: Remove chunk from v1 B-tree index.
+ * Purpose: Remove chunk from index.
*
* Return: Non-negative on success/Negative on failure
*
@@ -1108,32 +1121,35 @@ H5D_istore_idx_iterate(const H5D_chk_idx_info_t *idx_info,
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_istore_idx_remove(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t *udata)
+H5D_btree_idx_remove(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t *udata)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_istore_idx_remove)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_remove)
HDassert(idx_info);
HDassert(idx_info->f);
+ HDassert(idx_info->pline);
HDassert(idx_info->layout);
+ HDassert(idx_info->storage);
+ HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
HDassert(udata);
/* Remove the chunk from the v1 B-tree index and release the space for the
* chunk (in the B-tree callback).
*/
- if(H5B_remove(idx_info->f, idx_info->dxpl_id, H5B_ISTORE, idx_info->layout->u.chunk.addr, udata) < 0)
+ if(H5B_remove(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr, udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to remove chunk entry")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5D_istore_idx_remove() */
+} /* H5D_btree_idx_remove() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_idx_delete
+ * Function: H5D_btree_idx_delete
*
- * Purpose: Delete v1 B-tree index and raw data storage for entire dataset
+ * Purpose: Delete index and raw data storage for entire dataset
* (i.e. all chunks)
*
* Return: Success: Non-negative
@@ -1145,46 +1161,54 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_istore_idx_delete(const H5D_chk_idx_info_t *idx_info)
+H5D_btree_idx_delete(const H5D_chk_idx_info_t *idx_info)
{
- H5O_layout_t tmp_layout; /* Local copy of layout info */
- H5D_istore_ud0_t udata; /* User data for B-tree iterator call */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_istore_idx_delete)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_delete)
/* Sanity checks */
HDassert(idx_info);
HDassert(idx_info->f);
+ HDassert(idx_info->pline);
HDassert(idx_info->layout);
- HDassert(H5F_addr_defined(idx_info->layout->u.chunk.addr));
-
- /* Set up user data for B-tree deletion */
- HDmemset(&udata, 0, sizeof udata);
- tmp_layout = *idx_info->layout;
- udata.mesg = &tmp_layout;
-
- /* Set up the shared structure */
- if(H5D_istore_shared_create(idx_info->f, &tmp_layout) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info")
-
- /* Delete entire B-tree */
- if(H5B_delete(idx_info->f, idx_info->dxpl_id, H5B_ISTORE, tmp_layout.u.chunk.addr, &udata) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to delete chunk B-tree")
-
- /* Free the raw B-tree node buffer */
- if(NULL == tmp_layout.u.chunk.btree_shared)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "ref-counted page nil")
- if(H5RC_DEC(tmp_layout.u.chunk.btree_shared) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page")
+ HDassert(idx_info->storage);
+
+ /* Check if the index data structure has been allocated */
+ if(H5F_addr_defined(idx_info->storage->idx_addr)) {
+ H5O_storage_chunk_t tmp_storage; /* Local copy of storage info */
+ H5D_chunk_common_ud_t udata; /* User data for B-tree operations */
+
+ /* Set up temporary chunked storage info */
+ tmp_storage = *idx_info->storage;
+
+ /* Set up the shared structure */
+ if(H5D_btree_shared_create(idx_info->f, &tmp_storage, idx_info->layout->ndims) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info")
+
+ /* Set up B-tree user data */
+ HDmemset(&udata, 0, sizeof udata);
+ udata.layout = idx_info->layout;
+ udata.storage = &tmp_storage;
+
+ /* Delete entire B-tree */
+ if(H5B_delete(idx_info->f, idx_info->dxpl_id, H5B_BTREE, tmp_storage.idx_addr, &udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to delete chunk B-tree")
+
+ /* Release the shared B-tree page */
+ if(NULL == tmp_storage.u.btree.shared)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "ref-counted page nil")
+ if(H5RC_DEC(tmp_storage.u.btree.shared) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page")
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_idx_delete() */
+} /* end H5D_btree_idx_delete() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_idx_copy_setup
+ * Function: H5D_btree_idx_copy_setup
*
* Purpose: Set up any necessary information for copying chunks
*
@@ -1196,38 +1220,43 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_istore_idx_copy_setup(const H5D_chk_idx_info_t *idx_info_src,
+H5D_btree_idx_copy_setup(const H5D_chk_idx_info_t *idx_info_src,
const H5D_chk_idx_info_t *idx_info_dst)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_istore_idx_copy_setup)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_copy_setup)
HDassert(idx_info_src);
HDassert(idx_info_src->f);
+ HDassert(idx_info_src->pline);
HDassert(idx_info_src->layout);
+ HDassert(idx_info_src->storage);
HDassert(idx_info_dst);
HDassert(idx_info_dst->f);
+ HDassert(idx_info_dst->pline);
HDassert(idx_info_dst->layout);
- HDassert(!H5F_addr_defined(idx_info_dst->layout->u.chunk.addr));
+ HDassert(idx_info_dst->storage);
+ HDassert(!H5F_addr_defined(idx_info_dst->storage->idx_addr));
/* Create shared B-tree info for each file */
- if(H5D_istore_shared_create(idx_info_src->f, idx_info_src->layout) < 0)
+ if(H5D_btree_shared_create(idx_info_src->f, idx_info_src->storage, idx_info_src->layout->ndims) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for source shared B-tree info")
- if(H5D_istore_shared_create(idx_info_dst->f, idx_info_dst->layout) < 0)
+ if(H5D_btree_shared_create(idx_info_dst->f, idx_info_dst->storage, idx_info_dst->layout->ndims) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for destination shared B-tree info")
/* Create the root of the B-tree that describes chunked storage in the dest. file */
- if(H5D_istore_idx_create(idx_info_dst) < 0)
+ if(H5D_btree_idx_create(idx_info_dst) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to initialize chunked storage")
+ HDassert(H5F_addr_defined(idx_info_dst->storage->idx_addr));
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_idx_copy_setup() */
+} /* end H5D_btree_idx_copy_setup() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_idx_copy_shutdown
+ * Function: H5D_btree_idx_copy_shutdown
*
* Purpose: Shutdown any information from copying chunks
*
@@ -1239,30 +1268,32 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_istore_idx_copy_shutdown(H5O_layout_t *layout_src, H5O_layout_t *layout_dst)
+H5D_btree_idx_copy_shutdown(H5O_storage_chunk_t *storage_src,
+ H5O_storage_chunk_t *storage_dst,
+ hid_t UNUSED dxpl_id)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_istore_idx_copy_shutdown)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_copy_shutdown)
- HDassert(layout_src);
- HDassert(layout_dst);
+ HDassert(storage_src);
+ HDassert(storage_dst);
/* Decrement refcount on shared B-tree info */
- if(H5RC_DEC(layout_src->u.chunk.btree_shared) < 0)
+ if(H5RC_DEC(storage_src->u.btree.shared) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to decrement ref-counted page")
- if(H5RC_DEC(layout_dst->u.chunk.btree_shared) < 0)
+ if(H5RC_DEC(storage_dst->u.btree.shared) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to decrement ref-counted page")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_idx_copy_shutdown() */
+} /* end H5D_btree_idx_copy_shutdown() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_idx_size
+ * Function: H5D_btree_idx_size
*
- * Purpose: Retrieve the amount of B-tree storage for chunked dataset
+ * Purpose: Retrieve the amount of index storage for chunked dataset
*
* Return: Success: Non-negative
* Failure: negative
@@ -1272,33 +1303,36 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5D_istore_idx_size(const H5D_chk_idx_info_t *idx_info, hsize_t *index_size)
+static herr_t
+H5D_btree_idx_size(const H5D_chk_idx_info_t *idx_info, hsize_t *index_size)
{
- H5D_istore_ud0_t udata; /* User-data for loading istore nodes */
+ H5D_chunk_common_ud_t udata; /* User-data for loading B-tree nodes */
H5B_info_t bt_info; /* B-tree info */
hbool_t shared_init = FALSE; /* Whether shared B-tree info is initialized */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5D_istore_idx_size, FAIL)
+ FUNC_ENTER_NOAPI(H5D_btree_idx_size, FAIL)
/* Check args */
HDassert(idx_info);
HDassert(idx_info->f);
+ HDassert(idx_info->pline);
HDassert(idx_info->layout);
+ HDassert(idx_info->storage);
HDassert(index_size);
/* Initialize the shared info for the B-tree traversal */
- if(H5D_istore_shared_create(idx_info->f, idx_info->layout) < 0)
+ if(H5D_btree_shared_create(idx_info->f, idx_info->storage, idx_info->layout->ndims) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info")
shared_init = TRUE;
- /* Initialize istore node user-data */
+ /* Initialize B-tree node user-data */
HDmemset(&udata, 0, sizeof udata);
- udata.mesg = idx_info->layout;
+ udata.layout = idx_info->layout;
+ udata.storage = idx_info->storage;
/* Get metadata information for B-tree */
- if(H5B_get_info(idx_info->f, idx_info->dxpl_id, H5B_ISTORE, idx_info->layout->u.chunk.addr, &bt_info, NULL, &udata) < 0)
+ if(H5B_get_info(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr, &bt_info, NULL, &udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to iterate over chunk B-tree")
/* Set the size of the B-tree */
@@ -1306,18 +1340,72 @@ H5D_istore_idx_size(const H5D_chk_idx_info_t *idx_info, hsize_t *index_size)
done:
if(shared_init) {
- if(idx_info->layout->u.chunk.btree_shared == NULL)
+ if(NULL == idx_info->storage->u.btree.shared)
HDONE_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "ref-counted page nil")
- if(H5RC_DEC(idx_info->layout->u.chunk.btree_shared) < 0)
+ if(H5RC_DEC(idx_info->storage->u.btree.shared) < 0)
HDONE_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page")
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_idx_size() */
+} /* end H5D_btree_idx_size() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_idx_dest
+ * Function: H5D_btree_idx_reset
+ *
+ * Purpose: Reset indexing information.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, January 15, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_btree_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_btree_idx_reset)
+
+ HDassert(storage);
+
+ /* Reset index info */
+ if(reset_addr)
+ storage->idx_addr = HADDR_UNDEF;
+ storage->u.btree.shared = NULL;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5D_btree_idx_reset() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_btree_idx_dump
+ *
+ * Purpose: Dump indexing information to a stream.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, January 15, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_btree_idx_dump(const H5O_storage_chunk_t *storage, FILE *stream)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_btree_idx_dump)
+
+ HDassert(storage);
+ HDassert(stream);
+
+ HDfprintf(stream, " Address: %a\n", storage->idx_addr);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5D_btree_idx_dump() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_btree_idx_dest
*
* Purpose: Release indexing information in memory.
*
@@ -1329,29 +1417,31 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_istore_idx_dest(const H5D_chk_idx_info_t *idx_info)
+H5D_btree_idx_dest(const H5D_chk_idx_info_t *idx_info)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_istore_idx_dest)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_dest)
HDassert(idx_info);
HDassert(idx_info->f);
+ HDassert(idx_info->pline);
HDassert(idx_info->layout);
+ HDassert(idx_info->storage);
/* Free the raw B-tree node buffer */
- if(idx_info->layout->u.chunk.btree_shared == NULL)
+ if(NULL == idx_info->storage->u.btree.shared)
HGOTO_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "ref-counted page nil")
- if(H5RC_DEC(idx_info->layout->u.chunk.btree_shared) < 0)
+ if(H5RC_DEC(idx_info->storage->u.btree.shared) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_idx_dest() */
+} /* end H5D_btree_idx_dest() */
/*-------------------------------------------------------------------------
- * Function: H5D_istore_debug
+ * Function: H5D_btree_debug
*
* Purpose: Debugs a B-tree node for indexed raw data storage.
*
@@ -1363,39 +1453,43 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D_istore_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent,
+H5D_btree_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent,
int fwidth, unsigned ndims)
{
- H5D_istore_ud0_t udata; /* B-tree user data */
- H5O_layout_t layout; /* Layout information for B-tree callback */
+ H5D_chunk_common_ud_t udata; /* User data for B-tree callback */
+ H5O_storage_chunk_t storage; /* Storage information for B-tree callback */
hbool_t shared_init = FALSE; /* Whether B-tree shared info is initialized */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5D_istore_debug, FAIL)
+ FUNC_ENTER_NOAPI(H5D_btree_debug, FAIL)
- /* Set up "fake" layout info */
- layout.u.chunk.ndims = ndims;
+ /* Reset "fake" storage info */
+ HDmemset(&storage, 0, sizeof(storage));
+ storage.idx_type = H5D_CHUNK_BTREE;
/* Allocate the shared structure */
- if(H5D_istore_shared_create(f, &layout) < 0)
+ if(H5D_btree_shared_create(f, &storage, ndims) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info")
shared_init = TRUE;
- /* Set up B-tree user data */
- HDmemset(&udata, 0, sizeof udata);
- udata.mesg = &layout;
+ /* Set up user data for callback */
+ udata.layout = NULL;
+ udata.storage = &storage;
+ udata.offset = NULL;
- (void)H5B_debug(f, dxpl_id, addr, stream, indent, fwidth, H5B_ISTORE, &udata);
+ /* Dump the records for the B-tree */
+ (void)H5B_debug(f, dxpl_id, addr, stream, indent, fwidth, H5B_BTREE, &udata);
done:
if(shared_init) {
/* Free the raw B-tree node buffer */
- if(layout.u.chunk.btree_shared == NULL)
+ if(NULL == storage.u.btree.shared)
HDONE_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "ref-counted page nil")
- if(H5RC_DEC(layout.u.chunk.btree_shared) < 0)
- HDONE_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page")
+ else
+ if(H5RC_DEC(storage.u.btree.shared) < 0)
+ HDONE_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page")
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_debug() */
+} /* end H5D_btree_debug() */
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index 9f590db..67c6b2f 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -13,6 +13,33 @@
* access to either file, you may request a copy from help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/* Programmer: Quincey Koziol <koziol@hdfgroup.org>
+ * Thursday, April 24, 2008
+ *
+ * Purpose: Abstract indexed (chunked) I/O functions. The logical
+ * multi-dimensional data space is regularly partitioned into
+ * same-sized "chunks", the first of which is aligned with the
+ * logical origin. The chunks are indexed by different methods,
+ * that map a chunk index to disk address. Each chunk can be
+ * compressed independently and the chunks may move around in the
+ * file as their storage requirements change.
+ *
+ * Cache: Disk I/O is performed in units of chunks and H5MF_alloc()
+ * contains code to optionally align chunks on disk block
+ * boundaries for performance.
+ *
+ * The chunk cache is an extendible hash indexed by a function
+ * of storage B-tree address and chunk N-dimensional offset
+ * within the dataset. Collisions are not resolved -- one of
+ * the two chunks competing for the hash slot must be preempted
+ * from the cache. All entries in the hash also participate in
+ * a doubly-linked list and entries are penalized by moving them
+ * toward the front of the list. When a new chunk is about to
+ * be added to the cache the heap is pruned by preempting
+ * entries near the front of the list to make room for the new
+ * entry which is added to the end of the list.
+ */
+
/****************/
/* Module Setup */
/****************/
@@ -36,9 +63,6 @@
/* Local Macros */
/****************/
-/* Default skip list height for storing list of chunks */
-#define H5D_CHUNK_DEFAULT_SKIPLIST_HEIGHT 8
-
/* Macros for iterating over chunks to operate on */
#define H5D_CHUNK_GET_FIRST_NODE(map) (map->use_single ? (H5SL_node_t *)(1) : H5SL_first(map->sel_chunks))
#define H5D_CHUNK_GET_NODE_INFO(map, node) (map->use_single ? map->single_chunk_info : (H5D_chunk_info_t *)H5SL_item(node))
@@ -75,14 +99,20 @@
/* Local Typedefs */
/******************/
+/* Stack of chunks to remove during a "prune" iteration */
+typedef struct H5D_chunk_prune_stack_t {
+ H5D_chunk_rec_t rec; /* Chunk record */
+ struct H5D_chunk_prune_stack_t *next; /* Next chunk in stack */
+} H5D_chunk_prune_stack_t;
+
/* Callback info for iteration to prune chunks */
typedef struct H5D_chunk_it_ud1_t {
H5D_chunk_common_ud_t common; /* Common info for B-tree user data (must be first) */
const H5D_chk_idx_info_t *idx_info; /* Chunked index info */
const H5D_io_info_t *io_info; /* I/O info for dataset operation */
const hsize_t *dims; /* New dataset dimensions */
- const hsize_t *down_chunks; /* "down" size of number of chunks in each dimension */
- H5SL_t *outside; /* Skip list to hold chunks outside the new dimensions */
+ const hbool_t *shrunk_dims; /* Dimensions which have been shrunk */
+ H5D_chunk_prune_stack_t *rm_stack; /* Stack of chunks outside the new dimensions */
H5S_t *chunk_space; /* Dataspace for a chunk */
uint32_t elmts_per_chunk;/* Elements in chunk */
hsize_t *hyper_start; /* Starting location of hyperslab */
@@ -90,23 +120,10 @@ typedef struct H5D_chunk_it_ud1_t {
hbool_t fb_info_init; /* Whether the fill value buffer has been initialized */
} H5D_chunk_it_ud1_t;
-/* Skip list node for storing chunks to remove during a "prune" iteration */
-typedef struct H5D_chunk_sl_ck_t {
- hsize_t index; /* Index of chunk to remove (must be first) */
- H5D_chunk_rec_t rec; /* Chunk record */
-} H5D_chunk_sl_ck_t;
-
-/* Skip list callback info when destroying list & removing chunks during "prune" */
-typedef struct H5D_chunk_sl_rm_t {
- const H5D_chk_idx_info_t *idx_info; /* I/O info for dataset operation */
- const H5O_layout_t *mesg; /* Layout message */
-} H5D_chunk_sl_rm_t;
-
/* Callback info for iteration to obtain chunk address and the index of the chunk for all chunks in the B-tree. */
-typedef struct H5D_chunk_id_ud2_t {
+typedef struct H5D_chunk_it_ud2_t {
/* down */
H5D_chunk_common_ud_t common; /* Common info for B-tree user data (must be first) */
- const hsize_t *down_chunks; /* "down chunk" element counts for chunks */
/* up */
haddr_t *chunk_addr; /* Array of chunk addresses to fill in */
@@ -126,7 +143,7 @@ typedef struct H5D_chunk_it_ud3_t {
hid_t tid_src; /* Datatype ID for source datatype */
hid_t tid_dst; /* Datatype ID for destination datatype */
hid_t tid_mem; /* Datatype ID for memory datatype */
- H5T_t *dt_src; /* Source datatype */
+ const H5T_t *dt_src; /* Source datatype */
H5T_path_t *tpath_src_mem; /* Datatype conversion path from source file to memory */
H5T_path_t *tpath_mem_dst; /* Datatype conversion path from memory to dest. file */
void *reclaim_buf; /* Buffer for reclaiming data */
@@ -135,7 +152,7 @@ typedef struct H5D_chunk_it_ud3_t {
H5S_t *buf_space; /* Dataspace describing buffer */
/* needed for compressed variable-length data */
- H5O_pline_t *pline; /* Filter pipeline */
+ const H5O_pline_t *pline; /* Filter pipeline */
/* needed for copy object pointed by refs */
H5O_copy_t *cpy_info; /* Copy options */
@@ -154,8 +171,7 @@ typedef struct H5D_chunk_it_ud4_t {
/********************/
/* Chunked layout operation callbacks */
-static herr_t H5D_chunk_new(H5F_t *f, hid_t dxpl_id, H5D_t *dset,
- const H5P_genplist_t *dc_plist);
+static herr_t H5D_chunk_construct(H5F_t *f, H5D_t *dset);
static herr_t H5D_chunk_io_init(const H5D_io_info_t *io_info,
const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space,
const H5S_t *mem_space, H5D_chunk_map_t *fm);
@@ -165,16 +181,22 @@ static herr_t H5D_chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type
static herr_t H5D_chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
H5D_chunk_map_t *fm);
+static herr_t H5D_chunk_flush(H5D_t *dset, hid_t dxpl_id);
static herr_t H5D_chunk_io_term(const H5D_chunk_map_t *fm);
-/* "Null" layout operation callbacks */
-static ssize_t H5D_null_readvv(const H5D_io_info_t *io_info,
- size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+/* "Nonexistent" layout operation callback */
+static ssize_t
+H5D_nonexistent_readvv(const H5D_io_info_t *io_info,
+ size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[], hsize_t chunk_offset_arr[],
size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]);
/* Helper routines */
+static herr_t H5D_chunk_set_info_real(H5O_layout_chunk_t *layout, unsigned ndims,
+ const hsize_t *curr_dims);
static void *H5D_chunk_alloc(size_t size, const H5O_pline_t *pline);
static void *H5D_chunk_xfree(void *chk, const H5O_pline_t *pline);
+static herr_t H5D_chunk_cinfo_cache_update(H5D_chunk_cached_t *last,
+ const H5D_chunk_ud_t *udata);
static herr_t H5D_free_chunk_info(void *item, void *key, void *opdata);
static herr_t H5D_create_chunk_map_single(H5D_chunk_map_t *fm,
const H5D_io_info_t *io_info);
@@ -185,16 +207,21 @@ static herr_t H5D_chunk_file_cb(void *elem, hid_t type_id, unsigned ndims,
const hsize_t *coords, void *fm);
static herr_t H5D_chunk_mem_cb(void *elem, hid_t type_id, unsigned ndims,
const hsize_t *coords, void *fm);
-
+static herr_t H5D_chunk_flush_entry(const H5D_t *dset, hid_t dxpl_id,
+ const H5D_dxpl_cache_t *dxpl_cache, H5D_rdcc_ent_t *ent, hbool_t reset);
+static herr_t H5D_chunk_cache_evict(const H5D_t *dset, hid_t dxpl_id,
+ const H5D_dxpl_cache_t *dxpl_cache, H5D_rdcc_ent_t *ent, hbool_t flush);
/*********************/
/* Package Variables */
/*********************/
-/* Compact storage layout I/O ops */
+/* Chunked storage layout I/O ops */
const H5D_layout_ops_t H5D_LOPS_CHUNK[1] = {{
- H5D_chunk_new,
+ H5D_chunk_construct,
+ H5D_chunk_init,
+ H5D_chunk_is_space_alloc,
H5D_chunk_io_init,
H5D_chunk_read,
H5D_chunk_write,
@@ -204,6 +231,7 @@ const H5D_layout_ops_t H5D_LOPS_CHUNK[1] = {{
#endif /* H5_HAVE_PARALLEL */
NULL,
NULL,
+ H5D_chunk_flush,
H5D_chunk_io_term
}};
@@ -212,8 +240,10 @@ const H5D_layout_ops_t H5D_LOPS_CHUNK[1] = {{
/* Local Variables */
/*******************/
-/* "null" storage layout I/O ops */
-const H5D_layout_ops_t H5D_LOPS_NULL[1] = {{
+/* "nonexistent" storage layout I/O ops */
+const H5D_layout_ops_t H5D_LOPS_NONEXISTENT[1] = {{
+ NULL,
+ NULL,
NULL,
NULL,
NULL,
@@ -222,7 +252,8 @@ const H5D_layout_ops_t H5D_LOPS_NULL[1] = {{
NULL,
NULL,
#endif /* H5_HAVE_PARALLEL */
- H5D_null_readvv,
+ H5D_nonexistent_readvv,
+ NULL,
NULL,
NULL
}};
@@ -230,7 +261,7 @@ const H5D_layout_ops_t H5D_LOPS_NULL[1] = {{
/* Declare a free list to manage the H5F_rdcc_ent_ptr_t sequence information */
H5FL_SEQ_DEFINE_STATIC(H5D_rdcc_ent_ptr_t);
-/* Declare a free list to manage H5F_rdcc_ent_t objects */
+/* Declare a free list to manage H5D_rdcc_ent_t objects */
H5FL_DEFINE_STATIC(H5D_rdcc_ent_t);
/* Declare a free list to manage the H5D_chunk_info_t struct */
@@ -240,12 +271,98 @@ H5FL_DEFINE(H5D_chunk_info_t);
H5FL_BLK_DEFINE_STATIC(chunk);
/* Declare a free list to manage H5D_chunk_sl_ck_t objects */
-H5FL_DEFINE_STATIC(H5D_chunk_sl_ck_t);
+H5FL_DEFINE_STATIC(H5D_chunk_prune_stack_t);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_chunk_set_info_real
+ *
+ * Purpose: Internal routine to set the information about chunks for a dataset
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_chunk_set_info_real(H5O_layout_chunk_t *layout, unsigned ndims, const hsize_t *curr_dims)
+{
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5D_chunk_set_info_real, FAIL)
+
+ /* Sanity checks */
+ HDassert(layout);
+ HDassert(ndims > 0);
+ HDassert(curr_dims);
+
+ /* Compute the # of chunks in dataset dimensions */
+ for(u = 0, layout->nchunks = 1; u < ndims; u++) {
+ /* Round up to the next integer # of chunks, to accomodate partial chunks */
+ layout->chunks[u] = ((curr_dims[u] + layout->dim[u]) - 1) / layout->dim[u];
+
+ /* Accumulate the # of chunks */
+ layout->nchunks *= layout->chunks[u];
+ } /* end for */
+
+ /* Get the "down" sizes for each dimension */
+ if(H5V_array_down(ndims, layout->chunks, layout->down_chunks) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't compute 'down' chunk size value")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_chunk_set_info_real() */
/*-------------------------------------------------------------------------
- * Function: H5D_chunk_new
+ * Function: H5D_chunk_set_info
+ *
+ * Purpose: Sets the information about chunks for a dataset
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_chunk_set_info(const H5D_t *dset)
+{
+ hsize_t curr_dims[H5O_LAYOUT_NDIMS]; /* Curr. size of dataset dimensions */
+ int sndims; /* Rank of dataspace */
+ unsigned ndims; /* Rank of dataspace */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5D_chunk_set_info, FAIL)
+
+ /* Sanity checks */
+ HDassert(dset);
+
+ /* Get the dim info for dataset */
+ if((sndims = H5S_get_simple_extent_dims(dset->shared->space, curr_dims, NULL)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataspace dimensions")
+ H5_ASSIGN_OVERFLOW(ndims, sndims, int, unsigned);
+
+ /* Set the base layout information */
+ if(H5D_chunk_set_info_real(&dset->shared->layout.u.chunk, ndims, curr_dims) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set layout's chunk info")
+
+ /* Call the index's "resize" callback */
+ if(dset->shared->layout.storage.u.chunk.ops->resize && (dset->shared->layout.storage.u.chunk.ops->resize)(&dset->shared->layout.u.chunk) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to resize chunk index information")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_chunk_set_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_chunk_construct
*
* Purpose: Constructs new chunked layout information for dataset
*
@@ -257,58 +374,48 @@ H5FL_DEFINE_STATIC(H5D_chunk_sl_ck_t);
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_chunk_new(H5F_t *f, hid_t dxpl_id, H5D_t *dset,
- const H5P_genplist_t *dc_plist)
+H5D_chunk_construct(H5F_t UNUSED *f, H5D_t *dset)
{
const H5T_t *type = dset->shared->type; /* Convenience pointer to dataset's datatype */
hsize_t max_dim[H5O_LAYOUT_NDIMS]; /* Maximum size of data in elements */
uint64_t chunk_size; /* Size of chunk in bytes */
- unsigned chunk_ndims = 0; /* Dimensionality of chunk */
int ndims; /* Rank of dataspace */
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_new)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_construct)
/* Sanity checks */
HDassert(f);
HDassert(dset);
- HDassert(dc_plist);
-
- /* Retrieve rank of chunks from property list */
- if(H5P_get(dc_plist, H5D_CRT_CHUNK_DIM_NAME, &chunk_ndims) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve chunk dimensions")
/* Set up layout information */
if((ndims = H5S_GET_EXTENT_NDIMS(dset->shared->space)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get rank")
- dset->shared->layout.u.chunk.ndims = (unsigned)ndims + 1;
- HDassert((unsigned)(dset->shared->layout.u.chunk.ndims) <= NELMTS(dset->shared->layout.u.chunk.dim));
+ if(dset->shared->layout.u.chunk.ndims != (unsigned)ndims)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "dimensionality of chunks doesn't match the dataspace")
- /* Initialize to no address */
- dset->shared->layout.u.chunk.addr = HADDR_UNDEF;
+ /* Increment # of chunk dimensions, to account for datatype size as last element */
+ dset->shared->layout.u.chunk.ndims++;
+ HDassert((unsigned)(dset->shared->layout.u.chunk.ndims) <= NELMTS(dset->shared->layout.u.chunk.dim));
- /*
- * Chunked storage allows any type of data space extension, so we
- * don't even bother checking.
- */
- if(chunk_ndims != (unsigned)ndims)
- HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "dimensionality of chunks doesn't match the data space")
+ /* Chunked storage is not compatible with external storage (currently) */
if(dset->shared->dcpl_cache.efl.nused > 0)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "external storage not supported with chunked layout")
- /*
- * The chunk size of a dimension with a fixed size cannot exceed
- * the maximum dimension size
- */
- if(H5P_get(dc_plist, H5D_CRT_CHUNK_SIZE_NAME, dset->shared->layout.u.chunk.dim) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve chunk size")
- dset->shared->layout.u.chunk.dim[dset->shared->layout.u.chunk.ndims - 1] = H5T_get_size(type);
+ /* Set the last dimension of the chunk size to the size of the datatype */
+ dset->shared->layout.u.chunk.dim[dset->shared->layout.u.chunk.ndims - 1] = H5T_GET_SIZE(type);
- /* Sanity check dimensions */
+ /* Get local copy of dataset dimensions (for sanity checking) */
if(H5S_get_simple_extent_dims(dset->shared->space, NULL, max_dim) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to query maximum dimensions")
+
+ /* Sanity check dimensions */
for(u = 0; u < dset->shared->layout.u.chunk.ndims - 1; u++)
+ /*
+ * The chunk size of a dimension with a fixed size cannot exceed
+ * the maximum dimension size
+ */
if(max_dim[u] != H5S_UNLIMITED && max_dim[u] < dset->shared->layout.u.chunk.dim[u])
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "chunk size must be <= maximum dimension size for fixed-sized dimensions")
@@ -325,13 +432,120 @@ H5D_chunk_new(H5F_t *f, hid_t dxpl_id, H5D_t *dset,
/* Retain computed chunk size */
H5_ASSIGN_OVERFLOW(dset->shared->layout.u.chunk.size, chunk_size, uint64_t, uint32_t);
- /* Initialize the chunk cache for the dataset */
- if(H5D_chunk_init(f, dxpl_id, dset) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize chunk cache")
+ /* Reset address and pointer of the array struct for the chunked storage index */
+ if(H5D_chunk_idx_reset(&dset->shared->layout.storage.u.chunk, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to reset chunked storage index")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_chunk_construct() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_chunk_init
+ *
+ * Purpose: Initialize the raw data chunk cache for a dataset. This is
+ * called when the dataset is initialized.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Monday, May 18, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_chunk_init(H5F_t *f, hid_t dxpl_id, const H5D_t *dset, hid_t dapl_id)
+{
+ H5D_chk_idx_info_t idx_info; /* Chunked index info */
+ H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /* Convenience pointer to dataset's chunk cache */
+ H5P_genplist_t *dapl; /* Data access property list object pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5D_chunk_init, FAIL)
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(dset);
+
+ if(NULL == (dapl = (H5P_genplist_t *)H5I_object(dapl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for fapl ID");
+
+ /* Use the properties in dapl_id if they have been set, otherwise use the properties from the file */
+ if(H5P_get(dapl, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, &rdcc->nslots) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get data cache number of slots");
+ if(rdcc->nslots == H5D_CHUNK_CACHE_NSLOTS_DEFAULT)
+ rdcc->nslots = H5F_RDCC_NSLOTS(f);
+
+ if(H5P_get(dapl, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, &rdcc->nbytes_max) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get data cache byte size");
+ if(rdcc->nbytes_max == H5D_CHUNK_CACHE_NBYTES_DEFAULT)
+ rdcc->nbytes_max = H5F_RDCC_NBYTES(f);
+
+ if(H5P_get(dapl, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, &rdcc->w0) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get preempt read chunks");
+ if(rdcc->w0 < 0)
+ rdcc->w0 = H5F_RDCC_W0(f);
+
+ /* If nbytes_max or nslots is 0, set them both to 0 and avoid allocating space */
+ if(!rdcc->nbytes_max || !rdcc->nslots)
+ rdcc->nbytes_max = rdcc->nslots = 0;
+ else {
+ rdcc->slot = H5FL_SEQ_CALLOC(H5D_rdcc_ent_ptr_t, rdcc->nslots);
+ if(NULL == rdcc->slot)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Reset any cached chunk info for this dataset */
+ H5D_chunk_cinfo_cache_reset(&(rdcc->last));
+ } /* end else */
+
+ /* Compose chunked index info struct */
+ idx_info.f = f;
+ idx_info.dxpl_id = dxpl_id;
+ idx_info.pline = &dset->shared->dcpl_cache.pline;
+ idx_info.layout = &dset->shared->layout.u.chunk;
+ idx_info.storage = &dset->shared->layout.storage.u.chunk;
+
+ /* Allocate any indexing structures */
+ if(dset->shared->layout.storage.u.chunk.ops->init && (dset->shared->layout.storage.u.chunk.ops->init)(&idx_info, dset->shared->space, dset->oloc.addr) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize indexing information")
+
+ /* Set the number of chunks in dataset */
+ if(H5D_chunk_set_info(dset) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set # of chunks for dataset")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_chunk_new() */
+} /* end H5D_chunk_init() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_chunk_is_space_alloc
+ *
+ * Purpose: Query if space is allocated for layout
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, January 15, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5D_chunk_is_space_alloc(const H5O_storage_t *storage)
+{
+ hbool_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOFUNC(H5D_chunk_is_space_alloc)
+
+ /* Sanity checks */
+ HDassert(storage);
+
+ /* Query index layer */
+ ret_value = (storage->u.chunk.ops->is_space_alloc)(&storage->u.chunk);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_chunk_is_space_alloc() */
/*-------------------------------------------------------------------------
@@ -397,24 +611,14 @@ H5D_chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info
for(u = 0; u < f_ndims; u++) {
/* Keep the size of the chunk dimensions as hsize_t for various routines */
fm->chunk_dim[u] = fm->layout->u.chunk.dim[u];
-
- /* Round up to the next integer # of chunks, to accomodate partial chunks */
- fm->chunks[u] = ((fm->f_dims[u] + dataset->shared->layout.u.chunk.dim[u]) - 1) / dataset->shared->layout.u.chunk.dim[u];
} /* end for */
- /* Compute the "down" size of 'chunks' information */
- if(H5V_array_down(f_ndims, fm->chunks, fm->down_chunks) < 0)
- HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "can't compute 'down' sizes")
-
#ifdef H5_HAVE_PARALLEL
/* Calculate total chunk in file map*/
fm->select_chunk = NULL;
- fm->total_chunks = 1;
- for(u = 0; u < fm->f_ndims; u++)
- fm->total_chunks = fm->total_chunks * fm->chunks[u];
if(io_info->using_mpi_vfd) {
- H5_CHECK_OVERFLOW(fm->total_chunks, hsize_t, size_t);
- if(NULL == (fm->select_chunk = (H5D_chunk_info_t **)H5MM_calloc((size_t)fm->total_chunks * sizeof(H5D_chunk_info_t *))))
+ H5_CHECK_OVERFLOW(fm->layout->u.chunk.nchunks, hsize_t, size_t);
+ if(NULL == (fm->select_chunk = (H5D_chunk_info_t **)H5MM_calloc((size_t)fm->layout->u.chunk.nchunks * sizeof(H5D_chunk_info_t *))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info")
} /* end if */
#endif /* H5_HAVE_PARALLEL */
@@ -474,7 +678,7 @@ H5D_chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info
else {
/* Initialize skip list for chunk selections */
if(NULL == dataset->shared->cache.chunk.sel_chunks) {
- if(NULL == (dataset->shared->cache.chunk.sel_chunks = H5SL_create(H5SL_TYPE_HSIZE, 0.5, (size_t)H5D_CHUNK_DEFAULT_SKIPLIST_HEIGHT)))
+ if(NULL == (dataset->shared->cache.chunk.sel_chunks = H5SL_create(H5SL_TYPE_HSIZE)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create skip list for chunk selections")
} /* end if */
fm->sel_chunks = dataset->shared->cache.chunk.sel_chunks;
@@ -520,7 +724,7 @@ H5D_chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info
} /* end if */
else {
/* Create temporary datatypes for selection iteration */
- if((f_tid = H5I_register(H5I_DATATYPE, H5T_copy(dataset->shared->type, H5T_COPY_ALL))) < 0)
+ if((f_tid = H5I_register(H5I_DATATYPE, H5T_copy(dataset->shared->type, H5T_COPY_ALL), FALSE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register file datatype")
/* Spaces might not be the same shape, iterate over the file selection directly */
@@ -559,7 +763,7 @@ H5D_chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info
/* Create temporary datatypes for selection iteration */
if(f_tid < 0) {
- if((f_tid = H5I_register(H5I_DATATYPE, H5T_copy(dataset->shared->type, H5T_COPY_ALL))) < 0)
+ if((f_tid = H5I_register(H5I_DATATYPE, H5T_copy(dataset->shared->type, H5T_COPY_ALL), FALSE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register file datatype")
} /* end if */
@@ -617,7 +821,7 @@ done:
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
} /* end if */
if(f_tid!=(-1)) {
- if(H5I_dec_ref(f_tid) < 0)
+ if(H5I_dec_ref(f_tid, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
} /* end if */
if(file_space_normalized) {
@@ -649,7 +853,7 @@ H5D_chunk_alloc(size_t size, const H5O_pline_t *pline)
{
void *ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_alloc)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_chunk_alloc)
HDassert(size);
HDassert(pline);
@@ -732,7 +936,7 @@ H5D_free_chunk_info(void *item, void UNUSED *key, void UNUSED *opdata)
(void)H5S_close(chunk_info->mspace);
/* Free the actual chunk info */
- H5FL_FREE(H5D_chunk_info_t, chunk_info);
+ (void)H5FL_FREE(H5D_chunk_info_t, chunk_info);
FUNC_LEAVE_NOAPI(0)
} /* H5D_free_chunk_info() */
@@ -784,7 +988,7 @@ H5D_create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t
chunk_info->coords[fm->f_ndims] = 0;
/* Calculate the index of this chunk */
- if(H5V_chunk_index(fm->f_ndims, chunk_info->coords, fm->layout->u.chunk.dim, fm->down_chunks, &chunk_info->index) < 0)
+ if(H5V_chunk_index(fm->f_ndims, chunk_info->coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_info->index) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
/* Copy selection for file's dataspace into chunk dataspace */
@@ -868,22 +1072,21 @@ H5D_create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t
end[u] = (coords[u] + fm->chunk_dim[u]) - 1;
} /* end for */
-
/* Calculate the index of this chunk */
- if(H5V_chunk_index(fm->f_ndims, coords, fm->layout->u.chunk.dim, fm->down_chunks, &chunk_index) < 0)
+ if(H5V_chunk_index(fm->f_ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_index) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
/* Iterate through each chunk in the dataset */
while(sel_points) {
/* Check for intersection of temporary chunk and file selection */
/* (Casting away const OK - QAK) */
- if(H5S_hyper_intersect_block((H5S_t *)fm->file_space,coords,end)==TRUE) {
+ if(TRUE == H5S_hyper_intersect_block((H5S_t *)fm->file_space, coords, end)) {
H5S_t *tmp_fchunk; /* Temporary file dataspace */
H5D_chunk_info_t *new_chunk_info; /* chunk information to insert into skip list */
hssize_t schunk_points; /* Number of elements in chunk selection */
/* Create "temporary" chunk for selection operations (copy file space) */
- if((tmp_fchunk = H5S_copy(fm->file_space, TRUE, FALSE)) == NULL)
+ if(NULL == (tmp_fchunk = H5S_copy(fm->file_space, TRUE, FALSE)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space")
/* Make certain selections are stored in span tree form (not "optimized hyperslab" or "all") */
@@ -973,22 +1176,22 @@ H5D_create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t
end[curr_dim]+=fm->chunk_dim[curr_dim];
/* Bring chunk location back into bounds, if necessary */
- if(coords[curr_dim]>sel_end[curr_dim]) {
+ if(coords[curr_dim] > sel_end[curr_dim]) {
do {
/* Reset current dimension's location to 0 */
- coords[curr_dim]=start_coords[curr_dim]; /*lint !e771 The start_coords will always be initialized */
- end[curr_dim]=(coords[curr_dim]+(hssize_t)fm->chunk_dim[curr_dim])-1;
+ coords[curr_dim] = start_coords[curr_dim]; /*lint !e771 The start_coords will always be initialized */
+ end[curr_dim] = (coords[curr_dim] + fm->chunk_dim[curr_dim]) - 1;
/* Decrement current dimension */
curr_dim--;
/* Increment chunk location in current dimension */
- coords[curr_dim]+=fm->chunk_dim[curr_dim];
- end[curr_dim]=(coords[curr_dim]+fm->chunk_dim[curr_dim])-1;
- } while(coords[curr_dim]>sel_end[curr_dim]);
+ coords[curr_dim] += fm->chunk_dim[curr_dim];
+ end[curr_dim] = (coords[curr_dim] + fm->chunk_dim[curr_dim]) - 1;
+ } while(coords[curr_dim] > sel_end[curr_dim]);
- /* Re-Calculate the index of this chunk */
- if(H5V_chunk_index(fm->f_ndims, coords, fm->layout->u.chunk.dim, fm->down_chunks, &chunk_index) < 0)
+ /* Re-calculate the index of this chunk */
+ if(H5V_chunk_index(fm->f_ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_index) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
} /* end if */
} /* end while */
@@ -1045,7 +1248,7 @@ H5D_create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm)
/* Just point at the memory dataspace & selection */
/* (Casting away const OK -QAK) */
- chunk_info->mspace=(H5S_t *)fm->mem_space;
+ chunk_info->mspace = (H5S_t *)fm->mem_space;
/* Indicate that the chunk's memory space is shared */
chunk_info->mspace_shared = TRUE;
@@ -1136,7 +1339,7 @@ H5D_chunk_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const
FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_file_cb)
/* Calculate the index of this chunk */
- if(H5V_chunk_index(ndims, coords, fm->layout->u.chunk.dim, fm->down_chunks, &chunk_index) < 0)
+ if(H5V_chunk_index(ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_index) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
/* Find correct chunk in file & memory skip list */
@@ -1165,14 +1368,14 @@ H5D_chunk_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const
/* Create a dataspace for the chunk */
if((fspace = H5S_create_simple(fm->f_ndims,fm->chunk_dim,NULL))==NULL) {
- H5FL_FREE(H5D_chunk_info_t,chunk_info);
+ (void)H5FL_FREE(H5D_chunk_info_t,chunk_info);
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create dataspace for chunk")
} /* end if */
/* De-select the chunk space */
if(H5S_select_none(fspace) < 0) {
(void)H5S_close(fspace);
- H5FL_FREE(H5D_chunk_info_t,chunk_info);
+ (void)H5FL_FREE(H5D_chunk_info_t,chunk_info);
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to de-select dataspace")
} /* end if */
@@ -1248,15 +1451,15 @@ H5D_chunk_mem_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const
FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_mem_cb)
/* Calculate the index of this chunk */
- if(H5V_chunk_index(ndims, coords, fm->layout->u.chunk.dim, fm->down_chunks, &chunk_index) < 0)
+ if(H5V_chunk_index(ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_index) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
/* Find correct chunk in file & memory skip list */
- if(chunk_index==fm->last_index) {
+ if(chunk_index == fm->last_index) {
/* If the chunk index is the same as the last chunk index we used,
* get the cached spaces to operate on.
*/
- chunk_info=fm->last_chunk_info;
+ chunk_info = fm->last_chunk_info;
} /* end if */
else {
/* If the chunk index is not the same as the last chunk index we used,
@@ -1267,23 +1470,23 @@ H5D_chunk_mem_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const
HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, FAIL, "can't locate chunk in skip list")
/* Check if the chunk already has a memory space */
- if(chunk_info->mspace==NULL) {
+ if(NULL == chunk_info->mspace) {
/* Copy the template memory chunk dataspace */
- if((chunk_info->mspace = H5S_copy(fm->mchunk_tmpl, FALSE, FALSE)) == NULL)
+ if(NULL == (chunk_info->mspace = H5S_copy(fm->mchunk_tmpl, FALSE, FALSE)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file space")
} /* end else */
/* Update the "last chunk seen" information */
- fm->last_index=chunk_index;
- fm->last_chunk_info=chunk_info;
+ fm->last_index = chunk_index;
+ fm->last_chunk_info = chunk_info;
} /* end else */
/* Get coordinates of selection iterator for memory */
- if(H5S_SELECT_ITER_COORDS(&fm->mem_iter,coords_in_mem) < 0)
+ if(H5S_SELECT_ITER_COORDS(&fm->mem_iter, coords_in_mem) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator coordinates")
/* Add point to memory selection for chunk */
- if(fm->msel_type==H5S_SEL_POINTS) {
+ if(fm->msel_type == H5S_SEL_POINTS) {
if(H5S_select_elements(chunk_info->mspace, H5S_SELECT_APPEND, (size_t)1, coords_in_mem) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to select element")
} /* end if */
@@ -1314,13 +1517,13 @@ done:
*
*-------------------------------------------------------------------------
*/
-hbool_t
-H5D_chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr)
+htri_t
+H5D_chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr, hbool_t write_op)
{
const H5D_t *dataset = io_info->dset;
- hbool_t ret_value;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_chunk_cacheable)
+ htri_t ret_value = FAIL;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_cacheable)
HDassert(io_info);
HDassert(dataset);
@@ -1339,21 +1542,38 @@ H5D_chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr)
ret_value = FALSE;
else {
#endif /* H5_HAVE_PARALLEL */
- /* If the chunk is too large to keep in the cache and if the address
- * for the chunk has been defined, then don't load the chunk into the
+ /* If the chunk is too large to keep in the cache and if we don't
+ * need to write the fill value, then don't load the chunk into the
* cache, just write the data to it directly.
*/
H5_CHECK_OVERFLOW(dataset->shared->layout.u.chunk.size, uint32_t, size_t);
- if((size_t)dataset->shared->layout.u.chunk.size > dataset->shared->cache.chunk.nbytes
- && H5F_addr_defined(caddr))
- ret_value = FALSE;
- else
+ if((size_t)dataset->shared->layout.u.chunk.size > dataset->shared->cache.chunk.nbytes_max) {
+ if(write_op && !H5F_addr_defined(caddr)) {
+ const H5O_fill_t *fill = &(dataset->shared->dcpl_cache.fill); /* Fill value info */
+ H5D_fill_value_t fill_status; /* Fill value status */
+
+ /* Revtrieve the fill value status */
+ if(H5P_is_fill_value_defined(fill, &fill_status) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined")
+
+ /* If the fill value needs to be written then we will need
+ * to use the cache to write the fill value */
+ if(fill->fill_time == H5D_FILL_TIME_ALLOC ||
+ (fill->fill_time == H5D_FILL_TIME_IFSET
+ && fill_status == H5D_FILL_VALUE_USER_DEFINED))
+ ret_value = TRUE;
+ else
+ ret_value = FALSE;
+ } else
+ ret_value = FALSE;
+ } else
ret_value = TRUE;
#ifdef H5_HAVE_PARALLEL
} /* end else */
#endif /* H5_HAVE_PARALLEL */
} /* end else */
+done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_chunk_cacheable() */
@@ -1370,13 +1590,13 @@ H5D_chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr)
*
*-------------------------------------------------------------------------
*/
-static hbool_t
+static hbool_t
H5D_chunk_in_cache(const H5D_t *dset, const hsize_t *chunk_offset,
hsize_t chunk_idx)
{
H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk);/*raw data chunk cache*/
hbool_t found = FALSE; /*already in cache? */
-
+
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_chunk_in_cache)
/* Sanity checks */
@@ -1423,7 +1643,7 @@ H5D_chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
H5D_chunk_map_t *fm)
{
H5SL_node_t *chunk_node; /* Current node in chunk skip list */
- H5D_io_info_t nul_io_info; /* "null" I/O info object */
+ H5D_io_info_t nonexistent_io_info; /* "nonexistent" I/O info object */
H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
H5D_io_info_t cpt_io_info; /* Compact I/O info object */
@@ -1442,9 +1662,9 @@ H5D_chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
HDassert(type_info);
HDassert(fm);
- /* Set up "null" I/O info object */
- HDmemcpy(&nul_io_info, io_info, sizeof(nul_io_info));
- nul_io_info.layout_ops = *H5D_LOPS_NULL;
+ /* Set up "nonexistent" I/O info object */
+ HDmemcpy(&nonexistent_io_info, io_info, sizeof(nonexistent_io_info));
+ nonexistent_io_info.layout_ops = *H5D_LOPS_NONEXISTENT;
/* Set up contiguous I/O info object */
HDmemcpy(&ctg_io_info, io_info, sizeof(ctg_io_info));
@@ -1484,27 +1704,23 @@ H5D_chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
H5D_chunk_info_t *chunk_info; /* Chunk information */
H5D_io_info_t *chk_io_info; /* Pointer to I/O info object for this chunk */
void *chunk; /* Pointer to locked chunk buffer */
- haddr_t chunk_addr; /* Chunk address on disk */
H5D_chunk_ud_t udata; /* B-tree pass-through */
+ htri_t cacheable; /* Whether the chunk is cacheable */
/* Get the actual chunk information from the skip list node */
chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
- /* Get the address of the chunk in the file */
- chunk_addr = H5D_chunk_get_addr(io_info->dset, io_info->dxpl_id, chunk_info->coords, &udata);
+ /* Get the info for the chunk in the file */
+ if(H5D_chunk_get_info(io_info->dset, io_info->dxpl_id, chunk_info->coords, &udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
/* Check for non-existant chunk & skip it if appropriate */
- if(!H5F_addr_defined(chunk_addr) && !H5D_chunk_in_cache(io_info->dset, chunk_info->coords, chunk_info->index)
- && skip_missing_chunks) {
- /* No chunk cached */
- chunk = NULL;
-
- /* Point I/O info at "null" I/O info for this chunk */
- chk_io_info = &nul_io_info;
- } /* end if */
- else {
+ if(H5F_addr_defined(udata.addr) || H5D_chunk_in_cache(io_info->dset, chunk_info->coords, chunk_info->index)
+ || !skip_missing_chunks) {
/* Load the chunk into cache and lock it. */
- if(H5D_chunk_cacheable(io_info, chunk_addr)) {
+ if((cacheable = H5D_chunk_cacheable(io_info, udata.addr, FALSE)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable")
+ if(cacheable) {
/* Pass in chunk's coordinates in a union. */
io_info->store->chunk.offset = chunk_info->coords;
io_info->store->chunk.index = chunk_info->index;
@@ -1522,29 +1738,33 @@ H5D_chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
/* Point I/O info at contiguous I/O info for this chunk */
chk_io_info = &cpt_io_info;
} /* end if */
- else {
- /* Sanity check */
- HDassert(H5F_addr_defined(chunk_addr));
-
+ else if(H5F_addr_defined(udata.addr)) {
/* Set up the storage address information for this chunk */
- ctg_store.contig.dset_addr = chunk_addr;
+ ctg_store.contig.dset_addr = udata.addr;
/* No chunk cached */
chunk = NULL;
/* Point I/O info at temporary I/O info for this chunk */
chk_io_info = &ctg_io_info;
+ } /* end else if */
+ else {
+ /* No chunk cached */
+ chunk = NULL;
+
+ /* Point I/O info at "nonexistent" I/O info for this chunk */
+ chk_io_info = &nonexistent_io_info;
} /* end else */
- } /* end else */
- /* Perform the actual read operation */
- if((io_info->io_ops.single_read)(chk_io_info, type_info,
- (hsize_t)chunk_info->chunk_points, chunk_info->fspace, chunk_info->mspace) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked read failed")
+ /* Perform the actual read operation */
+ if((io_info->io_ops.single_read)(chk_io_info, type_info,
+ (hsize_t)chunk_info->chunk_points, chunk_info->fspace, chunk_info->mspace) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked read failed")
- /* Release the cache lock on the chunk. */
- if(chunk && H5D_chunk_unlock(io_info, FALSE, idx_hint, chunk, src_accessed_bytes) < 0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
+ /* Release the cache lock on the chunk. */
+ if(chunk && H5D_chunk_unlock(io_info, &udata, FALSE, idx_hint, chunk, src_accessed_bytes) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
+ } /* end if */
/* Advance to next chunk in list */
chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
@@ -1565,6 +1785,12 @@ done:
* Programmer: Raymond Lu
* Thursday, April 10, 2003
*
+ * Modification:Raymond Lu
+ * 4 Feb 2009
+ * One case that was considered cacheable was when the chunk
+ * was bigger than the cache size but not allocated on disk.
+ * I moved it to uncacheable branch to bypass the cache to
+ * improve performance.
*-------------------------------------------------------------------------
*/
static herr_t
@@ -1612,16 +1838,19 @@ H5D_chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
H5D_chunk_info_t *chunk_info; /* Chunk information */
H5D_io_info_t *chk_io_info; /* Pointer to I/O info object for this chunk */
void *chunk; /* Pointer to locked chunk buffer */
- haddr_t chunk_addr; /* Chunk address on disk */
- H5D_chunk_ud_t udata; /* B-tree pass-through */
+ H5D_chunk_ud_t udata; /* Index pass-through */
+ htri_t cacheable; /* Whether the chunk is cacheable */
/* Get the actual chunk information from the skip list node */
chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
/* Load the chunk into cache. But if the whole chunk is written,
* simply allocate space instead of load the chunk. */
- chunk_addr = H5D_chunk_get_addr(io_info->dset, io_info->dxpl_id, chunk_info->coords, &udata);
- if(H5D_chunk_cacheable(io_info, chunk_addr)) {
+ if(H5D_chunk_get_info(io_info->dset, io_info->dxpl_id, chunk_info->coords, &udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
+ if((cacheable = H5D_chunk_cacheable(io_info, udata.addr, TRUE)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable")
+ if(cacheable) {
hbool_t entire_chunk = TRUE; /* Whether whole chunk is selected */
/* Pass in chunk's coordinates in a union. */
@@ -1647,11 +1876,34 @@ H5D_chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
chk_io_info = &cpt_io_info;
} /* end if */
else {
- /* Sanity check */
- HDassert(H5F_addr_defined(chunk_addr));
+ /* If the chunk hasn't been allocated on disk, do so now. */
+ if(!H5F_addr_defined(udata.addr)) {
+ H5D_chk_idx_info_t idx_info; /* Chunked index info */
+
+ /* Compose chunked index info struct */
+ idx_info.f = io_info->dset->oloc.file;
+ idx_info.dxpl_id = io_info->dxpl_id;
+ idx_info.pline = &(io_info->dset->shared->dcpl_cache.pline);
+ idx_info.layout = &(io_info->dset->shared->layout.u.chunk);
+ idx_info.storage = &(io_info->dset->shared->layout.storage.u.chunk);
+
+ /* Set up the size of chunk for user data */
+ udata.nbytes = io_info->dset->shared->layout.u.chunk.size;
+
+ /* Create the chunk */
+ if((io_info->dset->shared->layout.storage.u.chunk.ops->insert)(&idx_info, &udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert/resize chunk")
+
+ /* Make sure the address of the chunk is returned. */
+ if(!H5F_addr_defined(udata.addr))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "chunk address isn't defined")
+
+ /* Cache the new chunk information */
+ H5D_chunk_cinfo_cache_update(&io_info->dset->shared->cache.chunk.last, &udata);
+ } /* end if */
/* Set up the storage address information for this chunk */
- ctg_store.contig.dset_addr = chunk_addr;
+ ctg_store.contig.dset_addr = udata.addr;
/* No chunk cached */
chunk = NULL;
@@ -1666,7 +1918,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked write failed")
/* Release the cache lock on the chunk. */
- if(chunk && H5D_chunk_unlock(io_info, TRUE, idx_hint, chunk, dst_accessed_bytes) < 0)
+ if(chunk && H5D_chunk_unlock(io_info, &udata, TRUE, idx_hint, chunk, dst_accessed_bytes) < 0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
/* Advance to next chunk in list */
@@ -1679,6 +1931,56 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D_chunk_flush
+ *
+ * Purpose: Writes all dirty chunks to disk and optionally preempts them
+ * from the cache.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Thursday, May 21, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_chunk_flush(H5D_t *dset, hid_t dxpl_id)
+{
+ H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */
+ H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */
+ H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk);
+ H5D_rdcc_ent_t *ent, *next;
+ unsigned nerrors = 0; /* Count of any errors encountered when flushing chunks */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_flush)
+
+ /* Sanity check */
+ HDassert(dset);
+
+ /* Flush any data caught in sieve buffer */
+ if(H5D_flush_sieve_buf(dset, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to flush sieve buffer")
+
+ /* Fill the DXPL cache values for later use */
+ if(H5D_get_dxpl_cache(dxpl_id, &dxpl_cache) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache")
+
+ /* Loop over all entries in the chunk cache */
+ for(ent = rdcc->head; ent; ent = next) {
+ next = ent->next;
+ if(H5D_chunk_flush_entry(dset, dxpl_id, dxpl_cache, ent, FALSE) < 0)
+ nerrors++;
+ } /* end for */
+ if(nerrors)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to flush one or more raw data chunks")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_chunk_flush() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_chunk_io_term
*
* Purpose: Destroy I/O operation information.
@@ -1730,54 +2032,35 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_chunk_init
+ * Function: H5D_chunk_idx_reset
*
- * Purpose: Initialize the raw data chunk cache for a dataset. This is
- * called when the dataset is initialized.
+ * Purpose: Reset index information
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * Monday, May 18, 1998
+ * Programmer: Quincey Koziol
+ * Thursday, January 15, 2009
*
*-------------------------------------------------------------------------
*/
herr_t
-H5D_chunk_init(H5F_t *f, hid_t dxpl_id, const H5D_t *dset)
+H5D_chunk_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr)
{
- H5D_chk_idx_info_t idx_info; /* Chunked index info */
- H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /* Convenience pointer to dataset's chunk cache */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5D_chunk_init, FAIL)
-
- /* Sanity check */
- HDassert(f);
- HDassert(dset);
-
- if(H5F_RDCC_NBYTES(f) > 0 && H5F_RDCC_NELMTS(f) > 0) {
- rdcc->nbytes = H5F_RDCC_NBYTES(f);
- rdcc->nslots = H5F_RDCC_NELMTS(f);
- rdcc->slot = H5FL_SEQ_CALLOC(H5D_rdcc_ent_ptr_t, rdcc->nslots);
- if(NULL == rdcc->slot)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Reset any cached chunk info for this dataset */
- H5D_chunk_cinfo_cache_reset(&(rdcc->last));
- } /* end if */
+ FUNC_ENTER_NOAPI(H5D_chunk_idx_reset, FAIL)
- /* Compose chunked index info struct */
- idx_info.f = f;
- idx_info.dxpl_id = dxpl_id;
- idx_info.layout = &dset->shared->layout;
+ /* Sanity checks */
+ HDassert(storage);
+ HDassert(storage->ops);
- /* Allocate any indexing structures */
- if((dset->shared->layout.u.chunk.ops->init)(&idx_info) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize indexing information")
+ /* Reset index structures */
+ if((storage->ops->reset)(storage, reset_addr) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset chunk index info")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_chunk_init() */
+} /* end H5D_chunk_idx_reset() */
/*-------------------------------------------------------------------------
@@ -1829,11 +2112,12 @@ H5D_chunk_cinfo_cache_update(H5D_chunk_cached_t *last, const H5D_chunk_ud_t *uda
/* Sanity check */
HDassert(last);
HDassert(udata);
- HDassert(udata->common.mesg);
+ HDassert(udata->common.layout);
+ HDassert(udata->common.storage);
HDassert(udata->common.offset);
/* Stored the information to cache */
- for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++)
+ for(u = 0; u < udata->common.layout->ndims; u++)
last->offset[u] = udata->common.offset[u];
last->nbytes = udata->nbytes;
last->filter_mask = udata->filter_mask;
@@ -1868,7 +2152,8 @@ H5D_chunk_cinfo_cache_found(const H5D_chunk_cached_t *last, H5D_chunk_ud_t *udat
/* Sanity check */
HDassert(last);
HDassert(udata);
- HDassert(udata->common.mesg);
+ HDassert(udata->common.layout);
+ HDassert(udata->common.storage);
HDassert(udata->common.offset);
/* Check if the cached information is what is desired */
@@ -1876,7 +2161,7 @@ H5D_chunk_cinfo_cache_found(const H5D_chunk_cached_t *last, H5D_chunk_ud_t *udat
unsigned u; /* Local index variable */
/* Check that the offset is the same */
- for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++)
+ for(u = 0; u < udata->common.layout->ndims; u++)
if(last->offset[u] != udata->common.offset[u])
HGOTO_DONE(FALSE)
@@ -1933,10 +2218,12 @@ H5D_chunk_create(H5D_t *dset /*in,out*/, hid_t dxpl_id)
/* Compose chunked index info struct */
idx_info.f = dset->oloc.file;
idx_info.dxpl_id = dxpl_id;
- idx_info.layout = &dset->shared->layout;
+ idx_info.pline = &dset->shared->dcpl_cache.pline;
+ idx_info.layout = &dset->shared->layout.u.chunk;
+ idx_info.storage = &dset->shared->layout.storage.u.chunk;
/* Create the index for the chunks */
- if((dset->shared->layout.u.chunk.ops->create)(&idx_info) < 0)
+ if((dset->shared->layout.storage.u.chunk.ops->create)(&idx_info) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't create chunk index")
done:
@@ -1945,9 +2232,9 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_chunk_get_addr
+ * Function: H5D_chunk_get_info
*
- * Purpose: Get the file address of a chunk if file space has been
+ * Purpose: Get the info about a chunk if file space has been
* assigned. Save the retrieved information in the udata
* supplied.
*
@@ -1958,26 +2245,25 @@ done:
*
*-------------------------------------------------------------------------
*/
-haddr_t
-H5D_chunk_get_addr(const H5D_t *dset, hid_t dxpl_id, const hsize_t *chunk_offset,
- H5D_chunk_ud_t *_udata)
+herr_t
+H5D_chunk_get_info(const H5D_t *dset, hid_t dxpl_id, const hsize_t *chunk_offset,
+ H5D_chunk_ud_t *udata)
{
- H5D_chunk_ud_t tmp_udata; /* Information about a chunk */
- H5D_chunk_ud_t *udata; /* Pointer to information about a chunk */
- haddr_t ret_value; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_chunk_get_addr)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_get_info)
HDassert(dset);
HDassert(dset->shared->layout.u.chunk.ndims > 0);
HDassert(chunk_offset);
+ HDassert(udata);
- /* Check for udata struct to return */
- udata = (_udata != NULL ? _udata : &tmp_udata);
-
- /* Initialize the information about the chunk we are looking for */
- udata->common.mesg = &(dset->shared->layout);
+ /* Initialize the query information about the chunk we are looking for */
+ udata->common.layout = &(dset->shared->layout.u.chunk);
+ udata->common.storage = &(dset->shared->layout.storage.u.chunk);
udata->common.offset = chunk_offset;
+
+ /* Reset information about the chunk we are looking for */
udata->nbytes = 0;
udata->filter_mask = 0;
udata->addr = HADDR_UNDEF;
@@ -1989,27 +2275,21 @@ H5D_chunk_get_addr(const H5D_t *dset, hid_t dxpl_id, const hsize_t *chunk_offset
/* Compose chunked index info struct */
idx_info.f = dset->oloc.file;
idx_info.dxpl_id = dxpl_id;
- idx_info.layout = &dset->shared->layout;
+ idx_info.pline = &dset->shared->dcpl_cache.pline;
+ idx_info.layout = &dset->shared->layout.u.chunk;
+ idx_info.storage = &dset->shared->layout.storage.u.chunk;
/* Go get the chunk information */
- if(!H5F_addr_defined((dset->shared->layout.u.chunk.ops->get_addr)(&idx_info, udata))) {
- /* Cache the fact that the chunk is not in the B-tree */
- H5D_chunk_cinfo_cache_update(&dset->shared->cache.chunk.last, udata);
-
- HGOTO_DONE(HADDR_UNDEF)
- } /* end if */
+ if((dset->shared->layout.storage.u.chunk.ops->get_addr)(&idx_info, udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't query chunk address")
/* Cache the information retrieved */
- HDassert(H5F_addr_defined(udata->addr));
H5D_chunk_cinfo_cache_update(&dset->shared->cache.chunk.last, udata);
} /* end if */
- /* Success! Set the return value */
- ret_value = udata->addr;
-
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5D_chunk_get_addr() */
+} /* H5D_chunk_get_info() */
/*-------------------------------------------------------------------------
@@ -2038,6 +2318,7 @@ H5D_chunk_flush_entry(const H5D_t *dset, hid_t dxpl_id, const H5D_dxpl_cache_t *
FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_flush_entry)
HDassert(dset);
+ HDassert(dset->shared);
HDassert(dxpl_cache);
HDassert(ent);
HDassert(!ent->locked);
@@ -2048,15 +2329,16 @@ H5D_chunk_flush_entry(const H5D_t *dset, hid_t dxpl_id, const H5D_dxpl_cache_t *
hbool_t must_insert = FALSE; /* Whether the chunk must go through the "insert" method */
/* Set up user data for index callbacks */
- udata.common.mesg = &dset->shared->layout;
+ udata.common.layout = &dset->shared->layout.u.chunk;
+ udata.common.storage = &dset->shared->layout.storage.u.chunk;
udata.common.offset = ent->offset;
udata.filter_mask = 0;
- udata.nbytes = ent->chunk_size;
+ udata.nbytes = dset->shared->layout.u.chunk.size;
udata.addr = ent->chunk_addr;
/* Should the chunk be filtered before writing it to disk? */
if(dset->shared->dcpl_cache.pline.nused) {
- size_t alloc = ent->alloc_size; /* Bytes allocated for BUF */
+ size_t alloc = udata.nbytes; /* Bytes allocated for BUF */
size_t nbytes; /* Chunk size (in bytes) */
if(!reset) {
@@ -2065,10 +2347,10 @@ H5D_chunk_flush_entry(const H5D_t *dset, hid_t dxpl_id, const H5D_dxpl_cache_t *
* the pipeline because we'll want to save the original buffer
* for later.
*/
- H5_ASSIGN_OVERFLOW(alloc, ent->chunk_size, uint32_t, size_t);
+ H5_ASSIGN_OVERFLOW(alloc, udata.nbytes, uint32_t, size_t);
if(NULL == (buf = H5MM_malloc(alloc)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for pipeline")
- HDmemcpy(buf, ent->chunk, ent->chunk_size);
+ HDmemcpy(buf, ent->chunk, udata.nbytes);
} /* end if */
else {
/*
@@ -2085,6 +2367,11 @@ H5D_chunk_flush_entry(const H5D_t *dset, hid_t dxpl_id, const H5D_dxpl_cache_t *
if(H5Z_pipeline(&(dset->shared->dcpl_cache.pline), 0, &(udata.filter_mask), dxpl_cache->err_detect,
dxpl_cache->filter_cb, &nbytes, &alloc, &buf) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, FAIL, "output pipeline failed")
+#if H5_SIZEOF_SIZE_T > 4
+ /* Check for the chunk expanding too much to encode in a 32-bit value */
+ if(nbytes > ((size_t)0xffffffff))
+ HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "chunk too large for 32-bit length")
+#endif /* H5_SIZEOF_SIZE_T > 4 */
H5_ASSIGN_OVERFLOW(udata.nbytes, nbytes, size_t, uint32_t);
/* Indicate that the chunk must go through 'insert' method */
@@ -2103,12 +2390,14 @@ H5D_chunk_flush_entry(const H5D_t *dset, hid_t dxpl_id, const H5D_dxpl_cache_t *
/* Compose chunked index info struct */
idx_info.f = dset->oloc.file;
idx_info.dxpl_id = dxpl_id;
- idx_info.layout = &dset->shared->layout;
+ idx_info.pline = &dset->shared->dcpl_cache.pline;
+ idx_info.layout = &dset->shared->layout.u.chunk;
+ idx_info.storage = &dset->shared->layout.storage.u.chunk;
/* Create the chunk it if it doesn't exist, or reallocate the chunk
* if its size changed.
*/
- if((dset->shared->layout.u.chunk.ops->insert)(&idx_info, &udata) < 0)
+ if((dset->shared->layout.storage.u.chunk.ops->insert)(&idx_info, &udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert/resize chunk")
/* Update the chunk entry's address, in case it was allocated or relocated */
@@ -2118,7 +2407,7 @@ H5D_chunk_flush_entry(const H5D_t *dset, hid_t dxpl_id, const H5D_dxpl_cache_t *
/* Write the data to the file */
HDassert(H5F_addr_defined(udata.addr));
if(H5F_block_write(dset->oloc.file, H5FD_MEM_DRAW, udata.addr, udata.nbytes, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
/* Cache the chunk's info, in case it's accessed again shortly */
H5D_chunk_cinfo_cache_update(&dset->shared->cache.chunk.last, &udata);
@@ -2142,6 +2431,7 @@ H5D_chunk_flush_entry(const H5D_t *dset, hid_t dxpl_id, const H5D_dxpl_cache_t *
done:
/* Free the temp buffer only if it's different than the entry chunk */
if(buf != ent->chunk)
+ /* coverity["double_free"] */
H5MM_xfree(buf);
/*
@@ -2212,11 +2502,11 @@ H5D_chunk_cache_evict(const H5D_t *dset, hid_t dxpl_id, const H5D_dxpl_cache_t *
/* Remove from cache */
rdcc->slot[ent->idx] = NULL;
ent->idx = UINT_MAX;
- rdcc->nbytes -= ent->chunk_size;
+ rdcc->nbytes_used -= dset->shared->layout.u.chunk.size;
--rdcc->nused;
/* Free */
- H5FL_FREE(H5D_rdcc_ent_t, ent);
+ (void)H5FL_FREE(H5D_rdcc_ent_t, ent);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -2242,7 +2532,7 @@ H5D_chunk_cache_prune(const H5D_t *dset, hid_t dxpl_id,
const H5D_dxpl_cache_t *dxpl_cache, size_t size)
{
const H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk);
- size_t total = rdcc->nbytes;
+ size_t total = rdcc->nbytes_max;
const int nmeth = 2; /*number of methods */
int w[1]; /*weighting as an interval */
H5D_rdcc_ent_t *p[2], *cur; /*list pointers */
@@ -2262,11 +2552,11 @@ H5D_chunk_cache_prune(const H5D_t *dset, hid_t dxpl_id,
* begins. The pointers participating in the list traversal are each
* given a chance at preemption before any of the pointers are advanced.
*/
- w[0] = (int)(rdcc->nused * H5F_RDCC_W0(dset->oloc.file));
+ w[0] = (int)(rdcc->nused * rdcc->w0);
p[0] = rdcc->head;
p[1] = NULL;
- while((p[0] || p[1]) && (rdcc->nbytes + size) > total) {
+ while((p[0] || p[1]) && (rdcc->nbytes_used + size) > total) {
int i; /* Local index variable */
/* Introduce new pointers */
@@ -2279,11 +2569,11 @@ H5D_chunk_cache_prune(const H5D_t *dset, hid_t dxpl_id,
n[i] = p[i] ? p[i]->next : NULL;
/* Give each method a chance */
- for(i = 0; i < nmeth && (rdcc->nbytes + size) > total; i++) {
+ for(i = 0; i < nmeth && (rdcc->nbytes_used + size) > total; i++) {
if(0 == i && p[0] && !p[0]->locked &&
((0 == p[0]->rd_count && 0 == p[0]->wr_count) ||
- (0 == p[0]->rd_count && p[0]->chunk_size == p[0]->wr_count) ||
- (p[0]->chunk_size == p[0]->rd_count && 0 == p[0]->wr_count))) {
+ (0 == p[0]->rd_count && dset->shared->layout.u.chunk.size == p[0]->wr_count) ||
+ (dset->shared->layout.u.chunk.size == p[0]->rd_count && 0 == p[0]->wr_count))) {
/*
* Method 0: Preempt entries that have been completely written
* and/or completely read but not entries that are partially
@@ -2338,7 +2628,7 @@ done:
* directly into the chunk cache and should not be freed
* by the caller but will be valid until it is unlocked. The
* input value IDX_HINT is used to speed up cache lookups and
- * it's output value should be given to H5F_chunk_unlock().
+ * it's output value should be given to H5D_chunk_unlock().
* IDX_HINT is ignored if it is out of range, and if it points
* to the wrong entry then we fall back to the normal search
* method.
@@ -2381,9 +2671,10 @@ H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_lock)
HDassert(io_info);
- HDassert(dset);
HDassert(io_info->dxpl_cache);
HDassert(io_info->store);
+ HDassert(udata);
+ HDassert(dset);
HDassert(TRUE == H5P_isa_class(io_info->dxpl_id, H5P_DATASET_XFER));
/* Get the chunk's size */
@@ -2420,26 +2711,19 @@ H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
if(NULL == (chunk = H5D_chunk_alloc(chunk_size, pline)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for raw data chunk")
-
+
/* In the case that some dataset functions look through this data,
* clear it to all 0s. */
HDmemset(chunk, 0, chunk_size);
} /* end if */
else {
- H5D_chunk_ud_t tmp_udata; /*B-tree pass-through */
-
- if(udata != NULL)
- chunk_addr = udata->addr;
- else {
- /* Point at temporary storage for B-tree pass through */
- udata = &tmp_udata;
+ /*
+ * Not in the cache. Count this as a miss if it's in the file
+ * or an init if it isn't.
+ */
- /*
- * Not in the cache. Read it from the file and count this as a miss
- * if it's in the file or an init if it isn't.
- */
- chunk_addr = H5D_chunk_get_addr(io_info->dset, io_info->dxpl_id, io_info->store->chunk.offset, udata);
- } /* end else */
+ /* Save the chunk address */
+ chunk_addr = udata->addr;
/* Check if the chunk exists on disk */
if(H5F_addr_defined(chunk_addr)) {
@@ -2466,11 +2750,6 @@ H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
else {
H5D_fill_value_t fill_status;
-#ifdef OLD_WAY
- /* Clear the error stack from not finding the chunk on disk */
- H5E_clear_stack(NULL);
-#endif /* OLD_WAY */
-
/* Chunk size on disk isn't [likely] the same size as the final chunk
* size in memory, so allocate memory big enough. */
if(NULL == (chunk = H5D_chunk_alloc(chunk_size, pline)))
@@ -2510,7 +2789,7 @@ H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
} /* end else */
HDassert(found || chunk_size > 0);
- if(!found && rdcc->nslots > 0 && chunk_size <= rdcc->nbytes &&
+ if(!found && rdcc->nslots > 0 && chunk_size <= rdcc->nbytes_max &&
(!ent || !ent->locked)) {
/*
* Add the chunk to the cache only if the slot is not already locked.
@@ -2528,8 +2807,6 @@ H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
ent->locked = 0;
ent->dirty = FALSE;
ent->chunk_addr = chunk_addr;
- H5_ASSIGN_OVERFLOW(ent->chunk_size, chunk_size, size_t, uint32_t);
- ent->alloc_size = chunk_size;
for(u = 0; u < layout->u.chunk.ndims; u++)
ent->offset[u] = io_info->store->chunk.offset[u];
H5_ASSIGN_OVERFLOW(ent->rd_count, chunk_size, size_t, uint32_t);
@@ -2540,7 +2817,7 @@ H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
HDassert(NULL == rdcc->slot[idx]);
rdcc->slot[idx] = ent;
ent->idx = idx;
- rdcc->nbytes += chunk_size;
+ rdcc->nbytes_used += chunk_size;
rdcc->nused++;
/* Add it to the linked list */
@@ -2554,6 +2831,8 @@ H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
rdcc->head = rdcc->tail = ent;
ent->prev = NULL;
} /* end else */
+
+ /* Indicate that the chunk is in the cache now */
found = TRUE;
} else if(!found) {
/*
@@ -2636,8 +2915,8 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D_chunk_unlock(const H5D_io_info_t *io_info, hbool_t dirty, unsigned idx_hint,
- void *chunk, uint32_t naccessed)
+H5D_chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata,
+ hbool_t dirty, unsigned idx_hint, void *chunk, uint32_t naccessed)
{
const H5O_layout_t *layout = &(io_info->dset->shared->layout); /* Dataset layout */
const H5D_rdcc_t *rdcc = &(io_info->dset->shared->cache.chunk);
@@ -2646,6 +2925,7 @@ H5D_chunk_unlock(const H5D_io_info_t *io_info, hbool_t dirty, unsigned idx_hint,
FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_unlock)
HDassert(io_info);
+ HDassert(udata);
if(UINT_MAX == idx_hint) {
/*
@@ -2655,18 +2935,16 @@ H5D_chunk_unlock(const H5D_io_info_t *io_info, hbool_t dirty, unsigned idx_hint,
* don't discard the `const' qualifier.
*/
if(dirty) {
- H5D_rdcc_ent_t x;
+ H5D_rdcc_ent_t fake_ent; /* "fake" chunk cache entry */
- HDmemset(&x, 0, sizeof(x));
- x.dirty = TRUE;
- HDmemcpy(x.offset, io_info->store->chunk.offset, layout->u.chunk.ndims * sizeof(x.offset[0]));
+ HDmemset(&fake_ent, 0, sizeof(fake_ent));
+ fake_ent.dirty = TRUE;
+ HDmemcpy(fake_ent.offset, io_info->store->chunk.offset, layout->u.chunk.ndims * sizeof(fake_ent.offset[0]));
HDassert(layout->u.chunk.size > 0);
- x.chunk_addr = HADDR_UNDEF;
- x.chunk_size = layout->u.chunk.size;
- H5_ASSIGN_OVERFLOW(x.alloc_size, x.chunk_size, uint32_t, size_t);
- x.chunk = (uint8_t *)chunk;
+ fake_ent.chunk_addr = udata->addr;
+ fake_ent.chunk = (uint8_t *)chunk;
- if(H5D_chunk_flush_entry(io_info->dset, io_info->dxpl_id, io_info->dxpl_cache, &x, TRUE) < 0)
+ if(H5D_chunk_flush_entry(io_info->dset, io_info->dxpl_id, io_info->dxpl_cache, &fake_ent, TRUE) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush indexed storage buffer")
} /* end if */
else {
@@ -2702,54 +2980,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_chunk_flush
- *
- * Purpose: Writes all dirty chunks to disk and optionally preempts them
- * from the cache.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * Thursday, May 21, 1998
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5D_chunk_flush(H5D_t *dset, hid_t dxpl_id, unsigned flags)
-{
- H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */
- H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */
- H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk);
- unsigned nerrors = 0;
- H5D_rdcc_ent_t *ent, *next;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5D_chunk_flush, FAIL)
-
- /* Fill the DXPL cache values for later use */
- if(H5D_get_dxpl_cache(dxpl_id, &dxpl_cache) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache")
-
- /* Loop over all entries in the chunk cache */
- for(ent = rdcc->head; ent; ent = next) {
- next = ent->next;
- if((flags & H5F_FLUSH_INVALIDATE)) {
- if(H5D_chunk_cache_evict(dset, dxpl_id, dxpl_cache, ent, TRUE) < 0)
- nerrors++;
- } else {
- if(H5D_chunk_flush_entry(dset, dxpl_id, dxpl_cache, ent, FALSE) < 0)
- nerrors++;
- }
- } /* end for */
- if(nerrors)
- HGOTO_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush one or more raw data chunks")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_chunk_flush() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5D_chunk_allocated_cb
*
* Purpose: Simply counts the number of chunks for a dataset.
@@ -2804,6 +3034,7 @@ H5D_chunk_allocated(H5D_t *dset, hid_t dxpl_id, hsize_t *nbytes)
FUNC_ENTER_NOAPI(H5D_chunk_allocated, FAIL)
HDassert(dset);
+ HDassert(dset->shared);
/* Fill the DXPL cache values for later use */
if(H5D_get_dxpl_cache(dxpl_id, &dxpl_cache) < 0)
@@ -2819,10 +3050,12 @@ H5D_chunk_allocated(H5D_t *dset, hid_t dxpl_id, hsize_t *nbytes)
/* Compose chunked index info struct */
idx_info.f = dset->oloc.file;
idx_info.dxpl_id = dxpl_id;
- idx_info.layout = &dset->shared->layout;
+ idx_info.pline = &dset->shared->dcpl_cache.pline;
+ idx_info.layout = &dset->shared->layout.u.chunk;
+ idx_info.storage = &dset->shared->layout.storage.u.chunk;
- /* Call the index-specific "get all the allocated chunks sizes" routine */
- if((dset->shared->layout.u.chunk.ops->iterate)(&idx_info, H5D_chunk_allocated_cb, &chunk_bytes) < 0)
+ /* Iterate over the chunks */
+ if((dset->shared->layout.storage.u.chunk.ops->iterate)(&idx_info, H5D_chunk_allocated_cb, &chunk_bytes) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve allocated chunk information from index")
/* Set number of bytes for caller */
@@ -2851,7 +3084,7 @@ herr_t
H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
{
H5D_chk_idx_info_t idx_info; /* Chunked index info */
- const H5D_chunk_ops_t *ops = dset->shared->layout.u.chunk.ops; /* Chunk operations */
+ const H5D_chunk_ops_t *ops = dset->shared->layout.storage.u.chunk.ops; /* Chunk operations */
hsize_t chunk_offset[H5O_LAYOUT_NDIMS]; /* Offset of current chunk */
size_t orig_chunk_size; /* Original size of chunk in bytes */
unsigned filter_mask = 0; /* Filter mask for chunks that have them */
@@ -2882,7 +3115,6 @@ H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
/* Check args */
HDassert(dset && H5D_CHUNKED == layout->type);
HDassert(layout->u.chunk.ndims > 0 && layout->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
- HDassert(H5F_addr_defined(layout->u.chunk.addr));
HDassert(TRUE == H5P_isa_class(dxpl_id, H5P_DATASET_XFER));
/* Retrieve the dataset dimensions */
@@ -2959,13 +3191,20 @@ H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
/* Push the chunk through the filters */
if(H5Z_pipeline(pline, 0, &filter_mask, dxpl_cache->err_detect, dxpl_cache->filter_cb, &orig_chunk_size, &buf_size, &fb_info.fill_buf) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_WRITEERROR, FAIL, "output pipeline failed")
+#if H5_SIZEOF_SIZE_T > 4
+ /* Check for the chunk expanding too much to encode in a 32-bit value */
+ if(orig_chunk_size > ((size_t)0xffffffff))
+ HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "chunk too large for 32-bit length")
+#endif /* H5_SIZEOF_SIZE_T > 4 */
} /* end if */
} /* end if */
/* Compose chunked index info struct */
idx_info.f = dset->oloc.file;
idx_info.dxpl_id = dxpl_id;
- idx_info.layout = &dset->shared->layout;
+ idx_info.pline = &dset->shared->dcpl_cache.pline;
+ idx_info.layout = &dset->shared->layout.u.chunk;
+ idx_info.storage = &dset->shared->layout.storage.u.chunk;
/* Reset the chunk offset indices */
HDmemset(chunk_offset, 0, (layout->u.chunk.ndims * sizeof(chunk_offset[0])));
@@ -2973,14 +3212,15 @@ H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
/* Loop over all chunks */
carry = FALSE;
while(!carry) {
- haddr_t chunk_addr; /* Address of chunk */
+ H5D_chunk_ud_t udata; /* User data for querying chunk info */
int i; /* Local index variable */
- /* Get the chunk's address */
- chunk_addr = H5D_chunk_get_addr(dset, dxpl_id, chunk_offset, NULL);
+ /* Get the chunk's info */
+ if(H5D_chunk_get_info(dset, dxpl_id, chunk_offset, &udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
/* Check if the chunk exists yet on disk */
- if(!H5F_addr_defined(chunk_addr)) {
+ if(!H5F_addr_defined(udata.addr)) {
const H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /* Raw data chunk cache */
H5D_rdcc_ent_t *ent; /* Cache entry */
hbool_t chunk_exists; /* Flag to indicate whether a chunk exists already */
@@ -3002,7 +3242,6 @@ H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
/* Chunk wasn't in cache either, create it now */
if(!chunk_exists) {
- H5D_chunk_ud_t udata; /* B-tree pass-through for creating chunk */
size_t chunk_size; /* Size of chunk in bytes, possibly filtered */
/* Check for VL datatype & non-default fill value */
@@ -3023,6 +3262,12 @@ H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
if(H5Z_pipeline(pline, 0, &filter_mask, dxpl_cache->err_detect, dxpl_cache->filter_cb, &nbytes, &buf_size, &fb_info.fill_buf) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_WRITEERROR, FAIL, "output pipeline failed")
+#if H5_SIZEOF_SIZE_T > 4
+ /* Check for the chunk expanding too much to encode in a 32-bit value */
+ if(nbytes > ((size_t)0xffffffff))
+ HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "chunk too large for 32-bit length")
+#endif /* H5_SIZEOF_SIZE_T > 4 */
+
/* Keep the number of bytes the chunk turned in to */
chunk_size = nbytes;
} /* end if */
@@ -3033,7 +3278,8 @@ H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
chunk_size = orig_chunk_size;
/* Initialize the chunk information */
- udata.common.mesg = layout;
+ udata.common.layout = &layout->u.chunk;
+ udata.common.storage = &layout->storage.u.chunk;
udata.common.offset = chunk_offset;
H5_ASSIGN_OVERFLOW(udata.nbytes, chunk_size, size_t, uint32_t);
udata.filter_mask = filter_mask;
@@ -3116,10 +3362,10 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_chunk_prune_cb
+ * Function: H5D_chunk_prune_fill
*
- * Purpose: Search for chunks that are no longer inside the pruned
- * dataset's extent
+ * Purpose: Write the fill value to the parts of the chunk that are no
+ * longer part of the dataspace
*
* Return: Non-negative on success/Negative on failure
*
@@ -3128,200 +3374,186 @@ done:
*
*-------------------------------------------------------------------------
*/
-/* ARGSUSED */
-static int
-H5D_chunk_prune_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
+static herr_t
+H5D_chunk_prune_fill(const H5D_chunk_rec_t *chunk_rec, H5D_chunk_it_ud1_t *udata)
{
- H5D_chunk_it_ud1_t *udata = (H5D_chunk_it_ud1_t *)_udata; /* User data */
- H5D_chunk_sl_ck_t *sl_node = NULL; /* Skip list node for chunk to remove */
- unsigned rank; /* Current # of dimensions */
- hbool_t should_delete = FALSE; /* Whether the chunk should be deleted */
- hbool_t needs_fill = FALSE; /* Whether the chunk overlaps the new extent and needs fill valiues */
- unsigned u; /* Local index variable */
- int ret_value = H5_ITER_CONT; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_prune_cb)
-
- /* Figure out what chunks are no longer in use for the specified extent and release them */
- rank = udata->common.mesg->u.chunk.ndims - 1;
- for(u = 0; u < rank; u++)
- /* The chunk record points to a chunk of storage that contains the
- * beginning of the logical address space represented by UDATA.
- */
- if(chunk_rec->offset[u] >= udata->dims[u]) {
- /* Indicate that the chunk will be deleted */
- should_delete = TRUE;
-
- /* Break out of loop, we know the chunk is outside the current dimensions */
- break;
- } /* end if */
- /* Check for chunk that overlaps new extent and will need fill values */
- else if((chunk_rec->offset[u] + udata->common.mesg->u.chunk.dim[u]) > udata->dims[u])
- /* Indicate that the chunk needs filling */
- /* (but continue in loop, since it could be outside the extent in
- * another dimension -QAK)
- */
- needs_fill = TRUE;
-
- /* Check for chunk to delete */
- if(should_delete) {
- /* Allocate space for the shared structure */
- if(NULL == (sl_node = H5FL_MALLOC(H5D_chunk_sl_ck_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed for shared B-tree info")
-
- /* Calculate the index of this chunk */
- if(H5V_chunk_index(rank, chunk_rec->offset, udata->common.mesg->u.chunk.dim, udata->down_chunks, &sl_node->index) < 0)
- HGOTO_ERROR(H5E_IO, H5E_BADRANGE, H5_ITER_ERROR, "can't get chunk index")
+ const H5D_io_info_t *io_info = udata->io_info; /* Local pointer to I/O info */
+ H5D_t *dset = io_info->dset; /* Local pointer to the dataset info */
+ const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset's layout */
+ unsigned rank = udata->common.layout->ndims - 1; /* Dataset rank */
+ H5S_sel_iter_t chunk_iter; /* Memory selection iteration info */
+ hssize_t sel_nelmts; /* Number of elements in selection */
+ hsize_t count[H5O_LAYOUT_NDIMS]; /* Element count of hyperslab */
+ void *chunk; /* The file chunk */
+ unsigned idx_hint; /* Which chunk we're dealing with */
+ H5D_chunk_ud_t chk_udata; /* User data for locking chunk */
+ uint32_t bytes_accessed; /* Bytes accessed in chunk */
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Store the key for the chunk */
- sl_node->rec = *chunk_rec;
+ FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_prune_fill)
- /* Insert the chunk description in the skip list */
- if(H5SL_insert(udata->outside, sl_node, &sl_node->index) < 0)
- HGOTO_ERROR(H5E_IO, H5E_CANTINSERT, H5_ITER_ERROR, "can't insert chunk into skip list")
+ /* Initialize the fill value buffer, if necessary */
+ if(!udata->fb_info_init) {
+ H5_CHECK_OVERFLOW(udata->elmts_per_chunk, uint32_t, size_t);
+ if(H5D_fill_init(&udata->fb_info, NULL, FALSE, NULL, NULL, NULL, NULL,
+ &dset->shared->dcpl_cache.fill,
+ dset->shared->type, dset->shared->type_id, (size_t)udata->elmts_per_chunk,
+ io_info->dxpl_cache->max_temp_buf, io_info->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize fill buffer info")
+ udata->fb_info_init = TRUE;
} /* end if */
- /* Check for chunk that overlaps the new dataset dimensions and needs filling */
- else if(needs_fill) {
- const H5D_io_info_t *io_info = udata->io_info; /* Local pointer to I/O info */
- H5D_t *dset = io_info->dset; /* Local pointer to the dataset info */
- const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset's layout */
- H5S_sel_iter_t chunk_iter; /* Memory selection iteration info */
- hssize_t sel_nelmts; /* Number of elements in selection */
- hsize_t count[H5O_LAYOUT_NDIMS]; /* Element count of hyperslab */
- void *chunk; /* The file chunk */
- unsigned idx_hint; /* Which chunk we're dealing with */
- H5D_chunk_ud_t chk_udata; /* User data for locking chunk */
- uint32_t bytes_accessed; /* Bytes accessed in chunk */
-
- /* Initialize the fill value buffer, if necessary */
- if(!udata->fb_info_init) {
- H5_CHECK_OVERFLOW(udata->elmts_per_chunk, uint32_t, size_t);
- if(H5D_fill_init(&udata->fb_info, NULL, FALSE, NULL, NULL, NULL, NULL,
- &dset->shared->dcpl_cache.fill,
- dset->shared->type, dset->shared->type_id, (size_t)udata->elmts_per_chunk,
- io_info->dxpl_cache->max_temp_buf, io_info->dxpl_id) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, H5_ITER_ERROR, "can't initialize fill buffer info")
- udata->fb_info_init = TRUE;
- } /* end if */
- /* Compute the # of elements to leave with existing value, in each dimension */
- for(u = 0; u < rank; u++) {
- count[u] = MIN(layout->u.chunk.dim[u], (udata->dims[u] - chunk_rec->offset[u]));
- HDassert(count[u] > 0);
- } /* end for */
+ /* Compute the # of elements to leave with existing value, in each dimension */
+ for(u = 0; u < rank; u++) {
+ count[u] = MIN(layout->u.chunk.dim[u], (udata->dims[u] - chunk_rec->offset[u]));
+ HDassert(count[u] > 0);
+ } /* end for */
- /* Select all elements in chunk, to begin with */
- if(H5S_select_all(udata->chunk_space, TRUE) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, H5_ITER_ERROR, "unable to select space")
+ /* Select all elements in chunk, to begin with */
+ if(H5S_select_all(udata->chunk_space, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "unable to select space")
- /* "Subtract out" the elements to keep */
- if(H5S_select_hyperslab(udata->chunk_space, H5S_SELECT_NOTB, udata->hyper_start, NULL, count, NULL) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, H5_ITER_ERROR, "unable to select hyperslab")
+ /* "Subtract out" the elements to keep */
+ if(H5S_select_hyperslab(udata->chunk_space, H5S_SELECT_NOTB, udata->hyper_start, NULL, count, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "unable to select hyperslab")
- /* Calculate the index of this chunk */
- if(H5V_chunk_index(rank, chunk_rec->offset, layout->u.chunk.dim, udata->down_chunks, &io_info->store->chunk.index) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, H5_ITER_ERROR, "can't get chunk index")
+ /* Calculate the index of this chunk */
+ if(H5V_chunk_index(rank, chunk_rec->offset, layout->u.chunk.dim, layout->u.chunk.down_chunks, &io_info->store->chunk.index) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, H5_ITER_ERROR, "can't get chunk index")
- /* Lock the chunk into the cache, to get a pointer to the chunk buffer */
- /* (Casting away const OK -QAK) */
- io_info->store->chunk.offset = (hsize_t *)chunk_rec->offset;
- chk_udata.common.mesg = layout;
- chk_udata.common.offset = chunk_rec->offset;
- chk_udata.nbytes = chunk_rec->nbytes;
- chk_udata.filter_mask = chunk_rec->filter_mask;
- chk_udata.addr = chunk_rec->chunk_addr;
- if(NULL == (chunk = (void *)H5D_chunk_lock(udata->io_info, &chk_udata, FALSE, &idx_hint)))
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, H5_ITER_ERROR, "unable to lock raw data chunk")
-
-
- /* Fill the selection in the memory buffer */
- /* Use the size of the elements in the chunk directly instead of */
- /* relying on the fill.size, which might be set to 0 if there is */
- /* no fill-value defined for the dataset -QAK */
-
- /* Get the number of elements in the selection */
- sel_nelmts = H5S_GET_SELECT_NPOINTS(udata->chunk_space);
- HDassert(sel_nelmts >= 0);
- H5_CHECK_OVERFLOW(sel_nelmts, hssize_t, size_t);
-
- /* Check for VL datatype & non-default fill value */
- if(udata->fb_info.has_vlen_fill_type)
- /* Re-fill the buffer to use for this I/O operation */
- if(H5D_fill_refill_vl(&udata->fb_info, (size_t)sel_nelmts, io_info->dxpl_id) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, H5_ITER_ERROR, "can't refill fill value buffer")
-
- /* Create a selection iterator for scattering the elements to memory buffer */
- if(H5S_select_iter_init(&chunk_iter, udata->chunk_space, layout->u.chunk.dim[rank]) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, H5_ITER_ERROR, "unable to initialize chunk selection information")
-
- /* Scatter the data into memory */
- if(H5D_scatter_mem(udata->fb_info.fill_buf, udata->chunk_space, &chunk_iter, (size_t)sel_nelmts, io_info->dxpl_cache, chunk/*out*/) < 0) {
- H5S_SELECT_ITER_RELEASE(&chunk_iter);
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, H5_ITER_ERROR, "scatter failed")
- } /* end if */
+ /* Lock the chunk into the cache, to get a pointer to the chunk buffer */
+ /* (Casting away const OK -QAK) */
+ io_info->store->chunk.offset = (hsize_t *)chunk_rec->offset;
+ chk_udata.common.layout = &layout->u.chunk;
+ chk_udata.common.storage = &layout->storage.u.chunk;
+ chk_udata.common.offset = chunk_rec->offset;
+ chk_udata.nbytes = chunk_rec->nbytes;
+ chk_udata.filter_mask = chunk_rec->filter_mask;
+ chk_udata.addr = chunk_rec->chunk_addr;
+ if(NULL == (chunk = (void *)H5D_chunk_lock(udata->io_info, &chk_udata, FALSE, &idx_hint)))
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to lock raw data chunk")
+
+
+ /* Fill the selection in the memory buffer */
+ /* Use the size of the elements in the chunk directly instead of */
+ /* relying on the fill.size, which might be set to 0 if there is */
+ /* no fill-value defined for the dataset -QAK */
+
+ /* Get the number of elements in the selection */
+ sel_nelmts = H5S_GET_SELECT_NPOINTS(udata->chunk_space);
+ HDassert(sel_nelmts >= 0);
+ H5_CHECK_OVERFLOW(sel_nelmts, hssize_t, size_t);
+
+ /* Check for VL datatype & non-default fill value */
+ if(udata->fb_info.has_vlen_fill_type)
+ /* Re-fill the buffer to use for this I/O operation */
+ if(H5D_fill_refill_vl(&udata->fb_info, (size_t)sel_nelmts, io_info->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "can't refill fill value buffer")
+
+ /* Create a selection iterator for scattering the elements to memory buffer */
+ if(H5S_select_iter_init(&chunk_iter, udata->chunk_space, layout->u.chunk.dim[rank]) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize chunk selection information")
+
+ /* Scatter the data into memory */
+ if(H5D_scatter_mem(udata->fb_info.fill_buf, udata->chunk_space, &chunk_iter, (size_t)sel_nelmts, io_info->dxpl_cache, chunk/*out*/) < 0) {
+ H5S_SELECT_ITER_RELEASE(&chunk_iter);
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "scatter failed")
+ } /* end if */
- /* Release the selection iterator */
- if(H5S_SELECT_ITER_RELEASE(&chunk_iter) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, H5_ITER_ERROR, "Can't release selection iterator")
+ /* Release the selection iterator */
+ if(H5S_SELECT_ITER_RELEASE(&chunk_iter) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release selection iterator")
- /* The number of bytes accessed in the chunk */
- /* (i.e. the bytes replaced with fill values) */
- bytes_accessed = sel_nelmts * layout->u.chunk.dim[rank];
+ /* The number of bytes accessed in the chunk */
+ /* (i.e. the bytes replaced with fill values) */
+ H5_CHECK_OVERFLOW(sel_nelmts, hssize_t, uint32_t);
+ bytes_accessed = (uint32_t)sel_nelmts * layout->u.chunk.dim[rank];
- /* Release lock on chunk */
- if(H5D_chunk_unlock(io_info, TRUE, idx_hint, chunk, bytes_accessed) < 0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, H5_ITER_ERROR, "unable to unlock raw data chunk")
- } /* end else-if */
+ /* Release lock on chunk */
+ if(H5D_chunk_unlock(io_info, &chk_udata, TRUE, idx_hint, chunk, bytes_accessed) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to unlock raw data chunk")
done:
- if(ret_value != H5_ITER_CONT && sl_node)
- H5FL_FREE(H5D_chunk_sl_ck_t, sl_node);
-
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_chunk_prune_cb() */
+} /* H5D_chunk_prune_fill */
/*-------------------------------------------------------------------------
- * Function: H5D_chunk_prune_sl_rm_cb
+ * Function: H5D_chunk_prune_cb
*
- * Purpose: Destroy a skip list node for "pruning" chunks, also removes
- * the chunk from the index.
+ * Purpose: Search for chunks that are no longer inside the pruned
+ * dataset's extent
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol, koziol@hdfgroup.org
- * May 3, 2007
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ * March 26, 2002
*
*-------------------------------------------------------------------------
*/
-static herr_t
-H5D_chunk_prune_sl_rm_cb(void *item, void UNUSED *key, void *op_data)
+/* ARGSUSED */
+static int
+H5D_chunk_prune_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
{
- H5D_chunk_sl_ck_t *sl_node = (H5D_chunk_sl_ck_t *)item; /* Temporary pointer to chunk to remove */
- H5D_chunk_sl_rm_t *rm_info = (H5D_chunk_sl_rm_t *)op_data; /* Information needed for removing chunk from B-tree */
- H5D_chunk_common_ud_t idx_udata; /* User data for index removal routine */
- herr_t ret_value = H5_ITER_CONT; /* Return value */
+ H5D_chunk_it_ud1_t *udata = (H5D_chunk_it_ud1_t *)_udata; /* User data */
+ H5D_chunk_prune_stack_t *stack_node = NULL; /* Stack node for chunk to remove */
+ unsigned rank; /* Current # of dimensions */
+ hbool_t should_delete = FALSE; /* Whether the chunk should be deleted */
+ hbool_t needs_fill = FALSE; /* Whether the chunk overlaps the new extent and needs fill valiues */
+ unsigned u; /* Local index variable */
+ int ret_value = H5_ITER_CONT; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_prune_sl_rm_cb)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_prune_cb)
- /* Sanity checks */
- HDassert(sl_node);
- HDassert(rm_info);
+ /* Figure out what chunks are no longer in use for the specified extent and release them */
+ rank = udata->common.layout->ndims - 1;
+ for(u = 0; u < rank; u++)
+ /* The chunk record points to a chunk of storage that contains the
+ * beginning of the logical address space represented by UDATA.
+ */
+ if(udata->shrunk_dims[u]) {
+ if(chunk_rec->offset[u] >= udata->dims[u]) {
+ /* Indicate that the chunk will be deleted */
+ should_delete = TRUE;
+
+ /* Break out of loop, we know the chunk is outside the current dimensions */
+ break;
+ } /* end if */
+ /* Check for chunk that overlaps new extent and will need fill values */
+ else if((chunk_rec->offset[u] + udata->common.layout->dim[u]) > udata->dims[u])
+ /* Indicate that the chunk needs filling */
+ /* (but continue in loop, since it could be outside the extent in
+ * another dimension -QAK)
+ */
+ needs_fill = TRUE;
+ } /* end if */
- /* Initialize the user data for the index callback */
- idx_udata.mesg = rm_info->mesg;
- idx_udata.offset = sl_node->rec.offset;
+ /* Check for chunk to delete */
+ if(should_delete) {
+ /* Allocate space for the removal stack node */
+ if(NULL == (stack_node = H5FL_MALLOC(H5D_chunk_prune_stack_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed for removal stack node")
- /* Remove */
- if((rm_info->idx_info->layout->u.chunk.ops->remove)(rm_info->idx_info, &idx_udata) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, H5_ITER_ERROR, "unable to remove chunk entry from index")
+ /* Store the record for the chunk */
+ stack_node->rec = *chunk_rec;
-done:
- H5FL_FREE(H5D_chunk_sl_ck_t, sl_node);
+ /* Push the chunk description onto the stack */
+ stack_node->next = udata->rm_stack;
+ udata->rm_stack = stack_node;
+ } /* end if */
+ /* Check for chunk that overlaps the new dataset dimensions and needs filling */
+ else if(needs_fill)
+ /* Write the fill value */
+ if(H5D_chunk_prune_fill(chunk_rec, udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, H5_ITER_ERROR, "unable to write fill value")
+done:
+ /* It is currently impossible to fail after the stack node has been
+ * malloc'ed. No need to free it here on failure. */
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5D_chunk_prune_sl_rm_cb() */
+} /* end H5D_chunk_prune_cb() */
/*-------------------------------------------------------------------------
@@ -3435,13 +3667,15 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dims)
const H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /*raw data chunk cache */
H5D_rdcc_ent_t *ent = NULL, *next = NULL; /* Cache entries */
hsize_t curr_dims[H5O_LAYOUT_NDIMS]; /* Current dataspace dimensions */
+ hbool_t shrunk_dims[H5O_LAYOUT_NDIMS]; /* Dimensions which have shrunk */
H5D_chunk_it_ud1_t udata; /* Chunk index iterator user data */
hbool_t udata_init = FALSE; /* Whether the chunk index iterator user data has been initialized */
- H5D_chunk_sl_rm_t rm_info; /* User data for skip list destroy callback */
+ hbool_t needs_fill; /* Whether we need to write the fill value */
+ H5D_chunk_prune_stack_t *fill_stack = NULL; /* Stack of chunks to fill */
+ H5D_chunk_prune_stack_t *tmp_stack; /* Temporary stack node pointer */
+ H5D_chunk_common_ud_t idx_udata; /* User data for index removal routine */
H5S_t *chunk_space = NULL; /* Dataspace for a chunk */
hsize_t chunk_dims[H5O_LAYOUT_NDIMS]; /* Chunk dimensions */
- hsize_t chunks[H5O_LAYOUT_NDIMS]; /* Current number of chunks in each dimension */
- hsize_t down_chunks[H5O_LAYOUT_NDIMS]; /* "down" size of number of elements in each dimension */
hsize_t hyper_start[H5O_LAYOUT_NDIMS]; /* Starting location of hyperslab */
uint32_t elmts_per_chunk; /* Elements in chunk */
unsigned rank; /* Current # of dimensions */
@@ -3453,9 +3687,12 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dims)
/* Check args */
HDassert(dset && H5D_CHUNKED == layout->type);
HDassert(layout->u.chunk.ndims > 0 && layout->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
- HDassert(H5F_addr_defined(layout->u.chunk.addr));
HDassert(dxpl_cache);
+ /* set the removal stack pointer in udata to NULL, so if the function fails
+ * early it will not try to free the nonexistent stack */
+ udata.rm_stack = NULL;
+
/* Fill the DXPL cache values for later use */
if(H5D_get_dxpl_cache(dxpl_id, &dxpl_cache) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache")
@@ -3466,42 +3703,19 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dims)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset dimensions")
curr_dims[rank] = layout->u.chunk.dim[rank];
- /*-------------------------------------------------------------------------
- * Figure out what chunks are no longer in use for the specified extent
- * and release them from the linked list raw data cache
- *-------------------------------------------------------------------------
- */
- for(ent = rdcc->head; ent; ent = next) {
- /* Get pointer to next extry in cache, in case this one is evicted */
- next = ent->next;
-
- /* Check for chunk offset outside of new dimensions */
- for(u = 0; u < rank; u++)
- if((hsize_t)ent->offset[u] > curr_dims[u]) {
- /* Evict the entry from the cache, but do not flush it to disk */
- if(H5D_chunk_cache_evict(dset, dxpl_id, dxpl_cache, ent, FALSE) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTREMOVE, FAIL, "unable to evict chunk")
-
- /* Break out of loop, chunk is evicted */
- break;
- } /* end if */
- } /* end for */
-
/* Round up to the next integer # of chunks, to accomodate partial chunks */
+ /* Use current dims because the indices have already been updated! -NAF */
/* (also compute the number of elements per chunk) */
/* (also copy the chunk dimensions into 'hsize_t' array for creating dataspace) */
+ /* (also compute the dimensions which have been shrunk) */
elmts_per_chunk = 1;
for(u = 0; u < rank; u++) {
- chunks[u] = ((old_dims[u] + layout->u.chunk.dim[u]) - 1) / layout->u.chunk.dim[u];
elmts_per_chunk *= layout->u.chunk.dim[u];
chunk_dims[u] = layout->u.chunk.dim[u];
+ shrunk_dims[u] = curr_dims[u] < old_dims[u];
} /* end for */
- /* Get the "down" sizes for each dimension */
- if(H5V_array_down(rank, chunks, down_chunks) < 0)
- HGOTO_ERROR(H5E_IO, H5E_BADVALUE, FAIL, "can't compute 'down' sizes")
-
- /* Create a data space for a chunk & set the extent */
+ /* Create a dataspace for a chunk & set the extent */
if(NULL == (chunk_space = H5S_create_simple(rank, chunk_dims, NULL)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace")
@@ -3516,34 +3730,101 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dims)
/* Compose chunked index info struct */
idx_info.f = dset->oloc.file;
idx_info.dxpl_id = dxpl_id;
- idx_info.layout = &dset->shared->layout;
+ idx_info.pline = &dset->shared->dcpl_cache.pline;
+ idx_info.layout = &dset->shared->layout.u.chunk;
+ idx_info.storage = &dset->shared->layout.storage.u.chunk;
/* Initialize the user data for the iteration */
HDmemset(&udata, 0, sizeof udata);
- udata.common.mesg = layout;
+ udata.common.layout = &layout->u.chunk;
+ udata.common.storage = &layout->storage.u.chunk;
udata.io_info = &chk_io_info;
udata.idx_info = &idx_info;
udata.dims = curr_dims;
- udata.down_chunks = down_chunks;
+ udata.shrunk_dims = shrunk_dims;
udata.elmts_per_chunk = elmts_per_chunk;
udata.chunk_space = chunk_space;
udata.hyper_start = hyper_start;
udata_init = TRUE;
- /* Initialize the skip list that will hold the chunks outside the dimensions */
- if(NULL == (udata.outside = H5SL_create(H5SL_TYPE_HSIZE, 0.5, (size_t)H5D_CHUNK_DEFAULT_SKIPLIST_HEIGHT)))
- HGOTO_ERROR(H5E_IO, H5E_CANTCREATE, FAIL, "can't create skip list for chunks outside new dimensions")
+ /*-------------------------------------------------------------------------
+ * Figure out what chunks are no longer in use for the specified extent
+ * and release them from the linked list raw data cache
+ *-------------------------------------------------------------------------
+ */
+ for(ent = rdcc->head; ent; ent = next) {
+ /* Get pointer to next extry in cache, in case this one is evicted */
+ next = ent->next;
+
+ needs_fill = FALSE;
+
+ /* Check for chunk offset outside of new dimensions */
+ for(u = 0; u < rank; u++) {
+ if((hsize_t)ent->offset[u] >= curr_dims[u]) {
+ /* Evict the entry from the cache, but do not flush it to disk */
+ if(H5D_chunk_cache_evict(dset, dxpl_id, dxpl_cache, ent, FALSE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTREMOVE, FAIL, "unable to evict chunk")
+
+ /* We don't need to write the fill value */
+ needs_fill = FALSE;
+
+ /* Break out of loop, chunk is evicted */
+ break;
+ } else if(!H5F_addr_defined(ent->chunk_addr) && shrunk_dims[u]
+ && (ent->offset[u] + chunk_dims[u]) > curr_dims[u])
+ /* We need to write the fill value to the unused parts of chunk */
+ needs_fill = TRUE;
+ } /* end for */
+
+ if(needs_fill) {
+ /* Allocate space for the stack node */
+ if(NULL == (tmp_stack = H5FL_MALLOC(H5D_chunk_prune_stack_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed for stack node")
+
+ /* Set up chunk record for fill routine */
+ tmp_stack->rec.nbytes = dset->shared->layout.u.chunk.size;
+ HDmemcpy(tmp_stack->rec.offset, ent->offset, sizeof(tmp_stack->rec.offset));
+ tmp_stack->rec.filter_mask = 0; /* Since the chunk is already in cache this doesn't matter */
+ tmp_stack->rec.chunk_addr = ent->chunk_addr;
+
+ /* Push the chunk description onto the stack */
+ tmp_stack->next = fill_stack;
+ fill_stack = tmp_stack;
+ } /* end if */
+ } /* end for */
+
+ /* Traverse the stack of chunks to be filled, filling each. We will free
+ * the nodes later in the "done" section. */
+ tmp_stack = fill_stack;
+ while(tmp_stack) {
+ /* Write the fill value */
+ if(H5D_chunk_prune_fill(&(tmp_stack->rec), &udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, H5_ITER_ERROR, "unable to write fill value")
+
+ /* Advance the stack pointer */
+ tmp_stack = tmp_stack->next;
+ } /* end while */
/* Iterate over the chunks */
- if((dset->shared->layout.u.chunk.ops->iterate)(&idx_info, H5D_chunk_prune_cb, &udata) < 0)
+ if((dset->shared->layout.storage.u.chunk.ops->iterate)(&idx_info, H5D_chunk_prune_cb, &udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve prune chunks from index")
- /* Set up user data for skip list callback */
- rm_info.idx_info = &idx_info;
- rm_info.mesg = layout;
-
- /* Destroy the skip list, deleting the chunks in the callback */
- H5SL_destroy(udata.outside, H5D_chunk_prune_sl_rm_cb, &rm_info);
+ /* Traverse the stack of chunks to be deleted, removing each. We will free
+ * the nodes later in the "done" section. */
+ idx_udata.layout = &layout->u.chunk;
+ idx_udata.storage = &layout->storage.u.chunk;
+ tmp_stack = udata.rm_stack;
+ while(tmp_stack) {
+ /* Update the offset in idx_udata */
+ idx_udata.offset = tmp_stack->rec.offset;
+
+ /* Remove the chunk from disk */
+ if((layout->storage.u.chunk.ops->remove)(&idx_info, &idx_udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, H5_ITER_ERROR, "unable to remove chunk entry from index")
+
+ /* Advance the stack pointer */
+ tmp_stack = tmp_stack->next;
+ } /* end while */
/* Reset any cached chunk info for this dataset */
H5D_chunk_cinfo_cache_reset(&dset->shared->cache.chunk.last);
@@ -3557,6 +3838,24 @@ done:
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release fill buffer info")
} /* end if */
+ /* Free stack of filled chunks */
+ tmp_stack = fill_stack;
+ while(tmp_stack) {
+ /* Free the stack node and advance the stack pointer */
+ tmp_stack = tmp_stack->next;
+ (void)H5FL_FREE(H5D_chunk_prune_stack_t, fill_stack);
+ fill_stack = tmp_stack;
+ } /* end while */
+
+ /* Free stack of removed chunks */
+ tmp_stack = udata.rm_stack;
+ while(tmp_stack) {
+ /* Free the stack node and advance the stack pointer */
+ tmp_stack = tmp_stack->next;
+ (void)H5FL_FREE(H5D_chunk_prune_stack_t, udata.rm_stack);
+ udata.rm_stack = tmp_stack;
+ } /* end while */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_chunk_prune_by_extent() */
@@ -3579,14 +3878,14 @@ static int
H5D_chunk_addrmap_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
{
H5D_chunk_it_ud2_t *udata = (H5D_chunk_it_ud2_t *)_udata; /* User data for callback */
- unsigned rank = udata->common.mesg->u.chunk.ndims - 1; /* # of dimensions of dataset */
+ unsigned rank = udata->common.layout->ndims - 1; /* # of dimensions of dataset */
hsize_t chunk_index;
int ret_value = H5_ITER_CONT; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_addrmap_cb)
/* Compute the index for this chunk */
- if(H5V_chunk_index(rank, chunk_rec->offset, udata->common.mesg->u.chunk.dim, udata->down_chunks, &chunk_index) < 0)
+ if(H5V_chunk_index(rank, chunk_rec->offset, udata->common.layout->dim, udata->common.layout->down_chunks, &chunk_index) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, H5_ITER_ERROR, "can't get chunk index")
/* Set it in the userdata to return */
@@ -3611,33 +3910,34 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D_chunk_addrmap(const H5D_io_info_t *io_info, haddr_t chunk_addr[],
- const hsize_t down_chunks[])
+H5D_chunk_addrmap(const H5D_io_info_t *io_info, haddr_t chunk_addr[])
{
H5D_chk_idx_info_t idx_info; /* Chunked index info */
H5D_t *dset = io_info->dset; /* Local pointer to dataset info */
- H5D_chunk_it_ud2_t udata; /* User data for iteration callback */
+ H5D_chunk_it_ud2_t udata; /* User data for iteration callback */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_chunk_addrmap, FAIL)
HDassert(dset);
+ HDassert(dset->shared);
HDassert(chunk_addr);
- HDassert(down_chunks);
/* Set up user data for B-tree callback */
HDmemset(&udata, 0, sizeof(udata));
- udata.common.mesg = &dset->shared->layout;
- udata.down_chunks = down_chunks;
+ udata.common.layout = &dset->shared->layout.u.chunk;
+ udata.common.storage = &dset->shared->layout.storage.u.chunk;
udata.chunk_addr = chunk_addr;
/* Compose chunked index info struct */
idx_info.f = dset->oloc.file;
idx_info.dxpl_id = io_info->dxpl_id;
- idx_info.layout = &dset->shared->layout;
+ idx_info.pline = &dset->shared->dcpl_cache.pline;
+ idx_info.layout = &dset->shared->layout.u.chunk;
+ idx_info.storage = &dset->shared->layout.storage.u.chunk;
/* Iterate over chunks to build mapping of chunk addresses */
- if((dset->shared->layout.u.chunk.ops->iterate)(&idx_info, H5D_chunk_addrmap_cb, &udata) < 0)
+ if((dset->shared->layout.storage.u.chunk.ops->iterate)(&idx_info, H5D_chunk_addrmap_cb, &udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to iterate over chunk index to build address map")
done:
@@ -3660,26 +3960,65 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D_chunk_delete(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout)
+H5D_chunk_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_storage_t *storage)
{
H5D_chk_idx_info_t idx_info; /* Chunked index info */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5O_layout_t layout; /* Dataset layout message */
+ hbool_t layout_read = FALSE; /* Whether the layout message was read from the file */
+ H5O_pline_t pline; /* I/O pipeline message */
+ hbool_t pline_read = FALSE; /* Whether the I/O pipeline message was read from the file */
+ htri_t exists; /* Flag if header message of interest exists */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_chunk_delete, FAIL)
+ /* Sanity check */
+ HDassert(f);
+ HDassert(oh);
+ HDassert(storage);
+
+ /* Check for I/O pipeline message */
+ if((exists = H5O_msg_exists_oh(oh, H5O_PLINE_ID)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to check for object header message")
+ else if(exists) {
+ if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_PLINE_ID, &pline))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get I/O pipeline message")
+ pline_read = TRUE;
+ } /* end else if */
+ else
+ HDmemset(&pline, 0, sizeof(pline));
+
+ /* Retrieve dataset layout message */
+ if((exists = H5O_msg_exists_oh(oh, H5O_LAYOUT_ID)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to check for object header message")
+ else if(exists) {
+ if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_LAYOUT_ID, &layout))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get layout message")
+ layout_read = TRUE;
+ } /* end else if */
+ else
+ HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "can't find layout message")
+
/* Compose chunked index info struct */
idx_info.f = f;
idx_info.dxpl_id = dxpl_id;
- idx_info.layout = layout;
+ idx_info.pline = &pline;
+ idx_info.layout = &layout.u.chunk;
+ idx_info.storage = &storage->u.chunk;
- /* Check if the index has been created in the file */
- if(H5F_addr_defined(layout->u.chunk.addr)) {
- /* Delete the chunked storage information in the file */
- if((layout->u.chunk.ops->delete)(&idx_info) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to delete chunk index")
- } /* end if */
+ /* Delete the chunked storage information in the file */
+ if((storage->u.chunk.ops->idx_delete)(&idx_info) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to delete chunk index")
done:
+ /* Clean up any messages read in */
+ if(pline_read)
+ if(H5O_msg_reset(H5O_PLINE_ID, &pline) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTRESET, FAIL, "unable to reset I/O pipeline message")
+ if(layout_read)
+ if(H5O_msg_reset(H5O_LAYOUT_ID, &layout) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTRESET, FAIL, "unable to reset layout message")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_chunk_delete() */
@@ -3707,10 +4046,6 @@ H5D_chunk_update_cache(H5D_t *dset, hid_t dxpl_id)
H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */
H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */
unsigned rank; /*current # of dimensions */
- hsize_t curr_dims[H5O_LAYOUT_NDIMS]; /*current dataspace dimensions */
- hsize_t chunks[H5O_LAYOUT_NDIMS]; /*current number of chunks in each dimension */
- hsize_t down_chunks[H5O_LAYOUT_NDIMS]; /* "down" size of number of elements in each dimension */
- unsigned u; /*counters */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_chunk_update_cache, FAIL)
@@ -3727,18 +4062,6 @@ H5D_chunk_update_cache(H5D_t *dset, hid_t dxpl_id)
if(rank == 1)
HGOTO_DONE(SUCCEED)
- /* Go get the dimensions */
- if(H5S_get_simple_extent_dims(dset->shared->space, curr_dims, NULL) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset dimensions")
-
- /* Round up to the next integer # of chunks, to accomodate partial chunks */
- for(u = 0; u < rank; u++)
- chunks[u] = ((curr_dims[u] + dset->shared->layout.u.chunk.dim[u]) - 1) / dset->shared->layout.u.chunk.dim[u];
-
- /* Get the "down" sizes for each dimension */
- if(H5V_array_down(rank, chunks, down_chunks) < 0)
- HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "can't compute 'down' sizes")
-
/* Fill the DXPL cache values for later use */
if(H5D_get_dxpl_cache(dxpl_id, &dxpl_cache) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache")
@@ -3752,7 +4075,7 @@ H5D_chunk_update_cache(H5D_t *dset, hid_t dxpl_id)
next = ent->next;
/* Calculate the index of this chunk */
- if(H5V_chunk_index(rank, ent->offset, dset->shared->layout.u.chunk.dim, down_chunks, &idx) < 0)
+ if(H5V_chunk_index(rank, ent->offset, dset->shared->layout.u.chunk.dim, dset->shared->layout.u.chunk.down_chunks, &idx) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
/* Compute the index for the chunk entry */
@@ -3812,7 +4135,7 @@ H5D_chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
void *bkg = udata->bkg; /* Background buffer for datatype conversion */
void *buf = udata->buf; /* Chunk buffer for I/O & datatype conversions */
size_t buf_size = udata->buf_size; /* Size of chunk buffer */
- H5O_pline_t *pline = udata->pline; /* I/O pipeline for applying filters */
+ const H5O_pline_t *pline = udata->pline; /* I/O pipeline for applying filters */
/* needed for commpressed variable length data */
hbool_t has_filters = FALSE; /* Whether chunk has filters */
@@ -3828,7 +4151,7 @@ H5D_chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
/* Check parameter for type conversion */
if(udata->do_convert) {
- if(H5T_detect_class(udata->dt_src, H5T_VLEN) > 0)
+ if(H5T_detect_class(udata->dt_src, H5T_VLEN, FALSE) > 0)
is_vlen = TRUE;
else if((H5T_get_class(udata->dt_src, FALSE) == H5T_REFERENCE) && (udata->file_src != udata->idx_info_dst->f))
fix_ref = TRUE;
@@ -3889,7 +4212,7 @@ H5D_chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
/* Convert from source file to memory */
H5_CHECK_OVERFLOW(udata->nelmts, uint32_t, size_t);
- if(H5T_convert(tpath_src_mem, tid_src, tid_mem, (size_t)udata->nelmts, (size_t)0, (size_t)0, buf, NULL, udata->idx_info_dst->dxpl_id) < 0)
+ if(H5T_convert(tpath_src_mem, tid_src, tid_mem, (size_t)udata->nelmts, (size_t)0, (size_t)0, buf, bkg, udata->idx_info_dst->dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5_ITER_ERROR, "datatype conversion failed")
/* Copy into another buffer, to reclaim memory later */
@@ -3925,7 +4248,8 @@ H5D_chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
} /* end if */
/* Set up destination chunk callback information for insertion */
- udata_dst.common.mesg = udata->idx_info_dst->layout;
+ udata_dst.common.layout = udata->idx_info_dst->layout;
+ udata_dst.common.storage = udata->idx_info_dst->storage;
udata_dst.common.offset = chunk_rec->offset;
udata_dst.nbytes = chunk_rec->nbytes;
udata_dst.filter_mask = chunk_rec->filter_mask;
@@ -3935,13 +4259,18 @@ H5D_chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
if(has_filters && (is_vlen || fix_ref) ) {
if(H5Z_pipeline(pline, 0, &(udata_dst.filter_mask), H5Z_NO_EDC, cb_struct, &nbytes, &buf_size, &buf) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, H5_ITER_ERROR, "output pipeline failed")
+#if H5_SIZEOF_SIZE_T > 4
+ /* Check for the chunk expanding too much to encode in a 32-bit value */
+ if(nbytes > ((size_t)0xffffffff))
+ HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "chunk too large for 32-bit length")
+#endif /* H5_SIZEOF_SIZE_T > 4 */
H5_ASSIGN_OVERFLOW(udata_dst.nbytes, nbytes, size_t, uint32_t);
udata->buf = buf;
udata->buf_size = buf_size;
} /* end if */
/* Insert chunk into the destination index */
- if((udata->idx_info_dst->layout->u.chunk.ops->insert)(udata->idx_info_dst, &udata_dst) < 0)
+ if((udata->idx_info_dst->storage->ops->insert)(udata->idx_info_dst, &udata_dst) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert chunk into index")
/* Write chunk data to destination file */
@@ -3968,13 +4297,16 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D_chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
- H5O_layout_t *layout_dst, H5T_t *dt_src, H5O_copy_t *cpy_info,
- H5O_pline_t *pline, hid_t dxpl_id)
+H5D_chunk_copy(H5F_t *f_src, H5O_storage_chunk_t *storage_src,
+ H5O_layout_chunk_t *layout_src, H5F_t *f_dst, H5O_storage_chunk_t *storage_dst,
+ const H5S_extent_t *ds_extent_src, const H5T_t *dt_src,
+ const H5O_pline_t *pline_src, H5O_copy_t *cpy_info, hid_t dxpl_id)
{
H5D_chunk_it_ud3_t udata; /* User data for iteration callback */
H5D_chk_idx_info_t idx_info_dst; /* Dest. chunked index info */
H5D_chk_idx_info_t idx_info_src; /* Source chunked index info */
+ H5O_pline_t _pline; /* Temporary pipeline info */
+ const H5O_pline_t *pline; /* Pointer to pipeline info to use */
H5T_path_t *tpath_src_mem = NULL, *tpath_mem_dst = NULL; /* Datatype conversion paths */
hid_t tid_src = -1; /* Datatype ID for source datatype */
hid_t tid_dst = -1; /* Datatype ID for destination datatype */
@@ -3995,32 +4327,65 @@ H5D_chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
/* Check args */
HDassert(f_src);
+ HDassert(storage_src);
+ HDassert(layout_src);
HDassert(f_dst);
- HDassert(layout_src && H5D_CHUNKED == layout_src->type);
- HDassert(layout_dst && H5D_CHUNKED == layout_dst->type);
+ HDassert(storage_dst);
+ HDassert(ds_extent_src);
HDassert(dt_src);
+ /* Initialize the temporary pipeline info */
+ if(NULL == pline_src) {
+ HDmemset(&_pline, 0, sizeof(_pline));
+ pline = &_pline;
+ } /* end if */
+ else
+ pline = pline_src;
+
+ /* Layout is not created in the destination file, reset index address */
+ if(H5D_chunk_idx_reset(storage_dst, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to reset chunked storage index in dest")
+
+ /* Initialize layout information */
+ {
+ hsize_t curr_dims[H5O_LAYOUT_NDIMS]; /* Curr. size of dataset dimensions */
+ int sndims; /* Rank of dataspace */
+ unsigned ndims; /* Rank of dataspace */
+
+ /* Get the dim info for dataset */
+ if((sndims = H5S_extent_get_dims(ds_extent_src, curr_dims, NULL)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataspace dimensions")
+ H5_ASSIGN_OVERFLOW(ndims, sndims, int, unsigned);
+
+ /* Set the source layout chunk information */
+ if(H5D_chunk_set_info_real(layout_src, ndims, curr_dims) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set layout's chunk info")
+ } /* end block */
+
/* Compose source & dest chunked index info structs */
idx_info_src.f = f_src;
idx_info_src.dxpl_id = dxpl_id;
+ idx_info_src.pline = pline;
idx_info_src.layout = layout_src;
+ idx_info_src.storage = storage_src;
idx_info_dst.f = f_dst;
idx_info_dst.dxpl_id = dxpl_id;
- idx_info_dst.layout = layout_dst;
+ idx_info_dst.pline = pline; /* Use same I/O filter pipeline for dest. */
+ idx_info_dst.layout = layout_src /* Use same layout for dest. */;
+ idx_info_dst.storage = storage_dst;
/* Call the index-specific "copy setup" routine */
- if((layout_src->u.chunk.ops->copy_setup)(&idx_info_src, &idx_info_dst) < 0)
+ if((storage_src->ops->copy_setup)(&idx_info_src, &idx_info_dst) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up index-specific chunk copying information")
- HDassert(H5F_addr_defined(layout_dst->u.chunk.addr));
copy_setup_done = TRUE;
/* Create datatype ID for src datatype */
- if((tid_src = H5I_register(H5I_DATATYPE, dt_src)) < 0)
+ if((tid_src = H5I_register(H5I_DATATYPE, dt_src, FALSE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register source file datatype")
/* If there's a VLEN source datatype, set up type conversion information */
- if(H5T_detect_class(dt_src, H5T_VLEN) > 0) {
+ if(H5T_detect_class(dt_src, H5T_VLEN, FALSE) > 0) {
H5T_t *dt_dst; /* Destination datatype */
H5T_t *dt_mem; /* Memory datatype */
size_t mem_dt_size; /* Memory datatype size */
@@ -4032,16 +4397,22 @@ H5D_chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
/* create a memory copy of the variable-length datatype */
if(NULL == (dt_mem = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy")
- if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem)) < 0)
+ if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem, FALSE)) < 0) {
+ (void)H5T_close(dt_mem);
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype")
+ } /* end if */
/* create variable-length datatype at the destinaton file */
if(NULL == (dt_dst = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy")
- if(H5T_set_loc(dt_dst, f_dst, H5T_LOC_DISK) < 0)
+ if(H5T_set_loc(dt_dst, f_dst, H5T_LOC_DISK) < 0) {
+ (void)H5T_close(dt_dst);
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk")
- if((tid_dst = H5I_register(H5I_DATATYPE, dt_dst)) < 0)
+ } /* end if */
+ if((tid_dst = H5I_register(H5I_DATATYPE, dt_dst, FALSE)) < 0) {
+ (void)H5T_close(dt_dst);
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register destination file datatype")
+ } /* end if */
/* Set up the conversion functions */
if(NULL == (tpath_src_mem = H5T_path_find(dt_src, dt_mem, NULL, NULL, dxpl_id, FALSE)))
@@ -4061,8 +4432,8 @@ H5D_chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
/* Compute the number of elements per chunk */
nelmts = 1;
- for(u = 0; u < (layout_src->u.chunk.ndims - 1); u++)
- nelmts *= layout_src->u.chunk.dim[u];
+ for(u = 0; u < (layout_src->ndims - 1); u++)
+ nelmts *= layout_src->dim[u];
/* Create the space and set the initial extent */
buf_dim = nelmts;
@@ -4070,8 +4441,8 @@ H5D_chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace")
/* Atomize */
- if((sid_buf = H5I_register(H5I_DATASPACE, buf_space)) < 0) {
- H5S_close(buf_space);
+ if((sid_buf = H5I_register(H5I_DATASPACE, buf_space, FALSE)) < 0) {
+ (void)H5S_close(buf_space);
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID")
} /* end if */
@@ -4092,7 +4463,7 @@ H5D_chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
do_convert = TRUE;
} /* end if */
- H5_ASSIGN_OVERFLOW(buf_size, layout_src->u.chunk.size, uint32_t, size_t);
+ H5_ASSIGN_OVERFLOW(buf_size, layout_src->size, uint32_t, size_t);
reclaim_buf_size = 0;
} /* end else */
@@ -4103,7 +4474,7 @@ H5D_chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for raw data chunk")
/* Check for reference datatype and no expanding references & clear background buffer */
- if(!cpy_info->expand_ref &&
+ if(!cpy_info->expand_ref &&
((H5T_get_class(dt_src, FALSE) == H5T_REFERENCE) && (f_src != f_dst)))
/* Reset value to zero */
HDmemset(bkg, 0, buf_size);
@@ -4115,7 +4486,8 @@ H5D_chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
/* Initialize the callback structure for the source */
HDmemset(&udata, 0, sizeof udata);
- udata.common.mesg = layout_src;
+ udata.common.layout = layout_src;
+ udata.common.storage = storage_src;
udata.file_src = f_src;
udata.idx_info_dst = &idx_info_dst;
udata.buf = buf;
@@ -4136,7 +4508,7 @@ H5D_chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
udata.cpy_info = cpy_info;
/* Iterate over chunks to copy data */
- if((layout_src->u.chunk.ops->iterate)(&idx_info_src, H5D_chunk_copy_cb, &udata) < 0)
+ if((storage_src->ops->iterate)(&idx_info_src, H5D_chunk_copy_cb, &udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to iterate over chunk index to copy data")
/* I/O buffers may have been re-allocated */
@@ -4144,17 +4516,16 @@ H5D_chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
bkg = udata.bkg;
done:
- if(sid_buf > 0)
- if(H5I_dec_ref(sid_buf) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary dataspace ID")
+ if(sid_buf > 0 && H5I_dec_ref(sid_buf, FALSE) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't decrement temporary dataspace ID")
if(tid_src > 0)
- if(H5I_dec_ref(tid_src) < 0)
+ if(H5I_dec_ref(tid_src, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
if(tid_dst > 0)
- if(H5I_dec_ref(tid_dst) < 0)
+ if(H5I_dec_ref(tid_dst, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
if(tid_mem > 0)
- if(H5I_dec_ref(tid_mem) < 0)
+ if(H5I_dec_ref(tid_mem, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
if(buf)
H5MM_xfree(buf);
@@ -4165,7 +4536,7 @@ done:
/* Clean up any index information */
if(copy_setup_done)
- if((layout_src->u.chunk.ops->copy_shutdown)(layout_src, layout_dst) < 0)
+ if((storage_src->ops->copy_shutdown)(storage_src, storage_dst, dxpl_id) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to shut down index copying info")
FUNC_LEAVE_NOAPI(ret_value)
@@ -4187,7 +4558,7 @@ done:
*/
herr_t
H5D_chunk_bh_info(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
- hsize_t *index_size)
+ const H5O_pline_t *pline, hsize_t *index_size)
{
H5D_chk_idx_info_t idx_info; /* Chunked index info */
herr_t ret_value = SUCCEED; /* Return value */
@@ -4197,15 +4568,18 @@ H5D_chunk_bh_info(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
/* Check args */
HDassert(f);
HDassert(layout);
+ HDassert(pline);
HDassert(index_size);
/* Compose chunked index info struct */
idx_info.f = f;
idx_info.dxpl_id = dxpl_id;
- idx_info.layout = layout;
+ idx_info.pline = pline;
+ idx_info.layout = &layout->u.chunk;
+ idx_info.storage = &layout->storage.u.chunk;
/* Get size of index structure */
- if((layout->u.chunk.ops->size)(&idx_info, index_size) < 0)
+ if((layout->storage.u.chunk.ops->size)(&idx_info, index_size) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve chunk index info")
done:
@@ -4214,7 +4588,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_istore_iter_dump
+ * Function: H5D_chunk_iter_dump
*
* Purpose: If the UDATA.STREAM member is non-null then debugging
* information is written to that stream.
@@ -4276,7 +4650,6 @@ H5D_chunk_dump_index_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
herr_t
H5D_chunk_dump_index(H5D_t *dset, hid_t dxpl_id, FILE *stream)
{
- H5D_chunk_it_ud4_t udata; /* User data for callback */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_chunk_dump_index, FAIL)
@@ -4286,23 +4659,27 @@ H5D_chunk_dump_index(H5D_t *dset, hid_t dxpl_id, FILE *stream)
/* Only display info if stream is defined */
if(stream) {
- H5D_chk_idx_info_t idx_info; /* Chunked index info */
+ H5D_chk_idx_info_t idx_info; /* Chunked index info */
+ H5D_chunk_it_ud4_t udata; /* User data for callback */
- /* Display address of index */
- HDfprintf(stream, " Address: %a\n", dset->shared->layout.u.chunk.addr);
+ /* Display info for index */
+ if((dset->shared->layout.storage.u.chunk.ops->dump)(&dset->shared->layout.storage.u.chunk, stream) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to dump chunk index info")
+
+ /* Compose chunked index info struct */
+ idx_info.f = dset->oloc.file;
+ idx_info.dxpl_id = dxpl_id;
+ idx_info.pline = &dset->shared->dcpl_cache.pline;
+ idx_info.layout = &dset->shared->layout.u.chunk;
+ idx_info.storage = &dset->shared->layout.storage.u.chunk;
/* Set up user data for callback */
udata.stream = stream;
udata.header_displayed = FALSE;
udata.ndims = dset->shared->layout.u.chunk.ndims;
- /* Compose chunked index info struct */
- idx_info.f = dset->oloc.file;
- idx_info.dxpl_id = dxpl_id;
- idx_info.layout = &dset->shared->layout;
-
/* Iterate over index and dump chunk info */
- if((dset->shared->layout.u.chunk.ops->iterate)(&idx_info, H5D_chunk_dump_index_cb, &udata) < 0)
+ if((dset->shared->layout.storage.u.chunk.ops->iterate)(&idx_info, H5D_chunk_dump_index_cb, &udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to iterate over chunk index to dump chunk info")
} /* end if */
@@ -4355,16 +4732,18 @@ H5D_chunk_dest(H5F_t *f, hid_t dxpl_id, H5D_t *dset)
/* Release cache structures */
if(rdcc->slot)
- H5FL_SEQ_FREE(H5D_rdcc_ent_ptr_t, rdcc->slot);
+ rdcc->slot = H5FL_SEQ_FREE(H5D_rdcc_ent_ptr_t, rdcc->slot);
HDmemset(rdcc, 0, sizeof(H5D_rdcc_t));
/* Compose chunked index info struct */
idx_info.f = f;
idx_info.dxpl_id = dxpl_id;
- idx_info.layout = &dset->shared->layout;
+ idx_info.pline = &dset->shared->dcpl_cache.pline;
+ idx_info.layout = &dset->shared->layout.u.chunk;
+ idx_info.storage = &dset->shared->layout.storage.u.chunk;
/* Free any index structures */
- if((dset->shared->layout.u.chunk.ops->dest)(&idx_info) < 0)
+ if((dset->shared->layout.storage.u.chunk.ops->dest)(&idx_info) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to release chunk index info")
done:
@@ -4437,28 +4816,38 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_null_readvv
+ * Function: H5D_nonexistent_readvv
+ *
+ * Purpose: When the chunk doesn't exist on disk and the chunk is bigger
+ * than the cache size, performs fill value I/O operation on
+ * memory buffer, advancing through two I/O vectors, until one
+ * runs out.
*
- * Purpose: Performs "no-op" I/O operation, advancing through two I/O
- * vectors, until one runs out.
+ * Note: This algorithm is pretty inefficient about initializing and
+ * terminating the fill buffer info structure and it would be
+ * faster to refactor this into a "real" initialization routine,
+ * and a "vectorized fill" routine. -QAK
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * Tuesday, April 1, 2008
+ * Programmer: Raymond Lu
+ * 6 Feb 2009
*
*-------------------------------------------------------------------------
*/
static ssize_t
-H5D_null_readvv(const H5D_io_info_t UNUSED *io_info,
+H5D_nonexistent_readvv(const H5D_io_info_t *io_info,
size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[], hsize_t chunk_offset_arr[],
size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[])
{
- size_t u, v; /* Local index variables */
- size_t size; /* Size of sequence in bytes */
- ssize_t bytes_processed = 0; /* Eventual return value */
+ H5D_t *dset = io_info->dset; /* Local pointer to the dataset info */
+ H5D_fill_buf_info_t fb_info; /* Dataset's fill buffer info */
+ hbool_t fb_info_init = FALSE; /* Whether the fill value buffer has been initialized */
+ ssize_t bytes_processed = 0; /* Eventual return value */
+ size_t u, v; /* Local index variables */
+ ssize_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_null_readvv)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_nonexistent_readvv)
/* Check args */
HDassert(chunk_len_arr);
@@ -4468,12 +4857,35 @@ H5D_null_readvv(const H5D_io_info_t UNUSED *io_info,
/* Work through all the sequences */
for(u = *mem_curr_seq, v = *chunk_curr_seq; u < mem_max_nseq && v < chunk_max_nseq; ) {
+ unsigned char *buf; /* Temporary pointer into read buffer */
+ size_t size; /* Size of sequence in bytes */
+
/* Choose smallest buffer to write */
if(chunk_len_arr[v] < mem_len_arr[u])
size = chunk_len_arr[v];
else
size = mem_len_arr[u];
+ /* Compute offset in memory */
+ buf = (unsigned char *)io_info->u.rbuf + mem_offset_arr[u];
+
+ /* Initialize the fill value buffer */
+ if(H5D_fill_init(&fb_info, buf, FALSE,
+ NULL, NULL, NULL, NULL,
+ &dset->shared->dcpl_cache.fill, dset->shared->type,
+ dset->shared->type_id, (size_t)0, size, io_info->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize fill buffer info")
+ fb_info_init = TRUE;
+
+ /* Check for VL datatype & fill the buffer with VL datatype fill values */
+ if(fb_info.has_vlen_fill_type && H5D_fill_refill_vl(&fb_info, fb_info.elmts_per_buf, io_info->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "can't refill fill value buffer")
+
+ /* Release the fill buffer info */
+ if(H5D_fill_term(&fb_info) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release fill buffer info")
+ fb_info_init = FALSE;
+
/* Update source information */
chunk_len_arr[v] -= size;
chunk_offset_arr[v] += size;
@@ -4494,6 +4906,14 @@ H5D_null_readvv(const H5D_io_info_t UNUSED *io_info,
*mem_curr_seq = u;
*chunk_curr_seq = v;
- FUNC_LEAVE_NOAPI(bytes_processed)
-} /* H5D_null_readvv() */
+ /* Set return value */
+ ret_value = bytes_processed;
+
+done:
+ /* Release the fill buffer info, if it's been initialized */
+ if(fb_info_init && H5D_fill_term(&fb_info) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release fill buffer info")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5D_nonexistent_readvv() */
diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c
index 0458e74..d8bf8b0 100644
--- a/src/H5Dcompact.c
+++ b/src/H5Dcompact.c
@@ -18,7 +18,7 @@
* August 5, 2002
*
* Purpose: Compact dataset I/O functions. These routines are similar
- * H5D_contig_* and H5D_istore_*.
+ * H5D_contig_* and H5D_chunk_*.
*/
/****************/
@@ -38,6 +38,7 @@
#include "H5FDprivate.h" /* File drivers */
#include "H5FLprivate.h" /* Free Lists */
#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
#include "H5Oprivate.h" /* Object headers */
#include "H5Vprivate.h" /* Vector and array functions */
@@ -57,8 +58,8 @@
/********************/
/* Layout operation callbacks */
-static herr_t H5D_compact_new(H5F_t *f, hid_t dxpl_id, H5D_t *dset,
- const H5P_genplist_t *dc_plist);
+static herr_t H5D_compact_construct(H5F_t *f, H5D_t *dset);
+static hbool_t H5D_compact_is_space_alloc(const H5O_storage_t *storage);
static herr_t H5D_compact_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
H5D_chunk_map_t *cm);
@@ -68,6 +69,7 @@ static ssize_t H5D_compact_readvv(const H5D_io_info_t *io_info,
static ssize_t H5D_compact_writevv(const H5D_io_info_t *io_info,
size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_size_arr[], hsize_t dset_offset_arr[],
size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[]);
+static herr_t H5D_compact_flush(H5D_t *dset, hid_t dxpl_id);
/*********************/
@@ -76,7 +78,9 @@ static ssize_t H5D_compact_writevv(const H5D_io_info_t *io_info,
/* Compact storage layout I/O ops */
const H5D_layout_ops_t H5D_LOPS_COMPACT[1] = {{
- H5D_compact_new,
+ H5D_compact_construct,
+ NULL,
+ H5D_compact_is_space_alloc,
H5D_compact_io_init,
H5D_contig_read,
H5D_contig_write,
@@ -86,6 +90,7 @@ const H5D_layout_ops_t H5D_LOPS_COMPACT[1] = {{
#endif /* H5_HAVE_PARALLEL */
H5D_compact_readvv,
H5D_compact_writevv,
+ H5D_compact_flush,
NULL
}};
@@ -123,16 +128,16 @@ H5D_compact_fill(H5D_t *dset, hid_t dxpl_id)
/* Check args */
HDassert(TRUE == H5P_isa_class(dxpl_id, H5P_DATASET_XFER));
HDassert(dset && H5D_COMPACT == dset->shared->layout.type);
- HDassert(dset->shared->layout.u.compact.buf);
+ HDassert(dset->shared->layout.storage.u.compact.buf);
HDassert(dset->shared->type);
HDassert(dset->shared->space);
/* Initialize the fill value buffer */
/* (use the compact dataset storage buffer as the fill value buffer) */
- if(H5D_fill_init(&fb_info, dset->shared->layout.u.compact.buf, FALSE,
+ if(H5D_fill_init(&fb_info, dset->shared->layout.storage.u.compact.buf, FALSE,
NULL, NULL, NULL, NULL,
&dset->shared->dcpl_cache.fill, dset->shared->type,
- dset->shared->type_id, (size_t)0, dset->shared->layout.u.compact.size, dxpl_id) < 0)
+ dset->shared->type_id, (size_t)0, dset->shared->layout.storage.u.compact.size, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize fill buffer info")
fb_info_init = TRUE;
@@ -152,7 +157,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_compact_new
+ * Function: H5D_compact_construct
*
* Purpose: Constructs new compact layout information for dataset
*
@@ -165,37 +170,60 @@ done:
*/
/* ARGSUSED */
static herr_t
-H5D_compact_new(H5F_t *f, hid_t UNUSED dxpl_id, H5D_t *dset,
- const H5P_genplist_t UNUSED *dc_plist)
+H5D_compact_construct(H5F_t *f, H5D_t *dset)
{
hssize_t tmp_size; /* Temporary holder for raw data size */
- hsize_t comp_data_size; /* Size of compact data */
+ hsize_t max_comp_data_size; /* Max. allowed size of compact data */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_compact_new)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_compact_construct)
/* Sanity checks */
HDassert(f);
HDassert(dset);
- HDassert(dc_plist);
/*
* Compact dataset is stored in dataset object header message of
* layout.
*/
tmp_size = H5S_GET_EXTENT_NPOINTS(dset->shared->space) * H5T_get_size(dset->shared->type);
- H5_ASSIGN_OVERFLOW(dset->shared->layout.u.compact.size, tmp_size, hssize_t, size_t);
+ H5_ASSIGN_OVERFLOW(dset->shared->layout.storage.u.compact.size, tmp_size, hssize_t, size_t);
/* Verify data size is smaller than maximum header message size
* (64KB) minus other layout message fields.
*/
- comp_data_size = H5O_MESG_MAX_SIZE - H5O_layout_meta_size(f, &(dset->shared->layout));
- if(dset->shared->layout.u.compact.size > comp_data_size)
+ max_comp_data_size = H5O_MESG_MAX_SIZE - H5D_layout_meta_size(f, &(dset->shared->layout), FALSE);
+ if(dset->shared->layout.storage.u.compact.size > max_comp_data_size)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "compact dataset size is bigger than header message maximum size")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_compact_new() */
+} /* end H5D_compact_construct() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_compact_is_space_alloc
+ *
+ * Purpose: Query if space is allocated for layout
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, January 15, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+H5D_compact_is_space_alloc(const H5O_storage_t UNUSED *storage)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_compact_is_space_alloc)
+
+ /* Sanity checks */
+ HDassert(storage);
+
+ /* Compact storage is currently always allocated */
+ FUNC_LEAVE_NOAPI(TRUE)
+} /* end H5D_compact_is_space_alloc() */
/*-------------------------------------------------------------------------
@@ -217,8 +245,8 @@ H5D_compact_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t UNUSED *
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_compact_io_init)
- io_info->store->compact.buf = io_info->dset->shared->layout.u.compact.buf;
- io_info->store->compact.dirty = &io_info->dset->shared->layout.u.compact.dirty;
+ io_info->store->compact.buf = io_info->dset->shared->layout.storage.u.compact.buf;
+ io_info->store->compact.dirty = &io_info->dset->shared->layout.storage.u.compact.dirty;
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5D_compact_io_init() */
@@ -307,6 +335,40 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D_compact_flush
+ *
+ * Purpose: Writes dirty compact data to object header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, July 27, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_compact_flush(H5D_t *dset, hid_t dxpl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_compact_flush)
+
+ /* Sanity check */
+ HDassert(dset);
+
+ /* Check if the buffered compact information is dirty */
+ if(dset->shared->layout.storage.u.compact.dirty) {
+ if(H5O_msg_write(&(dset->oloc), H5O_LAYOUT_ID, 0, H5O_UPDATE_TIME, &(dset->shared->layout), dxpl_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update layout message")
+ dset->shared->layout.storage.u.compact.dirty = FALSE;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_compact_flush() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_compact_copy
*
* Purpose: Copy compact storage raw data from SRC file to DST file.
@@ -319,8 +381,9 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D_compact_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
- H5O_layout_t *layout_dst, H5T_t *dt_src, H5O_copy_t *cpy_info, hid_t dxpl_id)
+H5D_compact_copy(H5F_t *f_src, H5O_storage_compact_t *storage_src, H5F_t *f_dst,
+ H5O_storage_compact_t *storage_dst, H5T_t *dt_src, H5O_copy_t *cpy_info,
+ hid_t dxpl_id)
{
hid_t tid_src = -1; /* Datatype ID for source datatype */
hid_t tid_dst = -1; /* Datatype ID for destination datatype */
@@ -334,18 +397,22 @@ H5D_compact_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
FUNC_ENTER_NOAPI(H5D_compact_copy, FAIL)
/* Check args */
- HDassert(layout_src && H5D_COMPACT == layout_src->type);
HDassert(f_src);
+ HDassert(storage_src);
HDassert(f_dst);
- HDassert(layout_dst && H5D_COMPACT == layout_dst->type);
+ HDassert(storage_dst);
HDassert(dt_src);
+ /* Allocate space for destination data */
+ if(NULL == (storage_dst->buf = H5MM_malloc(storage_src->size)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate memory for compact dataset")
+
/* Create datatype ID for src datatype, so it gets freed */
- if((tid_src = H5I_register(H5I_DATATYPE, dt_src)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register source file datatype")
+ if((tid_src = H5I_register(H5I_DATATYPE, dt_src, FALSE)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register source file datatype")
/* If there's a VLEN source datatype, do type conversion information */
- if(H5T_detect_class(dt_src, H5T_VLEN) > 0) {
+ if(H5T_detect_class(dt_src, H5T_VLEN, FALSE) > 0) {
H5T_path_t *tpath_src_mem, *tpath_mem_dst; /* Datatype conversion paths */
H5T_t *dt_dst; /* Destination datatype */
H5T_t *dt_mem; /* Memory datatype */
@@ -360,22 +427,28 @@ H5D_compact_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
/* create a memory copy of the variable-length datatype */
if(NULL == (dt_mem = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy")
- if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem)) < 0)
+ if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem, FALSE)) < 0) {
+ H5T_close(dt_mem);
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype")
+ } /* end if */
/* create variable-length datatype at the destinaton file */
if(NULL == (dt_dst = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy")
- if(H5T_set_loc(dt_dst, f_dst, H5T_LOC_DISK) < 0)
+ if(H5T_set_loc(dt_dst, f_dst, H5T_LOC_DISK) < 0) {
+ H5T_close(dt_dst);
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk")
- if((tid_dst = H5I_register(H5I_DATATYPE, dt_dst)) < 0)
+ } /* end if */
+ if((tid_dst = H5I_register(H5I_DATATYPE, dt_dst, FALSE)) < 0) {
+ H5T_close(dt_dst);
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register destination file datatype")
+ } /* end if */
/* Set up the conversion functions */
if(NULL == (tpath_src_mem = H5T_path_find(dt_src, dt_mem, NULL, NULL, dxpl_id, FALSE)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes")
if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, dt_dst, NULL, NULL, dxpl_id, FALSE)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between mem and dst datatypes")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to convert between mem and dst datatypes")
/* Determine largest datatype size */
if(0 == (src_dt_size = H5T_get_size(dt_src)))
@@ -388,7 +461,7 @@ H5D_compact_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
max_dt_size = MAX(max_dt_size, tmp_dt_size);
/* Set number of whole elements that fit in buffer */
- if(0 == (nelmts = layout_src->u.compact.size / src_dt_size))
+ if(0 == (nelmts = storage_src->size / src_dt_size))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "element size too large")
/* Set up number of bytes to copy, and initial buffer size */
@@ -402,7 +475,7 @@ H5D_compact_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace")
/* Atomize */
- if((buf_sid = H5I_register(H5I_DATASPACE, buf_space)) < 0) {
+ if((buf_sid = H5I_register(H5I_DATASPACE, buf_space, FALSE)) < 0) {
H5S_close(buf_space);
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID")
} /* end if */
@@ -415,23 +488,27 @@ H5D_compact_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
if(NULL == (buf = H5FL_BLK_MALLOC(type_conv, buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- HDmemcpy(buf, layout_src->u.compact.buf, layout_src->u.compact.size);
+ HDmemcpy(buf, storage_src->buf, storage_src->size);
+
+ /* allocate temporary bkg buff for data conversion */
+ if(NULL == (bkg = H5FL_BLK_MALLOC(type_conv, buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Convert from source file to memory */
- if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0)
+ if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, bkg, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed")
+ /* Copy into another buffer, to reclaim memory later */
HDmemcpy(reclaim_buf, buf, buf_size);
- /* allocate temporary bkg buff for data conversion */
- if(NULL == (bkg = H5FL_BLK_CALLOC(type_conv, buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ /* Set background buffer to all zeros */
+ HDmemset(bkg, 0, buf_size);
/* Convert from memory to destination file */
if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, nelmts, (size_t)0, (size_t)0, buf, bkg, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed")
- HDmemcpy(layout_dst->u.compact.buf, buf, layout_dst->u.compact.size);
+ HDmemcpy(storage_dst->buf, buf, storage_dst->size);
if(H5D_vlen_reclaim(tid_mem, buf_space, H5P_DATASET_XFER_DEFAULT, reclaim_buf) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to reclaim variable-length data")
@@ -443,37 +520,39 @@ H5D_compact_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
size_t ref_count;
/* Determine # of reference elements to copy */
- ref_count = layout_src->u.compact.size / H5T_get_size(dt_src);
+ ref_count = storage_src->size / H5T_get_size(dt_src);
/* Copy objects referenced in source buffer to destination file and set destination elements */
- if(H5O_copy_expand_ref(f_src, layout_src->u.compact.buf, dxpl_id, f_dst,
- layout_dst->u.compact.buf, ref_count, H5T_get_ref_type(dt_src), cpy_info) < 0)
+ if(H5O_copy_expand_ref(f_src, storage_src->buf, dxpl_id, f_dst,
+ storage_dst->buf, ref_count, H5T_get_ref_type(dt_src), cpy_info) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy reference attribute")
} /* end if */
else
/* Reset value to zero */
- HDmemset(layout_dst->u.compact.buf, 0, layout_src->u.compact.size);
+ HDmemset(storage_dst->buf, 0, storage_src->size);
} /* end if */
else
/* Type conversion not necessary */
- HDmemcpy(layout_dst->u.compact.buf, layout_src->u.compact.buf, layout_src->u.compact.size);
+ HDmemcpy(storage_dst->buf, storage_src->buf, storage_src->size);
} /* end if */
- else
+ else
/* Type conversion not necessary */
- HDmemcpy(layout_dst->u.compact.buf, layout_src->u.compact.buf, layout_src->u.compact.size);
+ HDmemcpy(storage_dst->buf, storage_src->buf, storage_src->size);
+
+ /* Mark destination buffer as dirty */
+ storage_dst->dirty = TRUE;
done:
- if(buf_sid > 0)
- if(H5I_dec_ref(buf_sid) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary dataspace ID")
+ if(buf_sid > 0 && H5I_dec_ref(buf_sid, FALSE) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't decrement temporary dataspace ID")
if(tid_src > 0)
- if(H5I_dec_ref(tid_src) < 0)
+ if(H5I_dec_ref(tid_src, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
if(tid_dst > 0)
- if(H5I_dec_ref(tid_dst) < 0)
+ if(H5I_dec_ref(tid_dst, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
if(tid_mem > 0)
- if(H5I_dec_ref(tid_mem) < 0)
+ if(H5I_dec_ref(tid_mem, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
if(buf)
(void)H5FL_BLK_FREE(type_conv, buf);
diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c
index 14ad520..e2fe420 100644
--- a/src/H5Dcontig.c
+++ b/src/H5Dcontig.c
@@ -19,7 +19,7 @@
*
* Purpose:
* Contiguous dataset I/O functions. These routines are similar to
- * the H5D_istore_* routines and really only an abstract way of dealing
+ * the H5D_chunk_* routines and really only an abstract way of dealing
* with the data sieve buffer from H5F_seq_read/write.
*/
@@ -61,11 +61,11 @@
/********************/
/* Layout operation callbacks */
-static herr_t H5D_contig_new(H5F_t *f, hid_t dxpl_id, H5D_t *dset,
- const H5P_genplist_t *dc_plist);
+static herr_t H5D_contig_construct(H5F_t *f, H5D_t *dset);
static herr_t H5D_contig_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
H5D_chunk_map_t *cm);
+static herr_t H5D_contig_flush(H5D_t *dset, hid_t dxpl_id);
/* Helper routines */
static herr_t H5D_contig_write_one(H5D_io_info_t *io_info, hsize_t offset,
@@ -78,7 +78,9 @@ static herr_t H5D_contig_write_one(H5D_io_info_t *io_info, hsize_t offset,
/* Contiguous storage layout I/O ops */
const H5D_layout_ops_t H5D_LOPS_CONTIG[1] = {{
- H5D_contig_new,
+ H5D_contig_construct,
+ NULL,
+ H5D_contig_is_space_alloc,
H5D_contig_io_init,
H5D_contig_read,
H5D_contig_write,
@@ -88,6 +90,7 @@ const H5D_layout_ops_t H5D_LOPS_CONTIG[1] = {{
#endif /* H5_HAVE_PARALLEL */
H5D_contig_readvv,
H5D_contig_writevv,
+ H5D_contig_flush,
NULL
}};
@@ -117,7 +120,7 @@ H5FL_BLK_EXTERN(type_conv);
*-------------------------------------------------------------------------
*/
herr_t
-H5D_contig_alloc(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout /*out */ )
+H5D_contig_alloc(H5F_t *f, hid_t dxpl_id, H5O_storage_contig_t *storage /*out */ )
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -125,10 +128,10 @@ H5D_contig_alloc(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout /*out */ )
/* check args */
HDassert(f);
- HDassert(layout);
+ HDassert(storage);
/* Allocate space for the contiguous data */
- if(HADDR_UNDEF == (layout->u.contig.addr = H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, layout->u.contig.size)))
+ if(HADDR_UNDEF == (storage->addr = H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, storage->size)))
HGOTO_ERROR(H5E_IO, H5E_NOSPACE, FAIL, "unable to reserve file space")
done:
@@ -175,8 +178,8 @@ H5D_contig_fill(H5D_t *dset, hid_t dxpl_id)
/* Check args */
HDassert(TRUE == H5P_isa_class(dxpl_id, H5P_DATASET_XFER));
HDassert(dset && H5D_CONTIGUOUS == dset->shared->layout.type);
- HDassert(H5F_addr_defined(dset->shared->layout.u.contig.addr));
- HDassert(dset->shared->layout.u.contig.size > 0);
+ HDassert(H5F_addr_defined(dset->shared->layout.storage.u.contig.addr));
+ HDassert(dset->shared->layout.storage.u.contig.size > 0);
HDassert(dset->shared->space);
HDassert(dset->shared->type);
@@ -210,8 +213,8 @@ H5D_contig_fill(H5D_t *dset, hid_t dxpl_id)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache")
/* Initialize storage info for this dataset */
- store.contig.dset_addr = dset->shared->layout.u.contig.addr;
- store.contig.dset_size = dset->shared->layout.u.contig.size;
+ store.contig.dset_addr = dset->shared->layout.storage.u.contig.addr;
+ store.contig.dset_size = dset->shared->layout.storage.u.contig.size;
/* Get the number of elements in the dataset's dataspace */
snpoints = H5S_GET_EXTENT_NPOINTS(dset->shared->space);
@@ -242,7 +245,7 @@ H5D_contig_fill(H5D_t *dset, hid_t dxpl_id)
while(npoints > 0) {
size_t curr_points; /* Number of elements to write on this iteration of the loop */
size_t size; /* Size of buffer to write */
-
+
/* Compute # of elements and buffer size to write for this iteration */
curr_points = MIN(fb_info.elmts_per_buf, npoints);
size = curr_points * fb_info.file_elmt_size;
@@ -313,7 +316,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D_contig_delete(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout)
+H5D_contig_delete(H5F_t *f, hid_t dxpl_id, const H5O_storage_t *storage)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -321,11 +324,11 @@ H5D_contig_delete(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout)
/* check args */
HDassert(f);
- HDassert(layout);
+ HDassert(storage);
/* Free the file space for the chunk */
- if(H5MF_xfree(f, H5FD_MEM_DRAW, dxpl_id, layout->u.contig.addr, layout->u.contig.size) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free object header")
+ if(H5MF_xfree(f, H5FD_MEM_DRAW, dxpl_id, storage->u.contig.addr, storage->u.contig.size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to free contiguous storage space")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -350,15 +353,15 @@ H5D_contig_get_addr(const H5D_t *dset)
FUNC_ENTER_NOAPI_NOFUNC(H5D_contig_get_addr)
/* check args */
- assert(dset);
- assert(dset->shared->layout.type==H5D_CONTIGUOUS);
+ HDassert(dset);
+ HDassert(dset->shared->layout.type == H5D_CONTIGUOUS);
- FUNC_LEAVE_NOAPI(dset->shared->layout.u.contig.addr)
-} /* end H5D_contig_get_addr */
+ FUNC_LEAVE_NOAPI(dset->shared->layout.storage.u.contig.addr)
+} /* end H5D_contig_get_addr() */
/*-------------------------------------------------------------------------
- * Function: H5D_contig_new
+ * Function: H5D_contig_construct
*
* Purpose: Constructs new contiguous layout information for dataset
*
@@ -371,18 +374,19 @@ H5D_contig_get_addr(const H5D_t *dset)
*/
/* ARGSUSED */
static herr_t
-H5D_contig_new(H5F_t *f, hid_t UNUSED dxpl_id, H5D_t *dset,
- const H5P_genplist_t UNUSED *dc_plist)
+H5D_contig_construct(H5F_t *f, H5D_t *dset)
{
- const H5T_t *type = dset->shared->type; /* Convenience pointer to dataset's datatype */
- hssize_t tmp_size; /* Temporary holder for raw data size */
+ hssize_t snelmts; /* Temporary holder for number of elements in dataspace */
+ hsize_t nelmts; /* Number of elements in dataspace */
+ size_t dt_size; /* Size of datatype */
+ hsize_t tmp_size; /* Temporary holder for raw data size */
hsize_t dim[H5O_LAYOUT_NDIMS]; /* Current size of data in elements */
hsize_t max_dim[H5O_LAYOUT_NDIMS]; /* Maximum size of data in elements */
int ndims; /* Rank of dataspace */
int i; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_contig_new)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_contig_construct)
/* Sanity checks */
HDassert(f);
@@ -393,7 +397,6 @@ H5D_contig_new(H5F_t *f, hid_t UNUSED dxpl_id, H5D_t *dset,
* Also, only the slowest varying dimension of a simple data space
* can be extendible (currently only for external data storage).
*/
- dset->shared->layout.u.contig.addr = HADDR_UNDEF; /* Initialize to no address */
/* Check for invalid dataset dimensions */
if((ndims = H5S_get_simple_extent_dims(dset->shared->space, dim, max_dim)) < 0)
@@ -402,16 +405,60 @@ H5D_contig_new(H5F_t *f, hid_t UNUSED dxpl_id, H5D_t *dset,
if(max_dim[i] > dim[i])
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "extendible contiguous non-external dataset")
- /* Compute the total size of dataset */
- tmp_size = H5S_GET_EXTENT_NPOINTS(dset->shared->space) * H5T_get_size(type);
- H5_ASSIGN_OVERFLOW(dset->shared->layout.u.contig.size, tmp_size, hssize_t, hsize_t);
+ /* Retrieve the number of elements in the dataspace */
+ if((snelmts = H5S_GET_EXTENT_NPOINTS(dset->shared->space)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve number of elements in dataspace")
+ nelmts = (hsize_t)snelmts;
+
+ /* Get the datatype's size */
+ if(0 == (dt_size = H5T_GET_SIZE(dset->shared->type)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve size of datatype")
+
+ /* Compute the size of the dataset's contiguous storage */
+ tmp_size = nelmts * dt_size;
+
+ /* Check for overflow during multiplication */
+ if(nelmts != (tmp_size / dt_size))
+ HGOTO_ERROR(H5E_DATASET, H5E_OVERFLOW, FAIL, "size of dataset's storage overflowed")
+
+ /* Assign the dataset's contiguous storage size */
+ dset->shared->layout.storage.u.contig.size = tmp_size;
/* Get the sieve buffer size for this dataset */
dset->shared->cache.contig.sieve_buf_size = H5F_SIEVE_BUF_SIZE(f);
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_contig_new() */
+} /* end H5D_contig_construct() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_contig_is_space_alloc
+ *
+ * Purpose: Query if space is allocated for layout
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, January 15, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5D_contig_is_space_alloc(const H5O_storage_t *storage)
+{
+ hbool_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_contig_is_space_alloc)
+
+ /* Sanity checks */
+ HDassert(storage);
+
+ /* Set return value */
+ ret_value = (hbool_t)H5F_addr_defined(storage->u.contig.addr);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_contig_is_space_alloc() */
/*-------------------------------------------------------------------------
@@ -433,8 +480,8 @@ H5D_contig_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t UNUSED *t
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_contig_io_init)
- io_info->store->contig.dset_addr = io_info->dset->shared->layout.u.contig.addr;
- io_info->store->contig.dset_size = io_info->dset->shared->layout.u.contig.size;
+ io_info->store->contig.dset_addr = io_info->dset->shared->layout.storage.u.contig.addr;
+ io_info->store->contig.dset_size = io_info->dset->shared->layout.storage.u.contig.size;
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5D_contig_io_init() */
@@ -543,7 +590,7 @@ H5D_contig_write_one(H5D_io_info_t *io_info, hsize_t offset, size_t size)
HDassert(io_info);
- if(H5D_contig_writevv(io_info, (size_t)1, &dset_curr_seq, &dset_len, &dset_off,
+ if(H5D_contig_writevv(io_info, (size_t)1, &dset_curr_seq, &dset_len, &dset_off,
(size_t)1, &mem_curr_seq, &mem_len, &mem_off) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vector write failed")
@@ -609,7 +656,6 @@ for(u = 0; u < mem_max_nseq; u++)
haddr_t sieve_start = HADDR_UNDEF, sieve_end = HADDR_UNDEF; /* Start & end locations of sieve buffer */
haddr_t contig_end; /* End locations of block to write */
size_t sieve_size = (size_t)-1; /* size of sieve buffer */
- haddr_t abs_eoa; /* Absolute end of file address */
haddr_t rel_eoa; /* Relative end of file address */
hsize_t max_data; /* Actual maximum size of data to cache */
@@ -654,12 +700,9 @@ for(u = 0; u < mem_max_nseq; u++)
dset_contig->sieve_loc=addr;
/* Make certain we don't read off the end of the file */
- if (HADDR_UNDEF==(abs_eoa=H5F_get_eoa(file)))
+ if(HADDR_UNDEF == (rel_eoa = H5F_get_eoa(file, H5FD_MEM_DRAW)))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size")
- /* Adjust absolute EOA address to relative EOA address */
- rel_eoa = abs_eoa - H5F_get_base_addr(file);
-
/* Set up the buffer parameters */
max_data = store_contig->dset_size-dset_offset_arr[u];
@@ -731,12 +774,9 @@ for(u = 0; u < mem_max_nseq; u++)
dset_contig->sieve_loc=addr;
/* Make certain we don't read off the end of the file */
- if (HADDR_UNDEF==(abs_eoa=H5F_get_eoa(file)))
+ if(HADDR_UNDEF == (rel_eoa = H5F_get_eoa(file, H5FD_MEM_DRAW)))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size")
- /* Adjust absolute EOA address to relative EOA address */
- rel_eoa=abs_eoa-H5F_get_base_addr(file);
-
/* Only need this when resizing sieve buffer */
max_data=store_contig->dset_size-dset_offset_arr[u];
@@ -873,7 +913,6 @@ H5D_contig_writevv(const H5D_io_info_t *io_info,
haddr_t sieve_start=HADDR_UNDEF, sieve_end=HADDR_UNDEF; /* Start & end locations of sieve buffer */
haddr_t contig_end; /* End locations of block to write */
size_t sieve_size=(size_t)-1; /* size of sieve buffer */
- haddr_t abs_eoa; /* Absolute end of file address */
haddr_t rel_eoa; /* Relative end of file address */
hsize_t max_data; /* Actual maximum size of data to cache */
@@ -922,12 +961,9 @@ if(dset_contig->sieve_size > size)
dset_contig->sieve_loc=addr;
/* Make certain we don't read off the end of the file */
- if (HADDR_UNDEF==(abs_eoa=H5F_get_eoa(file)))
+ if(HADDR_UNDEF == (rel_eoa = H5F_get_eoa(file, H5FD_MEM_DRAW)))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size")
- /* Adjust absolute EOA address to relative EOA address */
- rel_eoa=abs_eoa-H5F_get_base_addr(file);
-
/* Set up the buffer parameters */
max_data=store_contig->dset_size-dset_offset_arr[u];
@@ -1041,12 +1077,9 @@ if(dset_contig->sieve_size > size)
dset_contig->sieve_loc=addr;
/* Make certain we don't read off the end of the file */
- if (HADDR_UNDEF==(abs_eoa=H5F_get_eoa(file)))
+ if(HADDR_UNDEF == (rel_eoa = H5F_get_eoa(file, H5FD_MEM_DRAW)))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size")
- /* Adjust absolute EOA address to relative EOA address */
- rel_eoa=abs_eoa-H5F_get_base_addr(file);
-
/* Only need this when resizing sieve buffer */
max_data=store_contig->dset_size-dset_offset_arr[u];
@@ -1141,6 +1174,37 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D_contig_flush
+ *
+ * Purpose: Writes all dirty data to disk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, July 27, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_contig_flush(H5D_t *dset, hid_t dxpl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_contig_flush)
+
+ /* Sanity check */
+ HDassert(dset);
+
+ /* Flush any data in sieve buffer */
+ if(H5D_flush_sieve_buf(dset, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to flush sieve buffer")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_contig_flush() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_contig_copy
*
* Purpose: Copy contiguous storage raw data from SRC file to DST file.
@@ -1150,14 +1214,12 @@ done:
* Programmer: Quincey Koziol
* Monday, November 21, 2005
*
- * Modifier: Peter Cao
- * Saturday, January 07, 2006
- * Add case to deal with compressed variable length datasets
*-------------------------------------------------------------------------
*/
herr_t
-H5D_contig_copy(H5F_t *f_src, const H5O_layout_t *layout_src, H5F_t *f_dst,
- H5O_layout_t *layout_dst, H5T_t *dt_src, H5O_copy_t *cpy_info, hid_t dxpl_id)
+H5D_contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src,
+ H5F_t *f_dst, H5O_storage_contig_t *storage_dst, H5T_t *dt_src,
+ H5O_copy_t *cpy_info, hid_t dxpl_id)
{
haddr_t addr_src; /* File offset in source dataset */
haddr_t addr_dst; /* File offset in destination dataset */
@@ -1191,57 +1253,63 @@ H5D_contig_copy(H5F_t *f_src, const H5O_layout_t *layout_src, H5F_t *f_dst,
/* Check args */
HDassert(f_src);
- HDassert(layout_src && H5D_CONTIGUOUS == layout_src->type);
+ HDassert(storage_src);
HDassert(f_dst);
- HDassert(layout_dst && H5D_CONTIGUOUS == layout_dst->type);
+ HDassert(storage_dst);
HDassert(dt_src);
/* Allocate space for destination raw data */
- if(H5D_contig_alloc(f_dst, dxpl_id, layout_dst) < 0)
+ if(H5D_contig_alloc(f_dst, dxpl_id, storage_dst) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to allocate contiguous storage")
/* Set up number of bytes to copy, and initial buffer size */
/* (actually use the destination size, which has been fixed up, if necessary) */
- total_src_nbytes = layout_dst->u.contig.size;
+ total_src_nbytes = storage_dst->size;
H5_CHECK_OVERFLOW(total_src_nbytes, hsize_t, size_t);
buf_size = MIN(H5D_TEMP_BUF_SIZE, (size_t)total_src_nbytes);
/* Create datatype ID for src datatype. We may or may not use this ID,
* but this ensures that the src datatype will be freed.
*/
- if((tid_src = H5I_register(H5I_DATATYPE, dt_src)) < 0)
+ if((tid_src = H5I_register(H5I_DATATYPE, dt_src, FALSE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register source file datatype")
/* If there's a VLEN source datatype, set up type conversion information */
- if(H5T_detect_class(dt_src, H5T_VLEN) > 0) {
+ if(H5T_detect_class(dt_src, H5T_VLEN, FALSE) > 0) {
/* create a memory copy of the variable-length datatype */
if(NULL == (dt_mem = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy")
- if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype")
+ if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem, FALSE)) < 0) {
+ H5T_close(dt_mem);
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register memory datatype")
+ } /* end if */
/* create variable-length datatype at the destinaton file */
if(NULL == (dt_dst = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy")
- if(H5T_set_loc(dt_dst, f_dst, H5T_LOC_DISK) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk")
- if((tid_dst = H5I_register(H5I_DATATYPE, dt_dst)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register destination file datatype")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy")
+ if(H5T_set_loc(dt_dst, f_dst, H5T_LOC_DISK) < 0) {
+ H5T_close(dt_dst);
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "cannot mark datatype on disk")
+ } /* end if */
+ if((tid_dst = H5I_register(H5I_DATATYPE, dt_dst, FALSE)) < 0) {
+ H5T_close(dt_dst);
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register destination file datatype")
+ } /* end if */
/* Set up the conversion functions */
if(NULL == (tpath_src_mem = H5T_path_find(dt_src, dt_mem, NULL, NULL, dxpl_id, FALSE)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes")
if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, dt_dst, NULL, NULL, dxpl_id, FALSE)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between mem and dst datatypes")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to convert between mem and dst datatypes")
/* Determine largest datatype size */
if(0 == (src_dt_size = H5T_get_size(dt_src)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to determine datatype size")
if(0 == (mem_dt_size = H5T_get_size(dt_mem)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to determine datatype size")
max_dt_size = MAX(src_dt_size, mem_dt_size);
if(0 == (dst_dt_size = H5T_get_size(dt_dst)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to determine datatype size")
max_dt_size = MAX(max_dt_size, dst_dt_size);
/* Set maximum number of whole elements that fit in buffer */
@@ -1264,7 +1332,7 @@ H5D_contig_copy(H5F_t *f_src, const H5O_layout_t *layout_src, H5F_t *f_dst,
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace")
/* Atomize */
- if((buf_sid = H5I_register(H5I_DATASPACE, buf_space)) < 0) {
+ if((buf_sid = H5I_register(H5I_DATASPACE, buf_space, FALSE)) < 0) {
H5S_close(buf_space);
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID")
} /* end if */
@@ -1277,7 +1345,7 @@ H5D_contig_copy(H5F_t *f_src, const H5O_layout_t *layout_src, H5F_t *f_dst,
if(H5T_get_class(dt_src, FALSE) == H5T_REFERENCE) {
/* Need to fix values of references when copying across files */
if(f_src != f_dst)
- fix_ref = TRUE;
+ fix_ref = TRUE;
} /* end if */
/* Set the number of bytes to read & write to the buffer size */
@@ -1300,8 +1368,8 @@ H5D_contig_copy(H5F_t *f_src, const H5O_layout_t *layout_src, H5F_t *f_dst,
} /* end if */
/* Loop over copying data */
- addr_src = layout_src->u.contig.addr;
- addr_dst = layout_dst->u.contig.addr;
+ addr_src = storage_src->addr;
+ addr_dst = storage_dst->addr;
while(total_src_nbytes > 0) {
/* Check if we should reduce the number of bytes to transfer */
if(total_src_nbytes < src_nbytes) {
@@ -1334,7 +1402,7 @@ H5D_contig_copy(H5F_t *f_src, const H5O_layout_t *layout_src, H5F_t *f_dst,
/* Perform datatype conversion, if necessary */
if(is_vlen) {
/* Convert from source file to memory */
- if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0)
+ if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, bkg, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed")
/* Copy into another buffer, to reclaim memory later */
@@ -1382,17 +1450,16 @@ H5D_contig_copy(H5F_t *f_src, const H5O_layout_t *layout_src, H5F_t *f_dst,
} /* end while */
done:
- if(buf_sid > 0)
- if(H5I_dec_ref(buf_sid) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary dataspace ID")
+ if(buf_sid > 0 && H5I_dec_ref(buf_sid, FALSE) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't decrement temporary dataspace ID")
if(tid_src > 0)
- if(H5I_dec_ref(tid_src) < 0)
+ if(H5I_dec_ref(tid_src, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
if(tid_dst > 0)
- if(H5I_dec_ref(tid_dst) < 0)
+ if(H5I_dec_ref(tid_dst, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
if(tid_mem > 0)
- if(H5I_dec_ref(tid_mem) < 0)
+ if(H5I_dec_ref(tid_mem, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
if(buf)
(void)H5FL_BLK_FREE(type_conv, buf);
diff --git a/src/H5Ddbg.c b/src/H5Ddbg.c
index 714c2e3..fa4c54c 100644
--- a/src/H5Ddbg.c
+++ b/src/H5Ddbg.c
@@ -115,7 +115,7 @@ H5Ddebug(hid_t dset_id)
if(H5D_CHUNKED == dset->shared->layout.type)
(void)H5D_chunk_dump_index(dset, H5AC_dxpl_id, stdout);
else if(H5D_CONTIGUOUS == dset->shared->layout.type)
- HDfprintf(stdout, " %-10s %a\n", "Address:", dset->shared->layout.u.contig.addr);
+ HDfprintf(stdout, " %-10s %a\n", "Address:", dset->shared->layout.storage.u.contig.addr);
done:
FUNC_LEAVE_API(ret_value)
diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c
index a07c86f..637cb70 100644
--- a/src/H5Ddeprec.c
+++ b/src/H5Ddeprec.c
@@ -170,7 +170,7 @@ H5Dcreate1(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset")
/* Register the new dataset to get an ID for it */
- if((ret_value = H5I_register(H5I_DATASET, dset)) < 0)
+ if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset")
done:
@@ -209,6 +209,7 @@ H5Dopen1(hid_t loc_id, const char *name)
H5O_loc_t oloc; /* Dataset object location */
H5O_type_t obj_type; /* Type of object at location */
hbool_t loc_found = FALSE; /* Location at 'name' found */
+ hid_t dapl_id = H5P_DATASET_ACCESS_DEFAULT; /* dapl to use to open dataset */
hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open datset */
hid_t ret_value;
@@ -238,11 +239,11 @@ H5Dopen1(hid_t loc_id, const char *name)
HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataset")
/* Open the dataset */
- if((dset = H5D_open(&dset_loc, dxpl_id)) == NULL)
+ if((dset = H5D_open(&dset_loc, dapl_id, dxpl_id)) == NULL)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open dataset")
/* Register an atom for the dataset */
- if((ret_value = H5I_register(H5I_DATASET, dset)) < 0)
+ if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "can't register dataset atom")
done:
@@ -345,9 +346,12 @@ H5D_extend(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id)
/* Updated the dataset's info if the dataspace was successfully extended */
if(changed) {
/* Update the index values for the cached chunks for this dataset */
- if(H5D_CHUNKED == dataset->shared->layout.type)
+ if(H5D_CHUNKED == dataset->shared->layout.type) {
+ if(H5D_chunk_set_info(dataset) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to update # of chunks")
if(H5D_chunk_update_cache(dataset, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update cached chunk indices")
+ } /* end if */
/* Allocate space for the new parts of the dataset, if appropriate */
fill = &dataset->shared->dcpl_cache.fill;
diff --git a/src/H5Defl.c b/src/H5Defl.c
index 647f02c..8b2da6a 100644
--- a/src/H5Defl.c
+++ b/src/H5Defl.c
@@ -32,6 +32,7 @@
#include "H5Dpkg.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fprivate.h" /* Files */
+#include "H5HLprivate.h" /* Local Heaps */
/****************/
@@ -49,8 +50,7 @@
/********************/
/* Layout operation callbacks */
-static herr_t H5D_efl_new(H5F_t *f, hid_t dxpl_id, H5D_t *dset,
- const H5P_genplist_t *dc_plist);
+static herr_t H5D_efl_construct(H5F_t *f, H5D_t *dset);
static herr_t H5D_efl_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
H5D_chunk_map_t *cm);
@@ -74,7 +74,9 @@ static herr_t H5D_efl_write(const H5O_efl_t *efl, haddr_t addr, size_t size,
/* External File List (EFL) storage layout I/O ops */
const H5D_layout_ops_t H5D_LOPS_EFL[1] = {{
- H5D_efl_new,
+ H5D_efl_construct,
+ NULL,
+ H5D_efl_is_space_alloc,
H5D_efl_io_init,
H5D_contig_read,
H5D_contig_write,
@@ -84,6 +86,7 @@ const H5D_layout_ops_t H5D_LOPS_EFL[1] = {{
#endif /* H5_HAVE_PARALLEL */
H5D_efl_readvv,
H5D_efl_writevv,
+ NULL,
NULL
}};
@@ -95,7 +98,7 @@ const H5D_layout_ops_t H5D_LOPS_EFL[1] = {{
/*-------------------------------------------------------------------------
- * Function: H5D_efl_new
+ * Function: H5D_efl_construct
*
* Purpose: Constructs new EFL layout information for dataset
*
@@ -107,10 +110,9 @@ const H5D_layout_ops_t H5D_LOPS_EFL[1] = {{
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_efl_new(H5F_t *f, hid_t UNUSED dxpl_id, H5D_t *dset,
- const H5P_genplist_t UNUSED *dc_plist)
+H5D_efl_construct(H5F_t *f, H5D_t *dset)
{
- const H5T_t *type = dset->shared->type; /* Convenience pointer to dataset's datatype */
+ size_t dt_size; /* Size of datatype */
hsize_t dim[H5O_LAYOUT_NDIMS]; /* Current size of data in elements */
hsize_t max_dim[H5O_LAYOUT_NDIMS]; /* Maximum size of data in elements */
hssize_t tmp_size; /* Temporary holder for raw data size */
@@ -120,19 +122,17 @@ H5D_efl_new(H5F_t *f, hid_t UNUSED dxpl_id, H5D_t *dset,
int i; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_efl_new)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_efl_construct)
/* Sanity checks */
HDassert(f);
HDassert(dset);
- HDassert(dc_plist);
/*
* The maximum size of the dataset cannot exceed the storage size.
* Also, only the slowest varying dimension of a simple data space
* can be extendible (currently only for external data storage).
*/
- dset->shared->layout.u.contig.addr = HADDR_UNDEF; /* Initialize to no address */
/* Check for invalid dataset dimensions */
if((ndims = H5S_get_simple_extent_dims(dset->shared->space, dim, max_dim)) < 0)
@@ -141,28 +141,57 @@ H5D_efl_new(H5F_t *f, hid_t UNUSED dxpl_id, H5D_t *dset,
if(max_dim[i] > dim[i])
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "only the first dimension can be extendible")
+ /* Retrieve the size of the dataset's datatype */
+ if(0 == (dt_size = H5T_get_size(dset->shared->type)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to determine datatype size")
+
/* Check for storage overflows */
max_points = H5S_get_npoints_max(dset->shared->space);
max_storage = H5O_efl_total_size(&dset->shared->dcpl_cache.efl);
if(H5S_UNLIMITED == max_points) {
if(H5O_EFL_UNLIMITED != max_storage)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unlimited data space but finite storage")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unlimited dataspace but finite storage")
} /* end if */
- else if(max_points * H5T_get_size(type) < max_points)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data space * type size overflowed")
- else if(max_points * H5T_get_size(type) > max_storage)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data space size exceeds external storage size")
+ else if((max_points * dt_size) < max_points)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "dataspace * type size overflowed")
+ else if((max_points * dt_size) > max_storage)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "dataspace size exceeds external storage size")
/* Compute the total size of dataset */
- tmp_size = H5S_GET_EXTENT_NPOINTS(dset->shared->space) * H5T_get_size(type);
- H5_ASSIGN_OVERFLOW(dset->shared->layout.u.contig.size, tmp_size, hssize_t, hsize_t);
+ tmp_size = H5S_GET_EXTENT_NPOINTS(dset->shared->space) * dt_size;
+ H5_ASSIGN_OVERFLOW(dset->shared->layout.storage.u.contig.size, tmp_size, hssize_t, hsize_t);
/* Get the sieve buffer size for this dataset */
dset->shared->cache.contig.sieve_buf_size = H5F_SIEVE_BUF_SIZE(f);
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_efl_new() */
+} /* end H5D_efl_construct() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_efl_is_space_alloc
+ *
+ * Purpose: Query if space is allocated for layout
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, January 15, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5D_efl_is_space_alloc(const H5O_storage_t UNUSED *storage)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_efl_is_space_alloc)
+
+ /* Sanity checks */
+ HDassert(storage);
+
+ /* EFL storage is currently always treated as allocated */
+ FUNC_LEAVE_NOAPI(TRUE)
+} /* end H5D_efl_is_space_alloc() */
/*-------------------------------------------------------------------------
@@ -257,12 +286,11 @@ H5D_efl_read(const H5O_efl_t *efl, haddr_t addr, size_t size, uint8_t *buf)
#else /* NDEBUG */
to_read = MIN((size_t)(efl->slot[u].size-skip), size);
#endif /* NDEBUG */
- if ((n=HDread (fd, buf, to_read))<0) {
- HGOTO_ERROR (H5E_EFL, H5E_READERROR, FAIL, "read error in external raw data file")
- } else if ((size_t)n<to_read) {
- HDmemset (buf+n, 0, to_read-n);
- }
- HDclose (fd);
+ if((n = HDread(fd, buf, to_read)) < 0)
+ HGOTO_ERROR(H5E_EFL, H5E_READERROR, FAIL, "read error in external raw data file")
+ else if((size_t)n < to_read)
+ HDmemset(buf + n, 0, to_read - (size_t)n);
+ HDclose(fd);
fd = -1;
size -= to_read;
buf += to_read;
@@ -528,3 +556,37 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_efl_writevv() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_efl_bh_size
+ *
+ * Purpose: Retrieve the amount of heap storage used for External File
+ * List message
+ *
+ * Return: Success: Non-negative
+ * Failure: negative
+ *
+ * Programmer: Vailin Choi; August 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_efl_bh_info(H5F_t *f, hid_t dxpl_id, H5O_efl_t *efl, hsize_t *heap_size)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5D_efl_bh_info, FAIL)
+
+ /* Check args */
+ HDassert(f);
+ HDassert(efl);
+ HDassert(H5F_addr_defined(efl->heap_addr));
+ HDassert(heap_size);
+
+ /* Get the size of the local heap for EFL's file list */
+ if(H5HL_heapsize(f, dxpl_id, efl->heap_addr, heap_size) < 0)
+ HGOTO_ERROR(H5E_EFL, H5E_CANTINIT, FAIL, "unable to retrieve local heap info")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_chunk_bh_info() */
diff --git a/src/H5Dfill.c b/src/H5Dfill.c
index 4879f4d..2f3f112 100644
--- a/src/H5Dfill.c
+++ b/src/H5Dfill.c
@@ -123,11 +123,11 @@ H5Dfill(const void *fill, hid_t fill_type_id, void *buf, hid_t buf_type_id, hid_
/* Check args */
if(buf == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer")
- if(NULL == (space = H5I_object_verify(space_id, H5I_DATASPACE)))
+ if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a dataspace")
- if(NULL == (fill_type = H5I_object_verify(fill_type_id, H5I_DATATYPE)))
+ if(NULL == (fill_type = (H5T_t *)H5I_object_verify(fill_type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype")
- if(NULL == (buf_type = H5I_object_verify(buf_type_id, H5I_DATATYPE)))
+ if(NULL == (buf_type = (H5T_t *)H5I_object_verify(buf_type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype")
/* Fill the selection in the memory buffer */
@@ -165,7 +165,7 @@ done:
If there's VL type of data, the address of the data is copied multiple
times into the buffer, causing some trouble when the data is released.
Instead, make multiple copies of fill value first, then do conversion
- on each element so that each of them has a copy of the VL data.
+ on each element so that each of them has a copy of the VL data.
--------------------------------------------------------------------------*/
herr_t
H5D_fill(const void *fill, const H5T_t *fill_type, void *buf,
@@ -229,18 +229,18 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf,
/* Construct source & destination datatype IDs, if we will need them */
if(!H5T_path_noop(tpath)) {
- if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(fill_type, H5T_COPY_ALL))) < 0)
+ if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(fill_type, H5T_COPY_ALL), FALSE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
- if((dst_id = H5I_register(H5I_DATATYPE, H5T_copy(buf_type, H5T_COPY_ALL))) < 0)
+ if((dst_id = H5I_register(H5I_DATATYPE, H5T_copy(buf_type, H5T_COPY_ALL), FALSE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
} /* end if */
- /* If there's VL type of data, make multiple copies of fill value first,
- * then do conversion on each element so that each of them has a copy
- * of the VL data.
+ /* If there's VL type of data, make multiple copies of fill value first,
+ * then do conversion on each element so that each of them has a copy
+ * of the VL data.
*/
- if(TRUE == H5T_detect_class(fill_type, H5T_VLEN)) {
+ if(TRUE == H5T_detect_class(fill_type, H5T_VLEN, FALSE)) {
H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */
H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */
H5S_sel_iter_t mem_iter; /* Memory selection iteration info */
@@ -320,10 +320,10 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf,
HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed")
/* Point at element buffer */
- fill_buf = elem_ptr;
+ fill_buf = (const uint8_t *)elem_ptr;
} /* end if */
else
- fill_buf = fill;
+ fill_buf = (const uint8_t *)fill;
/* Fill the selection in the memory buffer */
if(H5S_select_fill(fill_buf, dst_type_size, space, buf) < 0)
@@ -332,9 +332,9 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf,
} /* end else */
done:
- if(src_id != (-1) && H5I_dec_ref(src_id) < 0)
+ if(src_id != (-1) && H5I_dec_ref(src_id, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
- if(dst_id != (-1) && H5I_dec_ref(dst_id) < 0)
+ if(dst_id != (-1) && H5I_dec_ref(dst_id, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
if(tmp_buf)
(void)H5FL_BLK_FREE(type_conv, tmp_buf);
@@ -394,15 +394,19 @@ H5D_fill_init(H5D_fill_buf_info_t *fb_info, void *caller_fill_buf,
/* Fill the buffer with the user's fill value */
if(fill->buf) {
+ htri_t has_vlen_type; /* Whether the datatype has a VL component */
+
/* Detect whether the datatype has a VL component */
- fb_info->has_vlen_fill_type = H5T_detect_class(dset_type, H5T_VLEN);
+ if((has_vlen_type = H5T_detect_class(dset_type, H5T_VLEN, FALSE)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "unable to detect vlen datatypes?")
+ fb_info->has_vlen_fill_type = (hbool_t)has_vlen_type;
/* If necessary, convert fill value datatypes (which copies VL components, etc.) */
if(fb_info->has_vlen_fill_type) {
/* Create temporary datatype for conversion operation */
if(NULL == (fb_info->mem_type = H5T_copy(dset_type, H5T_COPY_REOPEN)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy file datatype")
- if((fb_info->mem_tid = H5I_register(H5I_DATATYPE, fb_info->mem_type)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy file datatype")
+ if((fb_info->mem_tid = H5I_register(H5I_DATATYPE, fb_info->mem_type, FALSE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype")
/* Retrieve sizes of memory & file datatypes */
@@ -466,7 +470,8 @@ H5D_fill_init(H5D_fill_buf_info_t *fb_info, void *caller_fill_buf,
} /* end if */
else {
/* If fill value is not library default, use it to set the element size */
- fb_info->max_elmt_size = fb_info->file_elmt_size = fb_info->mem_elmt_size = fill->size;
+ HDassert(fill->size >= 0);
+ fb_info->max_elmt_size = fb_info->file_elmt_size = fb_info->mem_elmt_size = (size_t)fill->size;
/* Compute the number of elements that fit within a buffer to write */
if(total_nelmts > 0)
@@ -673,7 +678,7 @@ H5D_fill_term(H5D_fill_buf_info_t *fb_info)
/* Free other resources for vlen fill values */
if(fb_info->has_vlen_fill_type) {
if(fb_info->mem_tid > 0)
- H5I_dec_ref(fb_info->mem_tid);
+ H5I_dec_ref(fb_info->mem_tid, FALSE);
else if(fb_info->mem_type)
H5T_close(fb_info->mem_type);
if(fb_info->bkg_buf)
diff --git a/src/H5Dint.c b/src/H5Dint.c
index 839ea93..5d64415 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -30,7 +30,6 @@
#include "H5Dpkg.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
#include "H5FOprivate.h" /* File objects */
-#include "H5HLprivate.h" /* Local heaps */
#include "H5Iprivate.h" /* IDs */
#include "H5Lprivate.h" /* Links */
#include "H5MMprivate.h" /* Memory management */
@@ -49,7 +48,6 @@
typedef struct {
const H5F_t *f; /* Pointer to file being flushed */
hid_t dxpl_id; /* DXPL for I/O operations */
- unsigned flags; /* Flags for flush operation */
} H5D_flush_ud_t;
@@ -65,10 +63,10 @@ static H5D_shared_t *H5D_new(hid_t dcpl_id, hbool_t creating,
static herr_t H5D_init_type(H5F_t *file, const H5D_t *dset, hid_t type_id,
const H5T_t *type);
static herr_t H5D_init_space(H5F_t *file, const H5D_t *dset, const H5S_t *space);
-static herr_t H5D_set_io_ops(H5D_t *dataset);
-static herr_t H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset);
-static herr_t H5D_open_oid(H5D_t *dataset, hid_t dxpl_id);
-static herr_t H5D_flush_real(H5D_t *dataset, hid_t dxpl_id, unsigned flags);
+static herr_t H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset,
+ hid_t dapl_id);
+static herr_t H5D_open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id);
+static herr_t H5D_flush_real(H5D_t *dataset, hid_t dxpl_id);
/*********************/
@@ -172,8 +170,8 @@ H5D_init_interface(void)
if(NULL == (def_dcpl = (H5P_genplist_t *)H5I_object(H5P_LST_DATASET_CREATE_g)))
HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "can't get default dataset creation property list")
- /* Get the default data storage method */
- if(H5P_get(def_dcpl, H5D_CRT_LAYOUT_NAME, &H5D_def_dset.layout.type) < 0)
+ /* Get the default data storage layout */
+ if(H5P_get(def_dcpl, H5D_CRT_LAYOUT_NAME, &H5D_def_dset.layout) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve layout")
/* Get the default dataset creation properties */
@@ -181,7 +179,7 @@ H5D_init_interface(void)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve external file list")
if(H5P_get(def_dcpl, H5D_CRT_FILL_VALUE_NAME, &H5D_def_dset.dcpl_cache.fill) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill value")
- if(H5P_get(def_dcpl, H5D_CRT_DATA_PIPELINE_NAME, &H5D_def_dset.dcpl_cache.pline) < 0)
+ if(H5P_get(def_dcpl, H5O_CRT_PIPELINE_NAME, &H5D_def_dset.dcpl_cache.pline) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve pipeline filter")
/* Reset the "default DXPL cache" information */
@@ -242,7 +240,7 @@ H5D_term_interface(void)
*
* QAK - 5/13/03
*/
- H5I_clear_type(H5I_DATASET, TRUE);
+ H5I_clear_type(H5I_DATASET, TRUE, FALSE);
} else {
H5I_dec_type_ref(H5I_DATASET);
H5_interface_initialize_g = 0;
@@ -419,6 +417,7 @@ H5D_create_named(const H5G_loc_t *loc, const char *name, hid_t type_id,
dcrt_info.type_id = type_id;
dcrt_info.space = space;
dcrt_info.dcpl_id = dcpl_id;
+ dcrt_info.dapl_id = dapl_id;
/* Set up object creation information */
ocrt_info.obj_type = H5O_TYPE_DATASET;
@@ -457,8 +456,9 @@ H5D_get_space_status(H5D_t *dset, H5D_space_status_t *allocation, hid_t dxpl_id)
{
H5S_t *space; /* Dataset's dataspace */
hsize_t space_allocated; /* The number of bytes allocated for chunks */
- hssize_t total_elem; /* The total number of elements in dataspace */
- size_t type_size; /* The size of the datatype for the dataset */
+ hssize_t snelmts; /* Temporary holder for number of elements in dataspace */
+ hsize_t nelmts; /* Number of elements in dataspace */
+ size_t dt_size; /* Size of datatype */
hsize_t full_size; /* The number of bytes in the dataset when fully populated */
herr_t ret_value = SUCCEED;
@@ -471,16 +471,20 @@ H5D_get_space_status(H5D_t *dset, H5D_space_status_t *allocation, hid_t dxpl_id)
HDassert(space);
/* Get the total number of elements in dataset's dataspace */
- if((total_elem=H5S_GET_EXTENT_NPOINTS(space)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to get # of dataspace elements")
+ if((snelmts = H5S_GET_EXTENT_NPOINTS(space)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve number of elements in dataspace")
+ nelmts = (hsize_t)snelmts;
/* Get the size of the dataset's datatype */
- if((type_size = H5T_get_size(dset->shared->type)) == 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to get size of datatype")
+ if(0 == (dt_size = H5T_GET_SIZE(dset->shared->type)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve size of datatype")
/* Compute the maximum size of the dataset in bytes */
- H5_CHECK_OVERFLOW(total_elem,hssize_t,hsize_t);
- full_size=((hsize_t)total_elem)*type_size;
+ full_size = nelmts * dt_size;
+
+ /* Check for overflow during multiplication */
+ if(nelmts != (full_size / dt_size))
+ HGOTO_ERROR(H5E_DATASET, H5E_OVERFLOW, FAIL, "size of dataset's storage overflowed")
/* Difficult to error check, since the error value is 0 and 0 is a valid value... :-/ */
space_allocated = H5D_get_storage_size(dset, dxpl_id);
@@ -536,7 +540,7 @@ H5D_new(hid_t dcpl_id, hbool_t creating, hbool_t vl_type)
* don't bother to copy it, just increment the reference count
*/
if(!vl_type && creating && dcpl_id == H5P_DATASET_CREATE_DEFAULT) {
- if(H5I_inc_ref(dcpl_id) < 0)
+ if(H5I_inc_ref(dcpl_id, FALSE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINC, NULL, "can't increment default DCPL ID")
new_dset->dcpl_id = dcpl_id;
} /* end if */
@@ -545,7 +549,7 @@ H5D_new(hid_t dcpl_id, hbool_t creating, hbool_t vl_type)
if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list")
- new_dset->dcpl_id = H5P_copy_plist(plist);
+ new_dset->dcpl_id = H5P_copy_plist(plist, FALSE);
} /* end else */
/* Set return value */
@@ -555,8 +559,8 @@ done:
if(ret_value == NULL)
if(new_dset != NULL) {
if(new_dset->dcpl_id != 0)
- (void)H5I_dec_ref(new_dset->dcpl_id);
- H5FL_FREE(H5D_shared_t, new_dset);
+ (void)H5I_dec_ref(new_dset->dcpl_id, FALSE);
+ (void)H5FL_FREE(H5D_shared_t, new_dset);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -619,12 +623,12 @@ H5D_init_type(H5F_t *file, const H5D_t *dset, hid_t type_id, const H5T_t *type)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of datatype")
/* Get a datatype ID for the dataset's datatype */
- if((dset->shared->type_id = H5I_register(H5I_DATATYPE, dset->shared->type)) < 0)
+ if((dset->shared->type_id = H5I_register(H5I_DATATYPE, dset->shared->type, FALSE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register type")
} /* end if */
/* Not a custom datatype, just use it directly */
else {
- if(H5I_inc_ref(type_id) < 0)
+ if(H5I_inc_ref(type_id, FALSE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINC, FAIL, "Can't increment datatype ID")
/* Use existing datatype */
@@ -686,58 +690,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_set_io_ops
- *
- * Purpose: Set the I/O operation function pointers for a dataset
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Thursday, March 20, 2008
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5D_set_io_ops(H5D_t *dataset)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5D_set_io_ops)
-
- /* check args */
- HDassert(dataset);
-
- /* Set the I/O functions for each layout type */
- switch(dataset->shared->layout.type) {
- case H5D_CONTIGUOUS:
- if(dataset->shared->dcpl_cache.efl.nused > 0)
- dataset->shared->layout.ops = H5D_LOPS_EFL;
- else
- dataset->shared->layout.ops = H5D_LOPS_CONTIG;
- break;
-
- case H5D_CHUNKED:
- dataset->shared->layout.ops = H5D_LOPS_CHUNK;
-
- /* Set the chunk operations */
- /* (Only "istore" indexing type currently supported */
- dataset->shared->layout.u.chunk.ops = H5D_COPS_ISTORE;
- break;
-
- case H5D_COMPACT:
- dataset->shared->layout.ops = H5D_LOPS_COMPACT;
- break;
-
- default:
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unknown storage method")
- } /* end switch */ /*lint !e788 All appropriate cases are covered */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_set_io_ops() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5D_update_oh_info
*
* Purpose: Create and fill object header for dataset
@@ -751,7 +703,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset)
+H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, hid_t dapl_id)
{
H5O_t *oh = NULL; /* Pointer to dataset's object header */
size_t ohdr_size = H5D_MINHDR_SIZE; /* Size of dataset's object header */
@@ -762,6 +714,7 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset)
H5O_fill_t *fill_prop; /* Pointer to dataset's fill value information */
H5D_fill_value_t fill_status; /* Fill value status */
hbool_t fill_changed = FALSE; /* Flag indicating the fill value was changed */
+ hbool_t layout_init = FALSE; /* Flag to indicate that chunk information was initialized */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_update_oh_info)
@@ -784,7 +737,7 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined")
/* Special case handling for variable-length types */
- if(H5T_detect_class(type, H5T_VLEN)) {
+ if(H5T_detect_class(type, H5T_VLEN, FALSE)) {
/* If the default fill value is chosen for variable-length types, always write it */
if(fill_prop->fill_time == H5D_FILL_TIME_IFSET && fill_status == H5D_FILL_VALUE_DEFAULT) {
/* Update dataset creation property */
@@ -831,7 +784,7 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset)
/* Add the dataset's raw data size to the size of the header, if the raw data will be stored as compact */
if(layout->type == H5D_COMPACT)
- ohdr_size += layout->u.compact.size;
+ ohdr_size += layout->storage.u.compact.size;
/* Create an object header for the dataset */
if(H5O_create(file, dxpl_id, ohdr_size, dset->shared->dcpl_id, oloc/*out*/) < 0)
@@ -839,8 +792,8 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset)
HDassert(file == dset->oloc.file);
/* Get a pointer to the object header itself */
- if(NULL == (oh = H5O_protect(oloc, dxpl_id)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTPROTECT, FAIL, "unable to protect dataset object header")
+ if(NULL == (oh = H5O_pin(oloc, dxpl_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header")
/* Write new fill value message */
if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_FILL_NEW_ID, H5O_MSG_FLAG_CONSTANT, 0, fill_prop) < 0)
@@ -869,78 +822,12 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset)
if(H5S_append(file, dxpl_id, oh, dset->shared->space) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update dataspace header message")
- /* Update the filters message, if this is a chunked dataset */
- if(layout->type == H5D_CHUNKED) {
- H5O_pline_t *pline; /* Dataset's I/O pipeline information */
-
- pline = &dset->shared->dcpl_cache.pline;
- if(pline->nused > 0 && H5O_msg_append_oh(file, dxpl_id, oh, H5O_PLINE_ID, H5O_MSG_FLAG_CONSTANT, 0, pline) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update filter header message")
- } /* end if */
-
- /*
- * Allocate storage if space allocate time is early; otherwise delay
- * allocation until later.
- */
- if(fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY)
- if(H5D_alloc_storage(dset, dxpl_id, H5D_ALLOC_CREATE, FALSE) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage")
-
- /* Update external storage message, if it's used */
- if(dset->shared->dcpl_cache.efl.nused > 0) {
- H5O_efl_t *efl = &dset->shared->dcpl_cache.efl; /* Dataset's external file list */
- H5HL_t *heap; /* Pointer to local heap for EFL file names */
- size_t heap_size = H5HL_ALIGN(1);
- size_t u;
-
- /* Determine size of heap needed to stored the file names */
- for(u = 0; u < efl->nused; ++u)
- heap_size += H5HL_ALIGN(HDstrlen(efl->slot[u].name) + 1);
-
- /* Create the heap for the EFL file names */
- if(H5HL_create(file, dxpl_id, heap_size, &efl->heap_addr/*out*/) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create EFL file name heap")
-
- /* Pin the heap down in memory */
- if(NULL == (heap = H5HL_protect(file, dxpl_id, efl->heap_addr, H5AC_WRITE)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTPROTECT, FAIL, "unable to protect EFL file name heap")
-
- /* Insert "empty" name first */
- if((size_t)(-1) == H5HL_insert(file, dxpl_id, heap, (size_t)1, "")) {
- H5HL_unprotect(file, dxpl_id, heap, efl->heap_addr);
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert file name into heap")
- } /* end if */
-
- for(u = 0; u < efl->nused; ++u) {
- size_t offset; /* Offset of file name in heap */
-
- /* Insert file name into heap */
- if((size_t)(-1) == (offset = H5HL_insert(file, dxpl_id, heap,
- HDstrlen(efl->slot[u].name) + 1, efl->slot[u].name))) {
- H5HL_unprotect(file, dxpl_id, heap, efl->heap_addr);
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert file name into heap")
- } /* end if */
-
- /* Store EFL file name offset */
- HDassert(0 == efl->slot[u].name_offset);
- efl->slot[u].name_offset = offset;
- } /* end for */
-
- /* Release the heap */
- if(H5HL_unprotect(file, dxpl_id, heap, efl->heap_addr) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTUNPROTECT, FAIL, "unable to unprotect EFL file name heap")
- heap = NULL;
-
- /* Insert EFL message into dataset object header */
- if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_EFL_ID, H5O_MSG_FLAG_CONSTANT, 0, efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update external file list message")
- } /* end if */
+ /* Update/create the layout (and I/O pipeline & EFL) messages */
+ if(H5D_layout_oh_create(file, dxpl_id, oh, dset, dapl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout/pline/efl header message")
- /* Create layout message */
- /* (Don't make layout message constant unless allocation time is early, since space may not be allocated) */
- /* (Note: this is relying on H5D_alloc_storage not calling H5O_msg_write during dataset creation) */
- if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_LAYOUT_ID, ((fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY && H5D_COMPACT != layout->type) ? H5O_MSG_FLAG_CONSTANT : 0), 0, layout) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout")
+ /* Indicate that the layout information was initialized */
+ layout_init = TRUE;
#ifdef H5O_ENABLE_BOGUS
{
@@ -966,6 +853,9 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset)
#endif /* H5O_ENABLE_BOGUS */
/* Add a modification time message, if using older format. */
+ /* (If using the latest format, the modification time is part of the object
+ * header and doesn't use a separate message -QAK)
+ */
if(!use_latest_format)
if(H5O_touch_oh(file, dxpl_id, oh, TRUE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update modification time message")
@@ -973,8 +863,16 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset)
done:
/* Release pointer to object header itself */
if(oloc != NULL && oh != NULL)
- if(H5O_unprotect(oloc, oh) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CANTUNPROTECT, FAIL, "unable to unprotect dataset object header")
+ if(H5O_unpin(oloc, oh) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header")
+
+ /* Error cleanup */
+ if(ret_value < 0) {
+ if(dset->shared->layout.type == H5D_CHUNKED && layout_init) {
+ if(H5D_chunk_dest(file, dxpl_id, dset) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to destroy chunk cache")
+ } /* end if */
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_update_oh_info() */
@@ -1002,7 +900,7 @@ done:
*/
H5D_t *
H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
- hid_t dxpl_id)
+ hid_t dapl_id, hid_t dxpl_id)
{
const H5T_t *type; /* Datatype for dataset */
H5D_t *new_dset = NULL;
@@ -1016,10 +914,10 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
/* check args */
HDassert(file);
- HDassert(H5I_DATATYPE==H5I_get_type(type_id));
+ HDassert(H5I_DATATYPE == H5I_get_type(type_id));
HDassert(space);
- HDassert(H5I_GENPROP_LST==H5I_get_type(dcpl_id));
- HDassert(H5I_GENPROP_LST==H5I_get_type(dxpl_id));
+ HDassert(H5I_GENPROP_LST == H5I_get_type(dcpl_id));
+ HDassert(H5I_GENPROP_LST == H5I_get_type(dxpl_id));
/* Get the dataset's datatype */
if(NULL == (type = (const H5T_t *)H5I_object(type_id)))
@@ -1030,11 +928,11 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "datatype is not sensible")
/* Check if the datatype is/contains a VL-type */
- if(H5T_detect_class(type, H5T_VLEN))
- has_vl_type=TRUE;
+ if(H5T_detect_class(type, H5T_VLEN, FALSE))
+ has_vl_type = TRUE;
/* Check if the dataspace has an extent set (or is NULL) */
- if(!(H5S_has_extent(space)) )
+ if(!H5S_has_extent(space))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "dataspace extent has not been set.")
/* Initialize the dataset object */
@@ -1063,7 +961,7 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
/* Check if the dataset has a non-default DCPL & get important values, if so */
if(new_dset->shared->dcpl_id != H5P_DATASET_CREATE_DEFAULT) {
- H5D_layout_t *layout; /* Dataset's layout information */
+ H5O_layout_t *layout; /* Dataset's layout information */
H5O_pline_t *pline; /* Dataset's I/O pipeline information */
H5O_fill_t *fill; /* Dataset's fill value info */
@@ -1081,12 +979,12 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
/* Retrieve the properties we need */
pline = &new_dset->shared->dcpl_cache.pline;
- if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, pline) < 0)
+ if(H5P_get(dc_plist, H5O_CRT_PIPELINE_NAME, pline) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve pipeline filter")
- layout = &new_dset->shared->layout.type;
+ layout = &new_dset->shared->layout;
if(H5P_get(dc_plist, H5D_CRT_LAYOUT_NAME, layout) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout")
- if(pline->nused > 0 && H5D_CHUNKED != *layout)
+ if(pline->nused > 0 && H5D_CHUNKED != layout->type)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "filters can only be used with chunked layout")
fill = &new_dset->shared->dcpl_cache.fill;
if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, fill) < 0)
@@ -1097,7 +995,7 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "invalid space allocation state")
/* Don't allow compact datasets to allocate space later */
- if(*layout == H5D_COMPACT && fill->alloc_time != H5D_ALLOC_TIME_EARLY)
+ if(layout->type == H5D_COMPACT && fill->alloc_time != H5D_ALLOC_TIME_EARLY)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "compact dataset must have early space allocation")
/* If MPI VFD is used, no filter support yet. */
@@ -1109,10 +1007,10 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve external file list")
} /* end if */
- /* Set the latest version of the pline & fill messages, if requested */
+ /* Set the latest version of the layout, pline & fill messages, if requested */
if(H5F_USE_LATEST_FORMAT(file)) {
/* Set the latest version for the I/O pipeline message */
- if(H5Z_set_latest_version(&new_dset->shared->dcpl_cache.pline) < 0)
+ if(H5O_pline_set_latest_version(&new_dset->shared->dcpl_cache.pline) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest version of I/O filter pipeline")
/* Set the latest version for the fill value message */
@@ -1125,25 +1023,25 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
new_dset->shared->dcpl_cache.fill.alloc_time = H5D_ALLOC_TIME_EARLY;
/* Set the dataset's I/O operations */
- if(H5D_set_io_ops(new_dset) < 0)
+ if(H5D_layout_set_io_ops(new_dset) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize I/O operations")
/* Create the layout information for the new dataset */
- if((new_dset->shared->layout.ops->new)(file, dxpl_id, new_dset, dc_plist) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize layout information")
-
- /* Indicate that the layout information was initialized */
- layout_init = TRUE;
+ if((new_dset->shared->layout.ops->construct)(file, new_dset) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to construct layout information")
/* Update the dataset's object header info. */
- if(H5D_update_oh_info(file, dxpl_id, new_dset) != SUCCEED)
+ if(H5D_update_oh_info(file, dxpl_id, new_dset, dapl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "can't update the metadata cache")
+ /* Indicate that the layout information was initialized */
+ layout_init = TRUE;
+
/* Add the dataset to the list of opened objects in the file */
if(H5FO_top_incr(new_dset->oloc.file, new_dset->oloc.addr) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINC, NULL, "can't incr object ref. count")
if(H5FO_insert(new_dset->oloc.file, new_dset->oloc.addr, new_dset->shared, TRUE) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, NULL, "can't insert dataset into list of open objects")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, NULL, "can't insert dataset into list of open objects")
new_dset->shared->fo_count = 1;
@@ -1157,12 +1055,10 @@ done:
if(H5D_chunk_dest(file, dxpl_id, new_dset) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, NULL, "unable to destroy chunk cache")
} /* end if */
- if(new_dset->shared->space) {
- if(H5S_close(new_dset->shared->space) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, NULL, "unable to release dataspace")
- } /* end if */
+ if(new_dset->shared->space && H5S_close(new_dset->shared->space) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, NULL, "unable to release dataspace")
if(new_dset->shared->type) {
- if(H5I_dec_ref(new_dset->shared->type_id) < 0)
+ if(H5I_dec_ref(new_dset->shared->type_id, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, NULL, "unable to release datatype")
} /* end if */
if(H5F_addr_defined(new_dset->oloc.addr)) {
@@ -1173,14 +1069,12 @@ done:
HDONE_ERROR(H5E_DATASET, H5E_CANTDELETE, NULL, "unable to delete object header")
} /* end if */
} /* end if */
- if(new_dset->shared->dcpl_id != 0) {
- if(H5I_dec_ref(new_dset->shared->dcpl_id) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, NULL, "unable to decrement ref count on property list")
- } /* end if */
- H5FL_FREE(H5D_shared_t, new_dset->shared);
+ if(new_dset->shared->dcpl_id != 0 && H5I_dec_ref(new_dset->shared->dcpl_id, FALSE) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, NULL, "unable to decrement ref count on property list")
+ (void)H5FL_FREE(H5D_shared_t, new_dset->shared);
} /* end if */
new_dset->oloc.file = NULL;
- H5FL_FREE(H5D_t, new_dset);
+ (void)H5FL_FREE(H5D_t, new_dset);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -1203,7 +1097,7 @@ done:
*-------------------------------------------------------------------------
*/
H5D_t *
-H5D_open(const H5G_loc_t *loc, hid_t dxpl_id)
+H5D_open(const H5G_loc_t *loc, hid_t dapl_id, hid_t dxpl_id)
{
H5D_shared_t *shared_fo = NULL;
H5D_t *dataset = NULL;
@@ -1227,12 +1121,12 @@ H5D_open(const H5G_loc_t *loc, hid_t dxpl_id)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, NULL, "can't copy path")
/* Check if dataset was already open */
- if((shared_fo = (H5D_shared_t *)H5FO_opened(dataset->oloc.file, dataset->oloc.addr)) == NULL) {
+ if(NULL == (shared_fo = (H5D_shared_t *)H5FO_opened(dataset->oloc.file, dataset->oloc.addr))) {
/* Clear any errors from H5FO_opened() */
H5E_clear_stack(NULL);
/* Open the dataset object */
- if(H5D_open_oid(dataset, dxpl_id) < 0)
+ if(H5D_open_oid(dataset, dapl_id, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, NULL, "not found")
/* Add the dataset to the list of opened objects in the file */
@@ -1272,13 +1166,13 @@ done:
/* Free the location--casting away const*/
if(dataset) {
if(shared_fo == NULL) /* Need to free shared fo */
- H5FL_FREE(H5D_shared_t, dataset->shared);
+ (void)H5FL_FREE(H5D_shared_t, dataset->shared);
H5O_loc_free(&(dataset->oloc));
H5G_name_free(&(dataset->path));
- H5FL_FREE(H5D_t, dataset);
- }
+ (void)H5FL_FREE(H5D_t, dataset);
+ } /* end if */
if(shared_fo)
shared_fo->fo_count--;
} /* end if */
@@ -1300,7 +1194,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_open_oid(H5D_t *dataset, hid_t dxpl_id)
+H5D_open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id)
{
H5P_genplist_t *plist; /* Property list */
H5O_fill_t *fill_prop; /* Pointer to dataset's fill value info */
@@ -1324,109 +1218,24 @@ H5D_open_oid(H5D_t *dataset, hid_t dxpl_id)
/* Get the type and space */
if(NULL == (dataset->shared->type = (H5T_t *)H5O_msg_read(&(dataset->oloc), H5O_DTYPE_ID, NULL, dxpl_id)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to load type info from dataset header")
+
+ if(H5T_set_loc(dataset->shared->type, dataset->oloc.file, H5T_LOC_DISK) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
+
if(NULL == (dataset->shared->space = H5S_read(&(dataset->oloc), dxpl_id)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to load space info from dataset header")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to load dataspace info from dataset header")
/* Get a datatype ID for the dataset's datatype */
- if((dataset->shared->type_id = H5I_register(H5I_DATATYPE, dataset->shared->type)) < 0)
+ if((dataset->shared->type_id = H5I_register(H5I_DATATYPE, dataset->shared->type, FALSE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register type")
/* Get dataset creation property list object */
if(NULL == (plist = (H5P_genplist_t *)H5I_object(dataset->shared->dcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get dataset creation property list")
- /* Get the optional filters message */
- if((msg_exists = H5O_msg_exists(&(dataset->oloc), H5O_PLINE_ID, dxpl_id)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check if message exists")
- if(msg_exists) {
- /* Retrieve the I/O pipeline message */
- if(NULL == H5O_msg_read(&(dataset->oloc), H5O_PLINE_ID, &dataset->shared->dcpl_cache.pline, dxpl_id))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve message")
-
- /* Set the I/O pipeline info in the property list */
- if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &dataset->shared->dcpl_cache.pline) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set pipeline")
- } /* end if */
-
- /*
- * Get the raw data layout info. It's actually stored in two locations:
- * the storage message of the dataset (dataset->storage) and certain
- * values are copied to the dataset create plist so the user can query
- * them.
- */
- if(NULL == H5O_msg_read(&(dataset->oloc), H5O_LAYOUT_ID, &(dataset->shared->layout), dxpl_id))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data layout message")
- if(H5P_set(plist, H5D_CRT_LAYOUT_NAME, &dataset->shared->layout.type) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set layout")
-
- /* Get the external file list message, which might not exist. Space is
- * also undefined when space allocate time is H5D_ALLOC_TIME_LATE. */
- if((dataset->shared->layout.type == H5D_CONTIGUOUS && !H5F_addr_defined(dataset->shared->layout.u.contig.addr))
- || (dataset->shared->layout.type == H5D_CHUNKED && !H5F_addr_defined(dataset->shared->layout.u.chunk.addr))) {
- if((msg_exists = H5O_msg_exists(&(dataset->oloc), H5O_EFL_ID, dxpl_id)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check if message exists")
- if(msg_exists) {
- /* Retrieve the EFL message */
- if(NULL == H5O_msg_read(&(dataset->oloc), H5O_EFL_ID, &dataset->shared->dcpl_cache.efl, dxpl_id))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve message")
-
- /* Set the EFL info in the property list */
- if(H5P_set(plist, H5D_CRT_EXT_FILE_LIST_NAME, &dataset->shared->dcpl_cache.efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set external file list")
-
- /* Set the dataset's I/O operations */
- dataset->shared->layout.ops = H5D_LOPS_EFL;
- } /* end if */
- } /* end if */
-
- /* Sanity check that the layout operations are set up */
- HDassert(dataset->shared->layout.ops);
-
- switch(dataset->shared->layout.type) {
- case H5D_CONTIGUOUS:
- /* Compute the size of the contiguous storage for versions of the
- * layout message less than version 3 because versions 1 & 2 would
- * truncate the dimension sizes to 32-bits of information. - QAK 5/26/04
- */
- if(dataset->shared->layout.version < 3) {
- hssize_t tmp_size; /* Temporary holder for raw data size */
-
- tmp_size = H5S_GET_EXTENT_NPOINTS(dataset->shared->space) * H5T_get_size(dataset->shared->type);
- H5_ASSIGN_OVERFLOW(dataset->shared->layout.u.contig.size, tmp_size, hssize_t, hsize_t);
- } /* end if */
-
- /* Get the sieve buffer size for this dataset */
- dataset->shared->cache.contig.sieve_buf_size = H5F_SIEVE_BUF_SIZE(dataset->oloc.file);
- break;
-
- case H5D_CHUNKED:
- /*
- * Chunked storage. The creation plist's dimension is one less than
- * the chunk dimension because the chunk includes a dimension for the
- * individual bytes of the datatype.
- */
- {
- unsigned chunk_ndims; /* Dimensionality of chunk */
-
- chunk_ndims = dataset->shared->layout.u.chunk.ndims - 1;
-
- if(H5P_set(plist, H5D_CRT_CHUNK_DIM_NAME, &chunk_ndims) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set chunk dimensions")
- if(H5P_set(plist, H5D_CRT_CHUNK_SIZE_NAME, dataset->shared->layout.u.chunk.dim) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set chunk size")
-
- /* Initialize the chunk cache for the dataset */
- if(H5D_chunk_init(dataset->oloc.file, dxpl_id, dataset) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize chunk cache")
- }
- break;
-
- case H5D_COMPACT:
- break;
-
- default:
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unknown storage method")
- } /* end switch */ /*lint !e788 All appropriate cases are covered */
+ /* Get the layout/pline/efl message information */
+ if(H5D_layout_oh_read(dataset, dxpl_id, dapl_id, plist) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get layout/pline/efl info")
/* Point at dataset's copy, to cache it for later */
fill_prop = &dataset->shared->dcpl_cache.fill;
@@ -1468,7 +1277,7 @@ H5D_open_oid(H5D_t *dataset, hid_t dxpl_id)
/* If "old" fill value size is 0 (undefined), map it to -1 */
if(fill_prop->size == 0)
- fill_prop->size = (size_t)-1;
+ fill_prop->size = (ssize_t)-1;
} /* end if */
alloc_time_state = 0;
if((dataset->shared->layout.type == H5D_COMPACT && fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY)
@@ -1489,9 +1298,8 @@ H5D_open_oid(H5D_t *dataset, hid_t dxpl_id)
* This is important only for parallel I/O where the space must
* be fully allocated before I/O can happen.
*/
- if((H5F_get_intent(dataset->oloc.file) & H5F_ACC_RDWR)
- && ((dataset->shared->layout.type == H5D_CONTIGUOUS && !H5F_addr_defined(dataset->shared->layout.u.contig.addr))
- || (dataset->shared->layout.type == H5D_CHUNKED && !H5F_addr_defined(dataset->shared->layout.u.chunk.addr)))
+ if((H5F_INTENT(dataset->oloc.file) & H5F_ACC_RDWR)
+ && !(*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage)
&& IS_H5FD_MPI(dataset->oloc.file)) {
if(H5D_alloc_storage(dataset, dxpl_id, H5D_ALLOC_OPEN, FALSE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file storage")
@@ -1499,17 +1307,13 @@ H5D_open_oid(H5D_t *dataset, hid_t dxpl_id)
done:
if(ret_value < 0) {
- if(H5F_addr_defined(dataset->oloc.addr)) {
- if(H5O_close(&(dataset->oloc)) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release object header")
- } /* end if */
- if(dataset->shared->space) {
- if(H5S_close(dataset->shared->space) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace")
- } /* end if */
+ if(H5F_addr_defined(dataset->oloc.addr) && H5O_close(&(dataset->oloc)) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release object header")
+ if(dataset->shared->space && H5S_close(dataset->shared->space) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace")
if(dataset->shared->type) {
if(dataset->shared->type_id > 0) {
- if(H5I_dec_ref(dataset->shared->type_id) < 0)
+ if(H5I_dec_ref(dataset->shared->type_id, FALSE) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype")
} /* end if */
else {
@@ -1557,7 +1361,7 @@ H5D_close(H5D_t *dataset)
dataset->shared->fo_count--;
if(dataset->shared->fo_count == 0) {
/* Flush the dataset's information */
- if(H5D_flush_real(dataset, H5AC_dxpl_id, H5F_FLUSH_NONE) < 0)
+ if(H5D_flush_real(dataset, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to flush cached dataset info")
/* Free the data sieve buffer, if it's been allocated */
@@ -1599,7 +1403,7 @@ H5D_close(H5D_t *dataset)
case H5D_COMPACT:
/* Free the buffer for the raw data for compact datasets */
- dataset->shared->layout.u.compact.buf = H5MM_xfree(dataset->shared->layout.u.compact.buf);
+ dataset->shared->layout.storage.u.compact.buf = H5MM_xfree(dataset->shared->layout.storage.u.compact.buf);
break;
default:
@@ -1613,8 +1417,8 @@ H5D_close(H5D_t *dataset)
* Release datatype, dataspace and creation property list -- there isn't
* much we can do if one of these fails, so we just continue.
*/
- free_failed = (H5I_dec_ref(dataset->shared->type_id) < 0 || H5S_close(dataset->shared->space) < 0 ||
- H5I_dec_ref(dataset->shared->dcpl_id) < 0);
+ free_failed = (unsigned)(H5I_dec_ref(dataset->shared->type_id, FALSE) < 0 || H5S_close(dataset->shared->space) < 0 ||
+ H5I_dec_ref(dataset->shared->dcpl_id, FALSE) < 0);
/* Remove the dataset from the list of opened objects in the file */
if(H5FO_top_decr(dataset->oloc.file, dataset->oloc.addr) < 0)
@@ -1635,7 +1439,7 @@ H5D_close(H5D_t *dataset)
*/
dataset->oloc.file = NULL;
- H5FL_FREE(H5D_shared_t, dataset->shared);
+ (void)H5FL_FREE(H5D_shared_t, dataset->shared);
} /* end if */
else {
/* Decrement the ref. count for this object in the top file */
@@ -1653,7 +1457,7 @@ H5D_close(H5D_t *dataset)
free_failed = TRUE;
/* Free the dataset's memory structure */
- H5FL_FREE(H5D_t, dataset);
+ (void)H5FL_FREE(H5D_t, dataset);
/* Check if anything failed in the middle... */
if(free_failed)
@@ -1717,7 +1521,6 @@ H5D_nameof(H5D_t *dataset)
* is not copied.
*
* Return: Success: Ptr to the dataset's datatype, uncopied.
- *
* Failure: NULL
*
* Programmer: Robb Matzke
@@ -1732,6 +1535,7 @@ H5D_typeof(const H5D_t *dset)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_typeof)
HDassert(dset);
+ HDassert(dset->shared);
HDassert(dset->shared->type);
FUNC_LEAVE_NOAPI(dset->shared->type)
@@ -1739,33 +1543,6 @@ H5D_typeof(const H5D_t *dset)
/*-------------------------------------------------------------------------
- * Function: H5D_get_file
- *
- * Purpose: Returns the dataset's file pointer.
- *
- * Return: Success: Ptr to the dataset's file pointer.
- *
- * Failure: NULL
- *
- * Programmer: Quincey Koziol
- * Thursday, October 22, 1998
- *
- *-------------------------------------------------------------------------
- */
-static H5F_t *
-H5D_get_file(const H5D_t *dset)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_get_file)
-
- HDassert(dset);
- HDassert(dset->oloc.file);
-
- FUNC_LEAVE_NOAPI(dset->oloc.file)
-} /* end H5D_get_file() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5D_alloc_storage
*
* Purpose: Allocate storage for the raw data of a dataset.
@@ -1803,9 +1580,9 @@ H5D_alloc_storage(H5D_t *dset/*in,out*/, hid_t dxpl_id, H5D_time_alloc_t time_al
switch(layout->type) {
case H5D_CONTIGUOUS:
- if(!H5F_addr_defined(layout->u.contig.addr)) {
+ if(!(*dset->shared->layout.ops->is_space_alloc)(&dset->shared->layout.storage)) {
/* Reserve space in the file for the entire array */
- if(H5D_contig_alloc(f, dxpl_id, layout/*out*/) < 0)
+ if(H5D_contig_alloc(f, dxpl_id, &layout->storage.u.contig/*out*/) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to initialize contiguous storage")
/* Indicate that we set the storage addr */
@@ -1817,7 +1594,7 @@ H5D_alloc_storage(H5D_t *dset/*in,out*/, hid_t dxpl_id, H5D_time_alloc_t time_al
break;
case H5D_CHUNKED:
- if(!H5F_addr_defined(layout->u.chunk.addr)) {
+ if(!(*dset->shared->layout.ops->is_space_alloc)(&dset->shared->layout.storage)) {
/* Create the root of the B-tree that describes chunked storage */
if(H5D_chunk_create(dset /*in,out*/, dxpl_id) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to initialize chunked storage")
@@ -1840,17 +1617,14 @@ H5D_alloc_storage(H5D_t *dset/*in,out*/, hid_t dxpl_id, H5D_time_alloc_t time_al
case H5D_COMPACT:
/* Check if space is already allocated */
- if(layout->u.compact.buf==NULL) {
+ if(NULL == layout->storage.u.compact.buf) {
/* Reserve space in layout header message for the entire array. */
- HDassert(layout->u.compact.size > 0);
- if(NULL == (layout->u.compact.buf = H5MM_malloc(layout->u.compact.size)))
+ HDassert(layout->storage.u.compact.size > 0);
+ if(NULL == (layout->storage.u.compact.buf = H5MM_malloc(layout->storage.u.compact.size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for compact dataset")
if(!full_overwrite)
- HDmemset(layout->u.compact.buf, 0, layout->u.compact.size);
- layout->u.compact.dirty = TRUE;
-
- /* Indicate that we set the storage addr */
- addr_set = TRUE;
+ HDmemset(layout->storage.u.compact.buf, 0, layout->storage.u.compact.size);
+ layout->storage.u.compact.dirty = TRUE;
/* Indicate that we should initialize storage space */
must_init_space = TRUE;
@@ -1999,23 +1773,24 @@ H5D_get_storage_size(H5D_t *dset, hid_t dxpl_id)
switch(dset->shared->layout.type) {
case H5D_CHUNKED:
- if(dset->shared->layout.u.chunk.addr == HADDR_UNDEF)
- ret_value = 0;
- else
+ if((*dset->shared->layout.ops->is_space_alloc)(&dset->shared->layout.storage)) {
if(H5D_chunk_allocated(dset, dxpl_id, &ret_value) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, 0, "can't retrieve chunked dataset allocated size")
+ } /* end if */
+ else
+ ret_value = 0;
break;
case H5D_CONTIGUOUS:
/* Datasets which are not allocated yet are using no space on disk */
- if(dset->shared->layout.u.contig.addr == HADDR_UNDEF)
- ret_value = 0;
+ if((*dset->shared->layout.ops->is_space_alloc)(&dset->shared->layout.storage))
+ ret_value = dset->shared->layout.storage.u.contig.size;
else
- ret_value = dset->shared->layout.u.contig.size;
+ ret_value = 0;
break;
case H5D_COMPACT:
- ret_value = dset->shared->layout.u.compact.size;
+ ret_value = dset->shared->layout.storage.u.compact.size;
break;
default:
@@ -2045,8 +1820,6 @@ done:
haddr_t
H5D_get_offset(const H5D_t *dset)
{
- haddr_t base_addr;
- H5F_t *f;
haddr_t ret_value = HADDR_UNDEF;
FUNC_ENTER_NOAPI_NOINIT(H5D_get_offset)
@@ -2061,15 +1834,9 @@ H5D_get_offset(const H5D_t *dset)
case H5D_CONTIGUOUS:
/* If dataspace hasn't been allocated or dataset is stored in
* an external file, the value will be HADDR_UNDEF. */
- f = H5D_get_file(dset);
- base_addr = H5F_get_base_addr(f);
-
- /* If there's user block in file, returns the absolute dataset offset
- * from the beginning of file. */
- if(base_addr != HADDR_UNDEF)
- ret_value = dset->shared->layout.u.contig.addr + base_addr;
- else
- ret_value = dset->shared->layout.u.contig.addr;
+ if(dset->shared->dcpl_cache.efl.nused == 0 || H5F_addr_defined(dset->shared->layout.storage.u.contig.addr))
+ /* Return the absolute dataset offset from the beginning of file. */
+ ret_value = dset->shared->layout.storage.u.contig.addr + H5F_BASE_ADDR(dset->oloc.file);
break;
default:
@@ -2322,9 +2089,9 @@ herr_t
H5D_set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id)
{
H5S_t *space; /* Dataset's dataspace */
- int rank; /* Dataspace # of dimensions */
- hsize_t curr_dims[H5O_LAYOUT_NDIMS]; /* Current dimension sizes */
- htri_t changed; /* Whether the dataspace changed size */
+ int rank; /* Dataspace # of dimensions */
+ hsize_t curr_dims[H5O_LAYOUT_NDIMS];/* Current dimension sizes */
+ htri_t changed; /* Whether the dataspace changed size */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_set_extent)
@@ -2334,9 +2101,15 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id)
HDassert(size);
/* Check if we are allowed to modify this file */
- if(0 == (H5F_get_intent(dset->oloc.file) & H5F_ACC_RDWR))
- HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "no write intent on file")
-
+ if(0 == (H5F_INTENT(dset->oloc.file) & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "no write intent on file")
+
+ /* Check if we are allowed to modify the space; only datasets with chunked and external storage are allowed to be modified */
+ if(H5D_COMPACT == dset->shared->layout.type)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "dataset has compact storage")
+ if(H5D_CONTIGUOUS == dset->shared->layout.type && 0 == dset->shared->dcpl_cache.efl.nused)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "dataset has contiguous storage")
+
/* Check if the filters in the DCPL will need to encode, and if so, can they? */
if(H5D_check_filters(dset) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't apply filters")
@@ -2346,11 +2119,11 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id)
/* Check if we are shrinking or expanding any of the dimensions */
if((rank = H5S_get_simple_extent_dims(space, curr_dims, NULL)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset dimensions")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset dimensions")
/* Modify the size of the data space */
if((changed = H5S_set_extent(space, size)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space")
/* Don't bother updating things, unless they've changed */
if(changed) {
@@ -2371,11 +2144,14 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id)
*-------------------------------------------------------------------------
*/
/* Update the index values for the cached chunks for this dataset */
- if(H5D_CHUNKED == dset->shared->layout.type)
+ if(H5D_CHUNKED == dset->shared->layout.type) {
+ if(H5D_chunk_set_info(dset) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to update # of chunks")
if(H5D_chunk_update_cache(dset, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update cached chunk indices")
+ } /* end if */
- /* Allocate space for the new parts of the dataset, if appropriate */
+ /* Allocate space for the new parts of the dataset, if appropriate */
if(expand && dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_EARLY)
if(H5D_alloc_storage(dset, dxpl_id, H5D_ALLOC_EXTEND, FALSE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset storage")
@@ -2384,13 +2160,15 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id)
/*-------------------------------------------------------------------------
* Remove chunk information in the case of chunked datasets
* This removal takes place only in case we are shrinking the dateset
+ * and if the chunks are written
*-------------------------------------------------------------------------
*/
- if(shrink && H5D_CHUNKED == dset->shared->layout.type) {
- /* Remove excess chunks */
- if(H5D_chunk_prune_by_extent(dset, dxpl_id, curr_dims) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to remove chunks ")
- } /* end if */
+ if(shrink && H5D_CHUNKED == dset->shared->layout.type &&
+ (*dset->shared->layout.ops->is_space_alloc)(&dset->shared->layout.storage)) {
+ /* Remove excess chunks */
+ if(H5D_chunk_prune_by_extent(dset, dxpl_id, curr_dims) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to remove chunks ")
+ } /* end if */
/* Mark the dataspace as dirty, for later writing to the file */
dset->shared->space_dirty = TRUE;
@@ -2402,6 +2180,47 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D_flush_sieve_buf
+ *
+ * Purpose: Flush any dataset sieve buffer info cached in memory
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * July 27, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_flush_sieve_buf(H5D_t *dataset, hid_t dxpl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_flush_sieve_buf)
+
+ /* Check args */
+ HDassert(dataset);
+
+ /* Flush the raw data buffer, if we have a dirty one */
+ if(dataset->shared->cache.contig.sieve_buf && dataset->shared->cache.contig.sieve_dirty) {
+ HDassert(dataset->shared->layout.type != H5D_COMPACT); /* We should never have a sieve buffer for compact storage */
+
+ /* Write dirty data sieve buffer to file */
+ if(H5F_block_write(dataset->oloc.file, H5FD_MEM_DRAW, dataset->shared->cache.contig.sieve_loc,
+ dataset->shared->cache.contig.sieve_size, dxpl_id, dataset->shared->cache.contig.sieve_buf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed")
+
+ /* Reset sieve buffer dirty flag */
+ dataset->shared->cache.contig.sieve_dirty = FALSE;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_flush_sieve_buf() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_flush_real
*
* Purpose: Flush any dataset information cached in memory
@@ -2415,7 +2234,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_flush_real(H5D_t *dataset, hid_t dxpl_id, unsigned flags)
+H5D_flush_real(H5D_t *dataset, hid_t dxpl_id)
{
H5O_t *oh = NULL; /* Pointer to dataset's object header */
herr_t ret_value = SUCCEED; /* Return value */
@@ -2430,13 +2249,13 @@ H5D_flush_real(H5D_t *dataset, hid_t dxpl_id, unsigned flags)
unsigned update_flags = H5O_UPDATE_TIME; /* Modification time flag */
/* Get a pointer to the dataset's object header */
- if((oh = H5O_protect(&dataset->oloc, dxpl_id)) == NULL)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTPROTECT, FAIL, "unable to protect dataset object header")
+ if(NULL == (oh = H5O_pin(&dataset->oloc, dxpl_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header")
/* Update the layout on disk, if it's been changed */
if(dataset->shared->layout_dirty) {
- if(H5O_msg_write_oh(dataset->oloc.file, dxpl_id, oh, H5O_LAYOUT_ID, H5O_MSG_FLAG_CONSTANT, update_flags, &dataset->shared->layout) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update layout message")
+ if(H5D_layout_oh_write(dataset, dxpl_id, oh, update_flags) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update layout/pline/efl info")
dataset->shared->layout_dirty = FALSE;
/* Reset the "update the modification time" flag, so we only do it once */
@@ -2457,50 +2276,16 @@ H5D_flush_real(H5D_t *dataset, hid_t dxpl_id, unsigned flags)
HDassert(update_flags == 0);
} /* end if */
- /* Flush the raw data buffer, if we have a dirty one */
- if(dataset->shared->cache.contig.sieve_buf && dataset->shared->cache.contig.sieve_dirty) {
- HDassert(dataset->shared->layout.type != H5D_COMPACT); /* We should never have a sieve buffer for compact storage */
-
- /* Write dirty data sieve buffer to file */
- if(H5F_block_write(dataset->oloc.file, H5FD_MEM_DRAW, dataset->shared->cache.contig.sieve_loc,
- dataset->shared->cache.contig.sieve_size, dxpl_id, dataset->shared->cache.contig.sieve_buf) < 0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed")
-
- /* Reset sieve buffer dirty flag */
- dataset->shared->cache.contig.sieve_dirty = FALSE;
- } /* end if */
-
- /* Flush cached information for each kind of dataset */
- switch(dataset->shared->layout.type) {
- case H5D_CONTIGUOUS:
- break;
-
- case H5D_CHUNKED:
- /* Flush the raw data cache */
- if(H5D_chunk_flush(dataset, dxpl_id, flags & H5F_FLUSH_INVALIDATE) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush raw data cache")
- break;
-
- case H5D_COMPACT:
- if(dataset->shared->layout.u.compact.dirty) {
- if(H5O_msg_write(&(dataset->oloc), H5O_LAYOUT_ID, 0, H5O_UPDATE_TIME, &(dataset->shared->layout), dxpl_id) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update layout message")
- dataset->shared->layout.u.compact.dirty = FALSE;
- } /* end if */
- break;
-
- default:
- HDassert("not implemented yet" && 0);
-#ifdef NDEBUG
- HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout")
-#endif /* NDEBUG */
- } /* end switch */ /*lint !e788 All appropriate cases are covered */
+ /* Flush cached raw data for each kind of dataset layout */
+ if(dataset->shared->layout.ops->flush &&
+ (dataset->shared->layout.ops->flush)(dataset, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to flush raw data")
done:
/* Release pointer to object header */
if(oh != NULL)
- if(H5O_unprotect(&(dataset->oloc), oh) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CANTUNPROTECT, FAIL, "unable to unprotect dataset object header")
+ if(H5O_unpin(&(dataset->oloc), oh) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_flush_real() */
@@ -2534,7 +2319,7 @@ H5D_flush_cb(void *_dataset, hid_t UNUSED id, void *_udata)
/* Check for dataset in same file */
if(udata->f == dataset->oloc.file) {
/* Flush the dataset's information */
- if(H5D_flush_real(dataset, udata->dxpl_id, udata->flags) < 0)
+ if(H5D_flush_real(dataset, udata->dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, H5_ITER_ERROR, "unable to flush cached dataset info")
} /* end if */
@@ -2557,7 +2342,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D_flush(const H5F_t *f, hid_t dxpl_id, unsigned flags)
+H5D_flush(const H5F_t *f, hid_t dxpl_id)
{
H5D_flush_ud_t udata; /* User data for callback */
herr_t ret_value = SUCCEED; /* Return value */
@@ -2570,10 +2355,9 @@ H5D_flush(const H5F_t *f, hid_t dxpl_id, unsigned flags)
/* Set user data for callback */
udata.f = f;
udata.dxpl_id = dxpl_id;
- udata.flags = flags;
/* Iterate over all the open datasets */
- H5I_search(H5I_DATASET, H5D_flush_cb, &udata);
+ H5I_search(H5I_DATASET, H5D_flush_cb, &udata, FALSE);
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Dio.c b/src/H5Dio.c
index 2323eae..5723847 100644
--- a/src/H5Dio.c
+++ b/src/H5Dio.c
@@ -66,8 +66,7 @@ static herr_t H5D_typeinfo_init(const H5D_t *dset, const H5D_dxpl_cache_t *dxpl_
H5D_type_info_t *type_info);
#ifdef H5_HAVE_PARALLEL
static herr_t H5D_ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset,
- const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id,
- const H5S_t *file_space, const H5S_t *mem_space,
+ hid_t dxpl_id, const H5S_t *file_space, const H5S_t *mem_space,
const H5D_type_info_t *type_info, const H5D_chunk_map_t *fm);
static herr_t H5D_ioinfo_term(H5D_io_info_t *io_info);
#endif /* H5_HAVE_PARALLEL */
@@ -160,13 +159,13 @@ H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
else
if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_XFER))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
- if(!buf && H5S_GET_SELECT_NPOINTS(file_space) != 0)
+ if(!buf && (NULL == file_space || H5S_GET_SELECT_NPOINTS(file_space) != 0))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer")
/* If the buffer is nil, and 0 element is selected, make a fake buffer.
- * This is for some MPI package like ChaMPIon on NCSA's tungsten which
- * doesn't support this feature.
- */
+ * This is for some MPI package like ChaMPIon on NCSA's tungsten which
+ * doesn't support this feature.
+ */
if(!buf)
buf = &fake_char;
@@ -252,13 +251,13 @@ H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
else
if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
- if(!buf && H5S_GET_SELECT_NPOINTS(file_space) != 0)
+ if(!buf && (NULL == file_space || H5S_GET_SELECT_NPOINTS(file_space) != 0))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer")
-
+
/* If the buffer is nil, and 0 element is selected, make a fake buffer.
- * This is for some MPI package like ChaMPIon on NCSA's tungsten which
- * doesn't support this feature.
- */
+ * This is for some MPI package like ChaMPIon on NCSA's tungsten which
+ * doesn't support this feature.
+ */
if(!buf)
buf = &fake_char;
@@ -313,7 +312,7 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
if(!mem_space)
mem_space = file_space;
if((snelmts = H5S_GET_SELECT_NPOINTS(mem_space)) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dst dataspace has invalid selection")
H5_ASSIGN_OVERFLOW(nelmts,snelmts,hssize_t,hsize_t);
/* Fill the DXPL cache values for later use */
@@ -351,8 +350,7 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
* has been overwritten. So just proceed in reading.
*/
if(nelmts > 0 && dataset->shared->dcpl_cache.efl.nused == 0 &&
- ((dataset->shared->layout.type == H5D_CONTIGUOUS && !H5F_addr_defined(dataset->shared->layout.u.contig.addr))
- || (dataset->shared->layout.type == H5D_CHUNKED && !H5F_addr_defined(dataset->shared->layout.u.chunk.addr)))) {
+ !(*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage)) {
H5D_fill_value_t fill_status; /* Whether/How the fill value is defined */
/* Retrieve dataset's fill-value properties */
@@ -386,8 +384,7 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
/* Sanity check that space is allocated, if there are elements */
if(nelmts > 0)
- HDassert(((dataset->shared->layout.type == H5D_CONTIGUOUS && H5F_addr_defined(dataset->shared->layout.u.contig.addr))
- || (dataset->shared->layout.type == H5D_CHUNKED && H5F_addr_defined(dataset->shared->layout.u.chunk.addr)))
+ HDassert((*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage)
|| dataset->shared->dcpl_cache.efl.nused > 0
|| dataset->shared->layout.type == H5D_COMPACT);
@@ -398,7 +395,7 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
#ifdef H5_HAVE_PARALLEL
/* Adjust I/O info for any parallel I/O */
- if(H5D_ioinfo_adjust(&io_info, dataset, dxpl_cache, dxpl_id, file_space, mem_space, &type_info, &fm) < 0)
+ if(H5D_ioinfo_adjust(&io_info, dataset, dxpl_id, file_space, mem_space, &type_info, &fm) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to adjust I/O info for parallel I/O")
#endif /*H5_HAVE_PARALLEL*/
@@ -488,7 +485,7 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
/* If MPI based VFD is used, no VL datatype support yet. */
/* This is because they use the global heap in the file and we don't */
/* support parallel access of that yet */
- if(H5T_detect_class(type_info.mem_type, H5T_VLEN) > 0)
+ if(H5T_detect_class(type_info.mem_type, H5T_VLEN, FALSE) > 0)
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "Parallel IO does not support writing VL datatypes yet")
/* If MPI based VFD is used, no VL datatype support yet. */
@@ -537,8 +534,7 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
/* Allocate data space and initialize it if it hasn't been. */
if(nelmts > 0 && dataset->shared->dcpl_cache.efl.nused == 0 &&
- ((dataset->shared->layout.type == H5D_CONTIGUOUS && !H5F_addr_defined(dataset->shared->layout.u.contig.addr))
- || (dataset->shared->layout.type == H5D_CHUNKED && !H5F_addr_defined(dataset->shared->layout.u.chunk.addr)))) {
+ !(*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage)) {
hssize_t file_nelmts; /* Number of elements in file dataset's dataspace */
hbool_t full_overwrite; /* Whether we are over-writing all the elements */
@@ -547,10 +543,10 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "can't retrieve number of elements in file dataset")
/* Always allow fill values to be written if the dataset has a VL datatype */
- if(H5T_detect_class(dataset->shared->type, H5T_VLEN))
+ if(H5T_detect_class(dataset->shared->type, H5T_VLEN, FALSE))
full_overwrite = FALSE;
else
- full_overwrite = (hsize_t)file_nelmts == nelmts ? TRUE : FALSE;
+ full_overwrite = (hbool_t)((hsize_t)file_nelmts == nelmts ? TRUE : FALSE);
/* Allocate storage */
if(H5D_alloc_storage(dataset, dxpl_id, H5D_ALLOC_WRITE, full_overwrite) < 0)
@@ -573,7 +569,7 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
#ifdef H5_HAVE_PARALLEL
/* Adjust I/O info for any parallel I/O */
- if(H5D_ioinfo_adjust(&io_info, dataset, dxpl_cache, dxpl_id, file_space, mem_space, &type_info, &fm) < 0)
+ if(H5D_ioinfo_adjust(&io_info, dataset, dxpl_id, file_space, mem_space, &type_info, &fm) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to adjust I/O info for parallel I/O")
#endif /*H5_HAVE_PARALLEL*/
@@ -701,7 +697,7 @@ H5D_typeinfo_init(const H5D_t *dset, const H5D_dxpl_cache_t *dxpl_cache,
{
const H5T_t *src_type; /* Source datatype */
const H5T_t *dst_type; /* Destination datatype */
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_typeinfo_init)
@@ -710,7 +706,7 @@ H5D_typeinfo_init(const H5D_t *dset, const H5D_dxpl_cache_t *dxpl_cache,
HDassert(dset);
/* Initialize type info safely */
- HDmemset(type_info, 0, sizeof(H5D_type_info_t));
+ HDmemset(type_info, 0, sizeof(*type_info));
/* Get the memory & dataset datatypes */
if(NULL == (type_info->mem_type = (const H5T_t *)H5I_object_verify(mem_type_id, H5I_DATATYPE)))
@@ -748,7 +744,7 @@ H5D_typeinfo_init(const H5D_t *dset, const H5D_dxpl_cache_t *dxpl_cache,
type_info->is_conv_noop = H5T_path_noop(type_info->tpath);
type_info->is_xform_noop = H5Z_xform_noop(dxpl_cache->data_xform_prop);
if(type_info->is_xform_noop && type_info->is_conv_noop) {
- type_info->cmpd_subset = H5T_SUBSET_FALSE;
+ type_info->cmpd_subset = NULL;
type_info->need_bkg = H5T_BKG_NO;
} /* end if */
else {
@@ -758,7 +754,7 @@ H5D_typeinfo_init(const H5D_t *dset, const H5D_dxpl_cache_t *dxpl_cache,
type_info->cmpd_subset = H5T_path_compound_subset(type_info->tpath);
/* Check if we need a background buffer */
- if(do_write && H5T_detect_class(dset->shared->type, H5T_VLEN))
+ if(do_write && H5T_detect_class(dset->shared->type, H5T_VLEN, FALSE))
type_info->need_bkg = H5T_BKG_YES;
else {
H5T_bkg_t path_bkg; /* Type conversion's background info */
@@ -783,8 +779,8 @@ H5D_typeinfo_init(const H5D_t *dset, const H5D_dxpl_cache_t *dxpl_cache,
hbool_t default_buffer_info; /* Whether the buffer information are the defaults */
/* Detect if we have all default settings for buffers */
- default_buffer_info = (H5D_TEMP_BUF_SIZE == dxpl_cache->max_temp_buf)
- && (NULL == dxpl_cache->tconv_buf) && (NULL == dxpl_cache->bkgr_buf);
+ default_buffer_info = (hbool_t)((H5D_TEMP_BUF_SIZE == dxpl_cache->max_temp_buf)
+ && (NULL == dxpl_cache->tconv_buf) && (NULL == dxpl_cache->bkgr_buf));
/* Check if we are using the default buffer info */
if(default_buffer_info)
@@ -851,8 +847,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset,
- const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id,
+H5D_ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset, hid_t dxpl_id,
const H5S_t *file_space, const H5S_t *mem_space,
const H5D_type_info_t *type_info, const H5D_chunk_map_t *fm)
{
diff --git a/src/H5Dlayout.c b/src/H5Dlayout.c
new file mode 100644
index 0000000..d6b7619
--- /dev/null
+++ b/src/H5Dlayout.c
@@ -0,0 +1,466 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5D_PACKAGE /*suppress error about including H5Dpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Dpkg.h" /* Datasets */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5HLprivate.h" /* Local heaps */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_layout_set_io_ops
+ *
+ * Purpose: Set the I/O operation function pointers for a dataset,
+ * according to the dataset's layout
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, March 20, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_layout_set_io_ops(const H5D_t *dataset)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5D_layout_set_io_ops, FAIL)
+
+ /* check args */
+ HDassert(dataset);
+
+ /* Set the I/O functions for each layout type */
+ switch(dataset->shared->layout.type) {
+ case H5D_CONTIGUOUS:
+ if(dataset->shared->dcpl_cache.efl.nused > 0)
+ dataset->shared->layout.ops = H5D_LOPS_EFL;
+ else
+ dataset->shared->layout.ops = H5D_LOPS_CONTIG;
+ break;
+
+ case H5D_CHUNKED:
+ dataset->shared->layout.ops = H5D_LOPS_CHUNK;
+
+ /* Set the chunk operations */
+ /* (Only "B-tree" indexing type currently supported) */
+ dataset->shared->layout.storage.u.chunk.ops = H5D_COPS_BTREE;
+ break;
+
+ case H5D_COMPACT:
+ dataset->shared->layout.ops = H5D_LOPS_COMPACT;
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unknown storage method")
+ } /* end switch */ /*lint !e788 All appropriate cases are covered */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_layout_set_io_ops() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_layout_meta_size
+ *
+ * Purpose: Returns the size of the raw message in bytes except raw data
+ * part for compact dataset. This function doesn't take into
+ * account message alignment.
+ *
+ * Return: Success: Message data size in bytes
+ * Failure: 0
+ *
+ * Programmer: Raymond Lu
+ * August 14, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5D_layout_meta_size(const H5F_t *f, const H5O_layout_t *layout, hbool_t include_compact_data)
+{
+ size_t ret_value;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_layout_meta_size)
+
+ /* check args */
+ HDassert(f);
+ HDassert(layout);
+
+ ret_value = 1 + /* Version number */
+ 1; /* layout class type */
+
+ switch(layout->type) {
+ case H5D_COMPACT:
+ /* Size of raw data */
+ ret_value += 2;
+ if(include_compact_data)
+ ret_value += layout->storage.u.compact.size;/* data for compact dataset */
+ break;
+
+ case H5D_CONTIGUOUS:
+ ret_value += H5F_SIZEOF_ADDR(f); /* Address of data */
+ ret_value += H5F_SIZEOF_SIZE(f); /* Length of data */
+ break;
+
+ case H5D_CHUNKED:
+ /* Number of dimensions (1 byte) */
+ HDassert(layout->u.chunk.ndims > 0 && layout->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
+ ret_value++;
+
+ /* Dimension sizes */
+ ret_value += layout->u.chunk.ndims * 4;
+
+ /* B-tree address */
+ ret_value += H5F_SIZEOF_ADDR(f); /* Address of data */
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, 0, "Invalid layout class")
+ } /* end switch */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_layout_meta_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_layout_oh_create
+ *
+ * Purpose: Create layout/pline/efl information for dataset
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, July 27, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_layout_oh_create(H5F_t *file, hid_t dxpl_id, H5O_t *oh, H5D_t *dset,
+ hid_t dapl_id)
+{
+ H5O_layout_t *layout; /* Dataset's layout information */
+ const H5O_fill_t *fill_prop; /* Pointer to dataset's fill value information */
+ hbool_t layout_init = FALSE; /* Flag to indicate that chunk information was initialized */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_layout_oh_create)
+
+ /* Sanity checking */
+ HDassert(file);
+ HDassert(oh);
+ HDassert(dset);
+
+ /* Set some local variables, for convenience */
+ layout = &dset->shared->layout;
+ fill_prop = &dset->shared->dcpl_cache.fill;
+
+ /* Update the filters message, if this is a chunked dataset */
+ if(layout->type == H5D_CHUNKED) {
+ H5O_pline_t *pline; /* Dataset's I/O pipeline information */
+
+ pline = &dset->shared->dcpl_cache.pline;
+ if(pline->nused > 0 && H5O_msg_append_oh(file, dxpl_id, oh, H5O_PLINE_ID, H5O_MSG_FLAG_CONSTANT, 0, pline) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update filter header message")
+ } /* end if */
+
+ /* Initialize the layout information for the new dataset */
+ if(dset->shared->layout.ops->init && (dset->shared->layout.ops->init)(file, dxpl_id, dset, dapl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize layout information")
+
+ /* Indicate that the layout information was initialized */
+ layout_init = TRUE;
+
+ /*
+ * Allocate storage if space allocate time is early; otherwise delay
+ * allocation until later.
+ */
+ if(fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY)
+ if(H5D_alloc_storage(dset, dxpl_id, H5D_ALLOC_CREATE, FALSE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage")
+
+ /* Update external storage message, if it's used */
+ if(dset->shared->dcpl_cache.efl.nused > 0) {
+ H5O_efl_t *efl = &dset->shared->dcpl_cache.efl; /* Dataset's external file list */
+ H5HL_t *heap; /* Pointer to local heap for EFL file names */
+ size_t heap_size = H5HL_ALIGN(1);
+ size_t u;
+
+ /* Determine size of heap needed to stored the file names */
+ for(u = 0; u < efl->nused; ++u)
+ heap_size += H5HL_ALIGN(HDstrlen(efl->slot[u].name) + 1);
+
+ /* Create the heap for the EFL file names */
+ if(H5HL_create(file, dxpl_id, heap_size, &efl->heap_addr/*out*/) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create EFL file name heap")
+
+ /* Pin the heap down in memory */
+ if(NULL == (heap = H5HL_protect(file, dxpl_id, efl->heap_addr, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTPROTECT, FAIL, "unable to protect EFL file name heap")
+
+ /* Insert "empty" name first */
+ if((size_t)(-1) == H5HL_insert(file, dxpl_id, heap, (size_t)1, "")) {
+ H5HL_unprotect(file, dxpl_id, heap, efl->heap_addr);
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert file name into heap")
+ } /* end if */
+
+ for(u = 0; u < efl->nused; ++u) {
+ size_t offset; /* Offset of file name in heap */
+
+ /* Insert file name into heap */
+ if((size_t)(-1) == (offset = H5HL_insert(file, dxpl_id, heap,
+ HDstrlen(efl->slot[u].name) + 1, efl->slot[u].name))) {
+ H5HL_unprotect(file, dxpl_id, heap, efl->heap_addr);
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert file name into heap")
+ } /* end if */
+
+ /* Store EFL file name offset */
+ HDassert(0 == efl->slot[u].name_offset);
+ efl->slot[u].name_offset = offset;
+ } /* end for */
+
+ /* Release the heap */
+ if(H5HL_unprotect(file, dxpl_id, heap, efl->heap_addr) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTUNPROTECT, FAIL, "unable to unprotect EFL file name heap")
+ heap = NULL;
+
+ /* Insert EFL message into dataset object header */
+ if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_EFL_ID, H5O_MSG_FLAG_CONSTANT, 0, efl) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update external file list message")
+ } /* end if */
+
+ /* Create layout message */
+ /* (Don't make layout message constant unless allocation time is early, since space may not be allocated) */
+ /* (Note: this is relying on H5D_alloc_storage not calling H5O_msg_write during dataset creation) */
+ if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_LAYOUT_ID, ((fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY && H5D_COMPACT != layout->type) ? H5O_MSG_FLAG_CONSTANT : 0), 0, layout) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout")
+
+done:
+ /* Error cleanup */
+ if(ret_value < 0) {
+ if(dset->shared->layout.type == H5D_CHUNKED && layout_init) {
+ if(H5D_chunk_dest(file, dxpl_id, dset) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to destroy chunk cache")
+ } /* end if */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_layout_oh_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_layout_oh_read
+ *
+ * Purpose: Read layout/pline/efl information for dataset
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, July 27, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_layout_oh_read(H5D_t *dataset, hid_t dxpl_id, hid_t dapl_id, H5P_genplist_t *plist)
+{
+ htri_t msg_exists; /* Whether a particular type of message exists */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_layout_oh_read)
+
+ /* Sanity checking */
+ HDassert(dataset);
+ HDassert(plist);
+
+ /* Get the optional filters message */
+ if((msg_exists = H5O_msg_exists(&(dataset->oloc), H5O_PLINE_ID, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check if message exists")
+ if(msg_exists) {
+ /* Retrieve the I/O pipeline message */
+ if(NULL == H5O_msg_read(&(dataset->oloc), H5O_PLINE_ID, &dataset->shared->dcpl_cache.pline, dxpl_id))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve message")
+
+ /* Set the I/O pipeline info in the property list */
+ if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &dataset->shared->dcpl_cache.pline) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set pipeline")
+ } /* end if */
+
+ /*
+ * Get the raw data layout info. It's actually stored in two locations:
+ * the storage message of the dataset (dataset->storage) and certain
+ * values are copied to the dataset create plist so the user can query
+ * them.
+ */
+ if(NULL == H5O_msg_read(&(dataset->oloc), H5O_LAYOUT_ID, &(dataset->shared->layout), dxpl_id))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data layout message")
+
+ /* Check for external file list message (which might not exist) */
+ if((msg_exists = H5O_msg_exists(&(dataset->oloc), H5O_EFL_ID, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check if message exists")
+ if(msg_exists) {
+ /* Retrieve the EFL message */
+ if(NULL == H5O_msg_read(&(dataset->oloc), H5O_EFL_ID, &dataset->shared->dcpl_cache.efl, dxpl_id))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve message")
+
+ /* Set the EFL info in the property list */
+ if(H5P_set(plist, H5D_CRT_EXT_FILE_LIST_NAME, &dataset->shared->dcpl_cache.efl) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set external file list")
+
+ /* Set the dataset's I/O operations */
+ dataset->shared->layout.ops = H5D_LOPS_EFL;
+ } /* end if */
+
+ /* Sanity check that the layout operations are set up */
+ HDassert(dataset->shared->layout.ops);
+
+ /* Adjust chunk dimensions to omit datatype size (in last dimension) for creation property */
+ if(H5D_CHUNKED == dataset->shared->layout.type)
+ dataset->shared->layout.u.chunk.ndims--;
+ /* Copy layout to the DCPL */
+ if(H5P_set(plist, H5D_CRT_LAYOUT_NAME, &dataset->shared->layout) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set layout")
+ /* Adjust chunk dimensions back again (*sigh*) */
+ if(H5D_CHUNKED == dataset->shared->layout.type)
+ dataset->shared->layout.u.chunk.ndims++;
+
+ switch(dataset->shared->layout.type) {
+ case H5D_CONTIGUOUS:
+ /* Compute the size of the contiguous storage for versions of the
+ * layout message less than version 3 because versions 1 & 2 would
+ * truncate the dimension sizes to 32-bits of information. - QAK 5/26/04
+ */
+ if(dataset->shared->layout.version < 3) {
+ hssize_t snelmts; /* Temporary holder for number of elements in dataspace */
+ hsize_t nelmts; /* Number of elements in dataspace */
+ size_t dt_size; /* Size of datatype */
+ hsize_t tmp_size; /* Temporary holder for raw data size */
+
+ /* Retrieve the number of elements in the dataspace */
+ if((snelmts = H5S_GET_EXTENT_NPOINTS(dataset->shared->space)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve number of elements in dataspace")
+ nelmts = (hsize_t)snelmts;
+
+ /* Get the datatype's size */
+ if(0 == (dt_size = H5T_GET_SIZE(dataset->shared->type)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve size of datatype")
+
+ /* Compute the size of the dataset's contiguous storage */
+ tmp_size = nelmts * dt_size;
+
+ /* Check for overflow during multiplication */
+ if(nelmts != (tmp_size / dt_size))
+ HGOTO_ERROR(H5E_DATASET, H5E_OVERFLOW, FAIL, "size of dataset's storage overflowed")
+
+ /* Assign the dataset's contiguous storage size */
+ dataset->shared->layout.storage.u.contig.size = tmp_size;
+ } /* end if */
+
+ /* Get the sieve buffer size for this dataset */
+ dataset->shared->cache.contig.sieve_buf_size = H5F_SIEVE_BUF_SIZE(dataset->oloc.file);
+ break;
+
+ case H5D_CHUNKED:
+ /* Initialize the chunk cache for the dataset */
+ if(H5D_chunk_init(dataset->oloc.file, dxpl_id, dataset, dapl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize chunk cache")
+ break;
+
+ case H5D_COMPACT:
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unknown storage method")
+ } /* end switch */ /*lint !e788 All appropriate cases are covered */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_layout_oh_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_layout_oh_write
+ *
+ * Purpose: Read layout/pline/efl information for dataset
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, July 27, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_layout_oh_write(H5D_t *dataset, hid_t dxpl_id, H5O_t *oh, unsigned update_flags)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_layout_oh_write)
+
+ /* Sanity checking */
+ HDassert(dataset);
+ HDassert(oh);
+
+ /* Write the layout message to the dataset's header */
+ if(H5O_msg_write_oh(dataset->oloc.file, dxpl_id, oh, H5O_LAYOUT_ID, H5O_MSG_FLAG_CONSTANT, update_flags, &dataset->shared->layout) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update layout message")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_layout_oh_write() */
+
diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c
index a87c9d3..e111404 100644
--- a/src/H5Dmpio.c
+++ b/src/H5Dmpio.c
@@ -15,7 +15,7 @@
/*
* Programmer: rky 980813
- * KY 2005 revised the code and made the change to support and optimize
+ * KY 2005 revised the code and made the change to support and optimize
* collective IO support.
* Purpose: Functions to read/write directly between app buffer and file.
*
@@ -117,8 +117,10 @@ static herr_t H5D_inter_collective_io(H5D_io_info_t *io_info,
static herr_t H5D_final_collective_io(H5D_io_info_t *io_info,
const H5D_type_info_t *type_info, size_t nelmts, MPI_Datatype *mpi_file_type,
MPI_Datatype *mpi_buf_type);
+#ifdef H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS
static herr_t H5D_sort_chunk(H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
H5D_chunk_addr_info_t chunk_addr_info_array[], int many_chunk_opt);
+#endif /* H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS */
static herr_t H5D_obtain_mpio_mode(H5D_io_info_t *io_info, H5D_chunk_map_t *fm,
H5P_genplist_t *dx_plist, uint8_t assign_io_mode[], haddr_t chunk_addr[]);
static herr_t H5D_ioinfo_xfer_mode(H5D_io_info_t *io_info, H5P_genplist_t *dx_plist,
@@ -557,10 +559,10 @@ done:
/*-------------------------------------------------------------------------
* Function: H5D_chunk_collective_io
*
- * Purpose: Routine for
- * 1) choose an IO option:
+ * Purpose: Routine for
+ * 1) choose an IO option:
* a) One collective IO defined by one MPI derived datatype to link through all chunks
- * or b) multiple chunk IOs,to do MPI-IO for each chunk, the IO mode may be adjusted
+ * or b) multiple chunk IOs,to do MPI-IO for each chunk, the IO mode may be adjusted
* due to the selection pattern for each chunk.
* For option a)
* 1. Sort the chunk address, obtain chunk info according to the sorted chunk address
@@ -572,10 +574,10 @@ done:
* 1. Use MPI_gather and MPI_Bcast to obtain information of *collective/independent/none*
* IO mode for each chunk of the selection
* 2. Depending on whether the IO mode is collective or independent or none,
- * Create either MPI derived datatype for each chunk to do collective IO or
+ * Create either MPI derived datatype for each chunk to do collective IO or
* just do independent IO or independent IO with file set view
* 3. Set up collective IO property list for collective mode
- * 4. DO IO
+ * 4. DO IO
*
* Return: Non-negative on success/Negative on failure
*
@@ -584,7 +586,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+static herr_t
H5D_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
H5D_chunk_map_t *fm)
{
@@ -595,7 +597,7 @@ H5D_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
htri_t temp_not_link_io = FALSE;
#endif
- herr_t ret_value = SUCCEED;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_collective_io)
@@ -604,7 +606,7 @@ H5D_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info
HDassert(io_info->using_mpi_vfd);
HDassert(type_info);
HDassert(fm);
-
+
/* Obtain the data transfer properties */
if(NULL == (dx_plist = H5I_object(io_info->dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
@@ -620,10 +622,10 @@ H5D_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info
int mpi_size; /* Number of processes in MPI job */
if(H5D_mpio_get_sum_chunk(io_info, fm, &sum_chunk) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSWAP, FAIL, "unable to obtain the total chunk number of all processes");
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSWAP, FAIL, "unable to obtain the total chunk number of all processes");
if((mpi_size = H5F_mpi_get_size(io_info->dset->oloc.file)) < 0)
HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi size")
-
+
one_link_chunk_io_threshold = H5P_peek_unsigned(dx_plist, H5D_XFER_MPIO_CHUNK_OPT_NUM_NAME);
/* step 1: choose an IO option */
@@ -637,10 +639,36 @@ H5D_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info
} /* end else */
#ifndef H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS
- if(io_option == H5D_ONE_LINK_CHUNK_IO)
+ if(io_option == H5D_ONE_LINK_CHUNK_IO) {
io_option = H5D_MULTI_CHUNK_IO; /* We can not do this with one chunk IO. */
- if(io_option == H5D_ONE_LINK_CHUNK_IO_MORE_OPT)
+#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
+ { int new_value;
+ htri_t check_prop;
+ check_prop = H5Pexist(io_info->dxpl_id, H5D_XFER_COLL_CHUNK_LINK_TO_MULTI);
+ if(check_prop > 0) {
+ new_value = 1;
+ if(H5Pset(io_info->dxpl_id, H5D_XFER_COLL_CHUNK_LINK_TO_MULTI, &new_value) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTSET, FAIL, "unable to set property value")
+
+ }
+ }/* add this property because the library changes the option from one link to multiple chunks.*/
+#endif
+ }
+ if(io_option == H5D_ONE_LINK_CHUNK_IO_MORE_OPT){
io_option = H5D_MULTI_CHUNK_IO_MORE_OPT;
+#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
+ { int new_value;
+ htri_t check_prop;
+ check_prop = H5Pexist(io_info->dxpl_id, H5D_XFER_COLL_CHUNK_LINK_TO_MULTI_OPT);
+ if(check_prop > 0) {
+ new_value = 1;
+ if(H5Pset(io_info->dxpl_id, H5D_XFER_COLL_CHUNK_LINK_TO_MULTI_OPT, &new_value) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTSET, FAIL, "unable to set property value")
+
+ }
+ }/* add this property because the library changes the option from one link to multiple chunks.*/
+#endif
+ }
#endif
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
@@ -777,7 +805,7 @@ done:
* 1. Sort the chunk address and chunk info
* 2. Build up MPI derived datatype for each chunk
* 3. Build up the final MPI derived datatype
- * 4. Use common collective IO routine to do MPI-IO
+ * 4. Use common collective IO routine to do MPI-IO
*
* Return: Non-negative on success/Negative on failure
*
@@ -803,25 +831,26 @@ H5D_link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type
MPI_Aint *chunk_disp_array = NULL;
MPI_Aint *chunk_mem_disp_array = NULL;
int *blocklen = NULL;
- int mpi_code; /* MPI return code */
- herr_t ret_value = SUCCEED;
-
+ int mpi_code; /* MPI return code */
+ herr_t ret_value = SUCCEED;
+
FUNC_ENTER_NOAPI_NOINIT(H5D_link_chunk_collective_io)
/* Get the sum # of chunks, if not already available */
if(sum_chunk < 0) {
if(H5D_mpio_get_sum_chunk(io_info, fm, &sum_chunk) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSWAP, FAIL, "unable to obtain the total chunk number of all processes");
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSWAP, FAIL, "unable to obtain the total chunk number of all processes");
} /* end if */
/* Retrieve total # of chunks in dataset */
- H5_ASSIGN_OVERFLOW(total_chunks, fm->total_chunks, hsize_t, size_t);
+ H5_ASSIGN_OVERFLOW(total_chunks, fm->layout->u.chunk.nchunks, hsize_t, size_t);
/* Handle special case when dataspace dimensions only allow one chunk in
* the dataset. [This sometimes is used by developers who want the
* equivalent of compressed contiguous datasets - QAK]
*/
if(total_chunks == 1) {
+ H5D_chunk_ud_t udata; /* User data for querying chunk info */
hsize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of chunk in file dataset's dataspace */
H5SL_node_t *chunk_node; /* Pointer to chunk node for selection */
H5S_t *fspace; /* Dataspace describing chunk & selection in it */
@@ -832,9 +861,10 @@ H5D_link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type
HDmemset(coords, 0, sizeof(coords));
/* Look up address of chunk */
- if(HADDR_UNDEF == (ctg_store.contig.dset_addr = H5D_chunk_get_addr(io_info->dset, io_info->dxpl_id, coords, NULL)))
+ if(H5D_chunk_get_info(io_info->dset, io_info->dxpl_id, coords, &udata) < 0)
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list")
-
+ ctg_store.contig.dset_addr = udata.addr;
+
/* Check for this process having selection in this chunk */
chunk_node = H5SL_first(fm->sel_chunks);
if(chunk_node == NULL) {
@@ -878,7 +908,7 @@ if(H5DEBUG(D))
if(H5DEBUG(D))
HDfprintf(H5DEBUG(D),"total_chunks = %Zu, num_chunk = %Zu\n", total_chunks, num_chunk);
#endif
-
+
/* Set up MPI datatype for chunks selected */
if(num_chunk) {
hsize_t mpi_mem_extra_offset; /* Extra offset for memory MPI datatype */
@@ -886,7 +916,7 @@ if(H5DEBUG(D))
size_t mpi_mem_count; /* Memory MPI datatype count */
size_t mpi_file_count; /* File MPI datatype count */
hbool_t locl_mbt_is_derived = FALSE, /* Whether the buffer (memory) type is derived and needs to be free'd */
- local_mft_is_derived = FALSE; /* Whether the file type is derived and needs to be free'd */
+ local_mft_is_derived = FALSE; /* Whether the file type is derived and needs to be free'd */
int blocklen_value; /* Placeholder for array fill */
/* Allocate chunking information */
@@ -910,7 +940,7 @@ if(H5DEBUG(D))
HDfprintf(H5DEBUG(D),"after sorting the chunk address \n");
#endif
- /* Obtain MPI derived datatype from all individual chunks */
+ /* Obtain MPI derived datatype from all individual chunks */
for(u = 0; u < num_chunk; u++) {
/* Disk MPI derived datatype */
if(H5S_mpio_space_type(chunk_addr_info_array[u].chunk_info.fspace,
@@ -923,10 +953,13 @@ if(H5DEBUG(D))
type_info->dst_type_size, &chunk_mtype[u], &mpi_mem_count,
&mpi_mem_extra_offset, &locl_mbt_is_derived) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create MPI buf type")
-
+
/* Chunk address relative to the first chunk */
chunk_addr_info_array[u].chunk_addr -= ctg_store.contig.dset_addr;
- H5_ASSIGN_OVERFLOW(chunk_disp_array[u], chunk_addr_info_array[u].chunk_addr, haddr_t, MPI_Aint);
+
+ /* Assign chunk address to MPI displacement */
+ /* (assume MPI_Aint big enough to hold it) */
+ chunk_disp_array[u] = (MPI_Aint)chunk_addr_info_array[u].chunk_addr;
} /* end for */
/* Initialize the buffer with the constant value 1 */
@@ -964,7 +997,7 @@ if(H5DEBUG(D))
total_chunk_addr_array = H5MM_malloc(sizeof(haddr_t) * total_chunks);
/* Retrieve chunk address map */
- if(H5D_chunk_addrmap(io_info, total_chunk_addr_array, fm->down_chunks) < 0)
+ if(H5D_chunk_addrmap(io_info, total_chunk_addr_array) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address")
/* Get chunk with lowest address */
@@ -977,7 +1010,7 @@ if(H5DEBUG(D))
/* Set the MPI datatype */
chunk_final_ftype = MPI_BYTE;
chunk_final_mtype = MPI_BYTE;
-
+
/* buffer, file derived datatypes should be true */
mpi_buf_count = (size_t)0;
} /* end else */
@@ -1033,7 +1066,7 @@ if(H5DEBUG(D))
* 1. Use MPI_gather and MPI_Bcast to obtain IO mode in each chunk(collective/independent/none)
* 2. Depending on whether the IO mode is collective or independent or none,
* Create either MPI derived datatype for each chunk or just do independent IO
- * 3. Use common collective IO routine to do MPI-IO
+ * 3. Use common collective IO routine to do MPI-IO
*
* Return: Non-negative on success/Negative on failure
*
@@ -1042,11 +1075,10 @@ if(H5DEBUG(D))
*
*-------------------------------------------------------------------------
*/
-static herr_t
+static herr_t
H5D_multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
H5D_chunk_map_t *fm, H5P_genplist_t *dx_plist)
{
- H5D_t *dataset = io_info->dset;/* Local pointer to dataset info */
H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
H5D_io_info_t cpt_io_info; /* Compact I/O info object */
@@ -1062,7 +1094,7 @@ H5D_multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *typ
int mpi_rank;
#endif
size_t u; /* Local index variable */
- herr_t ret_value = SUCCEED;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5D_multi_chunk_collective_io)
@@ -1071,7 +1103,7 @@ H5D_multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *typ
#endif
/* Retrieve total # of chunks in dataset */
- H5_ASSIGN_OVERFLOW(total_chunk, fm->total_chunks, hsize_t, size_t);
+ H5_ASSIGN_OVERFLOW(total_chunk, fm->layout->u.chunk.nchunks, hsize_t, size_t);
HDassert(total_chunk != 0);
/* Allocate memories */
@@ -1083,7 +1115,7 @@ if(H5DEBUG(D))
#endif
/* Obtain IO option for each chunk */
- if(H5D_obtain_mpio_mode(io_info, fm, dx_plist, chunk_io_option, chunk_addr) < 0)
+ if(H5D_obtain_mpio_mode(io_info, fm, dx_plist, chunk_io_option, chunk_addr) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTRECV, FAIL, "unable to obtain MPIO mode")
/* Set up contiguous I/O info object */
@@ -1127,7 +1159,7 @@ if(H5DEBUG(D))
store.chunk.index = chunk_info->index;
} /* end if */
- /* Collective IO for this chunk,
+ /* Collective IO for this chunk,
* Note: even there is no selection for this process, the process still
* needs to contribute MPI NONE TYPE.
*/
@@ -1136,7 +1168,7 @@ if(H5DEBUG(D))
if(H5DEBUG(D))
HDfprintf(H5DEBUG(D),"inside collective chunk IO mpi_rank = %d, chunk index = %Zu\n", mpi_rank, u);
#endif
-
+
/* Set the file & memory dataspaces */
if(chunk_info) {
fspace = chunk_info->fspace;
@@ -1157,7 +1189,7 @@ if(H5DEBUG(D))
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't switch to collective I/O")
last_coll_opt_mode = H5FD_MPIO_COLLECTIVE_IO;
} /* end if */
-
+
/* Initialize temporary contiguous storage address */
ctg_store.contig.dset_addr = chunk_addr[u];
@@ -1170,7 +1202,7 @@ if(H5DEBUG(D))
if(H5DEBUG(D))
HDfprintf(H5DEBUG(D),"inside independent IO mpi_rank = %d, chunk index = %Zu\n", mpi_rank, u);
#endif
-
+
HDassert(chunk_io_option[u] == 0);
#if !defined(H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS) || !defined(H5_MPI_SPECIAL_COLLECTIVE_IO_WORKS)
@@ -1181,7 +1213,7 @@ if(H5DEBUG(D))
void *chunk; /* Pointer to the data chunk in cache */
uint32_t accessed_bytes; /* Total accessed size in a chunk */
unsigned idx_hint = 0; /* Cache index hint */
- haddr_t caddr; /* Address of the cached chunk */
+ htri_t cacheable; /* Whether the chunk is cacheable */
/* Switch to independent I/O */
if(last_xfer_mode != H5FD_MPIO_INDEPENDENT) {
@@ -1193,11 +1225,14 @@ if(H5DEBUG(D))
/* Load the chunk into cache. But if the whole chunk is written,
* simply allocate space instead of load the chunk.
*/
- if(HADDR_UNDEF == (caddr = H5D_chunk_get_addr(io_info->dset, io_info->dxpl_id, chunk_info->coords, &udata)))
+ if(H5D_chunk_get_info(io_info->dset, io_info->dxpl_id, chunk_info->coords, &udata) < 0)
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list")
/* Load the chunk into cache and lock it. */
- if(H5D_chunk_cacheable(io_info, caddr)) {
+ if((cacheable = H5D_chunk_cacheable(io_info, udata.addr,
+ io_info->op_type == H5D_IO_OP_WRITE)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable")
+ if(cacheable) {
hbool_t entire_chunk = TRUE; /* Whether whole chunk is selected */
/* Compute # of bytes accessed in chunk */
@@ -1220,7 +1255,7 @@ if(H5DEBUG(D))
} /* end if */
else {
/* Set up the storage address information for this chunk */
- ctg_store.contig.dset_addr = caddr;
+ ctg_store.contig.dset_addr = udata.addr;
/* No chunk cached */
chunk = NULL;
@@ -1241,7 +1276,7 @@ if(H5DEBUG(D))
} /* end else */
/* Release the cache lock on the chunk. */
- if(chunk && H5D_chunk_unlock(io_info, (io_info->op_type == H5D_IO_OP_WRITE), idx_hint, chunk, accessed_bytes) < 0)
+ if(chunk && H5D_chunk_unlock(io_info, &udata, (io_info->op_type == H5D_IO_OP_WRITE), idx_hint, chunk, accessed_bytes) < 0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
} /* end if */
#else /* !defined(H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS) || !defined(H5_MPI_SPECIAL_COLLECTIVE_IO_WORKS) */
@@ -1296,14 +1331,14 @@ done:
* to replace the independent IO when we find this chunk is not good to
* do collective IO. However, according to our performance study,
* this approach may not overcome the overhead caused by MPI gather/scatter.
- * So we decide to leave the original collective IO per chunk approach as
+ * So we decide to leave the original collective IO per chunk approach as
* an option for users. NO MPI gather/scatter calls are used.
* HDF5 will try to collective IO if possible.
- * If users choose to use
+ * If users choose to use
* H5Pset_dxpl_mpio_chunk_opt(dxpl_id,H5FD_MPIO_OPT_MULTI_IO),
- * this function will be called.
- * The HDF5 library won't do any IO management but leave it to MPI-IO to figure
- * out.
+ * this function will be called.
+ * The HDF5 library won't do any IO management but leave it to MPI-IO to figure
+ * out.
*
* Return: Non-negative on success/Negative on failure
*
@@ -1312,11 +1347,10 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+static herr_t
H5D_multi_chunk_collective_io_no_opt(H5D_io_info_t *io_info,
const H5D_type_info_t *type_info, H5D_chunk_map_t *fm, H5P_genplist_t *dx_plist)
{
- H5D_t *dataset = io_info->dset;/* Local pointer to dataset info */
H5SL_node_t *chunk_node; /* Current node in chunk skip list */
H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
@@ -1326,7 +1360,7 @@ H5D_multi_chunk_collective_io_no_opt(H5D_io_info_t *io_info,
int min_chunk = -1; /* Minimum # of chunks all processes will operate on */
int count_chunk; /* How many chunks have we operated on? */
H5D_storage_t store; /* union of EFL and chunk pointer in file space */
- herr_t ret_value = SUCCEED;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5D_multi_chunk_collective_io_no_opt)
@@ -1335,8 +1369,8 @@ if(H5DEBUG(D)) {
int mpi_rank;
mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file);
- HDfprintf(H5DEBUG(D), "coming to multi_chunk_collective_io_no_opt\n");
-}
+ HDfprintf(H5DEBUG(D), "Rank %d: coming to multi_chunk_collective_io_no_opt\n", mpi_rank);
+}
#endif
/* Set up contiguous I/O info object */
@@ -1370,7 +1404,6 @@ if(H5DEBUG(D)) {
/* Iterate through chunks to be operated on */
while(chunk_node) {
H5D_chunk_info_t *chunk_info; /* chunk information */
- haddr_t chunk_addr; /* Address of chunk in file */
H5D_chunk_ud_t udata; /* B-tree pass-through */
hbool_t make_ind, make_coll; /* Flags to indicate that the MPI mode should change */
@@ -1383,7 +1416,7 @@ if(H5DEBUG(D)) {
/* Reset flags for changing parallel I/O mode */
make_ind = make_coll = FALSE;
-
+
count_chunk++;
/* If the number of chunk is greater than minimum number of chunk,
@@ -1396,7 +1429,7 @@ if(H5DEBUG(D)) {
/* This case needs to be improved to check if the selected space
is regular. If all selections are regular, collective IO can still be done.
However, since we find an MPI-IO bug at a DOE machine(mcr) that cannot
- handle collective I/O selection for this case correctly,
+ handle collective I/O selection for this case correctly,
we turn off this optimization but leave the following code
for future optimization. Otherwise, the following else {} doesn't make sense.
KY 2006/8/4/ */
@@ -1408,22 +1441,26 @@ if(H5DEBUG(D)) {
#endif /* H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS */
/* Retrieve the chunk's address */
- if(HADDR_UNDEF == (chunk_addr = H5D_chunk_get_addr(io_info->dset, io_info->dxpl_id, chunk_info->coords, &udata)))
- HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL,"couldn't get chunk info from skipped list")
+ if(H5D_chunk_get_info(io_info->dset, io_info->dxpl_id, chunk_info->coords, &udata) < 0)
+ HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list")
/* Independent I/O */
if(make_ind) {
- void *chunk; /* Pointer to the data chunk in cache */
+ void *chunk; /* Pointer to the data chunk in cache */
H5D_io_info_t *chk_io_info; /* Pointer to I/O info object for this chunk */
- uint32_t accessed_bytes = 0; /* Total accessed size in a chunk */
- unsigned idx_hint = 0; /* Cache index hint */
+ uint32_t accessed_bytes = 0; /* Total accessed size in a chunk */
+ unsigned idx_hint = 0; /* Cache index hint */
+ htri_t cacheable; /* Whether the chunk is cacheable */
/* Switch to independent I/O */
if(H5D_ioinfo_xfer_mode(io_info, dx_plist, H5FD_MPIO_INDEPENDENT) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't switch to independent I/O")
/* Load the chunk into cache and lock it. */
- if(H5D_chunk_cacheable(io_info, chunk_addr)) {
+ if((cacheable = H5D_chunk_cacheable(io_info, udata.addr,
+ io_info->op_type == H5D_IO_OP_WRITE)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable")
+ if(cacheable) {
hbool_t entire_chunk = TRUE; /* Whether whole chunk is selected */
/* Compute # of bytes accessed in chunk */
@@ -1446,7 +1483,7 @@ if(H5DEBUG(D)) {
} /* end if */
else {
/* Set up the storage address information for this chunk */
- ctg_store.contig.dset_addr = chunk_addr;
+ ctg_store.contig.dset_addr = udata.addr;
/* No chunk cached */
chunk = NULL;
@@ -1468,12 +1505,12 @@ if(H5DEBUG(D)) {
/* Release the cache lock on the chunk. */
if(chunk)
- if(H5D_chunk_unlock(io_info, (io_info->op_type == H5D_IO_OP_WRITE), idx_hint, chunk, accessed_bytes) < 0)
+ if(H5D_chunk_unlock(io_info, &udata, (io_info->op_type == H5D_IO_OP_WRITE), idx_hint, chunk, accessed_bytes) < 0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
} /* end if */
else { /*collective I/O */
/* Set up the storage address information for this chunk */
- ctg_store.contig.dset_addr = chunk_addr;
+ ctg_store.contig.dset_addr = udata.addr;
if(H5D_inter_collective_io(&ctg_io_info, type_info, chunk_info->fspace, chunk_info->mspace) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL,"couldn't finish shared collective MPI-IO")
@@ -1505,7 +1542,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+static herr_t
H5D_inter_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
const H5S_t *file_space, const H5S_t *mem_space)
{
@@ -1513,7 +1550,7 @@ H5D_inter_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info
hbool_t mbt_is_derived = FALSE;
hbool_t mft_is_derived = FALSE;
MPI_Datatype mpi_file_type, mpi_buf_type;
- int mpi_code; /* MPI return code */
+ int mpi_code; /* MPI return code */
herr_t ret_value = SUCCEED; /* return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_inter_collective_io)
@@ -1532,7 +1569,7 @@ H5D_inter_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info
} /* end if */
else {
/* For non-selection, participate with a none MPI derived datatype, the count is 0. */
- mpi_buf_type = MPI_BYTE;
+ mpi_buf_type = MPI_BYTE;
mpi_file_type = MPI_BYTE;
mpi_buf_count = (size_t)0;
mbt_is_derived = FALSE;
@@ -1576,11 +1613,10 @@ if(H5DEBUG(D))
*
*-------------------------------------------------------------------------
*/
-static herr_t
+static herr_t
H5D_final_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
size_t mpi_buf_count, MPI_Datatype *mpi_file_type, MPI_Datatype *mpi_buf_type)
{
- int mpi_code; /* MPI return code */
hbool_t plist_is_setup = FALSE; /* Whether the dxpl has been customized */
herr_t ret_value = SUCCEED;
@@ -1592,13 +1628,11 @@ H5D_final_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info
plist_is_setup = TRUE;
if(io_info->op_type == H5D_IO_OP_WRITE) {
- if((io_info->io_ops.single_write)(io_info, type_info,
- (hsize_t)mpi_buf_count, NULL, NULL) < 0)
+ if((io_info->io_ops.single_write)(io_info, type_info, (hsize_t)mpi_buf_count, NULL, NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "optimized write failed")
} /* end if */
else {
- if((io_info->io_ops.single_read)(io_info, type_info,
- (hsize_t)mpi_buf_count, NULL, NULL) < 0)
+ if((io_info->io_ops.single_read)(io_info, type_info, (hsize_t)mpi_buf_count, NULL, NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "optimized read failed")
} /* end else */
@@ -1609,12 +1643,13 @@ done:
HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to reset dxpl values")
#ifdef H5D_DEBUG
-if(H5DEBUG(D))
+if(H5DEBUG(D))
HDfprintf(H5DEBUG(D),"ret_value before leaving final_collective_io=%d\n",ret_value);
#endif
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_final_collective_io */
+#ifdef H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS
/*-------------------------------------------------------------------------
* Function: H5D_sort_chunk
@@ -1630,8 +1665,8 @@ if(H5DEBUG(D))
* Parameters:
* Input: H5D_io_info_t* io_info,
* H5D_chunk_map_t *fm(global chunk map struct)
- * Input/Output: H5D_chunk_addr_info_t chunk_addr_info_array[] : array to store chunk address and information
- * many_chunk_opt : flag to optimize the way to obtain chunk addresses
+ * Input/Output: H5D_chunk_addr_info_t chunk_addr_info_array[] : array to store chunk address and information
+ * many_chunk_opt : flag to optimize the way to obtain chunk addresses
* for many chunks
*
* Return: Non-negative on success/Negative on failure
@@ -1641,7 +1676,7 @@ if(H5DEBUG(D))
*
*-------------------------------------------------------------------------
*/
-static herr_t
+static herr_t
H5D_sort_chunk(H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
H5D_chunk_addr_info_t chunk_addr_info_array[], int sum_chunk)
{
@@ -1656,14 +1691,14 @@ H5D_sort_chunk(H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
int mpi_code; /* MPI return code */
int i; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
-
+
FUNC_ENTER_NOAPI_NOINIT(H5D_sort_chunk)
/* Retrieve # of MPI processes */
if((mpi_size = H5F_mpi_get_size(io_info->dset->oloc.file)) < 0)
HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi size")
- /* Calculate the actual threshold to obtain all chunk addresses collectively
+ /* Calculate the actual threshold to obtain all chunk addresses collectively
* The bigger this number is, the more possible the use of obtaining chunk
* address collectively.
*/
@@ -1671,13 +1706,13 @@ H5D_sort_chunk(H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
* 0, we would always want to obtain the chunk addresses individually
* for each process.
*/
- bsearch_coll_chunk_threshold = (sum_chunk * 100) / ((int)fm->total_chunks * mpi_size);
+ bsearch_coll_chunk_threshold = (sum_chunk * 100) / ((int)fm->layout->u.chunk.nchunks * mpi_size);
if((bsearch_coll_chunk_threshold > H5D_ALL_CHUNK_ADDR_THRES_COL)
&& ((sum_chunk / mpi_size) >= H5D_ALL_CHUNK_ADDR_THRES_COL_NUM))
many_chunk_opt = H5D_OBTAIN_ALL_CHUNK_ADDR_COL;
#ifdef H5D_DEBUG
-if(H5DEBUG(D))
+if(H5DEBUG(D))
HDfprintf(H5DEBUG(D), "many_chunk_opt= %d\n", many_chunk_opt);
#endif
@@ -1690,19 +1725,19 @@ if(H5DEBUG(D))
HDfprintf(H5DEBUG(D), "Coming inside H5D_OBTAIN_ALL_CHUNK_ADDR_COL\n");
#endif
/* Allocate array for chunk addresses */
- if(NULL == (total_chunk_addr_array = H5MM_malloc(sizeof(haddr_t) * (size_t)fm->total_chunks)))
+ if(NULL == (total_chunk_addr_array = H5MM_malloc(sizeof(haddr_t) * (size_t)fm->layout->u.chunk.nchunks)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory chunk address array")
/* Retrieve all the chunk addresses with process 0 */
if((mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file)) < 0)
HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi rank")
if(mpi_rank == 0) {
- if(H5D_chunk_addrmap(io_info, total_chunk_addr_array, fm->down_chunks) < 0)
+ if(H5D_chunk_addrmap(io_info, total_chunk_addr_array) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address")
} /* end if */
/* Broadcasting the MPI_IO option info. and chunk address info. */
- if(MPI_SUCCESS != (mpi_code = MPI_Bcast(total_chunk_addr_array, (int)(sizeof(haddr_t) * fm->total_chunks), MPI_BYTE, (int)0, io_info->comm)))
+ if(MPI_SUCCESS != (mpi_code = MPI_Bcast(total_chunk_addr_array, (int)(sizeof(haddr_t) * fm->layout->u.chunk.nchunks), MPI_BYTE, (int)0, io_info->comm)))
HMPI_GOTO_ERROR(FAIL, "MPI_BCast failed", mpi_code)
} /* end if */
@@ -1715,12 +1750,16 @@ if(H5DEBUG(D))
while(chunk_node) {
if(NULL == (chunk_info = H5SL_item(chunk_node)))
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL,"couldn't get chunk info from skipped list")
-
+
if(many_chunk_opt == H5D_OBTAIN_ONE_CHUNK_ADDR_IND) {
- if(HADDR_UNDEF == (chunk_addr = H5D_chunk_get_addr(io_info->dset, io_info->dxpl_id, chunk_info->coords, NULL)))
+ H5D_chunk_ud_t udata; /* User data for querying chunk info */
+
+ /* Get address of chunk */
+ if(H5D_chunk_get_info(io_info->dset, io_info->dxpl_id, chunk_info->coords, &udata) < 0)
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list")
+ chunk_addr = udata.addr;
} /* end if */
- else
+ else
chunk_addr = total_chunk_addr_array[chunk_info->index];
/* Check if chunk addresses are not in increasing order in the file */
@@ -1752,7 +1791,8 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_sort_chunk() */
-
+#endif /* H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS */
+
/*-------------------------------------------------------------------------
* Function: H5D_obtain_mpio_mode
@@ -1763,7 +1803,7 @@ done:
* Description:
*
* 1) Each process provides two piece of information for all chunks having selection
- * a) chunk index
+ * a) chunk index
* b) wheather this chunk is regular(for MPI derived datatype not working case)
*
* 2) Gather all the information to the root process
@@ -1790,22 +1830,24 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+static herr_t
H5D_obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm,
H5P_genplist_t *dx_plist, uint8_t assign_io_mode[], haddr_t chunk_addr[])
{
int total_chunks;
- unsigned percent_nproc_per_chunk,threshold_nproc_per_chunk;
+ unsigned percent_nproc_per_chunk, threshold_nproc_per_chunk;
+#if defined(H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS) && defined(H5_MPI_SPECIAL_COLLECTIVE_IO_WORKS)
H5FD_mpio_chunk_opt_t chunk_opt_mode;
- uint8_t* io_mode_info=NULL;
- uint8_t* recv_io_mode_info=NULL;
- uint8_t* mergebuf=NULL;
+#endif
+ uint8_t* io_mode_info = NULL;
+ uint8_t* recv_io_mode_info = NULL;
+ uint8_t* mergebuf = NULL;
uint8_t* tempbuf;
- H5SL_node_t* chunk_node;
+ H5SL_node_t* chunk_node;
H5D_chunk_info_t* chunk_info;
- int mpi_size,mpi_rank;
+ int mpi_size, mpi_rank;
MPI_Comm comm;
- int ic,root;
+ int ic, root;
int mpi_code;
int mem_cleanup = 0;
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
@@ -1817,7 +1859,7 @@ H5D_obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm,
FUNC_ENTER_NOAPI_NOINIT(H5D_obtain_mpio_mode)
/* Assign the rank 0 to the root */
- root = 0;
+ root = 0;
comm = io_info->comm;
/* Obtain the number of process and the current rank of the process */
@@ -1825,30 +1867,30 @@ H5D_obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm,
HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi rank")
if((mpi_size = H5F_mpi_get_size(io_info->dset->oloc.file)) < 0)
HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi size")
-
+
/* Setup parameters */
- H5_ASSIGN_OVERFLOW(total_chunks, fm->total_chunks, hsize_t, int);
+ H5_ASSIGN_OVERFLOW(total_chunks, fm->layout->u.chunk.nchunks, hsize_t, int);
percent_nproc_per_chunk = H5P_peek_unsigned(dx_plist, H5D_XFER_MPIO_CHUNK_OPT_RATIO_NAME);
#if defined(H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS) && defined(H5_MPI_SPECIAL_COLLECTIVE_IO_WORKS)
chunk_opt_mode = (H5FD_mpio_chunk_opt_t)H5P_peek_unsigned(dx_plist, H5D_XFER_MPIO_CHUNK_OPT_HARD_NAME);
if((chunk_opt_mode == H5FD_MPIO_CHUNK_MULTI_IO) || (percent_nproc_per_chunk == 0)) {
- if(H5D_chunk_addrmap(io_info, chunk_addr, fm->down_chunks) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address");
+ if(H5D_chunk_addrmap(io_info, chunk_addr) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address");
for(ic = 0; ic < total_chunks; ic++)
assign_io_mode[ic] = H5D_CHUNK_IO_MODE_COL;
HGOTO_DONE(SUCCEED)
} /* end if */
-#endif
+#endif
threshold_nproc_per_chunk = mpi_size * percent_nproc_per_chunk/100;
/* Allocate memory */
io_mode_info = (uint8_t *)H5MM_calloc(total_chunks);
mergebuf = H5MM_malloc((sizeof(haddr_t) + 1) * total_chunks);
tempbuf = mergebuf + total_chunks;
- if(mpi_rank == root)
+ if(mpi_rank == root)
recv_io_mode_info = (uint8_t *)H5MM_malloc(total_chunks * mpi_size);
-
+
mem_cleanup = 1;
/* Obtain the regularity and selection information for all chunks in this process. */
@@ -1868,7 +1910,7 @@ H5D_obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm,
#endif
chunk_node = H5SL_next(chunk_node);
} /* end while */
-
+
/*Gather all the information */
if(MPI_SUCCESS != (mpi_code = MPI_Gather(io_mode_info, total_chunks, MPI_BYTE, recv_io_mode_info, total_chunks, MPI_BYTE, root, comm)))
HMPI_GOTO_ERROR(FAIL, "MPI_Gather failed", mpi_code)
@@ -1881,7 +1923,7 @@ H5D_obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm,
int* ind_this_chunk;
#endif
- /* pre-computing: calculate number of processes and
+ /* pre-computing: calculate number of processes and
regularity of the selection occupied in each chunk */
nproc_per_chunk = (int*)H5MM_calloc(total_chunks * sizeof(int));
#if !defined(H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS) || !defined(H5_MPI_SPECIAL_COLLECTIVE_IO_WORKS)
@@ -1889,7 +1931,7 @@ H5D_obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm,
#endif
/* calculating the chunk address */
- if(H5D_chunk_addrmap(io_info, chunk_addr, fm->down_chunks) < 0) {
+ if(H5D_chunk_addrmap(io_info, chunk_addr) < 0) {
HDfree(nproc_per_chunk);
#if !defined(H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS) || !defined(H5_MPI_SPECIAL_COLLECTIVE_IO_WORKS)
HDfree(ind_this_chunk);
@@ -1956,7 +1998,7 @@ H5D_obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm,
new_value = 0;
if(H5Pset(io_info->dxpl_id, H5D_XFER_COLL_CHUNK_MULTI_RATIO_COLL_NAME, &new_value) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_UNSUPPORTED, FAIL, "unable to set property value")
-#else
+#else
for(ic = 0; ic < total_chunks; ic++) {
if(assign_io_mode[ic] == H5D_CHUNK_IO_MODE_COL) {
new_value = 0;
@@ -1985,12 +2027,12 @@ H5D_obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm,
} /* end if */
} /* end if */
#endif
-
+
done:
if(mem_cleanup) {
HDfree(io_mode_info);
HDfree(mergebuf);
- if(mpi_rank == root)
+ if(mpi_rank == root)
HDfree(recv_io_mode_info);
} /* end if */
@@ -2003,7 +2045,7 @@ H5D_cmp_chunk_addr(const void *chunk_addr_info1, const void *chunk_addr_info2)
haddr_t addr1, addr2;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_cmp_chunk_addr)
-
+
addr1 = ((const H5D_chunk_addr_info_t *)chunk_addr_info1)->chunk_addr;
addr2 = ((const H5D_chunk_addr_info_t *)chunk_addr_info2)->chunk_addr;
diff --git a/src/H5Doh.c b/src/H5Doh.c
index e99f9ee..42ec606 100644
--- a/src/H5Doh.c
+++ b/src/H5Doh.c
@@ -48,10 +48,13 @@
static void *H5O_dset_get_copy_file_udata(void);
static void H5O_dset_free_copy_file_udata(void *);
static htri_t H5O_dset_isa(H5O_t *loc);
-static hid_t H5O_dset_open(const H5G_loc_t *obj_loc, hid_t dxpl_id);
+static hid_t H5O_dset_open(const H5G_loc_t *obj_loc, hid_t lapl_id,
+ hid_t dxpl_id, hbool_t app_ref);
static void *H5O_dset_create(H5F_t *f, void *_crt_info, H5G_loc_t *obj_loc,
hid_t dxpl_id);
static H5O_loc_t *H5O_dset_get_oloc(hid_t obj_id);
+static herr_t H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
+ H5_ih_info_t *bh_info);
/*********************/
@@ -77,7 +80,8 @@ const H5O_obj_class_t H5O_OBJ_DATASET[1] = {{
H5O_dset_isa, /* "isa" message */
H5O_dset_open, /* open an object of this class */
H5O_dset_create, /* create an object of this class */
- H5O_dset_get_oloc /* get an object header location for an object */
+ H5O_dset_get_oloc, /* get an object header location for an object */
+ H5O_dset_bh_info /* get the index & heap info for an object */
}};
/* Declare a free list to manage the H5D_copy_file_ud_t struct */
@@ -151,11 +155,11 @@ H5O_dset_free_copy_file_udata(void *_udata)
H5T_close(udata->src_dtype);
/* Release copy of dataset's filter pipeline, if it was set */
- if (udata->src_pline)
- H5O_msg_free(H5O_PLINE_ID, udata->src_pline);
+ if(udata->common.src_pline)
+ H5O_msg_free(H5O_PLINE_ID, udata->common.src_pline);
/* Release space for 'copy file' user data */
- H5FL_FREE(H5D_copy_file_ud_t, udata);
+ (void)H5FL_FREE(H5D_copy_file_ud_t, udata);
FUNC_LEAVE_NOAPI_VOID
} /* end H5O_dset_free_copy_file_udata() */
@@ -219,21 +223,35 @@ done:
*-------------------------------------------------------------------------
*/
static hid_t
-H5O_dset_open(const H5G_loc_t *obj_loc, hid_t dxpl_id)
+H5O_dset_open(const H5G_loc_t *obj_loc, hid_t lapl_id, hid_t dxpl_id, hbool_t app_ref)
{
H5D_t *dset = NULL; /* Dataset opened */
+ htri_t isdapl; /* lapl_id is a dapl */
+ hid_t dapl_id; /* dapl to use to open this dataset */
hid_t ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_dset_open)
HDassert(obj_loc);
+ /* If the lapl passed in is a dapl, use it. Otherwise, use the default dapl */
+ if(lapl_id == H5P_DEFAULT)
+ isdapl = FALSE;
+ else
+ if((isdapl = H5P_isa_class(lapl_id, H5P_DATASET_ACCESS)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOMPARE, FAIL, "unable to compare property list classes")
+
+ if(isdapl)
+ dapl_id = lapl_id;
+ else
+ dapl_id = H5P_DATASET_ACCESS_DEFAULT;
+
/* Open the dataset */
- if(NULL == (dset = H5D_open(obj_loc, dxpl_id)))
+ if(NULL == (dset = H5D_open(obj_loc, dapl_id, dxpl_id)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open dataset")
/* Register an ID for the dataset */
- if((ret_value = H5I_register(H5I_DATASET, dset)) < 0)
+ if((ret_value = H5I_register(H5I_DATASET, dset, app_ref)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataset")
done:
@@ -273,7 +291,8 @@ H5O_dset_create(H5F_t *f, void *_crt_info, H5G_loc_t *obj_loc, hid_t dxpl_id)
HDassert(obj_loc);
/* Create the the dqtaset */
- if(NULL == (dset = H5D_create(f, crt_info->type_id, crt_info->space, crt_info->dcpl_id, dxpl_id)))
+ if(NULL == (dset = H5D_create(f, crt_info->type_id, crt_info->space,
+ crt_info->dcpl_id, crt_info->dapl_id, dxpl_id)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to create dataset")
/* Set up the new dataset's location */
@@ -342,13 +361,14 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info)
{
H5O_layout_t layout; /* Data storage layout message */
- herr_t ret_value = SUCCEED; /* Return value */
+ htri_t exists; /* Flag if header message of interest exists */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5O_dset_bh_info, FAIL)
+ FUNC_ENTER_NOAPI_NOINIT(H5O_dset_bh_info)
/* Sanity check */
HDassert(f);
@@ -356,13 +376,45 @@ H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info)
HDassert(bh_info);
/* Get the layout message from the object header */
- if(NULL == H5O_msg_read_real(f, dxpl_id, oh, H5O_LAYOUT_ID, &layout))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't find LAYOUT message")
+ if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_LAYOUT_ID, &layout))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't find layout message")
/* Check for chunked dataset storage */
- if((layout.type == H5D_CHUNKED) && H5F_addr_defined(layout.u.chunk.addr))
- if(H5D_chunk_bh_info(f, dxpl_id, &layout, &(bh_info->index_size)) < 0)
+ if(layout.type == H5D_CHUNKED && H5D_chunk_is_space_alloc(&layout.storage)) {
+ H5O_pline_t pline; /* I/O pipeline message */
+
+ /* Check for I/O pipeline message */
+ if((exists = H5O_msg_exists_oh(oh, H5O_PLINE_ID)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read object header")
+ else if(exists) {
+ if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_PLINE_ID, &pline))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't find I/O pipeline message")
+ } /* end else if */
+ else
+ HDmemset(&pline, 0, sizeof(pline));
+
+ if(H5D_chunk_bh_info(f, dxpl_id, &layout, &pline, &(bh_info->index_size)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't determine chunked dataset btree info")
+ } /* end if */
+
+ /* Check for External File List message in the object header */
+ if((exists = H5O_msg_exists_oh(oh, H5O_EFL_ID)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "unable to check for EFL message")
+
+ if(exists && H5D_efl_is_space_alloc(&layout.storage)) {
+ H5O_efl_t efl; /* External File List message */
+
+ /* Start with clean EFL info */
+ HDmemset(&efl, 0, sizeof(efl));
+
+ /* Get External File List message from the object header */
+ if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_EFL_ID, &efl))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't find EFL message")
+
+ /* Get size of local heap for EFL message's file list */
+ if(H5D_efl_bh_info(f, dxpl_id, &efl, &(bh_info->heap_size)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't determine EFL heap info")
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h
index 33f628d..9fde879 100644
--- a/src/H5Dpkg.h
+++ b/src/H5Dpkg.h
@@ -33,8 +33,6 @@
/* Other private headers needed by this file */
#include "H5Gprivate.h" /* Groups */
-#include "H5Oprivate.h" /* Object headers */
-#include "H5Sprivate.h" /* Dataspaces */
#include "H5SLprivate.h" /* Skip lists */
#include "H5Tprivate.h" /* Datatypes */
@@ -86,7 +84,7 @@ typedef struct H5D_type_info_t {
size_t max_type_size; /* Size of largest source/destination type */
hbool_t is_conv_noop; /* Whether the type conversion is a NOOP */
hbool_t is_xform_noop; /* Whether the data transform is a NOOP */
- H5T_subset_t cmpd_subset; /* Whether (and which) the source/destination datatypes are compound subsets of one another */
+ const H5T_subset_info_t *cmpd_subset; /* Info related to the compound subset conversion functions */
H5T_bkg_t need_bkg; /* Type of background buf needed */
size_t request_nelmts; /* Requested strip mine */
uint8_t *tconv_buf; /* Datatype conv buffer */
@@ -100,8 +98,10 @@ struct H5D_io_info_t;
struct H5D_chunk_map_t;
/* Function pointers for I/O on particular types of dataset layouts */
-typedef herr_t (*H5D_layout_new_func_t)(H5F_t *f, hid_t dxpl_id,
- H5D_t *dset, const H5P_genplist_t *dc_plist);
+typedef herr_t (*H5D_layout_construct_func_t)(H5F_t *f, H5D_t *dset);
+typedef herr_t (*H5D_layout_init_func_t)(H5F_t *f, hid_t dxpl_id, const H5D_t *dset,
+ hid_t dapl_id);
+typedef hbool_t (*H5D_layout_is_space_alloc_func_t)(const H5O_storage_t *storage);
typedef herr_t (*H5D_layout_io_init_func_t)(const struct H5D_io_info_t *io_info,
const H5D_type_info_t *type_info,
hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
@@ -118,11 +118,14 @@ typedef ssize_t (*H5D_layout_readvv_func_t)(const struct H5D_io_info_t *io_info,
typedef ssize_t (*H5D_layout_writevv_func_t)(const struct H5D_io_info_t *io_info,
size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]);
+typedef herr_t (*H5D_layout_flush_func_t)(H5D_t *dataset, hid_t dxpl_id);
typedef herr_t (*H5D_layout_io_term_func_t)(const struct H5D_chunk_map_t *cm);
/* Typedef for grouping layout I/O routines */
typedef struct H5D_layout_ops_t {
- H5D_layout_new_func_t new; /* Layout constructor for new datasets */
+ H5D_layout_construct_func_t construct; /* Layout constructor for new datasets */
+ H5D_layout_init_func_t init; /* Layout initializer for dataset */
+ H5D_layout_is_space_alloc_func_t is_space_alloc; /* Query routine to determine if storage is allocated */
H5D_layout_io_init_func_t io_init; /* I/O initialization routine */
H5D_layout_read_func_t ser_read; /* High-level I/O routine for reading data in serial */
H5D_layout_write_func_t ser_write; /* High-level I/O routine for writing data in serial */
@@ -132,6 +135,7 @@ typedef struct H5D_layout_ops_t {
#endif /* H5_HAVE_PARALLEL */
H5D_layout_readvv_func_t readvv; /* Low-level I/O routine for reading data */
H5D_layout_writevv_func_t writevv; /* Low-level I/O routine for writing data */
+ H5D_layout_flush_func_t flush; /* Low-level I/O routine for flushing raw data */
H5D_layout_io_term_func_t io_term; /* I/O shutdown routine */
} H5D_layout_ops_t;
@@ -175,6 +179,11 @@ typedef union H5D_storage_t {
} H5D_storage_t;
/* Typedef for raw data I/O operation info */
+typedef enum H5D_io_op_type_t {
+ H5D_IO_OP_READ, /* Read operation */
+ H5D_IO_OP_WRITE /* Write operation */
+} H5D_io_op_type_t;
+
typedef struct H5D_io_info_t {
H5D_t *dset; /* Pointer to dataset being operated on */
#ifndef H5_HAVE_PARALLEL
@@ -189,15 +198,12 @@ typedef struct H5D_io_info_t {
H5FD_mpio_xfer_t xfer_mode; /* Parallel transfer for this request (H5D_XFER_IO_XFER_MODE_NAME) */
H5FD_mpio_collective_opt_t coll_opt_mode; /* Parallel transfer with independent IO or collective IO with this mode */
H5D_io_ops_t io_ops; /* I/O operation function pointers */
- } orig;
+ } orig;
#endif /* H5_HAVE_PARALLEL */
H5D_storage_t *store; /* Dataset storage info */
H5D_layout_ops_t layout_ops; /* Dataset layout I/O operation function pointers */
H5D_io_ops_t io_ops; /* I/O operation function pointers */
- enum {
- H5D_IO_OP_READ, /* Read operation */
- H5D_IO_OP_WRITE /* Write operation */
- } op_type;
+ H5D_io_op_type_t op_type;
union {
void *rbuf; /* Pointer to buffer for read */
const void *wbuf; /* Pointer to buffer to write */
@@ -213,7 +219,9 @@ typedef struct H5D_io_info_t {
typedef struct H5D_chk_idx_info_t {
H5F_t *f; /* File pointer for operation */
hid_t dxpl_id; /* DXPL ID for operation */
- H5O_layout_t *layout; /* Layout info for chunks */
+ const H5O_pline_t *pline; /* I/O pipeline info */
+ H5O_layout_chunk_t *layout; /* Chunk layout description */
+ H5O_storage_chunk_t *storage; /* Chunk storage description */
} H5D_chk_idx_info_t;
/*
@@ -229,7 +237,7 @@ typedef struct H5D_chk_idx_info_t {
*/
typedef struct H5D_chunk_rec_t {
uint32_t nbytes; /* Size of stored data */
- hsize_t offset[H5O_LAYOUT_NDIMS]; /* Logical offset to start*/
+ hsize_t offset[H5O_LAYOUT_NDIMS]; /* Logical offset to start */
unsigned filter_mask; /* Excluded filters */
haddr_t chunk_addr; /* Address of chunk in file */
} H5D_chunk_rec_t;
@@ -241,8 +249,9 @@ typedef struct H5D_chunk_rec_t {
*/
typedef struct H5D_chunk_common_ud_t {
/* downward */
- const H5O_layout_t *mesg; /*layout message */
- const hsize_t *offset; /*logical offset of chunk*/
+ const H5O_layout_chunk_t *layout; /* Chunk layout description */
+ const H5O_storage_chunk_t *storage; /* Chunk storage description */
+ const hsize_t *offset; /* Logical offset of chunk */
} H5D_chunk_common_ud_t;
/* B-tree callback info for various operations */
@@ -253,19 +262,22 @@ typedef struct H5D_chunk_ud_t {
uint32_t nbytes; /*size of stored data */
unsigned filter_mask; /*excluded filters */
haddr_t addr; /*file address of chunk */
-} H5D_chunk_ud_t;
+} H5D_chunk_ud_t;
/* Typedef for "generic" chunk callbacks */
typedef int (*H5D_chunk_cb_func_t)(const H5D_chunk_rec_t *chunk_rec,
void *udata);
/* Typedefs for chunk operations */
-typedef herr_t (*H5D_chunk_init_func_t)(const H5D_chk_idx_info_t *idx_info);
+typedef herr_t (*H5D_chunk_init_func_t)(const H5D_chk_idx_info_t *idx_info,
+ const H5S_t *space, haddr_t dset_ohdr_addr);
typedef herr_t (*H5D_chunk_create_func_t)(const H5D_chk_idx_info_t *idx_info);
+typedef hbool_t (*H5D_chunk_is_space_alloc_func_t)(const H5O_storage_chunk_t *storage);
typedef herr_t (*H5D_chunk_insert_func_t)(const H5D_chk_idx_info_t *idx_info,
H5D_chunk_ud_t *udata);
-typedef haddr_t (*H5D_chunk_get_addr_func_t)(const H5D_chk_idx_info_t *idx_info,
+typedef herr_t (*H5D_chunk_get_addr_func_t)(const H5D_chk_idx_info_t *idx_info,
H5D_chunk_ud_t *udata);
+typedef herr_t (*H5D_chunk_resize_func_t)(H5O_layout_chunk_t *layout);
typedef int (*H5D_chunk_iterate_func_t)(const H5D_chk_idx_info_t *idx_info,
H5D_chunk_cb_func_t chunk_cb, void *chunk_udata);
typedef herr_t (*H5D_chunk_remove_func_t)(const H5D_chk_idx_info_t *idx_info,
@@ -273,24 +285,31 @@ typedef herr_t (*H5D_chunk_remove_func_t)(const H5D_chk_idx_info_t *idx_info,
typedef herr_t (*H5D_chunk_delete_func_t)(const H5D_chk_idx_info_t *idx_info);
typedef herr_t (*H5D_chunk_copy_setup_func_t)(const H5D_chk_idx_info_t *idx_info_src,
const H5D_chk_idx_info_t *idx_info_dst);
-typedef herr_t (*H5D_chunk_copy_shutdown_func_t)(H5O_layout_t *layout_src,
- H5O_layout_t *layout_dst);
+typedef herr_t (*H5D_chunk_copy_shutdown_func_t)(H5O_storage_chunk_t *storage_src,
+ H5O_storage_chunk_t *storage_dst, hid_t dxpl_id);
typedef herr_t (*H5D_chunk_size_func_t)(const H5D_chk_idx_info_t *idx_info,
hsize_t *idx_size);
+typedef herr_t (*H5D_chunk_reset_func_t)(H5O_storage_chunk_t *storage, hbool_t reset_addr);
+typedef herr_t (*H5D_chunk_dump_func_t)(const H5O_storage_chunk_t *storage,
+ FILE *stream);
typedef herr_t (*H5D_chunk_dest_func_t)(const H5D_chk_idx_info_t *idx_info);
/* Typedef for grouping chunk I/O routines */
typedef struct H5D_chunk_ops_t {
H5D_chunk_init_func_t init; /* Routine to initialize indexing information in memory */
H5D_chunk_create_func_t create; /* Routine to create chunk index */
+ H5D_chunk_is_space_alloc_func_t is_space_alloc; /* Query routine to determine if storage/index is allocated */
H5D_chunk_insert_func_t insert; /* Routine to insert a chunk into an index */
H5D_chunk_get_addr_func_t get_addr; /* Routine to retrieve address of chunk in file */
+ H5D_chunk_resize_func_t resize; /* Routine to update chunk index info after resizing dataset */
H5D_chunk_iterate_func_t iterate; /* Routine to iterate over chunks */
H5D_chunk_remove_func_t remove; /* Routine to remove a chunk from an index */
- H5D_chunk_delete_func_t delete; /* Routine to delete index & all chunks from file*/
+ H5D_chunk_delete_func_t idx_delete; /* Routine to delete index & all chunks from file*/
H5D_chunk_copy_setup_func_t copy_setup; /* Routine to perform any necessary setup for copying chunks */
H5D_chunk_copy_shutdown_func_t copy_shutdown; /* Routine to perform any necessary shutdown for copying chunks */
H5D_chunk_size_func_t size; /* Routine to get size of indexing information */
+ H5D_chunk_reset_func_t reset; /* Routine to reset indexing information */
+ H5D_chunk_dump_func_t dump; /* Routine to dump indexing information */
H5D_chunk_dest_func_t dest; /* Routine to destroy indexing information in memory */
} H5D_chunk_ops_t;
@@ -329,12 +348,9 @@ typedef struct H5D_chunk_map_t {
hsize_t last_index; /* Index of last chunk operated on */
H5D_chunk_info_t *last_chunk_info; /* Pointer to last chunk's info */
- hsize_t chunks[H5O_LAYOUT_NDIMS]; /* Number of chunks in each dimension */
hsize_t chunk_dim[H5O_LAYOUT_NDIMS]; /* Size of chunk in each dimension */
- hsize_t down_chunks[H5O_LAYOUT_NDIMS]; /* "down" size of number of chunks in each dimension */
#ifdef H5_HAVE_PARALLEL
- hsize_t total_chunks; /* Number of chunks covered by dataspace */
H5D_chunk_info_t **select_chunk; /* Store the information about whether this chunk is selected or not */
#endif /* H5_HAVE_PARALLEL */
} H5D_chunk_map_t;
@@ -356,15 +372,17 @@ typedef struct H5D_rdcc_t {
unsigned nmisses;/* Number of cache misses */
unsigned nflushes;/* Number of cache flushes */
} stats;
- size_t nbytes; /* Current cached raw data in bytes */
+ size_t nbytes_max; /* Maximum cached raw data in bytes */
size_t nslots; /* Number of chunk slots allocated */
+ double w0; /* Chunk preemption policy */
struct H5D_rdcc_ent_t *head; /* Head of doubly linked list */
struct H5D_rdcc_ent_t *tail; /* Tail of doubly linked list */
- int nused; /* Number of chunk slots in use */
+ size_t nbytes_used; /* Current cached raw data in bytes */
+ int nused; /* Number of chunk slots in use */
H5D_chunk_cached_t last; /* Cached copy of last chunk information */
struct H5D_rdcc_ent_t **slot; /* Chunk slots, each points to a chunk*/
- H5SL_t *sel_chunks; /* Skip list containing information for each chunk selected */
- H5S_t *single_space; /* Dataspace for single element I/O on chunks */
+ H5SL_t *sel_chunks; /* Skip list containing information for each chunk selected */
+ H5S_t *single_space; /* Dataspace for single element I/O on chunks */
H5D_chunk_info_t *single_chunk_info; /* Pointer to single chunk's info */
} H5D_rdcc_t;
@@ -384,15 +402,15 @@ typedef struct H5D_rdcdc_t {
* there will be two IDs and two H5D_t structs, both sharing one H5D_shared_t.
*/
typedef struct H5D_shared_t {
- size_t fo_count; /* reference count */
+ size_t fo_count; /* Reference count */
hid_t type_id; /* ID for dataset's datatype */
- H5T_t *type; /* datatype of this dataset */
- H5S_t *space; /* dataspace of this dataset */
+ H5T_t *type; /* Datatype for this dataset */
+ H5S_t *space; /* Dataspace of this dataset */
hbool_t space_dirty; /* Whether the dataspace info needs to be flushed to the file */
hbool_t layout_dirty; /* Whether the layout info needs to be flushed to the file */
- hid_t dcpl_id; /* dataset creation property id */
+ hid_t dcpl_id; /* Dataset creation property id */
H5D_dcpl_cache_t dcpl_cache; /* Cached DCPL values */
- H5O_layout_t layout; /* data layout */
+ H5O_layout_t layout; /* Data layout */
hbool_t checked_filters;/* TRUE if dataset passes can_apply check */
/* Buffered/cached information for types of raw data storage*/
@@ -426,10 +444,11 @@ typedef struct {
hid_t type_id; /* Datatype for dataset */
const H5S_t *space; /* Dataspace for dataset */
hid_t dcpl_id; /* Dataset creation property list */
+ hid_t dapl_id; /* Dataset access property list */
} H5D_obj_create_t;
/* Typedef for filling a buffer with a fill value */
-typedef struct {
+typedef struct H5D_fill_buf_info_t {
hbool_t alloc_vl_during_refill; /* Whether to allocate VL-datatype fill buffer during refill */
H5MM_allocate_t fill_alloc_func; /* Routine to call for allocating fill buffer */
void *fill_alloc_info; /* Extra info for allocation routine */
@@ -472,8 +491,6 @@ typedef struct H5D_rdcc_ent_t {
uint32_t rd_count; /*bytes remaining to be read */
uint32_t wr_count; /*bytes remaining to be written */
haddr_t chunk_addr; /*address of chunk in file */
- uint32_t chunk_size; /*size of a chunk */
- size_t alloc_size; /*amount allocated for the chunk */
uint8_t *chunk; /*the unfiltered chunk data */
unsigned idx; /*index in hash table */
struct H5D_rdcc_ent_t *next;/*next item in doubly-linked list */
@@ -494,7 +511,7 @@ H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_COMPACT[1];
H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_CHUNK[1];
/* Chunked layout operations */
-H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_ISTORE[1];
+H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_BTREE[1];
/******************************/
@@ -502,7 +519,7 @@ H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_ISTORE[1];
/******************************/
H5_DLL H5D_t *H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space,
- hid_t dcpl_id, hid_t dxpl_id);
+ hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id);
H5_DLL H5D_t *H5D_create_named(const H5G_loc_t *loc, const char *name,
hid_t type_id, const H5S_t *space, hid_t lcpl_id, hid_t dcpl_id,
hid_t dapl_id, hid_t dxpl_id);
@@ -520,6 +537,7 @@ H5_DLL herr_t H5D_vlen_get_buf_size(void *elem, hid_t type_id, unsigned ndim,
H5_DLL herr_t H5D_check_filters(H5D_t *dataset);
H5_DLL herr_t H5D_set_extent(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id);
H5_DLL herr_t H5D_get_dxpl_cache(hid_t dxpl_id, H5D_dxpl_cache_t **cache);
+H5_DLL herr_t H5D_flush_sieve_buf(H5D_t *dataset, hid_t dxpl_id);
/* Functions that perform direct serial I/O operations */
H5_DLL herr_t H5D_select_read(const H5D_io_info_t *io_info,
@@ -540,8 +558,21 @@ H5_DLL herr_t H5D_scatgath_write(const H5D_io_info_t *io_info,
const H5D_type_info_t *type_info,
hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space);
+/* Functions that operate on dataset's layout information */
+H5_DLL herr_t H5D_layout_set_io_ops(const H5D_t *dataset);
+H5_DLL size_t H5D_layout_meta_size(const H5F_t *f, const H5O_layout_t *layout,
+ hbool_t include_compact_data);
+H5_DLL herr_t H5D_layout_oh_create(H5F_t *file, hid_t dxpl_id, H5O_t *oh,
+ H5D_t *dset, hid_t dapl_id);
+H5_DLL herr_t H5D_layout_oh_read(H5D_t *dset, hid_t dxpl_id, hid_t dapl_id,
+ H5P_genplist_t *plist);
+H5_DLL herr_t H5D_layout_oh_write(H5D_t *dataset, hid_t dxpl_id, H5O_t *oh,
+ unsigned update_flags);
+
/* Functions that operate on contiguous storage */
-H5_DLL herr_t H5D_contig_alloc(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout);
+H5_DLL herr_t H5D_contig_alloc(H5F_t *f, hid_t dxpl_id,
+ H5O_storage_contig_t *storage);
+H5_DLL hbool_t H5D_contig_is_space_alloc(const H5O_storage_t *storage);
H5_DLL herr_t H5D_contig_fill(H5D_t *dset, hid_t dxpl_id);
H5_DLL haddr_t H5D_contig_get_addr(const H5D_t *dset);
H5_DLL herr_t H5D_contig_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
@@ -556,35 +587,40 @@ H5_DLL ssize_t H5D_contig_readvv(const H5D_io_info_t *io_info,
H5_DLL ssize_t H5D_contig_writevv(const H5D_io_info_t *io_info,
size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]);
-H5_DLL herr_t H5D_contig_copy(H5F_t *f_src, const H5O_layout_t *layout_src, H5F_t *f_dst,
- H5O_layout_t *layout_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info, hid_t dxpl_id);
+H5_DLL herr_t H5D_contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src,
+ H5F_t *f_dst, H5O_storage_contig_t *storage_dst, H5T_t *src_dtype,
+ H5O_copy_t *cpy_info, hid_t dxpl_id);
/* Functions that operate on chunked dataset storage */
-H5_DLL hbool_t H5D_chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr);
+H5_DLL htri_t H5D_chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr,
+ hbool_t write_op);
H5_DLL herr_t H5D_chunk_cinfo_cache_reset(H5D_chunk_cached_t *last);
H5_DLL herr_t H5D_chunk_create(H5D_t *dset /*in,out*/, hid_t dxpl_id);
-H5_DLL herr_t H5D_chunk_init(H5F_t *f, hid_t dxpl_id, const H5D_t *dset);
-H5_DLL haddr_t H5D_chunk_get_addr(const H5D_t *dset, hid_t dxpl_id,
+H5_DLL herr_t H5D_chunk_set_info(const H5D_t *dset);
+H5_DLL herr_t H5D_chunk_init(H5F_t *f, hid_t dxpl_id, const H5D_t *dset,
+ hid_t dapl_id);
+H5_DLL hbool_t H5D_chunk_is_space_alloc(const H5O_storage_t *storage);
+H5_DLL herr_t H5D_chunk_get_info(const H5D_t *dset, hid_t dxpl_id,
const hsize_t *chunk_offset, H5D_chunk_ud_t *udata);
H5_DLL void *H5D_chunk_lock(const H5D_io_info_t *io_info,
H5D_chunk_ud_t *udata, hbool_t relax, unsigned *idx_hint/*in,out*/);
H5_DLL herr_t H5D_chunk_unlock(const H5D_io_info_t *io_info,
- hbool_t dirty, unsigned idx_hint, void *chunk, uint32_t naccessed);
-H5_DLL herr_t H5D_chunk_flush(H5D_t *dset, hid_t dxpl_id, unsigned flags);
+ const H5D_chunk_ud_t *udata, hbool_t dirty, unsigned idx_hint, void *chunk,
+ uint32_t naccessed);
H5_DLL herr_t H5D_chunk_allocated(H5D_t *dset, hid_t dxpl_id, hsize_t *nbytes);
H5_DLL herr_t H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite);
H5_DLL herr_t H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id,
const hsize_t *old_dims);
#ifdef H5_HAVE_PARALLEL
-H5_DLL herr_t H5D_chunk_addrmap(const H5D_io_info_t *io_info,
- haddr_t chunk_addr[], const hsize_t down_chunks[]);
+H5_DLL herr_t H5D_chunk_addrmap(const H5D_io_info_t *io_info, haddr_t chunk_addr[]);
#endif /* H5_HAVE_PARALLEL */
H5_DLL herr_t H5D_chunk_update_cache(H5D_t *dset, hid_t dxpl_id);
-H5_DLL herr_t H5D_chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src,
- H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *src_dtype,
- H5O_copy_t *cpy_info, H5O_pline_t *pline, hid_t dxpl_id);
+H5_DLL herr_t H5D_chunk_copy(H5F_t *f_src, H5O_storage_chunk_t *storage_src,
+ H5O_layout_chunk_t *layout_src, H5F_t *f_dst, H5O_storage_chunk_t *storage_dst,
+ const H5S_extent_t *ds_extent_src, const H5T_t *dt_src,
+ const H5O_pline_t *pline_src, H5O_copy_t *cpy_info, hid_t dxpl_id);
H5_DLL herr_t H5D_chunk_bh_info(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
- hsize_t *btree_size);
+ const H5O_pline_t *pline, hsize_t *btree_size);
H5_DLL herr_t H5D_chunk_dump_index(H5D_t *dset, hid_t dxpl_id, FILE *stream);
H5_DLL herr_t H5D_chunk_dest(H5F_t *f, hid_t dxpl_id, H5D_t *dset);
#ifdef H5D_CHUNK_DEBUG
@@ -593,8 +629,14 @@ H5_DLL herr_t H5D_chunk_stats(const H5D_t *dset, hbool_t headers);
/* Functions that operate on compact dataset storage */
H5_DLL herr_t H5D_compact_fill(H5D_t *dset, hid_t dxpl_id);
-H5_DLL herr_t H5D_compact_copy(H5F_t *f_src, H5O_layout_t *layout_src,
- H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info, hid_t dxpl_id);
+H5_DLL herr_t H5D_compact_copy(H5F_t *f_src, H5O_storage_compact_t *storage_src,
+ H5F_t *f_dst, H5O_storage_compact_t *storage_dst, H5T_t *src_dtype,
+ H5O_copy_t *cpy_info, hid_t dxpl_id);
+
+/* Functions that operate on EFL (External File List)*/
+H5_DLL hbool_t H5D_efl_is_space_alloc(const H5O_storage_t *storage);
+H5_DLL herr_t H5D_efl_bh_info(H5F_t *f, hid_t dxpl_id, H5O_efl_t *efl,
+ hsize_t *heap_size);
/* Functions that perform fill value operations on datasets */
H5_DLL herr_t H5D_fill(const void *fill, const H5T_t *fill_type, void *buf,
@@ -655,6 +697,7 @@ H5_DLL htri_t H5D_mpio_opt_possible(const H5D_io_info_t *io_info,
#ifdef H5D_TESTING
H5_DLL herr_t H5D_layout_version_test(hid_t did, unsigned *version);
H5_DLL herr_t H5D_layout_contig_size_test(hid_t did, hsize_t *size);
+H5_DLL herr_t H5D_current_cache_size_test(hid_t did, size_t *nbytes_used, int *nused);
#endif /* H5D_TESTING */
#endif /*_H5Dpkg_H*/
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index f1180a3..5849598 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -28,6 +28,7 @@
#include "H5Sprivate.h" /* Dataspaces */
#include "H5Zprivate.h" /* Data filters */
+
/**************************/
/* Library Private Macros */
/**************************/
@@ -43,12 +44,14 @@
/* ======== Dataset creation property names ======== */
#define H5D_CRT_LAYOUT_NAME "layout" /* Storage layout */
-#define H5D_CRT_CHUNK_DIM_NAME "chunk_ndims" /* Chunk dimensionality */
-#define H5D_CRT_CHUNK_SIZE_NAME "chunk_size" /* Chunk size */
#define H5D_CRT_FILL_VALUE_NAME "fill_value" /* Fill value */
#define H5D_CRT_ALLOC_TIME_STATE_NAME "alloc_time_state" /* Space allocation time state */
#define H5D_CRT_EXT_FILE_LIST_NAME "efl" /* External file list */
-#define H5D_CRT_DATA_PIPELINE_NAME "pline" /* Data filter pipeline */
+
+/* ======== Dataset access property names ======== */
+#define H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME "rdcc_nslots" /* Size of raw data chunk cache(slots) */
+#define H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME "rdcc_nbytes" /* Size of raw data chunk cache(bytes) */
+#define H5D_ACS_PREEMPT_READ_CHUNKS_NAME "rdcc_w0" /* Preemption read chunks first */
/* ======== Data transfer properties ======== */
#define H5D_XFER_MAX_TEMP_BUF_NAME "max_temp_buf" /* Maximum temp buffer size */
@@ -82,9 +85,13 @@
#define H5D_XFER_COLL_CHUNK_LINK_NUM_FALSE_NAME "coll_chunk_link_false"
#define H5D_XFER_COLL_CHUNK_MULTI_RATIO_COLL_NAME "coll_chunk_multi_coll"
#define H5D_XFER_COLL_CHUNK_MULTI_RATIO_IND_NAME "coll_chunk_multi_ind"
+#define H5D_XFER_COLL_CHUNK_LINK_TO_MULTI "coll_chunk_link_mul"/* Internal transferring from link to multiple chunk */
+#define H5D_XFER_COLL_CHUNK_LINK_TO_MULTI_OPT "coll_chunk_link_mul_opt"/* Internal transferring from link opt to multiple chunk opt*/
+
/* Definitions for all collective chunk instrumentation properties */
#define H5D_XFER_COLL_CHUNK_SIZE sizeof(unsigned)
#define H5D_XFER_COLL_CHUNK_DEF 1
+#define H5D_XFER_COLL_CHUNK_FIX 0
#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */
/* Default temporary buffer size */
@@ -99,6 +106,7 @@
#define H5D_VLEN_FREE NULL
#define H5D_VLEN_FREE_INFO NULL
+
/****************************/
/* Library Private Typedefs */
/****************************/
@@ -126,25 +134,34 @@ typedef struct H5D_dxpl_cache_t {
/* Typedef for cached dataset creation property list information */
typedef struct H5D_dcpl_cache_t {
H5O_fill_t fill; /* Fill value info (H5D_CRT_FILL_VALUE_NAME) */
- H5O_pline_t pline; /* I/O pipeline info (H5D_CRT_DATA_PIPELINE_NAME) */
+ H5O_pline_t pline; /* I/O pipeline info (H5O_CRT_PIPELINE_NAME) */
H5O_efl_t efl; /* External file list info (H5D_CRT_EXT_FILE_LIST_NAME) */
} H5D_dcpl_cache_t;
+/* Callback information for copying datasets */
+typedef struct H5D_copy_file_ud_t {
+ H5O_copy_file_ud_common_t common; /* Shared information (must be first) */
+ struct H5S_extent_t *src_space_extent; /* Copy of dataspace extent for dataset */
+ H5T_t *src_dtype; /* Copy of datatype for dataset */
+} H5D_copy_file_ud_t;
+
+
/*****************************/
/* Library Private Variables */
/*****************************/
+
/******************************/
/* Library Private Prototypes */
/******************************/
H5_DLL herr_t H5D_init(void);
-H5_DLL H5D_t *H5D_open(const H5G_loc_t *loc, hid_t dxpl_id);
+H5_DLL H5D_t *H5D_open(const H5G_loc_t *loc, hid_t dapl_id, hid_t dxpl_id);
H5_DLL herr_t H5D_close(H5D_t *dataset);
H5_DLL H5O_loc_t *H5D_oloc(H5D_t *dataset);
H5_DLL H5G_name_t *H5D_nameof(H5D_t *dataset);
H5_DLL H5T_t *H5D_typeof(const H5D_t *dset);
-H5_DLL herr_t H5D_flush(const H5F_t *f, hid_t dxpl_id, unsigned flags);
+H5_DLL herr_t H5D_flush(const H5F_t *f, hid_t dxpl_id);
/* Functions that operate on vlen data */
H5_DLL herr_t H5D_vlen_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id,
@@ -152,13 +169,15 @@ H5_DLL herr_t H5D_vlen_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id,
/* Functions that operate on contiguous storage */
H5_DLL herr_t H5D_contig_delete(H5F_t *f, hid_t dxpl_id,
- const H5O_layout_t *layout);
+ const H5O_storage_t *store);
/* Functions that operate on chunked storage */
-H5_DLL herr_t H5D_chunk_delete(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout);
+H5_DLL herr_t H5D_chunk_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr);
+H5_DLL herr_t H5D_chunk_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
+ H5O_storage_t *store);
/* Functions that operate on indexed storage */
-H5_DLL herr_t H5D_istore_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream,
+H5_DLL herr_t H5D_btree_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream,
int indent, int fwidth, unsigned ndims);
#endif /* _H5Dprivate_H */
diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h
index 0d8b63f..c878d4a 100644
--- a/src/H5Dpublic.h
+++ b/src/H5Dpublic.h
@@ -29,6 +29,11 @@
/* Public Macros */
/*****************/
+/* Macros used to "unset" chunk cache configuration parameters */
+#define H5D_CHUNK_CACHE_NSLOTS_DEFAULT ((size_t) -1)
+#define H5D_CHUNK_CACHE_NBYTES_DEFAULT ((size_t) -1)
+#define H5D_CHUNK_CACHE_W0_DEFAULT -1.
+
/*******************/
/* Public Typedefs */
/*******************/
@@ -43,6 +48,11 @@ typedef enum H5D_layout_t {
H5D_NLAYOUTS = 3 /*this one must be last! */
} H5D_layout_t;
+/* Types of chunk index data structures */
+typedef enum H5D_chunk_index_t {
+ H5D_CHUNK_BTREE = 0 /* v1 B-tree index */
+} H5D_chunk_index_t;
+
/* Values for the space allocation time property */
typedef enum H5D_alloc_time_t {
H5D_ALLOC_TIME_ERROR = -1,
@@ -101,6 +111,7 @@ H5_DLL hid_t H5Dget_space(hid_t dset_id);
H5_DLL herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation);
H5_DLL hid_t H5Dget_type(hid_t dset_id);
H5_DLL hid_t H5Dget_create_plist(hid_t dset_id);
+H5_DLL hid_t H5Dget_access_plist(hid_t dset_id);
H5_DLL hsize_t H5Dget_storage_size(hid_t dset_id);
H5_DLL haddr_t H5Dget_offset(hid_t dset_id);
H5_DLL herr_t H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
@@ -117,7 +128,7 @@ H5_DLL herr_t H5Dset_extent(hid_t dset_id, const hsize_t size[]);
H5_DLL herr_t H5Ddebug(hid_t dset_id);
/* Symbols defined for compatibility with previous versions of the HDF5 API.
- *
+ *
* Use of these symbols is deprecated.
*/
#ifndef H5_NO_DEPRECATED_SYMBOLS
diff --git a/src/H5Dscatgath.c b/src/H5Dscatgath.c
index 3ea4c69..ed73f3c 100644
--- a/src/H5Dscatgath.c
+++ b/src/H5Dscatgath.c
@@ -160,9 +160,9 @@ H5D_scatter_file(const H5D_io_info_t *_io_info,
done:
/* Release resources, if allocated */
if(len && len != _len)
- H5FL_SEQ_FREE(size_t, len);
+ len = H5FL_SEQ_FREE(size_t, len);
if(off && off != _off)
- H5FL_SEQ_FREE(hsize_t, off);
+ off = H5FL_SEQ_FREE(hsize_t, off);
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D_scatter_file() */
@@ -261,9 +261,9 @@ H5D_gather_file(const H5D_io_info_t *_io_info,
done:
/* Release resources, if allocated */
if(len && len != _len)
- H5FL_SEQ_FREE(size_t, len);
+ len = H5FL_SEQ_FREE(size_t, len);
if(off && off != _off)
- H5FL_SEQ_FREE(hsize_t, off);
+ off = H5FL_SEQ_FREE(hsize_t, off);
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D_gather_file() */
@@ -346,9 +346,9 @@ H5D_scatter_mem (const void *_tscat_buf, const H5S_t *space,
done:
/* Release resources, if allocated */
if(len && len != _len)
- H5FL_SEQ_FREE(size_t, len);
+ len = H5FL_SEQ_FREE(size_t, len);
if(off && off != _off)
- H5FL_SEQ_FREE(hsize_t, off);
+ off = H5FL_SEQ_FREE(hsize_t, off);
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D_scatter_mem() */
@@ -433,9 +433,9 @@ H5D_gather_mem(const void *_buf, const H5S_t *space,
done:
/* Release resources, if allocated */
if(len && len != _len)
- H5FL_SEQ_FREE(size_t, len);
+ len = H5FL_SEQ_FREE(size_t, len);
if(off && off != _off)
- H5FL_SEQ_FREE(hsize_t, off);
+ off = H5FL_SEQ_FREE(hsize_t, off);
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D_gather_mem() */
@@ -507,7 +507,7 @@ H5D_scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info
* if necessary.
*/
- /*
+ /*
* Gather data
*/
n = H5D_gather_file(io_info, file_space, &file_iter, smine_nelmts,
@@ -516,10 +516,10 @@ H5D_scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file gather failed")
/* If the source and destination are compound types and subset of each other
- * and no conversion is needed, copy the data directly into user's buffer and
+ * and no conversion is needed, copy the data directly into user's buffer and
* bypass the rest of steps.
*/
- if(H5T_SUBSET_FALSE != type_info->cmpd_subset) {
+ if(type_info->cmpd_subset && H5T_SUBSET_FALSE != type_info->cmpd_subset->subset) {
if(H5D_compound_opt_read(smine_nelmts, mem_space, &mem_iter, dxpl_cache,
type_info, buf /*out*/) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "datatype conversion failed")
@@ -644,12 +644,13 @@ H5D_scatgath_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "mem gather failed")
/* If the source and destination are compound types and the destination is
- * is a subset of the source and no conversion is needed, copy the data
+ * is a subset of the source and no conversion is needed, copy the data
* directly into user's buffer and bypass the rest of steps. If the source
* is a subset of the destination, the optimization is done in conversion
* function H5T_conv_struct_opt to protect the background data.
*/
- if(H5T_SUBSET_DST == type_info->cmpd_subset) {
+ if(type_info->cmpd_subset && H5T_SUBSET_DST == type_info->cmpd_subset->subset
+ && type_info->dst_type_size == type_info->cmpd_subset->copy_size) {
if(H5D_compound_opt_write(smine_nelmts, type_info) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "datatype conversion failed")
} /* end if */
@@ -661,6 +662,12 @@ H5D_scatgath_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file gather failed")
} /* end if */
+ /* Do the data transform before the type conversion (since
+ * transforms must be done in the memory type). */
+ if(!type_info->is_xform_noop)
+ if(H5Z_xform_eval(dxpl_cache->data_xform_prop, type_info->tconv_buf, smine_nelmts, type_info->mem_type) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Error performing data transform")
+
/*
* Perform datatype conversion.
*/
@@ -668,11 +675,6 @@ H5D_scatgath_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
smine_nelmts, (size_t)0, (size_t)0, type_info->tconv_buf,
type_info->bkg_buf, io_info->dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "datatype conversion failed")
-
- /* Do the data transform after the type conversion (since we're using dataset->shared->type). */
- if(!type_info->is_xform_noop)
- if(H5Z_xform_eval(dxpl_cache->data_xform_prop, type_info->tconv_buf, smine_nelmts, type_info->dset_type) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Error performing data transform")
} /* end else */
/*
@@ -705,9 +707,9 @@ done:
/*-------------------------------------------------------------------------
* Function: H5D_compound_opt_read
*
- * Purpose: A special optimization case when the source and
- * destination members are a subset of each other, and
- * the order is the same, and no conversion is needed.
+ * Purpose: A special optimization case when the source and
+ * destination members are a subset of each other, and
+ * the order is the same, and no conversion is needed.
* For example:
* struct source { struct destination {
* TYPE1 A; --> TYPE1 A;
@@ -724,7 +726,7 @@ done:
* }; TYPE4 D;
* TYPE5 E;
* };
- * The optimization is simply moving data to the appropriate
+ * The optimization is simply moving data to the appropriate
* places in the buffer.
*
* Return: Non-negative on success/Negative on failure
@@ -745,7 +747,7 @@ H5D_compound_opt_read(size_t nelmts, const H5S_t *space,
hsize_t *off = NULL; /* Pointer to sequence offsets */
size_t _len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths */
size_t *len = NULL; /* Pointer to sequence lengths */
- size_t src_stride, dst_stride, type_size;
+ size_t src_stride, dst_stride, copy_size;
herr_t ret_value = SUCCEED; /*return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_compound_opt_read)
@@ -756,6 +758,9 @@ H5D_compound_opt_read(size_t nelmts, const H5S_t *space,
HDassert(iter);
HDassert(dxpl_cache);
HDassert(type_info);
+ HDassert(type_info->cmpd_subset);
+ HDassert(H5T_SUBSET_SRC == type_info->cmpd_subset->subset ||
+ H5T_SUBSET_DST == type_info->cmpd_subset->subset);
HDassert(user_buf);
/* Allocate the vector I/O arrays */
@@ -774,12 +779,8 @@ H5D_compound_opt_read(size_t nelmts, const H5S_t *space,
src_stride = type_info->src_type_size;
dst_stride = type_info->dst_type_size;
- if(H5T_SUBSET_SRC == type_info->cmpd_subset)
- type_size = src_stride;
- else {
- HDassert(H5T_SUBSET_DST == type_info->cmpd_subset);
- type_size = dst_stride;
- } /* end else */
+ /* Get the size, in bytes, to copy for each element */
+ copy_size = type_info->cmpd_subset->copy_size;
/* Loop until all elements are written */
xdbuf = type_info->tconv_buf;
@@ -802,7 +803,8 @@ H5D_compound_opt_read(size_t nelmts, const H5S_t *space,
/* Get the number of bytes and offset in sequence */
curr_len = len[curr_seq];
- curr_off = off[curr_seq];
+ H5_CHECK_OVERFLOW(off[curr_seq], hsize_t, size_t);
+ curr_off = (size_t)off[curr_seq];
/* Decide the number of elements and position in the buffer. */
curr_nelmts = curr_len / dst_stride;
@@ -810,7 +812,7 @@ H5D_compound_opt_read(size_t nelmts, const H5S_t *space,
/* Copy the data into the right place. */
for(i = 0; i < curr_nelmts; i++) {
- HDmemmove(xubuf, xdbuf, type_size);
+ HDmemmove(xubuf, xdbuf, copy_size);
/* Update pointers */
xdbuf += src_stride;
@@ -825,9 +827,9 @@ H5D_compound_opt_read(size_t nelmts, const H5S_t *space,
done:
/* Release resources, if allocated */
if(len && len != _len)
- H5FL_SEQ_FREE(size_t, len);
+ len = H5FL_SEQ_FREE(size_t, len);
if(off && off != _off)
- H5FL_SEQ_FREE(hsize_t, off);
+ off = H5FL_SEQ_FREE(hsize_t, off);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_compound_opt_read() */
@@ -836,9 +838,9 @@ done:
/*-------------------------------------------------------------------------
* Function: H5D_compound_opt_write
*
- * Purpose: A special optimization case when the source and
- * destination members are a subset of each other, and
- * the order is the same, and no conversion is needed.
+ * Purpose: A special optimization case when the source and
+ * destination members are a subset of each other, and
+ * the order is the same, and no conversion is needed.
* For example:
* struct source { struct destination {
* TYPE1 A; --> TYPE1 A;
@@ -855,7 +857,7 @@ done:
* }; TYPE4 D;
* TYPE5 E;
* };
- * The optimization is simply moving data to the appropriate
+ * The optimization is simply moving data to the appropriate
* places in the buffer.
*
*
@@ -887,7 +889,7 @@ H5D_compound_opt_write(size_t nelmts, const H5D_type_info_t *type_info)
xsbuf = (uint8_t *)type_info->tconv_buf;
xdbuf = (uint8_t *)type_info->tconv_buf;
for(i = 0; i < nelmts; i++) {
- HDmemmove(xdbuf, xsbuf, dst_stride);
+ HDmemmove(xdbuf, xsbuf, dst_stride);
/* Update pointers */
xsbuf += src_stride;
diff --git a/src/H5Dselect.c b/src/H5Dselect.c
index 947c81e..6dade5c 100644
--- a/src/H5Dselect.c
+++ b/src/H5Dselect.c
@@ -160,7 +160,7 @@ H5D_select_io(const H5D_io_info_t *io_info, size_t elmt_size,
} /* end else */
/* Decrement number of elements left to process */
- HDassert((tmp_file_len % elmt_size) == 0);
+ HDassert(((size_t)tmp_file_len % elmt_size) == 0);
} /* end if */
else {
size_t mem_nelem; /* Number of elements used in memory sequences */
@@ -218,8 +218,8 @@ H5D_select_io(const H5D_io_info_t *io_info, size_t elmt_size,
} /* end else */
/* Decrement number of elements left to process */
- HDassert((tmp_file_len % elmt_size) == 0);
- nelmts -= (tmp_file_len / elmt_size);
+ HDassert(((size_t)tmp_file_len % elmt_size) == 0);
+ nelmts -= ((size_t)tmp_file_len / elmt_size);
} /* end while */
} /* end else */
@@ -236,13 +236,13 @@ done:
/* Release vector arrays, if allocated */
if(file_len && file_len != _file_len)
- H5FL_SEQ_FREE(size_t, file_len);
+ file_len = H5FL_SEQ_FREE(size_t, file_len);
if(file_off && file_off != _file_off)
- H5FL_SEQ_FREE(hsize_t, file_off);
+ file_off = H5FL_SEQ_FREE(hsize_t, file_off);
if(mem_len && mem_len != _mem_len)
- H5FL_SEQ_FREE(size_t, mem_len);
+ mem_len = H5FL_SEQ_FREE(size_t, mem_len);
if(mem_off && mem_off != _mem_off)
- H5FL_SEQ_FREE(hsize_t, mem_off);
+ mem_off = H5FL_SEQ_FREE(hsize_t, mem_off);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_select_io() */
diff --git a/src/H5Dtest.c b/src/H5Dtest.c
index 2fb3c10..34ef8fb 100644
--- a/src/H5Dtest.c
+++ b/src/H5Dtest.c
@@ -134,10 +134,56 @@ H5D_layout_contig_size_test(hid_t did, hsize_t *size)
if(size) {
HDassert(dset->shared->layout.type == H5D_CONTIGUOUS);
- *size = dset->shared->layout.u.contig.size;
+ *size = dset->shared->layout.storage.u.contig.size;
} /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D_layout_contig_size_test() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5D_current_cache_size_test
+ PURPOSE
+ Determine current the size of the dataset's chunk cache
+ USAGE
+ herr_t H5D_current_cache_size_test(did, size)
+ hid_t did; IN: Dataset to query
+ hsize_t *size; OUT: Pointer to location to place size info
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Checks the size of a contiguous dataset's storage.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5D_current_cache_size_test(hid_t did, size_t *nbytes_used, int *nused)
+{
+ H5D_t *dset; /* Pointer to dataset to query */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_NOAPI(H5D_current_cache_size_test, FAIL)
+
+ /* Check args */
+ if(NULL == (dset = (H5D_t *)H5I_object_verify(did, H5I_DATASET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+
+ if(nbytes_used) {
+ HDassert(dset->shared->layout.type == H5D_CHUNKED);
+ *nbytes_used = dset->shared->cache.chunk.nbytes_used;
+ } /* end if */
+
+ if(nused) {
+ HDassert(dset->shared->layout.type == H5D_CHUNKED);
+ *nused = dset->shared->cache.chunk.nused;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5D_current_cache_size_test() */
+
diff --git a/src/H5E.c b/src/H5E.c
index 72f0619..5a80787 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -230,7 +230,7 @@ H5E_init_interface(void)
HDsnprintf(lib_vers, sizeof(lib_vers), "%u.%u.%u%s", H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE, (HDstrlen(H5_VERS_SUBRELEASE) > 0 ? "-"H5_VERS_SUBRELEASE : ""));
if(NULL == (cls = H5E_register_class(H5E_CLS_NAME, H5E_CLS_LIB_NAME, lib_vers)))
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "class initialization failed")
- if((H5E_ERR_CLS_g = H5I_register(H5I_ERROR_CLASS, cls)) < 0)
+ if((H5E_ERR_CLS_g = H5I_register(H5I_ERROR_CLASS, cls, FALSE)) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error class")
/* Include the automatically generated error code initialization */
@@ -275,11 +275,11 @@ H5E_term_interface(void)
if(n > 0) {
/* Clear any outstanding error stacks */
if(nstk > 0)
- H5I_clear_type(H5I_ERROR_STACK, FALSE);
+ H5I_clear_type(H5I_ERROR_STACK, FALSE, FALSE);
/* Clear all the error classes */
if(ncls > 0) {
- H5I_clear_type(H5I_ERROR_CLASS, FALSE);
+ H5I_clear_type(H5I_ERROR_CLASS, FALSE, FALSE);
/* Reset the HDF5 error class, if its been closed */
if(H5I_nmembers(H5I_ERROR_CLASS) == 0)
@@ -288,7 +288,7 @@ H5E_term_interface(void)
/* Clear all the error messages */
if(nmsg > 0) {
- H5I_clear_type(H5I_ERROR_MSG, FALSE);
+ H5I_clear_type(H5I_ERROR_MSG, FALSE, FALSE);
/* Reset the HDF5 error messages, if they've been closed */
if(H5I_nmembers(H5I_ERROR_MSG) == 0) {
@@ -336,7 +336,7 @@ H5E_get_stack(void)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5E_get_stack)
- estack = pthread_getspecific(H5TS_errstk_key_g);
+ estack = (H5E_t *)pthread_getspecific(H5TS_errstk_key_g);
if(!estack) {
/* no associated value with current thread - create one */
@@ -390,7 +390,7 @@ H5Eregister_class(const char *cls_name, const char *lib_name, const char *versio
HGOTO_ERROR(H5E_ERROR, H5E_CANTCREATE, FAIL, "can't create error class")
/* Register the new error class to get an ID for it */
- if((ret_value = H5I_register(H5I_ERROR_CLASS, cls)) < 0)
+ if((ret_value = H5I_register(H5I_ERROR_CLASS, cls, TRUE)) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error class")
done:
@@ -471,7 +471,7 @@ H5Eunregister_class(hid_t class_id)
* Decrement the counter on the dataset. It will be freed if the count
* reaches zero.
*/
- if(H5I_dec_ref(class_id) < 0)
+ if(H5I_dec_ref(class_id, TRUE) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error class")
done:
@@ -501,7 +501,7 @@ H5E_unregister_class(H5E_cls_t *cls)
/* Iterate over all the messages and delete those in this error class */
/* (Ignore return value, since callback isn't designed to return a particular object) */
- (void)H5I_search(H5I_ERROR_MSG, H5E_close_msg_cb, cls);
+ (void)H5I_search(H5I_ERROR_MSG, H5E_close_msg_cb, cls, FALSE);
/* Free error class structure */
if(cls->cls_name)
@@ -510,7 +510,7 @@ H5E_unregister_class(H5E_cls_t *cls)
H5MM_xfree((void*)cls->lib_name);
if(cls->lib_vers)
H5MM_xfree((void*)cls->lib_vers);
- H5FL_FREE(H5E_cls_t, cls);
+ (void)H5FL_FREE(H5E_cls_t, cls);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5E_unregister_class() */
@@ -539,7 +539,7 @@ H5Eget_class_name(hid_t class_id, char *name, size_t size)
H5TRACE3("Zs", "i*sz", class_id, name, size);
/* Get the error class */
- if(NULL == (cls = H5I_object_verify(class_id, H5I_ERROR_CLASS)))
+ if(NULL == (cls = (H5E_cls_t *)H5I_object_verify(class_id, H5I_ERROR_CLASS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error class ID")
/* Retrieve the class name */
@@ -615,9 +615,12 @@ H5E_close_msg_cb(void *obj_ptr, hid_t obj_id, void *key)
HDassert(err_msg);
/* Close the message if it is in the class being closed */
- if(err_msg->cls == cls)
- if(H5I_dec_ref(obj_id) < 0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error message")
+ if(err_msg->cls == cls) {
+ if(H5E_close_msg(err_msg) < 0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTCLOSEOBJ, FAIL, "unable to close error message")
+ if(NULL == H5I_remove(obj_id))
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREMOVE, FAIL, "unable to remove error message")
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -649,7 +652,7 @@ H5Eclose_msg(hid_t err_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an error class")
/* Decrement the counter. It will be freed if the count reaches zero. */
- if(H5I_dec_ref(err_id) < 0)
+ if(H5I_dec_ref(err_id, TRUE) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error message")
done:
@@ -681,7 +684,7 @@ H5E_close_msg(H5E_msg_t *err)
H5MM_xfree((void*)err->msg);
/* Don't free err->cls here */
- H5FL_FREE(H5E_msg_t, err);
+ (void)H5FL_FREE(H5E_msg_t, err);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5E_close_msg() */
@@ -716,7 +719,7 @@ H5Ecreate_msg(hid_t class_id, H5E_type_t msg_type, const char *msg_str)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "message is NULL")
/* Get the error class */
- if(NULL == (cls = H5I_object_verify(class_id, H5I_ERROR_CLASS)))
+ if(NULL == (cls = (H5E_cls_t *)H5I_object_verify(class_id, H5I_ERROR_CLASS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error class ID")
/* Create the new error message object */
@@ -724,7 +727,7 @@ H5Ecreate_msg(hid_t class_id, H5E_type_t msg_type, const char *msg_str)
HGOTO_ERROR(H5E_ERROR, H5E_CANTCREATE, FAIL, "can't create error message")
/* Register the new error class to get an ID for it */
- if((ret_value = H5I_register(H5I_ERROR_MSG, msg)) < 0)
+ if((ret_value = H5I_register(H5I_ERROR_MSG, msg, TRUE)) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
done:
@@ -797,7 +800,7 @@ H5Eget_msg(hid_t msg_id, H5E_type_t *type, char *msg_str, size_t size)
H5TRACE4("Zs", "i*Et*sz", msg_id, type, msg_str, size);
/* Get the message object */
- if(NULL == (msg = H5I_object_verify(msg_id, H5I_ERROR_MSG)))
+ if(NULL == (msg = (H5E_msg_t *)H5I_object_verify(msg_id, H5I_ERROR_MSG)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error message ID")
/* Get the message's text */
@@ -838,7 +841,7 @@ H5Ecreate_stack(void)
H5E_set_default_auto(stk);
/* Register the stack */
- if((ret_value = H5I_register(H5I_ERROR_STACK, stk)) < 0)
+ if((ret_value = H5I_register(H5I_ERROR_STACK, stk, TRUE)) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't create error stack")
done:
@@ -874,7 +877,7 @@ H5Eget_current_stack(void)
HGOTO_ERROR(H5E_ERROR, H5E_CANTCREATE, FAIL, "can't create error stack")
/* Register the stack */
- if((ret_value = H5I_register(H5I_ERROR_STACK, stk)) < 0)
+ if((ret_value = H5I_register(H5I_ERROR_STACK, stk, TRUE)) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't create error stack")
done:
@@ -905,7 +908,7 @@ H5E_get_current_stack(void)
FUNC_ENTER_NOAPI_NOINIT(H5E_get_current_stack)
/* Get a pointer to the current error stack */
- if(NULL == (current_stack = H5E_get_my_stack ())) /*lint !e506 !e774 Make lint 'constant value Boolean' in non-threaded case */
+ if(NULL == (current_stack = H5E_get_my_stack())) /*lint !e506 !e774 Make lint 'constant value Boolean' in non-threaded case */
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, NULL, "can't get current error stack")
/* Allocate a new error stack */
@@ -922,13 +925,13 @@ H5E_get_current_stack(void)
new_error = &(estack_copy->slot[u]);
/* Increment the IDs to indicate that they are used in this stack */
- if(H5I_inc_ref(current_error->cls_id) < 0)
+ if(H5I_inc_ref(current_error->cls_id, FALSE) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, NULL, "unable to increment ref count on error class")
new_error->cls_id = current_error->cls_id;
- if(H5I_inc_ref(current_error->maj_num) < 0)
+ if(H5I_inc_ref(current_error->maj_num, FALSE) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, NULL, "unable to increment ref count on error message")
new_error->maj_num = current_error->maj_num;
- if(H5I_inc_ref(current_error->min_num) < 0)
+ if(H5I_inc_ref(current_error->min_num, FALSE) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, NULL, "unable to increment ref count on error message")
new_error->min_num = current_error->min_num;
if(NULL == (new_error->func_name = H5MM_xstrdup(current_error->func_name)))
@@ -953,7 +956,7 @@ H5E_get_current_stack(void)
done:
if(ret_value == NULL)
if(estack_copy)
- H5FL_FREE(H5E_t, estack_copy);
+ (void)H5FL_FREE(H5E_t, estack_copy);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5E_get_current_stack() */
@@ -981,7 +984,7 @@ H5Eset_current_stack(hid_t err_stack)
H5TRACE1("e", "i", err_stack);
if(err_stack != H5E_DEFAULT) {
- if(NULL == (estack = H5I_object_verify(err_stack, H5I_ERROR_STACK)))
+ if(NULL == (estack = (H5E_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
/* Set the current error stack */
@@ -1035,14 +1038,14 @@ H5E_set_current_stack(H5E_t *estack)
new_error = &(estack->slot[u]);
/* Increment the IDs to indicate that they are used in this stack */
- if(H5I_inc_ref(new_error->cls_id) < 0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to decrement ref count on error class")
+ if(H5I_inc_ref(new_error->cls_id, FALSE) < 0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error class")
current_error->cls_id = new_error->cls_id;
- if(H5I_inc_ref(new_error->maj_num) < 0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to decrement ref count on error class")
+ if(H5I_inc_ref(new_error->maj_num, FALSE) < 0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error class")
current_error->maj_num = new_error->maj_num;
- if(H5I_inc_ref(new_error->min_num) < 0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to decrement ref count on error class")
+ if(H5I_inc_ref(new_error->min_num, FALSE) < 0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error class")
current_error->min_num = new_error->min_num;
if(NULL == (current_error->func_name = H5MM_xstrdup(new_error->func_name)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
@@ -1087,7 +1090,7 @@ H5Eclose_stack(hid_t stack_id)
* Decrement the counter on the error stack. It will be freed if the count
* reaches zero.
*/
- if(H5I_dec_ref(stack_id)<0)
+ if(H5I_dec_ref(stack_id, TRUE)<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error stack")
} /* end if */
@@ -1120,7 +1123,7 @@ H5E_close_stack(H5E_t *estack)
H5E_clear_stack(estack);
/* Free the stack structure */
- H5FL_FREE(H5E_t, estack);
+ (void)H5FL_FREE(H5E_t, estack);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5E_close_stack() */
@@ -1158,7 +1161,7 @@ H5Eget_num(hid_t error_stack_id)
H5E_clear_stack(NULL);
/* Get the error stack to operate on */
- if(NULL == (estack = H5I_object_verify(error_stack_id, H5I_ERROR_STACK)))
+ if(NULL == (estack = (H5E_t *)H5I_object_verify(error_stack_id, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
} /* end else */
@@ -1226,7 +1229,7 @@ H5Epop(hid_t err_stack, size_t count)
H5E_clear_stack(NULL);
/* Get the error stack to operate on */
- if(NULL == (estack = H5I_object_verify(err_stack, H5I_ERROR_STACK)))
+ if(NULL == (estack = (H5E_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
} /* end else */
@@ -1270,7 +1273,6 @@ H5Epush2(hid_t err_stack, const char *file, const char *func, unsigned line,
{
va_list ap; /* Varargs info */
H5E_t *estack; /* Pointer to error stack to modify */
- H5E_msg_t *maj_ptr, *min_ptr; /* Pointer to major and minor error info */
#ifndef H5_HAVE_VASPRINTF
int tmp_len; /* Current size of description buffer */
int desc_len; /* Actual length of description when formatted */
@@ -1289,17 +1291,14 @@ H5Epush2(hid_t err_stack, const char *file, const char *func, unsigned line,
H5E_clear_stack(NULL);
/* Get the error stack to operate on */
- if(NULL == (estack = H5I_object_verify(err_stack, H5I_ERROR_STACK)))
+ if(NULL == (estack = (H5E_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
} /* end else */
- /* Check for mis-matches in major & minor error classes */
- if(NULL == (maj_ptr = H5I_object_verify(maj_id, H5I_ERROR_MSG)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error message ID")
- if(NULL == (min_ptr = H5I_object_verify(min_id, H5I_ERROR_MSG)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error message ID")
- if(maj_ptr->cls != min_ptr->cls)
- HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "major and minor errors not from same error class")
+/* Note that the variable-argument parsing for the format is identical in
+ * the H5E_printf_stack() routine - correct errors and make changes in both
+ * places. -QAK
+ */
/* Format the description */
va_start(ap, fmt);
@@ -1387,7 +1386,7 @@ H5Eclear2(hid_t err_stack)
/* Only clear the error stack if it's not the default stack */
H5E_clear_stack(NULL);
- if(NULL == (estack = H5I_object_verify(err_stack, H5I_ERROR_STACK)))
+ if(NULL == (estack = (H5E_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
} /* end else */
@@ -1434,7 +1433,7 @@ H5Eprint2(hid_t err_stack, FILE *stream)
/* Only clear the error stack if it's not the default stack */
H5E_clear_stack(NULL);
- if(NULL == (estack = H5I_object_verify(err_stack, H5I_ERROR_STACK)))
+ if(NULL == (estack = (H5E_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
} /* end else */
@@ -1480,7 +1479,7 @@ H5Ewalk2(hid_t err_stack, H5E_direction_t direction, H5E_walk2_t stack_func, voi
/* Only clear the error stack if it's not the default stack */
H5E_clear_stack(NULL);
- if(NULL == (estack = H5I_object_verify(err_stack, H5I_ERROR_STACK)))
+ if(NULL == (estack = (H5E_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
} /* end else */
@@ -1525,7 +1524,7 @@ H5Eget_auto2(hid_t estack_id, H5E_auto2_t *func, void **client_data)
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack")
} /* end if */
else
- if(NULL == (estack = H5I_object_verify(estack_id, H5I_ERROR_STACK)))
+ if(NULL == (estack = (H5E_t *)H5I_object_verify(estack_id, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
/* Get the automatic error reporting information */
@@ -1577,7 +1576,7 @@ H5Eset_auto2(hid_t estack_id, H5E_auto2_t func, void *client_data)
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack")
} /* end if */
else
- if(NULL == (estack = H5I_object_verify(estack_id, H5I_ERROR_STACK)))
+ if(NULL == (estack = (H5E_t *)H5I_object_verify(estack_id, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
/* Set the automatic error reporting information */
@@ -1620,7 +1619,7 @@ H5Eauto_is_v2(hid_t estack_id, unsigned *is_stack)
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack")
} /* end if */
else
- if(NULL == (estack = H5I_object_verify(estack_id, H5I_ERROR_STACK)))
+ if(NULL == (estack = (H5E_t *)H5I_object_verify(estack_id, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
/* Check if the error stack reporting function is the "newer" stack type */
diff --git a/src/H5EA.c b/src/H5EA.c
new file mode 100644
index 0000000..169c93f
--- /dev/null
+++ b/src/H5EA.c
@@ -0,0 +1,1150 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5EA.c
+ * Jun 17 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Implements an "extensible array" for storing elements
+ * in an array whose high bounds can extend and shrink.
+ *
+ * Please see the documentation in:
+ * doc/html/TechNotes/ExtensibleArray.html for a full
+ * description of how they work, etc.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/**********************/
+/* 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" /* Vector functions */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/* Typedef for generically unprotecting an object */
+typedef herr_t (*H5EA__unprotect_func_t)(void *thing, hid_t dxpl_id,
+ unsigned cache_flags);
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Extensible array client ID to class mapping */
+
+/* Remember to add client ID to H5EA_cls_id_t in H5EAprivate.h when adding a new
+ * client class..
+ */
+extern const H5EA_class_t H5EA_CLS_TEST[1];
+
+const H5EA_class_t *const H5EA_client_class_g[] = {
+ H5EA_CLS_TEST, /* 0 - H5EA_TEST_ID */
+};
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5EA_t struct */
+H5FL_DEFINE_STATIC(H5EA_t);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA_create
+ *
+ * Purpose: Creates a new empty extensible array in the file.
+ *
+ * Return: Pointer to earray wrapper on success
+ * NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jun 17 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+H5EA_t *, NULL, NULL,
+H5EA_create(H5F_t *f, hid_t dxpl_id, const H5EA_create_t *cparam, void *ctx_udata))
+
+ /* Local variables */
+ H5EA_t *ea = NULL; /* Pointer to new extensible array */
+ H5EA_hdr_t *hdr = NULL; /* The extensible array header information */
+ haddr_t ea_addr; /* Array header address */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(cparam);
+
+ /* H5EA interface sanity check */
+ HDcompile_assert(H5EA_NUM_CLS_ID == NELMTS(H5EA_client_class_g));
+
+ /* Create extensible array header */
+ if(HADDR_UNDEF == (ea_addr = H5EA__hdr_create(f, dxpl_id, cparam, ctx_udata)))
+ H5E_THROW(H5E_CANTINIT, "can't create extensible array header")
+
+ /* Allocate extensible array wrapper */
+ if(NULL == (ea = H5FL_MALLOC(H5EA_t)))
+ 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, ctx_udata, H5AC_WRITE)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header")
+
+ /* Point extensible array wrapper at header and bump it's ref count */
+ ea->hdr = hdr;
+ if(H5EA__hdr_incr(ea->hdr) < 0)
+ H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header")
+
+ /* Increment # of files using this array header */
+ if(H5EA__hdr_fuse_incr(ea->hdr) < 0)
+ H5E_THROW(H5E_CANTINC, "can't increment file reference count on shared array header")
+
+ /* Set file pointer for this array open context */
+ ea->f = f;
+
+ /* Set the return value */
+ ret_value = ea;
+
+CATCH
+
+ 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")
+ if(!ret_value)
+ if(ea && H5EA_close(ea, dxpl_id) < 0)
+ H5E_THROW(H5E_CLOSEERROR, "unable to close extensible array")
+
+END_FUNC(PRIV) /* end H5EA_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA_open
+ *
+ * Purpose: Opens an existing extensible array in the file.
+ *
+ * Return: Pointer to array wrapper on success
+ * NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 28 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+H5EA_t *, NULL, NULL,
+H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata))
+
+ /* Local variables */
+ H5EA_t *ea = NULL; /* Pointer to new extensible array wrapper */
+ H5EA_hdr_t *hdr = NULL; /* The extensible array header information */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(H5F_addr_defined(ea_addr));
+
+ /* Load 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, ctx_udata, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header, address = %llu", (unsigned long long)ea_addr)
+
+ /* Check for pending array deletion */
+ if(hdr->pending_delete)
+ H5E_THROW(H5E_CANTOPENOBJ, "can't open extensible array pending deletion")
+
+ /* Create fractal heap info */
+ if(NULL == (ea = H5FL_MALLOC(H5EA_t)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array info")
+
+ /* Point extensible array wrapper at header */
+ ea->hdr = hdr;
+ if(H5EA__hdr_incr(ea->hdr) < 0)
+ H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header")
+
+ /* Increment # of files using this array header */
+ if(H5EA__hdr_fuse_incr(ea->hdr) < 0)
+ H5E_THROW(H5E_CANTINC, "can't increment file reference count on shared array header")
+
+ /* Set file pointer for this array open context */
+ ea->f = f;
+
+ /* Set the return value */
+ ret_value = ea;
+
+CATCH
+
+ 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")
+ if(!ret_value)
+ if(ea && H5EA_close(ea, dxpl_id) < 0)
+ H5E_THROW(H5E_CLOSEERROR, "unable to close extensible array")
+
+END_FUNC(PRIV) /* end H5EA_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA_get_nelmts
+ *
+ * Purpose: Query the current number of elements in array
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 21 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, NOERR,
+herr_t, SUCCEED, -,
+H5EA_get_nelmts(const H5EA_t *ea, hsize_t *nelmts))
+
+ /* Local variables */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(ea);
+ HDassert(nelmts);
+
+ /* Retrieve the max. index set */
+ *nelmts = ea->hdr->stats.stored.max_idx_set;
+
+END_FUNC(PRIV) /* end H5EA_get_nelmts() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA_get_addr
+ *
+ * Purpose: Query the address of the array
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 21 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, NOERR,
+herr_t, SUCCEED, -,
+H5EA_get_addr(const H5EA_t *ea, haddr_t *addr))
+
+ /* Local variables */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(ea);
+ HDassert(ea->hdr);
+ HDassert(addr);
+
+ /* Retrieve the address of the extensible array's header */
+ *addr = ea->hdr->addr;
+
+END_FUNC(PRIV) /* end H5EA_get_addr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA_lookup_elmt
+ *
+ * Purpose: Retrieve the metadata object and the element buffer for a
+ * given element in the array.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 9 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__lookup_elmt(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, H5AC_protect_t thing_acc,
+ void **thing, uint8_t **thing_elmt_buf, hsize_t *thing_elmt_idx,
+ H5EA__unprotect_func_t *thing_unprot_func))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = ea->hdr; /* Header for EA */
+ 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 */
+ hbool_t stats_changed = FALSE; /* Whether array statistics changed */
+ hbool_t hdr_dirty = FALSE; /* Whether the array header changed */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx);
+#endif /* QAK */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(ea);
+ HDassert(hdr);
+ HDassert(thing);
+ HDassert(thing_elmt_buf);
+ HDassert(thing_unprot_func);
+
+ /* Set the shared array header's file context for this operation */
+ hdr->f = ea->f;
+
+ /* Reset the pointers to the 'thing' info */
+ *thing = NULL;
+ *thing_elmt_buf = NULL;
+ *thing_elmt_idx = 0;
+ *thing_unprot_func = (H5EA__unprotect_func_t)NULL;
+
+ /* 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 */
+ /* Check if we are allowed to create the thing */
+ if(H5AC_WRITE == thing_acc) {
+ /* Create the index block */
+ hdr->idx_blk_addr = H5EA__iblock_create(hdr, dxpl_id, &stats_changed);
+ if(!H5F_addr_defined(hdr->idx_blk_addr))
+ H5E_THROW(H5E_CANTCREATE, "unable to create index block")
+ hdr_dirty = TRUE;
+ } /* end if */
+ else
+ H5_LEAVE(SUCCEED)
+ } /* 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, thing_acc)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array index block, address = %llu", (unsigned long long)hdr->idx_blk_addr)
+
+ /* Check if element is in index block */
+ if(idx < hdr->cparam.idx_blk_elmts) {
+ /* Set 'thing' info to refer to the index block */
+ *thing = iblock;
+ *thing_elmt_buf = (uint8_t *)iblock->elmts;
+ *thing_elmt_idx = idx;
+ *thing_unprot_func = (H5EA__unprotect_func_t)H5EA__iblock_unprotect;
+ } /* end if */
+ else {
+ unsigned sblk_idx; /* Which superblock does this index fall in? */
+ size_t dblk_idx; /* Data block index */
+ 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);
+#ifdef QAK
+HDfprintf(stderr, "%s: sblk_idx = %u, iblock->nsblks = %Zu\n", FUNC, sblk_idx, iblock->nsblks);
+#endif /* QAK */
+
+ /* Adjust index to offset in super block */
+ elmt_idx = idx - (hdr->cparam.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) {
+#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, iblock->ndblk_addrs = %Zu\n", FUNC, dblk_idx, iblock->ndblk_addrs);
+#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])) {
+ /* Check if we are allowed to create the thing */
+ if(H5AC_WRITE == thing_acc) {
+ haddr_t dblk_addr; /* Address of data block created */
+ hsize_t dblk_off; /* Offset of data block in array */
+
+ /* Create data block */
+ dblk_off = hdr->sblk_info[sblk_idx].start_idx + (dblk_idx * hdr->sblk_info[sblk_idx].dblk_nelmts);
+ dblk_addr = H5EA__dblock_create(hdr, dxpl_id, iblock, &stats_changed, dblk_off, 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;
+ } /* end if */
+ else
+ H5_LEAVE(SUCCEED)
+ } /* end if */
+
+ /* Protect data block */
+ if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, iblock, iblock->dblk_addrs[dblk_idx], hdr->sblk_info[sblk_idx].dblk_nelmts, thing_acc)))
+ 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 'thing' info to refer to the data block */
+ *thing = dblock;
+ *thing_elmt_buf = (uint8_t *)dblock->elmts;
+ *thing_elmt_idx = elmt_idx;
+ *thing_unprot_func = (H5EA__unprotect_func_t)H5EA__dblock_unprotect;
+ } /* end if */
+ else {
+ size_t sblk_off; /* Offset of super block in index block array of super blocks */
+
+ /* Calculate offset of super block in index block's array */
+ sblk_off = sblk_idx - iblock->nsblks;
+
+ /* Check if the super block has been allocated on disk yet */
+ if(!H5F_addr_defined(iblock->sblk_addrs[sblk_off])) {
+ /* Check if we are allowed to create the thing */
+ if(H5AC_WRITE == thing_acc) {
+ haddr_t sblk_addr; /* Address of data block created */
+
+ /* Create super block */
+ sblk_addr = H5EA__sblock_create(hdr, dxpl_id, iblock, &stats_changed, sblk_idx);
+#ifdef QAK
+HDfprintf(stderr, "%s: New super block address is: %a\n", FUNC, sblk_addr);
+#endif /* QAK */
+ if(!H5F_addr_defined(sblk_addr))
+ H5E_THROW(H5E_CANTCREATE, "unable to create extensible array super block")
+
+ /* Set super block address in index block */
+ iblock->sblk_addrs[sblk_off] = sblk_addr;
+ iblock_cache_flags |= H5AC__DIRTIED_FLAG;
+ } /* end if */
+ else
+ H5_LEAVE(SUCCEED)
+ } /* end if */
+
+ /* Protect super block */
+ if(NULL == (sblock = H5EA__sblock_protect(hdr, dxpl_id, iblock, iblock->sblk_addrs[sblk_off], sblk_idx, thing_acc)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array super block, address = %llu", (unsigned long long)iblock->sblk_addrs[sblk_off])
+
+ /* Compute the data block index in super block */
+ dblk_idx = (size_t)(elmt_idx / sblock->dblk_nelmts);
+#ifdef QAK
+HDfprintf(stderr, "%s: dblk_idx = %u, sblock->ndblks = %Zu\n", FUNC, dblk_idx, sblock->ndblks);
+#endif /* QAK */
+ HDassert(dblk_idx < sblock->ndblks);
+
+ /* Check if the data block has been allocated on disk yet */
+ if(!H5F_addr_defined(sblock->dblk_addrs[dblk_idx])) {
+ /* Check if we are allowed to create the thing */
+ if(H5AC_WRITE == thing_acc) {
+ haddr_t dblk_addr; /* Address of data block created */
+ hsize_t dblk_off; /* Offset of data block in array */
+
+ /* Create data block */
+ dblk_off = hdr->sblk_info[sblk_idx].start_idx + (dblk_idx * hdr->sblk_info[sblk_idx].dblk_nelmts);
+ dblk_addr = H5EA__dblock_create(hdr, dxpl_id, sblock, &stats_changed, dblk_off, sblock->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 */
+ sblock->dblk_addrs[dblk_idx] = dblk_addr;
+ sblock_cache_flags |= H5AC__DIRTIED_FLAG;
+ } /* end if */
+ else
+ H5_LEAVE(SUCCEED)
+ } /* end if */
+
+#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)) {
+ /* Check if we are allowed to create the thing */
+ if(H5AC_WRITE == thing_acc) {
+ /* Create the data block page */
+ if(H5EA__dblk_page_create(hdr, dxpl_id, sblock, 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 */
+ else
+ H5_LEAVE(SUCCEED)
+ } /* end if */
+
+ /* Protect data block page */
+ if(NULL == (dblk_page = H5EA__dblk_page_protect(hdr, dxpl_id, sblock, dblk_page_addr, thing_acc)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block page, address = %llu", (unsigned long long)dblk_page_addr)
+
+ /* Set 'thing' info to refer to the data block page */
+ *thing = dblk_page;
+ *thing_elmt_buf = (uint8_t *)dblk_page->elmts;
+ *thing_elmt_idx = elmt_idx;
+ *thing_unprot_func = (H5EA__unprotect_func_t)H5EA__dblk_page_unprotect;
+ } /* end if */
+ else {
+ /* Protect data block */
+ if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, sblock, sblock->dblk_addrs[dblk_idx], sblock->dblk_nelmts, thing_acc)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long long)sblock->dblk_addrs[dblk_idx])
+
+ /* Set 'thing' info to refer to the data block */
+ *thing = dblock;
+ *thing_elmt_buf = (uint8_t *)dblock->elmts;
+ *thing_elmt_idx = elmt_idx;
+ *thing_unprot_func = (H5EA__unprotect_func_t)H5EA__dblock_unprotect;
+ } /* end else */
+ } /* end else */
+ } /* end else */
+
+CATCH
+ /* Reset 'thing' info on error */
+ if(ret_value < 0) {
+ *thing = NULL;
+ *thing_elmt_buf = NULL;
+ *thing_elmt_idx = 0;
+ *thing_unprot_func = (H5EA__unprotect_func_t)NULL;
+ } /* end if */
+
+ /* Check for updating array statistics */
+ if(stats_changed)
+ hdr_dirty = TRUE;
+
+ /* 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")
+
+ /* Release resources */
+ if(iblock && *thing != iblock && H5EA__iblock_unprotect(iblock, dxpl_id, iblock_cache_flags) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array index block")
+ /* (Note: super blocks don't contain elements, so don't have a '*thing != sblock' check) */
+ if(sblock && H5EA__sblock_unprotect(sblock, dxpl_id, sblock_cache_flags) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array super block")
+ if(dblock && *thing != 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 && *thing != 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(STATIC) /* end H5EA_lookup_elmt() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA_set
+ *
+ * Purpose: Set an element of an extensible array
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 9 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+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 */
+ void *thing = NULL; /* Pointer to the array metadata containing the array index we are interested in */
+ uint8_t *thing_elmt_buf; /* Pointer to the element buffer for the array metadata */
+ hsize_t thing_elmt_idx; /* Index of the element in the element buffer for the array metadata */
+ H5EA__unprotect_func_t thing_unprot_func; /* Function pointer for unprotecting the array metadata */
+ unsigned thing_cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting array metadata */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx);
+#endif /* QAK */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(ea);
+ HDassert(hdr);
+
+ /* Set the shared array header's file context for this operation */
+ hdr->f = ea->f;
+
+ /* Look up the array metadata containing the element we want to set */
+ if(H5EA__lookup_elmt(ea, dxpl_id, idx, H5AC_WRITE, &thing, &thing_elmt_buf, &thing_elmt_idx, &thing_unprot_func) < 0)
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect array metadata")
+
+ /* Sanity check */
+ HDassert(thing);
+ HDassert(thing_elmt_buf);
+ HDassert(thing_unprot_func);
+
+ /* Set element in thing's element buffer */
+ HDmemcpy(thing_elmt_buf + (hdr->cparam.cls->nat_elmt_size * thing_elmt_idx), elmt, hdr->cparam.cls->nat_elmt_size);
+ thing_cache_flags |= H5AC__DIRTIED_FLAG;
+
+ /* Update max. element set in array, if appropriate */
+#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.stored.max_idx_set) {
+ /* Update the max index for the array */
+ hdr->stats.stored.max_idx_set = idx + 1;
+ if(H5EA__hdr_modified(hdr) < 0)
+ H5E_THROW(H5E_CANTMARKDIRTY, "unable to mark extensible array header as modified")
+ } /* end if */
+
+CATCH
+ /* Release resources */
+ if(thing && (thing_unprot_func)(thing, dxpl_id, thing_cache_flags) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array metadata")
+
+END_FUNC(PRIV) /* end H5EA_set() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA_get
+ *
+ * Purpose: Get an element of an extensible array
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+herr_t, SUCCEED, FAIL,
+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 */
+ void *thing = NULL; /* Pointer to the array metadata containing the array index we are interested in */
+ H5EA__unprotect_func_t thing_unprot_func; /* Function pointer for unprotecting the array metadata */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx);
+#endif /* QAK */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(ea);
+ HDassert(hdr);
+
+ /* Check for element beyond max. element in array */
+ if(idx >= hdr->stats.stored.max_idx_set) {
+#ifdef QAK
+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->cparam.cls->fill)(elmt, (size_t)1) < 0)
+ H5E_THROW(H5E_CANTSET, "can't set element to class's fill value")
+ } /* end if */
+ else {
+ uint8_t *thing_elmt_buf; /* Pointer to the element buffer for the array metadata */
+ hsize_t thing_elmt_idx; /* Index of the element in the element buffer for the array metadata */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Index block address is: %a\n", FUNC, hdr->idx_blk_addr);
+#endif /* QAK */
+
+ /* Set the shared array header's file context for this operation */
+ hdr->f = ea->f;
+
+ /* Look up the array metadata containing the element we want to set */
+ if(H5EA__lookup_elmt(ea, dxpl_id, idx, H5AC_READ, &thing, &thing_elmt_buf, &thing_elmt_idx, &thing_unprot_func) < 0)
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect array metadata")
+
+ /* Check if the thing holding the element has been created yet */
+ if(NULL == thing) {
+ /* 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")
+ } /* end if */
+ else
+ /* Get element from thing's element buffer */
+ HDmemcpy(elmt, thing_elmt_buf + (hdr->cparam.cls->nat_elmt_size * thing_elmt_idx), hdr->cparam.cls->nat_elmt_size);
+ } /* end else */
+
+CATCH
+ /* Release thing */
+ if(thing && (thing_unprot_func)(thing, dxpl_id, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array metadata")
+
+END_FUNC(PRIV) /* end H5EA_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA_depend
+ *
+ * Purpose: Make a child flush dependency between the extensible array's
+ * header and another piece of metadata in the file.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * May 27 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA_depend(H5AC_info_t *parent_entry, H5EA_t *ea))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = ea->hdr; /* Header for EA */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(ea);
+ HDassert(hdr);
+
+ /* Set the shared array header's file context for this operation */
+ hdr->f = ea->f;
+
+ /* Set up flush dependency between child_entry and metadata array 'thing' */
+ if(H5EA__create_flush_depend(hdr, parent_entry, (H5AC_info_t *)hdr) < 0)
+ H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency on file metadata")
+
+CATCH
+
+END_FUNC(PRIV) /* end H5EA_depend() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA_undepend
+ *
+ * Purpose: Remove a child flush dependency between the extensible array's
+ * header and another piece of metadata in the file.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * May 27 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA_undepend(H5AC_info_t *parent_entry, H5EA_t *ea))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = ea->hdr; /* Header for EA */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(ea);
+ HDassert(hdr);
+
+ /* Set the shared array header's file context for this operation */
+ hdr->f = ea->f;
+
+ /* Remove flush dependency between child_entry and metadata array 'thing' */
+ if(H5EA__destroy_flush_depend(hdr, parent_entry, (H5AC_info_t *)hdr) < 0)
+ H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency on file metadata")
+
+CATCH
+
+END_FUNC(PRIV) /* end H5EA_undepend() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA_support
+ *
+ * Purpose: Create a child flush dependency on the array metadata that
+ * contains the element for an array index.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * May 21 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA_support(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, H5AC_info_t *child_entry))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = ea->hdr; /* Header for EA */
+ void *thing = NULL; /* Pointer to the array metadata containing the array index we are interested in */
+ uint8_t *thing_elmt_buf; /* Pointer to the element buffer for the array metadata */
+ hsize_t thing_elmt_idx; /* Index of the element in the element buffer for the array metadata */
+ H5EA__unprotect_func_t thing_unprot_func; /* Function pointer for unprotecting the array metadata */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx);
+#endif /* QAK */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(ea);
+ HDassert(hdr);
+
+ /* Set the shared array header's file context for this operation */
+ hdr->f = ea->f;
+
+ /* Look up the array metadata containing the element we want to set */
+ if(H5EA__lookup_elmt(ea, dxpl_id, idx, H5AC_WRITE, &thing, &thing_elmt_buf, &thing_elmt_idx, &thing_unprot_func) < 0)
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect array metadata")
+
+ /* Sanity check */
+ HDassert(thing);
+ HDassert(thing_elmt_buf);
+ HDassert(thing_unprot_func);
+
+ /* Set up flush dependency between child_entry and metadata array 'thing' */
+ if(H5EA__create_flush_depend(hdr, (H5AC_info_t *)thing, child_entry) < 0)
+ H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency on array metadata")
+
+CATCH
+ /* Release resources */
+ if(thing && (thing_unprot_func)(thing, dxpl_id, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array metadata")
+
+END_FUNC(PRIV) /* end H5EA_support() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA_unsupport
+ *
+ * Purpose: Remove a flush dependency on the array metadata that contains
+ * the element for an array index.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * May 21 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA_unsupport(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, H5AC_info_t *child_entry))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = ea->hdr; /* Header for EA */
+ void *thing = NULL; /* Pointer to the array metadata containing the array index we are interested in */
+ uint8_t *thing_elmt_buf; /* Pointer to the element buffer for the array metadata */
+ hsize_t thing_elmt_idx; /* Index of the element in the element buffer for the array metadata */
+ H5EA__unprotect_func_t thing_unprot_func; /* Function pointer for unprotecting the array metadata */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx);
+#endif /* QAK */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(ea);
+ HDassert(hdr);
+
+ /* Set the shared array header's file context for this operation */
+ hdr->f = ea->f;
+
+ /* Look up the array metadata containing the element we want to set */
+ if(H5EA__lookup_elmt(ea, dxpl_id, idx, H5AC_READ, &thing, &thing_elmt_buf, &thing_elmt_idx, &thing_unprot_func) < 0)
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect array metadata")
+
+ /* Sanity check */
+ HDassert(thing);
+ HDassert(thing_elmt_buf);
+ HDassert(thing_unprot_func);
+
+ /* Remove flush dependency between child_entry and metadata array 'thing' */
+ if(H5EA__destroy_flush_depend(hdr, (H5AC_info_t *)thing, child_entry) < 0)
+ H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency on array metadata")
+
+CATCH
+ /* Release resources */
+ if(thing && (thing_unprot_func)(thing, dxpl_id, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array metadata")
+
+END_FUNC(PRIV) /* end H5EA_unsupport() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA_close
+ *
+ * Purpose: Close an extensible array
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 21 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA_close(H5EA_t *ea, hid_t dxpl_id))
+
+ /* Local variables */
+ hbool_t pending_delete = FALSE; /* Whether the array is pending deletion */
+ haddr_t ea_addr = HADDR_UNDEF; /* Address of array (for deletion) */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(ea);
+
+ /* Decrement file reference & check if this is the last open extensible array using the shared array header */
+ if(0 == H5EA__hdr_fuse_decr(ea->hdr)) {
+ /* Set the shared array header's file context for this operation */
+ ea->hdr->f = ea->f;
+
+ /* Shut down anything that can't be put in the header's 'flush' callback */
+
+ /* Check for pending array deletion */
+ if(ea->hdr->pending_delete) {
+ /* Set local info, so array deletion can occur after decrementing the
+ * header's ref count
+ */
+ pending_delete = TRUE;
+ ea_addr = ea->hdr->addr;
+ } /* end if */
+ } /* end if */
+
+ /* Check for pending array deletion */
+ if(pending_delete) {
+ H5EA_hdr_t *hdr; /* Another pointer to extensible array header */
+
+#ifndef NDEBUG
+{
+ unsigned hdr_status = 0; /* Header's status in the metadata cache */
+
+ /* Check the header's status in the metadata cache */
+ if(H5AC_get_entry_status(ea->f, ea_addr, &hdr_status) < 0)
+ H5E_THROW(H5E_CANTGET, "unable to check metadata cache status for extensible array header")
+
+ /* Sanity checks on header */
+ HDassert(hdr_status & H5AC_ES__IN_CACHE);
+ HDassert(hdr_status & H5AC_ES__IS_PINNED);
+ HDassert(!(hdr_status & H5AC_ES__IS_PROTECTED));
+}
+#endif /* NDEBUG */
+
+ /* Lock the array header into memory */
+ /* (OK to pass in NULL for callback context, since we know the header must be in the cache) */
+ if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(ea->f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, NULL, H5AC_WRITE)))
+ H5E_THROW(H5E_CANTLOAD, "unable to load extensible array header")
+
+ /* Set the shared array header's file context for this operation */
+ hdr->f = ea->f;
+
+ /* Decrement the reference count on the array header */
+ /* (don't put in H5EA_hdr_fuse_decr() as the array header may be evicted
+ * immediately -QAK)
+ */
+ if(H5EA__hdr_decr(ea->hdr) < 0)
+ H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header")
+
+ /* Delete array, starting with header (unprotects header) */
+ if(H5EA__hdr_delete(hdr, dxpl_id) < 0)
+ H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array")
+ } /* end if */
+ else {
+ /* Decrement the reference count on the array header */
+ /* (don't put in H5EA_hdr_fuse_decr() as the array header may be evicted
+ * immediately -QAK)
+ */
+ if(H5EA__hdr_decr(ea->hdr) < 0)
+ H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header")
+ } /* end else */
+
+ /* Release the extensible array wrapper */
+ ea = (H5EA_t *)H5FL_FREE(H5EA_t, ea);
+
+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, void *ctx_udata))
+
+ /* 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, ctx_udata, 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
new file mode 100644
index 0000000..5138ae4
--- /dev/null
+++ b/src/H5EAcache.c
@@ -0,0 +1,2106 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5EAcache.c
+ * Aug 26 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Implement extensible array metadata cache methods.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/**********************/
+/* 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 */
+#include "H5Vprivate.h" /* Vectors and arrays */
+#include "H5WBprivate.h" /* Wrapped Buffers */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* Fractal heap format version #'s */
+#define H5EA_HDR_VERSION 0 /* Header */
+#define H5EA_IBLOCK_VERSION 0 /* Index block */
+#define H5EA_SBLOCK_VERSION 0 /* Super block */
+#define H5EA_DBLOCK_VERSION 0 /* Data block */
+
+/* Size of stack buffer for serialization buffers */
+#define H5EA_HDR_BUF_SIZE 512
+#define H5EA_IBLOCK_BUF_SIZE 512
+#define H5EA_SBLOCK_BUF_SIZE 512
+#define H5EA_DBLOCK_BUF_SIZE 512
+#define H5EA_DBLK_PAGE_BUF_SIZE 512
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* Metadata cache (H5AC) callbacks */
+static H5EA_hdr_t *H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2);
+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 * 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 herr_t H5EA__cache_hdr_dest(H5F_t *f, H5EA_hdr_t *hdr);
+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 * 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_notify(H5AC_notify_action_t action, H5EA_iblock_t *iblock);
+static herr_t H5EA__cache_iblock_size(const H5F_t *f, const H5EA_iblock_t *iblock, size_t *size_ptr);
+static herr_t H5EA__cache_iblock_dest(H5F_t *f, H5EA_iblock_t *iblock);
+static H5EA_sblock_t *H5EA__cache_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2);
+static herr_t H5EA__cache_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5EA_sblock_t *sblock, unsigned * flags_ptr);
+static herr_t H5EA__cache_sblock_clear(H5F_t *f, H5EA_sblock_t *sblock, hbool_t destroy);
+static herr_t H5EA__cache_sblock_size(const H5F_t *f, const H5EA_sblock_t *sblock, size_t *size_ptr);
+static herr_t H5EA__cache_sblock_notify(H5AC_notify_action_t action, H5EA_sblock_t *sblock);
+static herr_t H5EA__cache_sblock_dest(H5F_t *f, H5EA_sblock_t *sblock);
+static H5EA_dblock_t *H5EA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2);
+static herr_t H5EA__cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5EA_dblock_t *dblock, unsigned * flags_ptr);
+static herr_t H5EA__cache_dblock_clear(H5F_t *f, H5EA_dblock_t *dblock, hbool_t destroy);
+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_notify(H5AC_notify_action_t action, H5EA_dblock_t *dblock);
+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_notify(H5AC_notify_action_t action, H5EA_dblk_page_t *dblk_page);
+static herr_t H5EA__cache_dblk_page_dest(H5F_t *f, H5EA_dblk_page_t *dblk_page);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* H5EA header inherits cache-like properties from H5AC */
+const H5AC_class_t H5AC_EARRAY_HDR[1] = {{
+ H5AC_EARRAY_HDR_ID,
+ (H5AC_load_func_t)H5EA__cache_hdr_load,
+ (H5AC_flush_func_t)H5EA__cache_hdr_flush,
+ (H5AC_dest_func_t)H5EA__cache_hdr_dest,
+ (H5AC_clear_func_t)H5EA__cache_hdr_clear,
+ (H5AC_notify_func_t)NULL,
+ (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_notify_func_t)H5EA__cache_iblock_notify,
+ (H5AC_size_func_t)H5EA__cache_iblock_size,
+}};
+
+/* H5EA super block inherits cache-like properties from H5AC */
+const H5AC_class_t H5AC_EARRAY_SBLOCK[1] = {{
+ H5AC_EARRAY_SBLOCK_ID,
+ (H5AC_load_func_t)H5EA__cache_sblock_load,
+ (H5AC_flush_func_t)H5EA__cache_sblock_flush,
+ (H5AC_dest_func_t)H5EA__cache_sblock_dest,
+ (H5AC_clear_func_t)H5EA__cache_sblock_clear,
+ (H5AC_notify_func_t)H5EA__cache_sblock_notify,
+ (H5AC_size_func_t)H5EA__cache_sblock_size,
+}};
+
+/* H5EA data block inherits cache-like properties from H5AC */
+const H5AC_class_t H5AC_EARRAY_DBLOCK[1] = {{
+ H5AC_EARRAY_DBLOCK_ID,
+ (H5AC_load_func_t)H5EA__cache_dblock_load,
+ (H5AC_flush_func_t)H5EA__cache_dblock_flush,
+ (H5AC_dest_func_t)H5EA__cache_dblock_dest,
+ (H5AC_clear_func_t)H5EA__cache_dblock_clear,
+ (H5AC_notify_func_t)H5EA__cache_dblock_notify,
+ (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_notify_func_t)H5EA__cache_dblk_page_notify,
+ (H5AC_size_func_t)H5EA__cache_dblk_page_size,
+}};
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_hdr_load
+ *
+ * Purpose: Loads an extensible array header from the disk.
+ *
+ * Return: Success: Pointer to a new extensible array
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 26 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+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 *ctx_udata))
+
+ /* Local variables */
+ H5EA_cls_id_t id; /* ID of extensible array class, as found in file */
+ 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 */
+ uint8_t *buf; /* Pointer to header 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 */
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+
+ /* Allocate space for the extensible array data structure */
+ if(NULL == (hdr = H5EA__hdr_alloc(f)))
+ 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 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 extensible array header on disk */
+ size = H5EA_HEADER_SIZE(hdr);
+
+ /* Get a pointer to a buffer that's large enough for serialized header */
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
+ H5E_THROW(H5E_CANTGET, "can't get actual buffer")
+
+ /* Read header from disk */
+ if(H5F_block_read(f, H5FD_MEM_EARRAY_HDR, addr, size, dxpl_id, buf) < 0)
+ H5E_THROW(H5E_READERROR, "can't read extensible array header")
+
+ /* Get temporary pointer to serialized header */
+ p = buf;
+
+ /* Magic number */
+ if(HDmemcmp(p, H5EA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC))
+ H5E_THROW(H5E_BADVALUE, "wrong extensible array header signature")
+ p += H5_SIZEOF_MAGIC;
+
+ /* Version */
+ if(*p++ != H5EA_HDR_VERSION)
+ H5E_THROW(H5E_VERSION, "wrong extensible array header version")
+
+ /* Extensible array class */
+ id = *p++;
+ if(id >= H5EA_NUM_CLS_ID)
+ H5E_THROW(H5E_BADTYPE, "incorrect extensible array class")
+ hdr->cparam.cls = H5EA_client_class_g[id];
+
+ /* General array creation/configuration information */
+ hdr->cparam.raw_elmt_size = *p++; /* Element size in file (in bytes) */
+ hdr->cparam.max_nelmts_bits = *p++; /* Log2(Max. # of elements in array) - i.e. # of bits needed to store max. # of elements */
+ hdr->cparam.idx_blk_elmts = *p++; /* # of elements to store in index block */
+ hdr->cparam.data_blk_min_elmts = *p++; /* Min. # of elements per data block */
+ hdr->cparam.sup_blk_min_data_ptrs = *p++; /* Min. # of data block pointers for a super block */
+ hdr->cparam.max_dblk_page_nelmts_bits = *p++; /* Log2(Max. # of elements in data block page) - i.e. # of bits needed to store max. # of elements in data block page */
+
+ /* Array statistics */
+ hdr->stats.computed.hdr_size = size; /* Size of header in file */
+ H5F_DECODE_LENGTH(f, p, hdr->stats.stored.nsuper_blks); /* Number of super blocks created */
+ H5F_DECODE_LENGTH(f, p, hdr->stats.stored.super_blk_size); /* Size of super blocks created */
+ H5F_DECODE_LENGTH(f, p, hdr->stats.stored.ndata_blks); /* Number of data blocks created */
+ H5F_DECODE_LENGTH(f, p, hdr->stats.stored.data_blk_size); /* Size of data blocks created */
+ H5F_DECODE_LENGTH(f, p, hdr->stats.stored.max_idx_set); /* Max. index set (+1) */
+ H5F_DECODE_LENGTH(f, p, hdr->stats.stored.nelmts); /* Number of elements 'realized' */
+
+ /* Internal information */
+ H5F_addr_decode(f, &p, &hdr->idx_blk_addr); /* Address of index block */
+
+ /* Index block statistics */
+ if(H5F_addr_defined(hdr->idx_blk_addr)) {
+ H5EA_iblock_t iblock; /* Fake index block for computing size */
+
+ /* Set index block count for file */
+ hdr->stats.computed.nindex_blks = 1;
+
+ /* Set up fake index block for computing size on disk */
+ iblock.hdr = hdr;
+ iblock.nsblks = H5EA_SBLK_FIRST_IDX(hdr->cparam.sup_blk_min_data_ptrs);
+ iblock.ndblk_addrs = 2 * ((size_t)hdr->cparam.sup_blk_min_data_ptrs - 1);
+ iblock.nsblk_addrs = hdr->nsblks - iblock.nsblks;
+
+ /* Compute size of index block in file */
+ hdr->stats.computed.index_blk_size = H5EA_IBLOCK_SIZE(&iblock);
+ } /* end if */
+ else {
+ hdr->stats.computed.nindex_blks = 0; /* Number of index blocks in file */
+ hdr->stats.computed.index_blk_size = 0; /* Size of index blocks in file */
+ } /* end else */
+
+ /* Sanity check */
+ /* (allow for checksum not decoded yet) */
+ HDassert((size_t)(p - buf) == (size - H5EA_SIZEOF_CHKSUM));
+
+ /* Compute checksum on entire header */
+ /* (including the filter information, if present) */
+ computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
+
+ /* Metadata checksum */
+ UINT32DECODE(p, stored_chksum);
+
+ /* Sanity check */
+ HDassert((size_t)(p - buf) == size);
+
+ /* Verify checksum */
+ if(stored_chksum != computed_chksum)
+ H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array header")
+
+ /* Finish initializing extensible array header */
+ if(H5EA__hdr_init(hdr, ctx_udata) < 0)
+ H5E_THROW(H5E_CANTINIT, "initialization failed for extensible array header")
+ HDassert(hdr->size == size);
+
+ /* Set return value */
+ ret_value = hdr;
+
+CATCH
+
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer")
+ if(!ret_value)
+ if(hdr && H5EA__cache_hdr_dest(f, hdr) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array header")
+
+END_FUNC(STATIC) /* end H5EA__cache_hdr_load() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_hdr_flush
+ *
+ * Purpose: Flushes a dirty extensible array header to disk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 26 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+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))
+
+ H5WB_t *wb = NULL; /* Wrapped buffer for header data */
+ uint8_t hdr_buf[H5EA_HDR_BUF_SIZE]; /* Buffer for header */
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(hdr);
+
+ if(hdr->cache_info.is_dirty) {
+ uint8_t *buf; /* Temporary raw data buffer */
+ uint8_t *p; /* Pointer into raw data buffer */
+ size_t size; /* Header size on disk */
+ uint32_t metadata_chksum; /* Computed metadata checksum value */
+
+ /* Wrap the local buffer for serialized header info */
+ if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
+ H5E_THROW(H5E_CANTINIT, "can't wrap buffer")
+
+ /* 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 */
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
+ H5E_THROW(H5E_CANTGET, "can't get actual buffer")
+
+ /* Get temporary pointer to serialized header */
+ p = buf;
+
+ /* Magic number */
+ HDmemcpy(p, H5EA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
+
+ /* Version # */
+ *p++ = H5EA_HDR_VERSION;
+
+ /* Extensible array type */
+ *p++ = hdr->cparam.cls->id;
+
+ /* General array creation/configuration information */
+ *p++ = hdr->cparam.raw_elmt_size; /* Element size in file (in bytes) */
+ *p++ = hdr->cparam.max_nelmts_bits; /* Log2(Max. # of elements in array) - i.e. # of bits needed to store max. # of elements */
+ *p++ = hdr->cparam.idx_blk_elmts; /* # of elements to store in index block */
+ *p++ = hdr->cparam.data_blk_min_elmts; /* Min. # of elements per data block */
+ *p++ = hdr->cparam.sup_blk_min_data_ptrs; /* Min. # of data block pointers for a super block */
+ *p++ = hdr->cparam.max_dblk_page_nelmts_bits; /* Log2(Max. # of elements in data block page) - i.e. # of bits needed to store max. # of elements in data block page */
+
+ /* Array statistics */
+ H5F_ENCODE_LENGTH(f, p, hdr->stats.stored.nsuper_blks); /* Number of super blocks created */
+ H5F_ENCODE_LENGTH(f, p, hdr->stats.stored.super_blk_size); /* Size of super blocks created */
+ H5F_ENCODE_LENGTH(f, p, hdr->stats.stored.ndata_blks); /* Number of data blocks created */
+ H5F_ENCODE_LENGTH(f, p, hdr->stats.stored.data_blk_size); /* Size of data blocks created */
+ H5F_ENCODE_LENGTH(f, p, hdr->stats.stored.max_idx_set); /* Max. index set (+1) */
+ H5F_ENCODE_LENGTH(f, p, hdr->stats.stored.nelmts); /* Number of elements 'realized' */
+
+ /* Internal information */
+ H5F_addr_encode(f, &p, hdr->idx_blk_addr); /* Address of index block */
+
+ /* Compute metadata checksum */
+ metadata_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
+
+ /* Metadata checksum */
+ UINT32ENCODE(p, metadata_chksum);
+
+ /* Write the array header. */
+ HDassert((size_t)(p - buf) == size);
+ if(H5F_block_write(f, H5FD_MEM_EARRAY_HDR, addr, size, dxpl_id, buf) < 0)
+ H5E_THROW(H5E_WRITEERROR, "unable to save extensible array header to disk")
+
+ hdr->cache_info.is_dirty = FALSE;
+ } /* end if */
+
+ if(destroy)
+ if(H5EA__cache_hdr_dest(f, hdr) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array header")
+
+CATCH
+
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer")
+
+END_FUNC(STATIC) /* end H5EA__cache_hdr_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_hdr_clear
+ *
+ * Purpose: Mark a extensible array header in memory as non-dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 26 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_hdr_clear(H5F_t *f, H5EA_hdr_t *hdr, hbool_t destroy))
+
+ /* Sanity check */
+ HDassert(hdr);
+
+ /* Reset the dirty flag. */
+ hdr->cache_info.is_dirty = FALSE;
+
+ if(destroy)
+ if(H5EA__cache_hdr_dest(f, hdr) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array header")
+
+CATCH
+
+END_FUNC(STATIC) /* end H5EA__cache_hdr_clear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_hdr_size
+ *
+ * Purpose: Compute the size in bytes of a extensible array header
+ * 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
+ * Aug 26 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+H5EA__cache_hdr_size(const H5F_t UNUSED *f, const H5EA_hdr_t *hdr,
+ size_t *size_ptr))
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(hdr);
+ HDassert(size_ptr);
+
+ /* Set size value */
+ *size_ptr = hdr->size;
+
+END_FUNC(STATIC) /* end H5EA__cache_hdr_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_hdr_dest
+ *
+ * Purpose: Destroys an extensible array header in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 26 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_hdr_dest(H5F_t *f, H5EA_hdr_t *hdr))
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(hdr);
+
+ /* Verify that header is clean */
+ HDassert(hdr->cache_info.is_dirty == FALSE);
+
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!hdr->cache_info.free_file_space_on_destroy || H5F_addr_defined(hdr->cache_info.addr));
+
+ /* Check for freeing file space for extensible array header */
+ if(hdr->cache_info.free_file_space_on_destroy) {
+ /* Sanity check address */
+ HDassert(H5F_addr_eq(hdr->addr, hdr->cache_info.addr));
+
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_EARRAY_HDR, H5AC_dxpl_id, hdr->cache_info.addr, (hsize_t)hdr->size) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to free extensible array header")
+ } /* end if */
+
+ /* Release the extensible array header */
+ if(H5EA__hdr_dest(hdr) < 0)
+ H5E_THROW(H5E_CANTFREE, "can't free extensible array header")
+
+CATCH
+
+END_FUNC(STATIC) /* end H5EA__cache_hdr_dest() */
+
+
+/*-------------------------------------------------------------------------
+ * 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 */
+ haddr_t arr_addr; /* Address of array header in the file */
+
+ /* 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 index block")
+
+ /* 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(iblock);
+
+ /* 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)H5_SIZEOF_MAGIC))
+ H5E_THROW(H5E_BADVALUE, "wrong extensible array index block signature")
+ p += H5_SIZEOF_MAGIC;
+
+ /* Version */
+ if(*p++ != H5EA_IBLOCK_VERSION)
+ H5E_THROW(H5E_VERSION, "wrong extensible array index block version")
+
+ /* Address of header for array that owns this block (just for file integrity checks) */
+ H5F_addr_decode(f, &p, &arr_addr);
+ if(H5F_addr_ne(arr_addr, hdr->addr))
+ H5E_THROW(H5E_BADVALUE, "wrong extensible array header address")
+
+ /* Extensible array type */
+ if(*p++ != (uint8_t)hdr->cparam.cls->id)
+ H5E_THROW(H5E_BADTYPE, "incorrect extensible array class")
+
+ /* Internal information */
+
+ /* Decode elements in index block */
+ if(hdr->cparam.idx_blk_elmts > 0) {
+ /* Convert from raw elements on disk into native elements in memory */
+ if((hdr->cparam.cls->decode)(p, iblock->elmts, (size_t)hdr->cparam.idx_blk_elmts, hdr->cb_ctx) < 0)
+ H5E_THROW(H5E_CANTDECODE, "can't decode extensible array index elements")
+ p += (hdr->cparam.idx_blk_elmts * hdr->cparam.raw_elmt_size);
+ } /* end if */
+
+ /* Decode data block addresses in index block */
+ if(iblock->ndblk_addrs > 0) {
+ size_t u; /* Local index variable */
+
+ /* Decode addresses of data blocks in index block */
+ for(u = 0; u < iblock->ndblk_addrs; u++)
+ H5F_addr_decode(f, &p, &iblock->dblk_addrs[u]);
+ } /* end if */
+
+ /* Decode super block addresses in index block */
+ if(iblock->nsblk_addrs > 0) {
+ size_t u; /* Local index variable */
+
+ /* Decode addresses of super blocks in index block */
+ for(u = 0; u < iblock->nsblk_addrs; u++)
+ H5F_addr_decode(f, &p, &iblock->sblk_addrs[u]);
+ } /* 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_IBLOCK_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)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
+
+ /* Version # */
+ *p++ = H5EA_IBLOCK_VERSION;
+
+ /* Address of array header for array which owns this block */
+ H5F_addr_encode(f, &p, iblock->hdr->addr);
+
+ /* Extensible array type */
+ *p++ = iblock->hdr->cparam.cls->id;
+
+ /* Internal information */
+
+ /* Encode elements in index block */
+ if(iblock->hdr->cparam.idx_blk_elmts > 0) {
+ /* Convert from native elements in memory into raw elements on disk */
+ if((iblock->hdr->cparam.cls->encode)(p, iblock->elmts, (size_t)iblock->hdr->cparam.idx_blk_elmts, iblock->hdr->cb_ctx) < 0)
+ H5E_THROW(H5E_CANTENCODE, "can't encode extensible array index elements")
+ p += (iblock->hdr->cparam.idx_blk_elmts * iblock->hdr->cparam.raw_elmt_size);
+ } /* end if */
+
+ /* Encode data block addresses in index block */
+ if(iblock->ndblk_addrs > 0) {
+ size_t u; /* Local index variable */
+
+ /* Encode addresses of data blocks in index block */
+ for(u = 0; u < iblock->ndblk_addrs; u++)
+ H5F_addr_encode(f, &p, iblock->dblk_addrs[u]);
+ } /* end if */
+
+ /* Encode data block addresses in index block */
+ if(iblock->nsblk_addrs > 0) {
+ size_t u; /* Local index variable */
+
+ /* Encode addresses of super blocks in index block */
+ for(u = 0; u < iblock->nsblk_addrs; u++)
+ H5F_addr_encode(f, &p, iblock->sblk_addrs[u]);
+ } /* end if */
+
+ /* Compute metadata checksum */
+ metadata_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
+
+ /* Metadata checksum */
+ UINT32ENCODE(p, metadata_chksum);
+
+ /* Write the 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_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))
+
+ /* Sanity check */
+ 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_notify
+ *
+ * Purpose: Handle cache action notifications
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Mar 31 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_iblock_notify(H5AC_notify_action_t action, H5EA_iblock_t *iblock))
+
+ /* Sanity check */
+ HDassert(iblock);
+
+ /* Determine which action to take */
+ switch(action) {
+ case H5AC_NOTIFY_ACTION_AFTER_INSERT:
+ /* Create flush dependency on extensible array header */
+ if(H5EA__create_flush_depend(iblock->hdr, (H5AC_info_t *)iblock->hdr, (H5AC_info_t *)iblock) < 0)
+ H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency between index block and header, address = %llu", (unsigned long long)iblock->addr)
+ break;
+
+ case H5AC_NOTIFY_ACTION_BEFORE_EVICT:
+ /* Destroy flush dependency on extensible array header */
+ if(H5EA__destroy_flush_depend(iblock->hdr, (H5AC_info_t *)iblock->hdr, (H5AC_info_t *)iblock) < 0)
+ H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between index block and header, address = %llu", (unsigned long long)iblock->addr)
+ break;
+
+ default:
+#ifdef NDEBUG
+ H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache")
+#else /* NDEBUG */
+ HDassert(0 && "Unknown action?!?");
+#endif /* NDEBUG */
+ } /* end switch */
+
+CATCH
+
+END_FUNC(STATIC) /* end H5EA__cache_iblock_notify() */
+
+
+/*-------------------------------------------------------------------------
+ * 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() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_iblock_dest
+ *
+ * Purpose: Destroys an extensible array index block in memory.
+ *
+ * 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_dest(H5F_t *f, H5EA_iblock_t *iblock))
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(iblock);
+
+ /* Verify that index block is clean */
+ HDassert(iblock->cache_info.is_dirty == FALSE);
+
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!iblock->cache_info.free_file_space_on_destroy || H5F_addr_defined(iblock->cache_info.addr));
+
+ /* Check for freeing file space for extensible array index block */
+ if(iblock->cache_info.free_file_space_on_destroy) {
+ /* Sanity check address */
+ HDassert(H5F_addr_eq(iblock->addr, iblock->cache_info.addr));
+
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_EARRAY_IBLOCK, H5AC_dxpl_id, iblock->cache_info.addr, (hsize_t)iblock->size) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to free extensible array index block")
+ } /* end if */
+
+ /* Release the index block */
+ if(H5EA__iblock_dest(f, iblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "can't free extensible array index block")
+
+CATCH
+
+END_FUNC(STATIC) /* end H5EA__cache_iblock_dest() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_sblock_load
+ *
+ * Purpose: Loads an extensible array super block from the disk.
+ *
+ * Return: Success: Pointer to a new extensible array super block
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+H5EA_sblock_t *, NULL, NULL,
+H5EA__cache_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ const void *_udata1, void *_hdr))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = (H5EA_hdr_t *)_hdr; /* Shared extensible array information */
+ const H5EA_sblock_load_ud_t *ud_load = (const H5EA_sblock_load_ud_t *)_udata1; /* User data for loading super block */
+ H5EA_sblock_t *sblock = NULL; /* Super block info */
+ size_t size; /* Super block size */
+ H5WB_t *wb = NULL; /* Wrapped buffer for super block data */
+ uint8_t sblock_buf[H5EA_IBLOCK_BUF_SIZE]; /* Buffer for super block */
+ uint8_t *buf; /* Pointer to super block buffer */
+ const uint8_t *p; /* Pointer into raw data buffer */
+ uint32_t stored_chksum; /* Stored metadata checksum value */
+ uint32_t computed_chksum; /* Computed metadata checksum value */
+ haddr_t arr_addr; /* Address of array header in the file */
+ size_t u; /* Local index variable */
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(ud_load && ud_load->parent && ud_load->sblk_idx > 0);
+ HDassert(hdr);
+
+ /* Allocate the extensible array super block */
+ if(NULL == (sblock = H5EA__sblock_alloc(hdr, ud_load->parent, ud_load->sblk_idx)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array super block")
+
+ /* Set the extensible array super block's address */
+ sblock->addr = addr;
+
+ /* Wrap the local buffer for serialized info */
+ if(NULL == (wb = H5WB_wrap(sblock_buf, sizeof(sblock_buf))))
+ H5E_THROW(H5E_CANTINIT, "can't wrap buffer")
+
+ /* Compute the size of the extensible array super block on disk */
+ size = H5EA_SBLOCK_SIZE(sblock);
+
+ /* Get a pointer to a buffer that's large enough for serialized info */
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
+ H5E_THROW(H5E_CANTGET, "can't get actual buffer")
+
+ /* Read super block from disk */
+ if(H5F_block_read(f, H5FD_MEM_EARRAY_SBLOCK, addr, size, dxpl_id, buf) < 0)
+ H5E_THROW(H5E_READERROR, "can't read extensible array super block")
+
+ /* Get temporary pointer to serialized header */
+ p = buf;
+
+ /* Magic number */
+ if(HDmemcmp(p, H5EA_SBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC))
+ H5E_THROW(H5E_BADVALUE, "wrong extensible array super block signature")
+ p += H5_SIZEOF_MAGIC;
+
+ /* Version */
+ if(*p++ != H5EA_SBLOCK_VERSION)
+ H5E_THROW(H5E_VERSION, "wrong extensible array super block version")
+
+ /* Address of header for array that owns this block (just for file integrity checks) */
+ H5F_addr_decode(f, &p, &arr_addr);
+ if(H5F_addr_ne(arr_addr, hdr->addr))
+ H5E_THROW(H5E_BADVALUE, "wrong extensible array header address")
+
+ /* Offset of block within the array's address space */
+ UINT64DECODE_VAR(p, sblock->block_off, hdr->arr_off_size);
+
+ /* Extensible array type */
+ if(*p++ != (uint8_t)hdr->cparam.cls->id)
+ H5E_THROW(H5E_BADTYPE, "incorrect extensible array class")
+
+ /* Internal information */
+
+ /* Check for 'page init' bitmasks for this super block */
+ if(sblock->dblk_npages > 0) {
+ size_t tot_page_init_size = sblock->ndblks * sblock->dblk_page_init_size; /* Compute total size of 'page init' buffer */
+
+ /* Retrieve the 'page init' bitmasks */
+ HDmemcpy(sblock->page_init, p, tot_page_init_size);
+ p += tot_page_init_size;
+ } /* end if */
+
+ /* Decode data block addresses */
+ for(u = 0; u < sblock->ndblks; u++)
+ H5F_addr_decode(f, &p, &sblock->dblk_addrs[u]);
+
+ /* Sanity check */
+ /* (allow for checksum not decoded yet) */
+ HDassert((size_t)(p - buf) == (size - H5EA_SIZEOF_CHKSUM));
+
+ /* Save the super block's size */
+ sblock->size = size;
+
+ /* Compute checksum on super block */
+ computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
+
+ /* Metadata checksum */
+ UINT32DECODE(p, stored_chksum);
+
+ /* Sanity check */
+ HDassert((size_t)(p - buf) == sblock->size);
+
+ /* Verify checksum */
+ if(stored_chksum != computed_chksum)
+ H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array super block")
+
+ /* Set return value */
+ ret_value = sblock;
+
+CATCH
+
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer")
+ if(!ret_value)
+ if(sblock && H5EA__cache_sblock_dest(f, sblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array super block")
+
+END_FUNC(STATIC) /* end H5EA__cache_sblock_load() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_sblock_flush
+ *
+ * Purpose: Flushes a dirty extensible array super block to disk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
+ H5EA_sblock_t *sblock, unsigned UNUSED * flags_ptr))
+
+ /* Local variables */
+ H5WB_t *wb = NULL; /* Wrapped buffer for serializing data */
+ uint8_t ser_buf[H5EA_SBLOCK_BUF_SIZE]; /* Serialization buffer */
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(sblock);
+ HDassert(sblock->hdr);
+
+ if(sblock->cache_info.is_dirty) {
+ uint8_t *buf; /* Temporary raw data buffer */
+ uint8_t *p; /* Pointer into raw data buffer */
+ size_t size; /* Index block size on disk */
+ uint32_t metadata_chksum; /* Computed metadata checksum value */
+ size_t u; /* Local index variable */
+
+ /* Wrap the local buffer for serialized info */
+ if(NULL == (wb = H5WB_wrap(ser_buf, sizeof(ser_buf))))
+ H5E_THROW(H5E_CANTINIT, "can't wrap buffer")
+
+ /* Compute the size of the super block on disk */
+ size = sblock->size;
+
+ /* Get a pointer to a buffer that's large enough for serialized info */
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
+ H5E_THROW(H5E_CANTGET, "can't get actual buffer")
+
+ /* Get temporary pointer to serialized info */
+ p = buf;
+
+ /* Magic number */
+ HDmemcpy(p, H5EA_SBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
+
+ /* Version # */
+ *p++ = H5EA_SBLOCK_VERSION;
+
+ /* Address of array header for array which owns this block */
+ H5F_addr_encode(f, &p, sblock->hdr->addr);
+
+ /* Offset of block in array */
+ UINT64ENCODE_VAR(p, sblock->block_off, sblock->hdr->arr_off_size);
+
+ /* Extensible array type */
+ *p++ = sblock->hdr->cparam.cls->id;
+
+ /* Internal information */
+
+ /* Check for 'page init' bitmasks for this super block */
+ if(sblock->dblk_npages > 0) {
+ size_t tot_page_init_size = sblock->ndblks * sblock->dblk_page_init_size; /* Compute total size of 'page init' buffer */
+
+ /* Store the 'page init' bitmasks */
+ HDmemcpy(p, sblock->page_init, tot_page_init_size);
+ p += tot_page_init_size;
+ } /* end if */
+
+ /* Encode addresses of data blocks in super block */
+ for(u = 0; u < sblock->ndblks; u++)
+ H5F_addr_encode(f, &p, sblock->dblk_addrs[u]);
+
+ /* Compute metadata checksum */
+ metadata_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
+
+ /* Metadata checksum */
+ UINT32ENCODE(p, metadata_chksum);
+
+ /* Write the super block */
+ HDassert((size_t)(p - buf) == size);
+ if(H5F_block_write(f, H5FD_MEM_EARRAY_SBLOCK, addr, size, dxpl_id, buf) < 0)
+ H5E_THROW(H5E_WRITEERROR, "unable to save extensible array super block to disk")
+
+ sblock->cache_info.is_dirty = FALSE;
+ } /* end if */
+
+ if(destroy)
+ if(H5EA__cache_sblock_dest(f, sblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array super block")
+
+CATCH
+
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer")
+
+END_FUNC(STATIC) /* end H5EA__cache_sblock_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_sblock_clear
+ *
+ * Purpose: Mark a extensible array super block in memory as non-dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sept 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_sblock_clear(H5F_t *f, H5EA_sblock_t *sblock, hbool_t destroy))
+
+ /* Sanity check */
+ HDassert(sblock);
+
+ /* Reset the dirty flag */
+ sblock->cache_info.is_dirty = FALSE;
+
+ if(destroy)
+ if(H5EA__cache_sblock_dest(f, sblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array super block")
+
+CATCH
+
+END_FUNC(STATIC) /* end H5EA__cache_sblock_clear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_sblock_size
+ *
+ * Purpose: Compute the size in bytes of a extensible array super block
+ * on disk, and return it in *size_ptr. On failure,
+ * the value of *size_ptr is undefined.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sept 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+H5EA__cache_sblock_size(const H5F_t UNUSED *f, const H5EA_sblock_t *sblock,
+ size_t *size_ptr))
+
+ /* Sanity check */
+ HDassert(sblock);
+ HDassert(size_ptr);
+
+ /* Set size value */
+ *size_ptr = sblock->size;
+
+END_FUNC(STATIC) /* end H5EA__cache_sblock_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_sblock_notify
+ *
+ * Purpose: Handle cache action notifications
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Mar 31 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_sblock_notify(H5AC_notify_action_t action, H5EA_sblock_t *sblock))
+
+ /* Sanity check */
+ HDassert(sblock);
+
+ /* Determine which action to take */
+ switch(action) {
+ case H5AC_NOTIFY_ACTION_AFTER_INSERT:
+ /* Create flush dependency on index block */
+ if(H5EA__create_flush_depend(sblock->hdr, (H5AC_info_t *)sblock->parent, (H5AC_info_t *)sblock) < 0)
+ H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency between super block and index block, address = %llu", (unsigned long long)sblock->addr)
+ break;
+
+ case H5AC_NOTIFY_ACTION_BEFORE_EVICT:
+ /* Destroy flush dependency on index block */
+ if(H5EA__destroy_flush_depend(sblock->hdr, (H5AC_info_t *)sblock->parent, (H5AC_info_t *)sblock) < 0)
+ H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between super block and index block, address = %llu", (unsigned long long)sblock->addr)
+ break;
+
+ default:
+#ifdef NDEBUG
+ H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache")
+#else /* NDEBUG */
+ HDassert(0 && "Unknown action?!?");
+#endif /* NDEBUG */
+ } /* end switch */
+
+CATCH
+
+END_FUNC(STATIC) /* end H5EA__cache_sblock_notify() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_sblock_dest
+ *
+ * Purpose: Destroys an extensible array super block in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_sblock_dest(H5F_t *f, H5EA_sblock_t *sblock))
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(sblock);
+
+ /* Verify that super block is clean */
+ HDassert(sblock->cache_info.is_dirty == FALSE);
+
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!sblock->cache_info.free_file_space_on_destroy || H5F_addr_defined(sblock->cache_info.addr));
+
+ /* Check for freeing file space for extensible array super block */
+ if(sblock->cache_info.free_file_space_on_destroy) {
+ /* Sanity check address */
+ HDassert(H5F_addr_eq(sblock->addr, sblock->cache_info.addr));
+
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_EARRAY_SBLOCK, H5AC_dxpl_id, sblock->cache_info.addr, (hsize_t)sblock->size) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to free extensible array super block")
+ } /* end if */
+
+ /* Release the super block */
+ if(H5EA__sblock_dest(f, sblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "can't free extensible array super block")
+
+CATCH
+
+END_FUNC(STATIC) /* end H5EA__cache_sblock_dest() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_dblock_load
+ *
+ * Purpose: Loads an extensible array data block from the disk.
+ *
+ * Return: Success: Pointer to a new extensible array data block
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 16 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+H5EA_dblock_t *, NULL, NULL,
+H5EA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ const void *_udata1, void *_hdr))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = (H5EA_hdr_t *)_hdr; /* Shared extensible array information */
+ const H5EA_dblock_load_ud_t *ud_load = (const H5EA_dblock_load_ud_t *)_udata1; /* User data for loading data block */
+ H5EA_dblock_t *dblock = NULL; /* Data block info */
+ size_t size; /* Data block size */
+ H5WB_t *wb = NULL; /* Wrapped buffer for data block data */
+ uint8_t dblock_buf[H5EA_DBLOCK_BUF_SIZE]; /* Buffer for data block */
+ uint8_t *buf; /* Pointer to data 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 */
+ haddr_t arr_addr; /* Address of array header in the file */
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(ud_load && ud_load->parent && ud_load->nelmts > 0);
+ HDassert(hdr);
+
+ /* Allocate the extensible array data block */
+ if(NULL == (dblock = H5EA__dblock_alloc(hdr, ud_load->parent, ud_load->nelmts)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array data block")
+
+ /* Set the extensible array data block's information */
+ dblock->addr = addr;
+
+ /* Wrap the local buffer for serialized info */
+ if(NULL == (wb = H5WB_wrap(dblock_buf, sizeof(dblock_buf))))
+ H5E_THROW(H5E_CANTINIT, "can't wrap buffer")
+
+ /* Compute the size of the extensible array data block on disk */
+ 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)))
+ H5E_THROW(H5E_CANTGET, "can't get actual buffer")
+
+ /* Read data block from disk */
+ if(H5F_block_read(f, H5FD_MEM_EARRAY_DBLOCK, addr, size, dxpl_id, buf) < 0)
+ H5E_THROW(H5E_READERROR, "can't read extensible array data block")
+
+ /* Get temporary pointer to serialized header */
+ p = buf;
+
+ /* Magic number */
+ if(HDmemcmp(p, H5EA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC))
+ H5E_THROW(H5E_BADVALUE, "wrong extensible array data block signature")
+ p += H5_SIZEOF_MAGIC;
+
+ /* Version */
+ if(*p++ != H5EA_DBLOCK_VERSION)
+ H5E_THROW(H5E_VERSION, "wrong extensible array data block version")
+
+ /* Address of header for array that owns this block (just for file integrity checks) */
+ H5F_addr_decode(f, &p, &arr_addr);
+ if(H5F_addr_ne(arr_addr, hdr->addr))
+ H5E_THROW(H5E_BADVALUE, "wrong extensible array header address")
+
+ /* Offset of block within the array's address space */
+ UINT64DECODE_VAR(p, dblock->block_off, hdr->arr_off_size);
+
+ /* Extensible array type */
+ if(*p++ != (uint8_t)hdr->cparam.cls->id)
+ H5E_THROW(H5E_BADTYPE, "incorrect extensible array class")
+
+ /* Internal information */
+
+ /* 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, ud_load->nelmts, hdr->cb_ctx) < 0)
+ H5E_THROW(H5E_CANTDECODE, "can't decode extensible array data elements")
+ p += (ud_load->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));
+
+ /* 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);
+
+ /* Metadata checksum */
+ UINT32DECODE(p, stored_chksum);
+
+ /* Sanity check */
+ HDassert((size_t)(p - buf) == size);
+
+ /* Verify checksum */
+ if(stored_chksum != computed_chksum)
+ H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array data block")
+
+ /* Set return value */
+ ret_value = dblock;
+
+CATCH
+
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer")
+ if(!ret_value)
+ if(dblock && H5EA__cache_dblock_dest(f, dblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array data block")
+
+END_FUNC(STATIC) /* end H5EA__cache_dblock_load() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_dblock_flush
+ *
+ * Purpose: Flushes a dirty extensible array data block to disk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 18 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
+ H5EA_dblock_t *dblock, unsigned UNUSED * flags_ptr))
+
+ /* Local variables */
+ H5WB_t *wb = NULL; /* Wrapped buffer for serializing data */
+ uint8_t ser_buf[H5EA_DBLOCK_BUF_SIZE]; /* Serialization buffer */
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(dblock);
+ HDassert(dblock->hdr);
+
+ if(dblock->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 */
+ 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)))
+ H5E_THROW(H5E_CANTGET, "can't get actual buffer")
+
+ /* Get temporary pointer to serialized info */
+ p = buf;
+
+ /* Magic number */
+ HDmemcpy(p, H5EA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
+
+ /* Version # */
+ *p++ = H5EA_DBLOCK_VERSION;
+
+ /* Address of array header for array which owns this block */
+ H5F_addr_encode(f, &p, dblock->hdr->addr);
+
+ /* Offset of block in array */
+ UINT64ENCODE_VAR(p, dblock->block_off, dblock->hdr->arr_off_size);
+
+ /* Extensible array type */
+ *p++ = dblock->hdr->cparam.cls->id;
+
+ /* Internal information */
+
+ /* 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, dblock->hdr->cb_ctx) < 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);
+
+ /* Metadata checksum */
+ UINT32ENCODE(p, metadata_chksum);
+
+ /* Write the data block */
+ HDassert((size_t)(p - buf) == size);
+ if(H5F_block_write(f, H5FD_MEM_EARRAY_DBLOCK, addr, size, dxpl_id, buf) < 0)
+ H5E_THROW(H5E_WRITEERROR, "unable to save extensible array data block to disk")
+
+ dblock->cache_info.is_dirty = FALSE;
+ } /* end if */
+
+ if(destroy)
+ if(H5EA__cache_dblock_dest(f, dblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array data 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_dblock_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_dblock_clear
+ *
+ * Purpose: Mark a extensible array data block in memory as non-dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sept 18 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_dblock_clear(H5F_t *f, H5EA_dblock_t *dblock, hbool_t destroy))
+
+ /* Sanity check */
+ HDassert(dblock);
+
+ /* Reset the dirty flag */
+ dblock->cache_info.is_dirty = FALSE;
+
+ if(destroy)
+ if(H5EA__cache_dblock_dest(f, dblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array data block")
+
+CATCH
+
+END_FUNC(STATIC) /* end H5EA__cache_dblock_clear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_dblock_notify
+ *
+ * Purpose: Handle cache action notifications
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Mar 31 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_dblock_notify(H5AC_notify_action_t action, H5EA_dblock_t *dblock))
+
+ /* Sanity check */
+ HDassert(dblock);
+
+ /* Determine which action to take */
+ switch(action) {
+ case H5AC_NOTIFY_ACTION_AFTER_INSERT:
+ /* Create flush dependency on parent */
+ if(H5EA__create_flush_depend(dblock->hdr, (H5AC_info_t *)dblock->parent, (H5AC_info_t *)dblock) < 0)
+ H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency between data block and parent, address = %llu", (unsigned long long)dblock->addr)
+ break;
+
+ case H5AC_NOTIFY_ACTION_BEFORE_EVICT:
+ /* Destroy flush dependency on parent */
+ if(H5EA__destroy_flush_depend(dblock->hdr, (H5AC_info_t *)dblock->parent, (H5AC_info_t *)dblock) < 0)
+ H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between data block and parent, address = %llu", (unsigned long long)dblock->addr)
+ break;
+
+ default:
+#ifdef NDEBUG
+ H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache")
+#else /* NDEBUG */
+ HDassert(0 && "Unknown action?!?");
+#endif /* NDEBUG */
+ } /* end switch */
+
+CATCH
+
+END_FUNC(STATIC) /* end H5EA__cache_dblock_notify() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_dblock_size
+ *
+ * Purpose: Compute the size in bytes of a extensible array data 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 18 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+H5EA__cache_dblock_size(const H5F_t UNUSED *f, const H5EA_dblock_t *dblock,
+ size_t *size_ptr))
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(dblock);
+ HDassert(size_ptr);
+
+ /* Set size value */
+ if(!dblock->npages)
+ *size_ptr = dblock->size;
+ else
+ *size_ptr = H5EA_DBLOCK_PREFIX_SIZE(dblock);
+
+END_FUNC(STATIC) /* end H5EA__cache_dblock_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_dblock_dest
+ *
+ * Purpose: Destroys an extensible array data block in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 18 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_dblock_dest(H5F_t *f, H5EA_dblock_t *dblock))
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(dblock);
+
+ /* Verify that data block is clean */
+ HDassert(dblock->cache_info.is_dirty == FALSE);
+
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!dblock->cache_info.free_file_space_on_destroy || H5F_addr_defined(dblock->cache_info.addr));
+
+ /* Check for freeing file space for extensible array data block */
+ if(dblock->cache_info.free_file_space_on_destroy) {
+ /* Sanity check address */
+ 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")
+ } /* end if */
+
+ /* Release the data block */
+ if(H5EA__dblock_dest(f, dblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "can't free extensible array data block")
+
+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 *_ud_load, void *_hdr))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = (H5EA_hdr_t *)_hdr; /* Shared extensible array information */
+ const H5EA_dblk_page_load_ud_t *ud_load = (const H5EA_dblk_page_load_ud_t *)_ud_load; /* User data for loading data block page */
+ 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, ud_load->parent)))
+ 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, hdr->cb_ctx) < 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)
+ 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, dblk_page->hdr->cb_ctx) < 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_notify
+ *
+ * Purpose: Handle cache action notifications
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Mar 31 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_dblk_page_notify(H5AC_notify_action_t action, H5EA_dblk_page_t *dblk_page))
+
+ /* Sanity check */
+ HDassert(dblk_page);
+
+ /* Determine which action to take */
+ switch(action) {
+ case H5AC_NOTIFY_ACTION_AFTER_INSERT:
+ /* Create flush dependency on parent */
+ if(H5EA__create_flush_depend(dblk_page->hdr, (H5AC_info_t *)dblk_page->parent, (H5AC_info_t *)dblk_page) < 0)
+ H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency between data block page and parent, address = %llu", (unsigned long long)dblk_page->addr)
+ break;
+
+ case H5AC_NOTIFY_ACTION_BEFORE_EVICT:
+ /* Destroy flush dependency on parent */
+ if(H5EA__destroy_flush_depend(dblk_page->hdr, (H5AC_info_t *)dblk_page->parent, (H5AC_info_t *)dblk_page) < 0)
+ H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between data block page and parent, address = %llu", (unsigned long long)dblk_page->addr)
+ break;
+
+ default:
+#ifdef NDEBUG
+ H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache")
+#else /* NDEBUG */
+ HDassert(0 && "Unknown action?!?");
+#endif /* NDEBUG */
+ } /* end switch */
+
+CATCH
+
+END_FUNC(STATIC) /* end H5EA__cache_dblk_page_notify() */
+
+
+/*-------------------------------------------------------------------------
+ * 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/H5EAdbg.c b/src/H5EAdbg.c
new file mode 100644
index 0000000..0ac4807
--- /dev/null
+++ b/src/H5EAdbg.c
@@ -0,0 +1,442 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5EAdbg.c
+ * Sep 11 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Dump debugging information about an extensible array.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/**********************/
+/* 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__hdr_debug
+ *
+ * Purpose: Prints debugging info about a extensible array header.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
+ int fwidth, const H5EA_class_t *cls))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = NULL; /* Shared extensible array header */
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+ HDassert(cls);
+
+ /* Load the extensible array header */
+ if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, addr, cls, NULL, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header")
+
+ /* Print opening message */
+ HDfprintf(stream, "%*sExtensible Array Header...\n", indent, "");
+
+ /* Print the values */
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Array class ID:",
+ (hdr->cparam.cls->id == H5EA_CLS_TEST_ID ? "H5EA_CLS_TEST_ID" :
+ "Unknown!"));
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "Header size:",
+ hdr->size);
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Raw Element Size:",
+ (unsigned)hdr->cparam.raw_elmt_size);
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "Native Element Size (on this platform):",
+ hdr->cparam.cls->nat_elmt_size);
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Log2(Max. # of elements in array):",
+ (unsigned)hdr->cparam.max_nelmts_bits);
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "# of elements in index block:",
+ (unsigned)hdr->cparam.idx_blk_elmts);
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Min. # of elements per data block:",
+ (unsigned)hdr->cparam.data_blk_min_elmts);
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Min. # of data block pointers for a super block:",
+ (unsigned)hdr->cparam.sup_blk_min_data_ptrs);
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Log2(Max. # of elements in data block page):",
+ (unsigned)hdr->cparam.max_dblk_page_nelmts_bits);
+ HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
+ "Highest element index stored (+1):",
+ hdr->stats.stored.max_idx_set);
+ HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
+ "Number of super blocks created:",
+ hdr->stats.stored.nsuper_blks);
+ HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
+ "Number of data blocks created:",
+ hdr->stats.stored.ndata_blks);
+ HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
+ "Number of elements 'realized':",
+ hdr->stats.stored.nelmts);
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
+ "Index Block Address:",
+ hdr->idx_blk_addr);
+
+CATCH
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_EARRAY_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array header")
+
+END_FUNC(PKG) /* end H5EA__hdr_debug() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__iblock_debug
+ *
+ * Purpose: Prints debugging info about a extensible array index block.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, FILE *stream, int indent,
+ int fwidth, const H5EA_class_t *cls, haddr_t hdr_addr))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = NULL; /* Shared extensible array header */
+ H5EA_iblock_t *iblock = NULL; /* Extensible array index block */
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+ HDassert(cls);
+ HDassert(H5F_addr_defined(hdr_addr));
+
+ /* Load the extensible array header */
+ if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, hdr_addr, cls, NULL, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header")
+
+ /* Sanity check */
+ HDassert(H5F_addr_eq(hdr->idx_blk_addr, addr));
+
+ /* Protect 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)
+
+ /* Print opening message */
+ HDfprintf(stream, "%*sExtensible Array Index Block...\n", indent, "");
+
+ /* Print the values */
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Array class ID:",
+ (hdr->cparam.cls->id == H5EA_CLS_TEST_ID ? "H5EA_CLS_TEST_ID" :
+ "Unknown!"));
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "Index Block size:",
+ iblock->size);
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "# of data block addresses in index block:",
+ iblock->ndblk_addrs);
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "# of super block addresses in index block:",
+ iblock->nsblk_addrs);
+
+ /* Check if there are any elements in index block */
+ if(hdr->cparam.idx_blk_elmts > 0) {
+ unsigned u; /* Local index variable */
+
+ /* Print the elements in the index block */
+ HDfprintf(stream, "%*sElements in Index Block:\n", indent, "");
+ for(u = 0; u < hdr->cparam.idx_blk_elmts; u++) {
+ /* Call the class's 'debug' callback */
+ if((hdr->cparam.cls->debug)(stream, (indent + 3), MAX(0, (fwidth - 3)),
+ (hsize_t)u,
+ ((uint8_t *)iblock->elmts) + (hdr->cparam.cls->nat_elmt_size * u)) < 0)
+ H5E_THROW(H5E_CANTGET, "can't get element for debugging")
+ } /* end for */
+ } /* end if */
+
+ /* Check if there are any data block addresses in index block */
+ if(iblock->ndblk_addrs > 0) {
+ char temp_str[128]; /* Temporary string, for formatting */
+ unsigned u; /* Local index variable */
+
+ /* Print the data block addresses in the index block */
+ HDfprintf(stream, "%*sData Block Addresses in Index Block:\n", indent, "");
+ for(u = 0; u < iblock->ndblk_addrs; u++) {
+ /* Print address */
+ sprintf(temp_str, "Address #%u:", u);
+ HDfprintf(stream, "%*s%-*s %a\n", (indent + 3), "", MAX(0, (fwidth - 3)),
+ temp_str,
+ iblock->dblk_addrs[u]);
+ } /* end for */
+ } /* end if */
+
+ /* Check if there are any super block addresses in index block */
+ if(iblock->nsblk_addrs > 0) {
+ char temp_str[128]; /* Temporary string, for formatting */
+ unsigned u; /* Local index variable */
+
+ /* Print the super block addresses in the index block */
+ HDfprintf(stream, "%*sSuper Block Addresses in Index Block:\n", indent, "");
+ for(u = 0; u < iblock->nsblk_addrs; u++) {
+ /* Print address */
+ sprintf(temp_str, "Address #%u:", u);
+ HDfprintf(stream, "%*s%-*s %a\n", (indent + 3), "", MAX(0, (fwidth - 3)),
+ temp_str,
+ iblock->sblk_addrs[u]);
+ } /* end for */
+ } /* end if */
+
+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(hdr && H5AC_unprotect(f, dxpl_id, H5AC_EARRAY_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array header")
+
+END_FUNC(PKG) /* end H5EA__iblock_debug() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__sblock_debug
+ *
+ * Purpose: Prints debugging info about a extensible array super block.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__sblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
+ int fwidth, const H5EA_class_t *cls, haddr_t hdr_addr, unsigned sblk_idx))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = NULL; /* Shared extensible array header */
+ H5EA_sblock_t *sblock = NULL; /* Extensible array super block */
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+ HDassert(cls);
+ HDassert(H5F_addr_defined(hdr_addr));
+
+ /* Load the extensible array header */
+ if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, hdr_addr, cls, NULL, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header")
+
+ /* Protect super block */
+ /* (Note: setting parent of super block to 'hdr' for this operation should be OK -QAK) */
+ if(NULL == (sblock = H5EA__sblock_protect(hdr, dxpl_id, (H5EA_iblock_t *)hdr, addr, sblk_idx, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array super block, address = %llu", (unsigned long long)addr)
+
+ /* Print opening message */
+ HDfprintf(stream, "%*sExtensible Array Super Block...\n", indent, "");
+
+ /* Print the values */
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Array class ID:",
+ (hdr->cparam.cls->id == H5EA_CLS_TEST_ID ? "H5EA_CLS_TEST_ID" :
+ "Unknown!"));
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "Super Block size:",
+ sblock->size);
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "# of data block addresses in super block:",
+ sblock->ndblks);
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "# of elements in data blocks from this super block:",
+ sblock->dblk_nelmts);
+
+ /* Check if there are any data block addresses in super block */
+ if(sblock->ndblks > 0) {
+ char temp_str[128]; /* Temporary string, for formatting */
+ unsigned u; /* Local index variable */
+
+ /* Print the data block addresses in the super block */
+ HDfprintf(stream, "%*sData Block Addresses in Super Block:\n", indent, "");
+ for(u = 0; u < sblock->ndblks; u++) {
+ /* Print address */
+ sprintf(temp_str, "Address #%u:", u);
+ HDfprintf(stream, "%*s%-*s %a\n", (indent + 3), "", MAX(0, (fwidth - 3)),
+ temp_str,
+ sblock->dblk_addrs[u]);
+ } /* end for */
+ } /* end if */
+
+CATCH
+ if(sblock && H5EA__sblock_unprotect(sblock, dxpl_id, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array super block")
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_EARRAY_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array header")
+
+END_FUNC(PKG) /* end H5EA__sblock_debug() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__dblock_debug
+ *
+ * Purpose: Prints debugging info about a extensible array data block.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 22 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
+ int fwidth, const H5EA_class_t *cls, haddr_t hdr_addr, size_t dblk_nelmts))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = NULL; /* Shared extensible array header */
+ H5EA_dblock_t *dblock = NULL; /* Extensible array data block */
+ size_t u; /* Local index variable */
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+ HDassert(cls);
+ HDassert(H5F_addr_defined(hdr_addr));
+ HDassert(dblk_nelmts > 0);
+
+ /* Load the extensible array header */
+ if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, hdr_addr, cls, NULL, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header")
+
+ /* Protect data block */
+ /* (Note: setting parent of data block to 'hdr' for this operation should be OK -QAK) */
+ if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, hdr, addr, dblk_nelmts, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long long)addr)
+
+ /* Print opening message */
+ HDfprintf(stream, "%*sExtensible Array data Block...\n", indent, "");
+
+ /* Print the values */
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Array class ID:",
+ (hdr->cparam.cls->id == H5EA_CLS_TEST_ID ? "H5EA_CLS_TEST_ID" :
+ "Unknown!"));
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "Data Block size:",
+ dblock->size);
+
+
+ /* Print the elements in the index block */
+ HDfprintf(stream, "%*sElements:\n", indent, "");
+ for(u = 0; u < dblk_nelmts; u++) {
+ /* Call the class's 'debug' callback */
+ if((hdr->cparam.cls->debug)(stream, (indent + 3), MAX(0, (fwidth - 3)),
+ (hsize_t)u,
+ ((uint8_t *)dblock->elmts) + (hdr->cparam.cls->nat_elmt_size * u)) < 0)
+ H5E_THROW(H5E_CANTGET, "can't get element for debugging")
+ } /* end for */
+
+CATCH
+ 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(hdr && H5AC_unprotect(f, dxpl_id, H5AC_EARRAY_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array header")
+
+END_FUNC(PKG) /* end H5EA__dblock_debug() */
+
diff --git a/src/H5EAdblkpage.c b/src/H5EAdblkpage.c
new file mode 100644
index 0000000..429e9f8
--- /dev/null
+++ b/src/H5EAdblkpage.c
@@ -0,0 +1,318 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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, H5EA_sblock_t *parent))
+
+ /* 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 */
+ dblk_page->parent = parent;
+
+ /* 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, H5EA_sblock_t *parent,
+ 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, parent)))
+ 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, H5EA_sblock_t *parent,
+ haddr_t dblk_page_addr, H5AC_protect_t rw))
+
+ /* Local variables */
+ H5EA_dblk_page_load_ud_t load_ud; /* Information needed for loading data block page */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(H5F_addr_defined(dblk_page_addr));
+
+ /* Set up user data */
+ load_ud.parent = parent;
+
+ /* 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, &load_ud, 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
new file mode 100644
index 0000000..344b9fa
--- /dev/null
+++ b/src/H5EAdblock.c
@@ -0,0 +1,487 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5EAdblock.c
+ * Sep 11 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Data block routines for extensible arrays.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/**********************/
+/* Module Declaration */
+/**********************/
+
+#define H5EA_MODULE
+
+
+/***********************/
+/* Other Packages Used */
+/***********************/
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5EApkg.h" /* Extensible Arrays */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5MFprivate.h" /* File memory management */
+#include "H5Vprivate.h" /* Vectors and arrays */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5EA_dblock_t struct */
+H5FL_DEFINE_STATIC(H5EA_dblock_t);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__dblock_alloc
+ *
+ * Purpose: Allocate extensible array data block
+ *
+ * Return: Non-NULL pointer to data block on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+H5EA_dblock_t *, NULL, NULL,
+H5EA__dblock_alloc(H5EA_hdr_t *hdr, void *parent, size_t nelmts))
+
+ /* Local variables */
+ H5EA_dblock_t *dblock = NULL; /* Extensible array data block */
+
+ /* Check arguments */
+ HDassert(hdr);
+ HDassert(parent);
+ HDassert(nelmts > 0);
+
+ /* Allocate memory for the data block */
+ if(NULL == (dblock = H5FL_CALLOC(H5EA_dblock_t)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array data block")
+
+ /* Share common array information */
+ 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->parent = parent;
+ 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;
+
+CATCH
+ if(!ret_value)
+ if(dblock && H5EA__dblock_dest(hdr->f, dblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array data block")
+
+END_FUNC(PKG) /* end H5EA__dblock_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__dblock_create
+ *
+ * Purpose: Creates a new extensible array data 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__dblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, void *parent,
+ hbool_t *stats_changed, hsize_t dblk_off, size_t nelmts))
+
+ /* Local variables */
+ H5EA_dblock_t *dblock = NULL; /* Extensible array data block */
+ haddr_t dblock_addr; /* Extensible array data block address */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called, hdr->dblk_page_nelmts = %Zu, nelmts = %Zu\n", FUNC, hdr->dblk_page_nelmts, nelmts);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(stats_changed);
+ HDassert(nelmts > 0);
+
+ /* Allocate the data block */
+ if(NULL == (dblock = H5EA__dblock_alloc(hdr, parent, nelmts)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array data block")
+
+ /* Set size of data block on disk */
+ dblock->size = H5EA_DBLOCK_SIZE(dblock);
+#ifdef QAK
+HDfprintf(stderr, "%s: dblock->size = %Zu\n", FUNC, dblock->size);
+#endif /* QAK */
+
+ /* Set offset of block in array's address space */
+ dblock->block_off = dblk_off;
+#ifdef QAK
+HDfprintf(stderr, "%s: dblock->block_off = %Hu\n", FUNC, dblock->block_off);
+#endif /* QAK */
+
+ /* Allocate space for the data block on disk */
+ 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")
+ dblock->addr = dblock_addr;
+
+ /* 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 data block to cache")
+
+ /* Update extensible array data block statistics */
+ hdr->stats.stored.ndata_blks++;
+ hdr->stats.stored.data_blk_size += dblock->size;
+
+ /* Increment count of elements "realized" */
+ hdr->stats.stored.nelmts += nelmts;
+
+ /* Mark the statistics as changed */
+ *stats_changed = TRUE;
+
+ /* Set address of data block to return */
+ ret_value = dblock_addr;
+
+CATCH
+ if(!H5F_addr_defined(ret_value))
+ if(dblock) {
+ /* Release data block's disk space */
+ if(H5F_addr_defined(dblock->addr) && H5MF_xfree(hdr->f, H5FD_MEM_EARRAY_DBLOCK, dxpl_id, dblock->addr, (hsize_t)dblock->size) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to release extensible array data block")
+
+ /* Destroy data block */
+ if(H5EA__dblock_dest(hdr->f, dblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array data block")
+ } /* end if */
+
+END_FUNC(PKG) /* end H5EA__dblock_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__dblock_sblk_idx
+ *
+ * Purpose: Compute the index of the super block where the element is
+ * located.
+ *
+ * Return: Super block index on success/Can't fail
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, NOERR,
+unsigned, 0, -,
+H5EA__dblock_sblk_idx(const H5EA_hdr_t *hdr, hsize_t idx))
+
+ /* Local variables */
+ unsigned sblk_idx; /* Which superblock does this index fall in? */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(idx >= hdr->cparam.idx_blk_elmts);
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Entering - idx = %Hu\n", FUNC, idx);
+#endif /* QAK */
+ /* Adjust index for elements in index block */
+ idx -= hdr->cparam.idx_blk_elmts;
+#ifdef QAK
+HDfprintf(stderr, "%s: after adjusting for index block elements, idx = %Hu\n", FUNC, idx);
+#endif /* QAK */
+
+ /* Determine the superblock information for the index */
+ H5_CHECK_OVERFLOW(idx, /*From:*/hsize_t, /*To:*/uint64_t);
+#ifdef QAK
+HDfprintf(stderr, "%s: hdr->cparam.data_blk_min_elmts = %u\n", FUNC, (unsigned)hdr->cparam.data_blk_min_elmts);
+#endif /* QAK */
+ sblk_idx = H5V_log2_gen((uint64_t)((idx / hdr->cparam.data_blk_min_elmts) + 1));
+#ifdef QAK
+HDfprintf(stderr, "%s: sblk_idx = %u\n", FUNC, sblk_idx);
+HDfprintf(stderr, "%s: hdr->sblk_info[%u] = {%Hu, %Zu, %Hu, %Hu}\n", FUNC, sblk_idx, hdr->sblk_info[sblk_idx].ndblks, hdr->sblk_info[sblk_idx].dblk_nelmts, hdr->sblk_info[sblk_idx].start_idx, hdr->sblk_info[sblk_idx].start_dblk);
+#endif /* QAK */
+
+ /* Set return value */
+ ret_value = sblk_idx;
+
+END_FUNC(PKG) /* end H5EA__dblock_sblk_idx() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__dblock_protect
+ *
+ * Purpose: Convenience wrapper around protecting extensible array data block
+ *
+ * Return: Non-NULL pointer to data block on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 18 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+H5EA_dblock_t *, NULL, NULL,
+H5EA__dblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, void *parent,
+ haddr_t dblk_addr, size_t dblk_nelmts, H5AC_protect_t rw))
+
+ /* Local variables */
+ H5EA_dblock_load_ud_t load_ud; /* Information needed for loading data block */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(H5F_addr_defined(dblk_addr));
+ HDassert(dblk_nelmts);
+
+ /* Set up user data */
+ load_ud.parent = parent;
+ load_ud.nelmts = dblk_nelmts;
+
+ /* Protect the data block */
+ if(NULL == (ret_value = (H5EA_dblock_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_EARRAY_DBLOCK, dblk_addr, &load_ud, hdr, rw)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long long)dblk_addr)
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__dblock_protect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__dblock_unprotect
+ *
+ * Purpose: Convenience wrapper around unprotecting extensible array data block
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__dblock_unprotect(H5EA_dblock_t *dblock, hid_t dxpl_id, unsigned cache_flags))
+
+ /* Local variables */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(dblock);
+
+ /* Unprotect the data block */
+ if(H5AC_unprotect(dblock->hdr->f, dxpl_id, H5AC_EARRAY_DBLOCK, dblock->addr, dblock, cache_flags) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to unprotect extensible array data block, address = %llu", (unsigned long long)dblock->addr)
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__dblock_unprotect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__dblock_delete
+ *
+ * Purpose: Delete a data block
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 22 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__dblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id, void *parent,
+ haddr_t dblk_addr, size_t dblk_nelmts))
+
+ /* Local variables */
+ H5EA_dblock_t *dblock = NULL; /* Pointer to data block */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(parent);
+ HDassert(H5F_addr_defined(dblk_addr));
+ HDassert(dblk_nelmts > 0);
+
+ /* Protect data block */
+ if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, parent, 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)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array data block")
+
+END_FUNC(PKG) /* end H5EA__dblock_delete() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__dblock_dest
+ *
+ * Purpose: Destroys an extensible array data block in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__dblock_dest(H5F_t UNUSED *f, H5EA_dblock_t *dblock))
+
+ /* Sanity check */
+ HDassert(dblock);
+
+ /* 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);
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__dblock_dest() */
+
diff --git a/src/H5EAhdr.c b/src/H5EAhdr.c
new file mode 100644
index 0000000..b8d3334
--- /dev/null
+++ b/src/H5EAhdr.c
@@ -0,0 +1,732 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5EAhdr.c
+ * Aug 26 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Array header 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 */
+#include "H5Vprivate.h" /* Vectors and arrays */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+#ifndef NDEBUG
+/* Max. # of bits for max. nelmts index */
+#define H5EA_MAX_NELMTS_IDX_MAX 64
+#endif /* NDEBUG */
+
+/* # of elements in a data block for a particular super block */
+#define H5EA_SBLK_DBLK_NELMTS(s, m) \
+ (size_t)H5_EXP2(((s) + 1) / 2) * (m)
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/* Alias for pointer to factory, for use when allocating sequences of them */
+typedef H5FL_fac_head_t *H5FL_fac_head_ptr_t;
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5EA_hdr_t struct */
+H5FL_DEFINE_STATIC(H5EA_hdr_t);
+
+/* Declare a free list to manage the H5FL_fac_head_ptr_t sequence information */
+H5FL_SEQ_DEFINE_STATIC(H5FL_fac_head_ptr_t);
+
+/* Declare a free list to manage the H5EA_sblk_info_t sequence information */
+H5FL_SEQ_DEFINE_STATIC(H5EA_sblk_info_t);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__hdr_alloc
+ *
+ * Purpose: Allocate shared extensible array header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 26 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+H5EA_hdr_t *, NULL, NULL,
+H5EA__hdr_alloc(H5F_t *f))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = NULL; /* Shared extensible array header */
+
+ /* Check arguments */
+ HDassert(f);
+
+ /* Allocate space for the shared information */
+ if(NULL == (hdr = H5FL_CALLOC(H5EA_hdr_t)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array shared header")
+
+ /* Set non-zero internal fields */
+ hdr->addr = HADDR_UNDEF;
+
+ /* 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 return value */
+ ret_value = hdr;
+
+CATCH
+ if(!ret_value)
+ if(hdr && H5EA__hdr_dest(hdr) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array header")
+
+END_FUNC(PKG) /* end H5EA__hdr_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__hdr_init
+ *
+ * Purpose: Compute useful information for extensible array, based on
+ * "creation" information.
+ *
+ * Notes: The equations for variables below are based on this information:
+ *
+ * <sblk idx> <# of dblks> <size of dblks> Range of elements in sblk
+ * ========== ============ =============== =========================
+ * 0 1 1 * <dblk min elmts> 0 * <dblk min elmts> <-> 1 * <dblk min elmts> - 1
+ * 1 1 2 * <dblk min elmts> 1 * <dblk min elmts> <-> 3 * <dblk min elmts> - 1
+ * 2 2 2 * <dblk min elmts> 3 * <dblk min elmts> <-> 7 * <dblk min elmts> - 1
+ * 3 2 4 * <dblk min elmts> 7 * <dblk min elmts> <-> 15 * <dblk min elmts> - 1
+ * 4 4 4 * <dblk min elmts> 15 * <dblk min elmts> <-> 31 * <dblk min elmts> - 1
+ * 5 4 8 * <dblk min elmts> 31 * <dblk min elmts> <-> 63 * <dblk min elmts> - 1
+ * 6 8 8 * <dblk min elmts> 63 * <dblk min elmts> <-> 127 * <dblk min elmts> - 1
+ * 7 8 16 * <dblk min elmts> 127 * <dblk min elmts> <-> 255 * <dblk min elmts> - 1
+ * . . . * <dblk min elmts> . * <dblk min elmts> <-> . * <dblk min elmts> - 1
+ * . . . * <dblk min elmts> . * <dblk min elmts> <-> . * <dblk min elmts> - 1
+ * . . . * <dblk min elmts> . * <dblk min elmts> <-> . * <dblk min elmts> - 1
+ *
+ * Therefore:
+ * <sblk idx>(<elmt idx>) = lg2((<elmt idx> / <dblk min elmts>) + 1)
+ * <# of dblks>(<sblk idx>) = 2 ^ (<sblk idx> / 2)
+ * <size of dblk>(<sblk idx>) = 2 ^ ((<sblk idx> + 1) / 2)
+ * <total # of sblks>(<max. # of elmts>) = 1 + (lg2(<max. # of elmts>) - lg2(<dblk min_elmts>))
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 18 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__hdr_init(H5EA_hdr_t *hdr, void *ctx_udata))
+
+ /* Local variables */
+ hsize_t start_idx; /* First element index for each super block */
+ hsize_t start_dblk; /* First data block index for each super block */
+ size_t u; /* Local index variable */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(hdr->cparam.max_nelmts_bits);
+ HDassert(hdr->cparam.data_blk_min_elmts);
+ HDassert(hdr->cparam.sup_blk_min_data_ptrs);
+
+ /* 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 = (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 */
+
+ /* Allocate information for each super block */
+ if(NULL == (hdr->sblk_info = H5FL_SEQ_MALLOC(H5EA_sblk_info_t, hdr->nsblks)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for super block info array")
+
+ /* Compute information about each super block */
+ start_idx = 0;
+ start_dblk = 0;
+ for(u = 0; u < hdr->nsblks; u++) {
+ hdr->sblk_info[u].ndblks = (size_t)H5_EXP2(u / 2);
+ hdr->sblk_info[u].dblk_nelmts = H5EA_SBLK_DBLK_NELMTS(u, hdr->cparam.data_blk_min_elmts);
+ hdr->sblk_info[u].start_idx = start_idx;
+ hdr->sblk_info[u].start_dblk = start_dblk;
+#ifdef QAK
+HDfprintf(stderr, "%s: hdr->sblk_info[%Zu] = {%Zu, %Zu, %Hu, %Hu}\n", FUNC, u, hdr->sblk_info[u].ndblks, hdr->sblk_info[u].dblk_nelmts, hdr->sblk_info[u].start_idx, hdr->sblk_info[u].start_dblk);
+#endif /* QAK */
+
+ /* Advance starting indices for next super block */
+ start_idx += (hsize_t)hdr->sblk_info[u].ndblks * (hsize_t)hdr->sblk_info[u].dblk_nelmts;
+ start_dblk += (hsize_t)hdr->sblk_info[u].ndblks;
+ } /* end for */
+
+ /* Set size of header on disk (locally and in statistics) */
+ hdr->stats.computed.hdr_size = hdr->size = H5EA_HEADER_SIZE(hdr);
+
+ /* Create the callback context, if there's one */
+ if(hdr->cparam.cls->crt_context) {
+ if(NULL == (hdr->cb_ctx = (*hdr->cparam.cls->crt_context)(ctx_udata)))
+ H5E_THROW(H5E_CANTCREATE, "unable to create extensible array client callback context")
+ } /* end if */
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__hdr_init() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__hdr_alloc_elmts
+ *
+ * Purpose: Allocate extensible array data block elements
+ *
+ * Return: Non-NULL pointer to buffer for elements on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 16 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+void *, NULL, NULL,
+H5EA__hdr_alloc_elmts(H5EA_hdr_t *hdr, size_t nelmts))
+
+ /* Local variables */
+ void *elmts = NULL; /* Element buffer allocated */
+ unsigned idx; /* Index of element buffer factory in header */
+
+ /* Check arguments */
+ HDassert(hdr);
+ HDassert(nelmts > 0);
+
+ /* Compute the index of the element buffer factory */
+ H5_CHECK_OVERFLOW(nelmts, /*From:*/size_t, /*To:*/uint32_t);
+ idx = H5V_log2_of2((uint32_t)nelmts) - H5V_log2_of2((uint32_t)hdr->cparam.data_blk_min_elmts);
+#ifdef QAK
+HDfprintf(stderr, "%s: nelmts = %Zu, hdr->data_blk_min_elmts = %u, idx = %u\n", FUNC, nelmts, (unsigned)hdr->data_blk_min_elmts, idx);
+#endif /* QAK */
+
+ /* Check for needing to increase size of array of factories */
+ if(idx >= hdr->elmt_fac.nalloc) {
+ H5FL_fac_head_t **new_fac; /* New array of element factories */
+ size_t new_nalloc = MAX3(1, (idx + 1), (2 * hdr->elmt_fac.nalloc)); /* New number of factories allocated */
+
+ /* Re-allocate array of element factories */
+ if(NULL == (new_fac = H5FL_SEQ_REALLOC(H5FL_fac_head_ptr_t, hdr->elmt_fac.fac, new_nalloc)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for data block data element buffer factory array")
+
+ /* Zero out new elements allocated */
+ HDmemset(new_fac + hdr->elmt_fac.nalloc, 0, (new_nalloc - hdr->elmt_fac.nalloc) * sizeof(H5FL_fac_head_ptr_t));
+
+ /* Update information about element factories in header */
+ hdr->elmt_fac.nalloc = new_nalloc;
+ hdr->elmt_fac.fac = new_fac;
+ } /* end if */
+
+ /* Check for un-initialized factory at index */
+ if(NULL == hdr->elmt_fac.fac[idx]) {
+ if(NULL == (hdr->elmt_fac.fac[idx] = H5FL_fac_init(nelmts * (size_t)hdr->cparam.cls->nat_elmt_size)))
+ H5E_THROW(H5E_CANTINIT, "can't create data block data element buffer factory")
+ } /* end if */
+
+ /* Allocate buffer for elements in index block */
+ if(NULL == (elmts = H5FL_FAC_MALLOC(hdr->elmt_fac.fac[idx])))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for data block data element buffer")
+
+ /* Set the return value */
+ ret_value = elmts;
+
+CATCH
+ if(!ret_value)
+ if(elmts)
+ (void)H5FL_FAC_FREE(hdr->elmt_fac.fac[idx], elmts);
+
+END_FUNC(PKG) /* end H5EA__hdr_alloc_elmts() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__hdr_free_elmts
+ *
+ * Purpose: Free extensible array data block elements
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 18 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, NOERR,
+herr_t, SUCCEED, -,
+H5EA__hdr_free_elmts(H5EA_hdr_t *hdr, size_t nelmts, void *elmts))
+
+ /* Local variables */
+ unsigned idx; /* Index of element buffer factory in header */
+
+ /* Check arguments */
+ HDassert(hdr);
+ HDassert(nelmts > 0);
+ HDassert(elmts);
+
+ /* Compute the index of the element buffer factory */
+ H5_CHECK_OVERFLOW(nelmts, /*From:*/size_t, /*To:*/uint32_t);
+ idx = H5V_log2_of2((uint32_t)nelmts) - H5V_log2_of2((uint32_t)hdr->cparam.data_blk_min_elmts);
+#ifdef QAK
+HDfprintf(stderr, "%s: nelmts = %Zu, hdr->data_blk_min_elmts = %u, idx = %u\n", FUNC, nelmts, (unsigned)hdr->data_blk_min_elmts, idx);
+#endif /* QAK */
+
+ /* Free buffer for elements in index block */
+ HDassert(idx < hdr->elmt_fac.nalloc);
+ HDassert(hdr->elmt_fac.fac[idx]);
+ (void)H5FL_FAC_FREE(hdr->elmt_fac.fac[idx], elmts);
+
+END_FUNC(PKG) /* end H5EA__hdr_free_elmts() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__hdr_create
+ *
+ * Purpose: Creates a new extensible array header in the file
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jun 17 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+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,
+ void *ctx_udata))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = NULL; /* Extensible array header */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(cparam);
+
+#ifndef NDEBUG
+{
+ unsigned sblk_idx; /* Super block index for first "actual" super block */
+ size_t dblk_nelmts; /* Number of data block elements */
+ size_t dblk_page_nelmts; /* Number of elements in a data block page */
+
+ /* Check for valid parameters */
+ if(cparam->raw_elmt_size == 0)
+ H5E_THROW(H5E_BADVALUE, "element size must be greater than zero")
+ if(cparam->max_nelmts_bits == 0)
+ H5E_THROW(H5E_BADVALUE, "max. # of elements bits must be greater than zero")
+ if(cparam->max_nelmts_bits > H5EA_MAX_NELMTS_IDX_MAX)
+ H5E_THROW(H5E_BADVALUE, "max. # of elements bits must be <= %u", (unsigned)H5EA_MAX_NELMTS_IDX_MAX)
+ if(cparam->sup_blk_min_data_ptrs < 2)
+ H5E_THROW(H5E_BADVALUE, "min # of data block pointers in super block must be >= two")
+ if(!POWER_OF_TWO(cparam->sup_blk_min_data_ptrs))
+ H5E_THROW(H5E_BADVALUE, "min # of data block pointers in super block must be power of two")
+ if(!POWER_OF_TWO(cparam->data_blk_min_elmts))
+ H5E_THROW(H5E_BADVALUE, "min # of elements per data block must be power of two")
+ dblk_page_nelmts = (size_t)1 << cparam->max_dblk_page_nelmts_bits;
+ if(dblk_page_nelmts < cparam->idx_blk_elmts)
+ H5E_THROW(H5E_BADVALUE, "# of elements per data block page must be greater than # of elements in index block")
+
+ /* Compute the number of elements in data blocks for first actual super block */
+ sblk_idx = H5EA_SBLK_FIRST_IDX(cparam->sup_blk_min_data_ptrs);
+ dblk_nelmts = H5EA_SBLK_DBLK_NELMTS(sblk_idx, cparam->data_blk_min_elmts);
+ if(dblk_page_nelmts < dblk_nelmts)
+ H5E_THROW(H5E_BADVALUE, "max. # of elements per data block page bits must be > # of elements in first data block from super block")
+
+ if(cparam->max_dblk_page_nelmts_bits > cparam->max_nelmts_bits)
+ H5E_THROW(H5E_BADVALUE, "max. # of elements per data block page bits must be <= max. # of elements bits")
+}
+#endif /* NDEBUG */
+
+ /* Allocate space for the shared information */
+ if(NULL == (hdr = H5EA__hdr_alloc(f)))
+ 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 */
+ HDmemcpy(&hdr->cparam, cparam, sizeof(hdr->cparam));
+
+ /* Finish initializing extensible array header */
+ if(H5EA__hdr_init(hdr, ctx_udata) < 0)
+ H5E_THROW(H5E_CANTINIT, "initialization failed for extensible array header")
+
+ /* Allocate space for the header on disk */
+ if(HADDR_UNDEF == (hdr->addr = H5MF_alloc(f, H5FD_MEM_EARRAY_HDR, dxpl_id, (hsize_t)hdr->size)))
+ H5E_THROW(H5E_CANTALLOC, "file allocation failed for extensible array header")
+
+ /* Cache the new extensible array header */
+ if(H5AC_set(f, dxpl_id, H5AC_EARRAY_HDR, hdr->addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTINSERT, "can't add extensible array header to cache")
+
+ /* Set address of array header to return */
+ ret_value = hdr->addr;
+
+CATCH
+ if(!H5F_addr_defined(ret_value))
+ if(hdr) {
+ /* Release header's disk space */
+ if(H5F_addr_defined(hdr->addr) && H5MF_xfree(f, H5FD_MEM_EARRAY_HDR, dxpl_id, hdr->addr, (hsize_t)hdr->size) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to free extensible array header")
+
+ /* Destroy header */
+ if(H5EA__hdr_dest(hdr) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array header")
+ } /* end if */
+
+END_FUNC(PKG) /* end H5EA__hdr_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__hdr_incr
+ *
+ * Purpose: Increment component reference count on shared array header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 26 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__hdr_incr(H5EA_hdr_t *hdr))
+
+ /* Sanity check */
+ HDassert(hdr);
+
+ /* Mark header as un-evictable when something is depending on it */
+ if(hdr->rc == 0)
+ if(H5AC_pin_protected_entry(hdr->f, hdr) < 0)
+ H5E_THROW(H5E_CANTPIN, "unable to pin extensible array header")
+
+ /* Increment reference count on shared header */
+ hdr->rc++;
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__hdr_incr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__hdr_decr
+ *
+ * Purpose: Decrement component reference count on shared array header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 26 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__hdr_decr(H5EA_hdr_t *hdr))
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(hdr->rc);
+
+ /* Decrement reference count on shared header */
+ hdr->rc--;
+
+ /* Mark header as evictable again when nothing depend on it */
+ if(hdr->rc == 0) {
+ HDassert(hdr->file_rc == 0);
+ if(H5AC_unpin_entry(hdr->f, hdr) < 0)
+ H5E_THROW(H5E_CANTUNPIN, "unable to unpin extensible array header")
+ } /* end if */
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__hdr_decr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__hdr_fuse_incr
+ *
+ * Purpose: Increment file reference count on shared array header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 26 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, NOERR,
+herr_t, SUCCEED, -,
+H5EA__hdr_fuse_incr(H5EA_hdr_t *hdr))
+
+ /* Sanity check */
+ HDassert(hdr);
+
+ /* Increment file reference count on shared header */
+ hdr->file_rc++;
+
+END_FUNC(PKG) /* end H5EA__hdr_fuse_incr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__hdr_fuse_decr
+ *
+ * Purpose: Decrement file reference count on shared array header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 26 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, NOERR,
+size_t, 0, -,
+H5EA__hdr_fuse_decr(H5EA_hdr_t *hdr))
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(hdr->file_rc);
+
+ /* Decrement file reference count on shared header */
+ hdr->file_rc--;
+
+ /* Set return value */
+ ret_value = hdr->file_rc;
+
+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
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 26 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__hdr_delete(H5EA_hdr_t *hdr, hid_t dxpl_id))
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(!hdr->file_rc);
+
+#ifndef NDEBUG
+{
+ unsigned hdr_status = 0; /* Array header's status in the metadata cache */
+
+ /* Check the array header's status in the metadata cache */
+ if(H5AC_get_entry_status(hdr->f, hdr->addr, &hdr_status) < 0)
+ H5E_THROW(H5E_CANTGET, "unable to check metadata cache status for array header")
+
+ /* Sanity checks on array header */
+ HDassert(hdr_status & H5AC_ES__IN_CACHE);
+ HDassert(hdr_status & H5AC_ES__IS_PROTECTED);
+} /* end block */
+#endif /* NDEBUG */
+
+ /* Check for index block */
+ if(H5F_addr_defined(hdr->idx_blk_addr)) {
+#ifdef QAK
+HDfprintf(stderr, "%s: hdr->idx_blk_addr = %a\n", FUNC, hdr->idx_blk_addr);
+#endif /* QAK */
+ /* Delete index block */
+ if(H5EA__iblock_delete(hdr, dxpl_id) < 0)
+ H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array index block")
+ } /* end if */
+
+ /* Finished deleting header */
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_EARRAY_HDR, hdr->addr, hdr, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array header")
+ hdr = NULL;
+
+CATCH
+
+ /* Unprotect the header, if an error occurred */
+ if(hdr && H5AC_unprotect(hdr->f, dxpl_id, H5AC_EARRAY_HDR, hdr->addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array header")
+
+END_FUNC(PKG) /* end H5EA__hdr_delete() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__hdr_dest
+ *
+ * Purpose: Destroys an extensible array header in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__hdr_dest(H5EA_hdr_t *hdr))
+
+ /* Check arguments */
+ HDassert(hdr);
+ HDassert(hdr->rc == 0);
+
+ /* Destroy the callback context */
+ if(hdr->cb_ctx) {
+ if((*hdr->cparam.cls->dst_context)(hdr->cb_ctx) < 0)
+ H5E_THROW(H5E_CANTRELEASE, "unable to destroy extensible array client callback context")
+ } /* end if */
+ hdr->cb_ctx = NULL;
+
+ /* Check for data block element buffer factory info to free */
+ if(hdr->elmt_fac.fac) {
+ unsigned u; /* Local index variable */
+
+ /* Sanity check */
+ HDassert(hdr->elmt_fac.nalloc > 0);
+
+ /* Iterate over factories, shutting them down */
+ for(u = 0; u < hdr->elmt_fac.nalloc; u++) {
+ /* Check if this factory has been initialized */
+ if(hdr->elmt_fac.fac[u]) {
+ if(H5FL_fac_term(hdr->elmt_fac.fac[u]) < 0)
+ H5E_THROW(H5E_CANTRELEASE, "unable to destroy extensible array header factory")
+ hdr->elmt_fac.fac[u] = NULL;
+ } /* end if */
+ } /* end for */
+
+ /* Free factory array */
+ hdr->elmt_fac.fac = (H5FL_fac_head_t **)H5FL_SEQ_FREE(H5FL_fac_head_ptr_t, hdr->elmt_fac.fac);
+ } /* end if */
+
+ /* Free the super block info array */
+ if(hdr->sblk_info)
+ hdr->sblk_info = (H5EA_sblk_info_t *)H5FL_SEQ_FREE(H5EA_sblk_info_t, hdr->sblk_info);
+
+ /* Free the shared info itself */
+ hdr = H5FL_FREE(H5EA_hdr_t, hdr);
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__hdr_dest() */
+
diff --git a/src/H5EAiblock.c b/src/H5EAiblock.c
new file mode 100644
index 0000000..9920277
--- /dev/null
+++ b/src/H5EAiblock.c
@@ -0,0 +1,481 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 "H5FLprivate.h" /* Free Lists */
+#include "H5MFprivate.h" /* File memory management */
+#include "H5Vprivate.h" /* Vectors and arrays */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5EA_iblock_t struct */
+H5FL_DEFINE_STATIC(H5EA_iblock_t);
+
+/* Declare a free list to manage the index block elements */
+H5FL_BLK_DEFINE_STATIC(idx_blk_elmt_buf);
+
+/* Declare a free list to manage the haddr_t sequence information */
+H5FL_SEQ_DEFINE_STATIC(haddr_t);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__iblock_alloc
+ *
+ * Purpose: Allocate 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")
+
+ /* 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;
+
+ /* Compute information */
+ iblock->nsblks = H5EA_SBLK_FIRST_IDX(hdr->cparam.sup_blk_min_data_ptrs);
+ iblock->ndblk_addrs = 2 * ((size_t)hdr->cparam.sup_blk_min_data_ptrs - 1);
+ iblock->nsblk_addrs = hdr->nsblks - iblock->nsblks;
+#ifdef QAK
+HDfprintf(stderr, "%s: iblock->nsblks = %u\n", FUNC, iblock->nsblks);
+HDfprintf(stderr, "%s: iblock->ndblk_addrs = %Zu\n", FUNC, iblock->ndblk_addrs);
+HDfprintf(stderr, "%s: iblock->nsblk_addrs = %Zu\n", FUNC, iblock->nsblk_addrs);
+#endif /* QAK */
+
+ /* Allocate buffer for elements in index block */
+ if(hdr->cparam.idx_blk_elmts > 0)
+ if(NULL == (iblock->elmts = H5FL_BLK_MALLOC(idx_blk_elmt_buf, (size_t)(hdr->cparam.idx_blk_elmts * hdr->cparam.cls->nat_elmt_size))))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for index block data element buffer")
+
+ /* Allocate buffer for data block addresses in index block */
+ if(iblock->ndblk_addrs > 0)
+ if(NULL == (iblock->dblk_addrs = H5FL_SEQ_MALLOC(haddr_t, iblock->ndblk_addrs)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for index block data block addresses")
+
+ /* Allocate buffer for super block addresses in index block */
+ if(iblock->nsblk_addrs > 0)
+ 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")
+
+ /* Set the return value */
+ ret_value = iblock;
+
+CATCH
+ if(!ret_value)
+ if(iblock && H5EA__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, hbool_t *stats_changed))
+
+ /* Local variables */
+ H5EA_iblock_t *iblock = NULL; /* Extensible array index block */
+ haddr_t iblock_addr; /* Extensible array index block address */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(stats_changed);
+
+ /* 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 index block on disk */
+ iblock->size = H5EA_IBLOCK_SIZE(iblock);
+#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, (hsize_t)iblock->size)))
+ H5E_THROW(H5E_CANTALLOC, "file allocation failed for extensible array index block")
+ iblock->addr = iblock_addr;
+
+ /* Clear any elements in index block to fill value */
+ if(hdr->cparam.idx_blk_elmts > 0) {
+ /* Call the class's 'fill' callback */
+ if((hdr->cparam.cls->fill)(iblock->elmts, (size_t)hdr->cparam.idx_blk_elmts) < 0)
+ H5E_THROW(H5E_CANTSET, "can't set extensible array index block elements to class's fill value")
+ } /* end if */
+
+ /* Reset any data block addresses in the index block */
+ if(iblock->ndblk_addrs > 0) {
+ haddr_t tmp_addr = HADDR_UNDEF; /* Address value to fill data block addresses with */
+
+ /* Set all the data block addresses to "undefined" address value */
+ H5V_array_fill(iblock->dblk_addrs, &tmp_addr, sizeof(haddr_t), iblock->ndblk_addrs);
+ } /* end if */
+
+ /* Reset any super block addresses in the index block */
+ if(iblock->nsblk_addrs > 0) {
+ haddr_t tmp_addr = HADDR_UNDEF; /* Address value to fill super block addresses with */
+
+ /* Set all the super block addresses to "undefined" address value */
+ H5V_array_fill(iblock->sblk_addrs, &tmp_addr, sizeof(haddr_t), iblock->nsblk_addrs);
+ } /* 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")
+
+ /* Update extensible array index block statistics */
+ HDassert(0 == hdr->stats.computed.nindex_blks);
+ HDassert(0 == hdr->stats.computed.index_blk_size);
+ hdr->stats.computed.nindex_blks = 1;
+ hdr->stats.computed.index_blk_size = iblock->size;
+
+ /* Increment count of elements "realized" */
+ hdr->stats.stored.nelmts += hdr->cparam.idx_blk_elmts;
+
+ /* Mark the statistics as changed */
+ *stats_changed = TRUE;
+
+ /* 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__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))
+
+#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: Non-negative on success/Negative on failure
+ *
+ * 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)
+
+ /* Check for index block having data block pointers */
+ if(iblock->ndblk_addrs > 0) {
+ unsigned sblk_idx; /* Current super block index */
+ unsigned dblk_idx; /* Current data block index w/in super block */
+ size_t u; /* Local index variable */
+
+ /* Iterate over data blocks */
+ sblk_idx = dblk_idx = 0;
+ for(u = 0; u < iblock->ndblk_addrs; u++) {
+ /* Check for data block existing */
+ if(H5F_addr_defined(iblock->dblk_addrs[u])) {
+ /* Delete data block */
+ if(H5EA__dblock_delete(hdr, dxpl_id, iblock, iblock->dblk_addrs[u], hdr->sblk_info[sblk_idx].dblk_nelmts) < 0)
+ H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array data block")
+ iblock->dblk_addrs[u] = HADDR_UNDEF;
+ } /* end if */
+
+ /* Advance to next data block w/in super block */
+ dblk_idx++;
+
+ /* Check for moving to next super block */
+ if(dblk_idx >= hdr->sblk_info[sblk_idx].ndblks) {
+ sblk_idx++;
+ dblk_idx = 0;
+ } /* end if */
+ } /* end for */
+ } /* end if */
+
+ /* Check for index block having data block pointers (not yet) */
+ if(iblock->nsblk_addrs > 0) {
+ size_t u; /* Local index variable */
+
+ /* Iterate over super blocks */
+ for(u = 0; u < iblock->nsblk_addrs; u++) {
+ /* Check for data block existing */
+ if(H5F_addr_defined(iblock->sblk_addrs[u])) {
+ /* Delete super block */
+ if(H5EA__sblock_delete(hdr, dxpl_id, iblock, iblock->sblk_addrs[u], (unsigned)(u + iblock->nsblks)) < 0)
+ H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array super block")
+ iblock->sblk_addrs[u] = HADDR_UNDEF;
+ } /* end if */
+ } /* end for */
+ } /* end if */
+
+CATCH
+ /* Finished deleting index block in metadata cache */
+ if(iblock && H5EA__iblock_unprotect(iblock, dxpl_id, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array index block")
+
+END_FUNC(PKG) /* end H5EA__iblock_delete() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__iblock_dest
+ *
+ * Purpose: Destroys an extensible array index block in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__iblock_dest(H5F_t *f, H5EA_iblock_t *iblock))
+
+ /* Sanity check */
+ HDassert(iblock);
+ HDassert(iblock->rc == 0);
+
+ /* 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->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->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->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")
+ iblock->hdr = NULL;
+ } /* end if */
+
+ /* Free the index block itself */
+ (void)H5FL_FREE(H5EA_iblock_t, iblock);
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__iblock_dest() */
+
diff --git a/src/H5EAint.c b/src/H5EAint.c
new file mode 100644
index 0000000..5ce88fc
--- /dev/null
+++ b/src/H5EAint.c
@@ -0,0 +1,144 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5EAint.c
+ * Jun 17 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Internal routines for extnsible 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 */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__create_flush_depend
+ *
+ * Purpose: Create a flush dependency between two data structure components
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Mar 26 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__create_flush_depend(H5EA_hdr_t *hdr, H5AC_info_t *parent_entry,
+ H5AC_info_t *child_entry))
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(parent_entry);
+ HDassert(child_entry);
+
+ /* Create a flush dependency between parent and child entry */
+ if(H5AC_create_flush_dependency(hdr->f, parent_entry, child_entry) < 0)
+ H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency")
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__create_flush_depend() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__destroy_flush_depend
+ *
+ * Purpose: Destroy a flush dependency between two data structure components
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Mar 26 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__destroy_flush_depend(H5EA_hdr_t *hdr, H5AC_info_t *parent_entry, H5AC_info_t *child_entry))
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(parent_entry);
+ HDassert(child_entry);
+
+ /* Destroy a flush dependency between parent and child entry */
+ if(H5AC_destroy_flush_dependency(hdr->f, parent_entry, child_entry) < 0)
+ H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency")
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__destroy_flush_depend() */
+
diff --git a/src/H5EApkg.h b/src/H5EApkg.h
new file mode 100644
index 0000000..6e86a34
--- /dev/null
+++ b/src/H5EApkg.h
@@ -0,0 +1,453 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Quincey Koziol <koziol@hdfgroup.org>
+ * Tuesday, June 17, 2008
+ *
+ * Purpose: This file contains declarations which are visible only within
+ * the H5EA package. Source files outside the H5EA package should
+ * include H5EAprivate.h instead.
+ */
+#if !(defined(H5EA_PACKAGE) | defined(H5EA_MODULE))
+#error "Do not include this file outside the H5EA package!"
+#endif
+
+#ifndef _H5EApkg_H
+#define _H5EApkg_H
+
+/* Get package's private header */
+#include "H5EAprivate.h"
+
+/* Other private headers needed by this file */
+#include "H5FLprivate.h" /* Free Lists */
+
+
+/**************************/
+/* Package Private Macros */
+/**************************/
+
+/* If this package header is being included in one of the H5EA modules, define
+ * the proper control macros for the generic FUNC_ENTER/LEAVE and error
+ * reporting macros.
+ */
+#ifdef H5EA_MODULE
+#define H5_MY_PKG H5EA
+#define H5_MY_PKG_ERR H5E_EARRAY
+#define H5_MY_PKG_INIT NO
+#endif /* H5EA_MODULE */
+
+/* Fill value for extensible array test class */
+#ifdef H5EA_TESTING
+#define H5EA_TEST_FILL ((uint64_t)ULLONG_MAX)
+#endif /* H5EA_TESTING */
+
+/* Size of checksum information (on disk) */
+#define H5EA_SIZEOF_CHKSUM 4
+
+/* "Standard" size of prefix information for extensible array metadata */
+#define H5EA_METADATA_PREFIX_SIZE(c) ( \
+ H5_SIZEOF_MAGIC /* Signature */ \
+ + 1 /* Version */ \
+ + ((c) ? H5EA_SIZEOF_CHKSUM : 0) /* Metadata checksum */ \
+ )
+
+/* Size of the extensible array header on disk */
+#define H5EA_HEADER_SIZE(h) ( \
+ /* General metadata fields */ \
+ H5EA_METADATA_PREFIX_SIZE(TRUE) \
+ \
+ /* General array information */ \
+ + 1 /* Array type */ \
+ + 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 */ \
+ + 1 /* Log2(Max. # of elements in data block page) - i.e. # of bits needed to store max. # of elements in data block page */ \
+ \
+ /* Extensible Array statistics fields */ \
+ + (h)->sizeof_size /* Number of super blocks created */ \
+ + (h)->sizeof_size /* Size of super blocks created */ \
+ + (h)->sizeof_size /* Number of data blocks created */ \
+ + (h)->sizeof_size /* Size of data blocks created */ \
+ + (h)->sizeof_size /* Max. index set */ \
+ + (h)->sizeof_size /* Number of elements 'realized' */ \
+ \
+ /* Extensible Array Header specific fields */ \
+ + (h)->sizeof_addr /* File address of index block */ \
+ )
+
+/* Size of the extensible array index block on disk */
+#define H5EA_IBLOCK_SIZE(i) ( \
+ /* General metadata fields */ \
+ H5EA_METADATA_PREFIX_SIZE(TRUE) \
+ \
+ /* Sanity-checking fields */ \
+ + 1 /* Array type */ \
+ + (i)->hdr->sizeof_addr /* File address of array owning the block */ \
+ \
+ /* Extensible Array Index Block specific fields */ \
+ + ((size_t)(i)->hdr->cparam.idx_blk_elmts * (size_t)(i)->hdr->cparam.raw_elmt_size) /* Elements in index block */ \
+ + ((i)->ndblk_addrs * (i)->hdr->sizeof_addr) /* Data block addresses in index block */ \
+ + ((i)->nsblk_addrs * (i)->hdr->sizeof_addr) /* Super block addresses in index block */ \
+ )
+
+/* Size of the extensible array super block on disk */
+#define H5EA_SBLOCK_SIZE(s) ( \
+ /* General metadata fields */ \
+ H5EA_METADATA_PREFIX_SIZE(TRUE) \
+ \
+ /* Sanity-checking fields */ \
+ + 1 /* Array type */ \
+ + (s)->hdr->sizeof_addr /* File address of array owning the block */ \
+ + (s)->hdr->arr_off_size /* Offset of the block in the array */ \
+ \
+ /* Extensible Array Super Block specific fields */ \
+ + ((s)->ndblks * (s)->dblk_page_init_size) /* Data block 'page init' bitmasks in super block (can be 0 if no pages) */ \
+ + ((s)->ndblks * (s)->hdr->sizeof_addr) /* Data block addresses in super block */ \
+ )
+
+/* Size of the extensible array data block prefix on disk */
+#define H5EA_DBLOCK_PREFIX_SIZE(d) ( \
+ /* General metadata fields */ \
+ H5EA_METADATA_PREFIX_SIZE(TRUE) \
+ \
+ /* Sanity-checking fields */ \
+ + 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 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 */
+#define H5EA_SIZEOF_OFFSET_BITS(b) (((b) + 7) / 8)
+
+/* Compute the first super block index that will hold a certain # of data block pointers */
+#define H5EA_SBLK_FIRST_IDX(m) (2 * H5V_log2_of2((uint32_t)m))
+
+/****************************/
+/* Package Private Typedefs */
+/****************************/
+
+/* Information for each super block in extensible array */
+typedef struct H5EA_sblk_info_t {
+ size_t ndblks; /* Number of data blocks for a super block */
+ size_t dblk_nelmts; /* Number of elements in each data block for super block */
+ hsize_t start_idx; /* Index of first element in super block */
+ hsize_t start_dblk; /* Index of first data block in super block */
+} H5EA_sblk_info_t;
+
+/* The extensible array header information */
+/* (Each extensible array header has certain information that is shared across
+ * all the blocks in that extensible array)
+ */
+typedef struct H5EA_hdr_t {
+ /* Information for H5AC cache functions, _must_ be first field in structure */
+ H5AC_info_t cache_info;
+
+ /* Extensible array configuration/creation parameters (stored in header) */
+ H5EA_create_t cparam; /* Creation parameters for extensible array */
+
+ /* Index block information (stored in header) */
+ haddr_t idx_blk_addr; /* Address of index block in header */
+
+ /* Statistics for array (stored in index block, actually) */
+ /* (header and index number/size fields not stored) */
+ H5EA_stat_t stats; /* Statistics for extensible array */
+
+ /* Data block element buffer factory info (not stored in header) */
+ struct {
+ size_t nalloc; /* Number of factories allocated */
+ H5FL_fac_head_t **fac; /* Array of factories for data block element buffers */
+ } elmt_fac;
+
+ /* Computed/cached values (not stored in header) */
+ size_t rc; /* Reference count of heap's components using heap header */
+ haddr_t addr; /* Address of header in file */
+ size_t size; /* Size of header in file */
+ 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 */
+ unsigned char arr_off_size; /* Size of array offsets (in bytes) */
+
+ /* Super block information (not stored) */
+ size_t nsblks; /* Number of superblocks needed for array */
+ H5EA_sblk_info_t *sblk_info; /* Array of information for each super block */
+
+ /* Data block information (not stored) */
+ size_t dblk_page_nelmts; /* # of elements per data block page */
+
+ /* Client information (not stored) */
+ void *cb_ctx; /* Callback context */
+} 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 */
+ haddr_t *dblk_addrs; /* Buffer for addresses of data blocks in index block */
+ haddr_t *sblk_addrs; /* Buffer for addresses of super blocks 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 */
+
+ /* Computed/cached values (not stored) */
+ size_t nsblks; /* # of super blocks whose data block addresses are in index block */
+ size_t ndblk_addrs; /* Number of pointers to data blocks in index block */
+ size_t nsblk_addrs; /* Number of pointers to super blocks in index block */
+} H5EA_iblock_t;
+
+/* The extensible array super block information */
+typedef struct H5EA_sblock_t {
+ /* Information for H5AC cache functions, _must_ be first field in structure */
+ H5AC_info_t cache_info;
+
+ /* Extensible array information (stored) */
+ hsize_t block_off; /* Offset of the block within the array's address space */
+ haddr_t *dblk_addrs; /* Addresses of data blocks in super block */
+ uint8_t *page_init; /* Bitmap of whether a data block page is initialized */
+
+ /* Internal array information (not stored) */
+ size_t rc; /* Reference count of objects using this block */
+ H5EA_hdr_t *hdr; /* Shared array header info */
+ H5EA_iblock_t *parent; /* Parent object for super block (index block) */
+ haddr_t addr; /* Address of this index block on disk */
+ size_t size; /* Size of index block on disk */
+
+ /* Computed/cached values (not stored) */
+ unsigned idx; /* Super block index within the extensible array */
+ size_t ndblks; /* # of data block addresses that are in super block */
+ size_t dblk_nelmts; /* # of elements for data blocks reachable through this super block */
+ 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 */
+typedef struct H5EA_dblock_t {
+ /* Information for H5AC cache functions, _must_ be first field in structure */
+ H5AC_info_t cache_info;
+
+ /* Extensible array information (stored) */
+ hsize_t block_off; /* Offset of the block within the array's address space */
+ void *elmts; /* Buffer for elements stored in data block */
+
+ /* Internal array information (not stored) */
+ H5EA_hdr_t *hdr; /* Shared array header info */
+ void *parent; /* Parent object for data block (index or super block) */
+ haddr_t addr; /* Address of this data block on disk */
+ size_t size; /* Size of data block on disk */
+
+ /* 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 */
+ H5EA_sblock_t *parent; /* Parent object for data block page (super block) */
+ 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 */
+ H5F_t *f; /* Pointer to file for extensible array */
+};
+
+/* Metadata cache callback user data types */
+
+/* Info needed for loading data block page */
+typedef struct H5EA_dblk_page_load_ud_t {
+ H5EA_sblock_t *parent; /* Pointer to parent object for data block page (super block) */
+} H5EA_dblk_page_load_ud_t;
+
+/* Info needed for loading data block */
+typedef struct H5EA_dblock_load_ud_t {
+ void *parent; /* Pointer to parent object for data block (index or super block) */
+ size_t nelmts; /* Number of elements in data block */
+} H5EA_dblock_load_ud_t;
+
+/* Info needed for loading super block */
+typedef struct H5EA_sblock_load_ud_t {
+ H5EA_iblock_t *parent; /* Pointer to parent object for super block (index block) */
+ unsigned sblk_idx; /* Index of super block */
+} H5EA_sblock_load_ud_t;
+
+#ifdef H5EA_TESTING
+typedef struct H5EA__ctx_cb_t {
+ herr_t (*encode)(const void *elmt, size_t nelmts, void *udata); /* Perform action during encode step */
+ void *udata; /* User data for encode action */
+} H5EA__ctx_cb_t;
+#endif /* H5EA_TESTING */
+
+/*****************************/
+/* Package Private Variables */
+/*****************************/
+
+/* 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];
+
+/* H5EA index block inherits cache-like properties from H5AC */
+H5_DLLVAR const H5AC_class_t H5AC_EARRAY_SBLOCK[1];
+
+/* H5EA data block inherits cache-like properties from H5AC */
+H5_DLLVAR const H5AC_class_t H5AC_EARRAY_DBLOCK[1];
+
+/* 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];
+#endif /* H5EA_TESTING */
+
+/* Array of extensible array client ID -> client class mappings */
+extern const H5EA_class_t *const H5EA_client_class_g[];
+
+
+/******************************/
+/* Package Private Prototypes */
+/******************************/
+
+/* Generic routines */
+H5_DLL herr_t H5EA__create_flush_depend(H5EA_hdr_t *hdr, H5AC_info_t *parent_entry,
+ H5AC_info_t *child_entry);
+H5_DLL herr_t H5EA__destroy_flush_depend(H5EA_hdr_t *hdr, H5AC_info_t *parent_entry,
+ H5AC_info_t *child_entry);
+
+/* Header routines */
+H5_DLL H5EA_hdr_t *H5EA__hdr_alloc(H5F_t *f);
+H5_DLL herr_t H5EA__hdr_init(H5EA_hdr_t *hdr, void *ctx_udata);
+H5_DLL haddr_t H5EA__hdr_create(H5F_t *f, hid_t dxpl_id, const H5EA_create_t *cparam,
+ void *ctx_udata);
+H5_DLL void *H5EA__hdr_alloc_elmts(H5EA_hdr_t *hdr, size_t nelmts);
+H5_DLL herr_t H5EA__hdr_free_elmts(H5EA_hdr_t *hdr, size_t nelmts, void *elmts);
+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);
+H5_DLL herr_t H5EA__hdr_dest(H5EA_hdr_t *hdr);
+
+/* 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,
+ hbool_t *stats_changed);
+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);
+H5_DLL herr_t H5EA__iblock_dest(H5F_t *f, H5EA_iblock_t *iblock);
+
+/* Super block routines */
+H5_DLL H5EA_sblock_t *H5EA__sblock_alloc(H5EA_hdr_t *hdr, H5EA_iblock_t *parent,
+ unsigned sblk_idx);
+H5_DLL haddr_t H5EA__sblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id,
+ H5EA_iblock_t *parent, hbool_t *stats_changed, unsigned sblk_idx);
+H5_DLL H5EA_sblock_t *H5EA__sblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id,
+ H5EA_iblock_t *parent, haddr_t sblk_addr, unsigned sblk_idx, H5AC_protect_t rw);
+H5_DLL herr_t H5EA__sblock_unprotect(H5EA_sblock_t *sblock, hid_t dxpl_id,
+ unsigned cache_flags);
+H5_DLL herr_t H5EA__sblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id,
+ H5EA_iblock_t *parent, haddr_t sblk_addr, unsigned sblk_idx);
+H5_DLL herr_t H5EA__sblock_dest(H5F_t *f, H5EA_sblock_t *sblock);
+
+/* Data block routines */
+H5_DLL H5EA_dblock_t *H5EA__dblock_alloc(H5EA_hdr_t *hdr, void *parent,
+ size_t nelmts);
+H5_DLL haddr_t H5EA__dblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, void *parent,
+ hbool_t *stats_changed, hsize_t dblk_off, size_t nelmts);
+H5_DLL unsigned H5EA__dblock_sblk_idx(const H5EA_hdr_t *hdr, hsize_t idx);
+H5_DLL H5EA_dblock_t *H5EA__dblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id,
+ void *parent, haddr_t dblk_addr, size_t dblk_nelmts, H5AC_protect_t rw);
+H5_DLL herr_t H5EA__dblock_unprotect(H5EA_dblock_t *dblock, hid_t dxpl_id,
+ unsigned cache_flags);
+H5_DLL herr_t H5EA__dblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id, void *parent,
+ 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, H5EA_sblock_t *parent);
+H5_DLL herr_t H5EA__dblk_page_create(H5EA_hdr_t *hdr, hid_t dxpl_id,
+ H5EA_sblock_t *parent, haddr_t addr);
+H5_DLL H5EA_dblk_page_t *H5EA__dblk_page_protect(H5EA_hdr_t *hdr, hid_t dxpl_id,
+ H5EA_sblock_t *parent, 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);
+H5_DLL herr_t H5EA__iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ FILE *stream, int indent, int fwidth, const H5EA_class_t *cls,
+ haddr_t hdr_addr);
+H5_DLL herr_t H5EA__sblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ FILE *stream, int indent, int fwidth, const H5EA_class_t *cls,
+ haddr_t hdr_addr, unsigned sblk_idx);
+H5_DLL herr_t H5EA__dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ FILE *stream, int indent, int fwidth, const H5EA_class_t *cls,
+ haddr_t hdr_addr, size_t dblk_nelmts);
+
+/* Testing routines */
+#ifdef H5EA_TESTING
+H5_DLL herr_t H5EA_get_cparam_test(const H5EA_t *ea, H5EA_create_t *cparam);
+H5_DLL int H5EA_cmp_cparam_test(const H5EA_create_t *cparam1, const H5EA_create_t *cparam2);
+#endif /* H5EA_TESTING */
+
+#endif /* _H5EApkg_H */
+
diff --git a/src/H5EAprivate.h b/src/H5EAprivate.h
new file mode 100644
index 0000000..db61dee
--- /dev/null
+++ b/src/H5EAprivate.h
@@ -0,0 +1,147 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5EAprivate.h
+ * Jun 17 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Private header for library accessible extensible
+ * array routines.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef _H5EAprivate_H
+#define _H5EAprivate_H
+
+/* Include package's public header */
+#ifdef NOT_YET
+#include "H5EApublic.h"
+#endif /* NOT_YET */
+
+/* Private headers needed by this file */
+#include "H5ACprivate.h" /* Metadata cache */
+#include "H5Fprivate.h" /* File access */
+
+
+/**************************/
+/* Library Private Macros */
+/**************************/
+
+
+/****************************/
+/* Library Private Typedefs */
+/****************************/
+
+/* Extensible array class IDs */
+typedef enum H5EA_cls_id_t {
+ /* Start real class IDs at 0 -QAK */
+ /* (keep these last) */
+ H5EA_CLS_TEST_ID, /* Extensible array is for testing (do not use for actual data) */
+ H5EA_NUM_CLS_ID /* Number of Extensible Array class IDs (must be last) */
+} H5EA_cls_id_t;
+
+/*
+ * Each type of element that can be stored in an extesible array has a
+ * variable of this type that contains class variables and methods.
+ */
+typedef struct H5EA_class_t {
+ H5EA_cls_id_t id; /* ID of Extensible Array class, as found in file */
+ size_t nat_elmt_size; /* Size of native (memory) element */
+
+ /* Extensible array client callback methods */
+ void *(*crt_context)(void *udata); /* Create context for other callbacks */
+ herr_t (*dst_context)(void *ctx); /* Destroy context */
+ 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, void *ctx); /* Encode elements from native form to disk storage form */
+ herr_t (*decode)(const void *raw, void *elmt, size_t nelmts, void *ctx); /* Decode elements from disk storage form to native form */
+ herr_t (*debug)(FILE *stream, int indent, int fwidth, hsize_t idx, const void *elmt); /* Print an element for debugging */
+} H5EA_class_t;
+
+/* Extensible array creation parameters */
+typedef struct H5EA_create_t {
+ const H5EA_class_t *cls; /* Class of extensible array to create */
+ uint8_t raw_elmt_size; /* Element size in file (in bytes) */
+ uint8_t max_nelmts_bits; /* Log2(Max. # of elements in array) - i.e. # of bits needed to store max. # of elements */
+ uint8_t idx_blk_elmts; /* # of elements to store in index block */
+ 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 */
+ uint8_t max_dblk_page_nelmts_bits; /* Log2(Max. # of elements in data block page) - i.e. # of bits needed to store max. # of elements in data block page */
+} H5EA_create_t;
+
+/* Extensible array metadata statistics info */
+/* (If these are ever exposed to applications, don't let the application see
+ * which fields are computed vs. which fields are stored. -QAK)
+ */
+typedef struct H5EA_stat_t {
+ /* Non-stored (i.e. computed) fields */
+ struct {
+ hsize_t hdr_size; /* Size of header */
+ hsize_t nindex_blks; /* # of index blocks (should be 0 or 1) */
+ hsize_t index_blk_size; /* Size of index blocks allocated */
+ } computed;
+
+ /* Stored fields */
+ struct {
+ hsize_t nsuper_blks; /* # of super blocks */
+ hsize_t super_blk_size; /* Size of super blocks allocated */
+ hsize_t ndata_blks; /* # of data blocks */
+ hsize_t data_blk_size; /* Size of data blocks allocated */
+ 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') */
+ hsize_t nelmts; /* # of elements "realized" */
+ } stored;
+} H5EA_stat_t;
+
+/* Extensible array info (forward decl - defined in H5EApkg.h) */
+typedef struct H5EA_t H5EA_t;
+
+
+/*****************************/
+/* Library-private Variables */
+/*****************************/
+
+
+/***************************************/
+/* Library-private Function Prototypes */
+/***************************************/
+
+/* General routines */
+H5_DLL H5EA_t *H5EA_create(H5F_t *f, hid_t dxpl_id, const H5EA_create_t *cparam,
+ void *ctx_udata);
+H5_DLL H5EA_t *H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata);
+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_set(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, const void *elmt);
+H5_DLL herr_t H5EA_get(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, void *elmt);
+H5_DLL herr_t H5EA_depend(H5AC_info_t *parent_entry, H5EA_t *ea);
+H5_DLL herr_t H5EA_undepend(H5AC_info_t *parent_entry, H5EA_t *ea);
+H5_DLL herr_t H5EA_support(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx,
+ H5AC_info_t *child_entry);
+H5_DLL herr_t H5EA_unsupport(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx,
+ H5AC_info_t *child_entry);
+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, void *ctx_udata);
+
+/* Statistics routines */
+H5_DLL herr_t H5EA_get_stats(const H5EA_t *ea, H5EA_stat_t *stats);
+
+/* Debugging routines */
+#ifdef H5EA_DEBUGGING
+#endif /* H5EA_DEBUGGING */
+
+#endif /* _H5EAprivate_H */
+
diff --git a/src/H5EAsblock.c b/src/H5EAsblock.c
new file mode 100644
index 0000000..c6a4306
--- /dev/null
+++ b/src/H5EAsblock.c
@@ -0,0 +1,446 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5EAsblock.c
+ * Sep 30 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Super block routines for extensible arrays.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/**********************/
+/* Module Declaration */
+/**********************/
+
+#define H5EA_MODULE
+
+
+/***********************/
+/* Other Packages Used */
+/***********************/
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5EApkg.h" /* Extensible Arrays */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5MFprivate.h" /* File memory management */
+#include "H5Vprivate.h" /* Vectors and arrays */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5EA_iblock_t struct */
+H5FL_DEFINE_STATIC(H5EA_sblock_t);
+
+/* Declare a free list to manage the haddr_t sequence information */
+H5FL_SEQ_DEFINE_STATIC(haddr_t);
+
+/* Declare a free list to manage blocks of 'page init' bitmasks */
+H5FL_BLK_DEFINE(page_init);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__sblock_alloc
+ *
+ * Purpose: Allocate extensible array super block
+ *
+ * Return: Non-NULL pointer to super block on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+H5EA_sblock_t *, NULL, NULL,
+H5EA__sblock_alloc(H5EA_hdr_t *hdr, H5EA_iblock_t *parent, unsigned sblk_idx))
+
+ /* Local variables */
+ H5EA_sblock_t *sblock = NULL; /* Extensible array super block */
+
+ /* Check arguments */
+ HDassert(hdr);
+
+ /* Allocate memory for the index block */
+ if(NULL == (sblock = H5FL_CALLOC(H5EA_sblock_t)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array super block")
+
+ /* 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->parent = parent;
+ sblock->addr = HADDR_UNDEF;
+
+ /* Compute/cache information */
+ sblock->idx = sblk_idx;
+ sblock->ndblks = hdr->sblk_info[sblk_idx].ndblks;
+ HDassert(sblock->ndblks);
+ sblock->dblk_nelmts = hdr->sblk_info[sblk_idx].dblk_nelmts;
+#ifdef QAK
+HDfprintf(stderr, "%s: hdr->dblk_page_nelmts = %Zu, sblock->ndblks = %Zu, sblock->dblk_nelmts = %Zu\n", FUNC, hdr->dblk_page_nelmts, sblock->ndblks, sblock->dblk_nelmts);
+#endif /* QAK */
+
+ /* Allocate buffer for data block addresses in super block */
+ if(NULL == (sblock->dblk_addrs = H5FL_SEQ_MALLOC(haddr_t, sblock->ndblks)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for super block data block addresses")
+
+ /* Check if # of elements in data blocks requires paging */
+ if(sblock->dblk_nelmts > hdr->dblk_page_nelmts) {
+ /* Compute # of pages in each data block from this super block */
+ sblock->dblk_npages = sblock->dblk_nelmts / hdr->dblk_page_nelmts;
+
+ /* Sanity check that we have at least 2 pages in data block */
+ HDassert(sblock->dblk_npages > 1);
+
+ /* Sanity check for integer truncation */
+ HDassert((sblock->dblk_npages * hdr->dblk_page_nelmts) == sblock->dblk_nelmts);
+
+ /* Compute size of buffer for each data block's 'page init' bitmask */
+ sblock->dblk_page_init_size = ((sblock->dblk_npages) + 7) / 8;
+ HDassert(sblock->dblk_page_init_size > 0);
+
+ /* 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")
+
+ /* 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;
+
+CATCH
+ if(!ret_value)
+ if(sblock && H5EA__sblock_dest(hdr->f, sblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array super block")
+
+END_FUNC(PKG) /* end H5EA__sblock_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__sblock_create
+ *
+ * Purpose: Creates a new extensible array super block in the file
+ *
+ * Return: Valid file address on success/HADDR_UNDEF on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+haddr_t, HADDR_UNDEF, HADDR_UNDEF,
+H5EA__sblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, H5EA_iblock_t *parent,
+ hbool_t *stats_changed, unsigned sblk_idx))
+
+ /* Local variables */
+ H5EA_sblock_t *sblock = NULL; /* Extensible array super block */
+ haddr_t sblock_addr; /* Extensible array super block address */
+ haddr_t tmp_addr = HADDR_UNDEF; /* Address value to fill data block addresses with */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(stats_changed);
+
+ /* Allocate the super block */
+ if(NULL == (sblock = H5EA__sblock_alloc(hdr, parent, sblk_idx)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array super block")
+
+ /* Set size of super block on disk */
+ sblock->size = H5EA_SBLOCK_SIZE(sblock);
+#ifdef QAK
+HDfprintf(stderr, "%s: sblock->size = %Zu\n", FUNC, sblock->size);
+#endif /* QAK */
+
+ /* Set offset of block in array's address space */
+ sblock->block_off = hdr->sblk_info[sblk_idx].start_idx;
+#ifdef QAK
+HDfprintf(stderr, "%s: sblock->block_off = %Hu\n", FUNC, sblock->block_off);
+#endif /* QAK */
+
+ /* Allocate space for the super block on disk */
+ if(HADDR_UNDEF == (sblock_addr = H5MF_alloc(hdr->f, H5FD_MEM_EARRAY_SBLOCK, dxpl_id, (hsize_t)sblock->size)))
+ H5E_THROW(H5E_CANTALLOC, "file allocation failed for extensible array super block")
+ sblock->addr = sblock_addr;
+
+ /* Reset data block addresses to "undefined" address value */
+ H5V_array_fill(sblock->dblk_addrs, &tmp_addr, sizeof(haddr_t), sblock->ndblks);
+
+ /* Cache the new extensible array super block */
+ if(H5AC_set(hdr->f, dxpl_id, H5AC_EARRAY_SBLOCK, sblock_addr, sblock, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTINSERT, "can't add extensible array super block to cache")
+
+ /* Update extensible array super block statistics */
+ hdr->stats.stored.nsuper_blks++;
+ hdr->stats.stored.super_blk_size += sblock->size;
+
+ /* Mark the statistics as changed */
+ *stats_changed = TRUE;
+
+ /* Set address of super block to return */
+ ret_value = sblock_addr;
+
+CATCH
+ if(!H5F_addr_defined(ret_value))
+ if(sblock) {
+ /* Release super block's disk space */
+ if(H5F_addr_defined(sblock->addr) && H5MF_xfree(hdr->f, H5FD_MEM_EARRAY_SBLOCK, dxpl_id, sblock->addr, (hsize_t)sblock->size) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to release extensible array super block")
+
+ /* Destroy super block */
+ if(H5EA__sblock_dest(hdr->f, sblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array super block")
+ } /* end if */
+
+END_FUNC(PKG) /* end H5EA__sblock_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__sblock_protect
+ *
+ * Purpose: Convenience wrapper around protecting extensible array super block
+ *
+ * Return: Non-NULL pointer to data block on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+H5EA_sblock_t *, NULL, NULL,
+H5EA__sblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, H5EA_iblock_t *parent,
+ haddr_t sblk_addr, unsigned sblk_idx, H5AC_protect_t rw))
+
+ /* Local variables */
+ H5EA_sblock_load_ud_t load_ud; /* Information needed for loading super block */
+
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(H5F_addr_defined(sblk_addr));
+
+ /* Set up user data */
+ load_ud.parent = parent;
+ load_ud.sblk_idx = sblk_idx;
+
+ /* Protect the super block */
+ if(NULL == (ret_value = (H5EA_sblock_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_EARRAY_SBLOCK, sblk_addr, &load_ud, hdr, rw)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array super block, address = %llu", (unsigned long long)sblk_addr)
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__sblock_protect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__sblock_unprotect
+ *
+ * Purpose: Convenience wrapper around unprotecting extensible array super block
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__sblock_unprotect(H5EA_sblock_t *sblock, hid_t dxpl_id, unsigned cache_flags))
+
+ /* Local variables */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(sblock);
+
+ /* Unprotect the super block */
+ if(H5AC_unprotect(sblock->hdr->f, dxpl_id, H5AC_EARRAY_SBLOCK, sblock->addr, sblock, cache_flags) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to unprotect extensible array super block, address = %llu", (unsigned long long)sblock->addr)
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__sblock_unprotect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__sblock_delete
+ *
+ * Purpose: Delete a super block
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__sblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id, H5EA_iblock_t *parent,
+ haddr_t sblk_addr, unsigned sblk_idx))
+
+ /* Local variables */
+ H5EA_sblock_t *sblock = NULL; /* Pointer to super block */
+ size_t u; /* Local index variable */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(H5F_addr_defined(sblk_addr));
+
+ /* Protect super block */
+ if(NULL == (sblock = H5EA__sblock_protect(hdr, dxpl_id, parent, sblk_addr, sblk_idx, H5AC_WRITE)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array super block, address = %llu", (unsigned long long)sblk_addr)
+
+ /* Iterate over data blocks */
+ for(u = 0; u < sblock->ndblks; u++) {
+ /* Check for data block existing */
+ if(H5F_addr_defined(sblock->dblk_addrs[u])) {
+ /* Delete data block */
+ if(H5EA__dblock_delete(hdr, dxpl_id, sblock, sblock->dblk_addrs[u], sblock->dblk_nelmts) < 0)
+ H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array data block")
+ sblock->dblk_addrs[u] = HADDR_UNDEF;
+ } /* end if */
+ } /* end for */
+
+CATCH
+ /* Finished deleting super block in metadata cache */
+ if(sblock && H5EA__sblock_unprotect(sblock, dxpl_id, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array super block")
+
+END_FUNC(PKG) /* end H5EA__sblock_delete() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__sblock_dest
+ *
+ * Purpose: Destroys an extensible array super block in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__sblock_dest(H5F_t *f, H5EA_sblock_t *sblock))
+
+ /* Sanity check */
+ HDassert(sblock);
+ HDassert(sblock->rc == 0);
+#ifdef QAK
+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 */
+
+ /* 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)
+ 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);
+ 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")
+ sblock->hdr = NULL;
+ } /* end if */
+
+ /* Free the super block itself */
+ (void)H5FL_FREE(H5EA_sblock_t, sblock);
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__sblock_dest() */
+
diff --git a/src/H5EAstat.c b/src/H5EAstat.c
new file mode 100644
index 0000000..8a26e34
--- /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 2008
+ * 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);
+
+ /* Copy extensible array statistics */
+ HDmemcpy(stats, &ea->hdr->stats, sizeof(ea->hdr->stats));
+
+END_FUNC(PRIV) /* end H5EA_get_stats() */
+
diff --git a/src/H5EAtest.c b/src/H5EAtest.c
new file mode 100644
index 0000000..58da489
--- /dev/null
+++ b/src/H5EAtest.c
@@ -0,0 +1,422 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* Programmer: Quincey Koziol <koziol@hdfgroup.org>
+ * Thursday, August 28, 2008
+ *
+ * Purpose: Extensible array testing functions.
+ *
+ */
+
+/**********************/
+/* Module Declaration */
+/**********************/
+
+#define H5EA_MODULE
+#define H5EA_TESTING
+
+
+/***********************/
+/* 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" /* Vector functions */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* Sanity checking value for callback contexts */
+#define H5EA__TEST_BOGUS_VAL 42
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/* Callback context */
+typedef struct H5EA__test_ctx_t {
+ uint32_t bogus; /* Placeholder field to verify that context is working */
+ H5EA__ctx_cb_t *cb; /* Pointer to context's callback action */
+} H5EA__test_ctx_t;
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* Extensible array class callbacks */
+static void *H5EA__test_crt_context(void *udata);
+static herr_t H5EA__test_dst_context(void *ctx);
+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,
+ void *ctx);
+static herr_t H5EA__test_decode(const void *raw, void *elmt, size_t nelmts,
+ void *ctx);
+static herr_t H5EA__test_debug(FILE *stream, int indent, int fwidth,
+ hsize_t idx, const void *elmt);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Extensible array testing class information */
+const H5EA_class_t H5EA_CLS_TEST[1]={{
+ H5EA_CLS_TEST_ID, /* Type of Extensible array */
+ sizeof(uint64_t), /* Size of native element */
+ H5EA__test_crt_context, /* Create context */
+ H5EA__test_dst_context, /* Destroy context */
+ 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 */
+}};
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5EA__test_ctx_t struct */
+H5FL_DEFINE_STATIC(H5EA__test_ctx_t);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__test_crt_context
+ *
+ * Purpose: Create context for callbacks
+ *
+ * Return: Success: non-NULL
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, January 27, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+void *, NULL, NULL,
+H5EA__test_crt_context(void *_udata))
+
+ /* Local variables */
+ H5EA__test_ctx_t *ctx; /* Context for callbacks */
+ H5EA__ctx_cb_t *udata = (H5EA__ctx_cb_t *)_udata; /* User data for context */
+
+ /* Sanity checks */
+
+ /* Allocate new context structure */
+ if(NULL == (ctx = H5FL_MALLOC(H5EA__test_ctx_t)))
+ H5E_THROW(H5E_CANTALLOC, "can't allocate extensible array client callback context")
+
+ /* Initialize the context */
+ ctx->bogus = H5EA__TEST_BOGUS_VAL;
+ ctx->cb = udata;
+
+ /* Set return value */
+ ret_value = ctx;
+
+CATCH
+
+END_FUNC(STATIC) /* end H5EA__test_crt_context() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__test_dst_context
+ *
+ * Purpose: Destroy context for callbacks
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, January 27, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+H5EA__test_dst_context(void *_ctx))
+
+ /* Local variables */
+ H5EA__test_ctx_t *ctx = (H5EA__test_ctx_t *)_ctx; /* Callback context to destroy */
+
+ /* Sanity checks */
+ HDassert(H5EA__TEST_BOGUS_VAL == ctx->bogus);
+
+ /* Release context structure */
+ ctx = H5FL_FREE(H5EA__test_ctx_t, ctx);
+
+END_FUNC(STATIC) /* end H5EA__test_dst_context() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__test_fill
+ *
+ * Purpose: Fill "missing elements" in block of elements
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, August 28, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+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(nat_blk);
+ HDassert(nelmts);
+
+ H5V_array_fill(nat_blk, &fill_val, sizeof(uint64_t), nelmts);
+
+END_FUNC(STATIC) /* end H5EA__test_fill() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__test_encode
+ *
+ * Purpose: Encode an element from "native" to "raw" form
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, August 28, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__test_encode(void *raw, const void *_elmt, size_t nelmts, void *_ctx))
+
+ /* Local variables */
+ H5EA__test_ctx_t *ctx = (H5EA__test_ctx_t *)_ctx; /* Callback context to destroy */
+ const uint64_t *elmt = (const uint64_t *)_elmt; /* Convenience pointer to native elements */
+
+ /* Sanity checks */
+ HDassert(raw);
+ HDassert(elmt);
+ HDassert(nelmts);
+ HDassert(H5EA__TEST_BOGUS_VAL == ctx->bogus);
+
+ /* Check for callback action */
+ if(ctx->cb) {
+ if((*ctx->cb->encode)(elmt, nelmts, ctx->cb->udata) < 0)
+ H5E_THROW(H5E_BADVALUE, "extensible array testing callback action failed")
+ } /* end if */
+
+ /* Encode native elements into raw elements */
+ while(nelmts) {
+ /* Encode element */
+ /* (advances 'raw' pointer) */
+ UINT64ENCODE(raw, *elmt);
+
+ /* Advance native element pointer */
+ elmt++;
+
+ /* Decrement # of elements to encode */
+ nelmts--;
+ } /* end while */
+
+CATCH
+
+END_FUNC(STATIC) /* end H5EA__test_encode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__test_decode
+ *
+ * Purpose: Decode an element from "raw" to "native" form
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, August 28, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+H5EA__test_decode(const void *_raw, void *_elmt, size_t nelmts, void *_ctx))
+
+ /* Local variables */
+ H5EA__test_ctx_t *ctx = (H5EA__test_ctx_t *)_ctx; /* Callback context to destroy */
+ 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);
+ HDassert(H5EA__TEST_BOGUS_VAL == ctx->bogus);
+
+ /* 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() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__test_debug
+ *
+ * Purpose: Display an element for debugging
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, August 28, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+H5EA__test_debug(FILE *stream, int indent, int fwidth, hsize_t idx,
+ const void *elmt))
+
+ /* Local variables */
+ char temp_str[128]; /* Temporary string, for formatting */
+
+ /* Sanity checks */
+ HDassert(stream);
+ HDassert(elmt);
+
+ /* Print element */
+ sprintf(temp_str, "Element #%llu:", (unsigned long long)idx);
+ HDfprintf(stream, "%*s%-*s %llu\n", indent, "", fwidth, temp_str,
+ (unsigned long long)*(const uint64_t *)elmt);
+
+END_FUNC(STATIC) /* end H5EA__test_debug() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA_get_cparam_test
+ *
+ * Purpose: Retrieve the parameters used to create the extensible array
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, August 28, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, NOERR,
+herr_t, SUCCEED, -,
+H5EA_get_cparam_test(const H5EA_t *ea, H5EA_create_t *cparam))
+
+ /* Check arguments. */
+ HDassert(ea);
+ HDassert(cparam);
+
+ /* Get extensible array creation parameters */
+ cparam->raw_elmt_size = ea->hdr->cparam.raw_elmt_size;
+ cparam->max_nelmts_bits = ea->hdr->cparam.max_nelmts_bits;
+ cparam->idx_blk_elmts = ea->hdr->cparam.idx_blk_elmts;
+ cparam->sup_blk_min_data_ptrs = ea->hdr->cparam.sup_blk_min_data_ptrs;
+ cparam->data_blk_min_elmts = ea->hdr->cparam.data_blk_min_elmts;
+ cparam->max_dblk_page_nelmts_bits = ea->hdr->cparam.max_dblk_page_nelmts_bits;
+
+END_FUNC(PRIV) /* end H5EA_get_cparam_test() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA_cmp_cparam_test
+ *
+ * Purpose: Compare the parameters used to create the extensible array
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, August 28, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERRCATCH,
+int, 0, -,
+H5EA_cmp_cparam_test(const H5EA_create_t *cparam1, const H5EA_create_t *cparam2))
+
+ /* Check arguments. */
+ HDassert(cparam1);
+ HDassert(cparam2);
+
+ /* Compare creation parameters for array */
+ if(cparam1->raw_elmt_size < cparam2->raw_elmt_size)
+ H5_LEAVE(-1)
+ else if(cparam1->raw_elmt_size > cparam2->raw_elmt_size)
+ H5_LEAVE(1)
+ if(cparam1->max_nelmts_bits < cparam2->max_nelmts_bits)
+ H5_LEAVE(-1)
+ else if(cparam1->max_nelmts_bits > cparam2->max_nelmts_bits)
+ H5_LEAVE(1)
+ if(cparam1->idx_blk_elmts < cparam2->idx_blk_elmts)
+ H5_LEAVE(-1)
+ else if(cparam1->idx_blk_elmts > cparam2->idx_blk_elmts)
+ H5_LEAVE(1)
+ if(cparam1->sup_blk_min_data_ptrs < cparam2->sup_blk_min_data_ptrs)
+ H5_LEAVE(-1)
+ else if(cparam1->sup_blk_min_data_ptrs > cparam2->sup_blk_min_data_ptrs)
+ H5_LEAVE(1)
+ if(cparam1->data_blk_min_elmts < cparam2->data_blk_min_elmts)
+ H5_LEAVE(-1)
+ else if(cparam1->data_blk_min_elmts > cparam2->data_blk_min_elmts)
+ H5_LEAVE(1)
+ if(cparam1->max_dblk_page_nelmts_bits < cparam2->max_dblk_page_nelmts_bits)
+ H5_LEAVE(-1)
+ else if(cparam1->max_dblk_page_nelmts_bits > cparam2->max_dblk_page_nelmts_bits)
+ H5_LEAVE(1)
+
+CATCH
+
+END_FUNC(PRIV) /* end H5EA_cmp_cparam_test() */
+
diff --git a/src/H5Edefin.h b/src/H5Edefin.h
index 5638305..16e922a 100644
--- a/src/H5Edefin.h
+++ b/src/H5Edefin.h
@@ -21,9 +21,7 @@
#define _H5Edefin_H
/* Major error IDs */
-hid_t H5E_DATASET_g = FAIL; /* Dataset */
hid_t H5E_FUNC_g = FAIL; /* Function entry/exit */
-hid_t H5E_STORAGE_g = FAIL; /* Data storage */
hid_t H5E_FILE_g = FAIL; /* File accessability */
hid_t H5E_SOHM_g = FAIL; /* Shared Object Header Messages */
hid_t H5E_SYM_g = FAIL; /* Symbol table */
@@ -33,23 +31,27 @@ hid_t H5E_BTREE_g = FAIL; /* B-Tree node */
hid_t H5E_REFERENCE_g = FAIL; /* References */
hid_t H5E_DATASPACE_g = FAIL; /* Dataspace */
hid_t H5E_RESOURCE_g = FAIL; /* Resource unavailable */
-hid_t H5E_PLIST_g = FAIL; /* Property lists */
-hid_t H5E_LINK_g = FAIL; /* Links */
-hid_t H5E_DATATYPE_g = FAIL; /* Datatype */
hid_t H5E_RS_g = FAIL; /* Reference Counted Strings */
+hid_t H5E_FARRAY_g = FAIL; /* Fixed Array */
hid_t H5E_HEAP_g = FAIL; /* Heap */
-hid_t H5E_OHDR_g = FAIL; /* Object header */
-hid_t H5E_ATOM_g = FAIL; /* Object atom */
hid_t H5E_ATTR_g = FAIL; /* Attribute */
-hid_t H5E_NONE_MAJOR_g = FAIL; /* No error */
hid_t H5E_IO_g = FAIL; /* Low-level I/O */
-hid_t H5E_SLIST_g = FAIL; /* Skip Lists */
hid_t H5E_EFL_g = FAIL; /* External file list */
hid_t H5E_TST_g = FAIL; /* Ternary Search Trees */
+hid_t H5E_FSPACE_g = FAIL; /* Free Space Manager */
+hid_t H5E_DATASET_g = FAIL; /* Dataset */
+hid_t H5E_STORAGE_g = FAIL; /* Data storage */
+hid_t H5E_LINK_g = FAIL; /* Links */
+hid_t H5E_PLIST_g = FAIL; /* Property lists */
+hid_t H5E_DATATYPE_g = FAIL; /* Datatype */
+hid_t H5E_OHDR_g = FAIL; /* Object header */
+hid_t H5E_ATOM_g = FAIL; /* Object atom */
+hid_t H5E_NONE_MAJOR_g = FAIL; /* No error */
+hid_t H5E_SLIST_g = FAIL; /* Skip Lists */
hid_t H5E_ARGS_g = FAIL; /* Invalid arguments to routine */
-hid_t H5E_ERROR_g = FAIL; /* Error API */
+hid_t H5E_EARRAY_g = FAIL; /* Extensible Array */
hid_t H5E_PLINE_g = FAIL; /* Data filters */
-hid_t H5E_FSPACE_g = FAIL; /* Free Space Manager */
+hid_t H5E_ERROR_g = FAIL; /* Error API */
hid_t H5E_CACHE_g = FAIL; /* Object cache */
/* Minor error IDs */
@@ -163,6 +165,9 @@ hid_t H5E_CANTMARKDIRTY_g = FAIL; /* Unable to mark a pinned entry as dirt
hid_t H5E_CANTDIRTY_g = FAIL; /* Unable to mark metadata as dirty */
hid_t H5E_CANTEXPUNGE_g = FAIL; /* Unable to expunge a metadata cache entry */
hid_t H5E_CANTRESIZE_g = FAIL; /* Unable to resize a metadata cache entry */
+hid_t H5E_CANTDEPEND_g = FAIL; /* Unable to create a flush dependency */
+hid_t H5E_CANTUNDEPEND_g = FAIL; /* Unable to destroy a flush dependency */
+hid_t H5E_CANTNOTIFY_g = FAIL; /* Unable to notify object about action */
/* Link related errors */
hid_t H5E_TRAVERSE_g = FAIL; /* Link traversal failure */
diff --git a/src/H5Edeprec.c b/src/H5Edeprec.c
index c1a5a21..0997f3c 100644
--- a/src/H5Edeprec.c
+++ b/src/H5Edeprec.c
@@ -130,7 +130,7 @@ H5Eget_major(H5E_major_t maj)
FUNC_ENTER_API_NOCLEAR(H5Eget_major, NULL)
/* Get the message object */
- if(NULL == (msg = H5I_object_verify(maj, H5I_ERROR_MSG)))
+ if(NULL == (msg = (H5E_msg_t *)H5I_object_verify(maj, H5I_ERROR_MSG)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a error message ID")
/* Get the message's text */
@@ -178,7 +178,7 @@ H5Eget_minor(H5E_minor_t min)
FUNC_ENTER_API_NOCLEAR(H5Eget_minor, NULL)
/* Get the message object */
- if(NULL == (msg = H5I_object_verify(min, H5I_ERROR_MSG)))
+ if(NULL == (msg = (H5E_msg_t *)H5I_object_verify(min, H5I_ERROR_MSG)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a error message ID")
/* Get the message's text */
diff --git a/src/H5Einit.h b/src/H5Einit.h
index ac02d48..cea2888 100644
--- a/src/H5Einit.h
+++ b/src/H5Einit.h
@@ -24,155 +24,165 @@
/* Major error codes */
/*********************/
-assert(H5E_DATASET_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Dataset"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_DATASET_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_FUNC_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Function entry/exit"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_FUNC_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_STORAGE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Data storage"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_STORAGE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_FUNC_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_FILE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "File accessability"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_FILE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_FILE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_SOHM_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Shared Object Header Messages"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_SOHM_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_SOHM_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_SYM_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Symbol table"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_SYM_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_SYM_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_VFL_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Virtual File Layer"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_VFL_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_VFL_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_INTERNAL_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Internal error (too specific to document in detail)"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_INTERNAL_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_INTERNAL_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_BTREE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "B-Tree node"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BTREE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_BTREE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_REFERENCE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "References"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_REFERENCE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_REFERENCE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_DATASPACE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Dataspace"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_DATASPACE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_DATASPACE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_RESOURCE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Resource unavailable"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_RESOURCE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_RESOURCE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_PLIST_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Property lists"))==NULL)
+assert(H5E_RS_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Reference Counted Strings"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_PLIST_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_RS_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_LINK_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Links"))==NULL)
+assert(H5E_FARRAY_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Fixed Array"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_LINK_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_FARRAY_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_DATATYPE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Datatype"))==NULL)
+assert(H5E_HEAP_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Heap"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_DATATYPE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_HEAP_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_RS_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Reference Counted Strings"))==NULL)
+assert(H5E_ATTR_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Attribute"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_RS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_ATTR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_HEAP_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Heap"))==NULL)
+assert(H5E_IO_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Low-level I/O"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_HEAP_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_IO_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_OHDR_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object header"))==NULL)
+assert(H5E_EFL_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "External file list"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_OHDR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_EFL_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_ATOM_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object atom"))==NULL)
+assert(H5E_TST_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Ternary Search Trees"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_ATOM_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_TST_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_ATTR_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Attribute"))==NULL)
+assert(H5E_FSPACE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Free Space Manager"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_ATTR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_FSPACE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_NONE_MAJOR_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "No error"))==NULL)
+assert(H5E_DATASET_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Dataset"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NONE_MAJOR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_DATASET_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_IO_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Low-level I/O"))==NULL)
+assert(H5E_STORAGE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Data storage"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_IO_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_STORAGE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_SLIST_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Skip Lists"))==NULL)
+assert(H5E_LINK_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Links"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_SLIST_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_LINK_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_EFL_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "External file list"))==NULL)
+assert(H5E_PLIST_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Property lists"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_EFL_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_PLIST_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_TST_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Ternary Search Trees"))==NULL)
+assert(H5E_DATATYPE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Datatype"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_TST_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_DATATYPE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_OHDR_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object header"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_OHDR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_ATOM_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object atom"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_ATOM_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_NONE_MAJOR_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "No error"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_NONE_MAJOR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_SLIST_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Skip Lists"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_SLIST_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_ARGS_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Invalid arguments to routine"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_ARGS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_ARGS_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_ERROR_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Error API"))==NULL)
+assert(H5E_EARRAY_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Extensible Array"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_ERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_EARRAY_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_PLINE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Data filters"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_PLINE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_PLINE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_FSPACE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Free Space Manager"))==NULL)
+assert(H5E_ERROR_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Error API"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_FSPACE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_ERROR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CACHE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object cache"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CACHE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CACHE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/*********************/
@@ -184,610 +194,625 @@ if((H5E_CACHE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
assert(H5E_SEEKERROR_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Seek failed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_SEEKERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_SEEKERROR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_READERROR_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Read failed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_READERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_READERROR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_WRITEERROR_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Write failed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_WRITEERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_WRITEERROR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CLOSEERROR_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Close failed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CLOSEERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CLOSEERROR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_OVERFLOW_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Address overflowed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_OVERFLOW_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_OVERFLOW_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_FCNTL_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "File control (fcntl) failed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_FCNTL_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_FCNTL_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Resource errors */
assert(H5E_NOSPACE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "No space available for allocation"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NOSPACE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NOSPACE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTALLOC_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't allocate space"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTALLOC_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTALLOC_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTCOPY_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to copy object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTCOPY_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTCOPY_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTFREE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to free object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTFREE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTFREE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_ALREADYEXISTS_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Object already exists"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_ALREADYEXISTS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_ALREADYEXISTS_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTLOCK_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to lock object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTLOCK_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTLOCK_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTUNLOCK_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to unlock object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTUNLOCK_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTUNLOCK_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTGC_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to garbage collect"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTGC_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTGC_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTGETSIZE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to compute size"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTGETSIZE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTGETSIZE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_OBJOPEN_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Object is already open"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_OBJOPEN_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_OBJOPEN_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Heap errors */
assert(H5E_CANTRESTORE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't restore condition"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTRESTORE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTRESTORE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTCOMPUTE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't compute value"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTCOMPUTE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTCOMPUTE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTEXTEND_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't extend heap's space"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTEXTEND_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTEXTEND_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTATTACH_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't attach object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTATTACH_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTATTACH_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTUPDATE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't update object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTUPDATE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTUPDATE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTOPERATE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't operate on object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTOPERATE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTOPERATE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Function entry/exit interface errors */
assert(H5E_CANTINIT_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to initialize object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTINIT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTINIT_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_ALREADYINIT_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Object already initialized"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_ALREADYINIT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_ALREADYINIT_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTRELEASE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to release object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTRELEASE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTRELEASE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Property list errors */
assert(H5E_CANTGET_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't get value"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTGET_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTGET_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTSET_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't set value"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTSET_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTSET_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_DUPCLASS_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Duplicate class name in parent class"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_DUPCLASS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_DUPCLASS_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Free space errors */
assert(H5E_CANTMERGE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't merge objects"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTMERGE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTMERGE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTREVIVE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't revive object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTREVIVE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTREVIVE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTSHRINK_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't shrink container"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTSHRINK_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTSHRINK_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Object header related errors */
assert(H5E_LINKCOUNT_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad object header link count"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_LINKCOUNT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_LINKCOUNT_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_VERSION_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Wrong version number"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_VERSION_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_VERSION_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_ALIGNMENT_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Alignment error"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_ALIGNMENT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_ALIGNMENT_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_BADMESG_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unrecognized message"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADMESG_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_BADMESG_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTDELETE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't delete message"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTDELETE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTDELETE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_BADITER_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Iteration failed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADITER_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_BADITER_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTPACK_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't pack messages"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTPACK_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTPACK_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTRESET_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't reset object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTRESET_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTRESET_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* System level errors */
assert(H5E_SYSERRSTR_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "System error message"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_SYSERRSTR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_SYSERRSTR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* I/O pipeline errors */
assert(H5E_NOFILTER_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Requested filter is not available"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NOFILTER_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NOFILTER_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CALLBACK_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Callback failed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CALLBACK_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CALLBACK_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANAPPLY_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Error from filter 'can apply' callback"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANAPPLY_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANAPPLY_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_SETLOCAL_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Error from filter 'set local' callback"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_SETLOCAL_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_SETLOCAL_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_NOENCODER_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Filter present but encoding disabled"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NOENCODER_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NOENCODER_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTFILTER_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Filter operation failed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTFILTER_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTFILTER_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Group related errors */
assert(H5E_CANTOPENOBJ_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't open object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTOPENOBJ_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTOPENOBJ_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTCLOSEOBJ_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't close object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTCLOSEOBJ_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTCLOSEOBJ_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_COMPLEN_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Name component is too long"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_COMPLEN_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_COMPLEN_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_PATH_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Problem with path to object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_PATH_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_PATH_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* No error */
assert(H5E_NONE_MINOR_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "No error"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NONE_MINOR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NONE_MINOR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* File accessability errors */
assert(H5E_FILEEXISTS_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "File already exists"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_FILEEXISTS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_FILEEXISTS_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_FILEOPEN_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "File already open"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_FILEOPEN_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_FILEOPEN_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTCREATE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to create file"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTCREATE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTCREATE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTOPENFILE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to open file"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTOPENFILE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTOPENFILE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTCLOSEFILE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to close file"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTCLOSEFILE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTCLOSEFILE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_NOTHDF5_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Not an HDF5 file"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NOTHDF5_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NOTHDF5_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_BADFILE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad file ID accessed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADFILE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_BADFILE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_TRUNCATED_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "File has been truncated"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_TRUNCATED_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_TRUNCATED_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_MOUNT_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "File mount error"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_MOUNT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_MOUNT_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Object atom related errors */
assert(H5E_BADATOM_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to find atom information (already closed?)"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADATOM_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_BADATOM_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_BADGROUP_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to find ID group information"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADGROUP_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_BADGROUP_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTREGISTER_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to register new atom"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTREGISTER_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTREGISTER_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTINC_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to increment reference count"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTINC_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTINC_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTDEC_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to decrement reference count"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTDEC_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTDEC_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_NOIDS_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Out of IDs for group"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NOIDS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NOIDS_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Cache related errors */
assert(H5E_CANTFLUSH_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to flush data from cache"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTFLUSH_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTFLUSH_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTSERIALIZE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to serialize data from cache"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTSERIALIZE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTSERIALIZE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTLOAD_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to load metadata into cache"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTLOAD_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTLOAD_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_PROTECT_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Protected metadata error"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_PROTECT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_PROTECT_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_NOTCACHED_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Metadata not currently cached"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NOTCACHED_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NOTCACHED_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_SYSTEM_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Internal error detected"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_SYSTEM_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_SYSTEM_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTINS_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to insert metadata into cache"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTINS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTINS_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTRENAME_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to rename metadata"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTRENAME_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTRENAME_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTPROTECT_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to protect metadata"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTPROTECT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTPROTECT_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTUNPROTECT_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to unprotect metadata"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTUNPROTECT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTUNPROTECT_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTPIN_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to pin cache entry"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTPIN_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTPIN_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTUNPIN_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to un-pin cache entry"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTUNPIN_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTUNPIN_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTMARKDIRTY_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to mark a pinned entry as dirty"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTMARKDIRTY_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTMARKDIRTY_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTDIRTY_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to mark metadata as dirty"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTDIRTY_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTDIRTY_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTEXPUNGE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to expunge a metadata cache entry"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTEXPUNGE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTEXPUNGE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTRESIZE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to resize a metadata cache entry"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTRESIZE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTRESIZE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CANTDEPEND_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to create a flush dependency"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CANTDEPEND_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CANTUNDEPEND_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to destroy a flush dependency"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CANTUNDEPEND_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CANTNOTIFY_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to notify object about action"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CANTNOTIFY_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Link related errors */
assert(H5E_TRAVERSE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Link traversal failure"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_TRAVERSE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_TRAVERSE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_NLINKS_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Too many soft links in path"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NLINKS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NLINKS_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_NOTREGISTERED_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Link class not registered"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NOTREGISTERED_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NOTREGISTERED_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTMOVE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Move callback returned error"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTMOVE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTMOVE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTSORT_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't sort objects"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTSORT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTSORT_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Parallel MPI errors */
assert(H5E_MPI_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Some MPI function failed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_MPI_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_MPI_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_MPIERRSTR_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "MPI Error String"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_MPIERRSTR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_MPIERRSTR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTRECV_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't receive data"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTRECV_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTRECV_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Dataspace errors */
assert(H5E_CANTCLIP_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't clip hyperslab region"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTCLIP_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTCLIP_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTCOUNT_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't count elements"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTCOUNT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTCOUNT_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTSELECT_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't select hyperslab"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTSELECT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTSELECT_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTNEXT_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't move to next iterator location"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTNEXT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTNEXT_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_BADSELECT_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Invalid selection"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADSELECT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_BADSELECT_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTCOMPARE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't compare objects"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTCOMPARE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTCOMPARE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Argument errors */
assert(H5E_UNINITIALIZED_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Information is uinitialized"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_UNINITIALIZED_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_UNINITIALIZED_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_UNSUPPORTED_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Feature is unsupported"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_UNSUPPORTED_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_UNSUPPORTED_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_BADTYPE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Inappropriate type"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADTYPE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_BADTYPE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_BADRANGE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Out of range"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADRANGE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_BADRANGE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_BADVALUE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad value"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADVALUE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_BADVALUE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* B-tree related errors */
assert(H5E_NOTFOUND_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Object not found"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NOTFOUND_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NOTFOUND_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_EXISTS_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Object already exists"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_EXISTS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_EXISTS_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTENCODE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to encode value"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTENCODE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTENCODE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTDECODE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to decode value"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTDECODE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTDECODE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTSPLIT_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to split node"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTSPLIT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTSPLIT_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTREDISTRIBUTE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to redistribute records"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTREDISTRIBUTE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTREDISTRIBUTE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTSWAP_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to swap records"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTSWAP_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTSWAP_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTINSERT_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to insert object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTINSERT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTINSERT_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTLIST_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to list node"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTLIST_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTLIST_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTMODIFY_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to modify record"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTMODIFY_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTMODIFY_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_CANTREMOVE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to remove object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTREMOVE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTREMOVE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Datatype conversion errors */
assert(H5E_CANTCONVERT_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't convert datatypes"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTCONVERT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTCONVERT_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_BADSIZE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad size for object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADSIZE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_BADSIZE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
#endif /* H5Einit_H */
diff --git a/src/H5Eint.c b/src/H5Eint.c
index e0fa482..831d51b 100644
--- a/src/H5Eint.c
+++ b/src/H5Eint.c
@@ -238,8 +238,8 @@ H5E_walk1_cb(int n, H5E_error1_t *err_desc, void *client_data)
stream = eprint->stream;
/* Get descriptions for the major and minor error numbers */
- maj_ptr = H5I_object_verify(err_desc->maj_num, H5I_ERROR_MSG);
- min_ptr = H5I_object_verify(err_desc->min_num, H5I_ERROR_MSG);
+ maj_ptr = (H5E_msg_t *)H5I_object_verify(err_desc->maj_num, H5I_ERROR_MSG);
+ min_ptr = (H5E_msg_t *)H5I_object_verify(err_desc->min_num, H5I_ERROR_MSG);
HDassert(maj_ptr && min_ptr);
if(maj_ptr->msg)
maj_str = maj_ptr->msg;
@@ -275,7 +275,7 @@ H5E_walk1_cb(int n, H5E_error1_t *err_desc, void *client_data)
fprintf(stream, "thread 0");
} /* end block */
#elif defined(H5_HAVE_THREADSAFE)
- fprintf(stream, "thread %lu", HDpthread_self_ulong());
+ fprintf(stream, "thread %lu", (unsigned long)HDpthread_self_ulong());
#else
fprintf(stream, "thread 0");
#endif
@@ -354,16 +354,17 @@ H5E_walk2_cb(unsigned n, const H5E_error2_t *err_desc, void *client_data)
stream = eprint->stream;
/* Get descriptions for the major and minor error numbers */
- maj_ptr = H5I_object_verify(err_desc->maj_num, H5I_ERROR_MSG);
- min_ptr = H5I_object_verify(err_desc->min_num, H5I_ERROR_MSG);
+ maj_ptr = (H5E_msg_t *)H5I_object_verify(err_desc->maj_num, H5I_ERROR_MSG);
+ min_ptr = (H5E_msg_t *)H5I_object_verify(err_desc->min_num, H5I_ERROR_MSG);
HDassert(maj_ptr && min_ptr);
if(maj_ptr->msg)
maj_str = maj_ptr->msg;
if(min_ptr->msg)
min_str = min_ptr->msg;
- /* Get error class info */
- cls_ptr = maj_ptr->cls;
+ /* Get error class info. Don't use the class of the major or minor error because
+ * they might be different. */
+ cls_ptr = (H5E_cls_t *)H5I_object_verify(err_desc->cls_id, H5I_ERROR_CLASS);
/* Print error class header if new class */
if(eprint->cls.lib_name == NULL || HDstrcmp(cls_ptr->lib_name, eprint->cls.lib_name)) {
@@ -391,7 +392,7 @@ H5E_walk2_cb(unsigned n, const H5E_error2_t *err_desc, void *client_data)
fprintf(stream, "thread 0");
} /* end block */
#elif defined(H5_HAVE_THREADSAFE)
- fprintf(stream, "thread %lu", HDpthread_self_ulong());
+ fprintf(stream, "thread %lu", (unsigned long)HDpthread_self_ulong());
#else
fprintf(stream, "thread 0");
#endif
@@ -660,6 +661,107 @@ H5E_set_auto(H5E_t *estack, const H5E_auto_op_t *op, void *client_data)
/*-------------------------------------------------------------------------
+ * Function: H5E_printf_stack
+ *
+ * Purpose: Printf-like wrapper around H5E_push_stack.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, August 12, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5E_printf_stack(H5E_t *estack, const char *file, const char *func, unsigned line,
+ hid_t cls_id, hid_t maj_id, hid_t min_id, const char *fmt, ...)
+{
+ va_list ap; /* Varargs info */
+#ifndef H5_HAVE_VASPRINTF
+ int tmp_len; /* Current size of description buffer */
+ int desc_len; /* Actual length of description when formatted */
+#endif /* H5_HAVE_VASPRINTF */
+ char *tmp = NULL; /* Buffer to place formatted description in */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ /*
+ * WARNING: We cannot call HERROR() from within this function or else we
+ * could enter infinite recursion. Furthermore, we also cannot
+ * call any other HDF5 macro or function which might call
+ * HERROR(). HERROR() is called by HRETURN_ERROR() which could
+ * be called by FUNC_ENTER().
+ */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5E_printf_stack)
+
+ /* Sanity check */
+ HDassert(cls_id > 0);
+ HDassert(maj_id > 0);
+ HDassert(min_id > 0);
+ HDassert(fmt);
+
+/* Note that the variable-argument parsing for the format is identical in
+ * the H5Epush2() routine - correct errors and make changes in both
+ * places. -QAK
+ */
+
+ /* Start the variable-argument parsing */
+ va_start(ap, fmt);
+
+#ifdef H5_HAVE_VASPRINTF
+ /* Use the vasprintf() routine, since it does what we're trying to do below */
+ if(HDvasprintf(&tmp, fmt, ap) < 0)
+ HGOTO_DONE(FAIL)
+#else /* H5_HAVE_VASPRINTF */
+ /* Allocate space for the formatted description buffer */
+ tmp_len = 128;
+ if(NULL == (tmp = H5MM_malloc((size_t)tmp_len)))
+ HGOTO_DONE(FAIL)
+
+ /* If the description doesn't fit into the initial buffer size, allocate more space and try again */
+ while((desc_len = HDvsnprintf(tmp, (size_t)tmp_len, fmt, ap))
+#ifdef H5_VSNPRINTF_WORKS
+ >
+#else /* H5_VSNPRINTF_WORKS */
+ >=
+#endif /* H5_VSNPRINTF_WORKS */
+ (tmp_len - 1)
+#ifndef H5_VSNPRINTF_WORKS
+ || (desc_len < 0)
+#endif /* H5_VSNPRINTF_WORKS */
+ ) {
+ /* shutdown & restart the va_list */
+ va_end(ap);
+ va_start(ap, fmt);
+
+ /* Release the previous description, it's too small */
+ H5MM_xfree(tmp);
+
+ /* Allocate a description of the appropriate length */
+#ifdef H5_VSNPRINTF_WORKS
+ tmp_len = desc_len + 1;
+#else /* H5_VSNPRINTF_WORKS */
+ tmp_len = 2 * tmp_len;
+#endif /* H5_VSNPRINTF_WORKS */
+ if(NULL == (tmp = H5MM_malloc((size_t)tmp_len)))
+ HGOTO_DONE(FAIL)
+ } /* end while */
+#endif /* H5_HAVE_VASPRINTF */
+
+ va_end(ap);
+
+ /* Push the error on the stack */
+ if(H5E_push_stack(estack, file, func, line, cls_id, maj_id, min_id, tmp) < 0)
+ HGOTO_DONE(FAIL)
+
+done:
+ if(tmp)
+ H5MM_xfree(tmp);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5E_printf_stack() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5E_push_stack
*
* Purpose: Pushes a new error record onto error stack for the current
@@ -722,13 +824,13 @@ H5E_push_stack(H5E_t *estack, const char *file, const char *func, unsigned line,
if(estack->nused < H5E_NSLOTS) {
/* Increment the IDs to indicate that they are used in this stack */
- if(H5I_inc_ref(cls_id) < 0)
+ if(H5I_inc_ref(cls_id, FALSE) < 0)
HGOTO_DONE(FAIL)
estack->slot[estack->nused].cls_id = cls_id;
- if(H5I_inc_ref(maj_id) < 0)
+ if(H5I_inc_ref(maj_id, FALSE) < 0)
HGOTO_DONE(FAIL)
estack->slot[estack->nused].maj_num = maj_id;
- if(H5I_inc_ref(min_id) < 0)
+ if(H5I_inc_ref(min_id, FALSE) < 0)
HGOTO_DONE(FAIL)
estack->slot[estack->nused].min_num = min_id;
if(NULL == (estack->slot[estack->nused].func_name = H5MM_xstrdup(func)))
@@ -778,11 +880,11 @@ H5E_clear_entries(H5E_t *estack, size_t nentries)
/* Decrement the IDs to indicate that they are no longer used by this stack */
/* (In reverse order that they were incremented, so that reference counts work well) */
- if(H5I_dec_ref(error->min_num) < 0)
+ if(H5I_dec_ref(error->min_num, FALSE) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error message")
- if(H5I_dec_ref(error->maj_num) < 0)
+ if(H5I_dec_ref(error->maj_num, FALSE) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error message")
- if(H5I_dec_ref(error->cls_id) < 0)
+ if(H5I_dec_ref(error->cls_id, FALSE) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error class")
/* Release strings */
@@ -886,7 +988,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5E_dump_api_stack(int is_api)
+H5E_dump_api_stack(hbool_t is_api)
{
herr_t ret_value = SUCCEED; /* Return value */
diff --git a/src/H5Eprivate.h b/src/H5Eprivate.h
index 05ce10e..4c226d0 100644
--- a/src/H5Eprivate.h
+++ b/src/H5Eprivate.h
@@ -32,15 +32,15 @@ typedef struct H5E_t H5E_t;
* and a FUNC_LEAVE() within a function body. The arguments are the major
* error number, the minor error number, and a description of the error.
*/
-#define HERROR(maj_id, min_id, str) H5E_push_stack(NULL, __FILE__, FUNC, __LINE__, H5E_ERR_CLS_g, maj_id, min_id, str)
+#define HERROR(maj_id, min_id, ...) H5E_printf_stack(NULL, __FILE__, FUNC, __LINE__, H5E_ERR_CLS_g, maj_id, min_id, __VA_ARGS__)
/*
* HCOMMON_ERROR macro, used by HDONE_ERROR and HGOTO_ERROR
* (Shouldn't need to be used outside this header file)
*/
-#define HCOMMON_ERROR(maj, min, str) \
- HERROR(maj, min, str); \
- (void)H5E_dump_api_stack((int)H5_IS_API(FUNC));
+#define HCOMMON_ERROR(maj, min, ...) \
+ HERROR(maj, min, __VA_ARGS__); \
+ err_occurred = TRUE;
/*
* HDONE_ERROR macro, used to facilitate error reporting between a
@@ -51,8 +51,8 @@ typedef struct H5E_t H5E_t;
* (This macro can also be used to push an error and set the return value
* without jumping to any labels)
*/
-#define HDONE_ERROR(maj, min, ret_val, str) { \
- HCOMMON_ERROR(maj, min, str); \
+#define HDONE_ERROR(maj, min, ret_val, ...) { \
+ HCOMMON_ERROR(maj, min, __VA_ARGS__); \
ret_value = ret_val; \
}
@@ -63,8 +63,8 @@ typedef struct H5E_t H5E_t;
* error string. The return value is assigned to a variable `ret_value' and
* control branches to the `done' label.
*/
-#define HGOTO_ERROR(maj, min, ret_val, str) { \
- HCOMMON_ERROR(maj, min, str); \
+#define HGOTO_ERROR(maj, min, ret_val, ...) { \
+ HCOMMON_ERROR(maj, min, __VA_ARGS__); \
HGOTO_DONE(ret_val) \
}
@@ -76,13 +76,6 @@ typedef struct H5E_t H5E_t;
*/
#define HGOTO_DONE(ret_val) {ret_value = ret_val; goto done;}
-/* Library-private functions defined in H5E package */
-H5_DLL herr_t H5E_init(void);
-H5_DLL herr_t H5E_push_stack(H5E_t *estack, const char *file, const char *func, unsigned line,
- hid_t cls_id, hid_t maj_id, hid_t min_id, const char *desc);
-H5_DLL herr_t H5E_clear_stack(H5E_t *estack);
-H5_DLL herr_t H5E_dump_api_stack(int is_api);
-
/*
* Macros handling system error messages as described in C standard.
* These macros assume errnum is a valid system error code.
@@ -91,16 +84,13 @@ H5_DLL herr_t H5E_dump_api_stack(int is_api);
/* Retrieve the error code description string and push it onto the error
* stack.
*/
-#define HSYS_ERROR(errnum) { \
- HERROR(H5E_INTERNAL, H5E_SYSERRSTR, HDstrerror(errnum)); \
-}
#define HSYS_DONE_ERROR(majorcode, minorcode, retcode, str) { \
- HSYS_ERROR(errno); \
- HDONE_ERROR(majorcode, minorcode, retcode, str); \
+ int myerrno = errno; \
+ HDONE_ERROR(majorcode, minorcode, retcode, "%s, errno = %d, error message = '%s'", str, myerrno, HDstrerror(myerrno)); \
}
#define HSYS_GOTO_ERROR(majorcode, minorcode, retcode, str) { \
- HSYS_ERROR(errno); \
- HGOTO_ERROR(majorcode, minorcode, retcode, str); \
+ int myerrno = errno; \
+ HGOTO_ERROR(majorcode, minorcode, retcode, "%s, errno = %d, error message = '%s'", str, myerrno, HDstrerror(myerrno)); \
}
#ifdef H5_HAVE_PARALLEL
@@ -125,5 +115,58 @@ extern int H5E_mpi_error_str_len;
}
#endif /* H5_HAVE_PARALLEL */
+
+/******************************************************************************/
+/* Revisions to Error Macros, to go with Revisions to FUNC_ENTER/LEAVE Macros */
+/******************************************************************************/
+
+/*
+ * H5E_PRINTF macro, used to facilitate error reporting between a BEGIN_FUNC()
+ * and an END_FUNC() within a function body. The arguments are the minor
+ * error number, a description of the error (as a printf-like format string),
+ * and an optional set of arguments for the printf format arguments.
+ */
+#define H5E_PRINTF(...) H5E_printf_stack(NULL, __FILE__, FUNCNAME, __LINE__, H5E_ERR_CLS_g, H5_MY_PKG_ERR, __VA_ARGS__)
+
+/*
+ * H5_LEAVE macro, used to facilitate control flow between a
+ * BEGIN_FUNC() and an END_FUNC() within a function body. The argument is
+ * the return value.
+ * The return value is assigned to a variable `ret_value' and control branches
+ * to the `catch_except' label, if we're not already past it.
+ */
+#define H5_LEAVE(v) { \
+ ret_value = v; \
+ if(!past_catch) \
+ goto catch_except; \
+}
+
+/*
+ * H5E_THROW macro, used to facilitate error reporting between a
+ * FUNC_ENTER() and a FUNC_LEAVE() within a function body. The arguments are
+ * the minor error number, and an error string.
+ * The return value is assigned to a variable `ret_value' and control branches
+ * to the `catch_except' label, if we're not already past it.
+ */
+#define H5E_THROW(...) { \
+ H5E_PRINTF(__VA_ARGS__); \
+ H5_LEAVE(fail_value) \
+}
+
+/* Macro for "catching" flow of control when an error occurs. Note that the
+ * H5_LEAVE macro won't jump back here once it's past this point.
+ */
+#define CATCH past_catch = TRUE; catch_except:;
+
+
+/* Library-private functions defined in H5E package */
+H5_DLL herr_t H5E_init(void);
+H5_DLL herr_t H5E_push_stack(H5E_t *estack, const char *file, const char *func,
+ unsigned line, hid_t cls_id, hid_t maj_id, hid_t min_id, const char *desc);
+H5_DLL herr_t H5E_printf_stack(H5E_t *estack, const char *file, const char *func,
+ unsigned line, hid_t cls_id, hid_t maj_id, hid_t min_id, const char *fmt, ...);
+H5_DLL herr_t H5E_clear_stack(H5E_t *estack);
+H5_DLL herr_t H5E_dump_api_stack(hbool_t is_api);
+
#endif /* _H5Eprivate_H */
diff --git a/src/H5Epubgen.h b/src/H5Epubgen.h
index 8386e0f..999ea61 100644
--- a/src/H5Epubgen.h
+++ b/src/H5Epubgen.h
@@ -24,9 +24,7 @@
/* Major error codes */
/*********************/
-#define H5E_DATASET (H5OPEN H5E_DATASET_g)
#define H5E_FUNC (H5OPEN H5E_FUNC_g)
-#define H5E_STORAGE (H5OPEN H5E_STORAGE_g)
#define H5E_FILE (H5OPEN H5E_FILE_g)
#define H5E_SOHM (H5OPEN H5E_SOHM_g)
#define H5E_SYM (H5OPEN H5E_SYM_g)
@@ -36,27 +34,29 @@
#define H5E_REFERENCE (H5OPEN H5E_REFERENCE_g)
#define H5E_DATASPACE (H5OPEN H5E_DATASPACE_g)
#define H5E_RESOURCE (H5OPEN H5E_RESOURCE_g)
-#define H5E_PLIST (H5OPEN H5E_PLIST_g)
-#define H5E_LINK (H5OPEN H5E_LINK_g)
-#define H5E_DATATYPE (H5OPEN H5E_DATATYPE_g)
#define H5E_RS (H5OPEN H5E_RS_g)
+#define H5E_FARRAY (H5OPEN H5E_FARRAY_g)
#define H5E_HEAP (H5OPEN H5E_HEAP_g)
-#define H5E_OHDR (H5OPEN H5E_OHDR_g)
-#define H5E_ATOM (H5OPEN H5E_ATOM_g)
#define H5E_ATTR (H5OPEN H5E_ATTR_g)
-#define H5E_NONE_MAJOR (H5OPEN H5E_NONE_MAJOR_g)
#define H5E_IO (H5OPEN H5E_IO_g)
-#define H5E_SLIST (H5OPEN H5E_SLIST_g)
#define H5E_EFL (H5OPEN H5E_EFL_g)
#define H5E_TST (H5OPEN H5E_TST_g)
+#define H5E_FSPACE (H5OPEN H5E_FSPACE_g)
+#define H5E_DATASET (H5OPEN H5E_DATASET_g)
+#define H5E_STORAGE (H5OPEN H5E_STORAGE_g)
+#define H5E_LINK (H5OPEN H5E_LINK_g)
+#define H5E_PLIST (H5OPEN H5E_PLIST_g)
+#define H5E_DATATYPE (H5OPEN H5E_DATATYPE_g)
+#define H5E_OHDR (H5OPEN H5E_OHDR_g)
+#define H5E_ATOM (H5OPEN H5E_ATOM_g)
+#define H5E_NONE_MAJOR (H5OPEN H5E_NONE_MAJOR_g)
+#define H5E_SLIST (H5OPEN H5E_SLIST_g)
#define H5E_ARGS (H5OPEN H5E_ARGS_g)
-#define H5E_ERROR (H5OPEN H5E_ERROR_g)
+#define H5E_EARRAY (H5OPEN H5E_EARRAY_g)
#define H5E_PLINE (H5OPEN H5E_PLINE_g)
-#define H5E_FSPACE (H5OPEN H5E_FSPACE_g)
+#define H5E_ERROR (H5OPEN H5E_ERROR_g)
#define H5E_CACHE (H5OPEN H5E_CACHE_g)
-H5_DLLVAR hid_t H5E_DATASET_g; /* Dataset */
H5_DLLVAR hid_t H5E_FUNC_g; /* Function entry/exit */
-H5_DLLVAR hid_t H5E_STORAGE_g; /* Data storage */
H5_DLLVAR hid_t H5E_FILE_g; /* File accessability */
H5_DLLVAR hid_t H5E_SOHM_g; /* Shared Object Header Messages */
H5_DLLVAR hid_t H5E_SYM_g; /* Symbol table */
@@ -66,23 +66,27 @@ H5_DLLVAR hid_t H5E_BTREE_g; /* B-Tree node */
H5_DLLVAR hid_t H5E_REFERENCE_g; /* References */
H5_DLLVAR hid_t H5E_DATASPACE_g; /* Dataspace */
H5_DLLVAR hid_t H5E_RESOURCE_g; /* Resource unavailable */
-H5_DLLVAR hid_t H5E_PLIST_g; /* Property lists */
-H5_DLLVAR hid_t H5E_LINK_g; /* Links */
-H5_DLLVAR hid_t H5E_DATATYPE_g; /* Datatype */
H5_DLLVAR hid_t H5E_RS_g; /* Reference Counted Strings */
+H5_DLLVAR hid_t H5E_FARRAY_g; /* Fixed Array */
H5_DLLVAR hid_t H5E_HEAP_g; /* Heap */
-H5_DLLVAR hid_t H5E_OHDR_g; /* Object header */
-H5_DLLVAR hid_t H5E_ATOM_g; /* Object atom */
H5_DLLVAR hid_t H5E_ATTR_g; /* Attribute */
-H5_DLLVAR hid_t H5E_NONE_MAJOR_g; /* No error */
H5_DLLVAR hid_t H5E_IO_g; /* Low-level I/O */
-H5_DLLVAR hid_t H5E_SLIST_g; /* Skip Lists */
H5_DLLVAR hid_t H5E_EFL_g; /* External file list */
H5_DLLVAR hid_t H5E_TST_g; /* Ternary Search Trees */
+H5_DLLVAR hid_t H5E_FSPACE_g; /* Free Space Manager */
+H5_DLLVAR hid_t H5E_DATASET_g; /* Dataset */
+H5_DLLVAR hid_t H5E_STORAGE_g; /* Data storage */
+H5_DLLVAR hid_t H5E_LINK_g; /* Links */
+H5_DLLVAR hid_t H5E_PLIST_g; /* Property lists */
+H5_DLLVAR hid_t H5E_DATATYPE_g; /* Datatype */
+H5_DLLVAR hid_t H5E_OHDR_g; /* Object header */
+H5_DLLVAR hid_t H5E_ATOM_g; /* Object atom */
+H5_DLLVAR hid_t H5E_NONE_MAJOR_g; /* No error */
+H5_DLLVAR hid_t H5E_SLIST_g; /* Skip Lists */
H5_DLLVAR hid_t H5E_ARGS_g; /* Invalid arguments to routine */
-H5_DLLVAR hid_t H5E_ERROR_g; /* Error API */
+H5_DLLVAR hid_t H5E_EARRAY_g; /* Extensible Array */
H5_DLLVAR hid_t H5E_PLINE_g; /* Data filters */
-H5_DLLVAR hid_t H5E_FSPACE_g; /* Free Space Manager */
+H5_DLLVAR hid_t H5E_ERROR_g; /* Error API */
H5_DLLVAR hid_t H5E_CACHE_g; /* Object cache */
/*********************/
@@ -264,6 +268,9 @@ H5_DLLVAR hid_t H5E_NOIDS_g; /* Out of IDs for group */
#define H5E_CANTDIRTY (H5OPEN H5E_CANTDIRTY_g)
#define H5E_CANTEXPUNGE (H5OPEN H5E_CANTEXPUNGE_g)
#define H5E_CANTRESIZE (H5OPEN H5E_CANTRESIZE_g)
+#define H5E_CANTDEPEND (H5OPEN H5E_CANTDEPEND_g)
+#define H5E_CANTUNDEPEND (H5OPEN H5E_CANTUNDEPEND_g)
+#define H5E_CANTNOTIFY (H5OPEN H5E_CANTNOTIFY_g)
H5_DLLVAR hid_t H5E_CANTFLUSH_g; /* Unable to flush data from cache */
H5_DLLVAR hid_t H5E_CANTSERIALIZE_g; /* Unable to serialize data from cache */
H5_DLLVAR hid_t H5E_CANTLOAD_g; /* Unable to load metadata into cache */
@@ -280,6 +287,9 @@ H5_DLLVAR hid_t H5E_CANTMARKDIRTY_g; /* Unable to mark a pinned entry as dirty *
H5_DLLVAR hid_t H5E_CANTDIRTY_g; /* Unable to mark metadata as dirty */
H5_DLLVAR hid_t H5E_CANTEXPUNGE_g; /* Unable to expunge a metadata cache entry */
H5_DLLVAR hid_t H5E_CANTRESIZE_g; /* Unable to resize a metadata cache entry */
+H5_DLLVAR hid_t H5E_CANTDEPEND_g; /* Unable to create a flush dependency */
+H5_DLLVAR hid_t H5E_CANTUNDEPEND_g; /* Unable to destroy a flush dependency */
+H5_DLLVAR hid_t H5E_CANTNOTIFY_g; /* Unable to notify object about action */
/* Link related errors */
#define H5E_TRAVERSE (H5OPEN H5E_TRAVERSE_g)
diff --git a/src/H5Epublic.h b/src/H5Epublic.h
index b0e93bb..932b857 100644
--- a/src/H5Epublic.h
+++ b/src/H5Epublic.h
@@ -180,7 +180,7 @@ H5_DLL ssize_t H5Eget_num(hid_t error_stack_id);
/* Symbols defined for compatibility with previous versions of the HDF5 API.
- *
+ *
* Use of these symbols is deprecated.
*/
#ifndef H5_NO_DEPRECATED_SYMBOLS
diff --git a/src/H5Eterm.h b/src/H5Eterm.h
index dedc313..0997990 100644
--- a/src/H5Eterm.h
+++ b/src/H5Eterm.h
@@ -22,9 +22,7 @@
/* Reset major error IDs */
-H5E_DATASET_g=
H5E_FUNC_g=
-H5E_STORAGE_g=
H5E_FILE_g=
H5E_SOHM_g=
H5E_SYM_g=
@@ -34,23 +32,27 @@ H5E_BTREE_g=
H5E_REFERENCE_g=
H5E_DATASPACE_g=
H5E_RESOURCE_g=
-H5E_PLIST_g=
-H5E_LINK_g=
-H5E_DATATYPE_g=
H5E_RS_g=
+H5E_FARRAY_g=
H5E_HEAP_g=
-H5E_OHDR_g=
-H5E_ATOM_g=
H5E_ATTR_g=
-H5E_NONE_MAJOR_g=
H5E_IO_g=
-H5E_SLIST_g=
H5E_EFL_g=
H5E_TST_g=
+H5E_FSPACE_g=
+H5E_DATASET_g=
+H5E_STORAGE_g=
+H5E_LINK_g=
+H5E_PLIST_g=
+H5E_DATATYPE_g=
+H5E_OHDR_g=
+H5E_ATOM_g=
+H5E_NONE_MAJOR_g=
+H5E_SLIST_g=
H5E_ARGS_g=
-H5E_ERROR_g=
+H5E_EARRAY_g=
H5E_PLINE_g=
-H5E_FSPACE_g=
+H5E_ERROR_g=
H5E_CACHE_g= (-1);
/* Reset minor error IDs */
@@ -164,7 +166,10 @@ H5E_CANTUNPIN_g=
H5E_CANTMARKDIRTY_g=
H5E_CANTDIRTY_g=
H5E_CANTEXPUNGE_g=
-H5E_CANTRESIZE_g=
+H5E_CANTRESIZE_g=
+H5E_CANTDEPEND_g=
+H5E_CANTUNDEPEND_g=
+H5E_CANTNOTIFY_g=
/* Link related errors */
H5E_TRAVERSE_g=
diff --git a/src/H5F.c b/src/H5F.c
index 3992b24..0f63a59 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -29,6 +29,7 @@
#include "H5FDprivate.h" /* File drivers */
#include "H5Gprivate.h" /* Groups */
#include "H5Iprivate.h" /* IDs */
+#include "H5MFprivate.h" /* File memory management */
#include "H5MMprivate.h" /* Memory management */
#include "H5Pprivate.h" /* Property lists */
#include "H5SMprivate.h" /* Shared Object Header Messages */
@@ -42,7 +43,7 @@
#include "H5FDmulti.h" /*multiple files partitioned by mem usage */
#include "H5FDsec2.h" /*Posix unbuffered I/O */
#include "H5FDstdio.h" /* Standard C buffered I/O */
-#ifdef H5_HAVE_WINDOWS
+#ifdef H5_HAVE_WINDOWS
#include "H5FDwindows.h" /* Windows buffered I/O */
#endif
#include "H5FDdirect.h" /*Linux direct I/O */
@@ -51,7 +52,7 @@
typedef struct H5F_olist_t {
H5I_type_t obj_type; /* Type of object to look for */
hid_t *obj_id_list; /* Pointer to the list of open IDs to return */
- unsigned *obj_id_count; /* Number of open IDs */
+ size_t *obj_id_count; /* Number of open IDs */
struct {
hbool_t local; /* Set flag for "local" file searches */
union {
@@ -59,18 +60,18 @@ typedef struct H5F_olist_t {
const H5F_t *file; /* Pointer to file to look inside */
} ptr;
} file_info;
- unsigned list_index; /* Current index in open ID array */
- int max_index; /* Maximum # of IDs to put into array */
+ size_t list_index; /* Current index in open ID array */
+ size_t max_index; /* Maximum # of IDs to put into array */
} H5F_olist_t;
/* PRIVATE PROTOTYPES */
-static unsigned H5F_get_objects(const H5F_t *f, unsigned types, int max_objs, hid_t *obj_id_list);
+static size_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list, hbool_t app_ref);
static int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key);
-static herr_t H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void** file_handle);
static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id,
H5FD_t *lf);
+static herr_t H5F_build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl,
+ const char *name, char ** /*out*/ actual_name);
static herr_t H5F_dest(H5F_t *f, hid_t dxpl_id);
-static herr_t H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags);
static herr_t H5F_close(H5F_t *f);
/* Declare a free list to manage the H5F_t struct */
@@ -164,7 +165,7 @@ H5F_term_interface(void)
if(H5_interface_initialize_g) {
if((n = H5I_nmembers(H5I_FILE)) != 0) {
- H5I_clear_type(H5I_FILE, FALSE);
+ H5I_clear_type(H5I_FILE, FALSE, FALSE);
} else {
/* Make certain we've cleaned up all the shared file objects */
H5F_sfile_assert_num(0);
@@ -205,13 +206,13 @@ H5Fget_create_plist(hid_t file_id)
H5TRACE1("i", "i", file_id);
/* check args */
- if(NULL == (file = H5I_object_verify(file_id, H5I_FILE)))
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
- if(NULL == (plist = H5I_object(file->shared->fcpl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(file->shared->fcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
/* Create the property list object to return */
- if((ret_value = H5P_copy_plist(plist)) < 0)
+ if((ret_value = H5P_copy_plist(plist, TRUE)) < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to copy file creation properties")
done:
@@ -250,11 +251,11 @@ H5Fget_access_plist(hid_t file_id)
H5TRACE1("i", "i", file_id);
/* Check args */
- if(NULL == (f = H5I_object_verify(file_id, H5I_FILE)))
+ if(NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
/* Retrieve the file's access property list */
- if((ret_value = H5F_get_access_plist(f)) < 0)
+ if((ret_value = H5F_get_access_plist(f, TRUE)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file access property list")
done:
@@ -286,7 +287,7 @@ done:
*-------------------------------------------------------------------------
*/
hid_t
-H5F_get_access_plist(H5F_t *f)
+H5F_get_access_plist(H5F_t *f, hbool_t app_ref)
{
H5P_genplist_t *new_plist; /* New property list */
H5P_genplist_t *old_plist; /* Old property list */
@@ -299,18 +300,18 @@ H5F_get_access_plist(H5F_t *f)
HDassert(f);
/* Make a copy of the default file access property list */
- if(NULL == (old_plist = H5I_object(H5P_LST_FILE_ACCESS_g)))
+ if(NULL == (old_plist = (H5P_genplist_t *)H5I_object(H5P_LST_FILE_ACCESS_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
- if((ret_value = H5P_copy_plist(old_plist)) < 0)
+ if((ret_value = H5P_copy_plist(old_plist, app_ref)) < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "can't copy file access property list")
- if(NULL == (new_plist = H5I_object(ret_value)))
+ if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(ret_value)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
/* Copy properties of the file access property list */
if(H5P_set(new_plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set initial metadata cache resize config.")
- if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME, &(f->shared->rdcc_nelmts)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache element size")
+ if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(f->shared->rdcc_nslots)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache number of slots")
if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache byte size")
if(H5P_set(new_plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, &(f->shared->rdcc_w0)) < 0)
@@ -321,11 +322,11 @@ H5F_get_access_plist(H5F_t *f)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set alignment")
if(H5P_set(new_plist, H5F_ACS_GARBG_COLCT_REF_NAME, &(f->shared->gc_ref)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set garbage collect reference")
- if(H5P_set(new_plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->lf->meta_aggr.alloc_size)) < 0)
+ if(H5P_set(new_plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->meta_aggr.alloc_size)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set metadata cache size")
if(H5P_set(new_plist, H5F_ACS_SIEVE_BUF_SIZE_NAME, &(f->shared->sieve_buf_size)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't sieve buffer size")
- if(H5P_set(new_plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->lf->sdata_aggr.alloc_size)) < 0)
+ if(H5P_set(new_plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->sdata_aggr.alloc_size)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'small data' cache size")
if(H5P_set(new_plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag")
@@ -338,7 +339,7 @@ H5F_get_access_plist(H5F_t *f)
HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't free the old driver information")
/* Increment the reference count on the driver ID and insert it into the property list */
- if(H5I_inc_ref(f->shared->lf->driver_id) < 0)
+ if(H5I_inc_ref(f->shared->lf->driver_id, FALSE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINC, FAIL, "unable to increment ref count on VFL driver")
if(H5P_set(new_plist, H5F_ACS_FILE_DRV_ID_NAME, &(f->shared->lf->driver_id)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file driver ID")
@@ -370,31 +371,34 @@ done:
*
* Programmer: Raymond Lu
* Wednesday, Dec 5, 2001
- *
* Modification:
+ * Raymond Lu
+ * 24 September 2008
+ * Changed the return value to ssize_t to accommadate
+ * potential large number of objects.
*
*-------------------------------------------------------------------------
*/
-int
+ssize_t
H5Fget_obj_count(hid_t file_id, unsigned types)
{
- H5F_t *f=NULL;
- int ret_value; /* Return value */
+ H5F_t *f = NULL; /* File to query */
+ ssize_t ret_value; /* Return value */
FUNC_ENTER_API(H5Fget_obj_count, FAIL)
- H5TRACE2("Is", "iIu", file_id, types);
+ H5TRACE2("Zs", "iIu", file_id, types);
- if( file_id != (hid_t)H5F_OBJ_ALL && (NULL==(f=H5I_object_verify(file_id,H5I_FILE))) )
+ if(file_id != (hid_t)H5F_OBJ_ALL && (NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file id")
- if( (types&H5F_OBJ_ALL)==0)
+ if(0 == (types & H5F_OBJ_ALL))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an object type")
- if((ret_value = H5F_get_obj_count(f, types)) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTCOUNT, FAIL, "can't get object count")
+ /* H5F_get_obj_count doesn't fail */
+ ret_value = (ssize_t)H5F_get_obj_count(f, types, TRUE);
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Fget_obj_count() */
/*-------------------------------------------------------------------------
@@ -403,23 +407,28 @@ done:
* Purpose: Private function return the number of opened object IDs
* (files, datasets, groups, datatypes) in the same file.
*
- * Return: Non-negative on success; negative on failure.
+ * Return: Non-negative on success; can't fail.
*
* Programmer: Raymond Lu
* Wednesday, Dec 5, 2001
*
* Modification:
+ * Raymond Lu
+ * 24 September 2008
+ * Changed the return value to size_t to accommadate
+ * potential large number of objects.
*
*-------------------------------------------------------------------------
*/
-unsigned
-H5F_get_obj_count(const H5F_t *f, unsigned types)
+size_t
+H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref)
{
- unsigned ret_value; /* Return value */
+ size_t ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_obj_count)
- ret_value=H5F_get_objects(f, types, -1, NULL);
+ /* H5F_get_objects doesn't fail */
+ ret_value = H5F_get_objects(f, types, 0, NULL, app_ref);
FUNC_LEAVE_NOAPI(ret_value)
}
@@ -436,29 +445,34 @@ H5F_get_obj_count(const H5F_t *f, unsigned types)
* Wednesday, Dec 5, 2001
*
* Modification:
+ * Raymond Lu
+ * 24 September 2008
+ * Changed the return value to ssize_t and MAX_OBJTS to size_t to
+ * accommadate potential large number of objects.
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5Fget_obj_ids(hid_t file_id, unsigned types, int max_objs, hid_t *oid_list)
+ssize_t
+H5Fget_obj_ids(hid_t file_id, unsigned types, size_t max_objs, hid_t *oid_list)
{
- herr_t ret_value;
- H5F_t *f=NULL;
+ H5F_t *f = NULL; /* File to query */
+ ssize_t ret_value; /* Return value */
FUNC_ENTER_API(H5Fget_obj_ids, FAIL)
- H5TRACE4("e", "iIuIs*i", file_id, types, max_objs, oid_list);
+ H5TRACE4("Zs", "iIuz*i", file_id, types, max_objs, oid_list);
- if( file_id != (hid_t)H5F_OBJ_ALL && (NULL==(f=H5I_object_verify(file_id,H5I_FILE))) )
+ if(file_id != (hid_t)H5F_OBJ_ALL && (NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file id")
- if( (types&H5F_OBJ_ALL)==0)
+ if(0 == (types & H5F_OBJ_ALL))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an object type")
- assert(oid_list);
-
- ret_value = H5F_get_obj_ids(f, types, max_objs, oid_list);
+ HDassert(oid_list);
+
+ /* H5F_get_objects doesn't fail */
+ ret_value = (ssize_t)H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE);
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Fget_obj_ids() */
/*-------------------------------------------------------------------------
@@ -466,23 +480,28 @@ done:
*
* Purpose: Private function to return a list of opened object IDs.
*
- * Return: Non-negative on success; negative on failure.
+ * Return: Non-negative on success; can't fail.
*
* Programmer: Raymond Lu
* Wednesday, Dec 5, 2001
*
* Modification:
+ * Raymond Lu
+ * 24 September 2008
+ * Changed the return value and MAX_OBJTS to size_t to accommadate
+ * potential large number of objects.
*
*-------------------------------------------------------------------------
*/
-unsigned
-H5F_get_obj_ids(const H5F_t *f, unsigned types, int max_objs, hid_t *oid_list)
+size_t
+H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list, hbool_t app_ref)
{
- unsigned ret_value; /* Return value */
+ size_t ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_obj_ids)
- ret_value = H5F_get_objects(f, types, max_objs, oid_list);
+ /* H5F_get_objects doesn't fail */
+ ret_value = H5F_get_objects(f, types, max_objs, oid_list, app_ref);
FUNC_LEAVE_NOAPI(ret_value)
}
@@ -494,21 +513,19 @@ H5F_get_obj_ids(const H5F_t *f, unsigned types, int max_objs, hid_t *oid_list)
* Purpose: This function is called by H5F_get_obj_count or
* H5F_get_obj_ids to get number of object IDs and/or a
* list of opened object IDs (in return value).
- * Return: Non-negative on success; negative on failure.
+ * Return: Non-negative on success; Can't fail.
*
* Programmer: Raymond Lu
* Wednesday, Dec 5, 2001
*
- * Modification:
- *
*---------------------------------------------------------------------------
*/
-static unsigned
-H5F_get_objects(const H5F_t *f, unsigned types, int max_index, hid_t *obj_id_list)
+static size_t
+H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref)
{
- unsigned obj_id_count=0; /* Number of open IDs */
+ size_t obj_id_count=0; /* Number of open IDs */
H5F_olist_t olist; /* Structure to hold search results */
- unsigned ret_value; /* Return value */
+ size_t ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_objects)
@@ -519,7 +536,7 @@ H5F_get_objects(const H5F_t *f, unsigned types, int max_index, hid_t *obj_id_lis
olist.max_index = max_index;
/* Determine if we are searching for local or global objects */
- if(types&H5F_OBJ_LOCAL) {
+ if(types & H5F_OBJ_LOCAL) {
olist.file_info.local = TRUE;
olist.file_info.ptr.file = f;
} /* end if */
@@ -529,45 +546,46 @@ H5F_get_objects(const H5F_t *f, unsigned types, int max_index, hid_t *obj_id_lis
} /* end else */
/* Search through file IDs to count the number, and put their
- * IDs on the object list */
+ * IDs on the object list. H5I_search returns NULL if no object
+ * is found, so don't return failure in this function. */
if(types & H5F_OBJ_FILE) {
olist.obj_type = H5I_FILE;
- (void)H5I_search(H5I_FILE, H5F_get_objects_cb, &olist);
+ (void)H5I_search(H5I_FILE, H5F_get_objects_cb, &olist, app_ref);
} /* end if */
/* Search through dataset IDs to count number of datasets, and put their
* IDs on the object list */
- if( (max_index < 0 || (int)olist.list_index < max_index) && (types & H5F_OBJ_DATASET) ) {
+ if(types & H5F_OBJ_DATASET) {
olist.obj_type = H5I_DATASET;
- (void)H5I_search(H5I_DATASET, H5F_get_objects_cb, &olist);
+ (void)H5I_search(H5I_DATASET, H5F_get_objects_cb, &olist, app_ref);
}
/* Search through group IDs to count number of groups, and put their
* IDs on the object list */
- if( (max_index < 0 || (int)olist.list_index < max_index) && (types & H5F_OBJ_GROUP) ) {
+ if(types & H5F_OBJ_GROUP) {
olist.obj_type = H5I_GROUP;
- (void)H5I_search(H5I_GROUP, H5F_get_objects_cb, &olist);
+ (void)H5I_search(H5I_GROUP, H5F_get_objects_cb, &olist, app_ref);
}
/* Search through datatype IDs to count number of named datatypes, and put their
* IDs on the object list */
- if( (max_index < 0 || (int)olist.list_index < max_index) && (types & H5F_OBJ_DATATYPE) ) {
+ if(types & H5F_OBJ_DATATYPE) {
olist.obj_type = H5I_DATATYPE;
- (void)H5I_search(H5I_DATATYPE, H5F_get_objects_cb, &olist);
+ (void)H5I_search(H5I_DATATYPE, H5F_get_objects_cb, &olist, app_ref);
}
/* Search through attribute IDs to count number of attributes, and put their
* IDs on the object list */
- if( (max_index < 0 || (int)olist.list_index < max_index) && (types & H5F_OBJ_ATTR) ) {
+ if(types & H5F_OBJ_ATTR) {
olist.obj_type = H5I_ATTR;
- (void)H5I_search(H5I_ATTR, H5F_get_objects_cb, &olist);
+ (void)H5I_search(H5I_ATTR, H5F_get_objects_cb, &olist, app_ref);
}
/* Set the number of objects currently open */
ret_value = obj_id_count;
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5F_get_objects() */
/*-------------------------------------------------------------------------
@@ -577,6 +595,9 @@ H5F_get_objects(const H5F_t *f, unsigned types, int max_index, hid_t *obj_id_lis
* object is in the file, and either count it or put its ID
* on the list.
*
+ * Return: TRUE if the array of object IDs is filled up.
+ * FALSE otherwise.
+ *
* Programmer: Raymond Lu
* Wednesday, Dec 5, 2001
*
@@ -592,8 +613,8 @@ H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key)
FUNC_ENTER_NOAPI_NOINIT(H5F_get_objects_cb)
- assert(obj_ptr);
- assert(olist);
+ HDassert(obj_ptr);
+ HDassert(olist);
/* Count file IDs */
if(olist->obj_type == H5I_FILE) {
@@ -611,60 +632,71 @@ H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key)
if(olist->obj_id_count)
(*olist->obj_id_count)++;
- /* Check if we've filled up the array */
- if(olist->max_index>=0 && (int)olist->list_index>=olist->max_index)
+ /* Check if we've filled up the array. Return TRUE only if
+ * we have filled up the array. Otherwise return FALSE(RET_VALUE is
+ * preset to FALSE) because H5I_search needs the return value of FALSE
+ * to continue searching. */
+ if(olist->max_index>0 && olist->list_index>=olist->max_index)
HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */
}
- } else { /* either count opened object IDs or put the IDs on the list */
+ } /* end if */
+ else { /* either count opened object IDs or put the IDs on the list */
H5O_loc_t *oloc; /* Group entry info for object */
switch(olist->obj_type) {
case H5I_ATTR:
- oloc = H5A_oloc((H5A_t*)obj_ptr);
+ oloc = H5A_oloc((H5A_t *)obj_ptr);
break;
+
case H5I_GROUP:
- oloc = H5G_oloc((H5G_t*)obj_ptr);
+ oloc = H5G_oloc((H5G_t *)obj_ptr);
break;
+
case H5I_DATASET:
- oloc = H5D_oloc((H5D_t*)obj_ptr);
+ oloc = H5D_oloc((H5D_t *)obj_ptr);
break;
+
case H5I_DATATYPE:
if(H5T_is_named((H5T_t*)obj_ptr)==TRUE)
oloc = H5T_oloc((H5T_t*)obj_ptr);
else
oloc = NULL;
break;
+
default:
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown data object")
- }
+ } /* end switch */
if((olist->file_info.local &&
- ( (!olist->file_info.ptr.file && olist->obj_type==H5I_DATATYPE && H5T_is_immutable((H5T_t*)obj_ptr)==FALSE)
- || (!olist->file_info.ptr.file && olist->obj_type!=H5I_DATATYPE)
- || (oloc && oloc->file == olist->file_info.ptr.file) ))
+ ( (!olist->file_info.ptr.file && olist->obj_type == H5I_DATATYPE && H5T_is_immutable((H5T_t *)obj_ptr) == FALSE)
+ || (!olist->file_info.ptr.file && olist->obj_type != H5I_DATATYPE)
+ || (oloc && oloc->file == olist->file_info.ptr.file)))
|| (!olist->file_info.local &&
- ((!olist->file_info.ptr.shared && olist->obj_type==H5I_DATATYPE && H5T_is_immutable((H5T_t*)obj_ptr)==FALSE)
- || (!olist->file_info.ptr.shared && olist->obj_type!=H5I_DATATYPE)
- || (oloc && oloc->file && oloc->file->shared == olist->file_info.ptr.shared) ))) {
+ ((!olist->file_info.ptr.shared && olist->obj_type == H5I_DATATYPE && H5T_is_immutable((H5T_t *)obj_ptr) == FALSE)
+ || (!olist->file_info.ptr.shared && olist->obj_type != H5I_DATATYPE)
+ || (oloc && oloc->file && oloc->file->shared == olist->file_info.ptr.shared)))) {
/* Add the object's ID to the ID list, if appropriate */
if(olist->obj_id_list) {
olist->obj_id_list[olist->list_index] = obj_id;
olist->list_index++;
- }
+ } /* end if */
/* Increment the number of open objects */
if(olist->obj_id_count)
(*olist->obj_id_count)++;
- /* Check if we've filled up the array */
- if(olist->max_index>=0 && (int)olist->list_index>=olist->max_index)
+ /* Check if we've filled up the array. Return TRUE only if
+ * we have filled up the array. Otherwise return FALSE(RET_VALUE is
+ * preset to FALSE) because H5I_search needs the return value of FALSE
+ * to continue searching. */
+ if(olist->max_index>0 && olist->list_index>=olist->max_index)
HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */
- }
- }
+ } /* end if */
+ } /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5F_get_objects_cb() */
/*-------------------------------------------------------------------------
@@ -674,68 +706,37 @@ done:
* driver.
*
* Return: Success: non-negative value.
- *
- * Failture: negative.
+ * Failure: negative.
*
* Programmer: Raymond Lu
* Sep. 16, 2002
*
- * Modification:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5Fget_vfd_handle(hid_t file_id, hid_t fapl, void **file_handle)
{
- H5F_t *file=NULL;
- herr_t ret_value;
+ H5F_t *file; /* File to query */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Fget_vfd_handle, FAIL)
H5TRACE3("e", "ii**x", file_id, fapl, file_handle);
/* Check args */
- assert(file_handle);
- if(NULL==(file=H5I_object_verify(file_id, H5I_FILE)))
+ if(!file_handle)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file handle pointer")
+
+ /* Get the file */
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file id")
- ret_value=H5F_get_vfd_handle(file, fapl, file_handle);
+ /* Retrieve the VFD handle for the file */
+ if(H5F_get_vfd_handle(file, fapl, file_handle) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve VFD handle")
done:
FUNC_LEAVE_API(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_get_vfd_handle
- *
- * Purpose: Returns a pointer to the file handle of the low-level file
- * driver. This is the private function for H5Fget_vfd_handle.
- *
- * Return: Success: Non-negative.
- *
- * Failture: negative.
- *
- * Programmer: Raymond Lu
- * Sep. 16, 2002
- *
- * Modification:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void**file_handle)
-{
- herr_t ret_value;
-
- FUNC_ENTER_NOAPI_NOINIT(H5F_get_vfd_handle)
-
- assert(file_handle);
- if((ret_value=H5FD_get_vfd_handle(file->shared->lf, fapl, file_handle)) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file handle for file driver")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5Fget_vfd_handle() */
/*-------------------------------------------------------------------------
@@ -761,31 +762,31 @@ done:
htri_t
H5Fis_hdf5(const char *name)
{
- H5FD_t *file = NULL;
- htri_t ret_value;
+ H5FD_t *file = NULL; /* Low-level file struct */
+ htri_t ret_value; /* Return value */
FUNC_ENTER_API(H5Fis_hdf5, FAIL)
H5TRACE1("t", "*s", name);
/* Check args and all the boring stuff. */
- if (!name || !*name)
+ if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "no file name specified")
/* Open the file at the virtual file layer */
- if (NULL==(file=H5FD_open(name, H5F_ACC_RDONLY, H5P_FILE_ACCESS_DEFAULT, HADDR_UNDEF)))
+ if(NULL == (file = H5FD_open(name, H5F_ACC_RDONLY, H5P_FILE_ACCESS_DEFAULT, HADDR_UNDEF)))
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to open file")
/* The file is an hdf5 file if the hdf5 file signature can be found */
- ret_value = (HADDR_UNDEF!=H5F_locate_signature(file, H5AC_ind_dxpl_id));
+ ret_value = (HADDR_UNDEF != H5F_locate_signature(file, H5AC_ind_dxpl_id));
done:
/* Close the file */
- if (file)
- if(H5FD_close(file) < 0 && ret_value>=0)
+ if(file)
+ if(H5FD_close(file) < 0 && ret_value >= 0)
HDONE_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file")
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Fis_hdf5() */
/*-------------------------------------------------------------------------
@@ -808,22 +809,6 @@ done:
* matzke@llnl.gov
* Jul 18 1997
*
- * Modifications:
- *
- * Raymond Lu, Oct 14, 2001
- * Changed the file creation and access property list to the
- * new generic property list.
- *
- * J Mainzer, Mar 10, 2005
- * Updated for the new metadata cache, and associated
- * property list changes.
- *
- * J Mainzer, Jun 30, 2005
- * Added lf parameter so the shared->lf field can be
- * initialized prior to the call to H5AC_create() if a
- * new instance of H5F_file_t is created. lf should be
- * NULL if shared isn't, and vise versa.
- *
*-------------------------------------------------------------------------
*/
static H5F_t *
@@ -842,18 +827,18 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
f->shared = shared;
} /* end if */
else {
- unsigned super_vers = HDF5_SUPERBLOCK_VERSION_DEF; /* Superblock version for file */
- H5P_genplist_t *plist; /* Property list */
+ H5P_genplist_t *plist; /* Property list */
+ size_t u; /* Local index variable */
HDassert(lf != NULL);
if(NULL == (f->shared = H5FL_CALLOC(H5F_file_t)))
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared file structure")
- f->shared->super_addr = HADDR_UNDEF;
- f->shared->base_addr = HADDR_UNDEF;
- f->shared->extension_addr = HADDR_UNDEF;
+
f->shared->sohm_addr = HADDR_UNDEF;
f->shared->sohm_vers = HDF5_SHAREDHEADER_VERSION;
- f->shared->driver_addr = HADDR_UNDEF;
+ for(u = 0; u < NELMTS(f->shared->fs_addr); u++)
+ f->shared->fs_addr[u] = HADDR_UNDEF;
+ f->shared->accum.loc = HADDR_UNDEF;
f->shared->lf = lf;
/*
@@ -861,32 +846,32 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
* new file handle. We do this early because some values might need
* to change as the file is being opened.
*/
- if(NULL == (plist = H5I_object(fcpl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not property list")
- f->shared->fcpl_id = H5P_copy_plist(plist);
+ f->shared->fcpl_id = H5P_copy_plist(plist, FALSE);
/* Get the FCPL values to cache */
if(H5P_get(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &f->shared->sizeof_addr) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for address")
if(H5P_get(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &f->shared->sizeof_size) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for object size")
- if(H5P_get(plist, H5F_CRT_SYM_LEAF_NAME, &f->shared->sym_leaf_k) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for object size")
- if(H5P_get(plist, H5F_CRT_BTREE_RANK_NAME, &f->shared->btree_k[0]) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to get rank for btree internal nodes")
- if(H5P_get(plist, H5F_CRT_SHMSG_NINDEXES_NAME, &f->shared->sohm_nindexes)<0)
+ if(H5P_get(plist, H5F_CRT_SHMSG_NINDEXES_NAME, &f->shared->sohm_nindexes) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get number of SOHM indexes")
HDassert(f->shared->sohm_nindexes < 255);
+ if(H5P_get(plist, H5F_CRT_FILE_SPACE_STRATEGY_NAME, &f->shared->fs_strategy) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file space strategy")
+ if(H5P_get(plist, H5F_CRT_FREE_SPACE_THRESHOLD_NAME, &f->shared->fs_threshold) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get free-space section threshold")
/* Get the FAPL values to cache */
- if(NULL == (plist = H5I_object(fapl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list")
if(H5P_get(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial metadata cache resize config")
- if(H5P_get(plist, H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME, &(f->shared->rdcc_nelmts)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache element size")
+ if(H5P_get(plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(f->shared->rdcc_nslots)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache number of slots")
if(H5P_get(plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache cache size")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache byte size")
if(H5P_get(plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, &(f->shared->rdcc_w0)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get preempt read chunk")
if(H5P_get(plist, H5F_ACS_ALIGN_THRHD_NAME, &(f->shared->threshold)) < 0)
@@ -899,34 +884,34 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get sieve buffer size")
if(H5P_get(plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'latest format' flag")
+ if(H5P_get(plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->meta_aggr.alloc_size)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get metadata cache size")
+ f->shared->meta_aggr.feature_flag = H5FD_FEAT_AGGREGATE_METADATA;
+ if(H5P_get(plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->sdata_aggr.alloc_size)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'small data' cache size")
+ f->shared->sdata_aggr.feature_flag = H5FD_FEAT_AGGREGATE_SMALLDATA;
/* Get the VFD values to cache */
f->shared->maxaddr = H5FD_get_maxaddr(lf);
if(!H5F_addr_defined(f->shared->maxaddr))
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad maximum address from VFD")
-
- /* Bump superblock version if we are to use the latest version of the format */
- if(f->shared->latest_format)
- super_vers = HDF5_SUPERBLOCK_VERSION_LATEST;
- /* Bump superblock version to create superblock extension for SOHM info */
- else if(f->shared->sohm_nindexes > 0)
- super_vers = HDF5_SUPERBLOCK_VERSION_2;
- /* Check for non-default indexed storage B-tree internal 'K' value
- * and set the version # of the superblock to 1 if it is a non-default
- * value.
+ if(H5FD_get_feature_flags(lf, &f->shared->feature_flags) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get feature flags from VFD")
+ if(H5FD_get_fs_type_map(lf, f->shared->fs_type_map) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get free space type mapping from VFD")
+ if(H5MF_init_merge_flags(f) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "problem initializing free space merge flags")
+ f->shared->tmp_addr = f->shared->maxaddr;
+ /* Disable temp. space allocation for parallel I/O (for now) */
+ /* (When we've arranged to have the relocated metadata addresses (and
+ * sizes) broadcast during the "end of epoch" metadata operations,
+ * this can be enabled - QAK)
*/
- else if(f->shared->btree_k[H5B_ISTORE_ID] != HDF5_BTREE_ISTORE_IK_DEF)
- super_vers = HDF5_SUPERBLOCK_VERSION_1;
-
- /* If a newer superblock version is required, set it here */
- if(super_vers != HDF5_SUPERBLOCK_VERSION_DEF) {
- H5P_genplist_t *c_plist; /* Property list */
-
- if(NULL == (c_plist = H5I_object(f->shared->fcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not property list")
- if(H5P_set(c_plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set superblock version")
- } /* end if */
+ /* (This should be disabled when the metadata journaling branch is
+ * merged into the trunk and journaling is enabled, at least until
+ * we make it work. - QAK)
+ */
+ f->shared->use_tmp_space = !(IS_H5FD_MPI(f));
/*
* Create a metadata cache with the specified number of elements.
@@ -957,8 +942,8 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
done:
if(!ret_value && f) {
if(!shared)
- H5FL_FREE(H5F_file_t, f->shared);
- H5FL_FREE(H5F_t, f);
+ (void)H5FL_FREE(H5F_file_t, f->shared);
+ (void)H5FL_FREE(H5F_t, f);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -978,16 +963,13 @@ done:
* Programmer: Robb Matzke
* matzke@llnl.gov
* Jul 18 1997
- * Modifications:
- * Vailin Choi, April 2, 2008
- * Free f->extpath
*
*-------------------------------------------------------------------------
*/
static herr_t
H5F_dest(H5F_t *f, hid_t dxpl_id)
{
- herr_t ret_value = SUCCEED;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5F_dest)
@@ -1007,10 +989,24 @@ H5F_dest(H5F_t *f, hid_t dxpl_id)
H5AC_stats(f);
#endif /* H5AC_DUMP_STATS_ON_CLOSE */
- /* Flush and invalidate all caches */
- if(H5F_flush(f, dxpl_id, H5F_SCOPE_LOCAL, H5F_FLUSH_INVALIDATE | H5F_FLUSH_CLOSING) < 0)
+ /* Shutdown file free space manager(s) */
+ /* (We should release the free space information now (before truncating
+ * the file and before the metadata cache is shut down) since the
+ * free space manager is holding some data structures in memory
+ * and also because releasing free space can shrink the file's
+ * 'eoa' value)
+ */
+ if(H5F_ACC_RDWR & H5F_INTENT(f)) {
+ if(H5MF_close(f, dxpl_id) < 0)
+ /* Push error, but keep going*/
+ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file free space info")
+ } /* end if */
+
+ /* Unpin the superblock, since we're about to destroy the cache */
+ if(H5AC_unpin_entry(f, f->shared->sblock) < 0)
/* Push error, but keep going*/
- HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache")
+ HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin superblock")
+ f->shared->sblock = NULL;
} /* end if */
/* Remove shared file struct from list of open files */
@@ -1018,6 +1014,11 @@ H5F_dest(H5F_t *f, hid_t dxpl_id)
/* Push error, but keep going*/
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file")
+ /* Shutdown the metadata cache */
+ if(H5AC_dest(f, dxpl_id))
+ /* Push error, but keep going*/
+ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file")
+
/*
* Do not close the root group since we didn't count it, but free
* the memory associated with it.
@@ -1035,13 +1036,14 @@ H5F_dest(H5F_t *f, hid_t dxpl_id)
f->shared->root_grp = NULL;
} /* end if */
- if(H5AC_dest(f, dxpl_id) < 0)
+ /* Destroy other components of the file */
+ if(H5F_accum_reset(f, dxpl_id) < 0)
/* Push error, but keep going*/
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file")
if(H5FO_dest(f) < 0)
/* Push error, but keep going*/
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file")
- f->shared->cwfs = H5MM_xfree(f->shared->cwfs);
+ f->shared->cwfs = (struct H5HG_heap_t **)H5MM_xfree(f->shared->cwfs);
if(H5G_node_close(f) < 0)
/* Push error, but keep going*/
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file")
@@ -1050,21 +1052,29 @@ H5F_dest(H5F_t *f, hid_t dxpl_id)
if(H5I_GENPROP_LST != H5I_get_type(f->shared->fcpl_id))
/* Push error, but keep going*/
HDONE_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a property list")
- if(H5I_dec_ref(f->shared->fcpl_id) < 0)
+ if(H5I_dec_ref(f->shared->fcpl_id, FALSE) < 0)
/* Push error, but keep going*/
HDONE_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close property list")
- /* Close low-level file */
+ /* Only truncate the file on an orderly close, with write-access */
+ if(f->closing && (H5F_ACC_RDWR & H5F_INTENT(f))) {
+ /* Truncate the file to the current allocated size */
+ if(H5FD_truncate(f->shared->lf, dxpl_id, (unsigned)TRUE) < 0)
+ /* Push error, but keep going*/
+ HDONE_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "low level truncate failed")
+ } /* end if */
+
+ /* Close the file */
if(H5FD_close(f->shared->lf) < 0)
/* Push error, but keep going*/
- HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "problems closing file")
+ HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file")
/* Free mount table */
- f->shared->mtab.child = H5MM_xfree(f->shared->mtab.child);
+ f->shared->mtab.child = (H5F_mount_t *)H5MM_xfree(f->shared->mtab.child);
f->shared->mtab.nalloc = 0;
/* Destroy shared file struct */
- f->shared = H5FL_FREE(H5F_file_t,f->shared);
+ f->shared = (H5F_file_t *)H5FL_FREE(H5F_file_t, f->shared);
} else if(f->shared->nrefs > 0) {
/*
@@ -1075,12 +1085,13 @@ H5F_dest(H5F_t *f, hid_t dxpl_id)
}
/* Free the non-shared part of the file */
- f->name = H5MM_xfree(f->name);
- f->extpath = H5MM_xfree(f->extpath);
+ f->open_name = (char *)H5MM_xfree(f->open_name);
+ f->actual_name = (char *)H5MM_xfree(f->actual_name);
+ f->extpath = (char *)H5MM_xfree(f->extpath);
if(H5FO_top_dest(f) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "problems closing file")
f->shared = NULL;
- H5FL_FREE(H5F_t, f);
+ (void)H5FL_FREE(H5F_t, f);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_dest() */
@@ -1125,53 +1136,16 @@ H5F_dest(H5F_t *f, hid_t dxpl_id)
* cause the default file access parameters to be used.
*
* Return: Success: A new file pointer.
- *
* Failure: NULL
*
* Programmer: Robb Matzke
* Tuesday, September 23, 1997
*
- * Modifications:
- * Albert Cheng, 1998-02-05
- * Added the access_parms argument to pass down access template
- * information.
- *
- * Robb Matzke, 1998-02-18
- * The H5F_access_t changed to allow more generality. The low
- * level driver is part of the file access template so the TYPE
- * argument has been removed.
- *
- * Robb Matzke, 1999-08-02
- * Rewritten to use the virtual file layer.
- *
- * Robb Matzke, 1999-08-16
- * Added decoding of file driver information block, which uses a
- * formerly reserved address slot in the boot block in order to
- * be compatible with previous versions of the file format.
- *
- * Robb Matzke, 1999-08-20
- * Optimizations for opening a file. If the driver can't
- * determine when two file handles refer to the same file then
- * we open the file in one step. Otherwise if the first attempt
- * to open the file fails then we skip the second attempt if the
- * arguments would be the same.
- *
- * Raymond Lu, 2001-10-14
- * Changed the file creation and access property lists to the
- * new generic property list.
- *
- * Bill Wendling, 2003-03-18
- * Modified H5F_flush call to take one flag instead of
- * multiple Boolean flags.
- *
- * Vailin Choi, 2008-04-02
- * To formulate path for later searching of target file for
- * external link via H5_build_extpath().
- *
*-------------------------------------------------------------------------
*/
H5F_t *
-H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id)
+H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id,
+ hid_t dxpl_id)
{
H5F_t *file = NULL; /*the success return value */
H5F_file_t *shared = NULL; /*shared part of `file' */
@@ -1192,7 +1166,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
* Otherwise it is the application's responsibility to never open the
* same file more than once at a time.
*/
- if((drvr = H5FD_get_class(fapl_id)) == NULL)
+ if(NULL == (drvr = H5FD_get_class(fapl_id)))
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to retrieve VFL class")
/*
@@ -1278,23 +1252,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
* file can be accessed through the C library.
*/
file->intent = flags;
- file->name = H5MM_xstrdup(name);
-
- /* Get the file access property list, for future queries */
- if(NULL == (a_plist = H5I_object(fapl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list")
-
- /* This step is for h5repart tool only. If user wants to change file driver from
- * family to sec2 while using h5repart, this private property should be set so that
- * in the later step, the library can ignore the family driver information saved
- * in the superblock.
- */
- if(H5P_exist_plist(a_plist, H5F_ACS_FAMILY_TO_SEC2_NAME) > 0) {
- if(H5P_get(a_plist, H5F_ACS_FAMILY_TO_SEC2_NAME, &shared->fam_to_sec2) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property of changing family to sec2")
- } /* end if */
- else
- shared->fam_to_sec2 = FALSE;
+ file->open_name = H5MM_xstrdup(name);
/*
* Read or write the file superblock, depending on whether the file is
@@ -1315,34 +1273,22 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
/* (This must be after the space for the superblock is allocated in
* the file, since the superblock must be at offset 0)
*/
- if(H5G_mkroot(file, dxpl_id, NULL) < 0)
+ if(H5G_mkroot(file, dxpl_id, TRUE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create/open root group")
-
- /* Write the superblock to the file */
- /* (This must be after the root group is created, since the root
- * group's symbol table entry is part of the superblock)
- */
- if(H5F_super_write(file, dxpl_id) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to write file superblock")
} else if (1 == shared->nrefs) {
- H5G_loc_t root_loc; /*root location */
- H5O_loc_t root_oloc; /*root object location */
- H5G_name_t root_path; /*root group hier. path */
-
- /* Set up root location to fill in */
- root_loc.oloc = &root_oloc;
- root_loc.path = &root_path;
- H5G_loc_reset(&root_loc);
-
/* Read the superblock if it hasn't been read before. */
- if(H5F_super_read(file, dxpl_id, &root_loc) < 0)
+ if(H5F_super_read(file, dxpl_id) < 0)
HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock")
/* Open the root group */
- if(H5G_mkroot(file, dxpl_id, &root_loc) < 0)
+ if(H5G_mkroot(file, dxpl_id, FALSE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root group")
} /* end if */
+ /* Get the file access property list, for future queries */
+ if(NULL == (a_plist = (H5P_genplist_t *)H5I_object(fapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list")
+
/*
* Decide the file close degree. If it's the first time to open the
* file, set the degree to access property list value; if it's the
@@ -1364,10 +1310,14 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match")
} /* end if */
- /* formulate the absolute path for later search of target file for external link */
- if (H5_build_extpath(name, &file->extpath) < 0)
+ /* Formulate the absolute path for later search of target file for external links */
+ if(H5_build_extpath(name, &file->extpath) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build extpath")
-
+
+ /* Formulate the actual file name, after following symlinks, etc. */
+ if(H5F_build_actual_name(file, a_plist, name, &file->actual_name) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build actual name")
+
/* Success */
ret_value = file;
@@ -1405,33 +1355,6 @@ done:
*
* Programmer: Unknown
*
- * Modifications:
- * Robb Matzke, 1997-07-18
- * File struct creation and destruction is through H5F_new() and
- * H5F_dest(). Writing the root symbol table entry is done with
- * H5G_encode().
- *
- * Robb Matzke, 1997-08-29
- * Moved creation of the boot block to H5F_flush().
- *
- * Robb Matzke, 1997-09-23
- * Most of the work is now done by H5F_open() since H5Fcreate()
- * and H5Fopen() originally contained almost identical code.
- *
- * Robb Matzke, 1998-02-18
- * Better error checking for the creation and access property
- * lists. It used to be possible to swap the two and core the
- * library. Also, zero is no longer valid as a default property
- * list; one must use H5P_DEFAULT instead.
- *
- * Robb Matzke, 1999-08-02
- * The file creation and file access property lists are passed
- * to the H5F_open() as object IDs.
- *
- * Raymond Lu, 2001-10-14
- * Changed the file creation and access property list to the
- * new generic property list.
- *
*-------------------------------------------------------------------------
*/
hid_t
@@ -1444,11 +1367,15 @@ H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
H5TRACE4("i", "*sIuii", filename, flags, fcpl_id, fapl_id);
/* Check/fix arguments */
- if (!filename || !*filename)
+ if(!filename || !*filename)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name")
- if (flags & ~(H5F_ACC_EXCL|H5F_ACC_TRUNC|H5F_ACC_DEBUG))
+ /* In this routine, we only accept the following flags:
+ * H5F_ACC_EXCL, H5F_ACC_TRUNC and H5F_ACC_DEBUG
+ */
+ if(flags & ~(H5F_ACC_EXCL | H5F_ACC_TRUNC | H5F_ACC_DEBUG))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags")
- if ((flags & H5F_ACC_EXCL) && (flags & H5F_ACC_TRUNC))
+ /* The H5F_ACC_EXCL and H5F_ACC_TRUNC flags are mutually exclusive */
+ if((flags & H5F_ACC_EXCL) && (flags & H5F_ACC_TRUNC))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mutually exclusive flags for file creation")
/* Check file creation property list */
@@ -1481,7 +1408,7 @@ H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create file")
/* Get an atom for the file */
- if((ret_value = H5I_register(H5I_FILE, new_file)) < 0)
+ if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file")
/* Keep this ID in file object structure */
@@ -1548,6 +1475,7 @@ H5Fopen(const char *filename, unsigned flags, hid_t fapl_id)
/* Check/fix arguments. */
if(!filename || !*filename)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name")
+ /* Reject undefined flags (~H5F_ACC_PUBLIC_FLAGS) and the H5F_ACC_TRUNC & H5F_ACC_EXCL flags */
if((flags & ~H5F_ACC_PUBLIC_FLAGS) ||
(flags & H5F_ACC_TRUNC) || (flags & H5F_ACC_EXCL))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags")
@@ -1562,7 +1490,7 @@ H5Fopen(const char *filename, unsigned flags, hid_t fapl_id)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to open file")
/* Get an atom for the file */
- if((ret_value = H5I_register(H5I_FILE, new_file)) < 0)
+ if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle")
/* Keep this ID in file object structure */
@@ -1588,58 +1516,62 @@ done:
* Programmer: Robb Matzke
* Thursday, August 6, 1998
*
- * Modifications:
- * Robb Matzke, 1998-10-16
- * Added the `scope' argument.
- *
- * Bill Wendling, 2003-03-18
- * Modified H5F_flush call to take one flag instead of
- * several Boolean flags.
- *
*-------------------------------------------------------------------------
*/
herr_t
H5Fflush(hid_t object_id, H5F_scope_t scope)
{
- H5F_t *f = NULL;
- H5G_t *grp = NULL;
- H5T_t *type = NULL;
- H5D_t *dset = NULL;
- H5A_t *attr = NULL;
- H5O_loc_t *oloc = NULL;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5F_t *f = NULL; /* File to flush */
+ H5O_loc_t *oloc = NULL; /* Object location for ID */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Fflush, FAIL)
H5TRACE2("e", "iFs", object_id, scope);
switch(H5I_get_type(object_id)) {
case H5I_FILE:
- if(NULL == (f = H5I_object(object_id)))
+ if(NULL == (f = (H5F_t *)H5I_object(object_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
break;
case H5I_GROUP:
- if(NULL == (grp = H5I_object(object_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid group identifier")
- oloc = H5G_oloc(grp);
+ {
+ H5G_t *grp;
+
+ if(NULL == (grp = (H5G_t *)H5I_object(object_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid group identifier")
+ oloc = H5G_oloc(grp);
+ }
break;
case H5I_DATATYPE:
- if(NULL == (type = H5I_object(object_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid type identifier")
- oloc = H5T_oloc(type);
+ {
+ H5T_t *type;
+
+ if(NULL == (type = (H5T_t *)H5I_object(object_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid type identifier")
+ oloc = H5T_oloc(type);
+ }
break;
case H5I_DATASET:
- if(NULL == (dset = H5I_object(object_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier")
- oloc = H5D_oloc(dset);
+ {
+ H5D_t *dset;
+
+ if(NULL == (dset = (H5D_t *)H5I_object(object_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier")
+ oloc = H5D_oloc(dset);
+ }
break;
case H5I_ATTR:
- if(NULL == (attr = H5I_object(object_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid attribute identifier")
- oloc = H5A_oloc(attr);
+ {
+ H5A_t *attr;
+
+ if(NULL == (attr = (H5A_t *)H5I_object(object_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid attribute identifier")
+ oloc = H5A_oloc(attr);
+ }
break;
default:
@@ -1655,8 +1587,26 @@ H5Fflush(hid_t object_id, H5F_scope_t scope)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "object is not associated with a file")
/* Flush the file */
- if(H5F_flush(f, H5AC_dxpl_id, scope, H5F_FLUSH_NONE) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "flush failed")
+ /*
+ * Nothing to do if the file is read only. This determination is
+ * made at the shared open(2) flags level, implying that opening a
+ * file twice, once for read-only and once for read-write, and then
+ * calling H5Fflush() with the read-only handle, still causes data
+ * to be flushed.
+ */
+ if(H5F_ACC_RDWR & H5F_INTENT(f)) {
+ /* Flush other files, depending on scope */
+ if(H5F_SCOPE_GLOBAL == scope) {
+ /* Call the flush routine for mounted file hierarchies */
+ if(H5F_flush_mounts(f, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush mounted file hierarchy")
+ } /* end if */
+ else {
+ /* Call the flush routine, for this file */
+ if(H5F_flush(f, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information")
+ } /* end else */
+ } /* end if */
done:
FUNC_LEAVE_API(ret_value)
@@ -1666,9 +1616,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5F_flush
*
- * Purpose: Flushes (and optionally invalidates) cached data plus the
- * file superblock. If the logical file size field is zero
- * then it is updated to be the length of the superblock.
+ * Purpose: Flushes cached data.
*
* Return: Non-negative on success/Negative on failure
*
@@ -1678,75 +1626,45 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
-H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags)
+herr_t
+H5F_flush(H5F_t *f, hid_t dxpl_id)
{
- unsigned nerrors = 0; /* Errors from nested flushes */
- unsigned i; /* Index variable */
- unsigned int H5AC_flags; /* translated flags for H5AC_flush() */
- herr_t ret_value; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5F_flush)
+ FUNC_ENTER_NOAPI(H5F_flush, FAIL)
/* Sanity check arguments */
HDassert(f);
- /*
- * Nothing to do if the file is read only. This determination is
- * made at the shared open(2) flags level, implying that opening a
- * file twice, once for read-only and once for read-write, and then
- * calling H5F_flush() with the read-only handle, still causes data
- * to be flushed.
- */
- if(0 == (H5F_ACC_RDWR & f->shared->flags))
- HGOTO_DONE(SUCCEED)
-
- /* Flush other files, depending on scope */
- if(H5F_SCOPE_GLOBAL == scope) {
- while(f->parent)
- f = f->parent;
-
- scope = H5F_SCOPE_DOWN;
- } /* end while */
- if(H5F_SCOPE_DOWN == scope)
- for(i = 0; i < f->shared->mtab.nmounts; i++)
- if(H5F_flush(f->shared->mtab.child[i].file, dxpl_id, scope, flags) < 0)
- nerrors++;
-
/* Flush any cached dataset storage raw data */
- if(H5D_flush(f, dxpl_id, flags) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush dataset cache")
+ if(H5D_flush(f, dxpl_id) < 0)
+ /* Push error, but keep going*/
+ HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush dataset cache")
- /* flush (and invalidate, if requested) the entire metadata cache */
- H5AC_flags = 0;
- if((flags & H5F_FLUSH_INVALIDATE) != 0 )
- H5AC_flags |= H5AC__FLUSH_INVALIDATE_FLAG;
- if(H5AC_flush(f, dxpl_id, H5AC_flags) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush metadata cache")
-
- /*
- * If we are invalidating everything (which only happens just before
- * the file closes), release the unused portion of the metadata and
- * "small data" blocks back to the free lists in the file.
+ /* Release any space allocated to space aggregators, so that the eoa value
+ * corresponds to the end of the space written to in the file.
+ */
+ /* (needs to happen before cache flush, with superblock write, since the
+ * 'eoa' value is written in superblock -QAK)
*/
- if(flags & H5F_FLUSH_INVALIDATE) {
- if(H5FD_aggr_reset(f->shared->lf, &(f->shared->lf->meta_aggr), dxpl_id) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't reset metadata block")
+ if(H5MF_free_aggrs(f, dxpl_id) < 0)
+ /* Push error, but keep going*/
+ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file space")
- if(H5FD_aggr_reset(f->shared->lf, &(f->shared->lf->sdata_aggr), dxpl_id) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't reset 'small data' block")
- } /* end if */
+ /* Flush the entire metadata cache */
+ if(H5AC_flush(f, dxpl_id) < 0)
+ /* Push error, but keep going*/
+ HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush metadata cache")
- /* Write the superblock to disk */
- if(H5F_super_write(f, dxpl_id) != SUCCEED)
- HGOTO_ERROR(H5E_CACHE, H5E_WRITEERROR, FAIL, "unable to write superblock to file")
+ /* Flush out the metadata accumulator */
+ if(H5F_accum_flush(f, dxpl_id) < 0)
+ /* Push error, but keep going*/
+ HDONE_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush metadata accumulator")
/* Flush file buffers to disk. */
- if(H5FD_flush(f->shared->lf, dxpl_id, (unsigned)((flags & H5F_FLUSH_CLOSING) > 0)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed")
-
- /* Check flush errors for children - errors are already on the stack */
- ret_value = (nerrors ? FAIL : SUCCEED);
+ if(H5FD_flush(f->shared->lf, dxpl_id, FALSE) < 0)
+ /* Push error, but keep going*/
+ HDONE_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1916,10 +1834,10 @@ H5F_try_close(H5F_t *f)
unsigned u; /* Local index variable */
/* Get the list of IDs of open dataset, group, & attribute objects */
- while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_ATTR, (int)(sizeof(objs)/sizeof(objs[0])), objs)) != 0) {
+ while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_ATTR, (int)(sizeof(objs)/sizeof(objs[0])), objs, FALSE)) != 0) {
/* Try to close all the open objects in this file */
for(u = 0; u < obj_count; u++)
- if(H5I_dec_ref(objs[u]) < 0)
+ if(H5I_dec_ref(objs[u], FALSE) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
} /* end while */
@@ -1928,10 +1846,10 @@ H5F_try_close(H5F_t *f)
* they could be using one of the named datatypes and then the
* open named datatype ID will get closed twice)
*/
- while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATATYPE, (int)(sizeof(objs)/sizeof(objs[0])), objs)) != 0) {
+ while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATATYPE, (int)(sizeof(objs)/sizeof(objs[0])), objs, FALSE)) != 0) {
/* Try to close all the open objects in this file */
for(u = 0; u < obj_count; u++)
- if(H5I_dec_ref(objs[u]) < 0)
+ if(H5I_dec_ref(objs[u], FALSE) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
} /* end while */
} /* end if */
@@ -1954,9 +1872,9 @@ H5F_try_close(H5F_t *f)
* copy of the cache needs to be clean.
* Only try to flush the file if it was opened with write access.
*/
- if(f->intent&H5F_ACC_RDWR) {
- /* Flush and destroy all caches */
- if(H5F_flush(f, H5AC_dxpl_id, H5F_SCOPE_LOCAL, H5C__NO_FLAGS_SET) < 0)
+ if(f->intent & H5F_ACC_RDWR) {
+ /* Flush all caches */
+ if(H5F_flush(f, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache")
} /* end if */
@@ -2010,7 +1928,7 @@ H5Fclose(hid_t file_id)
* Decrement reference count on atom. When it reaches zero the file will
* be closed.
*/
- if(H5I_dec_ref(file_id) < 0)
+ if(H5I_dec_ref(file_id, TRUE) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed")
done:
@@ -2051,7 +1969,7 @@ H5Freopen(hid_t file_id)
H5TRACE1("i", "i", file_id);
/* Check arguments */
- if(NULL == (old_file = H5I_object_verify(file_id, H5I_FILE)))
+ if(NULL == (old_file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
/* Get a new "top level" file struct, sharing the same "low level" file struct */
@@ -2061,10 +1979,11 @@ H5Freopen(hid_t file_id)
/* Keep old file's read/write intent in new file */
new_file->intent = old_file->intent;
- /* Duplicate old file's name */
- new_file->name = H5MM_xstrdup(old_file->name);
+ /* Duplicate old file's names */
+ new_file->open_name = H5MM_xstrdup(old_file->open_name);
+ new_file->actual_name = H5MM_xstrdup(old_file->actual_name);
- if((ret_value = H5I_register(H5I_FILE, new_file)) < 0)
+ if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle")
/* Keep this ID in file object structure */
@@ -2090,410 +2009,37 @@ done:
* Programmer: James Laird
* August 23, 2006
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5Fget_intent(hid_t file_id, unsigned *intent_flags)
{
- H5F_t * file = NULL;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(H5Fget_intent, FAIL)
H5TRACE2("e", "i*Iu", file_id, intent_flags);
- if(NULL == (file = H5I_object_verify(file_id, H5I_FILE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
-
/* If no intent flags were passed in, exit quietly */
- if(!intent_flags)
- HGOTO_DONE(SUCCEED)
-
- *intent_flags = H5F_get_intent(file);
-
- /* HDF5 uses some flags internally that users don't know about.
- * Simplify things for them so that they get one of H5F_ACC_RDWR
- * or H5F_ACC_RDONLY.
- */
- if(*intent_flags & H5F_ACC_RDWR)
- *intent_flags = H5F_ACC_RDWR;
- else
- *intent_flags = H5F_ACC_RDONLY;
-
-done:
- FUNC_LEAVE_API(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_get_intent
- *
- * Purpose: Quick and dirty routine to retrieve the file's 'intent' flags
- * (Mainly added to stop non-file routines from poking about in the
- * H5F_t data structure)
- *
- * Return: 'intent' on success/abort on failure (shouldn't fail)
- *
- * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
- * September 29, 2000
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-unsigned
-H5F_get_intent(const H5F_t *f)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_intent)
-
- HDassert(f);
-
- FUNC_LEAVE_NOAPI(f->intent)
-} /* end H5F_get_intent() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_get_extpath
- *
- * Purpose: Retrieve the file's 'extpath' flags
- * This is used by H5L_extern_traverse() to retrieve the main file's location
- * when searching the target file.
- *
- * Return: 'extpath' on success/abort on failure (shouldn't fail)
- *
- * Programmer: Vailin Choi, April 2, 2008
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-char *
-H5F_get_extpath(const H5F_t *f)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_extpath)
-
- HDassert(f);
-
- FUNC_LEAVE_NOAPI(f->extpath)
-} /* end H5F_get_extpath() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_sizeof_addr
- *
- * Purpose: Quick and dirty routine to retrieve the size of the file's size_t
- * (Mainly added to stop non-file routines from poking about in the
- * H5F_t data structure)
- *
- * Return: 'sizeof_addr' on success/abort on failure (shouldn't fail)
- *
- * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
- * September 29, 2000
- *
- * Modifications:
- *
- * Raymond Lu, Oct 14, 2001
- * Changed to generic property list.
- *
- *-------------------------------------------------------------------------
- */
-size_t
-H5F_sizeof_addr(const H5F_t *f)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_sizeof_addr)
-
- assert(f);
- assert(f->shared);
-
- FUNC_LEAVE_NOAPI(f->shared->sizeof_addr)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_sizeof_size
- *
- * Purpose: Quick and dirty routine to retrieve the size of the file's off_t
- * (Mainly added to stop non-file routines from poking about in the
- * H5F_t data structure)
- *
- * Return: 'sizeof_size' on success/abort on failure (shouldn't fail)
- *
- * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
- * September 29, 2000
- *
- *-------------------------------------------------------------------------
- */
-size_t
-H5F_sizeof_size(const H5F_t *f)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_sizeof_size)
-
- assert(f);
- assert(f->shared);
-
- FUNC_LEAVE_NOAPI(f->shared->sizeof_size)
-} /* H5F_sizeof_size() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_sym_leaf_k
- *
- * Purpose: Replaced a macro to retrieve the symbol table leaf size,
- * now that the generic properties are being used to store
- * the values.
- *
- * Return: Success: Non-negative, and the symbol table leaf size is
- * returned.
- *
- * Failure: Negative (should not happen)
- *
- * Programmer: Raymond Lu
- * slu@ncsa.uiuc.edu
- * Oct 14 2001
- *
- *-------------------------------------------------------------------------
- */
-unsigned
-H5F_sym_leaf_k(const H5F_t *f)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_sym_leaf_k)
-
- assert(f);
- assert(f->shared);
-
- FUNC_LEAVE_NOAPI(f->shared->sym_leaf_k)
-} /* end H5F_sym_leaf_k() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_Kvalue
- *
- * Purpose: Replaced a macro to retrieve a B-tree key value for a certain
- * type, now that the generic properties are being used to store
- * the B-tree values.
- *
- * Return: Success: Non-negative, and the B-tree key value is
- * returned.
- *
- * Failure: Negative (should not happen)
- *
- * Programmer: Raymond Lu
- * slu@ncsa.uiuc.edu
- * Oct 14 2001
- *
- *-------------------------------------------------------------------------
- */
-unsigned
-H5F_Kvalue(const H5F_t *f, const H5B_class_t *type)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_Kvalue)
-
- assert(f);
- assert(f->shared);
- assert(type);
-
- FUNC_LEAVE_NOAPI(f->shared->btree_k[type->id])
-} /* end H5F_Kvalue() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_rdcc_nelmts
- *
- * Purpose: Replaced a macro to retrieve the raw data cache number of elments,
- * now that the generic properties are being used to store
- * the values.
- *
- * Return: Success: Non-negative, and the raw data cache number of
- * of elemnts is returned.
- *
- * Failure: Negative (should not happen)
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Jun 1 2004
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-size_t
-H5F_rdcc_nelmts(const H5F_t *f)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_rdcc_nelmts)
-
- assert(f);
- assert(f->shared);
+ if(intent_flags) {
+ H5F_t * file; /* Pointer to file structure */
- FUNC_LEAVE_NOAPI(f->shared->rdcc_nelmts)
-} /* end H5F_rdcc_nelmts() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_rdcc_nbytes
- *
- * Purpose: Replaced a macro to retrieve the raw data cache number of bytes,
- * now that the generic properties are being used to store
- * the values.
- *
- * Return: Success: Non-negative, and the raw data cache number of
- * of bytes is returned.
- *
- * Failure: Negative (should not happen)
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Jun 1 2004
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-size_t
-H5F_rdcc_nbytes(const H5F_t *f)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_rdcc_nbytes)
-
- assert(f);
- assert(f->shared);
-
- FUNC_LEAVE_NOAPI(f->shared->rdcc_nbytes)
-} /* end H5F_rdcc_nbytes() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_rdcc_w0
- *
- * Purpose: Replaced a macro to retrieve the raw data cache 'w0' value
- * now that the generic properties are being used to store
- * the values.
- *
- * Return: Success: Non-negative, and the raw data cache 'w0' value
- * is returned.
- *
- * Failure: Negative (should not happen)
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Jun 2 2004
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-double
-H5F_rdcc_w0(const H5F_t *f)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_rdcc_w0)
-
- assert(f);
- assert(f->shared);
-
- FUNC_LEAVE_NOAPI(f->shared->rdcc_w0)
-} /* end H5F_rdcc_w0() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_has_feature
- *
- * Purpose: Check if a file has a particular feature enabled
- *
- * Return: Success: Non-negative - TRUE or FALSE
- * Failure: Negative (should not happen)
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * May 31 2004
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-hbool_t
-H5F_has_feature(const H5F_t *f, unsigned feature)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_has_feature)
-
- assert(f);
- assert(f->shared);
-
- FUNC_LEAVE_NOAPI((hbool_t)(f->shared->lf->feature_flags&feature))
-} /* end H5F_has_feature() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_get_driver_id
- *
- * Purpose: Quick and dirty routine to retrieve the file's 'driver_id' value
- * (Mainly added to stop non-file routines from poking about in the
- * H5F_t data structure)
- *
- * Return: 'driver_id' on success/abort on failure (shouldn't fail)
- *
- * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
- * October 10, 2000
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-hid_t
-H5F_get_driver_id(const H5F_t *f)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_driver_id)
-
- assert(f);
- assert(f->shared);
- assert(f->shared->lf);
-
- FUNC_LEAVE_NOAPI(f->shared->lf->driver_id)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_get_fileno
- *
- * Purpose: Quick and dirty routine to retrieve the file's 'fileno' value
- * (Mainly added to stop non-file routines from poking about in the
- * H5F_t data structure)
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
- * March 27, 2002
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5F_get_fileno(const H5F_t *f, unsigned long *filenum)
-{
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI(H5F_get_fileno, FAIL)
-
- HDassert(f);
- HDassert(f->shared);
- HDassert(f->shared->lf);
- HDassert(filenum);
+ /* Get the internal file structure */
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
- /* Retrieve the file's serial number */
- if(H5FD_get_fileno(f->shared->lf, filenum) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "can't retrieve fileno")
+ /* HDF5 uses some flags internally that users don't know about.
+ * Simplify things for them so that they only get either H5F_ACC_RDWR
+ * or H5F_ACC_RDONLY.
+ */
+ if(H5F_INTENT(file) & H5F_ACC_RDWR)
+ *intent_flags = H5F_ACC_RDWR;
+ else
+ *intent_flags = H5F_ACC_RDONLY;
+ } /* end if */
done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5F_get_fileno() */
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Fget_intent() */
/*-------------------------------------------------------------------------
@@ -2510,7 +2056,7 @@ done:
*-------------------------------------------------------------------------
*/
hid_t
-H5F_get_id(H5F_t *file)
+H5F_get_id(H5F_t *file, hbool_t app_ref)
{
hid_t ret_value;
@@ -2520,11 +2066,11 @@ H5F_get_id(H5F_t *file)
if(file->file_id == -1) {
/* Get an atom for the file */
- if((file->file_id = H5I_register(H5I_FILE, file)) < 0)
+ if((file->file_id = H5I_register(H5I_FILE, file, app_ref)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file")
} else {
/* Increment reference count on atom. */
- if(H5I_inc_ref(file->file_id) < 0)
+ if(H5I_inc_ref(file->file_id, app_ref) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed")
} /* end else */
@@ -2536,354 +2082,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5F_get_base_addr
- *
- * Purpose: Quick and dirty routine to retrieve the file's 'base_addr' value
- * (Mainly added to stop non-file routines from poking about in the
- * H5F_t data structure)
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Raymond Lu <slu@ncsa.uiuc.edu>
- * December 20, 2002
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-haddr_t
-H5F_get_base_addr(const H5F_t *f)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_base_addr)
-
- assert(f);
- assert(f->shared);
-
- FUNC_LEAVE_NOAPI(f->shared->base_addr)
-} /* end H5F_get_base_addr() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_get_eoa
- *
- * Purpose: Quick and dirty routine to retrieve the file's 'eoa' value
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
- * June 1, 2004
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-haddr_t
-H5F_get_eoa(const H5F_t *f)
-{
- haddr_t ret_value;
-
- FUNC_ENTER_NOAPI(H5F_get_eoa, HADDR_UNDEF)
-
- assert(f);
- assert(f->shared);
-
- /* Dispatch to driver */
- if (HADDR_UNDEF==(ret_value=H5FD_get_eoa(f->shared->lf, H5FD_MEM_DEFAULT)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "driver get_eoa request failed")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5F_get_eoa() */
-
-#ifdef H5_HAVE_PARALLEL
-
-/*-------------------------------------------------------------------------
- * Function: H5F_mpi_get_rank
- *
- * Purpose: Retrieves the rank of an MPI process.
- *
- * Return: Success: The rank (non-negative)
- *
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * Friday, January 30, 2004
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-int
-H5F_mpi_get_rank(const H5F_t *f)
-{
- int ret_value;
-
- FUNC_ENTER_NOAPI(H5F_mpi_get_rank, FAIL)
-
- assert(f && f->shared);
-
- /* Dispatch to driver */
- if ((ret_value=H5FD_mpi_get_rank(f->shared->lf)) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "driver get_rank request failed")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5F_mpi_get_rank() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_mpi_get_comm
- *
- * Purpose: Retrieves the file's communicator
- *
- * Return: Success: The communicator (non-negative)
- *
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * Friday, January 30, 2004
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-MPI_Comm
-H5F_mpi_get_comm(const H5F_t *f)
-{
- MPI_Comm ret_value;
-
- FUNC_ENTER_NOAPI(H5F_mpi_get_comm, MPI_COMM_NULL)
-
- assert(f && f->shared);
-
- /* Dispatch to driver */
- if ((ret_value=H5FD_mpi_get_comm(f->shared->lf))==MPI_COMM_NULL)
- HGOTO_ERROR(H5E_VFL, H5E_CANTGET, MPI_COMM_NULL, "driver get_comm request failed")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5F_mpi_get_comm() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_mpi_get_size
- *
- * Purpose: Retrieves the size of an MPI process.
- *
- * Return: Success: The size (positive)
- *
- * Failure: Negative
- *
- * Programmer: John Mainzer
- * Friday, May 6, 2005
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-int
-H5F_mpi_get_size(const H5F_t *f)
-{
- int ret_value;
-
- FUNC_ENTER_NOAPI(H5F_mpi_get_size, FAIL)
-
- assert(f && f->shared);
-
- /* Dispatch to driver */
- if ((ret_value=H5FD_mpi_get_size(f->shared->lf)) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "driver get_size request failed")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5F_mpi_get_size() */
-#endif /* H5_HAVE_PARALLEL */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_grp_btree_shared
- *
- * Purpose: Replaced a macro to retrieve the shared B-tree node info
- * now that the generic properties are being used to store
- * the values.
- *
- * Return: Success: Non-void, and the shared B-tree node info
- * is returned.
- *
- * Failure: void (should not happen)
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Jul 5 2004
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-H5RC_t *
-H5F_grp_btree_shared(const H5F_t *f)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_grp_btree_shared)
-
- assert(f);
- assert(f->shared);
-
- FUNC_LEAVE_NOAPI(f->shared->grp_btree_shared)
-} /* end H5F_grp_btree_shared() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_sieve_buf_size
- *
- * Purpose: Replaced a macro to retrieve the dataset sieve buffer size
- * now that the generic properties are being used to store
- * the values.
- *
- * Return: Success: Non-void, and the dataset sieve buffer size
- * is returned.
- *
- * Failure: void (should not happen)
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Jul 8 2005
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-size_t
-H5F_sieve_buf_size(const H5F_t *f)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_sieve_buf_size)
-
- assert(f);
- assert(f->shared);
-
- FUNC_LEAVE_NOAPI(f->shared->sieve_buf_size)
-} /* end H5F_sieve_buf_size() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_gc_ref
- *
- * Purpose: Replaced a macro to retrieve the "garbage collect
- * references flag" now that the generic properties are being used
- * to store the values.
- *
- * Return: Success: The "garbage collect references flag"
- * is returned.
- *
- * Failure: (should not happen)
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Jul 8 2005
- *
- *-------------------------------------------------------------------------
- */
-unsigned
-H5F_gc_ref(const H5F_t *f)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_gc_ref)
-
- HDassert(f);
- HDassert(f->shared);
-
- FUNC_LEAVE_NOAPI(f->shared->gc_ref)
-} /* end H5F_gc_ref() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_get_fcpl
- *
- * Purpose: Retrieve the value of a file's FCPL.
- *
- * Return: Success: The FCPL for the file.
- *
- * Failure: ? (should not happen)
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * May 25 2005
- *
- *-------------------------------------------------------------------------
- */
-hid_t
-H5F_get_fcpl(const H5F_t *f)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_fcpl)
-
- assert(f);
- assert(f->shared);
-
- FUNC_LEAVE_NOAPI(f->shared->fcpl_id)
-} /* end H5F_get_fcpl() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_use_latest_format
- *
- * Purpose: Retrieve the 'use the latest version of the format' flag for
- * the file.
- *
- * Return: Success: Non-negative, the 'use the latest format' flag
- *
- * Failure: (can't happen)
- *
- * Programmer: Quincey Koziol
- * koziol@hdfgroup.org
- * Oct 2 2006
- *
- *-------------------------------------------------------------------------
- */
-hbool_t
-H5F_use_latest_format(const H5F_t *f)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_use_latest_format)
-
- HDassert(f);
- HDassert(f->shared);
-
- FUNC_LEAVE_NOAPI(f->shared->latest_format)
-} /* end H5F_use_latest_format() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_get_fc_degree
- *
- * Purpose: Retrieve the 'file close degree' for the file.
- *
- * Return: Success: Non-negative, the 'file close degree'
- *
- * Failure: (can't happen)
- *
- * Programmer: Quincey Koziol
- * koziol@hdfgroup.org
- * Mar 5 2007
- *
- *-------------------------------------------------------------------------
- */
-H5F_close_degree_t
-H5F_get_fc_degree(const H5F_t *f)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_fc_degree)
-
- HDassert(f);
- HDassert(f->shared);
-
- FUNC_LEAVE_NOAPI(f->shared->fc_degree)
-} /* end H5F_get_fc_degree() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5F_incr_nopen_objs
*
* Purpose: Increment the number of open objects for a file.
@@ -2938,145 +2136,157 @@ H5F_decr_nopen_objs(H5F_t *f)
/*-------------------------------------------------------------------------
- * Function: H5F_store_msg_crt_idx
+ * Function: H5F_build_actual_name
*
- * Purpose: Retrieve the 'store message creation index' flag for the file.
+ * Purpose: Retrieve the name of a file, after following symlinks, etc.
*
- * Return: Success: Non-negative, the 'store message creation index' flag
+ * Note: Currently only working for "POSIX I/O compatible" VFDs
*
- * Failure: (can't happen)
+ * Return: Success: 0
+ * Failure: -1
*
* Programmer: Quincey Koziol
- * koziol@hdfgroup.org
- * Mar 6 2007
+ * November 25, 2009
*
*-------------------------------------------------------------------------
*/
-hbool_t
-H5F_store_msg_crt_idx(const H5F_t *f)
+static herr_t
+H5F_build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, const char *name,
+ char **actual_name/*out*/)
{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_store_msg_crt_idx)
+ hid_t new_fapl_id = -1; /* ID for duplicated FAPL */
+ herr_t ret_value = SUCCEED; /* Return value */
+ FUNC_ENTER_NOAPI_NOINIT(H5F_build_actual_name)
+
+ /* Sanity check */
HDassert(f);
- HDassert(f->shared);
+ HDassert(fapl);
+ HDassert(name);
+ HDassert(actual_name);
+
+ /* Clear actual name pointer to begin with */
+ *actual_name = NULL;
+
+/* Assume that if the OS can't create symlinks, that we don't need to worry
+ * about resolving them either. -QAK
+ */
+#ifdef H5_HAVE_SYMLINK
+ /* Check for POSIX I/O compatible file handle */
+ if(H5F_HAS_FEATURE(f, H5FD_FEAT_POSIX_COMPAT_HANDLE)) {
+ h5_stat_t lst; /* Stat info from lstat() call */
+
+ /* Call lstat() on the file's name */
+ if(HDlstat(name, &lst) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve stat info for file")
+
+ /* Check for symbolic link */
+ if(S_IFLNK == (lst.st_mode & S_IFMT)) {
+ H5P_genplist_t *new_fapl; /* Duplicated FAPL */
+ int *fd; /* POSIX I/O file descriptor */
+ h5_stat_t st; /* Stat info from stat() call */
+ h5_stat_t fst; /* Stat info from fstat() call */
+ char realname[PATH_MAX]; /* Fully resolved path name of file */
+ hbool_t want_posix_fd; /* Flag for retrieving file descriptor from VFD */
+
+ /* Perform a sanity check that the file or link wasn't switched
+ * between when we opened it and when we called lstat(). This is
+ * according to the security best practices for lstat() documented
+ * here: https://www.securecoding.cert.org/confluence/display/seccode/POS35-C.+Avoid+race+conditions+while+checking+for+the+existence+of+a+symbolic+link
+ */
- FUNC_LEAVE_NOAPI(f->shared->store_msg_crt_idx)
-} /* end H5F_store_msg_crt_idx() */
+ /* Copy the FAPL object to modify */
+ if((new_fapl_id = H5P_copy_plist(fapl, FALSE)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy file access property list")
+ if(NULL == (new_fapl = (H5P_genplist_t *)H5I_object(new_fapl_id)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "can't get property list")
-
-/*-------------------------------------------------------------------------
- * Function: H5F_block_read
- *
- * Purpose: Reads some data from a file/server/etc into a buffer.
- * The data is contiguous. The address is relative to the base
- * address for the file.
- *
- * Errors:
- * IO READERROR Low-level read failed.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Jul 10 1997
- *
- * Modifications:
- * Albert Cheng, 1998-06-02
- * Added XFER_MODE argument
- *
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
- *
- * Robb Matzke, 1999-08-02
- * Modified to use the virtual file layer. The data transfer
- * property list is passed in by object ID since that's how the
- * virtual file layer needs it.
- *-------------------------------------------------------------------------
- */
-herr_t
-H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, hid_t dxpl_id,
- void *buf/*out*/)
-{
- haddr_t abs_addr;
- herr_t ret_value=SUCCEED; /* Return value */
+ /* Set the character encoding on the new property list */
+ want_posix_fd = TRUE;
+ if(H5P_set(new_fapl, H5F_ACS_WANT_POSIX_FD_NAME, &want_posix_fd) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set character encoding")
- FUNC_ENTER_NOAPI(H5F_block_read, FAIL)
+ /* Retrieve the file handle */
+ if(H5F_get_vfd_handle(f, new_fapl_id, (void **)&fd) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve POSIX file descriptor")
- assert (f);
- assert (f->shared);
- assert(size<SIZET_MAX);
- assert (buf);
+ /* Stat the filename we're resolving */
+ if(HDstat(name, &st) < 0)
+ HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to stat file")
- /* convert the relative address to an absolute address */
- abs_addr = f->shared->base_addr + addr;
+ /* Stat the file we opened */
+ if(HDfstat(*fd, &fst) < 0)
+ HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to fstat file")
- /* Read the data */
- if(H5FD_read(f->shared->lf, type, dxpl_id, abs_addr, size, buf) < 0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed")
+ /* Verify that the files are really the same */
+ if(st.st_mode != fst.st_mode || st.st_ino != fst.st_ino || st.st_dev != fst.st_dev)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "files' st_ino or st_dev fields changed!")
+
+ /* Get the resolved path for the file name */
+ if(NULL == HDrealpath(name, realname))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve real path for file")
+
+ /* Duplicate the resolved path for the file name */
+ if(NULL == (*actual_name = (char *)H5MM_strdup(realname)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate real path")
+ } /* end if */
+ } /* end if */
+#endif /* H5_HAVE_SYMLINK */
+
+ /* Check if we've resolved the file's name */
+ if(NULL == *actual_name) {
+ /* Just duplicate the name used to open the file */
+ if(NULL == (*actual_name = (char *)H5MM_strdup(name)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate open name")
+ } /* end else */
done:
+ if(new_fapl_id > 0 && H5Pclose(new_fapl_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "can't close duplicated FAPL")
+
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* H5F_build_actual_name() */
/*-------------------------------------------------------------------------
- * Function: H5F_block_write
- *
- * Purpose: Writes some data from memory to a file/server/etc. The
- * data is contiguous. The address is relative to the base
- * address.
+ * Function: H5F_addr_encode_len
*
- * Errors:
- * IO WRITEERROR Low-level write failed.
- * IO WRITEERROR No write intent.
+ * Purpose: Encodes an address into the buffer pointed to by *PP and
+ * then increments the pointer to the first byte after the
+ * address. An undefined value is stored as all 1's.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: void
*
* Programmer: Robb Matzke
- * matzke@llnl.gov
- * Jul 10 1997
- *
- * Modifications:
- * Albert Cheng, 1998-06-02
- * Added XFER_MODE argument
- *
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
+ * Friday, November 7, 1997
*
- * Robb Matzke, 1999-08-02
- * Modified to use the virtual file layer. The data transfer
- * property list is passed in by object ID since that's how the
- * virtual file layer needs it.
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_block_write(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size,
- hid_t dxpl_id, const void *buf)
+void
+H5F_addr_encode_len(size_t addr_len, uint8_t **pp/*in,out*/, haddr_t addr)
{
- haddr_t abs_addr;
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5F_block_write, FAIL)
-
- assert (f);
- assert (f->shared);
- assert (size<SIZET_MAX);
- assert (buf);
+ unsigned u; /* Local index variable */
- if (0==(f->intent & H5F_ACC_RDWR))
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "no write intent")
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_addr_encode_len)
- /* Convert the relative address to an absolute address */
- abs_addr = f->shared->base_addr + addr;
+ HDassert(addr_len);
+ HDassert(pp && *pp);
- /* Write the data */
- if (H5FD_write(f->shared->lf, type, dxpl_id, abs_addr, size, buf))
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed")
+ if(H5F_addr_defined(addr)) {
+ for(u = 0; u < addr_len; u++) {
+ *(*pp)++ = (uint8_t)(addr & 0xff);
+ addr >>= 8;
+ } /* end for */
+ HDassert("overflow" && 0 == addr);
+ } /* end if */
+ else {
+ for(u = 0; u < addr_len; u++)
+ *(*pp)++ = 0xff;
+ } /* end else */
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5F_addr_encode_len() */
/*-------------------------------------------------------------------------
@@ -3091,35 +2301,24 @@ done:
* Programmer: Robb Matzke
* Friday, November 7, 1997
*
- * Modifications:
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
*-------------------------------------------------------------------------
*/
void
H5F_addr_encode(const H5F_t *f, uint8_t **pp/*in,out*/, haddr_t addr)
{
- unsigned u; /* Local index variable */
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_addr_encode)
HDassert(f);
- HDassert(pp && *pp);
- if(H5F_addr_defined(addr)) {
- for(u = 0; u < H5F_SIZEOF_ADDR(f); u++) {
- *(*pp)++ = (uint8_t)(addr & 0xff);
- addr >>= 8;
- } /* end for */
- assert("overflow" && 0 == addr);
- } /* end if */
- else {
- for(u = 0; u < H5F_SIZEOF_ADDR(f); u++)
- *(*pp)++ = 0xff;
- } /* end else */
+ H5F_addr_encode_len(H5F_SIZEOF_ADDR(f), pp, addr);
+
+ FUNC_LEAVE_NOAPI_VOID
} /* end H5F_addr_encode() */
/*-------------------------------------------------------------------------
- * Function: H5F_addr_decode
+ * Function: H5F_addr_decode_len
*
* Purpose: Decodes an address from the buffer pointed to by *PP and
* updates the pointer to point to the next byte after the
@@ -3133,40 +2332,88 @@ H5F_addr_encode(const H5F_t *f, uint8_t **pp/*in,out*/, haddr_t addr)
* Programmer: Robb Matzke
* Friday, November 7, 1997
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
void
-H5F_addr_decode(const H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/)
+H5F_addr_decode_len(size_t addr_len, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/)
{
- unsigned i;
- haddr_t tmp;
- uint8_t c;
- hbool_t all_zero = TRUE;
+ hbool_t all_zero = TRUE; /* True if address was all zeroes */
+ unsigned u; /* Local index variable */
- assert(f);
- assert(pp && *pp);
- assert(addr_p);
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_addr_decode_len)
+ HDassert(addr_len);
+ HDassert(pp && *pp);
+ HDassert(addr_p);
+
+ /* Reset value in destination */
*addr_p = 0;
- for (i=0; i<H5F_SIZEOF_ADDR(f); i++) {
+ /* Decode bytes from address */
+ for(u = 0; u < addr_len; u++) {
+ uint8_t c; /* Local decoded byte */
+
+ /* Get decoded byte (and advance pointer) */
c = *(*pp)++;
- if (c != 0xff)
+
+ /* Check for non-undefined address byte value */
+ if(c != 0xff)
all_zero = FALSE;
- if (i<sizeof(*addr_p)) {
- tmp = c;
- tmp <<= (i * 8); /*use tmp to get casting right */
+ if(u < sizeof(*addr_p)) {
+ haddr_t tmp = c; /* Local copy of address, for casting */
+
+ /* Shift decoded byte to correct position */
+ tmp <<= (u * 8); /*use tmp to get casting right */
+
+ /* Merge into already decoded bytes */
*addr_p |= tmp;
- } else if (!all_zero) {
- assert(0 == **pp); /*overflow */
- }
- }
- if (all_zero)
+ } /* end if */
+ else
+ if(!all_zero)
+ HDassert(0 == **pp); /*overflow */
+ } /* end for */
+
+ /* If 'all_zero' is still TRUE, the address was entirely composed of '0xff'
+ * bytes, which is the encoded form of 'HADDR_UNDEF', so set the destination
+ * to that value */
+ if(all_zero)
*addr_p = HADDR_UNDEF;
-}
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5F_addr_decode_len() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_addr_decode
+ *
+ * Purpose: Decodes an address from the buffer pointed to by *PP and
+ * updates the pointer to point to the next byte after the
+ * address.
+ *
+ * If the value read is all 1's then the address is returned
+ * with an undefined value.
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Friday, November 7, 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5F_addr_decode(const H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_addr_decode)
+
+ HDassert(f);
+
+ H5F_addr_decode_len(H5F_SIZEOF_ADDR(f), pp, addr_p);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5F_addr_decode() */
/*-------------------------------------------------------------------------
@@ -3186,20 +2433,23 @@ H5F_addr_decode(const H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*o
hssize_t
H5Fget_freespace(hid_t file_id)
{
- H5F_t *file=NULL; /* File object for file ID */
+ H5F_t *file; /* File object for file ID */
+ hsize_t tot_space; /* Amount of free space in the file */
hssize_t ret_value; /* Return value */
FUNC_ENTER_API(H5Fget_freespace, FAIL)
H5TRACE1("Hs", "i", file_id);
/* Check args */
- if(NULL == (file = H5I_object_verify(file_id, H5I_FILE)))
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
/* Go get the actual amount of free space in the file */
- if((ret_value = H5FD_get_freespace(file->shared->lf)) < 0)
+ if(H5MF_get_freespace(file, H5AC_ind_dxpl_id, &tot_space, NULL) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file")
+ ret_value = (hssize_t)tot_space;
+
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Fget_freespace() */
@@ -3226,20 +2476,20 @@ done:
herr_t
H5Fget_filesize(hid_t file_id, hsize_t *size)
{
- H5F_t *file=NULL; /* File object for file ID */
- herr_t ret_value = SUCCEED; /* Return value */
- haddr_t eof;
+ H5F_t *file; /* File object for file ID */
+ haddr_t eof; /* End of file address */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Fget_filesize, FAIL)
H5TRACE2("e", "i*h", file_id, size);
/* Check args */
- if(NULL==(file=H5I_object_verify(file_id, H5I_FILE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
/* Go get the actual file size */
- if((eof = H5FDget_eof(file->shared->lf))==HADDR_UNDEF)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size")
+ if(HADDR_UNDEF == (eof = H5FDget_eof(file->shared->lf)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size")
*size = (hsize_t)eof;
@@ -3270,16 +2520,16 @@ herr_t
H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr)
{
H5F_t *file; /* File object for file ID */
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Fget_mdc_config, FAIL)
H5TRACE2("e", "i*x", file_id, config_ptr);
/* Check args */
- if(NULL == (file = H5I_object_verify(file_id, H5I_FILE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
if((NULL == config_ptr) || (config_ptr->version != H5AC__CURR_CACHE_CONFIG_VERSION))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Bad config_ptr")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Bad config_ptr")
/* Go get the resize configuration */
if(H5AC_get_cache_auto_resize_config(file->shared->cache, config_ptr) < 0)
@@ -3315,7 +2565,7 @@ H5Fset_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr)
H5TRACE2("e", "i*x", file_id, config_ptr);
/* Check args */
- if(NULL == (file = H5I_object_verify(file_id, H5I_FILE)))
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
/* set the resize configuration */
@@ -3353,10 +2603,11 @@ H5Fget_mdc_hit_rate(hid_t file_id, double *hit_rate_ptr)
H5TRACE2("e", "i*d", file_id, hit_rate_ptr);
/* Check args */
- if(NULL == (file = H5I_object_verify(file_id, H5I_FILE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+
if(NULL == hit_rate_ptr)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL hit rate pointer")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL hit rate pointer")
/* Go get the current hit rate */
if(H5AC_get_cache_hit_rate(file->shared->cache, hit_rate_ptr) < 0)
@@ -3397,7 +2648,7 @@ H5Fget_mdc_size(hid_t file_id, size_t *max_size_ptr, size_t *min_clean_size_ptr,
cur_size_ptr, cur_num_entries_ptr);
/* Check args */
- if(NULL == (file = H5I_object_verify(file_id, H5I_FILE)))
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
/* Go get the size data */
@@ -3443,7 +2694,7 @@ H5Freset_mdc_hit_rate_stats(hid_t file_id)
H5TRACE1("e", "i", file_id);
/* Check args */
- if(NULL == (file = H5I_object_verify(file_id, H5I_FILE)))
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
/* Reset the hit rate statistic */
@@ -3466,6 +2717,9 @@ done:
* If an error occurs then the buffer pointed to by `name' (NULL or non-NULL)
* is unchanged and the function returns a negative value.
*
+ * Note: This routine returns the name that was used to open the file,
+ * not the actual name after resolving symlinks, etc.
+ *
* Return: Success: The length of the file name
* Failure: Negative
*
@@ -3489,7 +2743,7 @@ H5Fget_name(hid_t obj_id, char *name/*out*/, size_t size)
* the top file in a mount hierarchy)
*/
if(H5I_get_type(obj_id) == H5I_FILE ) {
- if(NULL == (f = H5I_object(obj_id)))
+ if(NULL == (f = (H5F_t *)H5I_object(obj_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
} /* end if */
else {
@@ -3501,10 +2755,10 @@ H5Fget_name(hid_t obj_id, char *name/*out*/, size_t size)
f = loc.oloc->file;
} /* end else */
- len = HDstrlen(f->name);
+ len = HDstrlen(H5F_OPEN_NAME(f));
if(name) {
- HDstrncpy(name, f->name, MIN(len+1,size));
+ HDstrncpy(name, H5F_OPEN_NAME(f), MIN(len + 1,size));
if(len >= size)
name[size-1]='\0';
} /* end if */
@@ -3518,26 +2772,29 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5Fget_info
- * 1. Get storage size for superblock extension if there is one
+ * Function: H5Fget_info2
+ *
+ * Purpose: Gets general information about the file, including:
+ * 1. Get storage size for superblock extension if there is one.
* 2. Get the amount of btree and heap storage for entries
* in the SOHM table if there is one.
- * Consider success when there is no superblock extension and/or SOHM table
+ * 3. The amount of free space tracked in the file.
*
* Return: Success: non-negative on success
* Failure: Negative
*
* Programmer: Vailin Choi
* July 11, 2007
+ *
*-------------------------------------------------------------------------
*/
herr_t
-H5Fget_info(hid_t obj_id, H5F_info_t *finfo)
+H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo)
{
H5F_t *f; /* Top file in mount hierarchy */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API(H5Fget_info, FAIL)
+ FUNC_ENTER_API(H5Fget_info2, FAIL)
H5TRACE2("e", "i*x", obj_id, finfo);
/* Check args */
@@ -3549,7 +2806,7 @@ H5Fget_info(hid_t obj_id, H5F_info_t *finfo)
* the top file in a mount hierarchy)
*/
if(H5I_get_type(obj_id) == H5I_FILE ) {
- if(NULL == (f = H5I_object(obj_id)))
+ if(NULL == (f = (H5F_t *)H5I_object(obj_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
} /* end if */
else {
@@ -3563,19 +2820,67 @@ H5Fget_info(hid_t obj_id, H5F_info_t *finfo)
HDassert(f->shared);
/* Reset file info struct */
- HDmemset(finfo, 0, sizeof(H5F_info_t));
+ HDmemset(finfo, 0, sizeof(*finfo));
- /* Check for superblock extension info */
- if(H5F_addr_defined(f->shared->extension_addr))
- if(H5F_super_ext_size(f, H5AC_ind_dxpl_id, &finfo->super_ext_size) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve superblock extension size")
+ /* Get the size of the superblock and any superblock extensions */
+ if(H5F_super_size(f, H5AC_ind_dxpl_id, &finfo->super.super_size, &finfo->super.super_ext_size) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve superblock sizes")
+
+ /* Get the size of any persistent free space */
+ if(H5MF_get_freespace(f, H5AC_ind_dxpl_id, &finfo->free.tot_space, &finfo->free.meta_size) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve free space information")
/* Check for SOHM info */
if(H5F_addr_defined(f->shared->sohm_addr))
- if(H5SM_ih_size(f, H5AC_ind_dxpl_id, finfo) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve SOHM btree & heap storage info")
+ if(H5SM_ih_size(f, H5AC_ind_dxpl_id, &finfo->sohm.hdr_size, &finfo->sohm.msgs_info) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve SOHM index & heap storage info")
+
+ /* Set version # fields */
+ finfo->super.version = f->shared->sblock->super_vers;
+ finfo->sohm.version = f->shared->sohm_vers;
+ finfo->free.version = HDF5_FREESPACE_VERSION;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Fget_info2() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Fget_free_sections
+ *
+ * Purpose: To get free-space section information for free-space manager with
+ * TYPE that is associated with file FILE_ID.
+ * If SECT_INFO is null, this routine returns the total # of free-space
+ * sections.
+ *
+ * Return: Success: non-negative, the total # of free space sections
+ * Failure: negative
+ *
+ * Programmer: Vailin Choi; July 1st, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects,
+ H5F_sect_info_t *sect_info/*out*/)
+{
+ H5F_t *file; /* Top file in mount hierarchy */
+ ssize_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Fget_free_sections, FAIL)
+ H5TRACE4("Zs", "iFmzx", file_id, type, nsects, sect_info);
+
+ /* Check args */
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+ if(sect_info && nsects == 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "nsects must be > 0")
+
+ /* Go get the free-space section information in the file */
+ if((ret_value = H5MF_get_free_sections(file, H5AC_ind_dxpl_id, type, nsects, sect_info)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Fget_info() */
+} /* end H5Fget_free_sections() */
diff --git a/src/H5FA.c b/src/H5FA.c
new file mode 100644
index 0000000..20a63af
--- /dev/null
+++ b/src/H5FA.c
@@ -0,0 +1,740 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5FA.c
+ * April 2009
+ * Vailin Choi <vchoi@hdfgroup.org>
+ *
+ * Purpose: Implements a Fixed Array for storing elements
+ * of datasets with fixed dimensions
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/**********************/
+/* Module Declaration */
+/**********************/
+
+#define H5FA_MODULE
+
+/***********************/
+/* Other Packages Used */
+/***********************/
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FApkg.h" /* Fixed Arrays */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5Vprivate.h" /* Vector functions */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Fixed array client ID to class mapping */
+
+/* Remember to add client ID to H5FA_cls_id_t in H5FAprivate.h when adding a new
+ * client class..
+ */
+extern const H5FA_class_t H5FA_CLS_TEST[1];
+
+const H5FA_class_t *const H5FA_client_class_g[] = {
+ H5FA_CLS_TEST, /* 0 - H5FA_TEST_ID */
+};
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5FA_t struct */
+H5FL_DEFINE_STATIC(H5FA_t);
+
+/* Declare a PQ free list to manage the element */
+H5FL_BLK_DEFINE(native_elmt);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA_create
+ *
+ * Purpose: Creates a new fixed array (header) in the file.
+ *
+ * Return: Pointer to fixed array wrapper on success
+ * NULL on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+H5FA_t *, NULL, NULL,
+H5FA_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam, void *ctx_udata))
+
+ /* Local variables */
+ H5FA_t *fa = NULL; /* Pointer to new fixed array */
+ H5FA_hdr_t *hdr = NULL; /* The fixed array header information */
+ haddr_t fa_addr; /* Fixed Array header address */
+
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* H5FA_DEBUG */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(cparam);
+
+ /* H5FA interface sanity check */
+ HDcompile_assert(H5FA_NUM_CLS_ID == NELMTS(H5FA_client_class_g));
+
+ /* Create fixed array header */
+ if(HADDR_UNDEF == (fa_addr = H5FA__hdr_create(f, dxpl_id, cparam, ctx_udata)))
+ H5E_THROW(H5E_CANTINIT, "can't create fixed array header")
+
+ /* Allocate fixed array wrapper */
+ if(NULL == (fa = H5FL_MALLOC(H5FA_t)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array info")
+
+ /* Lock the array header into memory */
+ if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, ctx_udata, H5AC_WRITE)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header")
+
+ /* Point fixed array wrapper at header and bump it's ref count */
+ fa->hdr = hdr;
+ if(H5FA__hdr_incr(fa->hdr) < 0)
+ H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header")
+
+ /* Increment # of files using this array header */
+ if(H5FA__hdr_fuse_incr(fa->hdr) < 0)
+ H5E_THROW(H5E_CANTINC, "can't increment file reference count on shared array header")
+
+ /* Set file pointer for this array open context */
+ fa->f = f;
+
+ /* Set the return value */
+ ret_value = fa;
+
+CATCH
+
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array header")
+ if(!ret_value)
+ if(fa && H5FA_close(fa, dxpl_id) < 0)
+ H5E_THROW(H5E_CLOSEERROR, "unable to close fixed array")
+
+END_FUNC(PRIV) /* end H5FA_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA_open
+ *
+ * Purpose: Opens an existing fixed array in the file.
+ *
+ * Return: Pointer to array wrapper on success
+ * NULL on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+H5FA_t *, NULL, NULL,
+H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, void *ctx_udata))
+
+ /* Local variables */
+ H5FA_t *fa = NULL; /* Pointer to new fixed array wrapper */
+ H5FA_hdr_t *hdr = NULL; /* The fixed array header information */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(H5F_addr_defined(fa_addr));
+
+ /* Load the array header into memory */
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: fa_addr = %a\n", FUNC, fa_addr);
+#endif /* H5FA_DEBUG */
+ if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, ctx_udata, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header, address = %llu", (unsigned long long)fa_addr)
+
+ /* Check for pending array deletion */
+ if(hdr->pending_delete)
+ H5E_THROW(H5E_CANTOPENOBJ, "can't open fixed array pending deletion")
+
+ /* Create fixed array info */
+ if(NULL == (fa = H5FL_MALLOC(H5FA_t)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array info")
+
+ /* Point fixed array wrapper at header */
+ fa->hdr = hdr;
+ if(H5FA__hdr_incr(fa->hdr) < 0)
+ H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header")
+
+ /* Increment # of files using this array header */
+ if(H5FA__hdr_fuse_incr(fa->hdr) < 0)
+ H5E_THROW(H5E_CANTINC, "can't increment file reference count on shared array header")
+
+ /* Set file pointer for this array open context */
+ fa->f = f;
+
+ /* Set the return value */
+ ret_value = fa;
+
+CATCH
+
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array header")
+ if(!ret_value)
+ if(fa && H5FA_close(fa, dxpl_id) < 0)
+ H5E_THROW(H5E_CLOSEERROR, "unable to close fixed array")
+
+END_FUNC(PRIV) /* end H5FA_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA_get_nelmts
+ *
+ * Purpose: Query the current number of elements in array
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, NOERR,
+herr_t, SUCCEED, -,
+H5FA_get_nelmts(const H5FA_t *fa, hsize_t *nelmts))
+
+ /* Local variables */
+
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* H5FA_DEBUG */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(fa);
+ HDassert(nelmts);
+
+ /* Retrieve the current number of elements in the fixed array */
+ *nelmts = fa->hdr->stats.nelmts;
+
+END_FUNC(PRIV) /* end H5FA_get_nelmts() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA_get_addr
+ *
+ * Purpose: Query the address of the array
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, NOERR,
+herr_t, SUCCEED, -,
+H5FA_get_addr(const H5FA_t *fa, haddr_t *addr))
+
+ /* Local variables */
+
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* H5FA_DEBUG */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(fa);
+ HDassert(fa->hdr);
+ HDassert(addr);
+
+ /* Retrieve the address of the fixed array's header */
+ *addr = fa->hdr->addr;
+
+END_FUNC(PRIV) /* end H5FA_get_addr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA_set
+ *
+ * Purpose: Set an element of a fixed array
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA_set(const H5FA_t *fa, hid_t dxpl_id, hsize_t idx, const void *elmt))
+
+ /* Local variables */
+ H5FA_hdr_t *hdr = fa->hdr; /* Header for fixed array */
+ H5FA_dblock_t *dblock = NULL; /* Pointer to fixed array Data block */
+ H5FA_dblk_page_t *dblk_page = NULL; /* Pointer to fixed array Data block page */
+ unsigned dblock_cache_flags = H5AC__NO_FLAGS_SET; /* Flags to unprotecting fixed array Data block */
+ unsigned dblk_page_cache_flags = H5AC__NO_FLAGS_SET; /* Flags to unprotecting FIxed Array Data block page */
+ hbool_t hdr_dirty = FALSE; /* Whether header information changed */
+
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: Called\n", FUNC);
+HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx);
+#endif /* H5FA_DEBUG */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(fa);
+ HDassert(fa->hdr);
+
+ /* Set the shared array header's file context for this operation */
+ hdr->f = fa->f;
+
+ /* Check if we need to create the fixed array data block */
+ if(!H5F_addr_defined(hdr->dblk_addr)) {
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: fixed array data block address not defined!\n", FUNC, idx);
+#endif /* H5FA_DEBUG */
+ /* Create the data block */
+ hdr->dblk_addr = H5FA__dblock_create(hdr, dxpl_id, &hdr_dirty, hdr->cparam.nelmts);
+ if(!H5F_addr_defined(hdr->dblk_addr))
+ H5E_THROW(H5E_CANTCREATE, "unable to create fixed array data block")
+ } /* end if */
+
+ HDassert(idx < hdr->cparam.nelmts);
+
+ /* Protect data block */
+ if(NULL == (dblock = H5FA__dblock_protect(hdr, dxpl_id, hdr->dblk_addr, hdr->stats.nelmts, H5AC_WRITE)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block, address = %llu", (unsigned long long)hdr->dblk_addr)
+
+ /* Check for paging data block */
+ if(!dblock->npages) {
+ /* Set element in data block */
+ HDmemcpy(((uint8_t *)dblock->elmts) + (hdr->cparam.cls->nat_elmt_size * idx), elmt, hdr->cparam.cls->nat_elmt_size);
+ dblock_cache_flags |= H5AC__DIRTIED_FLAG;
+ } /* end if */
+ else { /* paging */
+ size_t page_idx; /* Index of page within data block */
+ size_t dblk_page_nelmts; /* # of elements in a data block page */
+ size_t elmt_idx; /* Element index within the page */
+ haddr_t dblk_page_addr; /* Address of data block page */
+
+ /* Compute the page & element index */
+ page_idx = (size_t)(idx / dblock->dblk_page_nelmts);
+ elmt_idx = (size_t)(idx % dblock->dblk_page_nelmts);
+
+ /* Get the address of the data block page */
+ dblk_page_addr = dblock->addr + H5FA_DBLOCK_PREFIX_SIZE(dblock) +
+ ((hsize_t)page_idx * dblock->dblk_page_size);
+
+ /* Check for using last page, to set the number of elements on the page */
+ if((page_idx + 1) == dblock->npages)
+ dblk_page_nelmts = dblock->last_page_nelmts;
+ else
+ dblk_page_nelmts = dblock->dblk_page_nelmts;
+
+ /* Check if the page has been created yet */
+ if(!H5V_bit_get(dblock->dblk_page_init, page_idx)) {
+ /* Create the data block page */
+ if(H5FA__dblk_page_create(hdr, dxpl_id, dblk_page_addr, dblk_page_nelmts) < 0)
+ H5E_THROW(H5E_CANTCREATE, "unable to create data block page")
+
+ /* Mark data block page as initialized in data block */
+ H5V_bit_set(dblock->dblk_page_init, page_idx, TRUE);
+ dblock_cache_flags |= H5AC__DIRTIED_FLAG;
+ } /* end if */
+
+ /* Protect the data block page */
+ if(NULL == (dblk_page = H5FA__dblk_page_protect(hdr, dxpl_id, dblk_page_addr, dblk_page_nelmts, H5AC_WRITE)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block page, address = %llu", (unsigned long long)dblk_page_addr)
+
+ /* Set the element in the data block page */
+ HDmemcpy(((uint8_t *)dblk_page->elmts) + (hdr->cparam.cls->nat_elmt_size * elmt_idx), elmt, hdr->cparam.cls->nat_elmt_size);
+ dblk_page_cache_flags |= H5AC__DIRTIED_FLAG;
+ } /* end else */
+
+CATCH
+ /* Check for header modified */
+ if(hdr_dirty)
+ if(H5FA__hdr_modified(hdr) < 0)
+ H5E_THROW(H5E_CANTMARKDIRTY, "unable to mark fixed array header as modified")
+
+ /* Release resources */
+ if(dblock && H5FA__dblock_unprotect(dblock, dxpl_id, dblock_cache_flags) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array data block")
+ if(dblk_page && H5FA__dblk_page_unprotect(dblk_page, dxpl_id, dblk_page_cache_flags) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array data block page")
+
+END_FUNC(PRIV) /* end H5FA_set() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA_get
+ *
+ * Purpose: Get an element of a fixed array
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA_get(const H5FA_t *fa, hid_t dxpl_id, hsize_t idx, void *elmt))
+
+ /* Local variables */
+ H5FA_hdr_t *hdr = fa->hdr; /* Header for FA */
+ H5FA_dblock_t *dblock = NULL; /* Pointer to data block for FA */
+ H5FA_dblk_page_t *dblk_page = NULL; /* Pointer to data block page for FA */
+
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: Called\n", FUNC);
+HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx);
+#endif /* H5FA_DEBUG */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(fa);
+ HDassert(fa->hdr);
+
+ /* Set the shared array header's file context for this operation */
+ hdr->f = fa->f;
+
+ /* Check if the fixed array data block has been allocated on disk yet */
+ if(!H5F_addr_defined(hdr->dblk_addr)) {
+ /* 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")
+ } /* end if */
+ else {
+ /* Get the data block */
+ HDassert(H5F_addr_defined(hdr->dblk_addr));
+ if(NULL == (dblock = H5FA__dblock_protect(hdr, dxpl_id, hdr->dblk_addr, hdr->stats.nelmts, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block, address = %llu", (unsigned long long)hdr->dblk_addr)
+
+ /* Check for paged data block */
+ if(!dblock->npages)
+ /* Retrieve element from data block */
+ HDmemcpy(elmt, ((uint8_t *)dblock->elmts) + (hdr->cparam.cls->nat_elmt_size * idx), hdr->cparam.cls->nat_elmt_size);
+ else { /* paging */
+ size_t page_idx; /* Index of page within data block */
+
+ /* Compute the page index */
+ page_idx = (size_t)(idx / dblock->dblk_page_nelmts);
+
+ /* Check if the page is defined yet */
+ if(!H5V_bit_get(dblock->dblk_page_init, page_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 { /* get the page */
+ size_t dblk_page_nelmts; /* # of elements in a data block page */
+ size_t elmt_idx; /* Element index within the page */
+ haddr_t dblk_page_addr; /* Address of data block page */
+
+ /* Compute the element index */
+ elmt_idx = (size_t)(idx % dblock->dblk_page_nelmts);
+
+ /* Compute the address of the data block */
+ dblk_page_addr = dblock->addr + H5FA_DBLOCK_PREFIX_SIZE(dblock) + ((hsize_t)page_idx * dblock->dblk_page_size);
+
+ /* Check for using last page, to set the number of elements on the page */
+ if((page_idx + 1) == dblock->npages)
+ dblk_page_nelmts = dblock->last_page_nelmts;
+ else
+ dblk_page_nelmts = dblock->dblk_page_nelmts;
+
+ /* Protect the data block page */
+ if(NULL == (dblk_page = H5FA__dblk_page_protect(hdr, dxpl_id, dblk_page_addr, dblk_page_nelmts, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block page, address = %llu", (unsigned long long)dblk_page_addr)
+
+ /* Retrieve element from data block */
+ HDmemcpy(elmt, ((uint8_t *)dblk_page->elmts) + (hdr->cparam.cls->nat_elmt_size * elmt_idx), hdr->cparam.cls->nat_elmt_size);
+ } /* end else */
+ } /* end else */
+ } /* end else */
+
+CATCH
+ if(dblock && H5FA__dblock_unprotect(dblock, dxpl_id, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array data block")
+ if(dblk_page && H5FA__dblk_page_unprotect(dblk_page, dxpl_id, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array data block page")
+
+END_FUNC(PRIV) /* end H5FA_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA_close
+ *
+ * Purpose: Close a fixed array
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA_close(H5FA_t *fa, hid_t dxpl_id))
+
+ /* Local variables */
+ hbool_t pending_delete = FALSE; /* Whether the array is pending deletion */
+ haddr_t fa_addr = HADDR_UNDEF; /* Address of array (for deletion) */
+
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* H5FA_DEBUG */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(fa);
+
+ /* Decrement file reference & check if this is the last open fixed array using the shared array header */
+ if(0 == H5FA__hdr_fuse_decr(fa->hdr)) {
+ /* Set the shared array header's file context for this operation */
+ fa->hdr->f = fa->f;
+
+ /* Shut down anything that can't be put in the header's 'flush' callback */
+
+ /* Check for pending array deletion */
+ if(fa->hdr->pending_delete) {
+ /* Set local info, so array deletion can occur after decrementing the
+ * header's ref count
+ */
+ pending_delete = TRUE;
+ fa_addr = fa->hdr->addr;
+ } /* end if */
+ } /* end if */
+
+ /* Check for pending array deletion */
+ if(pending_delete) {
+ H5FA_hdr_t *hdr; /* Another pointer to fixed array header */
+
+#ifndef NDEBUG
+{
+ unsigned hdr_status = 0; /* Header's status in the metadata cache */
+
+ /* Check the header's status in the metadata cache */
+ if(H5AC_get_entry_status(fa->f, fa_addr, &hdr_status) < 0)
+ H5E_THROW(H5E_CANTGET, "unable to check metadata cache status for fixed array header")
+
+ /* Sanity checks on header */
+ HDassert(hdr_status & H5AC_ES__IN_CACHE);
+ HDassert(hdr_status & H5AC_ES__IS_PINNED);
+ HDassert(!(hdr_status & H5AC_ES__IS_PROTECTED));
+}
+#endif /* NDEBUG */
+
+ /* Lock the array header into memory */
+ /* (OK to pass in NULL for callback context, since we know the header must be in the cache) */
+ if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(fa->f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, NULL, H5AC_WRITE)))
+ H5E_THROW(H5E_CANTLOAD, "unable to load fixed array header")
+
+ /* Set the shared array header's file context for this operation */
+ hdr->f = fa->f;
+
+ /* Decrement the reference count on the array header */
+ /* (don't put in H5FA_hdr_fuse_decr() as the array header may be evicted
+ * immediately -QAK)
+ */
+ if(H5FA__hdr_decr(fa->hdr) < 0)
+ H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header")
+
+ /* Delete array, starting with header (unprotects header) */
+ if(H5FA__hdr_delete(hdr, dxpl_id) < 0)
+ H5E_THROW(H5E_CANTDELETE, "unable to delete fixed array")
+ } /* end if */
+ else {
+ /* Decrement the reference count on the array header */
+ /* (don't put in H5FA_hdr_fuse_decr() as the array header may be evicted
+ * immediately -QAK)
+ */
+ if(H5FA__hdr_decr(fa->hdr) < 0)
+ H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header")
+ } /* end else */
+
+ /* Release the fixed array wrapper */
+ fa = H5FL_FREE(H5FA_t, fa);
+
+CATCH
+
+END_FUNC(PRIV) /* end H5FA_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA_delete
+ *
+ * Purpose: Delete a fixed array
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, void *ctx_udata))
+
+ /* Local variables */
+ H5FA_hdr_t *hdr = NULL; /* The fixed array header information */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(H5F_addr_defined(fa_addr));
+
+ /* Lock the array header into memory */
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: fa_addr = %a\n", FUNC, fa_addr);
+#endif /* H5FA_DEBUG */
+ if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, ctx_udata, H5AC_WRITE)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array header, address = %llu", (unsigned long long)fa_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(H5FA__hdr_delete(hdr, dxpl_id) < 0)
+ H5E_THROW(H5E_CANTDELETE, "unable to delete fixed array")
+ hdr = NULL;
+ } /* end if */
+
+CATCH
+
+ /* Unprotect the header, if an error occurred */
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array header")
+
+END_FUNC(PRIV) /* end H5FA_delete() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA_iterate
+ *
+ * Purpose: Iterate over the elements of a fixed array
+ *
+ * Note: This is not very efficient, we should be iterating directly
+ * over the fixed array's direct block [pages].
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA_iterate(H5FA_t *fa, hid_t dxpl_id, H5FA_operator_t op, void *udata))
+
+ /* Local variables */
+ uint8_t *elmt = NULL;
+ hsize_t u;
+
+ /*
+ * Check arguments.
+ */
+ HDassert(fa);
+ HDassert(op);
+ HDassert(udata);
+
+ /* Allocate space for a native array element */
+ if(NULL == (elmt = H5FL_BLK_MALLOC(native_elmt, fa->hdr->cparam.cls->nat_elmt_size)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array element")
+
+ /* Iterate over all elements in array */
+ for(u = 0; u < fa->hdr->stats.nelmts; u++) {
+ int cb_ret; /* Return value from callback */
+
+ /* Get array element */
+ if(H5FA_get(fa, dxpl_id, u, elmt) < 0)
+ H5E_THROW(H5E_CANTGET, "unable to delete fixed array")
+
+ /* Make callback */
+ if((cb_ret = (*op)(u, elmt, udata)) < 0) {
+ H5E_PRINTF(H5E_BADITER, "iterator function failed");
+ H5_LEAVE(cb_ret)
+ } /* end if */
+ } /* end for */
+
+CATCH
+
+ if(elmt)
+ (void)H5FL_BLK_FREE(native_elmt, elmt);
+
+END_FUNC(PRIV) /* end H5FA_iterate() */
+
diff --git a/src/H5FAcache.c b/src/H5FAcache.c
new file mode 100644
index 0000000..3488531
--- /dev/null
+++ b/src/H5FAcache.c
@@ -0,0 +1,1129 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5FAcache.c
+ *
+ * Purpose: Implement fixed array metadata cache methods.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/**********************/
+/* Module Declaration */
+/**********************/
+
+#define H5FA_MODULE
+
+
+/***********************/
+/* Other Packages Used */
+/***********************/
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FApkg.h" /* Fixed Arrays */
+#include "H5MFprivate.h" /* File memory management */
+#include "H5Vprivate.h" /* Vectors and arrays */
+#include "H5WBprivate.h" /* Wrapped Buffers */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* Fixed Array format version #'s */
+#define H5FA_HDR_VERSION 0 /* Header */
+#define H5FA_DBLOCK_VERSION 0 /* Data block */
+
+/* Size of stack buffer for serialization buffers */
+#define H5FA_HDR_BUF_SIZE 512
+#define H5FA_DBLOCK_BUF_SIZE 512
+#define H5FA_DBLK_PAGE_BUF_SIZE 512
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* Metadata cache (H5AC) callbacks */
+static H5FA_hdr_t *H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2);
+static herr_t H5FA__cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5FA_hdr_t *hdr, unsigned * flags_ptr);
+static herr_t H5FA__cache_hdr_clear(H5F_t *f, H5FA_hdr_t *hdr, hbool_t destroy);
+static herr_t H5FA__cache_hdr_size(const H5F_t *f, const H5FA_hdr_t *hdr, size_t *size_ptr);
+static herr_t H5FA__cache_hdr_dest(H5F_t *f, H5FA_hdr_t *hdr);
+
+static H5FA_dblock_t *H5FA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2);
+static herr_t H5FA__cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5FA_dblock_t *dblock, unsigned * flags_ptr);
+static herr_t H5FA__cache_dblock_clear(H5F_t *f, H5FA_dblock_t *dblock, hbool_t destroy);
+static herr_t H5FA__cache_dblock_size(const H5F_t *f, const H5FA_dblock_t *dblock, size_t *size_ptr);
+static herr_t H5FA__cache_dblock_dest(H5F_t *f, H5FA_dblock_t *dblock);
+
+static H5FA_dblk_page_t *H5FA__cache_dblk_page_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2);
+static herr_t H5FA__cache_dblk_page_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5FA_dblk_page_t *dblk_page, unsigned * flags_ptr);
+static herr_t H5FA__cache_dblk_page_clear(H5F_t *f, H5FA_dblk_page_t *dblk_page, hbool_t destroy);
+static herr_t H5FA__cache_dblk_page_size(const H5F_t *f, const H5FA_dblk_page_t *dblk_page, size_t *size_ptr);
+static herr_t H5FA__cache_dblk_page_dest(H5F_t *f, H5FA_dblk_page_t *dblk_page);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* H5FA header inherits cache-like properties from H5AC */
+const H5AC_class_t H5AC_FARRAY_HDR[1] = {{
+ H5AC_FARRAY_HDR_ID,
+ (H5AC_load_func_t)H5FA__cache_hdr_load,
+ (H5AC_flush_func_t)H5FA__cache_hdr_flush,
+ (H5AC_dest_func_t)H5FA__cache_hdr_dest,
+ (H5AC_clear_func_t)H5FA__cache_hdr_clear,
+ (H5AC_notify_func_t)NULL,
+ (H5AC_size_func_t)H5FA__cache_hdr_size,
+}};
+
+
+/* H5FA data block inherits cache-like properties from H5AC */
+const H5AC_class_t H5AC_FARRAY_DBLOCK[1] = {{
+ H5AC_FARRAY_DBLOCK_ID,
+ (H5AC_load_func_t)H5FA__cache_dblock_load,
+ (H5AC_flush_func_t)H5FA__cache_dblock_flush,
+ (H5AC_dest_func_t)H5FA__cache_dblock_dest,
+ (H5AC_clear_func_t)H5FA__cache_dblock_clear,
+ (H5AC_notify_func_t)NULL,
+ (H5AC_size_func_t)H5FA__cache_dblock_size,
+}};
+
+/* H5FA data block page inherits cache-like properties from H5AC */
+const H5AC_class_t H5AC_FARRAY_DBLK_PAGE[1] = {{
+ H5AC_FARRAY_DBLK_PAGE_ID,
+ (H5AC_load_func_t)H5FA__cache_dblk_page_load,
+ (H5AC_flush_func_t)H5FA__cache_dblk_page_flush,
+ (H5AC_dest_func_t)H5FA__cache_dblk_page_dest,
+ (H5AC_clear_func_t)H5FA__cache_dblk_page_clear,
+ (H5AC_notify_func_t)NULL,
+ (H5AC_size_func_t)H5FA__cache_dblk_page_size,
+}};
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__cache_hdr_load
+ *
+ * Purpose: Loads a fixed array header from the disk.
+ *
+ * Return: Success: Pointer to a new fixed array
+ * Failure: NULL
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+H5FA_hdr_t *, NULL, NULL,
+H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1,
+ void *ctx_udata))
+
+ /* Local variables */
+ H5FA_cls_id_t id; /* ID of fixed array class, as found in file */
+ H5FA_hdr_t *hdr = NULL; /* Fixed array info */
+ size_t size; /* Header size */
+ H5WB_t *wb = NULL; /* Wrapped buffer for header data */
+ uint8_t hdr_buf[H5FA_HDR_BUF_SIZE]; /* Buffer for header */
+ uint8_t *buf; /* Pointer to header 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 */
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+
+ /* Allocate space for the fixed array data structure */
+ if(NULL == (hdr = H5FA__hdr_alloc(f)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array shared header")
+
+ /* Set the fixed array header's address */
+ hdr->addr = addr;
+
+ /* 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 fixed array header on disk */
+ size = H5FA_HEADER_SIZE(hdr);
+
+ /* Get a pointer to a buffer that's large enough for serialized header */
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
+ H5E_THROW(H5E_CANTGET, "can't get actual buffer")
+
+ /* Read header from disk */
+ if(H5F_block_read(f, H5FD_MEM_FARRAY_HDR, addr, size, dxpl_id, buf) < 0)
+ H5E_THROW(H5E_READERROR, "can't read fixed array header")
+
+ /* Get temporary pointer to serialized header */
+ p = buf;
+
+ /* Magic number */
+ if(HDmemcmp(p, H5FA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC))
+ H5E_THROW(H5E_BADVALUE, "wrong fixed array header signature")
+ p += H5_SIZEOF_MAGIC;
+
+ /* Version */
+ if(*p++ != H5FA_HDR_VERSION)
+ H5E_THROW(H5E_VERSION, "wrong fixed array header version")
+
+ /* Fixed array class */
+ id = *p++;
+ if(id >= H5FA_NUM_CLS_ID)
+ H5E_THROW(H5E_BADTYPE, "incorrect fixed array class")
+ hdr->cparam.cls = H5FA_client_class_g[id];
+
+ /* General array creation/configuration information */
+ hdr->cparam.raw_elmt_size = *p++; /* Element size in file (in bytes) */
+ hdr->cparam.max_dblk_page_nelmts_bits = *p++; /* Log2(Max. # of elements in data block page) -
+ i.e. # of bits needed to store max. # of
+ elements in data block page. */
+
+ /* Array statistics */
+ H5F_DECODE_LENGTH(f, p, hdr->cparam.nelmts); /* Number of elements */
+
+ /* Internal information */
+ H5F_addr_decode(f, &p, &hdr->dblk_addr); /* Address of index block */
+
+ /* Check for data block */
+ if(H5F_addr_defined(hdr->dblk_addr)) {
+ H5FA_dblock_t dblock; /* Fake data block for computing size */
+ size_t dblk_page_nelmts; /* # of elements per data block page */
+
+ /* Set up fake data block for computing size on disk */
+ dblock.hdr = hdr;
+ dblock.dblk_page_init_size = 0;
+ dblock.npages = 0;
+ dblk_page_nelmts = (size_t)1 << hdr->cparam.max_dblk_page_nelmts_bits;
+ if(hdr->cparam.nelmts > dblk_page_nelmts) {
+ dblock.npages = (size_t)(((hdr->cparam.nelmts + dblk_page_nelmts) - 1) / dblk_page_nelmts);
+ dblock.dblk_page_init_size = (dblock.npages + 7) / 8;
+ } /* end if */
+
+ /* Compute Fixed Array data block size for hdr statistics */
+ hdr->stats.dblk_size = (size_t)H5FA_DBLOCK_SIZE(&dblock);
+ } /* end if */
+
+ /* Sanity check */
+ /* (allow for checksum not decoded yet) */
+ HDassert((size_t)(p - buf) == (size - H5FA_SIZEOF_CHKSUM));
+
+ /* Compute checksum on entire header */
+ /* (including the filter information, if present) */
+ computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
+
+ /* Metadata checksum */
+ UINT32DECODE(p, stored_chksum);
+
+ /* Sanity check */
+ HDassert((size_t)(p - buf) == size);
+
+ /* Verify checksum */
+ if(stored_chksum != computed_chksum)
+ H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for fixed array header")
+
+ /* Finish initializing fixed array header */
+ if(H5FA__hdr_init(hdr, ctx_udata) < 0)
+ H5E_THROW(H5E_CANTINIT, "initialization failed for fixed array header")
+ HDassert(hdr->size == size);
+
+ /* Set return value */
+ ret_value = hdr;
+
+CATCH
+
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer")
+ if(!ret_value)
+ if(hdr && H5FA__cache_hdr_dest(f, hdr) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array header")
+
+END_FUNC(STATIC) /* end H5FA__cache_hdr_load() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__cache_hdr_flush
+ *
+ * Purpose: Flushes a dirty fixed array header to disk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
+ H5FA_hdr_t *hdr, unsigned UNUSED * flags_ptr))
+
+ H5WB_t *wb = NULL; /* Wrapped buffer for header data */
+ uint8_t hdr_buf[H5FA_HDR_BUF_SIZE]; /* Buffer for header */
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(hdr);
+
+ if(hdr->cache_info.is_dirty) {
+ uint8_t *buf; /* Temporary raw data buffer */
+ uint8_t *p; /* Pointer into raw data buffer */
+ size_t size; /* Header size on disk */
+ uint32_t metadata_chksum; /* Computed metadata checksum value */
+
+ /* Wrap the local buffer for serialized header info */
+ if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
+ H5E_THROW(H5E_CANTINIT, "can't wrap buffer")
+
+ /* 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 */
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
+ H5E_THROW(H5E_CANTGET, "can't get actual buffer")
+
+ /* Get temporary pointer to serialized header */
+ p = buf;
+
+ /* Magic number */
+ HDmemcpy(p, H5FA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
+
+ /* Version # */
+ *p++ = H5FA_HDR_VERSION;
+
+ /* Fixed array type */
+ *p++ = hdr->cparam.cls->id;
+
+ /* General array creation/configuration information */
+ *p++ = hdr->cparam.raw_elmt_size; /* Element size in file (in bytes) */
+ *p++ = hdr->cparam.max_dblk_page_nelmts_bits; /* Log2(Max. # of elements in data block page) - i.e. # of bits needed to store max. # of elements in data block page */
+
+ /* Array statistics */
+ H5F_ENCODE_LENGTH(f, p, hdr->stats.nelmts); /* Number of elements for the fixed array */
+
+ /* Internal information */
+ H5F_addr_encode(f, &p, hdr->dblk_addr); /* Address of fixed array data block */
+
+ /* Compute metadata checksum */
+ metadata_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
+
+ /* Metadata checksum */
+ UINT32ENCODE(p, metadata_chksum);
+
+ /* Write the array header. */
+ HDassert((size_t)(p - buf) == size);
+ if(H5F_block_write(f, H5FD_MEM_FARRAY_HDR, addr, size, dxpl_id, buf) < 0)
+ H5E_THROW(H5E_WRITEERROR, "unable to save fixed array header to disk")
+
+ hdr->cache_info.is_dirty = FALSE;
+ } /* end if */
+
+ if(destroy)
+ if(H5FA__cache_hdr_dest(f, hdr) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array header")
+
+CATCH
+
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer")
+
+END_FUNC(STATIC) /* end H5FA__cache_hdr_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__cache_hdr_clear
+ *
+ * Purpose: Mark a fixed array header in memory as non-dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__cache_hdr_clear(H5F_t *f, H5FA_hdr_t *hdr, hbool_t destroy))
+
+ /* Sanity check */
+ HDassert(hdr);
+
+ /* Reset the dirty flag. */
+ hdr->cache_info.is_dirty = FALSE;
+
+ if(destroy)
+ if(H5FA__cache_hdr_dest(f, hdr) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array header")
+
+CATCH
+
+END_FUNC(STATIC) /* end H5FA__cache_hdr_clear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__cache_hdr_size
+ *
+ * Purpose: Compute the size in bytes of a fixed array header
+ * 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: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+H5FA__cache_hdr_size(const H5F_t UNUSED *f, const H5FA_hdr_t *hdr,
+ size_t *size_ptr))
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(hdr);
+ HDassert(size_ptr);
+
+ /* Set size value */
+ *size_ptr = hdr->size;
+
+END_FUNC(STATIC) /* end H5FA__cache_hdr_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__cache_hdr_dest
+ *
+ * Purpose: Destroys a fixed array header in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__cache_hdr_dest(H5F_t *f, H5FA_hdr_t *hdr))
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(hdr);
+
+ /* Verify that header is clean */
+ HDassert(hdr->cache_info.is_dirty == FALSE);
+
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!hdr->cache_info.free_file_space_on_destroy || H5F_addr_defined(hdr->cache_info.addr));
+
+ /* Check for freeing file space for fixed array header */
+ if(hdr->cache_info.free_file_space_on_destroy) {
+ /* Sanity check address */
+ HDassert(H5F_addr_eq(hdr->addr, hdr->cache_info.addr));
+
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_FARRAY_HDR, H5AC_dxpl_id, hdr->cache_info.addr, (hsize_t)hdr->size) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to free fixed array header")
+ } /* end if */
+
+ /* Release the fixed array header */
+ if(H5FA__hdr_dest(hdr) < 0)
+ H5E_THROW(H5E_CANTFREE, "can't free fixed array header")
+
+CATCH
+
+END_FUNC(STATIC) /* end H5FA__cache_hdr_dest() */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__cache_dblock_load
+ *
+ * Purpose: Loads a fixed array data block from the disk.
+ *
+ * Return: Success: Pointer to a new fixed array data block
+ * Failure: NULL
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+H5FA_dblock_t *, NULL, NULL,
+H5FA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ const void *_nelmts, void *_hdr))
+
+ /* Local variables */
+ H5FA_hdr_t *hdr = (H5FA_hdr_t *)_hdr; /* Shared fixed array information */
+ const hsize_t *nelmts = (const hsize_t *)_nelmts; /* Number of elements in data block */
+ H5FA_dblock_t *dblock = NULL; /* Data block info */
+ size_t size; /* Data block size */
+ H5WB_t *wb = NULL; /* Wrapped buffer for data block data */
+ uint8_t dblock_buf[H5FA_DBLOCK_BUF_SIZE]; /* Buffer for data block */
+ uint8_t *buf; /* Pointer to data 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 */
+ haddr_t arr_addr; /* Address of array header in the file */
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(nelmts && *nelmts > 0);
+ HDassert(hdr);
+
+ /* Allocate the fixed array data block */
+ if(NULL == (dblock = H5FA__dblock_alloc(hdr, *nelmts)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array data block")
+
+ /* Set the fixed array data block's information */
+ dblock->addr = addr;
+
+ /* Wrap the local buffer for serialized info */
+ if(NULL == (wb = H5WB_wrap(dblock_buf, sizeof(dblock_buf))))
+ H5E_THROW(H5E_CANTINIT, "can't wrap buffer")
+
+ /* Compute the size of the fixed array data block on disk */
+ if(!dblock->npages)
+ size = (size_t)H5FA_DBLOCK_SIZE(dblock);
+ else
+ size = H5FA_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)))
+ H5E_THROW(H5E_CANTGET, "can't get actual buffer")
+
+ /* Read data block from disk */
+ if(H5F_block_read(f, H5FD_MEM_FARRAY_DBLOCK, addr, size, dxpl_id, buf) < 0)
+ H5E_THROW(H5E_READERROR, "can't read fixed array data block")
+
+ /* Get temporary pointer to serialized header */
+ p = buf;
+
+ /* Magic number */
+ if(HDmemcmp(p, H5FA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC))
+ H5E_THROW(H5E_BADVALUE, "wrong fixed array data block signature")
+ p += H5_SIZEOF_MAGIC;
+
+ /* Version */
+ if(*p++ != H5FA_DBLOCK_VERSION)
+ H5E_THROW(H5E_VERSION, "wrong fixed array data block version")
+
+ /* Address of header for array that owns this block (just for file integrity checks) */
+ H5F_addr_decode(f, &p, &arr_addr);
+ if(H5F_addr_ne(arr_addr, hdr->addr))
+ H5E_THROW(H5E_BADVALUE, "wrong fixed array header address")
+
+ /* Fixed array type */
+ if(*p++ != (uint8_t)hdr->cparam.cls->id)
+ H5E_THROW(H5E_BADTYPE, "incorrect fixed array class")
+
+ /* Page initialization flags */
+ if(dblock->npages > 0) {
+ HDmemcpy(dblock->dblk_page_init, p, dblock->dblk_page_init_size);
+ p += dblock->dblk_page_init_size;
+ } /* end if */
+
+ /* 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, (size_t)*nelmts, hdr->cb_ctx) < 0)
+ H5E_THROW(H5E_CANTDECODE, "can't decode fixed 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 - H5FA_SIZEOF_CHKSUM));
+
+ /* Set the data block's size */
+ dblock->size = H5FA_DBLOCK_SIZE(dblock);
+
+ /* 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) == size);
+
+ /* Verify checksum */
+ if(stored_chksum != computed_chksum)
+ H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for fixed array data block")
+
+ /* Set return value */
+ ret_value = dblock;
+
+CATCH
+
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer")
+ if(!ret_value)
+ if(dblock && H5FA__cache_dblock_dest(f, dblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block")
+
+END_FUNC(STATIC) /* end H5FA__cache_dblock_load() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__cache_dblock_flush
+ *
+ * Purpose: Flushes a dirty fixed array data block to disk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
+ H5FA_dblock_t *dblock, unsigned UNUSED * flags_ptr))
+
+ /* Local variables */
+ H5WB_t *wb = NULL; /* Wrapped buffer for serializing data */
+ uint8_t ser_buf[H5FA_DBLOCK_BUF_SIZE]; /* Serialization buffer */
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(dblock);
+ HDassert(dblock->hdr);
+
+ if(dblock->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 */
+ if(!dblock->npages)
+ size = (size_t)dblock->size;
+ else
+ size = H5FA_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)))
+ H5E_THROW(H5E_CANTGET, "can't get actual buffer")
+
+ /* Get temporary pointer to serialized info */
+ p = buf;
+
+ /* Magic number */
+ HDmemcpy(p, H5FA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
+
+ /* Version # */
+ *p++ = H5FA_DBLOCK_VERSION;
+
+ /* Address of array header for array which owns this block */
+ H5F_addr_encode(f, &p, dblock->hdr->addr);
+
+ /* Fixed array type */
+ *p++ = dblock->hdr->cparam.cls->id;
+
+ /* Page init flags */
+ if(dblock->npages > 0) {
+ /* Store the 'page init' bitmasks */
+ HDmemcpy(p, dblock->dblk_page_init, dblock->dblk_page_init_size);
+ p += dblock->dblk_page_init_size;
+ } /* end if */
+
+ /* 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 */
+ H5_CHECK_OVERFLOW(dblock->hdr->cparam.nelmts, /* From: */hsize_t, /* To: */size_t);
+ if((dblock->hdr->cparam.cls->encode)(p, dblock->elmts, (size_t)dblock->hdr->cparam.nelmts, dblock->hdr->cb_ctx) < 0)
+ H5E_THROW(H5E_CANTENCODE, "can't encode fixed array data elements")
+ p += (dblock->hdr->cparam.nelmts * dblock->hdr->cparam.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 data block */
+ HDassert((size_t)(p - buf) == size);
+ if(H5F_block_write(f, H5FD_MEM_FARRAY_DBLOCK, addr, size, dxpl_id, buf) < 0)
+ H5E_THROW(H5E_WRITEERROR, "unable to save fixed array data block to disk")
+
+ dblock->cache_info.is_dirty = FALSE;
+ } /* end if */
+
+ if(destroy)
+ if(H5FA__cache_dblock_dest(f, dblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block")
+
+CATCH
+
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer")
+
+END_FUNC(STATIC) /* end H5FA__cache_dblock_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__cache_dblock_clear
+ *
+ * Purpose: Mark a fixed array data block in memory as non-dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__cache_dblock_clear(H5F_t *f, H5FA_dblock_t *dblock, hbool_t destroy))
+
+ /* Sanity check */
+ HDassert(dblock);
+
+ /* Reset the dirty flag */
+ dblock->cache_info.is_dirty = FALSE;
+
+ if(destroy)
+ if(H5FA__cache_dblock_dest(f, dblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block")
+
+CATCH
+
+END_FUNC(STATIC) /* end H5FA__cache_dblock_clear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__cache_dblock_size
+ *
+ * Purpose: Compute the size in bytes of a fixed array data 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: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+H5FA__cache_dblock_size(const H5F_t UNUSED *f, const H5FA_dblock_t *dblock,
+ size_t *size_ptr))
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(dblock);
+ HDassert(size_ptr);
+
+ /* Set size value */
+ if(!dblock->npages)
+ *size_ptr = (size_t)dblock->size;
+ else
+ *size_ptr = H5FA_DBLOCK_PREFIX_SIZE(dblock);
+
+END_FUNC(STATIC) /* end H5FA__cache_dblock_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__cache_dblock_dest
+ *
+ * Purpose: Destroys a fixed array data block in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__cache_dblock_dest(H5F_t *f, H5FA_dblock_t *dblock))
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(dblock);
+
+ /* Verify that data block is clean */
+ HDassert(dblock->cache_info.is_dirty == FALSE);
+
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!dblock->cache_info.free_file_space_on_destroy || H5F_addr_defined(dblock->cache_info.addr));
+
+ /* Check for freeing file space for fixed array data block */
+ if(dblock->cache_info.free_file_space_on_destroy) {
+ /* Sanity check address */
+ 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_FARRAY_DBLOCK, H5AC_dxpl_id, dblock->cache_info.addr, (hsize_t)dblock->size) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to free fixed array data block")
+ } /* end if */
+
+ /* Release the data block */
+ if(H5FA__dblock_dest(f, dblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "can't free fixed array data block")
+
+CATCH
+
+END_FUNC(STATIC) /* end H5FA__cache_dblock_dest() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__cache_dblk_page_load
+ *
+ * Purpose: Loads a fixed array data block page from the disk.
+ *
+ * Return: Success: Pointer to a new fixed array data block page
+ * Failure: NULL
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+H5FA_dblk_page_t *, NULL, NULL,
+H5FA__cache_dblk_page_load(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ const void *_udata1, void *_hdr))
+
+ /* Local variables */
+ H5FA_hdr_t *hdr = (H5FA_hdr_t *)_hdr; /* Shared fixed array information */
+ const H5FA_dblk_page_load_ud_t *ud_load = (const H5FA_dblk_page_load_ud_t *)_udata1; /* User data for loading data block page */
+ H5FA_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[H5FA_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 fixed array data block page */
+ if(NULL == (dblk_page = H5FA__dblk_page_alloc(hdr, ud_load->nelmts)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array data block page")
+
+ /* Set the fixed 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 fixed array data block page on disk */
+ size = H5FA_DBLK_PAGE_SIZE(dblk_page, ud_load->nelmts);
+
+ /* 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_FARRAY_DBLK_PAGE, addr, size, dxpl_id, buf) < 0)
+ H5E_THROW(H5E_READERROR, "can't read fixed 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, ud_load->nelmts, hdr->cb_ctx) < 0)
+ H5E_THROW(H5E_CANTDECODE, "can't decode fixed array data elements")
+ p += (ud_load->nelmts * hdr->cparam.raw_elmt_size);
+
+ /* Sanity check */
+ /* (allow for checksum not decoded yet) */
+ HDassert((size_t)(p - buf) == (size - H5FA_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)
+ H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for fixed 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 && H5FA__cache_dblk_page_dest(f, dblk_page) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block page")
+
+END_FUNC(STATIC) /* end H5FA__cache_dblk_page_load() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__cache_dblk_page_flush
+ *
+ * Purpose: Flushes a dirty fixed array data block page to disk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__cache_dblk_page_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
+ H5FA_dblk_page_t *dblk_page, unsigned UNUSED * flags_ptr))
+
+ /* Local variables */
+ H5WB_t *wb = NULL; /* Wrapped buffer for serializing data */
+ uint8_t ser_buf[H5FA_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->nelmts, dblk_page->hdr->cb_ctx) < 0)
+ H5E_THROW(H5E_CANTENCODE, "can't encode fixed array data elements")
+ p += (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_FARRAY_DBLK_PAGE, addr, size, dxpl_id, buf) < 0)
+ H5E_THROW(H5E_WRITEERROR, "unable to save fixed array data block page to disk")
+
+ dblk_page->cache_info.is_dirty = FALSE;
+ } /* end if */
+
+ if(destroy)
+ if(H5FA__cache_dblk_page_dest(f, dblk_page) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy fixed 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 H5FA__cache_dblk_page_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__cache_dblk_page_clear
+ *
+ * Purpose: Mark a fixed array data block page in memory as non-dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__cache_dblk_page_clear(H5F_t *f, H5FA_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(H5FA__cache_dblk_page_dest(f, dblk_page) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block page")
+
+CATCH
+
+END_FUNC(STATIC) /* end H5FA__cache_dblk_page_clear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__cache_dblk_page_size
+ *
+ * Purpose: Compute the size in bytes of a fixed 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: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+H5FA__cache_dblk_page_size(const H5F_t UNUSED *f, const H5FA_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 H5FA__cache_dblk_page_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__cache_dblk_page_dest
+ *
+ * Purpose: Destroys a fixed 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: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__cache_dblk_page_dest(H5F_t UNUSED *f, H5FA_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(H5FA__dblk_page_dest(dblk_page) < 0)
+ H5E_THROW(H5E_CANTFREE, "can't free fixed array data block page")
+
+CATCH
+
+END_FUNC(STATIC) /* end H5FA__cache_dblk_page_dest() */
+
diff --git a/src/H5FAdbg.c b/src/H5FAdbg.c
new file mode 100644
index 0000000..c1aa3d4
--- /dev/null
+++ b/src/H5FAdbg.c
@@ -0,0 +1,287 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5FAdbg.c
+ *
+ * Purpose: Dump debugging information about a fixed array.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/**********************/
+/* Module Declaration */
+/**********************/
+
+#define H5FA_MODULE
+
+
+/***********************/
+/* Other Packages Used */
+/***********************/
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FApkg.h" /* Fixed Arrays */
+#include "H5Oprivate.h" /* Object Header */
+#include "H5Vprivate.h" /* Vector functions */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__hdr_debug
+ *
+ * Purpose: Prints debugging info about a fixed array header.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
+ int fwidth, const H5FA_class_t *cls, haddr_t obj_addr))
+
+ /* Local variables */
+ H5FA_hdr_t *hdr = NULL; /* Shared fixed array header */
+ void *dbg_ctx = NULL; /* Fixed array debugging context */
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(H5F_addr_defined(obj_addr));
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+ HDassert(cls);
+
+ /* Check for debugging context callback available */
+ if(cls->crt_dbg_ctx) {
+ /* Create debugging context */
+ if(NULL == (dbg_ctx = cls->crt_dbg_ctx(f, dxpl_id, obj_addr)))
+ H5E_THROW(H5E_CANTGET, "unable to create fixed array debugging context")
+ } /* end if */
+
+ /* Load the fixed array header */
+ if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, addr, cls, dbg_ctx, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header")
+
+ /* Print opening message */
+ HDfprintf(stream, "%*sFixed Array Header...\n", indent, "");
+
+ /* Print the values */
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Array class ID:", hdr->cparam.cls->name);
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "Header size:",
+ hdr->size);
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Raw Element Size:",
+ (unsigned)hdr->cparam.raw_elmt_size);
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "Native Element Size (on this platform):",
+ hdr->cparam.cls->nat_elmt_size);
+
+
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Max. # of elements in data block page:",
+ (unsigned)((size_t)1 << hdr->cparam.max_dblk_page_nelmts_bits));
+
+ HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
+ "Number of elements in Fixed Array:", hdr->stats.nelmts);
+
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
+ "Fixed Array Data Block Address:", hdr->dblk_addr);
+
+CATCH
+ if(dbg_ctx && cls->dst_dbg_ctx(dbg_ctx) < 0)
+ H5E_THROW(H5E_CANTRELEASE, "unable to release fixed array debugging context")
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FARRAY_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array header")
+
+END_FUNC(PKG) /* end H5FA__hdr_debug() */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__dblock_debug
+ *
+ * Purpose: Prints debugging info about a fixed array data block.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
+ int fwidth, const H5FA_class_t *cls, haddr_t hdr_addr, haddr_t obj_addr))
+
+ /* Local variables */
+ H5FA_hdr_t *hdr = NULL; /* Shared fixed array header */
+ H5FA_dblock_t *dblock = NULL; /* Fixed array data block */
+ void *dbg_ctx = NULL; /* Fixed array context */
+ size_t u; /* Local index variable */
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+ HDassert(cls);
+ HDassert(H5F_addr_defined(hdr_addr));
+ HDassert(H5F_addr_defined(obj_addr));
+
+ /* Check for debugging context callback available */
+ if(cls->crt_dbg_ctx) {
+ /* Create debugging context */
+ if(NULL == (dbg_ctx = cls->crt_dbg_ctx(f, dxpl_id, obj_addr)))
+ H5E_THROW(H5E_CANTGET, "unable to create fixed array debugging context")
+ } /* end if */
+
+ /* Load the fixed array header */
+ if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, hdr_addr, cls, dbg_ctx, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header")
+
+ /* Protect data block */
+ if(NULL == (dblock = H5FA__dblock_protect(hdr, dxpl_id, addr, hdr->cparam.nelmts, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block, address = %llu", (unsigned long long)addr)
+
+ /* Print opening message */
+ HDfprintf(stream, "%*sFixed Array data Block...\n", indent, "");
+
+ /* Print the values */
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Array class ID:", hdr->cparam.cls->name);
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, "Address of Data Block:", dblock->addr);
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, "Data Block size:", dblock->size);
+ HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
+ "Number of elements in Data Block:", hdr->cparam.nelmts);
+ HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
+ "Number of pages in Data Block:", dblock->npages);
+ HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
+ "Number of elements per Data Block page:", dblock->dblk_page_nelmts);
+
+ if(dblock->npages) { /* paging */
+ size_t dblk_page_nelmts; /* # of elements in a data block page */
+ haddr_t dblk_page_addr; /* Address of a data block page */
+ size_t page_idx; /* Page index within data block */
+
+ HDfprintf(stream, "%*sPaging:\n", indent, "");
+
+ /* Iterate over the pages */
+ dblk_page_addr = dblock->addr + H5FA_DBLOCK_PREFIX_SIZE(dblock);
+ dblk_page_nelmts = dblock->dblk_page_nelmts;
+
+ /* Read and print each page's elements in the data block */
+ for(page_idx = 0; page_idx < dblock->npages; page_idx++) {
+ if(!H5V_bit_get(dblock->dblk_page_init, page_idx)) {
+ HDfprintf(stream, "%*s%-*s %Hu %s\n", indent, "", fwidth,
+ "Page %Zu:", page_idx, "empty");
+
+ } /* end if */
+ else { /* get the page */
+ H5FA_dblk_page_t *dblk_page; /* Pointer to a data block page */
+ hsize_t nelmts_left; /* Remaining elements in the last data block page */
+
+ /* Check for last page */
+ if(((page_idx + 1) == dblock->npages) && (nelmts_left = hdr->cparam.nelmts % dblock->dblk_page_nelmts))
+ dblk_page_nelmts = (size_t)nelmts_left;
+
+ if(NULL == (dblk_page = H5FA__dblk_page_protect(hdr, dxpl_id, dblk_page_addr, dblk_page_nelmts, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block page, address = %llu", (unsigned long long)dblk_page_addr)
+
+ HDfprintf(stream, "%*sElements in page %Zu:\n", indent, "", page_idx);
+ for(u = 0; u < dblk_page_nelmts; u++) {
+ /* Call the class's 'debug' callback */
+ if((hdr->cparam.cls->debug)(stream, (indent + 3), MAX(0, (fwidth - 3)), (hsize_t)u,
+ ((uint8_t *)dblk_page->elmts) + (hdr->cparam.cls->nat_elmt_size * u)) < 0)
+ H5E_THROW(H5E_CANTGET, "can't get element for debugging")
+ } /* end for */
+ if(H5FA__dblk_page_unprotect(dblk_page, dxpl_id, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array data block page")
+
+ /* Advance to next page address */
+ dblk_page_addr += dblock->dblk_page_size;
+ } /* paging */
+ } /* end for npages */
+ } /* end if */
+ else { /* not paging */
+ /* Print the elements in the data block */
+ HDfprintf(stream, "%*sElements:\n", indent, "");
+ for(u = 0; u < hdr->cparam.nelmts; u++) {
+ /* Call the class's 'debug' callback */
+ if((hdr->cparam.cls->debug)(stream, (indent + 3), MAX(0, (fwidth - 3)), (hsize_t)u,
+ ((uint8_t *)dblock->elmts) + (hdr->cparam.cls->nat_elmt_size * u)) < 0)
+ H5E_THROW(H5E_CANTGET, "can't get element for debugging")
+ } /* end for */
+ } /* end else */
+
+CATCH
+ if(dbg_ctx && cls->dst_dbg_ctx(dbg_ctx) < 0)
+ H5E_THROW(H5E_CANTRELEASE, "unable to release fixed array debugging context")
+ if(dblock && H5FA__dblock_unprotect(dblock, dxpl_id, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array data block")
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FARRAY_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array header")
+
+END_FUNC(PKG) /* end H5FA__dblock_debug() */
+
diff --git a/src/H5FAdblkpage.c b/src/H5FAdblkpage.c
new file mode 100644
index 0000000..dde299f
--- /dev/null
+++ b/src/H5FAdblkpage.c
@@ -0,0 +1,312 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5FAdblkpage.c
+ *
+ * Purpose: Data block page routines for fixed array.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/**********************/
+/* Module Declaration */
+/**********************/
+
+#define H5FA_MODULE
+
+
+/***********************/
+/* Other Packages Used */
+/***********************/
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FApkg.h" /* Fixed Arrays */
+#include "H5FLprivate.h" /* Free Lists */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5FA_dblk_page_t struct */
+H5FL_DEFINE_STATIC(H5FA_dblk_page_t);
+
+/* Declare a free list to manage the page elements */
+H5FL_BLK_DEFINE(page_elmts);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__dblk_page_alloc
+ *
+ * Purpose: Allocate fixed array data block page
+ *
+ * Return: Non-NULL pointer to data block on success/NULL on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+H5FA_dblk_page_t *, NULL, NULL,
+H5FA__dblk_page_alloc(H5FA_hdr_t *hdr, size_t nelmts))
+
+ /* Local variables */
+ H5FA_dblk_page_t *dblk_page = NULL; /* Fixed array data block page */
+
+ /* Check arguments */
+ HDassert(hdr);
+
+ /* Allocate memory for the data block */
+ if(NULL == (dblk_page = H5FL_CALLOC(H5FA_dblk_page_t)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array data block page")
+
+ /* Share common array information */
+ if(H5FA__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 */
+ dblk_page->nelmts = nelmts;
+
+ /* Allocate buffer for elements in data block page */
+ if(NULL == (dblk_page->elmts = H5FL_BLK_MALLOC(page_elmts, nelmts * hdr->cparam.cls->nat_elmt_size)))
+ 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 && H5FA__dblk_page_dest(dblk_page) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block page")
+
+END_FUNC(PKG) /* end H5FA__dblk_page_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__dblk_page_create
+ *
+ * Purpose: Creates a new fixed array data block page in the file
+ *
+ * Return: Valid file address on success/HADDR_UNDEF on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__dblk_page_create(H5FA_hdr_t *hdr, hid_t dxpl_id, haddr_t addr, size_t nelmts))
+
+ /* Local variables */
+ H5FA_dblk_page_t *dblk_page = NULL; /* Fixed array data block page */
+
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: Called, addr = %a\n", FUNC, addr);
+#endif /* H5FA_DEBUG */
+
+ /* Sanity check */
+ HDassert(hdr);
+
+ /* Allocate the data block page */
+ if(NULL == (dblk_page = H5FA__dblk_page_alloc(hdr, nelmts)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array data block page")
+
+ /* Set info about data block page on disk */
+ dblk_page->addr = addr;
+ dblk_page->size = H5FA_DBLK_PAGE_SIZE(dblk_page, nelmts);
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: dblk_page->size = %Zu\n", FUNC, dblk_page->size);
+#endif /* H5FA_DEBUG */
+
+ /* Clear any elements in data block page to fill value */
+ if((hdr->cparam.cls->fill)(dblk_page->elmts, nelmts) < 0)
+ H5E_THROW(H5E_CANTSET, "can't set fixed array data block page elements to class's fill value")
+
+ /* Cache the new fixed array data block page */
+ if(H5AC_set(hdr->f, dxpl_id, H5AC_FARRAY_DBLK_PAGE, dblk_page->addr, dblk_page, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTINSERT, "can't add fixed array data block page to cache")
+
+CATCH
+ if(ret_value < 0)
+ if(dblk_page) {
+ /* Destroy data block page */
+ if(H5FA__dblk_page_dest(dblk_page) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block page")
+ } /* end if */
+
+END_FUNC(PKG) /* end H5FA__dblk_page_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__dblk_page_protect
+ *
+ * Purpose: Convenience wrapper around protecting fixed array data
+ * block page
+ *
+ * Return: Non-NULL pointer to data block page on success/NULL on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+H5FA_dblk_page_t *, NULL, NULL,
+H5FA__dblk_page_protect(H5FA_hdr_t *hdr, hid_t dxpl_id, haddr_t dblk_page_addr,
+ size_t dblk_page_nelmts, H5AC_protect_t rw))
+
+ /* Local variables */
+ H5FA_dblk_page_load_ud_t load_ud; /* Information needed for loading data block page */
+
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* H5FA_DEBUG */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(H5F_addr_defined(dblk_page_addr));
+
+ /* Set up user data */
+ load_ud.nelmts = dblk_page_nelmts;
+
+ /* Protect the data block page */
+ if(NULL == (ret_value = (H5FA_dblk_page_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_FARRAY_DBLK_PAGE, dblk_page_addr, &load_ud, hdr, rw)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block page, address = %llu", (unsigned long long)dblk_page_addr)
+
+CATCH
+
+END_FUNC(PKG) /* end H5FA__dblk_page_protect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__dblk_page_unprotect
+ *
+ * Purpose: Convenience wrapper around unprotecting fixed array
+ * data block page
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__dblk_page_unprotect(H5FA_dblk_page_t *dblk_page, hid_t dxpl_id,
+ unsigned cache_flags))
+
+ /* Local variables */
+
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* H5FA_DEBUG */
+
+ /* Sanity check */
+ HDassert(dblk_page);
+
+ /* Unprotect the data block page */
+ if(H5AC_unprotect(dblk_page->hdr->f, dxpl_id, H5AC_FARRAY_DBLK_PAGE, dblk_page->addr, dblk_page, cache_flags) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to unprotect fixed array data block page, address = %llu", (unsigned long long)dblk_page->addr)
+
+CATCH
+
+END_FUNC(PKG) /* end H5FA__dblk_page_unprotect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__dblk_page_dest
+ *
+ * Purpose: Destroys a fixed array data block page in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__dblk_page_dest(H5FA_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 */
+ (void) H5FL_BLK_FREE(page_elmts, dblk_page->elmts);
+ dblk_page->elmts = NULL;
+ } /* end if */
+
+ /* Decrement reference count on shared info */
+ if(H5FA__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(H5FA_dblk_page_t, dblk_page);
+
+CATCH
+
+END_FUNC(PKG) /* end H5FA__dblk_page_dest() */
+
diff --git a/src/H5FAdblock.c b/src/H5FAdblock.c
new file mode 100644
index 0000000..f564fee
--- /dev/null
+++ b/src/H5FAdblock.c
@@ -0,0 +1,442 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5FAdblock.c
+ *
+ * Purpose: Data block routines for fixed arrays.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/**********************/
+/* Module Declaration */
+/**********************/
+
+#define H5FA_MODULE
+
+
+/***********************/
+/* Other Packages Used */
+/***********************/
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FApkg.h" /* Fixed Arrays */
+#include "H5FLprivate.h" /* Free Lists */
+#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 H5FA_dblock_t struct */
+H5FL_DEFINE_STATIC(H5FA_dblock_t);
+
+/* Declare a free list to manage the chunk elements */
+H5FL_BLK_DEFINE(chunk_elmts);
+
+/* Declare a free list to manage blocks of 'page init' bitmasks */
+H5FL_BLK_DEFINE(fa_page_init);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__dblock_alloc
+ *
+ * Purpose: Allocate fixed array data block
+ *
+ * Return: Non-NULL pointer to data block on success/NULL on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+H5FA_dblock_t *, NULL, NULL,
+H5FA__dblock_alloc(H5FA_hdr_t *hdr, hsize_t nelmts))
+
+ /* Local variables */
+ H5FA_dblock_t *dblock = NULL; /* fixed array data block */
+
+ /* Check arguments */
+ HDassert(hdr);
+ HDassert(nelmts > 0);
+
+ /* Allocate memory for the data block */
+ if(NULL == (dblock = H5FL_CALLOC(H5FA_dblock_t)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array data block")
+
+ /* Share common array information */
+ if(H5FA__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->dblk_page_nelmts = (size_t)1 << hdr->cparam.max_dblk_page_nelmts_bits;
+
+ /* Check if this data block should be paged */
+ if(nelmts > dblock->dblk_page_nelmts) {
+ /* Compute number of pages */
+ hsize_t npages = ((nelmts + dblock->dblk_page_nelmts) - 1) / dblock->dblk_page_nelmts;
+
+ /* Safely assign the number of pages */
+ H5_ASSIGN_OVERFLOW(/* To: */ dblock->npages, /* From: */ npages, /* From: */ hsize_t, /* To: */ size_t);
+
+ /* Sanity check that we have at least 1 page */
+ HDassert(dblock->npages > 0);
+
+ /* Compute size of 'page init' flag array, in bytes */
+ dblock->dblk_page_init_size = (dblock->npages + 7) / 8;
+ HDassert(dblock->dblk_page_init_size > 0);
+
+ /* Allocate space for 'page init' flags */
+ if(NULL == (dblock->dblk_page_init = H5FL_BLK_CALLOC(fa_page_init, dblock->dblk_page_init_size)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for page init bitmask")
+
+ /* Compute data block page size */
+ dblock->dblk_page_size = (dblock->dblk_page_nelmts * hdr->cparam.raw_elmt_size) + H5FA_SIZEOF_CHKSUM;
+
+ /* Compute the # of elements on last page */
+ if(0 == nelmts % dblock->dblk_page_nelmts)
+ dblock->last_page_nelmts = dblock->dblk_page_nelmts;
+ else
+ dblock->last_page_nelmts = (size_t)(nelmts % dblock->dblk_page_nelmts);
+ } /* end if */
+ else {
+ hsize_t dblk_size = hdr->cparam.nelmts * hdr->cparam.cls->nat_elmt_size;
+
+ /* Allocate buffer for elements in data block */
+ H5_CHECK_OVERFLOW(dblk_size, /* From: */hsize_t, /* To: */size_t);
+ if(NULL == (dblock->elmts = H5FL_BLK_MALLOC(chunk_elmts, (size_t)dblk_size)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for data block element buffer")
+ } /* end else */
+
+ /* Set the return value */
+ ret_value = dblock;
+
+CATCH
+
+ if(!ret_value)
+ if(dblock && H5FA__dblock_dest(hdr->f, dblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block")
+
+END_FUNC(PKG) /* end H5FA__dblock_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__dblock_create
+ *
+ * Purpose: Creates a fixed array data block in the file
+ *
+ * Return: Valid file address on success/HADDR_UNDEF on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+haddr_t, HADDR_UNDEF, HADDR_UNDEF,
+H5FA__dblock_create(H5FA_hdr_t *hdr, hid_t dxpl_id, hbool_t *hdr_dirty,
+ hsize_t nelmts))
+
+ /* Local variables */
+ H5FA_dblock_t *dblock = NULL; /* fixed array data block */
+ haddr_t dblock_addr; /* fixed array data block address */
+
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: Called, hdr->stats.nelmts = %Zu, nelmts = %Zu\n", FUNC, hdr->stats.nelmts, nelmts);
+#endif /* H5FA_DEBUG */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(hdr_dirty);
+ HDassert(nelmts > 0);
+
+ /* Allocate the data block */
+ if(NULL == (dblock = H5FA__dblock_alloc(hdr, nelmts)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array data block")
+
+ /* Set size of data block on disk */
+ hdr->stats.dblk_size = dblock->size = H5FA_DBLOCK_SIZE(dblock);
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: dblock->size = %Zu\n", FUNC, dblock->size);
+#endif /* H5FA_DEBUG */
+
+
+ /* Allocate space for the data block on disk */
+ if(HADDR_UNDEF == (dblock_addr = H5MF_alloc(hdr->f, H5FD_MEM_FARRAY_DBLOCK, dxpl_id, (hsize_t)dblock->size)))
+ H5E_THROW(H5E_CANTALLOC, "file allocation failed for fixed array data block")
+ dblock->addr = dblock_addr;
+
+ /* 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)hdr->cparam.nelmts) < 0)
+ H5E_THROW(H5E_CANTSET, "can't set fixed array data block elements to class's fill value")
+
+ /* Cache the new fixed array data block */
+ if(H5AC_set(hdr->f, dxpl_id, H5AC_FARRAY_DBLOCK, dblock_addr, dblock, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTINSERT, "can't add fixed array data block to cache")
+
+ /* Mark the header dirty (for updating statistics) */
+ *hdr_dirty = TRUE;
+
+ /* Set address of data block to return */
+ ret_value = dblock_addr;
+
+CATCH
+
+ if(!H5F_addr_defined(ret_value))
+ if(dblock) {
+ /* Release data block's disk space */
+ if(H5F_addr_defined(dblock->addr) && H5MF_xfree(hdr->f, H5FD_MEM_FARRAY_DBLOCK, dxpl_id, dblock->addr, (hsize_t)dblock->size) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to release fixed array data block")
+
+ /* Destroy data block */
+ if(H5FA__dblock_dest(hdr->f, dblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block")
+ } /* end if */
+
+END_FUNC(PKG) /* end H5FA__dblock_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__dblock_protect
+ *
+ * Purpose: Convenience wrapper around protecting fixed array data block
+ *
+ * Return: Non-NULL pointer to data block on success/NULL on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+H5FA_dblock_t *, NULL, NULL,
+H5FA__dblock_protect(H5FA_hdr_t *hdr, hid_t dxpl_id, haddr_t dblk_addr,
+ hsize_t dblk_nelmts, H5AC_protect_t rw))
+
+ /* Local variables */
+
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* H5FA_DEBUG */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(H5F_addr_defined(dblk_addr));
+ HDassert(dblk_nelmts);
+
+ /* Protect the data block */
+ if(NULL == (ret_value = (H5FA_dblock_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_FARRAY_DBLOCK, dblk_addr, &dblk_nelmts, hdr, rw)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block, address = %llu", (unsigned long long)dblk_addr)
+
+CATCH
+
+END_FUNC(PKG) /* end H5FA__dblock_protect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__dblock_unprotect
+ *
+ * Purpose: Convenience wrapper around unprotecting fixed array data block
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__dblock_unprotect(H5FA_dblock_t *dblock, hid_t dxpl_id, unsigned cache_flags))
+
+ /* Local variables */
+
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* H5FA_DEBUG */
+
+ /* Sanity check */
+ HDassert(dblock);
+
+ /* Unprotect the data block */
+ if(H5AC_unprotect(dblock->hdr->f, dxpl_id, H5AC_FARRAY_DBLOCK, dblock->addr, dblock, cache_flags) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to unprotect fixed array data block, address = %llu", (unsigned long long)dblock->addr)
+
+CATCH
+
+END_FUNC(PKG) /* end H5FA__dblock_unprotect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__dblock_delete
+ *
+ * Purpose: Delete a data block
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__dblock_delete(H5FA_hdr_t *hdr, hid_t dxpl_id, haddr_t dblk_addr,
+ hsize_t dblk_nelmts))
+
+ /* Local variables */
+ H5FA_dblock_t *dblock = NULL; /* Pointer to data block */
+
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* H5FA_DEBUG */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(H5F_addr_defined(dblk_addr));
+ HDassert(dblk_nelmts > 0);
+
+ /* Protect data block */
+ if(NULL == (dblock = H5FA__dblock_protect(hdr, dxpl_id, dblk_addr, dblk_nelmts, H5AC_WRITE)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block, address = %llu", (unsigned long long)dblk_addr)
+
+ /* Check if data block is paged */
+ if(dblock->npages) {
+ haddr_t dblk_page_addr; /* Address of each data block page */
+ size_t u; /* Local index variable */
+
+ /* Set up initial state */
+ dblk_page_addr = dblk_addr + H5FA_DBLOCK_PREFIX_SIZE(dblock);
+
+ /* Iterate over pages in data block */
+ for(u = 0; u < dblock->npages; u++) {
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: Expunging data block page from cache\n", FUNC);
+#endif /* H5FA_DEBUG */
+ /* 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_FARRAY_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 H5FA_DEBUG
+HDfprintf(stderr, "%s: Done expunging data block page from cache\n", FUNC);
+#endif /* H5FA_DEBUG */
+
+ /* Advance to next page address */
+ dblk_page_addr += dblock->dblk_page_size;
+ } /* end for */
+ } /* end if */
+
+CATCH
+
+ /* Finished deleting data block in metadata cache */
+ if(dblock && H5FA__dblock_unprotect(dblock, dxpl_id, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array data block")
+
+END_FUNC(PKG) /* end H5FA__dblock_delete() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__dblock_dest
+ *
+ * Purpose: Destroys a fixed array data block in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__dblock_dest(H5F_t UNUSED *f, H5FA_dblock_t *dblock))
+
+ /* Sanity check */
+ HDassert(dblock);
+
+ /* 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->hdr->cparam.nelmts > 0);
+ (void) H5FL_BLK_FREE(chunk_elmts, dblock->elmts);
+ dblock->elmts = NULL;
+ } /* end if */
+
+ /* Check if data block is paged */
+ if(dblock->npages) {
+ /* Free buffer for 'page init' bitmask, if there is one */
+ HDassert(dblock->dblk_page_init_size > 0);
+ if(dblock->dblk_page_init)
+ dblock->dblk_page_init = H5FL_BLK_FREE(fa_page_init, dblock->dblk_page_init);
+ } /* end if */
+
+ /* Decrement reference count on shared info */
+ if(H5FA__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(H5FA_dblock_t, dblock);
+
+CATCH
+
+END_FUNC(PKG) /* end H5FA__dblock_dest() */
+
diff --git a/src/H5FAhdr.c b/src/H5FAhdr.c
new file mode 100644
index 0000000..94fb7b2
--- /dev/null
+++ b/src/H5FAhdr.c
@@ -0,0 +1,488 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5FAhdr.c
+ *
+ * Purpose: Array header routines for Fixed Array.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/**********************/
+/* Module Declaration */
+/**********************/
+
+#define H5FA_MODULE
+
+
+/***********************/
+/* Other Packages Used */
+/***********************/
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FApkg.h" /* Fixed 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 H5FA_hdr_t struct */
+H5FL_DEFINE_STATIC(H5FA_hdr_t);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__hdr_alloc
+ *
+ * Purpose: Allocate shared Fixed Array header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+H5FA_hdr_t *, NULL, NULL,
+H5FA__hdr_alloc(H5F_t *f))
+
+ /* Local variables */
+ H5FA_hdr_t *hdr = NULL; /* Shared Fixed Array header */
+
+ /* Check arguments */
+ HDassert(f);
+
+ /* Allocate space for the shared information */
+ if(NULL == (hdr = H5FL_CALLOC(H5FA_hdr_t)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for Fixed Array shared header")
+
+ /* Set non-zero internal fields */
+ hdr->addr = HADDR_UNDEF;
+
+ /* 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 return value */
+ ret_value = hdr;
+
+CATCH
+ if(!ret_value)
+ if(hdr && H5FA__hdr_dest(hdr) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array header")
+
+END_FUNC(PKG) /* end H5FA__hdr_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__hdr_init
+ *
+ * Purpose: Initialize shared fixed array header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, November 15, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__hdr_init(H5FA_hdr_t *hdr, void *ctx_udata))
+
+ /* Local variables */
+
+ /* Check arguments */
+ HDassert(hdr);
+
+ /* Set size of header on disk (locally and in statistics) */
+ hdr->stats.hdr_size = hdr->size = H5FA_HEADER_SIZE(hdr);
+
+ /* Set number of elements for Fixed Array in statistics */
+ hdr->stats.nelmts = hdr->cparam.nelmts;
+
+ /* Create the callback context, if there's one */
+ if(hdr->cparam.cls->crt_context) {
+ if(NULL == (hdr->cb_ctx = (*hdr->cparam.cls->crt_context)(ctx_udata)))
+ H5E_THROW(H5E_CANTCREATE, "unable to create fixed array client callback context")
+ } /* end if */
+
+CATCH
+
+END_FUNC(PKG) /* end H5FA__hdr_init() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__hdr_create
+ *
+ * Purpose: Creates a new Fixed Array header in the file
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+haddr_t, HADDR_UNDEF, HADDR_UNDEF,
+H5FA__hdr_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam,
+ void *ctx_udata))
+
+ /* Local variables */
+ H5FA_hdr_t *hdr = NULL; /* Fixed array header */
+
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* H5FA_DEBUG */
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(cparam);
+
+#ifndef NDEBUG
+{
+ /* Check for valid parameters */
+ if(cparam->raw_elmt_size == 0)
+ H5E_THROW(H5E_BADVALUE, "element size must be greater than zero")
+ if(cparam->max_dblk_page_nelmts_bits == 0)
+ H5E_THROW(H5E_BADVALUE, "max. # of elements bits must be greater than zero")
+ if(cparam->nelmts == 0)
+ H5E_THROW(H5E_BADVALUE, "# of elements must be greater than zero")
+}
+#endif /* NDEBUG */
+
+ /* Allocate space for the shared information */
+ if(NULL == (hdr = H5FA__hdr_alloc(f)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for Fixed Array shared header")
+
+ hdr->dblk_addr = HADDR_UNDEF;
+
+ /* Set the creation parameters for the array */
+ HDmemcpy(&hdr->cparam, cparam, sizeof(hdr->cparam));
+
+ /* Finish initializing fixed array header */
+ if(H5FA__hdr_init(hdr, ctx_udata) < 0)
+ H5E_THROW(H5E_CANTINIT, "initialization failed for fixed array header")
+
+ /* Allocate space for the header on disk */
+ if(HADDR_UNDEF == (hdr->addr = H5MF_alloc(f, H5FD_MEM_FARRAY_HDR, dxpl_id, (hsize_t)hdr->size)))
+ H5E_THROW(H5E_CANTALLOC, "file allocation failed for Fixed Array header")
+
+ /* Cache the new Fixed Array header */
+ if(H5AC_set(f, dxpl_id, H5AC_FARRAY_HDR, hdr->addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTINSERT, "can't add fixed array header to cache")
+
+ /* Set address of array header to return */
+ ret_value = hdr->addr;
+
+CATCH
+ if(!H5F_addr_defined(ret_value))
+ if(hdr) {
+ /* Release header's disk space */
+ if(H5F_addr_defined(hdr->addr) && H5MF_xfree(f, H5FD_MEM_FARRAY_HDR, dxpl_id, hdr->addr, (hsize_t)hdr->size) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to free Fixed Array header")
+
+ /* Destroy header */
+ if(H5FA__hdr_dest(hdr) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy Fixed Array header")
+ } /* end if */
+
+END_FUNC(PKG) /* end H5FA__hdr_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__hdr_incr
+ *
+ * Purpose: Increment component reference count on shared array header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__hdr_incr(H5FA_hdr_t *hdr))
+
+ /* Sanity check */
+ HDassert(hdr);
+
+ /* Mark header as un-evictable when something is depending on it */
+ if(hdr->rc == 0)
+ if(H5AC_pin_protected_entry(hdr->f, hdr) < 0)
+ H5E_THROW(H5E_CANTPIN, "unable to pin fixed array header")
+
+ /* Increment reference count on shared header */
+ hdr->rc++;
+
+CATCH
+
+END_FUNC(PKG) /* end H5FA__hdr_incr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__hdr_decr
+ *
+ * Purpose: Decrement component reference count on shared array header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__hdr_decr(H5FA_hdr_t *hdr))
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(hdr->rc);
+
+ /* Decrement reference count on shared header */
+ hdr->rc--;
+
+ /* Mark header as evictable again when nothing depend on it */
+ if(hdr->rc == 0) {
+ HDassert(hdr->file_rc == 0);
+ if(H5AC_unpin_entry(hdr->f, hdr) < 0)
+ H5E_THROW(H5E_CANTUNPIN, "unable to unpin fixed array header")
+ } /* end if */
+
+CATCH
+
+END_FUNC(PKG) /* end H5FA__hdr_decr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__hdr_fuse_incr
+ *
+ * Purpose: Increment file reference count on shared array header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, NOERR,
+herr_t, SUCCEED, -,
+H5FA__hdr_fuse_incr(H5FA_hdr_t *hdr))
+
+ /* Sanity check */
+ HDassert(hdr);
+
+ /* Increment file reference count on shared header */
+ hdr->file_rc++;
+
+END_FUNC(PKG) /* end H5FA__hdr_fuse_incr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__hdr_fuse_decr
+ *
+ * Purpose: Decrement file reference count on shared array header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, NOERR,
+size_t, 0, -,
+H5FA__hdr_fuse_decr(H5FA_hdr_t *hdr))
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(hdr->file_rc);
+
+ /* Decrement file reference count on shared header */
+ hdr->file_rc--;
+
+ /* Set return value */
+ ret_value = hdr->file_rc;
+
+END_FUNC(PKG) /* end H5FA__hdr_fuse_decr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__hdr_modified
+ *
+ * Purpose: Mark a fixed array as modified
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__hdr_modified(H5FA_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 fixed array header as dirty")
+
+CATCH
+
+END_FUNC(PKG) /* end H5FA__hdr_modified() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__hdr_delete
+ *
+ * Purpose: Delete a fixed array, starting with the header
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__hdr_delete(H5FA_hdr_t *hdr, hid_t dxpl_id))
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(!hdr->file_rc);
+
+#ifndef NDEBUG
+{
+ unsigned hdr_status = 0; /* Array header's status in the metadata cache */
+
+ /* Check the array header's status in the metadata cache */
+ if(H5AC_get_entry_status(hdr->f, hdr->addr, &hdr_status) < 0)
+ H5E_THROW(H5E_CANTGET, "unable to check metadata cache status for array header")
+
+ /* Sanity checks on array header */
+ HDassert(hdr_status & H5AC_ES__IN_CACHE);
+ HDassert(hdr_status & H5AC_ES__IS_PROTECTED);
+} /* end block */
+#endif /* NDEBUG */
+
+ /* Check for Fixed Array Data block */
+ if(H5F_addr_defined(hdr->dblk_addr)) {
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: hdr->dblk_addr = %a\n", FUNC, hdr->dblk_addr);
+#endif /* H5FA_DEBUG */
+
+ /* Delete Fixed Array Data block */
+ if(H5FA__dblock_delete(hdr, dxpl_id, hdr->dblk_addr, hdr->cparam.nelmts) < 0)
+ H5E_THROW(H5E_CANTDELETE, "unable to delete fixed array data block")
+ } /* end if */
+
+ /* Finished deleting header */
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FARRAY_HDR, hdr->addr, hdr, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array header")
+ hdr = NULL;
+
+CATCH
+
+ /* Unprotect the header, if an error occurred */
+ if(hdr && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FARRAY_HDR, hdr->addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array header")
+
+END_FUNC(PKG) /* end H5FA__hdr_delete() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__hdr_dest
+ *
+ * Purpose: Destroys a fixed array header in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5FA__hdr_dest(H5FA_hdr_t *hdr))
+
+ /* Check arguments */
+ HDassert(hdr);
+ HDassert(hdr->rc == 0);
+
+ /* Destroy the callback context */
+ if(hdr->cb_ctx) {
+ if((*hdr->cparam.cls->dst_context)(hdr->cb_ctx) < 0)
+ H5E_THROW(H5E_CANTRELEASE, "unable to destroy fixed array client callback context")
+ } /* end if */
+ hdr->cb_ctx = NULL;
+
+ /* Free the shared info itself */
+ hdr = H5FL_FREE(H5FA_hdr_t, hdr);
+
+CATCH
+
+END_FUNC(PKG) /* end H5FA__hdr_dest() */
+
diff --git a/src/H5FApkg.h b/src/H5FApkg.h
new file mode 100644
index 0000000..c817b1a
--- /dev/null
+++ b/src/H5FApkg.h
@@ -0,0 +1,289 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer:
+ *
+ * Purpose: This file contains declarations which are visible only within
+ * the H5FA package. Source files outside the H5FA package should
+ * include H5FAprivate.h instead.
+ */
+#if !(defined(H5FA_PACKAGE) | defined(H5FA_MODULE))
+#error "Do not include this file outside the H5FA package!"
+#endif
+
+#ifndef _H5FApkg_H
+#define _H5FApkg_H
+
+/* Get package's private header */
+#include "H5FAprivate.h"
+
+/* Other private headers needed by this file */
+#include "H5ACprivate.h" /* Metadata cache */
+#include "H5FLprivate.h" /* Free Lists */
+
+
+/**************************/
+/* Package Private Macros */
+/**************************/
+
+/* Define this to display debugging information for the Fixed Array layer */
+/* #define H5FA_DEBUG */
+
+
+/* If this package header is being included in one of the H5FA modules, define
+ * the proper control macros for the generic FUNC_ENTER/LEAVE and error
+ * reporting macros.
+ */
+#ifdef H5FA_MODULE
+#define H5_MY_PKG H5FA
+#define H5_MY_PKG_ERR H5E_FARRAY
+#define H5_MY_PKG_INIT NO
+#endif /* H5FA_MODULE */
+
+/* Fill value for fixed array test class */
+#ifdef H5FA_TESTING
+#define H5FA_TEST_FILL ((uint64_t)ULLONG_MAX)
+#endif /* H5FA_TESTING */
+
+/* Size of checksum information (on disk) */
+#define H5FA_SIZEOF_CHKSUM 4
+
+/* "Standard" size of prefix information for fixed array metadata */
+#define H5FA_METADATA_PREFIX_SIZE(c) ( \
+ H5_SIZEOF_MAGIC /* Signature */ \
+ + 1 /* Version */ \
+ + ((c) ? H5FA_SIZEOF_CHKSUM : 0) /* Metadata checksum */ \
+ )
+
+/* Size of the Fixed Array header on disk */
+#define H5FA_HEADER_SIZE(h) ( \
+ /* General metadata fields */ \
+ H5FA_METADATA_PREFIX_SIZE(TRUE) \
+ \
+ /* General array information */ \
+ + 1 /* Array type */ \
+ + 1 /* Element Size */ \
+ + 1 /* Log2(Max. # of elements in data block page) - i.e. # of bits needed to store max. # of elements in data block page */ \
+ \
+ /* Fixed Array statistics fields */ \
+ + (h)->sizeof_size /* # of elements in the fixed array */ \
+ \
+ /* Fixed Array Header specific fields */ \
+ + (h)->sizeof_addr /* File address of Fixed Array data block */ \
+ )
+
+/* Size of the Fixed Array data block prefix on disk */
+#define H5FA_DBLOCK_PREFIX_SIZE(d) ( \
+ /* General metadata fields */ \
+ H5FA_METADATA_PREFIX_SIZE(TRUE) \
+ \
+ /* Sanity-checking fields */ \
+ + (d)->hdr->sizeof_addr /* File address of Fixed Array header owning the data block */ \
+ + 1 /* Array type */ \
+ \
+ /* Fixed Array Data Block specific fields */ \
+ + (d)->dblk_page_init_size /* Fixed array data block 'page init' bitmasks (can be 0 if no pages) */ \
+ )
+
+/* Size of the Fixed Array data block on disk */
+#define H5FA_DBLOCK_SIZE(d) ( \
+ /* Data block prefix size */ \
+ H5FA_DBLOCK_PREFIX_SIZE(d) \
+ \
+ /* Fixed Array Elements|Pages of Elements*/ \
+ + ((d)->hdr->cparam.nelmts * (size_t)(d)->hdr->cparam.raw_elmt_size) \
+ + ((d)->npages * H5FA_SIZEOF_CHKSUM) /* Checksum */ \
+ )
+
+/* Size of the Fixed Array data block page on disk */
+#define H5FA_DBLK_PAGE_SIZE(d, nelmts) ( \
+ /* Fixed Array Data Block Page */ \
+ + (nelmts * (size_t)(d)->hdr->cparam.raw_elmt_size) /* Elements in data block page */ \
+ + H5FA_SIZEOF_CHKSUM /* Checksum for each page */ \
+ )
+
+/****************************/
+/* Package Private Typedefs */
+/****************************/
+
+/* The Fixed Array header information */
+typedef struct H5FA_hdr_t {
+ /* Information for H5AC cache functions, _must_ be first field in structure */
+ H5AC_info_t cache_info;
+
+ /* Fixed array configuration/creation parameters (stored in header) */
+ H5FA_create_t cparam; /* Creation parameters for Fixed Array */
+
+ /* Fixed Array data block information (stored in header) */
+ haddr_t dblk_addr; /* Address of Fixed Array Data block */
+
+ /* Statistics for Fixed Array (stored in header) */
+ H5FA_stat_t stats; /* Statistcs for Fixed Array */
+
+ /* Computed/cached values (not stored in header) */
+ size_t rc; /* Reference count of the header */
+ haddr_t addr; /* Address of header in file */
+ size_t size; /* Size of header in file */
+ H5F_t *f; /* Pointer to file for fixed 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 */
+
+ /* Client information (not stored) */
+ void *cb_ctx; /* Callback context */
+} H5FA_hdr_t;
+
+/* The fixed array data block information */
+typedef struct H5FA_dblock_t {
+ /* Information for H5AC cache functions, _must_ be first field in structure */
+ H5AC_info_t cache_info;
+
+ /* Fixed array information (stored) */
+ uint8_t *dblk_page_init;/* Bitmap of whether a data block page is initialized */
+ void *elmts; /* Buffer for elements stored in data block */
+
+ /* Internal array information (not stored) */
+ H5FA_hdr_t *hdr; /* Shared array header info */
+
+ /* Computed/cached values (not stored) */
+ haddr_t addr; /* Address of this data block on disk */
+ hsize_t size; /* Size of data block on disk */
+ size_t npages; /* Nummber of pages in data block (zero if not paged) */
+ size_t last_page_nelmts; /* Nummber of elements in last page, if paged */
+
+ /* Fixed Array data block information (not stored) */
+ size_t dblk_page_nelmts; /* # of elements per data block page */
+ size_t dblk_page_size; /* Size of a data block page */
+ size_t dblk_page_init_size; /* Size of 'page init' bitmask */
+} H5FA_dblock_t;
+
+/* The fixed array data block page information */
+typedef struct H5FA_dbk_page_t {
+ /* Information for H5AC cache functions, _must_ be first field in structure */
+ H5AC_info_t cache_info;
+
+ /* Fixed array information (stored) */
+ void *elmts; /* Buffer for elements stored in data block page */
+
+ /* Internal array information (not stored) */
+ H5FA_hdr_t *hdr; /* Shared array header info */
+
+ /* Computed/cached values (not stored) */
+ haddr_t addr; /* Address of this data block page on disk */
+ size_t size; /* Size of data block page on disk */
+ size_t nelmts; /* Number of elements in data block page */
+} H5FA_dblk_page_t;
+
+/* Fixed array */
+struct H5FA_t {
+ H5FA_hdr_t *hdr; /* Pointer to internal fixed array header info */
+ H5F_t *f; /* Pointer to file for fixed array */
+};
+
+
+/* Metadata cache callback user data types */
+
+/* Info needed for loading data block page */
+typedef struct H5FA_dblk_page_load_ud_t {
+ size_t nelmts; /* Number of elements in data block page */
+} H5FA_dblk_page_load_ud_t;
+
+
+/*****************************/
+/* Package Private Variables */
+/*****************************/
+
+/* H5FA header inherits cache-like properties from H5AC */
+H5_DLLVAR const H5AC_class_t H5AC_FARRAY_HDR[1];
+
+/* H5FA data block inherits cache-like properties from H5AC */
+H5_DLLVAR const H5AC_class_t H5AC_FARRAY_DBLOCK[1];
+
+/* H5FA data block page inherits cache-like properties from H5AC */
+H5_DLLVAR const H5AC_class_t H5AC_FARRAY_DBLK_PAGE[1];
+
+
+/* The Fixed Array class for dataset chunks w/o filters*/
+H5_DLLVAR const H5FA_class_t H5FA_CLS_CHUNK[1];
+
+/* The Fixed Array class for dataset chunks w/ filters*/
+H5_DLLVAR const H5FA_class_t H5FA_CLS_FILT_CHUNK[1];
+
+/* Internal fixed array testing class */
+#ifdef H5FA_TESTING
+H5_DLLVAR const H5FA_class_t H5FA_CLS_TEST[1];
+#endif /* H5FA_TESTING */
+
+/* Array of fixed array client ID -> client class mappings */
+extern const H5FA_class_t *const H5FA_client_class_g[];
+
+
+/******************************/
+/* Package Private Prototypes */
+/******************************/
+
+/* Header routines */
+H5_DLL H5FA_hdr_t *H5FA__hdr_alloc(H5F_t *f);
+H5_DLL herr_t H5FA__hdr_init(H5FA_hdr_t *hdr, void *ctx_udata);
+H5_DLL haddr_t H5FA__hdr_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam, void *ctx_udata);
+H5_DLL void *H5FA__hdr_alloc_elmts(H5FA_hdr_t *hdr, size_t nelmts);
+H5_DLL herr_t H5FA__hdr_free_elmts(H5FA_hdr_t *hdr, size_t nelmts, void *elmts);
+H5_DLL herr_t H5FA__hdr_incr(H5FA_hdr_t *hdr);
+H5_DLL herr_t H5FA__hdr_decr(H5FA_hdr_t *hdr);
+H5_DLL herr_t H5FA__hdr_fuse_incr(H5FA_hdr_t *hdr);
+H5_DLL size_t H5FA__hdr_fuse_decr(H5FA_hdr_t *hdr);
+H5_DLL herr_t H5FA__hdr_modified(H5FA_hdr_t *hdr);
+H5_DLL herr_t H5FA__hdr_delete(H5FA_hdr_t *hdr, hid_t dxpl_id);
+H5_DLL herr_t H5FA__hdr_dest(H5FA_hdr_t *hdr);
+
+/* Data block routines */
+H5_DLL H5FA_dblock_t *H5FA__dblock_alloc(H5FA_hdr_t *hdr, hsize_t nelmts);
+H5_DLL haddr_t H5FA__dblock_create(H5FA_hdr_t *hdr, hid_t dxpl_id, hbool_t *hdr_dirty, hsize_t nelmts);
+H5_DLL unsigned H5FA__dblock_sblk_idx(const H5FA_hdr_t *hdr, hsize_t idx);
+H5_DLL H5FA_dblock_t *H5FA__dblock_protect(H5FA_hdr_t *hdr, hid_t dxpl_id,
+ haddr_t dblk_addr, hsize_t dblk_nelmts, H5AC_protect_t rw);
+H5_DLL herr_t H5FA__dblock_unprotect(H5FA_dblock_t *dblock, hid_t dxpl_id,
+ unsigned cache_flags);
+H5_DLL herr_t H5FA__dblock_delete(H5FA_hdr_t *hdr, hid_t dxpl_id,
+ haddr_t dblk_addr, hsize_t dblk_nelmts);
+H5_DLL herr_t H5FA__dblock_dest(H5F_t *f, H5FA_dblock_t *dblock);
+
+/* Data block page routines */
+H5_DLL herr_t H5FA__dblk_page_create(H5FA_hdr_t *hdr, hid_t dxpl_id,
+ haddr_t addr, size_t nelmts);
+H5_DLL H5FA_dblk_page_t *H5FA__dblk_page_alloc(H5FA_hdr_t *hdr, size_t nelmts);
+H5_DLL H5FA_dblk_page_t *H5FA__dblk_page_protect(H5FA_hdr_t *hdr, hid_t dxpl_id,
+ haddr_t dblk_page_addr, size_t dblk_page_nelmts, H5AC_protect_t rw);
+H5_DLL herr_t H5FA__dblk_page_unprotect(H5FA_dblk_page_t *dblk_page,
+ hid_t dxpl_id, unsigned cache_flags);
+H5_DLL herr_t H5FA__dblk_page_dest(H5FA_dblk_page_t *dblk_page);
+
+/* Debugging routines for dumping file structures */
+H5_DLL herr_t H5FA__hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ FILE *stream, int indent, int fwidth, const H5FA_class_t *cls, haddr_t obj_addr);
+H5_DLL herr_t H5FA__dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ FILE *stream, int indent, int fwidth, const H5FA_class_t *cls,
+ haddr_t hdr_addr, haddr_t obj_addr);
+
+/* Testing routines */
+#ifdef H5FA_TESTING
+H5_DLL herr_t H5FA_get_cparam_test(const H5FA_t *ea, H5FA_create_t *cparam);
+H5_DLL int H5FA_cmp_cparam_test(const H5FA_create_t *cparam1, const H5FA_create_t *cparam2);
+#endif /* H5FA_TESTING */
+
+#endif /* _H5FApkg_H */
+
diff --git a/src/H5FAprivate.h b/src/H5FAprivate.h
new file mode 100644
index 0000000..1a5a6a0
--- /dev/null
+++ b/src/H5FAprivate.h
@@ -0,0 +1,131 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5FAprivate.h
+ *
+ * Purpose: Private header for library accessible Fixed
+ * Array routines.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef _H5FAprivate_H
+#define _H5FAprivate_H
+
+/* Include package's public header */
+#ifdef NOT_YET
+#include "H5FApublic.h"
+#endif /* NOT_YET */
+
+/* Private headers needed by this file */
+#include "H5Fprivate.h" /* File access */
+
+
+/**************************/
+/* Library Private Macros */
+/**************************/
+
+
+/****************************/
+/* Library Private Typedefs */
+/****************************/
+
+/* Fixed Array class IDs */
+typedef enum H5FA_cls_id_t {
+ /* Start real class IDs at 0 -QAK */
+ /* (keep these last) */
+ H5FA_CLS_TEST_ID, /* Fixed array is for testing (do not use for actual data) */
+ H5FA_NUM_CLS_ID /* Number of Fixed Array class IDs (must be last) */
+} H5FA_cls_id_t;
+
+/*
+ * Each type of element that can be stored in a Fixed Array has a
+ * variable of this type that contains class variables and methods.
+ */
+typedef struct H5FA_class_t {
+ H5FA_cls_id_t id; /* ID of Fixed Array class, as found in file */
+ const char *name; /* Name of class (for debugging) */
+ size_t nat_elmt_size; /* Size of native (memory) element */
+
+ /* Fixed array client callback methods */
+ void *(*crt_context)(void *udata); /* Create context for other callbacks */
+ herr_t (*dst_context)(void *ctx); /* Destroy context */
+ 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, void *ctx); /* Encode elements from native form to disk storage form */
+ herr_t (*decode)(const void *raw, void *elmt, size_t nelmts, void *ctx); /* Decode elements from disk storage form to native form */
+ herr_t (*debug)(FILE *stream, int indent, int fwidth, hsize_t idx, const void *elmt); /* Print an element for debugging */
+ void *(*crt_dbg_ctx)(H5F_t *f, hid_t dxpl_id, haddr_t obj_addr); /* Create debugging context */
+ herr_t (*dst_dbg_ctx)(void *dbg_ctx); /* Destroy debugging context */
+} H5FA_class_t;
+
+/* Fixed array creation parameters */
+typedef struct H5FA_create_t {
+ const H5FA_class_t *cls; /* Class of Fixed Array to create */
+ uint8_t raw_elmt_size; /* Element size in file (in bytes) */
+ uint8_t max_dblk_page_nelmts_bits; /* Log2(Max. # of elements in a data block page) -
+ i.e. # of bits needed to store max. # of elements
+ in a data block page */
+ hsize_t nelmts; /* # of elements in array */
+} H5FA_create_t;
+
+/* Fixed array metadata statistics info */
+typedef struct H5FA_stat_t {
+ /* Non-stored (i.e. computed) fields */
+ hsize_t hdr_size; /* Size of header */
+ hsize_t dblk_size; /* Size of data block */
+
+ /* Stored fields */
+ hsize_t nelmts; /* # of elements */
+} H5FA_stat_t;
+
+/* Fixed Array info (forward decl - defined in H5FApkg.h) */
+typedef struct H5FA_t H5FA_t;
+
+/* Define the operator callback function pointer for H5FA_iterate() */
+typedef int (*H5FA_operator_t)(hsize_t idx, const void *_elmt, void *_udata);
+
+
+/*****************************/
+/* Library-private Variables */
+/*****************************/
+
+
+/***************************************/
+/* Library-private Function Prototypes */
+/***************************************/
+
+/* General routines */
+H5_DLL H5FA_t *H5FA_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam,
+ void *ctx_udata);
+H5_DLL H5FA_t *H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata);
+H5_DLL herr_t H5FA_get_nelmts(const H5FA_t *ea, hsize_t *nelmts);
+H5_DLL herr_t H5FA_get_addr(const H5FA_t *ea, haddr_t *addr);
+H5_DLL herr_t H5FA_set(const H5FA_t *ea, hid_t dxpl_id, hsize_t idx, const void *elmt);
+H5_DLL herr_t H5FA_get(const H5FA_t *ea, hid_t dxpl_id, hsize_t idx, void *elmt);
+H5_DLL herr_t H5FA_iterate(H5FA_t *fa, hid_t dxpl_id, H5FA_operator_t op, void *udata);
+H5_DLL herr_t H5FA_close(H5FA_t *ea, hid_t dxpl_id);
+H5_DLL herr_t H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata);
+
+/* Statistics routines */
+H5_DLL herr_t H5FA_get_stats(const H5FA_t *ea, H5FA_stat_t *stats);
+
+/* Debugging routines */
+#ifdef H5FA_DEBUGGING
+#endif /* H5FA_DEBUGGING */
+
+#endif /* _H5FAprivate_H */
+
diff --git a/src/H5FAstat.c b/src/H5FAstat.c
new file mode 100644
index 0000000..bed6c6e
--- /dev/null
+++ b/src/H5FAstat.c
@@ -0,0 +1,113 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5FAstat.c
+ *
+ * Purpose: Fixed array metadata statistics functions.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/**********************/
+/* Module Declaration */
+/**********************/
+
+#define H5FA_MODULE
+
+
+/***********************/
+/* Other Packages Used */
+/***********************/
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FApkg.h" /* Fixed Arrays */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA_get_stats
+ *
+ * Purpose: Query the metadata stats of an array
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, NOERR,
+herr_t, SUCCEED, -,
+H5FA_get_stats(const H5FA_t *fa, H5FA_stat_t *stats))
+
+ /* Local variables */
+
+#ifdef H5FA_DEBUG
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* H5FA_DEBUG */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(fa);
+ HDassert(stats);
+
+ /* Copy fixed array statistics */
+ HDmemcpy(stats, &fa->hdr->stats, sizeof(fa->hdr->stats));
+
+END_FUNC(PRIV) /* end H5FA_get_stats() */
+
diff --git a/src/H5FAtest.c b/src/H5FAtest.c
new file mode 100644
index 0000000..187b5be
--- /dev/null
+++ b/src/H5FAtest.c
@@ -0,0 +1,431 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer:
+ *
+ * Purpose: Fixed array testing functions.
+ *
+ */
+
+/**********************/
+/* Module Declaration */
+/**********************/
+
+#define H5FA_MODULE
+#define H5FA_TESTING
+
+
+/***********************/
+/* Other Packages Used */
+/***********************/
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FApkg.h" /* Fixed Arrays */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5Vprivate.h" /* Vector functions */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* Sanity checking value for callback contexts */
+#define H5FA__TEST_BOGUS_VAL 42
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/* Callback context */
+typedef struct H5FA__test_ctx_t {
+ uint32_t bogus; /* Placeholder field to verify that context is working */
+} H5FA__test_ctx_t;
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* Fixed array class callbacks */
+static void *H5FA__test_crt_context(void *udata);
+static herr_t H5FA__test_dst_context(void *ctx);
+static herr_t H5FA__test_fill(void *nat_blk, size_t nelmts);
+static herr_t H5FA__test_encode(void *raw, const void *elmt, size_t nelmts,
+ void *ctx);
+static herr_t H5FA__test_decode(const void *raw, void *elmt, size_t nelmts,
+ void *ctx);
+static herr_t H5FA__test_debug(FILE *stream, int indent, int fwidth,
+ hsize_t idx, const void *elmt);
+static void *H5FA__test_crt_dbg_context(H5F_t *f, hid_t dxpl_id,
+ haddr_t obj_addr);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Fixed array testing class information */
+const H5FA_class_t H5FA_CLS_TEST[1]={{
+ H5FA_CLS_TEST_ID, /* Type of Fixed array */
+ "Testing", /* Name of fixed array class */
+ sizeof(uint64_t), /* Size of native element */
+ H5FA__test_crt_context, /* Create context */
+ H5FA__test_dst_context, /* Destroy context */
+ H5FA__test_fill, /* Fill block of missing elements callback */
+ H5FA__test_encode, /* Element encoding callback */
+ H5FA__test_decode, /* Element decoding callback */
+ H5FA__test_debug, /* Element debugging callback */
+ H5FA__test_crt_dbg_context, /* Create debugging context */
+ H5FA__test_dst_context /* Destroy debugging context */
+}};
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5FA__test_ctx_t struct */
+H5FL_DEFINE_STATIC(H5FA__test_ctx_t);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__test_crt_context
+ *
+ * Purpose: Create context for callbacks
+ *
+ * Return: Success: non-NULL
+ * Failure: NULL
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+void *, NULL, NULL,
+H5FA__test_crt_context(void UNUSED *udata))
+
+ /* Local variables */
+ H5FA__test_ctx_t *ctx; /* Context for callbacks */
+
+ /* Allocate new context structure */
+ if(NULL == (ctx = H5FL_MALLOC(H5FA__test_ctx_t)))
+ H5E_THROW(H5E_CANTALLOC, "can't allocate fixed array client callback context")
+
+ /* Initialize the context */
+ ctx->bogus = H5FA__TEST_BOGUS_VAL;
+
+ /* Set return value */
+ ret_value = ctx;
+
+CATCH
+
+END_FUNC(STATIC) /* end H5FA__test_crt_context() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__test_dst_context
+ *
+ * Purpose: Destroy context for callbacks
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+H5FA__test_dst_context(void *_ctx))
+
+ /* Local variables */
+ H5FA__test_ctx_t *ctx = (H5FA__test_ctx_t *)_ctx; /* Callback context to destroy */
+
+ /* Sanity checks */
+ HDassert(H5FA__TEST_BOGUS_VAL == ctx->bogus);
+
+ /* Release context structure */
+ ctx = H5FL_FREE(H5FA__test_ctx_t, ctx);
+
+END_FUNC(STATIC) /* end H5FA__test_dst_context() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__test_fill
+ *
+ * Purpose: Fill "missing elements" in block of elements
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+H5FA__test_fill(void *nat_blk, size_t nelmts))
+
+ /* Local variables */
+ uint64_t fill_val = H5FA_TEST_FILL; /* Value to fill elements with */
+
+ /* Sanity checks */
+ HDassert(nat_blk);
+ HDassert(nelmts);
+
+ H5V_array_fill(nat_blk, &fill_val, sizeof(uint64_t), nelmts);
+
+END_FUNC(STATIC) /* end H5FA__test_fill() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__test_encode
+ *
+ * Purpose: Encode an element from "native" to "raw" form
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+H5FA__test_encode(void *raw, const void *_elmt, size_t nelmts, void UNUSED *_ctx))
+
+ /* Local variables */
+#ifndef NDEBUG
+ H5FA__test_ctx_t *ctx = (H5FA__test_ctx_t *)_ctx; /* Callback context to destroy */
+#endif /* NDEBUG */
+ const uint64_t *elmt = (const uint64_t *)_elmt; /* Convenience pointer to native elements */
+
+ /* Sanity checks */
+ HDassert(raw);
+ HDassert(elmt);
+ HDassert(nelmts);
+ HDassert(H5FA__TEST_BOGUS_VAL == ctx->bogus);
+
+ /* Encode native elements into raw elements */
+ while(nelmts) {
+ /* Encode element */
+ /* (advances 'raw' pointer) */
+ UINT64ENCODE(raw, *elmt);
+
+ /* Advance native element pointer */
+ elmt++;
+
+ /* Decrement # of elements to encode */
+ nelmts--;
+ } /* end while */
+
+END_FUNC(STATIC) /* end H5FA__test_encode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__test_decode
+ *
+ * Purpose: Decode an element from "raw" to "native" form
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+H5FA__test_decode(const void *_raw, void *_elmt, size_t nelmts, void UNUSED *_ctx))
+
+ /* Local variables */
+#ifndef NDEBUG
+ H5FA__test_ctx_t *ctx = (H5FA__test_ctx_t *)_ctx; /* Callback context to destroy */
+#endif /* NDEBUG */
+ 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);
+ HDassert(H5FA__TEST_BOGUS_VAL == ctx->bogus);
+
+ /* 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 H5FA__test_decode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__test_debug
+ *
+ * Purpose: Display an element for debugging
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+H5FA__test_debug(FILE *stream, int indent, int fwidth, hsize_t idx,
+ const void *elmt))
+
+ /* Local variables */
+ char temp_str[128]; /* Temporary string, for formatting */
+
+ /* Sanity checks */
+ HDassert(stream);
+ HDassert(elmt);
+
+ /* Print element */
+ sprintf(temp_str, "Element #%llu:", (unsigned long long)idx);
+ HDfprintf(stream, "%*s%-*s %llu\n", indent, "", fwidth, temp_str,
+ (unsigned long long)*(const uint64_t *)elmt);
+
+END_FUNC(STATIC) /* end H5FA__test_debug() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA__test_crt_dbg_context
+ *
+ * Purpose: Create context for debugging callback
+ *
+ * Return: Success: non-NULL
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, December 1, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+void *, NULL, NULL,
+H5FA__test_crt_dbg_context(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, haddr_t UNUSED obj_addr))
+
+ /* Local variables */
+ H5FA__test_ctx_t *ctx; /* Context for callbacks */
+
+ /* Allocate new context structure */
+ if(NULL == (ctx = H5FL_MALLOC(H5FA__test_ctx_t)))
+ H5E_THROW(H5E_CANTALLOC, "can't allocate fixed array client callback context")
+
+ /* Initialize the context */
+ ctx->bogus = H5FA__TEST_BOGUS_VAL;
+
+ /* Set return value */
+ ret_value = ctx;
+
+CATCH
+
+END_FUNC(STATIC) /* end H5FA__test_crt_dbg_context() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA_get_cparam_test
+ *
+ * Purpose: Retrieve the parameters used to create the fixed array
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, NOERR,
+herr_t, SUCCEED, -,
+H5FA_get_cparam_test(const H5FA_t *fa, H5FA_create_t *cparam))
+
+ /* Check arguments. */
+ HDassert(fa);
+ HDassert(cparam);
+
+ /* Get fixed array creation parameters */
+ cparam->raw_elmt_size = fa->hdr->cparam.raw_elmt_size;
+ cparam->nelmts = fa->hdr->cparam.nelmts;
+
+END_FUNC(PRIV) /* end H5FA_get_cparam_test() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FA_cmp_cparam_test
+ *
+ * Purpose: Compare the parameters used to create the fixed array
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Vailin Choi
+ * Thursday, April 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERRCATCH,
+int, 0, -,
+H5FA_cmp_cparam_test(const H5FA_create_t *cparam1, const H5FA_create_t *cparam2))
+
+ /* Check arguments. */
+ HDassert(cparam1);
+ HDassert(cparam2);
+
+ /* Compare creation parameters for array */
+ if(cparam1->raw_elmt_size < cparam2->raw_elmt_size)
+ H5_LEAVE(-1)
+ else if(cparam1->raw_elmt_size > cparam2->raw_elmt_size)
+ H5_LEAVE(1)
+
+CATCH
+
+END_FUNC(PRIV) /* end H5FA_cmp_cparam_test() */
+
diff --git a/src/H5FD.c b/src/H5FD.c
index 3ae6d8e..4c0da40 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -62,9 +62,6 @@
/* Local Macros */
/****************/
-/* Metadata accumulator controls */
-#define H5FD_ACCUM_THROTTLE 8
-#define H5FD_ACCUM_THRESHOLD 2048
/******************/
/* Local Typedefs */
@@ -203,14 +200,14 @@ H5FD_term_interface(void)
if(H5_interface_initialize_g) {
if((n=H5I_nmembers(H5I_VFL))!=0) {
- H5I_clear_type(H5I_VFL, FALSE);
+ H5I_clear_type(H5I_VFL, FALSE, FALSE);
/* Reset the VFL drivers, if they've been closed */
if(H5I_nmembers(H5I_VFL)==0) {
H5FD_sec2_term();
-#ifdef H5_HAVE_DIRECT
+#ifdef H5_HAVE_DIRECT
H5FD_direct_term();
-#endif
+#endif
H5FD_log_term();
H5FD_stdio_term();
#ifdef H5_HAVE_WINDOWS
@@ -281,7 +278,7 @@ H5FD_free_cls(H5FD_class_t *cls)
* Monday, July 26, 1999
*
* Modifications:
- * Copied guts of function info H5FD_register
+ * Copied guts of function into H5FD_register
* Quincey Koziol
* Friday, January 30, 2004
*
@@ -312,7 +309,7 @@ H5FDregister(const H5FD_class_t *cls)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid free-list mapping")
/* Create the new class ID */
- if((ret_value=H5FD_register(cls, sizeof(H5FD_class_t))) < 0)
+ if((ret_value=H5FD_register(cls, sizeof(H5FD_class_t), TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register file driver ID")
done:
@@ -348,35 +345,35 @@ done:
*-------------------------------------------------------------------------
*/
hid_t
-H5FD_register(const void *_cls, size_t size)
+H5FD_register(const void *_cls, size_t size, hbool_t app_ref)
{
- hid_t ret_value;
- const H5FD_class_t *cls=(const H5FD_class_t *)_cls;
- H5FD_class_t *saved=NULL;
+ const H5FD_class_t *cls = (const H5FD_class_t *)_cls;
+ H5FD_class_t *saved = NULL;
H5FD_mem_t type;
+ hid_t ret_value;
FUNC_ENTER_NOAPI(H5FD_register, FAIL)
/* Check arguments */
- assert(cls);
- assert(cls->open && cls->close);
- assert(cls->get_eoa && cls->set_eoa);
- assert(cls->get_eof);
- assert(cls->read && cls->write);
- for (type=H5FD_MEM_DEFAULT; type<H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t,type))
- assert(cls->fl_map[type]>=H5FD_MEM_NOLIST && cls->fl_map[type]<H5FD_MEM_NTYPES);
+ HDassert(cls);
+ HDassert(cls->open && cls->close);
+ HDassert(cls->get_eoa && cls->set_eoa);
+ HDassert(cls->get_eof);
+ HDassert(cls->read && cls->write);
+ for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type))
+ HDassert(cls->fl_map[type] >= H5FD_MEM_NOLIST && cls->fl_map[type] < H5FD_MEM_NTYPES);
/* Copy the class structure so the caller can reuse or free it */
- if(NULL==(saved=H5MM_malloc(size)))
+ if(NULL == (saved = (H5FD_class_t *)H5MM_malloc(size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for file driver class struct")
- HDmemcpy(saved,cls,size);
+ HDmemcpy(saved, cls, size);
/* Create the new class ID */
- if((ret_value=H5I_register(H5I_VFL, saved)) < 0)
+ if((ret_value = H5I_register(H5I_VFL, saved, app_ref)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register file driver ID")
done:
- if(ret_value<0)
+ if(ret_value < 0)
if(saved)
H5MM_xfree(saved);
@@ -416,7 +413,7 @@ H5FDunregister(hid_t driver_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file driver")
/* The H5FD_class_t struct will be freed by this function */
- if(H5I_dec_ref(driver_id) < 0)
+ if(H5I_dec_ref(driver_id, TRUE) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to unregister file driver")
done:
@@ -427,7 +424,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5FD_get_class
*
- * Purpose: Optains a pointer to the driver struct containing all the
+ * Purpose: Obtains a pointer to the driver struct containing all the
* callback pointers, etc. The PLIST_ID argument can be a file
* access property list, a data transfer property list, or a
* file driver identifier.
@@ -452,13 +449,13 @@ H5FD_get_class(hid_t id)
FUNC_ENTER_NOAPI(H5FD_get_class, NULL)
if(H5I_VFL == H5I_get_type(id))
- ret_value = H5I_object(id);
+ ret_value = (H5FD_class_t *)H5I_object(id);
else {
H5P_genplist_t *plist; /* Property list pointer */
hid_t driver_id = -1;
/* Get the plist structure */
- if(NULL == (plist = H5I_object(id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(id)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID")
if(TRUE == H5P_isa_class(id, H5P_FILE_ACCESS)) {
@@ -558,31 +555,27 @@ done:
* Purpose: Decodes the driver information block.
*
* Return: Success: Non-negative
- *
* Failure: Negative
*
* Programmer: Robb Matzke
* Monday, August 16, 1999
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5FD_sb_decode(H5FD_t *file, const char *name, const uint8_t *buf)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_sb_decode, FAIL)
- assert(file && file->cls);
- if(file->cls->sb_decode &&
- (file->cls->sb_decode)(file, name, buf) < 0)
+ HDassert(file && file->cls);
+ if(file->cls->sb_decode && (file->cls->sb_decode)(file, name, buf) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver sb_decode request failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_sb_decode() */
/*-------------------------------------------------------------------------
@@ -667,7 +660,7 @@ H5FD_pl_close(hid_t driver_id, herr_t (*free_func)(void *), void *pl)
H5MM_xfree(pl);
/* Decrement reference count for driver */
- if(H5I_dec_ref(driver_id) < 0)
+ if(H5I_dec_ref(driver_id, FALSE) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't decrement reference count for driver")
done:
@@ -743,7 +736,7 @@ H5FD_fapl_open(H5P_genplist_t *plist, hid_t driver_id, const void *driver_info)
FUNC_ENTER_NOAPI(H5FD_fapl_open, FAIL)
/* Increment the reference count on driver and copy driver info */
- if(H5I_inc_ref(driver_id) < 0)
+ if(H5I_inc_ref(driver_id, FALSE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINC, FAIL, "unable to increment ref count on VFL driver")
if(H5FD_fapl_copy(driver_id, driver_info, &copied_driver_info) < 0)
HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy VFL driver info")
@@ -779,17 +772,17 @@ done:
herr_t
H5FD_fapl_copy(hid_t driver_id, const void *old_fapl, void **copied_fapl)
{
- H5FD_class_t *driver=NULL;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5FD_class_t *driver;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_fapl_copy, FAIL)
/* Check args */
- if(NULL==(driver=H5I_object(driver_id)))
+ if(NULL == (driver = (H5FD_class_t *)H5I_object(driver_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a driver ID")
/* Copy the file access property list */
- if(H5FD_pl_copy(driver->fapl_copy,driver->fapl_size,old_fapl,copied_fapl) < 0)
+ if(H5FD_pl_copy(driver->fapl_copy, driver->fapl_size, old_fapl, copied_fapl) < 0)
HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "can't copy driver file access property list")
done:
@@ -822,7 +815,7 @@ H5FD_fapl_close(hid_t driver_id, void *fapl)
/* Check args */
if(driver_id > 0) {
- if(NULL == (driver = H5I_object(driver_id)))
+ if(NULL == (driver = (H5FD_class_t *)H5I_object(driver_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a driver ID")
/* Close the driver for the property list */
@@ -860,7 +853,7 @@ H5FD_dxpl_open(H5P_genplist_t *plist, hid_t driver_id, const void *driver_info)
FUNC_ENTER_NOAPI(H5FD_dxpl_open, FAIL)
/* Increment the reference count on the driver and copy the driver info */
- if(H5I_inc_ref(driver_id) < 0)
+ if(H5I_inc_ref(driver_id, FALSE) < 0)
HGOTO_ERROR (H5E_DATASET, H5E_CANTINC, FAIL, "can't increment VFL driver ID")
if(H5FD_dxpl_copy(driver_id, driver_info, &copied_driver_info) < 0)
HGOTO_ERROR (H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy VFL driver")
@@ -896,17 +889,17 @@ done:
herr_t
H5FD_dxpl_copy(hid_t driver_id, const void *old_dxpl, void **copied_dxpl)
{
- H5FD_class_t *driver=NULL;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5FD_class_t *driver;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_dxpl_copy, FAIL)
/* Check args */
- if(NULL==(driver=H5I_object(driver_id)))
+ if(NULL == (driver = (H5FD_class_t *)H5I_object(driver_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a driver ID")
/* Copy the file access property list */
- if(H5FD_pl_copy(driver->dxpl_copy,driver->dxpl_size,old_dxpl,copied_dxpl) < 0)
+ if(H5FD_pl_copy(driver->dxpl_copy, driver->dxpl_size, old_dxpl, copied_dxpl) < 0)
HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "can't copy driver data transfer property list")
done:
@@ -932,18 +925,18 @@ done:
herr_t
H5FD_dxpl_close(hid_t driver_id, void *dxpl)
{
- H5FD_class_t *driver=NULL;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5FD_class_t *driver;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_dxpl_close, FAIL)
/* Check args */
- if(driver_id>0) {
- if(NULL==(driver=H5I_object(driver_id)))
+ if(driver_id > 0) {
+ if(NULL == (driver = (H5FD_class_t *)H5I_object(driver_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a driver ID")
/* Close the driver for the property list */
- if(H5FD_pl_close(driver_id,driver->dxpl_free,dxpl) < 0)
+ if(H5FD_pl_close(driver_id, driver->dxpl_free, dxpl) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver fapl_free request failed")
} /* end if */
@@ -1053,36 +1046,36 @@ done:
H5FD_t *
H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
{
- H5FD_class_t *driver;
- H5FD_t *file=NULL;
- hid_t driver_id = -1;
- hsize_t meta_block_size=0;
- hsize_t sdata_block_size=0;
- H5P_genplist_t *plist; /* Property list pointer */
- H5FD_t *ret_value;
+ H5FD_class_t *driver; /* VFD for file */
+ H5FD_t *file = NULL; /* VFD file struct */
+ hid_t driver_id = -1; /* VFD ID */
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5FD_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5FD_open, NULL)
- /* Get file access property list */
- if(NULL == (plist = H5I_object(fapl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
-
- if(0==maxaddr)
+ /* Sanity check */
+ if(0 == maxaddr)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "zero format address range")
+ /* Get file access property list */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list");
+
+ /* Get the VFD to open the file with */
if(H5P_get(plist, H5F_ACS_FILE_DRV_ID_NAME, &driver_id) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver ID")
/* Get driver info */
- if(NULL==(driver=H5I_object(driver_id)))
+ if(NULL == (driver = (H5FD_class_t *)H5I_object(driver_id)))
HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid driver ID in file access property list")
- if(NULL==driver->open)
+ if(NULL == driver->open)
HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, "file driver has no `open' method")
/* Dispatch to file driver */
- if(HADDR_UNDEF==maxaddr)
+ if(HADDR_UNDEF == maxaddr)
maxaddr = driver->maxaddr;
- if(NULL==(file=(driver->open)(name, flags, fapl_id, maxaddr)))
+ if(NULL == (file = (driver->open)(name, flags, fapl_id, maxaddr)))
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "open failed")
/*
@@ -1090,20 +1083,10 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
* driver ID to prevent it from being freed while this file is open.
*/
file->driver_id = driver_id;
- if(H5I_inc_ref(file->driver_id) < 0)
+ if(H5I_inc_ref(file->driver_id, FALSE) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINC, NULL, "unable to increment ref count on VFL driver")
file->cls = driver;
file->maxaddr = maxaddr;
- HDmemset(file->fl, 0, sizeof(file->fl));
- if(H5P_get(plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(meta_block_size)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get meta data block size")
- file->meta_aggr.feature_flag = H5FD_FEAT_AGGREGATE_METADATA;
- file->meta_aggr.alloc_size = meta_block_size;
- if(H5P_get(plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(sdata_block_size)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'small data' block size")
- file->sdata_aggr.feature_flag = H5FD_FEAT_AGGREGATE_SMALLDATA;
- file->sdata_aggr.alloc_size = sdata_block_size;
- file->accum_loc = HADDR_UNDEF;
if(H5P_get(plist, H5F_ACS_ALIGN_THRHD_NAME, &(file->threshold)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment threshold")
if(H5P_get(plist, H5F_ACS_ALIGN_NAME, &(file->alignment)) < 0)
@@ -1114,19 +1097,23 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to query file driver")
/* Increment the global serial number & assign it to this H5FD_t object */
- if(++file_serial_no==0) {
+ if(++file_serial_no == 0) {
/* (Just error out if we wrap around for now...) */
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to get file serial number")
} /* end if */
- file->fileno=file_serial_no;
+ file->fileno = file_serial_no;
+
+ /* Start with base address set to 0 */
+ /* (This will be changed later, when the superblock is located) */
+ file->base_addr = 0;
/* Set return value */
- ret_value=file;
+ ret_value = file;
done:
/* Can't cleanup 'file' information, since we don't know what type it is */
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_open() */
/*-------------------------------------------------------------------------
@@ -1139,14 +1126,11 @@ done:
* the `open' callback.
*
* Return: Success: Non-negative
- *
* Failure: Negative
*
* Programmer: Robb Matzke
* Tuesday, July 27, 1999
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -1161,11 +1145,11 @@ H5FDclose(H5FD_t *file)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer")
if(H5FD_close(file) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to close file")
+ HGOTO_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close file")
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5FDclose() */
/*-------------------------------------------------------------------------
@@ -1174,22 +1158,11 @@ done:
* Purpose: Private version of H5FDclose()
*
* Return: Success: Non-negative
- *
* Failure: Negative
*
* Programmer: Robb Matzke
* Wednesday, August 4, 1999
*
- * Modifications:
- * Robb Matzke, 2000-11-10
- * Removed a call to set *file to all zero because the struct
- * has already been freed by the close method. This fixes a write
- * to freed memory.
- *
- * Bill Wendling, 2003-02-17
- * Split out the freeing of the freelist from this function
- * so that the Flexible PHDF5 stuff can call it without
- * having to call H5FD_close().
*-------------------------------------------------------------------------
*/
herr_t
@@ -1203,13 +1176,9 @@ H5FD_close(H5FD_t *file)
/* check args */
HDassert(file && file->cls);
- /* Free the freelist */
- if(H5FD_free_freelist(file) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't release file space free list")
-
/* Prepare to close file by clearing all public fields */
driver = file->cls;
- if(H5I_dec_ref(file->driver_id) < 0)
+ if(H5I_dec_ref(file->driver_id, FALSE) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close driver ID")
/*
@@ -1218,7 +1187,7 @@ H5FD_close(H5FD_t *file)
*/
HDassert(driver->close);
if((driver->close)(file) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "close failed")
+ HGOTO_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "close failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1422,8 +1391,6 @@ done:
* Programmer: Robb Matzke
* Tuesday, July 27, 1999
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
haddr_t
@@ -1448,12 +1415,15 @@ H5FDalloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "not a data transfer property list")
/* Do the real work */
- if(HADDR_UNDEF == (ret_value = H5FD_alloc(file, type, dxpl_id, size)))
+ if(HADDR_UNDEF == (ret_value = H5FD_alloc_real(file, dxpl_id, type, size, NULL, NULL)))
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "unable to allocate file memory")
+ /* (Note compensating for base address subtraction in internal routine) */
+ ret_value += file->base_addr;
+
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5FDalloc() */
/*-------------------------------------------------------------------------
@@ -1497,7 +1467,8 @@ H5FDfree(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t siz
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
/* Do the real work */
- if(H5FD_free(file, type, dxpl_id, addr, size) < 0)
+ /* (Note compensating for base address addition in internal routine) */
+ if(H5FD_free_real(file, dxpl_id, type, addr - file->base_addr, size) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "file deallocation request failed")
done:
@@ -1506,65 +1477,17 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FDrealloc
- *
- * Purpose: Changes the size of an allocated chunk of memory, possibly
- * also changing its location in the file.
- *
- * Return: Success: New address of the block of memory, not
- * necessarily the same as the original address.
- *
- * Failure: HADDR_UNDEF
- *
- * Programmer: Robb Matzke
- * Tuesday, August 3, 1999
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-haddr_t
-H5FDrealloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsize_t old_size,
- hsize_t new_size)
-{
- haddr_t ret_value = HADDR_UNDEF;
-
- FUNC_ENTER_API(H5FDrealloc, HADDR_UNDEF)
- H5TRACE6("a", "*xMtiahh", file, type, dxpl_id, old_addr, old_size, new_size);
-
- /* Check args */
- if(H5P_DEFAULT == dxpl_id)
- dxpl_id = H5P_DATASET_XFER_DEFAULT;
- else
- if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "not a data transfer property list")
-
- if(HADDR_UNDEF == (ret_value = H5FD_realloc(file, type, dxpl_id, old_addr, old_size, new_size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "file reallocation request failed")
-
-done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5FDrealloc() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5FDget_eoa
*
* Purpose: Returns the address of the first byte after the last
* allocated memory in the file.
*
* Return: Success: First byte after allocated memory.
- *
* Failure: HADDR_UNDEF
*
* Programmer: Robb Matzke
* Friday, July 30, 1999
*
- * Modifications:
- * Raymond Lu
- * 21 Dec. 2006
- * Added the parameter TYPE. It's only used for MULTI driver.
- *
*-------------------------------------------------------------------------
*/
haddr_t
@@ -1578,52 +1501,19 @@ H5FDget_eoa(H5FD_t *file, H5FD_mem_t type)
/* Check args */
if(!file || !file->cls)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid file pointer")
- if(type<H5FD_MEM_DEFAULT || type >= H5FD_MEM_NTYPES)
+ if(type < H5FD_MEM_DEFAULT || type >= H5FD_MEM_NTYPES)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid file type")
/* The real work */
- if(HADDR_UNDEF==(ret_value=H5FD_get_eoa(file, type)))
+ if(HADDR_UNDEF == (ret_value = H5FD_get_eoa(file, type)))
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "file get eoa request failed")
-done:
- FUNC_LEAVE_API(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_get_eoa
- *
- * Purpose: Private version of H5FDget_eoa()
- *
- * Return: Success: First byte after allocated memory.
- *
- * Failure: HADDR_UNDEF
- *
- * Programmer: Robb Matzke
- * Wednesday, August 4, 1999
- *
- * Modifications:
- * Raymond Lu
- * 21 Dec. 2006
- * Added the parameter TYPE. It's only used for MULTI driver.
- *
- *-------------------------------------------------------------------------
- */
-haddr_t
-H5FD_get_eoa(const H5FD_t *file, H5FD_mem_t type)
-{
- haddr_t ret_value;
-
- FUNC_ENTER_NOAPI(H5FD_get_eoa, HADDR_UNDEF)
- assert(file && file->cls);
-
- /* Dispatch to driver */
- if(HADDR_UNDEF==(ret_value=(file->cls->get_eoa)(file, type)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "driver get_eoa request failed")
+ /* (Note compensating for base address subtraction in internal routine) */
+ ret_value += file->base_addr;
done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5FDget_eoa() */
/*-------------------------------------------------------------------------
@@ -1643,23 +1533,17 @@ done:
* and the driver didn't supply an allocation callback.
*
* Return: Success: Non-negative
- *
* Failure: Negative, no side effect
*
* Programmer: Robb Matzke
* Friday, July 30, 1999
*
- * Modifications:
- * Raymond Lu
- * 21 Dec. 2006
- * Added the parameter TYPE. It's only used for MULTI driver.
- *
*-------------------------------------------------------------------------
*/
herr_t
H5FDset_eoa(H5FD_t *file, H5FD_mem_t type, haddr_t addr)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5FDset_eoa, FAIL)
H5TRACE3("e", "*xMta", file, type, addr);
@@ -1667,57 +1551,19 @@ H5FDset_eoa(H5FD_t *file, H5FD_mem_t type, haddr_t addr)
/* Check args */
if(!file || !file->cls)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer")
- if(type<H5FD_MEM_DEFAULT || type >= H5FD_MEM_NTYPES)
+ if(type < H5FD_MEM_DEFAULT || type >= H5FD_MEM_NTYPES)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file type")
-
- if(!H5F_addr_defined(addr) || addr>file->maxaddr)
+ if(!H5F_addr_defined(addr) || addr > file->maxaddr)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid end-of-address value")
/* The real work */
- if(H5FD_set_eoa(file, type, addr) < 0)
+ /* (Note compensating for base address addition in internal routine) */
+ if(H5FD_set_eoa(file, type, addr - file->base_addr) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "file set eoa request failed")
done:
FUNC_LEAVE_API(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_set_eoa
- *
- * Purpose: Private version of H5FDset_eoa()
- *
- * Return: Success: Non-negative
- *
- * Failure: Negative, no side effect
- *
- * Programmer: Robb Matzke
- * Wednesday, August 4, 1999
- *
- * Modifications:
- * Raymond Lu
- * 21 Dec. 2006
- * Added the parameter TYPE. It's only used for MULTI driver.
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5FD_set_eoa(H5FD_t *file, H5FD_mem_t UNUSED type, haddr_t addr)
-{
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_set_eoa, FAIL)
-
- assert(file && file->cls);
- assert(H5F_addr_defined(addr) && addr<=file->maxaddr);
-
- /* Dispatch to driver */
- if((file->cls->set_eoa)(file, type, addr) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver set_eoa request failed")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FDset_eoa() */
/*-------------------------------------------------------------------------
@@ -1759,80 +1605,112 @@ H5FDget_eof(H5FD_t *file)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid file pointer")
/* The real work */
- if(HADDR_UNDEF==(ret_value=H5FD_get_eof(file)))
+ if(HADDR_UNDEF == (ret_value = H5FD_get_eof(file)))
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "file get eof request failed")
+ /* (Note compensating for base address subtraction in internal routine) */
+ ret_value += file->base_addr;
+
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5FDget_eof() */
/*-------------------------------------------------------------------------
- * Function: H5FD_get_eof
+ * Function: H5FD_get_maxaddr
*
* Purpose: Private version of H5FDget_eof()
*
- * Return: Success: The EOF address.
- *
+ * Return: Success: The maximum address allowed in the file.
* Failure: HADDR_UNDEF
*
- * Programmer: Robb Matzke
- * Wednesday, August 4, 1999
- *
- * Modifications:
+ * Programmer: Quincey Koziol
+ * Thursday, January 3, 2008
*
*-------------------------------------------------------------------------
*/
haddr_t
-H5FD_get_eof(const H5FD_t *file)
+H5FD_get_maxaddr(const H5FD_t *file)
{
- haddr_t ret_value;
+ haddr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5FD_get_eof, HADDR_UNDEF)
+ FUNC_ENTER_NOAPI(H5FD_get_maxaddr, HADDR_UNDEF)
- assert(file && file->cls);
+ HDassert(file);
- /* Dispatch to driver */
- if(file->cls->get_eof) {
- if(HADDR_UNDEF==(ret_value=(file->cls->get_eof)(file)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "driver get_eof request failed")
- } else {
- ret_value = file->maxaddr;
- }
+ /* Set return value */
+ ret_value = file->maxaddr;
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_get_maxaddr() */
/*-------------------------------------------------------------------------
- * Function: H5FD_get_maxaddr
+ * Function: H5FD_get_feature_flags
*
- * Purpose: Private version of H5FDget_eof()
+ * Purpose: Retrieve the feature flags for the VFD
*
- * Return: Success: The maximum address allowed in the file.
- * Failure: HADDR_UNDEF
+ * Return: Success: Non-negative
+ * Failure: Negative
*
* Programmer: Quincey Koziol
- * Thursday, January 3, 2008
+ * Tuesday, January 8, 2008
*
*-------------------------------------------------------------------------
*/
-haddr_t
-H5FD_get_maxaddr(const H5FD_t *file)
+herr_t
+H5FD_get_feature_flags(const H5FD_t *file, unsigned long *feature_flags)
{
- haddr_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_get_maxaddr, HADDR_UNDEF)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_get_feature_flags)
HDassert(file);
+ HDassert(feature_flags);
- /* Set return value */
- ret_value = file->maxaddr;
+ /* Set feature flags to return */
+ *feature_flags = file->feature_flags;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5FD_get_feature_flags() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_get_fs_type_map
+ *
+ * Purpose: Retrieve the free space type mapping for the VFD
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, January 17, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FD_get_fs_type_map(const H5FD_t *file, H5FD_mem_t *type_map)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_get_fs_type_map, FAIL)
+
+ /* Sanity check */
+ HDassert(file && file->cls);
+ HDassert(type_map);
+
+ /* Check for VFD class providing a type map retrieval rouine */
+ if(file->cls->get_type_map) {
+ /* Retrieve type mapping for this file */
+ if((file->cls->get_type_map)(file, type_map) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "driver get type map failed")
+ } /* end if */
+ else
+ /* Copy class's default free space type mapping */
+ HDmemcpy(type_map, file->cls->fl_map, sizeof(file->cls->fl_map));
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_get_maxaddr() */
+} /* end H5FD_get_fs_type_map() */
/*-------------------------------------------------------------------------
@@ -1860,7 +1738,7 @@ herr_t
H5FDread(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
void *buf/*out*/)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5FDread, FAIL)
H5TRACE6("e", "*xMtiazx", file, type, dxpl_id, addr, size, buf);
@@ -1873,206 +1751,76 @@ H5FDread(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size
if(H5P_DEFAULT == dxpl_id)
dxpl_id= H5P_DATASET_XFER_DEFAULT;
else
- if(TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER))
+ if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
if(!buf)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null result buffer")
/* Do the real work */
- if(H5FD_read(file, type, dxpl_id, addr, size, buf) < 0)
+ /* (Note compensating for base address addition in internal routine) */
+ if(H5FD_read(file, dxpl_id, type, addr - file->base_addr, size, buf) < 0)
HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "file read request failed")
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5FDread() */
/*-------------------------------------------------------------------------
- * Function: H5FD_read
+ * Function: H5FDwrite
*
- * Purpose: Private version of H5FDread()
+ * Purpose: Writes SIZE bytes to FILE beginning at address ADDR according
+ * to the data transfer property list DXPL_ID (which may be the
+ * constant H5P_DEFAULT). The bytes to be written come from the
+ * buffer BUF.
*
* Return: Success: Non-negative
*
* Failure: Negative
*
* Programmer: Robb Matzke
- * Wednesday, August 4, 1999
+ * Thursday, July 29, 1999
*
* Modifications:
- * Albert Cheng, 2000-11-21
- * Disable the code that does early return when size==0 for
- * Parallel mode since a collective call would require the process
- * to continue on with "nothing" to transfer.
*
*-------------------------------------------------------------------------
*/
herr_t
-H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
- void *buf/*out*/)
+H5FDwrite(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
+ const void *buf)
{
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_read, FAIL)
-
- assert(file && file->cls);
- assert(H5I_GENPROP_LST==H5I_get_type(dxpl_id));
- assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
- assert(buf);
-
-#ifndef H5_HAVE_PARALLEL
- /* Do not return early for Parallel mode since the I/O could be a */
- /* collective transfer. */
- /* The no-op case */
- if(0==size)
- HGOTO_DONE(SUCCEED)
-#endif /* H5_HAVE_PARALLEL */
-
- /* Check if this information is in the metadata accumulator */
- if((file->feature_flags&H5FD_FEAT_ACCUMULATE_METADATA) && type!=H5FD_MEM_DRAW) {
- /* Current read overlaps with metadata accumulator */
- if(H5F_addr_overlap(addr,size,file->accum_loc,file->accum_size)) {
- unsigned char *read_buf=(unsigned char *)buf; /* Pointer to the buffer being read in */
- size_t amount_read; /* Amount to read at a time */
-#ifndef NDEBUG
- hsize_t tempamount_read; /* Amount to read at a time */
-#endif /* NDEBUG */
- hsize_t read_off; /* Offset to read from */
-
- /* Double check that we aren't reading raw data */
- assert(type!=H5FD_MEM_DRAW);
-
- /* Read the part before the metadata accumulator */
- if(addr<file->accum_loc) {
- /* Set the amount to read */
- H5_ASSIGN_OVERFLOW(amount_read,file->accum_loc-addr,hsize_t,size_t);
-
- /* Dispatch to driver */
- if((file->cls->read)(file, type, dxpl_id, addr, amount_read, read_buf) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed")
-
- /* Adjust the buffer, address & size */
- read_buf+=amount_read;
- addr+=amount_read;
- size-=amount_read;
- } /* end if */
-
- /* Copy the part overlapping the metadata accumulator */
- if(size>0 && (addr>=file->accum_loc && addr<(file->accum_loc+file->accum_size))) {
- /* Set the offset to "read" from */
- read_off=addr-file->accum_loc;
-
- /* Set the amount to "read" */
-#ifndef NDEBUG
- tempamount_read = file->accum_size-read_off;
- H5_CHECK_OVERFLOW(tempamount_read,hsize_t,size_t);
- amount_read = MIN(size, (size_t)tempamount_read);
-#else /* NDEBUG */
- amount_read = MIN(size, (size_t)(file->accum_size-read_off));
-#endif /* NDEBUG */
-
- /* Copy the data out of the buffer */
- HDmemcpy(read_buf,file->meta_accum+read_off,amount_read);
-
- /* Adjust the buffer, address & size */
- read_buf+=amount_read;
- addr+=amount_read;
- size-=amount_read;
- } /* end if */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Read the part after the metadata accumulator */
- if(size>0 && addr>=(file->accum_loc+file->accum_size)) {
- /* Dispatch to driver */
- if((file->cls->read)(file, type, dxpl_id, addr, size, read_buf) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed")
+ FUNC_ENTER_API(H5FDwrite, FAIL)
+ H5TRACE6("e", "*xMtiaz*x", file, type, dxpl_id, addr, size, buf);
- /* Adjust the buffer, address & size */
- read_buf+=size;
- addr+=size;
- size-=size;
- } /* end if */
+ /* Check args */
+ if(!file || !file->cls)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer")
+ /* Get the default dataset transfer property list if the user didn't provide one */
+ if(H5P_DEFAULT == dxpl_id)
+ dxpl_id = H5P_DATASET_XFER_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
+ if(!buf)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null buffer")
- /* Make certain we've read it all */
- assert(size==0);
- } /* end if */
- /* Current read doesn't overlap with metadata accumulator, read it into accumulator */
- else {
- /* Only update the metadata accumulator if it is not dirty or if
- * we are allowed to write the accumulator out during reads (when
- * it is dirty)
- */
- if(file->feature_flags&H5FD_FEAT_ACCUMULATE_METADATA_READ || !file->accum_dirty) {
- /* Flush current contents, if dirty */
- if(file->accum_dirty) {
- if((file->cls->write)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write request failed")
-
- /* Reset accumulator dirty flag */
- file->accum_dirty=FALSE;
- } /* end if */
-
- /* Cache the new piece of metadata */
- /* Check if we need to resize the buffer */
- if(size>file->accum_buf_size) {
- /* Grow the metadata accumulator buffer */
- if((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer")
-
- /* Note the new buffer size */
- file->accum_buf_size=size;
- } /* end if */
- else {
- /* Check if we should shrink the accumulator buffer */
- if(size<(file->accum_buf_size/H5FD_ACCUM_THROTTLE) &&
- file->accum_buf_size>H5FD_ACCUM_THRESHOLD) {
- size_t new_size=(file->accum_buf_size/H5FD_ACCUM_THROTTLE); /* New size of accumulator buffer */
-
- /* Shrink the accumulator buffer */
- if((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,new_size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer")
-
- /* Note the new buffer size */
- file->accum_buf_size=new_size;
- } /* end if */
- } /* end else */
-
- /* Update accumulator information */
- file->accum_loc=addr;
- file->accum_size=size;
- file->accum_dirty=FALSE;
-
- /* Read into accumulator */
- if((file->cls->read)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed")
-
- /* Copy into buffer */
- HDmemcpy(buf,file->meta_accum,size);
- } /* end if */
- else {
- /* Dispatch to driver */
- if((file->cls->read)(file, type, dxpl_id, addr, size, buf) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed")
- } /* end else */
- } /* end else */
- } /* end if */
- else {
- /* Dispatch to driver */
- if((file->cls->read)(file, type, dxpl_id, addr, size, buf) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed")
- } /* end else */
+ /* The real work */
+ /* (Note compensating for base address addition in internal routine) */
+ if(H5FD_write(file, dxpl_id, type, addr - file->base_addr, size, buf) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file write request failed")
done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5FDwrite() */
/*-------------------------------------------------------------------------
- * Function: H5FDwrite
+ * Function: H5FDflush
*
- * Purpose: Writes SIZE bytes to FILE beginning at address ADDR according
- * to the data transfer property list DXPL_ID (which may be the
- * constant H5P_DEFAULT). The bytes to be written come from the
- * buffer BUF.
+ * Purpose: Notify driver to flush all cached data. If the driver has no
+ * flush method then nothing happens.
*
* Return: Success: Non-negative
*
@@ -2082,33 +1830,31 @@ done:
* Thursday, July 29, 1999
*
* Modifications:
+ * Quincey Koziol, May 20, 2002
+ * Added 'closing' parameter
*
*-------------------------------------------------------------------------
*/
herr_t
-H5FDwrite(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
- const void *buf)
+H5FDflush(H5FD_t *file, hid_t dxpl_id, unsigned closing)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API(H5FDwrite, FAIL)
- H5TRACE6("e", "*xMtiaz*x", file, type, dxpl_id, addr, size, buf);
+ FUNC_ENTER_API(H5FDflush, FAIL)
+ H5TRACE3("e", "*xiIu", file, dxpl_id, closing);
/* Check args */
if(!file || !file->cls)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer")
- /* Get the default dataset transfer property list if the user didn't provide one */
if(H5P_DEFAULT == dxpl_id)
- dxpl_id= H5P_DATASET_XFER_DEFAULT;
+ dxpl_id = H5P_DATASET_XFER_DEFAULT;
else
- if(TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER))
+ if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
- if(!buf)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null buffer")
- /* The real work */
- if(H5FD_write(file, type, dxpl_id, addr, size, buf) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file write request failed")
+ /* Do the real work */
+ if(H5FD_flush(file, dxpl_id, closing) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFLUSH, FAIL, "file flush request failed")
done:
FUNC_LEAVE_API(ret_value)
@@ -2116,303 +1862,68 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FD_write
+ * Function: H5FD_flush
*
- * Purpose: Private version of H5FDwrite()
+ * Purpose: Private version of H5FDflush()
*
* Return: Success: Non-negative
- *
* Failure: Negative
*
* Programmer: Robb Matzke
* Wednesday, August 4, 1999
*
- * Modifications:
- * Albert Cheng, 2000-11-21
- * Disable the code that does early return when size==0 for
- * Parallel mode since a collective call would require the process
- * to continue on with "nothing" to transfer.
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
- const void *buf)
+H5FD_flush(H5FD_t *file, hid_t dxpl_id, unsigned closing)
{
- size_t new_size; /* New size of the accumulator buffer */
- size_t old_offset; /* Offset of old data within the accumulator buffer */
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_write, FAIL)
-
- assert(file && file->cls);
- assert(H5I_GENPROP_LST==H5I_get_type(dxpl_id));
- assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
- assert(buf);
-
-#ifndef H5_HAVE_PARALLEL
- /* Do not return early for Parallel mode since the I/O could be a */
- /* collective transfer. */
- /* The no-op case */
- if(0==size)
- HGOTO_DONE(SUCCEED)
-#endif /* H5_HAVE_PARALLEL */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Check for accumulating metadata */
- if((file->feature_flags&H5FD_FEAT_ACCUMULATE_METADATA) && type!=H5FD_MEM_DRAW) {
- /* Check if there is already metadata in the accumulator */
- if(file->accum_size>0) {
- /* Check if the piece of metadata being written adjoins or is inside the metadata accumulator */
- if((addr>=file->accum_loc && addr<=(file->accum_loc+file->accum_size))
- || ((addr+size)>file->accum_loc && (addr+size)<=(file->accum_loc+file->accum_size))
- || (addr<file->accum_loc && (addr+size)>=file->accum_loc)) {
-
- /* Check if the new metadata adjoins the beginning of the current accumulator */
- if((addr+size)==file->accum_loc) {
- /* Check if we need more buffer space */
- if((size+file->accum_size)>file->accum_buf_size) {
- /* Adjust the buffer size, by doubling it */
- file->accum_buf_size = MAX(file->accum_buf_size*2,size+file->accum_size);
-
- /* Reallocate the metadata accumulator buffer */
- if((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,file->accum_buf_size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer")
-#ifdef H5_CLEAR_MEMORY
-HDmemset(file->meta_accum + file->accum_size, 0, (file->accum_buf_size - (file->accum_size + size)));
-#endif /* H5_CLEAR_MEMORY */
- } /* end if */
-
- /* Move the existing metadata to the proper location */
- HDmemmove(file->meta_accum+size,file->meta_accum,file->accum_size);
-
- /* Copy the new metadata at the front */
- HDmemcpy(file->meta_accum,buf,size);
-
- /* Set the new size & location of the metadata accumulator */
- file->accum_loc=addr;
- file->accum_size=file->accum_size+size;
-
- /* Mark it as written to */
- file->accum_dirty=TRUE;
- } /* end if */
- /* Check if the new metadata adjoins the end of the current accumulator */
- else if(addr==(file->accum_loc+file->accum_size)) {
- /* Check if we need more buffer space */
- if((size+file->accum_size)>file->accum_buf_size) {
- /* Adjust the buffer size, by doubling it */
- file->accum_buf_size = MAX(file->accum_buf_size*2,size+file->accum_size);
-
- /* Reallocate the metadata accumulator buffer */
- if((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,file->accum_buf_size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer")
-#ifdef H5_CLEAR_MEMORY
-HDmemset(file->meta_accum + file->accum_size + size, 0, (file->accum_buf_size - (file->accum_size + size)));
-#endif /* H5_CLEAR_MEMORY */
- } /* end if */
-
- /* Copy the new metadata to the end */
- HDmemcpy(file->meta_accum+file->accum_size,buf,size);
-
- /* Set the new size of the metadata accumulator */
- file->accum_size=file->accum_size+size;
-
- /* Mark it as written to */
- file->accum_dirty=TRUE;
- } /* end if */
- /* Check if the new metadata is entirely within the current accumulator */
- else if(addr>=file->accum_loc && (addr+size)<=(file->accum_loc+file->accum_size)) {
- /* Copy the new metadata to the proper location within the accumulator */
- HDmemcpy(file->meta_accum+(addr-file->accum_loc),buf,size);
-
- /* Mark it as written to */
- file->accum_dirty=TRUE;
- } /* end if */
- /* Check if the new metadata overlaps the beginning of the current accumulator */
- else if(addr<file->accum_loc && (addr+size)<=(file->accum_loc+file->accum_size)) {
- /* Calculate the new accumulator size, based on the amount of overlap */
- H5_ASSIGN_OVERFLOW(new_size,(file->accum_loc-addr)+file->accum_size,hsize_t,size_t);
-
- /* Check if we need more buffer space */
- if(new_size>file->accum_buf_size) {
- /* Adjust the buffer size, by doubling it */
- file->accum_buf_size = MAX(file->accum_buf_size*2,new_size);
-
- /* Reallocate the metadata accumulator buffer */
- if((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,file->accum_buf_size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer")
-#ifdef H5_CLEAR_MEMORY
-HDmemset(file->meta_accum + file->accum_size, 0, (file->accum_buf_size - file->accum_size));
-#endif /* H5_CLEAR_MEMORY */
- } /* end if */
-
- /* Calculate the proper offset of the existing metadata */
- H5_ASSIGN_OVERFLOW(old_offset,(addr+size)-file->accum_loc,hsize_t,size_t);
-
- /* Move the existing metadata to the proper location */
- HDmemmove(file->meta_accum+size,file->meta_accum+old_offset,(file->accum_size-old_offset));
-
- /* Copy the new metadata at the front */
- HDmemcpy(file->meta_accum,buf,size);
-
- /* Set the new size & location of the metadata accumulator */
- file->accum_loc=addr;
- file->accum_size=new_size;
-
- /* Mark it as written to */
- file->accum_dirty=TRUE;
- } /* end if */
- /* Check if the new metadata overlaps the end of the current accumulator */
- else if(addr>=file->accum_loc && (addr+size)>(file->accum_loc+file->accum_size)) {
- /* Calculate the new accumulator size, based on the amount of overlap */
- H5_ASSIGN_OVERFLOW(new_size,(addr-file->accum_loc)+size,hsize_t,size_t);
-
- /* Check if we need more buffer space */
- if(new_size>file->accum_buf_size) {
- /* Adjust the buffer size, by doubling it */
- file->accum_buf_size = MAX(file->accum_buf_size*2,new_size);
-
- /* Reallocate the metadata accumulator buffer */
- if((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,file->accum_buf_size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer")
-#ifdef H5_CLEAR_MEMORY
-HDmemset(file->meta_accum + file->accum_size, 0, (file->accum_buf_size - file->accum_size));
-#endif /* H5_CLEAR_MEMORY */
- } /* end if */
-
- /* Copy the new metadata to the end */
- HDmemcpy(file->meta_accum+(addr-file->accum_loc),buf,size);
-
- /* Set the new size & location of the metadata accumulator */
- file->accum_size=new_size;
-
- /* Mark it as written to */
- file->accum_dirty=TRUE;
- } /* end if */
- else {
- assert(0 && "New metadata overlapped both beginning and end of existing metadata accumulator!");
- } /* end else */
- } /* end if */
- /* New piece of metadata doesn't adjoin or overlap the existing accumulator */
- else {
- /* Write out the existing metadata accumulator, with dispatch to driver */
- if(file->accum_dirty) {
- if((file->cls->write)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write request failed")
- /* Reset accumulator dirty flag */
- file->accum_dirty=FALSE;
- } /* end if */
-
- /* Cache the new piece of metadata */
- /* Check if we need to resize the buffer */
- if(size>file->accum_buf_size) {
- /* Grow the metadata accumulator buffer */
- if((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer")
-
- /* Note the new buffer size */
- file->accum_buf_size=size;
-#ifdef H5_CLEAR_MEMORY
-{
-size_t clear_size = MAX(file->accum_size, size);
-HDmemset(file->meta_accum + clear_size, 0, (file->accum_buf_size - clear_size));
-}
-#endif /* H5_CLEAR_MEMORY */
- } /* end if */
- else {
- /* Check if we should shrink the accumulator buffer */
- if(size<(file->accum_buf_size/H5FD_ACCUM_THROTTLE) &&
- file->accum_buf_size>H5FD_ACCUM_THRESHOLD) {
- size_t tmp_size=(file->accum_buf_size/H5FD_ACCUM_THROTTLE); /* New size of accumulator buffer */
-
- /* Shrink the accumulator buffer */
- if((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,tmp_size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer")
-
- /* Note the new buffer size */
- file->accum_buf_size=tmp_size;
- } /* end if */
- } /* end else */
-
- /* Update the metadata accumulator information */
- file->accum_loc=addr;
- file->accum_size=size;
- file->accum_dirty=TRUE;
-
- /* Store the piece of metadata in the accumulator */
- HDmemcpy(file->meta_accum,buf,size);
- } /* end else */
- } /* end if */
- /* No metadata in the accumulator, grab this piece and keep it */
- else {
- /* Check if we need to reallocate the buffer */
- if(size>file->accum_buf_size) {
- /* Reallocate the metadata accumulator buffer */
- if((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer")
-
- /* Note the new buffer size */
- file->accum_buf_size=size;
- } /* end if */
+ FUNC_ENTER_NOAPI(H5FD_flush, FAIL)
- /* Update the metadata accumulator information */
- file->accum_loc=addr;
- file->accum_size=size;
- file->accum_dirty=TRUE;
+ HDassert(file && file->cls);
- /* Store the piece of metadata in the accumulator */
- HDmemcpy(file->meta_accum,buf,size);
- } /* end else */
- } /* end if */
- else {
- /* Dispatch to driver */
- if((file->cls->write)(file, type, dxpl_id, addr, size, buf) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write request failed")
- } /* end else */
+ if(file->cls->flush && (file->cls->flush)(file, dxpl_id, closing) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver flush request failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_flush() */
/*-------------------------------------------------------------------------
- * Function: H5FDflush
+ * Function: H5FDtruncate
*
- * Purpose: Notify driver to flush all cached data. If the driver has no
- * flush method then nothing happens.
+ * Purpose: Notify driver to truncate the file back to the allocated size.
*
* Return: Success: Non-negative
- *
* Failure: Negative
*
- * Programmer: Robb Matzke
- * Thursday, July 29, 1999
- *
- * Modifications:
- * Quincey Koziol, May 20, 2002
- * Added 'closing' parameter
+ * Programmer: Quincey Koziol
+ * Thursday, January 31, 2008
*
*-------------------------------------------------------------------------
*/
herr_t
-H5FDflush(H5FD_t *file, hid_t dxpl_id, unsigned closing)
+H5FDtruncate(H5FD_t *file, hid_t dxpl_id, unsigned closing)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API(H5FDflush, FAIL)
+ FUNC_ENTER_API(H5FDtruncate, FAIL)
H5TRACE3("e", "*xiIu", file, dxpl_id, closing);
/* Check args */
if(!file || !file->cls)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer")
if(H5P_DEFAULT == dxpl_id)
- dxpl_id= H5P_DATASET_XFER_DEFAULT;
+ dxpl_id = H5P_DATASET_XFER_DEFAULT;
else
- if(TRUE!=H5P_isa_class(dxpl_id,H5P_DATASET_XFER))
+ if(TRUE != H5P_isa_class(dxpl_id,H5P_DATASET_XFER))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
/* Do the real work */
- if(H5FD_flush(file,dxpl_id,closing) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "file flush request failed")
+ if(H5FD_truncate(file, dxpl_id, closing) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTUPDATE, FAIL, "file flush request failed")
done:
FUNC_LEAVE_API(ret_value)
@@ -2420,49 +1931,33 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FD_flush
+ * Function: H5FD_truncate
*
- * Purpose: Private version of H5FDflush()
+ * Purpose: Private version of H5FDtruncate()
*
* Return: Success: Non-negative
- *
* Failure: Negative
*
- * Programmer: Robb Matzke
- * Wednesday, August 4, 1999
- *
- * Modifications:
- * Quincey Koziol, May 20, 2002
- * Added 'closing' parameter
+ * Programmer: Quincey Koziol
+ * Thursday, January 31, 2008
*
*-------------------------------------------------------------------------
*/
herr_t
-H5FD_flush(H5FD_t *file, hid_t dxpl_id, unsigned closing)
+H5FD_truncate(H5FD_t *file, hid_t dxpl_id, unsigned closing)
{
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_flush, FAIL)
-
- assert(file && file->cls);
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Check if we need to flush out the metadata accumulator */
- if((file->feature_flags&H5FD_FEAT_ACCUMULATE_METADATA) && file->accum_dirty && file->accum_size>0) {
- /* Flush the metadata contents */
- /* Not certain if the type and dxpl should be the way they are... -QAK */
- if((file->cls->write)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver write request failed")
+ FUNC_ENTER_NOAPI(H5FD_truncate, FAIL)
- /* Reset the dirty flag */
- file->accum_dirty=FALSE;
- } /* end if */
+ HDassert(file && file->cls);
- if(file->cls->flush && (file->cls->flush)(file,dxpl_id,closing) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver flush request failed")
+ if(file->cls->truncate && (file->cls->truncate)(file, dxpl_id, closing) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTUPDATE, FAIL, "driver truncate request failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_truncate() */
/*-------------------------------------------------------------------------
@@ -2541,8 +2036,6 @@ done:
* Programmer: Raymond Lu
* Sep. 16, 2002
*
- * Modifications:
- *
*--------------------------------------------------------------------------
*/
herr_t
@@ -2552,14 +2045,76 @@ H5FD_get_vfd_handle(H5FD_t *file, hid_t fapl, void **file_handle)
FUNC_ENTER_NOAPI(H5FD_get_vfd_handle, FAIL)
+ /* Sanity check */
+ HDassert(file);
HDassert(file_handle);
if(NULL == file->cls->get_handle)
HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "file driver has no `get_vfd_handle' method")
- if((ret_value = file->cls->get_handle(file, fapl, file_handle)) < 0)
+ if((file->cls->get_handle)(file, fapl, file_handle) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file handle for file driver")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_get_vfd_handle() */
+
+/*--------------------------------------------------------------------------
+ * Function: H5FD_set_base_addr
+ *
+ * Purpose: Set the base address for the file
+ *
+ * Return: Non-negative if succeed; negative if fails.
+ *
+ * Programmer: Quincey Koziol
+ * Jan. 17, 2008
+ *
+ *--------------------------------------------------------------------------
+ */
+herr_t
+H5FD_set_base_addr(H5FD_t *file, haddr_t base_addr)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5FD_set_base_addr, FAIL)
+
+ HDassert(file);
+ HDassert(H5F_addr_defined(base_addr));
+
+ /* Set the file's base address */
+ file->base_addr = base_addr;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_set_base_addr() */
+
+
+/*--------------------------------------------------------------------------
+ * Function: H5FD_get_base_addr
+ *
+ * Purpose: Get the base address for the file
+ *
+ * Return: Success: The absolute base address of the file
+ * Failure: The undefined address (HADDR_UNDEF)
+ *
+ * Programmer: Quincey Koziol
+ * Sept. 10, 2009
+ *
+ *--------------------------------------------------------------------------
+ */
+haddr_t
+H5FD_get_base_addr(const H5FD_t *file)
+{
+ haddr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_get_base_addr, HADDR_UNDEF)
+
+ HDassert(file);
+
+ /* Return the file's base address */
+ ret_value = file->base_addr;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_get_base_addr() */
+
diff --git a/src/H5FDcore.c b/src/H5FDcore.c
index 4c468b6..1333995 100644
--- a/src/H5FDcore.c
+++ b/src/H5FDcore.c
@@ -91,6 +91,7 @@ static H5FD_t *H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
haddr_t maxaddr);
static herr_t H5FD_core_close(H5FD_t *_file);
static int H5FD_core_cmp(const H5FD_t *_f1, const H5FD_t *_f2);
+static herr_t H5FD_core_query(const H5FD_t *_f1, unsigned long *flags);
static haddr_t H5FD_core_get_eoa(const H5FD_t *_file, H5FD_mem_t type);
static herr_t H5FD_core_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr);
static haddr_t H5FD_core_get_eof(const H5FD_t *_file);
@@ -100,6 +101,7 @@ static herr_t H5FD_core_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, hadd
static herr_t H5FD_core_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr,
size_t size, const void *buf);
static herr_t H5FD_core_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing);
+static herr_t H5FD_core_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
static const H5FD_class_t H5FD_core_g = {
"core", /*name */
@@ -118,7 +120,8 @@ static const H5FD_class_t H5FD_core_g = {
H5FD_core_open, /*open */
H5FD_core_close, /*close */
H5FD_core_cmp, /*cmp */
- NULL, /*query */
+ H5FD_core_query, /*query */
+ NULL, /*get_type_map */
NULL, /*alloc */
NULL, /*free */
H5FD_core_get_eoa, /*get_eoa */
@@ -128,6 +131,7 @@ static const H5FD_class_t H5FD_core_g = {
H5FD_core_read, /*read */
H5FD_core_write, /*write */
H5FD_core_flush, /*flush */
+ H5FD_core_truncate, /*truncate */
NULL, /*lock */
NULL, /*unlock */
H5FD_FLMAP_SINGLE /*fl_map */
@@ -181,7 +185,7 @@ H5FD_core_init(void)
FUNC_ENTER_NOAPI(H5FD_core_init, FAIL)
if (H5I_VFL!=H5Iget_type(H5FD_CORE_g))
- H5FD_CORE_g = H5FD_register(&H5FD_core_g,sizeof(H5FD_class_t));
+ H5FD_CORE_g = H5FD_register(&H5FD_core_g,sizeof(H5FD_class_t),FALSE);
/* Set return value */
ret_value=H5FD_CORE_g;
@@ -297,11 +301,11 @@ H5Pget_fapl_core(hid_t fapl_id, size_t *increment/*out*/,
FUNC_ENTER_API(H5Pget_fapl_core, FAIL)
H5TRACE3("e", "ixx", fapl_id, increment, backing_store);
- if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
+ if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- if (H5FD_CORE!=H5P_get_driver(plist))
+ if(H5FD_CORE != H5P_get_driver(plist))
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver")
- if (NULL==(fa=H5P_get_driver_info(plist)))
+ if(NULL == (fa = (H5FD_core_fapl_t *)H5P_get_driver_info(plist)))
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "bad VFL driver info")
if (increment)
@@ -334,16 +338,16 @@ static void *
H5FD_core_fapl_get(H5FD_t *_file)
{
H5FD_core_t *file = (H5FD_core_t*)_file;
- H5FD_core_fapl_t *fa = NULL;
+ H5FD_core_fapl_t *fa;
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5FD_core_fapl_get, NULL)
- if (NULL==(fa=H5MM_calloc(sizeof(H5FD_core_fapl_t))))
+ if(NULL == (fa = (H5FD_core_fapl_t *)H5MM_calloc(sizeof(H5FD_core_fapl_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
fa->increment = file->increment;
- fa->backing_store = (file->fd>=0);
+ fa->backing_store = (hbool_t)(file->fd >= 0);
/* Set return value */
ret_value=fa;
@@ -370,10 +374,13 @@ done:
* Modifications:
* Robb Matzke, 1999-10-19
* The backing store file is created and opened if specified.
- *
+ *
* Raymond Lu, 2006-11-30
- * Enabled the driver to read an existing file depending on
+ * Enabled the driver to read an existing file depending on
* the setting of the backing_store and file open flags.
+ *
+ * Allen Byrne, 2008-1-23
+ * changed if of fapl_id to assert
*-------------------------------------------------------------------------
*/
static H5FD_t *
@@ -391,36 +398,35 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
FUNC_ENTER_NOAPI(H5FD_core_open, NULL)
/* Check arguments */
- if (!name || !*name)
+ if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name")
- if (0==maxaddr || HADDR_UNDEF==maxaddr)
+ if(0 == maxaddr || HADDR_UNDEF == maxaddr)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr")
- if (ADDR_OVERFLOW(maxaddr))
+ if(ADDR_OVERFLOW(maxaddr))
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "maxaddr overflow")
- if (H5P_DEFAULT!=fapl_id) {
- if(NULL == (plist = H5I_object(fapl_id)))
+ HDassert(H5P_DEFAULT != fapl_id);
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
- fa = H5P_get_driver_info(plist);
- } /* end if */
+ fa = (H5FD_core_fapl_t *)H5P_get_driver_info(plist);
/* Build the open flags */
o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY;
- if (H5F_ACC_TRUNC & flags) o_flags |= O_TRUNC;
- if (H5F_ACC_CREAT & flags) o_flags |= O_CREAT;
- if (H5F_ACC_EXCL & flags) o_flags |= O_EXCL;
+ if(H5F_ACC_TRUNC & flags) o_flags |= O_TRUNC;
+ if(H5F_ACC_CREAT & flags) o_flags |= O_CREAT;
+ if(H5F_ACC_EXCL & flags) o_flags |= O_EXCL;
/* Open backing store. The only case that backing store is off is when
* the backing_store flag is off and H5F_ACC_CREAT is on. */
if(fa->backing_store || !(H5F_ACC_CREAT & flags)) {
- if (fa && (fd=HDopen(name, o_flags, 0666))<0)
+ if(fa && (fd = HDopen(name, o_flags, 0666)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file")
- }
+ } /* end if */
/* Create the new file struct */
- if (NULL==(file=H5MM_calloc(sizeof(H5FD_core_t))))
+ if(NULL == (file = (H5FD_core_t *)H5MM_calloc(sizeof(H5FD_core_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct")
file->fd = fd;
- if (name && *name)
+ if(name && *name)
file->name = H5MM_xstrdup(name);
/*
@@ -435,35 +441,34 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
/* If an existing file is opened, load the whole file into memory. */
if(!(H5F_ACC_CREAT & flags)) {
- unsigned char *x=NULL;
size_t size;
- if (HDfstat(file->fd, &sb)<0)
+ /* stat() file to retrieve its size */
+ if(HDfstat(file->fd, &sb) < 0)
HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file")
-
size = (size_t)sb.st_size;
+ /* Check if we should allocate the memory buffer and read in existing data */
if(size) {
- if (NULL==file->mem)
- x = (unsigned char*)H5MM_malloc(size);
-
- if (!x)
+ /* Allocate memory for the file's data */
+ if(NULL == (file->mem = (unsigned char*)H5MM_malloc(size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory block")
- file->mem = x;
+ /* Set up data structures */
file->eof = size;
- if(HDread(file->fd, file->mem, size)<0)
+ /* Read in existing data */
+ if(HDread(file->fd, file->mem, size) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read file")
- }
- }
+ } /* end if */
+ } /* end if */
/* Set return value */
- ret_value=(H5FD_t *)file;
+ ret_value = (H5FD_t *)file;
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_core_open() */
/*-------------------------------------------------------------------------
@@ -478,33 +483,33 @@ done:
* Programmer: Robb Matzke
* Thursday, July 29, 1999
*
- * Modifications:
- * Robb Matzke, 1999-10-19
- * The contents of memory are written to the backing store if
- * one is open.
*-------------------------------------------------------------------------
*/
static herr_t
H5FD_core_close(H5FD_t *_file)
{
H5FD_core_t *file = (H5FD_core_t*)_file;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_core_close, FAIL)
+ /* Flush any changed buffers */
+ if(H5FD_core_flush(_file, (hid_t)-1, TRUE) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file")
+
/* Release resources */
- if (file->fd>=0)
+ if(file->fd >= 0)
HDclose(file->fd);
- if (file->name)
+ if(file->name)
H5MM_xfree(file->name);
- if (file->mem)
+ if(file->mem)
H5MM_xfree(file->mem);
HDmemset(file, 0, sizeof(H5FD_core_t));
H5MM_xfree(file);
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_core_close() */
/*-------------------------------------------------------------------------
@@ -557,6 +562,44 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5FD_core_query
+ *
+ * Purpose: Set the flags that this VFL driver is capable of supporting.
+ * (listed in H5FDpublic.h)
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, October 7, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_core_query(const H5FD_t * _file, unsigned long *flags /* out */)
+{
+ const H5FD_core_t *file = (const H5FD_core_t*)_file;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_core_query)
+
+ /* Set the VFL feature flags that this driver supports */
+ if(flags) {
+ *flags = 0;
+ *flags |= H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
+ *flags |= H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */
+ *flags |= H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
+ *flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
+
+ /* If the backing store is open, a POSIX file handle is available */
+ if(file->fd >= 0 && file->backing_store)
+ *flags |= H5FD_FEAT_POSIX_COMPAT_HANDLE; /* VFD handle is POSIX I/O call compatible */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5FD_core_query() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5FD_core_get_eoa
*
* Purpose: Gets the end-of-address marker for the file. The EOA marker
@@ -580,9 +623,8 @@ done:
static haddr_t
H5FD_core_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type)
{
- haddr_t ret_value; /* Return value */
-
const H5FD_core_t *file = (const H5FD_core_t*)_file;
+ haddr_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5FD_core_get_eoa, HADDR_UNDEF)
@@ -619,18 +661,18 @@ static herr_t
H5FD_core_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED type, haddr_t addr)
{
H5FD_core_t *file = (H5FD_core_t*)_file;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_core_set_eoa, FAIL)
- if (ADDR_OVERFLOW(addr))
+ if(ADDR_OVERFLOW(addr))
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "address overflow")
file->eoa = addr;
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_core_set_eoa() */
/*-------------------------------------------------------------------------
@@ -684,23 +726,52 @@ done:
*
*-------------------------------------------------------------------------
*/
-/* ARGSUSED */
static herr_t
-H5FD_core_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void** file_handle)
+H5FD_core_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle)
{
- H5FD_core_t *file = (H5FD_core_t *)_file;
- herr_t ret_value = SUCCEED;
+ H5FD_core_t *file = (H5FD_core_t *)_file; /* core VFD info */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_core_get_handle, FAIL)
+ /* Check args */
if(!file_handle)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid")
- *file_handle = &(file->mem);
+ /* Check for non-default FAPL */
+ if(H5P_FILE_ACCESS_DEFAULT != fapl && H5P_DEFAULT != fapl) {
+ H5P_genplist_t *plist; /* Property list pointer */
+
+ /* Get the FAPL */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl)))
+ HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, FAIL, "not a file access property list")
+
+ /* Check if private property for retrieving the backing store POSIX
+ * file descriptor is set. (This should not be set except within the
+ * library) QAK - 2009/12/04
+ */
+ if(H5P_exist_plist(plist, H5F_ACS_WANT_POSIX_FD_NAME) > 0) {
+ hbool_t want_posix_fd; /* Setting for retrieving file descriptor from core VFD */
+
+ /* Get property */
+ if(H5P_get(plist, H5F_ACS_WANT_POSIX_FD_NAME, &want_posix_fd) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get property of retrieving file descriptor")
+
+ /* If property is set, pass back the file descriptor instead of the memory address */
+ if(want_posix_fd)
+ *file_handle = &(file->fd);
+ else
+ *file_handle = &(file->mem);
+ } /* end if */
+ else
+ *file_handle = &(file->mem);
+ } /* end if */
+ else
+ *file_handle = &(file->mem);
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_core_get_handle() */
/*-------------------------------------------------------------------------
@@ -794,18 +865,18 @@ static herr_t
H5FD_core_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr,
size_t size, const void *buf)
{
- H5FD_core_t *file = (H5FD_core_t*)_file;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5FD_core_t *file = (H5FD_core_t*)_file;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_core_write, FAIL)
- assert(file && file->pub.cls);
- assert(buf);
+ HDassert(file && file->pub.cls);
+ HDassert(buf);
/* Check for overflow conditions */
- if (REGION_OVERFLOW(addr, size))
+ if(REGION_OVERFLOW(addr, size))
HGOTO_ERROR(H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed")
- if (addr+size>file->eoa)
+ if(addr + size > file->eoa)
HGOTO_ERROR(H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed")
/*
@@ -814,34 +885,33 @@ H5FD_core_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had
* careful of non-Posix realloc() that doesn't understand what to do when
* the first argument is null.
*/
- if (addr+size>file->eof) {
+ if(addr + size > file->eof) {
unsigned char *x;
size_t new_eof;
- H5_ASSIGN_OVERFLOW(new_eof,file->increment*((addr+size)/file->increment),hsize_t,size_t);
-
- if ((addr+size) % file->increment)
+ /* Determine new size of memory buffer */
+ H5_ASSIGN_OVERFLOW(new_eof, file->increment * ((addr + size) / file->increment), hsize_t, size_t);
+ if((addr + size) % file->increment)
new_eof += file->increment;
- if (NULL==file->mem)
- x = H5MM_malloc(new_eof);
- else
- x = H5MM_realloc(file->mem, new_eof);
+
+ /* (Re)allocate memory for the file buffer */
+ if(NULL == (x = (unsigned char *)H5MM_realloc(file->mem, new_eof)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory block")
#ifdef H5_CLEAR_MEMORY
HDmemset(x + file->eof, 0, (size_t)(new_eof - file->eof));
#endif /* H5_CLEAR_MEMORY */
- if (!x)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory block")
file->mem = x;
+
file->eof = new_eof;
- }
+ } /* end if */
/* Write from BUF to memory */
- HDmemcpy(file->mem+addr, buf, size);
+ HDmemcpy(file->mem + addr, buf, size);
file->dirty = TRUE;
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_core_write() */
/*-------------------------------------------------------------------------
@@ -860,7 +930,7 @@ done:
* Modifications:
* Raymond Lu, 2006-11-30
* Added a condition check for backing store flag, for an
- * existing file can be opened for read and write now.
+ * existing file can be opened for read and write now.
*-------------------------------------------------------------------------
*/
/* ARGSUSED */
@@ -898,3 +968,70 @@ H5FD_core_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing)
done:
FUNC_LEAVE_NOAPI(ret_value)
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_core_truncate
+ *
+ * Purpose: Makes sure that the true file size is the same (or larger)
+ * than the end-of-address.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, October 7, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static herr_t
+H5FD_core_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing)
+{
+ H5FD_core_t *file = (H5FD_core_t*)_file;
+ size_t new_eof; /* New size of memory buffer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_core_truncate, FAIL)
+
+ HDassert(file);
+
+ /* Determine new size of memory buffer */
+ H5_ASSIGN_OVERFLOW(new_eof, file->increment * (file->eoa / file->increment), hsize_t, size_t);
+ if(file->eoa % file->increment)
+ new_eof += file->increment;
+
+ /* Extend the file to make sure it's large enough */
+ if(!H5F_addr_eq(file->eof, (haddr_t)new_eof)) {
+ unsigned char *x; /* Pointer to new buffer for file data */
+
+ /* (Re)allocate memory for the file buffer */
+ if(NULL == (x = (unsigned char *)H5MM_realloc(file->mem, new_eof)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory block")
+#ifdef H5_CLEAR_MEMORY
+if(file->eof < new_eof)
+ HDmemset(x + file->eof, 0, (size_t)(new_eof - file->eof));
+#endif /* H5_CLEAR_MEMORY */
+ file->mem = x;
+
+ /* Update backing store, if using it */
+ if(file->fd >= 0 && file->backing_store) {
+#ifdef H5_VMS
+ /* Reset seek offset to the beginning of the file, so that the file isn't
+ * re-extended later. This may happen on Open VMS. */
+ if(-1 == HDlseek(file->fd, 0, SEEK_SET))
+ HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
+#endif
+
+ if(-1 == HDftruncate(file->fd, (off_t)new_eof))
+ HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
+ } /* end if */
+
+ /* Update the eof value */
+ file->eof = new_eof;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_core_truncate() */
+
diff --git a/src/H5FDdirect.c b/src/H5FDdirect.c
index b078511..fff31f3 100644
--- a/src/H5FDdirect.c
+++ b/src/H5FDdirect.c
@@ -18,7 +18,7 @@
* Wednesday, 20 September 2006
*
* Purpose: The Direct I/O file driver forces the data to be written to
- * the file directly without being copied into system kernel
+ * the file directly without being copied into system kernel
* buffer. The main system support this feature is Linux.
*/
@@ -163,14 +163,14 @@ static herr_t H5FD_direct_close(H5FD_t *_file);
static int H5FD_direct_cmp(const H5FD_t *_f1, const H5FD_t *_f2);
static herr_t H5FD_direct_query(const H5FD_t *_f1, unsigned long *flags);
static haddr_t H5FD_direct_get_eoa(const H5FD_t *_file, H5FD_mem_t type);
-static herr_t H5FD_direct_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED type, haddr_t addr);
+static herr_t H5FD_direct_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr);
static haddr_t H5FD_direct_get_eof(const H5FD_t *_file);
static herr_t H5FD_direct_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle);
static herr_t H5FD_direct_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr,
size_t size, void *buf);
static herr_t H5FD_direct_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr,
size_t size, const void *buf);
-static herr_t H5FD_direct_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing);
+static herr_t H5FD_direct_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
static const H5FD_class_t H5FD_direct_g = {
"direct", /*name */
@@ -190,6 +190,7 @@ static const H5FD_class_t H5FD_direct_g = {
H5FD_direct_close, /*close */
H5FD_direct_cmp, /*cmp */
H5FD_direct_query, /*query */
+ NULL, /*get_type_map */
NULL, /*alloc */
NULL, /*free */
H5FD_direct_get_eoa, /*get_eoa */
@@ -198,7 +199,8 @@ static const H5FD_class_t H5FD_direct_g = {
H5FD_direct_get_handle, /*get_handle */
H5FD_direct_read, /*read */
H5FD_direct_write, /*write */
- H5FD_direct_flush, /*flush */
+ NULL, /*flush */
+ H5FD_direct_truncate, /*truncate */
NULL, /*lock */
NULL, /*unlock */
H5FD_FLMAP_SINGLE /*fl_map */
@@ -255,7 +257,7 @@ H5FD_direct_init(void)
FUNC_ENTER_NOAPI(H5FD_direct_init, FAIL)
if (H5I_VFL!=H5I_get_type(H5FD_DIRECT_g))
- H5FD_DIRECT_g = H5FD_register(&H5FD_direct_g,sizeof(H5FD_class_t));
+ H5FD_DIRECT_g = H5FD_register(&H5FD_direct_g,sizeof(H5FD_class_t),FALSE);
/* Set return value */
ret_value=H5FD_DIRECT_g;
@@ -322,7 +324,7 @@ H5Pset_fapl_direct(hid_t fapl_id, size_t boundary, size_t block_size, size_t cbu
if(boundary != 0)
fa.mboundary = boundary;
- else
+ else
fa.mboundary = MBOUNDARY_DEF;
if(block_size != 0)
fa.fbsize = block_size;
@@ -365,7 +367,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Pget_fapl_direct(hid_t fapl_id, size_t *boundary/*out*/, size_t *block_size/*out*/,
+H5Pget_fapl_direct(hid_t fapl_id, size_t *boundary/*out*/, size_t *block_size/*out*/,
size_t *cbuf_size/*out*/)
{
H5FD_direct_fapl_t *fa;
@@ -573,7 +575,7 @@ H5FD_direct_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxadd
if(write(file->fd, (void*)buf1, sizeof(int))<0) {
if(write(file->fd, (void*)buf2, file->fa.fbsize)<0)
HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, NULL, "file system may not support Direct I/O")
- else
+ else
file->fa.must_align = TRUE;
} else {
file->fa.must_align = FALSE;
@@ -583,7 +585,7 @@ H5FD_direct_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxadd
if(read(file->fd, (void*)buf1, sizeof(int))<0) {
if(read(file->fd, (void*)buf2, file->fa.fbsize)<0)
HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "file system may not support Direct I/O")
- else
+ else
file->fa.must_align = TRUE;
} else
file->fa.must_align = FALSE;
@@ -929,20 +931,20 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha
if (addr+size>file->eoa)
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
- /* If the system doesn't require data to be aligned, read the data in
+ /* If the system doesn't require data to be aligned, read the data in
* the same way as sec2 driver.
*/
_must_align = file->fa.must_align;
- /* Get the memory boundary for alignment, file system block size, and maximal
+ /* Get the memory boundary for alignment, file system block size, and maximal
* copy buffer size.
*/
_boundary = file->fa.mboundary;
_fbsize = file->fa.fbsize;
_cbsize = file->fa.cbsize;
- /* if the data is aligned or the system doesn't require data to be aligned,
- * read it directly from the file. If not, read a bigger
+ /* if the data is aligned or the system doesn't require data to be aligned,
+ * read it directly from the file. If not, read a bigger
* and aligned data first, then copy the data into memory buffer.
*/
if(!_must_align || ((addr%_fbsize==0) && (size%_fbsize==0) && ((size_t)buf%_boundary==0))) {
@@ -950,7 +952,7 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha
if ((addr!=file->pos || OP_READ!=file->op) &&
file_seek(file->fd, (file_offset_t)addr, SEEK_SET)<0)
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
- /* Read the aligned data in file first, being careful of interrupted
+ /* Read the aligned data in file first, being careful of interrupted
* system calls and partial results. */
while (size>0) {
do {
@@ -972,8 +974,8 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha
buf = (char*)buf + nbytes;
}
} else {
- /* allocate memory needed for the Direct IO option up to the maximal
- * copy buffer size. Make a bigger buffer for aligned I/O if size is
+ /* allocate memory needed for the Direct IO option up to the maximal
+ * copy buffer size. Make a bigger buffer for aligned I/O if size is
* smaller than maximal copy buffer. */
if(size < _cbsize)
alloc_size = ((size / _fbsize) * _fbsize) + _fbsize;
@@ -987,15 +989,15 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
/*
- * Read the aligned data in file into aligned buffer first, then copy the data
+ * Read the aligned data in file into aligned buffer first, then copy the data
* into the final buffer. If the data size is bigger than maximal copy buffer
* size, do the reading by segment (the outer while loop). If not, do one step
- * reading.
+ * reading.
*/
p3 = buf;
do {
- /* Read the aligned data in file first. Not able to handle interrupted
- * system calls and partial results like sec2 driver does because the
+ /* Read the aligned data in file first. Not able to handle interrupted
+ * system calls and partial results like sec2 driver does because the
* data may no longer be aligned. It's expecially true when the data in
* file is smaller than ALLOC_SIZE. */
HDmemset(copy_buf, 0, alloc_size);
@@ -1008,7 +1010,7 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha
HSYS_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed")
/* look for the right position and copy the data to the original buffer.
- * Consider all possible situations here: file address is not aligned on
+ * Consider all possible situations here: file address is not aligned on
* file block size; the end of data address is not aligned; the end of data
* address is aligned; data size is smaller or bigger than maximal copy size.*/
p2 = (unsigned char*)copy_buf + (size_t)(copy_addr % _fbsize);
@@ -1018,7 +1020,7 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha
HDmemcpy(p3, p2, copy_size);
else if(size >= _cbsize && copy_size > (alloc_size-(size_t)(copy_addr%_fbsize))) {
HDmemcpy(p3, p2, (alloc_size - (size_t)(copy_addr % _fbsize)));
- p3 = (unsigned char*)p3 + (alloc_size - (size_t)(copy_addr % _fbsize));
+ p3 = (unsigned char*)p3 + (alloc_size - (size_t)(copy_addr % _fbsize));
}
/* update the size and address of data being read. */
@@ -1079,7 +1081,8 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
hbool_t _must_align = TRUE;
herr_t ret_value=SUCCEED; /* Return value */
size_t alloc_size;
- void *copy_buf, *p1, *p3;
+ void *copy_buf, *p1;
+ const void *p3;
size_t _boundary;
size_t _fbsize;
size_t _cbsize;
@@ -1099,20 +1102,20 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
if (addr+size>file->eoa)
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
- /* If the system doesn't require data to be aligned, read the data in
+ /* If the system doesn't require data to be aligned, read the data in
* the same way as sec2 driver.
*/
_must_align = file->fa.must_align;
- /* Get the memory boundary for alignment, file system block size, and maximal
+ /* Get the memory boundary for alignment, file system block size, and maximal
* copy buffer size.
*/
_boundary = file->fa.mboundary;
_fbsize = file->fa.fbsize;
_cbsize = file->fa.cbsize;
- /* if the data is aligned or the system doesn't require data to be aligned,
- * write it directly to the file. If not, read a bigger and aligned data
+ /* if the data is aligned or the system doesn't require data to be aligned,
+ * write it directly to the file. If not, read a bigger and aligned data
* first, update buffer with user data, then write the data out.
*/
if(!_must_align || ((addr%_fbsize==0) && (size%_fbsize==0) && ((size_t)buf%_boundary==0))) {
@@ -1140,7 +1143,7 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
* copy buffer size. Make a bigger buffer for aligned I/O if size is
* smaller than maximal copy buffer.
*/
- if(size < _cbsize)
+ if(size < _cbsize)
alloc_size = ((size / _fbsize) * _fbsize) + _fbsize;
else
alloc_size = _cbsize;
@@ -1156,8 +1159,8 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
do {
/*
* Read the aligned data first if the aligned region doesn't fall
- * entirely in the range to be writen. Not able to handle interrupted
- * system calls and partial results like sec2 driver does because the
+ * entirely in the range to be writen. Not able to handle interrupted
+ * system calls and partial results like sec2 driver does because the
* data may no longer be aligned. It's expecially true when the data in
* file is smaller than ALLOC_SIZE.
*/
@@ -1172,7 +1175,7 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
HSYS_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed")
}
- /* look for the right position and append or copy the data to be written to
+ /* look for the right position and append or copy the data to be written to
* the aligned buffer.
* Consider all possible situations here: file address is not aligned on
* file block size; the end of data address is not aligned; the end of data
@@ -1185,15 +1188,15 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
HDmemcpy(p1, p3, copy_size);
}else if(size >= _cbsize && copy_size > (alloc_size-(size_t)(copy_addr%_fbsize))) {
HDmemcpy(p1, p3, (alloc_size - (size_t)(copy_addr % _fbsize)));
- p3 = (unsigned char*)p3 + (alloc_size - (size_t)(copy_addr % _fbsize));
+ p3 = (const unsigned char *)p3 + (alloc_size - (size_t)(copy_addr % _fbsize));
}
-
+
/*look for the aligned position for writing the data*/
if(file_seek(file->fd, (file_offset_t)(copy_addr - copy_addr % _fbsize), SEEK_SET) < 0)
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
/*
- * Write the data. It doesn't truncate the extra data introduced by
+ * Write the data. It doesn't truncate the extra data introduced by
* alignment because that step is done in H5FD_direct_flush.
*/
do {
@@ -1215,7 +1218,7 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
/*Update the address and size*/
addr += (haddr_t)size;
buf = (const char*)buf + size;
-
+
if(copy_buf)
HDfree(copy_buf);
}
@@ -1238,7 +1241,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FD_direct_flush
+ * Function: H5FD_direct_truncate
*
* Purpose: Makes sure that the true file size is the same (or larger)
* than the end-of-address.
@@ -1250,17 +1253,15 @@ done:
* Programmer: Raymond Lu
* Thursday, 21 September 2006
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5FD_direct_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing)
+H5FD_direct_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing)
{
H5FD_direct_t *file = (H5FD_direct_t*)_file;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5FD_direct_flush, FAIL)
+ FUNC_ENTER_NOAPI(H5FD_direct_truncate, FAIL)
assert(file);
@@ -1290,16 +1291,17 @@ H5FD_direct_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing)
/* Reset last file I/O information */
file->pos = HADDR_UNDEF;
file->op = OP_UNKNOWN;
- }
- else if (file->fa.must_align){
+ }
+ else if (file->fa.must_align){
/*Even though eof is equal to eoa, file is still truncated because Direct I/O
*write introduces some extra data for alignment.
*/
if (-1==file_truncate(file->fd, (file_offset_t)file->eof))
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
}
-
+
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_direct_truncate() */
#endif /* H5_HAVE_DIRECT */
+
diff --git a/src/H5FDdirect.h b/src/H5FDdirect.h
index 79886e7..26c70f3 100644
--- a/src/H5FDdirect.h
+++ b/src/H5FDdirect.h
@@ -43,9 +43,9 @@ extern "C" {
H5_DLL hid_t H5FD_direct_init(void);
H5_DLL void H5FD_direct_term(void);
-H5_DLL herr_t H5Pset_fapl_direct(hid_t fapl_id, size_t alignment, size_t block_size,
+H5_DLL herr_t H5Pset_fapl_direct(hid_t fapl_id, size_t alignment, size_t block_size,
size_t cbuf_size);
-H5_DLL herr_t H5Pget_fapl_direct(hid_t fapl_id, size_t *boundary/*out*/,
+H5_DLL herr_t H5Pget_fapl_direct(hid_t fapl_id, size_t *boundary/*out*/,
size_t *block_size/*out*/, size_t *cbuf_size/*out*/);
#ifdef __cplusplus
diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c
index 34360e5..87e5e84 100644
--- a/src/H5FDfamily.c
+++ b/src/H5FDfamily.c
@@ -61,14 +61,19 @@ typedef struct H5FD_family_t {
hid_t memb_fapl_id; /*file access property list for members */
hsize_t memb_size; /*actual size of each member file */
hsize_t pmem_size; /*member size passed in from property */
- hsize_t mem_newsize; /*new member size passed in as private
- *property. It's used only by h5repart */
unsigned nmembs; /*number of family members */
unsigned amembs; /*number of member slots allocated */
H5FD_t **memb; /*dynamic array of member pointers */
haddr_t eoa; /*end of allocated addresses */
char *name; /*name generator printf format */
unsigned flags; /*flags for opening additional members */
+
+ /* Information from properties set by 'h5repart' tool */
+ hsize_t mem_newsize; /*new member size passed in as private
+ * property. It's used only by h5repart */
+ hbool_t repart_members; /* Whether to mark the superblock dirty
+ * when it is loaded, so that the family
+ * member sizes can be re-encoded */
} H5FD_family_t;
/* Driver-specific file access properties */
@@ -107,6 +112,7 @@ static herr_t H5FD_family_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, ha
static herr_t H5FD_family_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr,
size_t size, const void *_buf);
static herr_t H5FD_family_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing);
+static herr_t H5FD_family_truncate(H5FD_t *_file, hid_t dxpl_id, unsigned closing);
/* The class struct */
static const H5FD_class_t H5FD_family_g = {
@@ -127,6 +133,7 @@ static const H5FD_class_t H5FD_family_g = {
H5FD_family_close, /*close */
H5FD_family_cmp, /*cmp */
H5FD_family_query, /*query */
+ NULL, /*get_type_map */
NULL, /*alloc */
NULL, /*free */
H5FD_family_get_eoa, /*get_eoa */
@@ -136,6 +143,7 @@ static const H5FD_class_t H5FD_family_g = {
H5FD_family_read, /*read */
H5FD_family_write, /*write */
H5FD_family_flush, /*flush */
+ H5FD_family_truncate, /*truncate */
NULL, /*lock */
NULL, /*unlock */
H5FD_FLMAP_SINGLE /*fl_map */
@@ -189,7 +197,7 @@ H5FD_family_init(void)
FUNC_ENTER_NOAPI(H5FD_family_init, FAIL)
if (H5I_VFL!=H5Iget_type(H5FD_FAMILY_g))
- H5FD_FAMILY_g = H5FD_register(&H5FD_family_g,sizeof(H5FD_class_t));
+ H5FD_FAMILY_g = H5FD_register(&H5FD_family_g,sizeof(H5FD_class_t),FALSE);
/* Set return value */
ret_value=H5FD_FAMILY_g;
@@ -277,7 +285,7 @@ H5Pset_fapl_family(hid_t fapl_id, hsize_t msize, hid_t memb_fapl_id)
fa.memb_size = msize;
fa.memb_fapl_id = memb_fapl_id;
- if(NULL == (plist = H5I_object(fapl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
ret_value= H5P_set_driver(plist, H5FD_FAMILY, &fa);
@@ -321,16 +329,16 @@ H5Pget_fapl_family(hid_t fapl_id, hsize_t *msize/*out*/,
if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list")
- if (H5FD_FAMILY!=H5P_get_driver(plist))
+ if(H5FD_FAMILY != H5P_get_driver(plist))
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver")
- if (NULL==(fa=H5P_get_driver_info(plist)))
+ if(NULL == (fa = (H5FD_family_fapl_t *)H5P_get_driver_info(plist)))
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "bad VFL driver info")
- if (msize)
+ if(msize)
*msize = fa->memb_size;
- if (memb_fapl_id) {
- if(NULL == (plist = H5I_object(fa->memb_fapl_id)))
+ if(memb_fapl_id) {
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fa->memb_fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list")
- *memb_fapl_id = H5P_copy_plist(plist);
+ *memb_fapl_id = H5P_copy_plist(plist, TRUE);
} /* end if */
done:
@@ -365,13 +373,13 @@ H5FD_family_fapl_get(H5FD_t *_file)
FUNC_ENTER_NOAPI(H5FD_family_fapl_get, NULL)
- if (NULL==(fa=H5MM_calloc(sizeof(H5FD_family_fapl_t))))
+ if(NULL == (fa = (H5FD_family_fapl_t *)H5MM_calloc(sizeof(H5FD_family_fapl_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
fa->memb_size = file->memb_size;
- if(NULL == (plist = H5I_object(file->memb_fapl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(file->memb_fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
- fa->memb_fapl_id = H5P_copy_plist(plist);
+ fa->memb_fapl_id = H5P_copy_plist(plist, FALSE);
/* Set return value */
ret_value=fa;
@@ -411,7 +419,7 @@ H5FD_family_fapl_copy(const void *_old_fa)
FUNC_ENTER_NOAPI(H5FD_family_fapl_copy, NULL)
- if (NULL==(new_fa=H5MM_malloc(sizeof(H5FD_family_fapl_t))))
+ if(NULL == (new_fa = (H5FD_family_fapl_t *)H5MM_malloc(sizeof(H5FD_family_fapl_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Copy the fields of the structure */
@@ -419,13 +427,13 @@ H5FD_family_fapl_copy(const void *_old_fa)
/* Deep copy the property list objects in the structure */
if(old_fa->memb_fapl_id==H5P_FILE_ACCESS_DEFAULT) {
- if(H5I_inc_ref(new_fa->memb_fapl_id)<0)
+ if(H5I_inc_ref(new_fa->memb_fapl_id, FALSE)<0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINC, NULL, "unable to increment ref count on VFL driver")
} /* end if */
else {
- if(NULL == (plist = H5I_object(old_fa->memb_fapl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(old_fa->memb_fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
- new_fa->memb_fapl_id = H5P_copy_plist(plist);
+ new_fa->memb_fapl_id = H5P_copy_plist(plist, FALSE);
} /* end else */
/* Set return value */
@@ -464,7 +472,7 @@ H5FD_family_fapl_free(void *_fa)
FUNC_ENTER_NOAPI(H5FD_family_fapl_free, FAIL)
- if(H5I_dec_ref(fa->memb_fapl_id)<0)
+ if(H5I_dec_ref(fa->memb_fapl_id, FALSE)<0)
HGOTO_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close driver ID")
H5MM_xfree(fa);
@@ -499,19 +507,19 @@ H5FD_family_dxpl_copy(const void *_old_dx)
FUNC_ENTER_NOAPI(H5FD_family_dxpl_copy, NULL)
- if (NULL==(new_dx=H5MM_malloc(sizeof(H5FD_family_dxpl_t))))
+ if(NULL == (new_dx = (H5FD_family_dxpl_t *)H5MM_malloc(sizeof(H5FD_family_dxpl_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- memcpy(new_dx, old_dx, sizeof(H5FD_family_dxpl_t));
+ HDmemcpy(new_dx, old_dx, sizeof(H5FD_family_dxpl_t));
- if(old_dx->memb_dxpl_id==H5P_DATASET_XFER_DEFAULT) {
- if(H5I_inc_ref(new_dx->memb_dxpl_id)<0)
+ if(old_dx->memb_dxpl_id == H5P_DATASET_XFER_DEFAULT) {
+ if(H5I_inc_ref(new_dx->memb_dxpl_id, FALSE)<0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINC, NULL, "unable to increment ref count on VFL driver")
} /* end if */
else {
- if(NULL == (plist = H5I_object(old_dx->memb_dxpl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(old_dx->memb_dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
- new_dx->memb_dxpl_id = H5P_copy_plist(plist);
+ new_dx->memb_dxpl_id = H5P_copy_plist(plist, FALSE);
} /* end else */
/* Set return value */
@@ -550,7 +558,7 @@ H5FD_family_dxpl_free(void *_dx)
FUNC_ENTER_NOAPI(H5FD_family_dxpl_free, FAIL)
- if(H5I_dec_ref(dx->memb_dxpl_id)<0)
+ if(H5I_dec_ref(dx->memb_dxpl_id, FALSE)<0)
HGOTO_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close driver ID")
H5MM_xfree(dx);
@@ -623,8 +631,15 @@ H5FD_family_sb_encode(H5FD_t *_file, char *name/*out*/, unsigned char *buf/*out*
HDstrncpy(name, "NCSAfami", (size_t)8);
name[8] = '\0';
- /* Store member file size */
- UINT64ENCODE(buf, (uint64_t)file->memb_size);
+ /* Store member file size. Use the member file size from the property here.
+ * This is to guarantee backward compatibility. If a file is created with
+ * v1.6 library and the driver info isn't saved in the superblock. We open
+ * it with v1.8, the FILE->MEMB_SIZE will be the actual size of the first
+ * member file (see H5FD_family_open). So it isn't safe to use FILE->MEMB_SIZE.
+ * If the file is created with v1.8, the correctness of FILE->PMEM_SIZE is
+ * checked in H5FD_family_sb_decode. SLU - 2009/3/21
+ */
+ UINT64ENCODE(buf, (uint64_t)file->pmem_size);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5FD_family_sb_encode() */
@@ -646,8 +661,6 @@ H5FD_family_sb_encode(H5FD_t *_file, char *name/*out*/, unsigned char *buf/*out*
* Programmer: Raymond Lu
* Tuesday, May 10, 2005
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -665,9 +678,9 @@ H5FD_family_sb_decode(H5FD_t *_file, const char UNUSED *name, const unsigned cha
/* For h5repart only. Private property of new member size is used to signal
* h5repart is being used to change member file size. h5repart will open
* files for read and write. When the files are closed, metadata will be
- * flushed to the files and updated this new size */
+ * flushed to the files and updated to this new size */
if(file->mem_newsize) {
- file->memb_size = file->mem_newsize;
+ file->memb_size = file->pmem_size = file->mem_newsize;
HGOTO_DONE(ret_value)
} /* end if */
@@ -679,7 +692,7 @@ H5FD_family_sb_decode(H5FD_t *_file, const char UNUSED *name, const unsigned cha
if(msize != file->pmem_size) {
char err_msg[128];
- sprintf(err_msg, "family member size should be %lu, is %lu", (unsigned long)msize, (unsigned long)file->pmem_size);
+ sprintf(err_msg, "Family member size should be %lu. But the size from file access property is %lu", (unsigned long)msize, (unsigned long)file->pmem_size);
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, err_msg)
} /* end if */
@@ -733,78 +746,87 @@ H5FD_family_open(const char *name, unsigned flags, hid_t fapl_id,
H5FD_t *ret_value=NULL;
char memb_name[4096], temp[4096];
hsize_t eof=HADDR_UNDEF;
- hsize_t fam_newsize = 0;
unsigned t_flags = flags & ~H5F_ACC_CREAT;
- H5P_genplist_t *plist; /* Property list pointer */
FUNC_ENTER_NOAPI(H5FD_family_open, NULL)
/* Check arguments */
- if (!name || !*name)
+ if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name")
- if (0==maxaddr || HADDR_UNDEF==maxaddr)
+ if(0 == maxaddr || HADDR_UNDEF == maxaddr)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr")
/* Initialize file from file access properties */
- if (NULL==(file=H5MM_calloc(sizeof(H5FD_family_t))))
+ if(NULL == (file = (H5FD_family_t *)H5MM_calloc(sizeof(H5FD_family_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct")
- if (H5P_FILE_ACCESS_DEFAULT==fapl_id) {
+ if(H5P_FILE_ACCESS_DEFAULT==fapl_id) {
file->memb_fapl_id = H5P_FILE_ACCESS_DEFAULT;
- if(H5I_inc_ref(file->memb_fapl_id)<0)
+ if(H5I_inc_ref(file->memb_fapl_id, FALSE) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINC, NULL, "unable to increment ref count on VFL driver")
- file->memb_size = 1024*1024*1024; /*1GB. Actual member size to be updated later */
- file->pmem_size = 1024*1024*1024; /*1GB. Member size passed in through property */
+ file->memb_size = 1024 * 1024 * 1024; /*1GB. Actual member size to be updated later */
+ file->pmem_size = 1024 * 1024 * 1024; /*1GB. Member size passed in through property */
file->mem_newsize = 0; /*New member size used by h5repart only */
- } else {
+ } /* end if */
+ else {
+ H5P_genplist_t *plist; /* Property list pointer */
H5FD_family_fapl_t *fa;
- if(NULL == (plist = H5I_object(fapl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
- fa = H5P_get_driver_info(plist);
+ fa = (H5FD_family_fapl_t *)H5P_get_driver_info(plist);
+ HDassert(fa);
+
+ /* Check for new family file size. It's used by h5repart only. */
+ if(H5P_exist_plist(plist, H5F_ACS_FAMILY_NEWSIZE_NAME) > 0) {
+ hsize_t fam_newsize = 0; /* New member size, when repartitioning */
- /* New family file size. It's used by h5repart only. */
- if(H5P_exist_plist(plist, H5F_ACS_FAMILY_NEWSIZE_NAME) > 0)
+ /* Get the new family file size */
if(H5P_get(plist, H5F_ACS_FAMILY_NEWSIZE_NAME, &fam_newsize) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get new family member size")
+ /* Store information for later */
+ file->mem_newsize = fam_newsize; /* New member size passed in through property */
+ file->repart_members = TRUE;
+ } /* end if */
+
if(fa->memb_fapl_id==H5P_FILE_ACCESS_DEFAULT) {
- if(H5I_inc_ref(fa->memb_fapl_id)<0)
+ if(H5I_inc_ref(fa->memb_fapl_id, FALSE)<0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINC, NULL, "unable to increment ref count on VFL driver")
file->memb_fapl_id = fa->memb_fapl_id;
} /* end if */
else {
- if(NULL == (plist = H5I_object(fa->memb_fapl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fa->memb_fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
- file->memb_fapl_id = H5P_copy_plist(plist);
+ file->memb_fapl_id = H5P_copy_plist(plist, FALSE);
} /* end else */
file->memb_size = fa->memb_size; /* Actual member size to be updated later */
file->pmem_size = fa->memb_size; /* Member size passed in through property */
- file->mem_newsize = fam_newsize; /* New member size passed in through property */
- }
+ } /* end else */
file->name = H5MM_strdup(name);
file->flags = flags;
/* Check that names are unique */
sprintf(memb_name, name, 0);
sprintf(temp, name, 1);
-
- if (!strcmp(memb_name, temp))
+ if(!HDstrcmp(memb_name, temp))
HGOTO_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, "file names not unique")
/* Open all the family members */
- while (1) {
+ while(1) {
sprintf(memb_name, name, file->nmembs);
/* Enlarge member array */
- if (file->nmembs>=file->amembs) {
- unsigned n = MAX(64, 2*file->amembs);
- H5FD_t **x = H5MM_realloc(file->memb, n*sizeof(H5FD_t*));
+ if(file->nmembs >= file->amembs) {
+ unsigned n = MAX(64, 2 * file->amembs);
+ H5FD_t **x;
- if (!x)
+ HDassert(n > 0);
+ /* coverity["freed_arg"] */
+ if(NULL == (x = (H5FD_t **)H5MM_realloc(file->memb, n * sizeof(H5FD_t *))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to reallocate members")
file->amembs = n;
file->memb = x;
- }
+ } /* end if */
/*
* Attempt to open file. If the first file cannot be opened then fail;
@@ -849,7 +871,7 @@ done:
if (file->memb)
H5MM_xfree(file->memb);
- if(H5I_dec_ref(file->memb_fapl_id)<0)
+ if(H5I_dec_ref(file->memb_fapl_id, FALSE)<0)
HDONE_ERROR(H5E_VFL, H5E_CANTDEC, NULL, "can't close driver ID")
if (file->name)
H5MM_xfree(file->name);
@@ -901,7 +923,7 @@ H5FD_family_close(H5FD_t *_file)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close member files")
/* Clean up other stuff */
- if(H5I_dec_ref(file->memb_fapl_id)<0)
+ if(H5I_dec_ref(file->memb_fapl_id, FALSE)<0)
HGOTO_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close driver ID")
if (file->memb)
H5MM_xfree(file->memb);
@@ -958,38 +980,36 @@ done:
* (listed in H5FDpublic.h)
*
* Return: Success: non-negative
- *
* Failure: negative
*
* Programmer: Quincey Koziol
* Friday, August 25, 2000
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
/* ARGSUSED */
static herr_t
-H5FD_family_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */)
+H5FD_family_query(const H5FD_t * _file, unsigned long *flags /* out */)
{
- herr_t ret_value=SUCCEED;
+ const H5FD_family_t *file = (const H5FD_family_t*)_file; /* Family VFD info */
- FUNC_ENTER_NOAPI(H5FD_family_query, FAIL)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_family_query)
/* Set the VFL feature flags that this driver supports */
if(flags) {
- *flags=0;
- *flags|=H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
- /**flags|=H5FD_FEAT_ACCUMULATE_METADATA;*/ /* OK to accumulate metadata for faster writes.
- * - Turn it off temporarily because there's a bug
- * when trying to flush metadata during closing. */
- *flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
- *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
- }
+ *flags = 0;
+ *flags |= H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
+ *flags |= H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes. */
+ *flags |= H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
+ *flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
+
+ /* Check for flags that are set by h5repart */
+ if(file->repart_members)
+ *flags |= H5FD_FEAT_DIRTY_SBLK_LOAD; /* Mark the superblock dirty when it is loaded (so the family member sizes are rewritten) */
+ } /* end if */
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5FD_family_query() */
/*-------------------------------------------------------------------------
@@ -1049,56 +1069,59 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5FD_family_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t eoa)
+H5FD_family_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t abs_eoa)
{
H5FD_family_t *file = (H5FD_family_t*)_file;
- haddr_t addr=eoa;
+ haddr_t addr = abs_eoa;
char memb_name[4096];
- unsigned u; /* Local index variable */
- herr_t ret_value=SUCCEED; /* Return value */
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_family_set_eoa, FAIL)
- for (u=0; addr || u<file->nmembs; u++) {
+ for(u = 0; addr || u < file->nmembs; u++) {
/* Enlarge member array */
- if (u>=file->amembs) {
- unsigned n = MAX(64, 2*file->amembs);
- H5FD_t **x = H5MM_realloc(file->memb, n*sizeof(H5FD_t*));
- if (!x)
+ if(u >= file->amembs) {
+ unsigned n = MAX(64, 2 * file->amembs);
+ H5FD_t **x = (H5FD_t **)H5MM_realloc(file->memb, n * sizeof(H5FD_t *));
+
+ if(!x)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory block")
file->amembs = n;
file->memb = x;
file->nmembs = u;
- }
+ } /* end if */
/* Create another file if necessary */
- if (u>=file->nmembs || !file->memb[u]) {
+ if(u >= file->nmembs || !file->memb[u]) {
file->nmembs = MAX(file->nmembs, u+1);
sprintf(memb_name, file->name, u);
H5E_BEGIN_TRY {
- H5_CHECK_OVERFLOW(file->memb_size,hsize_t,haddr_t);
- file->memb[u] = H5FDopen(memb_name, file->flags|H5F_ACC_CREAT,
+ H5_CHECK_OVERFLOW(file->memb_size, hsize_t, haddr_t);
+ file->memb[u] = H5FDopen(memb_name, file->flags | H5F_ACC_CREAT,
file->memb_fapl_id, (haddr_t)file->memb_size);
} H5E_END_TRY;
- if (NULL==file->memb[u])
+ if(NULL == file->memb[u])
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to open member file")
- }
+ } /* end if */
/* Set the EOA marker for the member */
- H5_CHECK_OVERFLOW(file->memb_size,hsize_t,haddr_t);
- if (addr>(haddr_t)file->memb_size) {
- if(H5FD_set_eoa(file->memb[u], type, (haddr_t)file->memb_size)<0)
+ /* (Note compensating for base address addition in internal routine) */
+ H5_CHECK_OVERFLOW(file->memb_size, hsize_t, haddr_t);
+ if(addr > (haddr_t)file->memb_size) {
+ if(H5FD_set_eoa(file->memb[u], type, ((haddr_t)file->memb_size - file->pub.base_addr)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to set file eoa")
addr -= file->memb_size;
- } else {
- if(H5FD_set_eoa(file->memb[u], type, addr)<0)
+ } /* end if */
+ else {
+ if(H5FD_set_eoa(file->memb[u], type, (addr - file->pub.base_addr)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to set file eoa")
addr = 0;
- }
- }
+ } /* end else */
+ } /* end for */
- file->eoa = eoa;
+ file->eoa = abs_eoa;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1139,13 +1162,16 @@ H5FD_family_get_eof(const H5FD_t *_file)
* with `i' equal to that member. If all members have zero EOF then exit
* loop with i==0.
*/
- assert(file->nmembs>0);
- for (i=(int)file->nmembs-1; i>=0; --i) {
- if ((eof=H5FD_get_eof(file->memb[i]))!=0)
+ HDassert(file->nmembs > 0);
+ for(i = (int)file->nmembs - 1; i >= 0; --i) {
+ if((eof = H5FD_get_eof(file->memb[i])) != 0)
break;
- if (0==i)
+ if(0 == i)
break;
- }
+ } /* end for */
+
+ /* Adjust for base address for file */
+ eof += file->pub.base_addr;
/*
* The file size is the number of members before the i'th member plus the
@@ -1154,7 +1180,7 @@ H5FD_family_get_eof(const H5FD_t *_file)
eof += ((unsigned)i)*file->memb_size;
/* Set return value */
- ret_value=MAX(eof, file->eoa);
+ ret_value = MAX(eof, file->eoa);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1192,7 +1218,7 @@ H5FD_family_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle)
if(H5P_get(plist, H5F_ACS_FAMILY_OFFSET_NAME, &offset) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get offset for family driver")
- if(offset>(file->memb_size*file->nmembs))
+ if(offset > (file->memb_size * file->nmembs))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "offset is bigger than file size")
memb = (int)(offset/file->memb_size);
@@ -1242,18 +1268,18 @@ H5FD_family_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, si
* Get the member data transfer property list. If the transfer property
* list does not belong to this driver then assume defaults
*/
- if(NULL == (plist = H5I_object(dxpl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- if (H5P_DATASET_XFER_DEFAULT!=dxpl_id && H5FD_FAMILY==H5P_get_driver(plist)) {
- H5FD_family_dxpl_t *dx = H5P_get_driver_info(plist);
+ if(H5P_DATASET_XFER_DEFAULT != dxpl_id && H5FD_FAMILY == H5P_get_driver(plist)) {
+ H5FD_family_dxpl_t *dx = (H5FD_family_dxpl_t *)H5P_get_driver_info(plist);
- assert(TRUE==H5P_isa_class(dxpl_id, H5P_DATASET_XFER));
+ HDassert(TRUE == H5P_isa_class(dxpl_id, H5P_DATASET_XFER));
assert(dx);
memb_dxpl_id = dx->memb_dxpl_id;
- }
+ } /* end if */
/* Read from each member */
- while (size>0) {
+ while(size > 0) {
H5_ASSIGN_OVERFLOW(u,addr /file->memb_size,hsize_t,unsigned);
sub = addr % file->memb_size;
@@ -1311,7 +1337,7 @@ H5FD_family_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, s
hsize_t tempreq;
unsigned u; /* Local index variable */
H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_family_write, FAIL)
@@ -1319,15 +1345,15 @@ H5FD_family_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, s
* Get the member data transfer property list. If the transfer property
* list does not belong to this driver then assume defaults.
*/
- if(NULL == (plist = H5I_object(dxpl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- if (H5P_DATASET_XFER_DEFAULT!=dxpl_id && H5FD_FAMILY==H5P_get_driver(plist)) {
- H5FD_family_dxpl_t *dx = H5P_get_driver_info(plist);
+ if(H5P_DATASET_XFER_DEFAULT != dxpl_id && H5FD_FAMILY == H5P_get_driver(plist)) {
+ H5FD_family_dxpl_t *dx = (H5FD_family_dxpl_t *)H5P_get_driver_info(plist);
- assert(TRUE==H5P_isa_class(dxpl_id, H5P_DATASET_XFER));
- assert(dx);
+ HDassert(TRUE == H5P_isa_class(dxpl_id, H5P_DATASET_XFER));
+ HDassert(dx);
memb_dxpl_id = dx->memb_dxpl_id;
- }
+ } /* end if */
/* Write to each member */
while (size>0) {
@@ -1364,32 +1390,65 @@ done:
* Purpose: Flushes all family members.
*
* Return: Success: 0
- *
* Failure: -1, as many files flushed as possible.
*
* Programmer: Robb Matzke
* Wednesday, August 4, 1999
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
H5FD_family_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing)
{
H5FD_family_t *file = (H5FD_family_t*)_file;
- unsigned u, nerrors=0;
- herr_t ret_value=SUCCEED; /* Return value */
+ unsigned u, nerrors = 0;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_family_flush, FAIL)
- for (u=0; u<file->nmembs; u++)
- if (file->memb[u] && H5FD_flush(file->memb[u], dxpl_id, closing)<0)
+ for(u = 0; u < file->nmembs; u++)
+ if(file->memb[u] && H5FD_flush(file->memb[u], dxpl_id, closing) < 0)
nerrors++;
- if (nerrors)
+ if(nerrors)
HGOTO_ERROR(H5E_IO, H5E_BADVALUE, FAIL, "unable to flush member files")
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_family_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_family_truncate
+ *
+ * Purpose: Truncates all family members.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1, as many files truncated as possible.
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, February 23, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_family_truncate(H5FD_t *_file, hid_t dxpl_id, unsigned closing)
+{
+ H5FD_family_t *file = (H5FD_family_t*)_file;
+ unsigned u, nerrors = 0;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_family_truncate, FAIL)
+
+ for(u = 0; u < file->nmembs; u++)
+ if(file->memb[u] && H5FD_truncate(file->memb[u], dxpl_id, closing) < 0)
+ nerrors++;
+
+ if(nerrors)
+ HGOTO_ERROR(H5E_IO, H5E_BADVALUE, FAIL, "unable to flush member files")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_family_truncate() */
+
diff --git a/src/H5FDint.c b/src/H5FDint.c
new file mode 100644
index 0000000..74b3bf6
--- /dev/null
+++ b/src/H5FDint.c
@@ -0,0 +1,312 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5FDint.c
+ * Jan 17 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Internal routine for VFD operations
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5FD_PACKAGE /*suppress error about including H5FDpkg */
+
+/* Interface initialization */
+#define H5_INTERFACE_INIT_FUNC H5FD_int_init_interface
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fprivate.h" /* File access */
+#include "H5FDpkg.h" /* File Drivers */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Pprivate.h" /* Property lists */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*--------------------------------------------------------------------------
+NAME
+ H5FD_int_init_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5FD_int_init_interface()
+
+RETURNS
+ Non-negative on success/Negative on failure
+DESCRIPTION
+ Initializes any interface-specific data or routines. (Just calls
+ H5FD_init_iterface currently).
+
+--------------------------------------------------------------------------*/
+static herr_t
+H5FD_int_init_interface(void)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_int_init_interface)
+
+ FUNC_LEAVE_NOAPI(H5FD_init())
+} /* H5FD_int_init_interface() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_read
+ *
+ * Purpose: Private version of H5FDread()
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FD_read(H5FD_t *file, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr,
+ size_t size, void *buf/*out*/)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_read, FAIL)
+
+ HDassert(file && file->cls);
+ HDassert(H5I_GENPROP_LST == H5I_get_type(dxpl_id));
+ HDassert(TRUE == H5P_isa_class(dxpl_id, H5P_DATASET_XFER));
+ HDassert(buf);
+
+#ifndef H5_HAVE_PARALLEL
+ /* Do not return early for Parallel mode since the I/O could be a */
+ /* collective transfer. */
+ /* The no-op case */
+ if(0 == size)
+ HGOTO_DONE(SUCCEED)
+#endif /* H5_HAVE_PARALLEL */
+
+ /* Dispatch to driver */
+ if((file->cls->read)(file, type, dxpl_id, addr + file->base_addr, size, buf) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_write
+ *
+ * Purpose: Private version of H5FDwrite()
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FD_write(H5FD_t *file, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr,
+ size_t size, const void *buf)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_write, FAIL)
+
+ HDassert(file && file->cls);
+ HDassert(H5I_GENPROP_LST == H5I_get_type(dxpl_id));
+ HDassert(TRUE == H5P_isa_class(dxpl_id, H5P_DATASET_XFER));
+ HDassert(buf);
+
+#ifndef H5_HAVE_PARALLEL
+ /* Do not return early for Parallel mode since the I/O could be a */
+ /* collective transfer. */
+ /* The no-op case */
+ if(0 == size)
+ HGOTO_DONE(SUCCEED)
+#endif /* H5_HAVE_PARALLEL */
+
+ /* Dispatch to driver */
+ if((file->cls->write)(file, type, dxpl_id, addr + file->base_addr, size, buf) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write request failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_write() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_set_eoa
+ *
+ * Purpose: Private version of H5FDset_eoa()
+ *
+ * This function expects the EOA is a RELATIVE address, i.e.
+ * relative to the base address. This is NOT the same as the
+ * EOA stored in the superblock, which is an absolute
+ * address. Object addresses are relative.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative, no side effect
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FD_set_eoa(H5FD_t *file, H5FD_mem_t type, haddr_t addr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_set_eoa, FAIL)
+
+ HDassert(file && file->cls);
+ HDassert(H5F_addr_defined(addr) && addr <= file->maxaddr);
+
+ /* Dispatch to driver, convert to absolute address */
+ if((file->cls->set_eoa)(file, type, addr + file->base_addr) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver set_eoa request failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_set_eoa() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_get_eoa
+ *
+ * Purpose: Private version of H5FDget_eoa()
+ *
+ * This function returns the EOA as a RELATIVE address, i.e.
+ * relative to the base address. This is NOT the same as the
+ * EOA stored in the superblock, which is an absolute
+ * address. Object addresses are relative.
+ *
+ * Return: Success: First byte after allocated memory.
+ * Failure: HADDR_UNDEF
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ *-------------------------------------------------------------------------
+ */
+haddr_t
+H5FD_get_eoa(const H5FD_t *file, H5FD_mem_t type)
+{
+ haddr_t ret_value;
+
+ FUNC_ENTER_NOAPI(H5FD_get_eoa, HADDR_UNDEF)
+
+ HDassert(file && file->cls);
+
+ /* Dispatch to driver */
+ if(HADDR_UNDEF == (ret_value = (file->cls->get_eoa)(file, type)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "driver get_eoa request failed")
+
+ /* Adjust for base address in file (convert to relative address) */
+ ret_value -= file->base_addr;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_get_eoa() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_get_eof
+ *
+ * Purpose: Private version of H5FDget_eof()
+ *
+ * This function returns the EOF as a RELATIVE address, i.e.
+ * relative to the base address. This will be different
+ * from the end of the physical file if there is a user
+ * block.
+ *
+ * Return: Success: The EOF address.
+ *
+ * Failure: HADDR_UNDEF
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+haddr_t
+H5FD_get_eof(const H5FD_t *file)
+{
+ haddr_t ret_value;
+
+ FUNC_ENTER_NOAPI(H5FD_get_eof, HADDR_UNDEF)
+
+ HDassert(file && file->cls);
+
+ /* Dispatch to driver */
+ if(file->cls->get_eof) {
+ if(HADDR_UNDEF == (ret_value = (file->cls->get_eof)(file)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "driver get_eof request failed")
+ } /* end if */
+ else
+ ret_value = file->maxaddr;
+
+ /* Adjust for base address in file (convert to relative address) */
+ ret_value -= file->base_addr;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_get_eof() */
+
diff --git a/src/H5FDlog.c b/src/H5FDlog.c
index dee4581..bde63cc 100644
--- a/src/H5FDlog.c
+++ b/src/H5FDlog.c
@@ -190,8 +190,9 @@ static herr_t H5FD_log_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr
size_t size, void *buf);
static herr_t H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr,
size_t size, const void *buf);
-static herr_t H5FD_log_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing);
+static herr_t H5FD_log_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
+#ifdef OLD_WAY
/*
* The free list map which causes each request type to use no free lists
*/
@@ -204,6 +205,7 @@ static herr_t H5FD_log_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing);
H5FD_MEM_NOLIST, /*lheap*/ \
H5FD_MEM_NOLIST /*ohdr*/ \
}
+#endif /* OLD_WAY */
static const H5FD_class_t H5FD_log_g = {
"log", /*name */
@@ -223,6 +225,7 @@ static const H5FD_class_t H5FD_log_g = {
H5FD_log_close, /*close */
H5FD_log_cmp, /*cmp */
H5FD_log_query, /*query */
+ NULL, /*get_type_map */
H5FD_log_alloc, /*alloc */
NULL, /*free */
H5FD_log_get_eoa, /*get_eoa */
@@ -231,14 +234,11 @@ static const H5FD_class_t H5FD_log_g = {
H5FD_log_get_handle, /*get_handle */
H5FD_log_read, /*read */
H5FD_log_write, /*write */
- H5FD_log_flush, /*flush */
+ NULL, /*flush */
+ H5FD_log_truncate, /*truncate */
NULL, /*lock */
NULL, /*unlock */
-#ifdef OLD_WAY
- H5FD_FLMAP_NOLIST /*fl_map */
-#else /* OLD_WAY */
H5FD_FLMAP_SINGLE /*fl_map */
-#endif /* OLD_WAY */
};
@@ -289,7 +289,7 @@ H5FD_log_init(void)
FUNC_ENTER_NOAPI(H5FD_log_init, FAIL)
if (H5I_VFL!=H5Iget_type(H5FD_LOG_g))
- H5FD_LOG_g = H5FD_register(&H5FD_log_g,sizeof(H5FD_class_t));
+ H5FD_LOG_g = H5FD_register(&H5FD_log_g,sizeof(H5FD_class_t),FALSE);
/* Set return value */
ret_value=H5FD_LOG_g;
@@ -358,14 +358,14 @@ H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned flags, size_t buf_s
if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- fa.logfile=(char*)logfile;
- fa.flags=flags;
- fa.buf_size=buf_size;
- ret_value= H5P_set_driver(plist, H5FD_LOG, &fa);
+ fa.logfile = (char *)logfile;
+ fa.flags = flags;
+ fa.buf_size = buf_size;
+ ret_value = H5P_set_driver(plist, H5FD_LOG, &fa);
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Pset_fapl_log() */
/*-------------------------------------------------------------------------
@@ -409,39 +409,47 @@ done:
* Purpose: Copies the log-specific file access properties.
*
* Return: Success: Ptr to a new property list
- *
* Failure: NULL
*
* Programmer: Quincey Koziol
* Thursday, April 20, 2000
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static void *
H5FD_log_fapl_copy(const void *_old_fa)
{
const H5FD_log_fapl_t *old_fa = (const H5FD_log_fapl_t*)_old_fa;
- H5FD_log_fapl_t *new_fa = H5MM_malloc(sizeof(H5FD_log_fapl_t));
+ H5FD_log_fapl_t *new_fa = NULL; /* New FAPL info */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5FD_log_fapl_copy, NULL)
- assert(new_fa);
+ HDassert(new_fa);
+
+ /* Allocate the new FAPL info */
+ if(NULL == (new_fa = (H5FD_log_fapl_t *)H5MM_calloc(sizeof(H5FD_log_fapl_t))))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "unable to allocate log file FAPL")
/* Copy the general information */
HDmemcpy(new_fa, old_fa, sizeof(H5FD_log_fapl_t));
/* Deep copy the log file name */
- if(old_fa->logfile!=NULL)
- if (NULL==(new_fa->logfile=H5MM_xstrdup(old_fa->logfile)))
+ if(old_fa->logfile != NULL)
+ if(NULL == (new_fa->logfile = H5MM_xstrdup(old_fa->logfile)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate log file name")
/* Set return value */
- ret_value=new_fa;
+ ret_value = new_fa;
done:
+ if(NULL == ret_value)
+ if(new_fa) {
+ if(new_fa->logfile)
+ H5MM_free(new_fa->logfile);
+ H5MM_free(new_fa);
+ } /* end if */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_log_fapl_copy() */
@@ -452,21 +460,18 @@ done:
* Purpose: Frees the log-specific file access properties.
*
* Return: Success: 0
- *
* Failure: -1
*
* Programmer: Quincey Koziol
* Thursday, April 20, 2000
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
H5FD_log_fapl_free(void *_fa)
{
H5FD_log_fapl_t *fa = (H5FD_log_fapl_t*)_fa;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_log_fapl_free, FAIL)
@@ -488,65 +493,66 @@ done:
* Return: Success: A pointer to a new file data structure. The
* public fields will be initialized by the
* caller, which is always H5FD_open().
- *
* Failure: NULL
*
* Programmer: Robb Matzke
* Thursday, July 29, 1999
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static H5FD_t *
H5FD_log_open(const char *name, unsigned flags, hid_t fapl_id,
haddr_t maxaddr)
{
- int o_flags;
- int fd=(-1);
- H5FD_log_t *file=NULL;
+ int o_flags;
+ int fd = (-1);
+ H5FD_log_t *file = NULL;
H5FD_log_fapl_t *fa; /* File access property list information */
#ifdef _WIN32
HFILE filehandle;
struct _BY_HANDLE_FILE_INFORMATION fileinfo;
#endif
- h5_stat_t sb;
+ h5_stat_t sb;
H5P_genplist_t *plist; /* Property list */
H5FD_t *ret_value;
FUNC_ENTER_NOAPI(H5FD_log_open, NULL)
/* Check arguments */
- if (!name || !*name)
+ if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name")
- if (0==maxaddr || HADDR_UNDEF==maxaddr)
+ if(0 == maxaddr || HADDR_UNDEF == maxaddr)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr")
- if (ADDR_OVERFLOW(maxaddr))
+ if(ADDR_OVERFLOW(maxaddr))
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr")
/* Build the open flags */
o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY;
- if (H5F_ACC_TRUNC & flags) o_flags |= O_TRUNC;
- if (H5F_ACC_CREAT & flags) o_flags |= O_CREAT;
- if (H5F_ACC_EXCL & flags) o_flags |= O_EXCL;
+ if(H5F_ACC_TRUNC & flags)
+ o_flags |= O_TRUNC;
+ if(H5F_ACC_CREAT & flags)
+ o_flags |= O_CREAT;
+ if(H5F_ACC_EXCL & flags)
+ o_flags |= O_EXCL;
/* Open the file */
- if ((fd=HDopen(name, o_flags, 0666))<0)
+ if((fd = HDopen(name, o_flags, 0666)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file")
- if (HDfstat(fd, &sb)<0)
+ if(HDfstat(fd, &sb) < 0)
HGOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file")
/* Create the new file struct */
- if (NULL==(file=H5MM_calloc(sizeof(H5FD_log_t))))
+ if(NULL == (file = (H5FD_log_t *)H5MM_calloc(sizeof(H5FD_log_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct")
/* Get the driver specific information */
- if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
+ if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
- fa = H5P_get_driver_info(plist);
+ fa = (H5FD_log_fapl_t *)H5P_get_driver_info(plist);
+ HDassert(fa);
file->fd = fd;
- H5_ASSIGN_OVERFLOW(file->eof,sb.st_size,h5_stat_size_t,haddr_t);
+ H5_ASSIGN_OVERFLOW(file->eof, sb.st_size, h5_stat_size_t, haddr_t);
file->pos = HADDR_UNDEF;
file->op = OP_UNKNOWN;
#ifdef _WIN32
@@ -560,36 +566,37 @@ H5FD_log_open(const char *name, unsigned flags, hid_t fapl_id,
#endif
/* Get the flags for logging */
- file->fa.flags=fa->flags;
+ file->fa.flags = fa->flags;
/* Check if we are doing any logging at all */
- if(file->fa.flags!=0) {
- file->iosize=fa->buf_size;
- if(file->fa.flags&H5FD_LOG_FILE_READ) {
- file->nread=H5MM_calloc(file->iosize);
- assert(file->nread);
+ if(file->fa.flags != 0) {
+ file->iosize = fa->buf_size;
+ if(file->fa.flags & H5FD_LOG_FILE_READ) {
+ file->nread = (unsigned char *)H5MM_calloc(file->iosize);
+ HDassert(file->nread);
} /* end if */
- if(file->fa.flags&H5FD_LOG_FILE_WRITE) {
- file->nwrite=H5MM_calloc(file->iosize);
- assert(file->nwrite);
+ if(file->fa.flags & H5FD_LOG_FILE_WRITE) {
+ file->nwrite = (unsigned char *)H5MM_calloc(file->iosize);
+ HDassert(file->nwrite);
} /* end if */
- if(file->fa.flags&H5FD_LOG_FLAVOR) {
- file->flavor=H5MM_calloc(file->iosize);
- assert(file->flavor);
+ if(file->fa.flags & H5FD_LOG_FLAVOR) {
+ file->flavor = (unsigned char *)H5MM_calloc(file->iosize);
+ HDassert(file->flavor);
} /* end if */
if(fa->logfile)
- file->logfp=HDfopen(fa->logfile,"w");
+ file->logfp = HDfopen(fa->logfile, "w");
else
- file->logfp=stderr;
+ file->logfp = stderr;
} /* end if */
/* Set return value */
- ret_value=(H5FD_t*)file;
+ ret_value = (H5FD_t*)file;
done:
- if(ret_value==NULL) {
- if(fd>=0)
+ if(NULL == ret_value) {
+ if(fd >= 0)
HDclose(fd);
+ file = (H5FD_log_t *)H5MM_xfree(file);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -602,14 +609,11 @@ done:
* Purpose: Closes a Unix file.
*
* Return: Success: 0
- *
* Failure: -1, file not closed.
*
* Programmer: Robb Matzke
* Thursday, July 29, 1999
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -620,7 +624,7 @@ H5FD_log_close(H5FD_t *_file)
struct timeval timeval_start,timeval_stop;
struct timeval timeval_diff;
#endif /* H5_HAVE_GETTIMEOFDAY */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_log_close, FAIL)
@@ -628,7 +632,7 @@ H5FD_log_close(H5FD_t *_file)
if(file->fa.flags&H5FD_LOG_TIME_CLOSE)
HDgettimeofday(&timeval_start,NULL);
#endif /* H5_HAVE_GETTIMEOFDAY */
- if (HDclose(file->fd)<0)
+ if(HDclose(file->fd) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file")
#ifdef H5_HAVE_GETTIMEOFDAY
if(file->fa.flags&H5FD_LOG_TIME_CLOSE)
@@ -636,83 +640,83 @@ H5FD_log_close(H5FD_t *_file)
#endif /* H5_HAVE_GETTIMEOFDAY */
/* Dump I/O information */
- if(file->fa.flags!=0) {
+ if(file->fa.flags != 0) {
haddr_t addr;
haddr_t last_addr;
unsigned char last_val;
#ifdef H5_HAVE_GETTIMEOFDAY
- if(file->fa.flags&H5FD_LOG_TIME_CLOSE) {
+ if(file->fa.flags & H5FD_LOG_TIME_CLOSE) {
/* Calculate the elapsed gettimeofday time */
- timeval_diff.tv_usec=timeval_stop.tv_usec-timeval_start.tv_usec;
- timeval_diff.tv_sec=timeval_stop.tv_sec-timeval_start.tv_sec;
- if(timeval_diff.tv_usec<0) {
- timeval_diff.tv_usec+=1000000;
+ timeval_diff.tv_usec = timeval_stop.tv_usec - timeval_start.tv_usec;
+ timeval_diff.tv_sec = timeval_stop.tv_sec - timeval_start.tv_sec;
+ if(timeval_diff.tv_usec < 0) {
+ timeval_diff.tv_usec += 1000000;
timeval_diff.tv_sec--;
} /* end if */
- HDfprintf(file->logfp,"Close took: (%f s)\n",(double)timeval_diff.tv_sec+((double)timeval_diff.tv_usec/(double)1000000.0));
+ HDfprintf(file->logfp, "Close took: (%f s)\n", (double)timeval_diff.tv_sec + ((double)timeval_diff.tv_usec / (double)1000000.0));
} /* end if */
#endif /* H5_HAVE_GETTIMEOFDAY */
/* Dump the write I/O information */
- if(file->fa.flags&H5FD_LOG_FILE_WRITE) {
- HDfprintf(file->logfp,"Dumping write I/O information:\n");
- last_val=file->nwrite[0];
- last_addr=0;
- addr=1;
- while(addr<file->eoa) {
- if(file->nwrite[addr]!=last_val) {
- HDfprintf(file->logfp,"\tAddr %10a-%10a (%10lu bytes) written to %3d times\n",last_addr,(addr-1),(unsigned long)(addr-last_addr),(int)last_val);
- last_val=file->nwrite[addr];
- last_addr=addr;
+ if(file->fa.flags & H5FD_LOG_FILE_WRITE) {
+ HDfprintf(file->logfp, "Dumping write I/O information:\n");
+ last_val = file->nwrite[0];
+ last_addr = 0;
+ addr = 1;
+ while(addr < file->eoa) {
+ if(file->nwrite[addr] != last_val) {
+ HDfprintf(file->logfp, "\tAddr %10a-%10a (%10lu bytes) written to %3d times\n", last_addr, (addr - 1), (unsigned long)(addr - last_addr), (int)last_val);
+ last_val = file->nwrite[addr];
+ last_addr = addr;
} /* end if */
addr++;
} /* end while */
- HDfprintf(file->logfp,"\tAddr %10a-%10a (%10lu bytes) written to %3d times\n",last_addr,(addr-1),(unsigned long)(addr-last_addr),(int)last_val);
+ HDfprintf(file->logfp, "\tAddr %10a-%10a (%10lu bytes) written to %3d times\n", last_addr, (addr - 1), (unsigned long)(addr - last_addr), (int)last_val);
} /* end if */
/* Dump the read I/O information */
- if(file->fa.flags&H5FD_LOG_FILE_READ) {
- HDfprintf(file->logfp,"Dumping read I/O information:\n");
- last_val=file->nread[0];
- last_addr=0;
- addr=1;
- while(addr<file->eoa) {
- if(file->nread[addr]!=last_val) {
- HDfprintf(file->logfp,"\tAddr %10a-%10a (%10lu bytes) read from %3d times\n",last_addr,(addr-1),(unsigned long)(addr-last_addr),(int)last_val);
- last_val=file->nread[addr];
- last_addr=addr;
+ if(file->fa.flags & H5FD_LOG_FILE_READ) {
+ HDfprintf(file->logfp, "Dumping read I/O information:\n");
+ last_val = file->nread[0];
+ last_addr = 0;
+ addr = 1;
+ while(addr < file->eoa) {
+ if(file->nread[addr] != last_val) {
+ HDfprintf(file->logfp, "\tAddr %10a-%10a (%10lu bytes) read from %3d times\n", last_addr, (addr - 1), (unsigned long)(addr - last_addr), (int)last_val);
+ last_val = file->nread[addr];
+ last_addr = addr;
} /* end if */
addr++;
} /* end while */
- HDfprintf(file->logfp,"\tAddr %10a-%10a (%10lu bytes) read from %3d times\n",last_addr,(addr-1),(unsigned long)(addr-last_addr),(int)last_val);
+ HDfprintf(file->logfp, "\tAddr %10a-%10a (%10lu bytes) read from %3d times\n", last_addr, (addr - 1), (unsigned long)(addr - last_addr), (int)last_val);
} /* end if */
/* Dump the I/O flavor information */
- if(file->fa.flags&H5FD_LOG_FLAVOR) {
- HDfprintf(file->logfp,"Dumping I/O flavor information:\n");
- last_val=file->flavor[0];
- last_addr=0;
- addr=1;
- while(addr<file->eoa) {
- if(file->flavor[addr]!=last_val) {
- HDfprintf(file->logfp,"\tAddr %10a-%10a (%10lu bytes) flavor is %s\n",last_addr,(addr-1),(unsigned long)(addr-last_addr),flavors[last_val]);
- last_val=file->flavor[addr];
- last_addr=addr;
+ if(file->fa.flags & H5FD_LOG_FLAVOR) {
+ HDfprintf(file->logfp, "Dumping I/O flavor information:\n");
+ last_val = file->flavor[0];
+ last_addr = 0;
+ addr = 1;
+ while(addr < file->eoa) {
+ if(file->flavor[addr] != last_val) {
+ HDfprintf(file->logfp, "\tAddr %10a-%10a (%10lu bytes) flavor is %s\n", last_addr, (addr - 1), (unsigned long)(addr - last_addr), flavors[last_val]);
+ last_val = file->flavor[addr];
+ last_addr = addr;
} /* end if */
addr++;
} /* end while */
- HDfprintf(file->logfp,"\tAddr %10a-%10a (%10lu bytes) flavor is %s\n",last_addr,(addr-1),(unsigned long)(addr-last_addr),flavors[last_val]);
+ HDfprintf(file->logfp, "\tAddr %10a-%10a (%10lu bytes) flavor is %s\n", last_addr, (addr - 1), (unsigned long)(addr - last_addr), flavors[last_val]);
} /* end if */
/* Free the logging information */
- if(file->fa.flags&H5FD_LOG_FILE_WRITE)
- file->nwrite=H5MM_xfree(file->nwrite);
- if(file->fa.flags&H5FD_LOG_FILE_READ)
- file->nread=H5MM_xfree(file->nread);
- if(file->fa.flags&H5FD_LOG_FLAVOR)
- file->flavor=H5MM_xfree(file->flavor);
- if(file->logfp!=stderr)
+ if(file->fa.flags & H5FD_LOG_FILE_WRITE)
+ file->nwrite = (unsigned char *)H5MM_xfree(file->nwrite);
+ if(file->fa.flags & H5FD_LOG_FILE_READ)
+ file->nread = (unsigned char *)H5MM_xfree(file->nread);
+ if(file->fa.flags & H5FD_LOG_FLAVOR)
+ file->flavor = (unsigned char *)H5MM_xfree(file->flavor);
+ if(file->logfp != stderr)
fclose(file->logfp);
} /* end if */
@@ -720,7 +724,7 @@ H5FD_log_close(H5FD_t *_file)
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_log_close() */
/*-------------------------------------------------------------------------
@@ -800,22 +804,20 @@ done:
static herr_t
H5FD_log_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */)
{
- herr_t ret_value=SUCCEED;
-
- FUNC_ENTER_NOAPI(H5FD_log_query, FAIL)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_query)
/* Set the VFL feature flags that this driver supports */
if(flags) {
*flags = 0;
- *flags|=H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
- *flags|=H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */
- *flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
- *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
- }
+ *flags |= H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
+ *flags |= H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */
+ *flags |= H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
+ *flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
+ *flags |= H5FD_FEAT_POSIX_COMPAT_HANDLE; /* VFD handle is POSIX I/O call compatible */
+ } /* end if */
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5FD_log_query() */
/*-------------------------------------------------------------------------
@@ -1303,30 +1305,27 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FD_log_flush
+ * Function: H5FD_log_truncate
*
* Purpose: Makes sure that the true file size is the same (or larger)
* than the end-of-address.
*
* Return: Success: Non-negative
- *
* Failure: Negative
*
* Programmer: Robb Matzke
* Wednesday, August 4, 1999
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
/* ARGSUSED */
static herr_t
-H5FD_log_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing)
+H5FD_log_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing)
{
H5FD_log_t *file = (H5FD_log_t*)_file;
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5FD_log_flush, FAIL)
+ FUNC_ENTER_NOAPI(H5FD_log_truncate, FAIL)
if(file->eoa>file->eof) {
if(-1 == file_seek(file->fd, (file_offset_t)(file->eoa - 1), SEEK_SET))
@@ -1340,4 +1339,5 @@ H5FD_log_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing)
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_log_truncate() */
+
diff --git a/src/H5FDmpi.h b/src/H5FDmpi.h
index 0384018..b9998dd 100644
--- a/src/H5FDmpi.h
+++ b/src/H5FDmpi.h
@@ -22,8 +22,8 @@
#ifndef H5FDmpi_H
#define H5FDmpi_H
-/***** Macros for One linked collective IO case. *****/
-/* The default value to do one linked collective IO for all chunks.
+/***** Macros for One linked collective IO case. *****/
+/* The default value to do one linked collective IO for all chunks.
If the average number of chunks per process is greater than this value,
the library will create an MPI derived datatype to link all chunks to do collective IO.
The user can set this value through an API. */
@@ -120,3 +120,4 @@ H5_DLL MPI_Comm H5FD_mpi_get_comm(const H5FD_t *_file);
#endif /* H5_HAVE_PARALLEL */
#endif /* H5FDmpi_H */
+
diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c
index 89a8637..5e5349d 100644
--- a/src/H5FDmpio.c
+++ b/src/H5FDmpio.c
@@ -82,6 +82,7 @@ static herr_t H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, hadd
static herr_t H5FD_mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr,
size_t size, const void *buf);
static herr_t H5FD_mpio_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing);
+static herr_t H5FD_mpio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
static int H5FD_mpio_mpi_rank(const H5FD_t *_file);
static int H5FD_mpio_mpi_size(const H5FD_t *_file);
static MPI_Comm H5FD_mpio_communicator(const H5FD_t *_file);
@@ -112,6 +113,7 @@ static const H5FD_class_mpi_t H5FD_mpio_g = {
H5FD_mpio_close, /*close */
NULL, /*cmp */
H5FD_mpio_query, /*query */
+ NULL, /*get_type_map */
NULL, /*alloc */
NULL, /*free */
H5FD_mpio_get_eoa, /*get_eoa */
@@ -121,6 +123,7 @@ static const H5FD_class_mpi_t H5FD_mpio_g = {
H5FD_mpio_read, /*read */
H5FD_mpio_write, /*write */
H5FD_mpio_flush, /*flush */
+ H5FD_mpio_truncate, /*truncate */
NULL, /*lock */
NULL, /*unlock */
H5FD_FLMAP_SINGLE /*fl_map */
@@ -201,7 +204,7 @@ H5FD_mpio_init(void)
FUNC_ENTER_NOAPI(H5FD_mpio_init, FAIL)
if (H5I_VFL!=H5I_get_type(H5FD_MPIO_g))
- H5FD_MPIO_g = H5FD_register((const H5FD_class_t *)&H5FD_mpio_g,sizeof(H5FD_class_mpi_t));
+ H5FD_MPIO_g = H5FD_register((const H5FD_class_t *)&H5FD_mpio_g,sizeof(H5FD_class_mpi_t),FALSE);
#ifdef H5FDmpio_DEBUG
if (!H5FD_mpio_Debug_inited)
@@ -326,7 +329,7 @@ H5Pset_fapl_mpio(hid_t fapl_id, MPI_Comm comm, MPI_Info info)
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
/* Check arguments */
- if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+ if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a file access list")
if(MPI_COMM_NULL == comm)
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a valid communicator")
@@ -393,7 +396,7 @@ H5Pget_fapl_mpio(hid_t fapl_id, MPI_Comm *comm/*out*/, MPI_Info *info/*out*/)
FUNC_ENTER_API(H5Pget_fapl_mpio, FAIL)
H5TRACE3("e", "ixx", fapl_id, comm, info);
- if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+ if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a file access list")
if(H5FD_MPIO != H5P_get_driver(plist))
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver")
@@ -471,7 +474,7 @@ H5Pset_dxpl_mpio(hid_t dxpl_id, H5FD_mpio_xfer_t xfer_mode)
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
/* Check arguments */
- if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
if(H5FD_MPIO_INDEPENDENT != xfer_mode && H5FD_MPIO_COLLECTIVE != xfer_mode)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "incorrect xfer_mode")
@@ -517,7 +520,7 @@ H5Pget_dxpl_mpio(hid_t dxpl_id, H5FD_mpio_xfer_t *xfer_mode/*out*/)
FUNC_ENTER_API(H5Pget_dxpl_mpio, FAIL)
H5TRACE2("e", "ix", dxpl_id, xfer_mode);
- if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
if(H5FD_MPIO != H5P_get_driver(plist))
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver")
@@ -544,14 +547,14 @@ Description:
The library won't behave as it asks for only when we find
that the low-level MPI-IO package doesn't support this.
-Parameters:
+Parameters:
hid_t dxpl_id in: Data transfer property list identifier
H5FD_mpio_chunk_opt_t in: The optimization flag for linked chunk IO
or multi-chunk IO.
-
-Returns:
-Returns a non-negative value if successful. Otherwise returns a negative value.
+
+Returns:
+Returns a non-negative value if successful. Otherwise returns a negative value.
*
*-------------------------------------------------------------------------
*/
@@ -568,7 +571,7 @@ H5Pset_dxpl_mpio_collective_opt(hid_t dxpl_id, H5FD_mpio_collective_opt_t opt_mo
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
/* Check arguments */
- if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
/* Set the transfer mode */
@@ -596,14 +599,14 @@ Description:
The library won't behave as it asks for only when we find
that the low-level MPI-IO package doesn't support this.
-Parameters:
+Parameters:
hid_t dxpl_id in: Data transfer property list identifier
H5FD_mpio_chunk_opt_t in: The optimization flag for linked chunk IO
or multi-chunk IO.
-
-Returns:
-Returns a non-negative value if successful. Otherwise returns a negative value.
+
+Returns:
+Returns a non-negative value if successful. Otherwise returns a negative value.
*
*-------------------------------------------------------------------------
*/
@@ -620,7 +623,7 @@ H5Pset_dxpl_mpio_chunk_opt(hid_t dxpl_id, H5FD_mpio_chunk_opt_t opt_mode)
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
/* Check arguments */
- if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
/* Set the transfer mode */
@@ -643,15 +646,15 @@ Purpose:
To set a threshold for doing linked chunk IO
Description:
- If the number is greater than the threshold set by the user,
+ If the number is greater than the threshold set by the user,
the library will do linked chunk IO; otherwise, IO will be done for every chunk.
-Parameters:
+Parameters:
hid_t dxpl_id in: Data transfer property list identifier
- unsigned num_proc_per_chunk in: the threshold of the average number of chunks selected by each process
+ unsigned num_proc_per_chunk in: the threshold of the average number of chunks selected by each process
-Returns:
-Returns a non-negative value if successful. Otherwise returns a negative value.
+Returns:
+Returns a non-negative value if successful. Otherwise returns a negative value.
*
*-------------------------------------------------------------------------
*/
@@ -668,7 +671,7 @@ H5Pset_dxpl_mpio_chunk_opt_num(hid_t dxpl_id, unsigned num_chunk_per_proc)
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
/* Check arguments */
- if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
/* Set the transfer mode */
@@ -690,13 +693,13 @@ Purpose:
To set a threshold for doing collective IO for each chunk
Description:
The library will calculate the percentage of the number of process holding selections at each chunk. If that percentage of number of process in the individual chunk is greater than the threshold set by the user, the library will do collective chunk IO for this chunk; otherwise, independent IO will be done for this chunk.
-Parameters:
- hid_t dxpl_id
+Parameters:
+ hid_t dxpl_id
in: Data transfer property list identifier
- unsigned percent_num_proc_per_chunk
+ unsigned percent_num_proc_per_chunk
in: the threshold of the percentage of the number of process holding selections per chunk
-Returns:
-Returns a non-negative value if successful. Otherwise returns a negative value.
+Returns:
+Returns a non-negative value if successful. Otherwise returns a negative value.
*
@@ -715,7 +718,7 @@ H5Pset_dxpl_mpio_chunk_opt_ratio(hid_t dxpl_id, unsigned percent_num_proc_per_ch
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
/* Check arguments */
- if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
/* Set the transfer mode */
@@ -941,7 +944,7 @@ H5FD_mpio_open(const char *name, unsigned flags, hid_t fapl_id,
#ifndef H5_HAVE_MPI_GET_SIZE
struct stat stat_buf;
#endif
-
+
FUNC_ENTER_NOAPI(H5FD_mpio_open, NULL)
#ifdef H5FDmpio_DEBUG
@@ -952,7 +955,7 @@ H5FD_mpio_open(const char *name, unsigned flags, hid_t fapl_id,
#endif
/* Obtain a pointer to mpio-specific file access properties */
- if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+ if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
if(H5P_FILE_ACCESS_DEFAULT == fapl_id || H5FD_MPIO != H5P_get_driver(plist)) {
_fa.comm = MPI_COMM_SELF; /*default*/
@@ -1016,7 +1019,7 @@ H5FD_mpio_open(const char *name, unsigned flags, hid_t fapl_id,
/* Only processor p0 will get the filesize and broadcast it. */
if (mpi_rank == 0) {
/* Get current file size. If MPI_File_get_size is disabled in configuration
- * because it doesn't return correct value (SGI Altix Propack 4),
+ * because it doesn't return correct value (SGI Altix Propack 4),
* use stat to get the file size. */
#ifdef H5_HAVE_MPI_GET_SIZE
if (MPI_SUCCESS != (mpi_code=MPI_File_get_size(fh, &size)))
@@ -1514,7 +1517,7 @@ H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t add
if(MPI_SUCCESS != (mpi_code = MPI_File_read_at(file->f, mpi_off, buf, size_i, buf_type, &mpi_stat)))
HMPI_GOTO_ERROR(FAIL, "MPI_File_read_at failed", mpi_code)
} /* end else */
-
+
/*
* Reset the file view when we used MPI derived types
*/
@@ -1859,68 +1862,106 @@ done:
*
* Failure: Negative
*
- * Programmer: Unknown
+ * Programmer: Robb Matzke
* January 30, 1998
*
- * Modifications:
- * Robb Matzke, 1998-02-18
- * Added the ACCESS_PARMS argument.
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_mpio_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned closing)
+{
+ H5FD_mpio_t *file = (H5FD_mpio_t*)_file;
+ int mpi_code; /* mpi return code */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5FD_mpio_flush, FAIL)
+
+#ifdef H5FDmpio_DEBUG
+ if(H5FD_mpio_Debug[(int)'t'])
+ HDfprintf(stdout, "Entering %s\n", FUNC);
+#endif
+ HDassert(file);
+ HDassert(H5FD_MPIO == file->pub.driver_id);
+
+ /* Only sync the file if we are not going to immediately close it */
+ if(!closing) {
+ if(MPI_SUCCESS != (mpi_code = MPI_File_sync(file->f)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_File_sync failed", mpi_code)
+ } /* end if */
+
+done:
+#ifdef H5FDmpio_DEBUG
+ if(H5FD_mpio_Debug[(int)'t'])
+ HDfprintf(stdout, "Leaving %s\n", FUNC);
+#endif
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_mpio_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_mpio_truncate
*
- * Robb Matzke, 1999-08-06
- * Modified to work with the virtual file layer.
+ * Purpose: Make certain the file's size matches it's allocated size
*
- * Robb Matzke, 2000-12-29
- * Make sure file size is at least as large as the last
- * allocated byte.
+ * Return: Success: Non-negative
+ * Failure: Negative
*
- * Quincey Koziol, 2002-06-??
- * Changed file extension method to use MPI_File_set_size instead
- * read->write method.
+ * Programmer: Quincey Koziol
+ * January 31, 2008
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5FD_mpio_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned closing)
+H5FD_mpio_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing)
{
H5FD_mpio_t *file = (H5FD_mpio_t*)_file;
- int mpi_code; /* mpi return code */
- MPI_Offset mpi_off;
- herr_t ret_value=SUCCEED;
+ herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI(H5FD_mpio_flush, FAIL)
+ FUNC_ENTER_NOAPI(H5FD_mpio_truncate, FAIL)
#ifdef H5FDmpio_DEBUG
- if (H5FD_mpio_Debug[(int)'t'])
- fprintf(stdout, "Entering H5FD_mpio_flush\n" );
+ if(H5FD_mpio_Debug[(int)'t'])
+ HDfprintf(stdout, "Entering %s\n", FUNC);
#endif
- assert(file);
- assert(H5FD_MPIO==file->pub.driver_id);
+ HDassert(file);
+ HDassert(H5FD_MPIO == file->pub.driver_id);
/* Extend the file to make sure it's large enough, then sync.
* Unfortunately, keeping track of EOF is an expensive operation, so
* we can't just check whether EOF<EOA like with other drivers.
* Therefore we'll just read the byte at EOA-1 and then write it back. */
- if(file->eoa>file->last_eoa) {
+ if(file->eoa > file->last_eoa) {
+ int mpi_code; /* mpi return code */
+ MPI_Offset mpi_off;
+
#ifdef H5_MPI_FILE_SET_SIZE_BIG
- if (H5FD_mpi_haddr_to_MPIOff(file->eoa, &mpi_off)<0)
+ if(H5FD_mpi_haddr_to_MPIOff(file->eoa, &mpi_off) < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "cannot convert from haddr_t to MPI_Offset")
/* Extend the file's size */
- if (MPI_SUCCESS != (mpi_code=MPI_File_set_size(file->f, mpi_off)))
+ if(MPI_SUCCESS != (mpi_code = MPI_File_set_size(file->f, mpi_off)))
HMPI_GOTO_ERROR(FAIL, "MPI_File_set_size failed", mpi_code)
#else /* H5_MPI_FILE_SET_SIZE_BIG */
- if (0==file->mpi_rank) {
- uint8_t byte=0;
+ /* Wait until all processes are here before reading/writing the byte at
+ * process 0's end of address space. The window for corruption is
+ * probably tiny, but does exist...
+ */
+ if(MPI_SUCCESS != (mpi_code = MPI_Barrier(file->comm)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code)
+
+ if(0 == file->mpi_rank) {
+ uint8_t byte = 0;
MPI_Status mpi_stat;
/* Portably initialize MPI status variable */
- HDmemset(&mpi_stat,0,sizeof(MPI_Status));
+ HDmemset(&mpi_stat, 0, sizeof(MPI_Status));
- if (H5FD_mpi_haddr_to_MPIOff(file->eoa-1, &mpi_off)<0)
+ if(H5FD_mpi_haddr_to_MPIOff(file->eoa-1, &mpi_off) < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "cannot convert from haddr_t to MPI_Offset")
- if (MPI_SUCCESS != (mpi_code=MPI_File_read_at(file->f, mpi_off, &byte, 1, MPI_BYTE, &mpi_stat)))
+ if(MPI_SUCCESS != (mpi_code = MPI_File_read_at(file->f, mpi_off, &byte, 1, MPI_BYTE, &mpi_stat)))
HMPI_GOTO_ERROR(FAIL, "MPI_File_read_at failed", mpi_code)
- if (MPI_SUCCESS != (mpi_code=MPI_File_write_at(file->f, mpi_off, &byte, 1, MPI_BYTE, &mpi_stat)))
+ if(MPI_SUCCESS != (mpi_code = MPI_File_write_at(file->f, mpi_off, &byte, 1, MPI_BYTE, &mpi_stat)))
HMPI_GOTO_ERROR(FAIL, "MPI_File_write_at failed", mpi_code)
} /* end if */
#endif /* H5_MPI_FILE_SET_SIZE_BIG */
@@ -1931,27 +1972,21 @@ H5FD_mpio_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned closing)
* it the shorter length, potentially truncating the file and dropping
* the new data written)
*/
- if (MPI_SUCCESS!= (mpi_code=MPI_Barrier(file->comm)))
+ if(MPI_SUCCESS != (mpi_code = MPI_Barrier(file->comm)))
HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code)
/* Update the 'last' eoa value */
- file->last_eoa=file->eoa;
- } /* end if */
-
- /* Only sync the file if we are not going to immediately close it */
- if(!closing) {
- if (MPI_SUCCESS != (mpi_code=MPI_File_sync(file->f)))
- HMPI_GOTO_ERROR(FAIL, "MPI_File_sync failed", mpi_code)
+ file->last_eoa = file->eoa;
} /* end if */
done:
#ifdef H5FDmpio_DEBUG
- if (H5FD_mpio_Debug[(int)'t'])
- fprintf(stdout, "Leaving H5FD_mpio_flush\n" );
+ if(H5FD_mpio_Debug[(int)'t'])
+ HDfprintf(stdout, "Leaving %s\n", FUNC);
#endif
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_mpio_truncate() */
/*-------------------------------------------------------------------------
diff --git a/src/H5FDmpio.h b/src/H5FDmpio.h
index 8fa1be5..41baf8d 100644
--- a/src/H5FDmpio.h
+++ b/src/H5FDmpio.h
@@ -31,7 +31,7 @@
/* Macros */
#define IS_H5FD_MPIO(f) /* (H5F_t *f) */ \
- (H5FD_MPIO==H5F_get_driver_id(f))
+ (H5FD_MPIO==H5F_DRIVER_ID(f))
#ifdef H5_HAVE_PARALLEL
/*Turn on H5FDmpio_debug if H5F_DEBUG is on */
diff --git a/src/H5FDmpiposix.c b/src/H5FDmpiposix.c
index 6c30065..ff5b118 100644
--- a/src/H5FDmpiposix.c
+++ b/src/H5FDmpiposix.c
@@ -190,7 +190,7 @@ static herr_t H5FD_mpiposix_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id,
size_t size, void *buf);
static herr_t H5FD_mpiposix_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr,
size_t size, const void *buf);
-static herr_t H5FD_mpiposix_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing);
+static herr_t H5FD_mpiposix_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
static int H5FD_mpiposix_mpi_rank(const H5FD_t *_file);
static int H5FD_mpiposix_mpi_size(const H5FD_t *_file);
static MPI_Comm H5FD_mpiposix_communicator(const H5FD_t *_file);
@@ -221,6 +221,7 @@ static const H5FD_class_mpi_t H5FD_mpiposix_g = {
H5FD_mpiposix_close, /*close */
H5FD_mpiposix_cmp, /*cmp */
H5FD_mpiposix_query, /*query */
+ NULL, /*get_type_map */
NULL, /*alloc */
NULL, /*free */
H5FD_mpiposix_get_eoa, /*get_eoa */
@@ -229,7 +230,8 @@ static const H5FD_class_mpi_t H5FD_mpiposix_g = {
H5FD_mpiposix_get_handle, /*get_handle */
H5FD_mpiposix_read, /*read */
H5FD_mpiposix_write, /*write */
- H5FD_mpiposix_flush, /*flush */
+ NULL, /*flush */
+ H5FD_mpiposix_truncate, /*truncate */
NULL, /*lock */
NULL, /*unlock */
H5FD_FLMAP_SINGLE /*fl_map */
@@ -287,7 +289,7 @@ H5FD_mpiposix_init(void)
FUNC_ENTER_NOAPI(H5FD_mpiposix_init, FAIL)
if (H5I_VFL!=H5Iget_type(H5FD_MPIPOSIX_g))
- H5FD_MPIPOSIX_g = H5FD_register((const H5FD_class_t *)&H5FD_mpiposix_g,sizeof(H5FD_class_mpi_t));
+ H5FD_MPIPOSIX_g = H5FD_register((const H5FD_class_t *)&H5FD_mpiposix_g,sizeof(H5FD_class_mpi_t),FALSE);
/* Set return value */
ret_value=H5FD_MPIPOSIX_g;
@@ -1213,7 +1215,9 @@ H5FD_mpiposix_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr,
size_t size, const void *buf)
{
H5FD_mpiposix_t *file = (H5FD_mpiposix_t*)_file;
+#if 0 /* JRM */
int mpi_code; /* MPI return code */
+#endif /* JRM */
ssize_t nbytes; /* Number of bytes written each I/O call */
H5P_genplist_t *plist; /* Property list pointer */
herr_t ret_value=SUCCEED; /* Return value */
@@ -1365,9 +1369,10 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FD_mpiposix_flush
+ * Function: H5FD_mpiposix_truncate
*
- * Purpose: Makes sure that all data is on disk. This is collective.
+ * Purpose: Makes sure that the true file size is the same (or larger)
+ * than the end-of-address.
*
* Return: Success: Non-negative
* Failure: Negative
@@ -1375,12 +1380,10 @@ done:
* Programmer: Quincey Koziol
* Thursday, July 11, 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5FD_mpiposix_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing)
+H5FD_mpiposix_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing)
{
H5FD_mpiposix_t *file = (H5FD_mpiposix_t*)_file;
#ifdef _WIN32
@@ -1388,15 +1391,15 @@ H5FD_mpiposix_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing
LARGE_INTEGER li; /* 64-bit integer for SetFilePointer() call */
#endif /* _WIN32 */
int mpi_code; /* MPI return code */
- herr_t ret_value=SUCCEED;
+ herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI(H5FD_mpiposix_flush, FAIL)
+ FUNC_ENTER_NOAPI(H5FD_mpiposix_truncate, FAIL)
- assert(file);
- assert(H5FD_MPIPOSIX==file->pub.driver_id);
+ HDassert(file);
+ HDassert(H5FD_MPIPOSIX == file->pub.driver_id);
/* Extend the file to make sure it's large enough */
- if(file->eoa>file->last_eoa) {
+ if(file->eoa > file->last_eoa) {
/* Use the round-robin process to truncate (extend) the file */
if(file->mpi_rank == H5_PAR_META_WRITE) {
#ifdef _WIN32
@@ -1406,8 +1409,8 @@ H5FD_mpiposix_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing
/* Translate 64-bit integers into form Windows wants */
/* [This algorithm is from the Windows documentation for SetFilePointer()] */
li.QuadPart = file->eoa;
- SetFilePointer((HANDLE)filehandle,li.LowPart,&li.HighPart,FILE_BEGIN);
- if(SetEndOfFile((HANDLE)filehandle)==0)
+ SetFilePointer((HANDLE)filehandle, li.LowPart, &li.HighPart, FILE_BEGIN);
+ if(SetEndOfFile((HANDLE)filehandle) == 0)
HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
#else /* _WIN32 */
if(-1==file_truncate(file->fd, (file_offset_t)file->eoa))
@@ -1421,11 +1424,11 @@ H5FD_mpiposix_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing
* it the shorter length, potentially truncating the file and dropping
* the new data written)
*/
- if (MPI_SUCCESS!= (mpi_code=MPI_Barrier(file->comm)))
+ if(MPI_SUCCESS != (mpi_code = MPI_Barrier(file->comm)))
HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code)
/* Update the 'last' eoa and eof values */
- file->last_eoa=file->eoa;
+ file->last_eoa = file->eoa;
file->eof = file->eoa;
/* Reset last file I/O information */
@@ -1435,7 +1438,7 @@ H5FD_mpiposix_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_mpiposix_flush() */
+} /* end H5FD_mpiposix_truncate() */
/*-------------------------------------------------------------------------
diff --git a/src/H5FDmpiposix.h b/src/H5FDmpiposix.h
index 70e632a..832839e 100644
--- a/src/H5FDmpiposix.h
+++ b/src/H5FDmpiposix.h
@@ -32,7 +32,7 @@
/* Macros */
#define IS_H5FD_MPIPOSIX(f) /* (H5F_t *f) */ \
- (H5FD_MPIPOSIX==H5F_get_driver_id(f))
+ (H5FD_MPIPOSIX==H5F_DRIVER_ID(f))
#ifdef H5_HAVE_PARALLEL
@@ -54,4 +54,3 @@ H5_DLL herr_t H5Pget_fapl_mpiposix(hid_t fapl_id, MPI_Comm *comm/*out*/, hbool_t
#endif /* __H5FDmpiposix_H */
-
diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c
index 8c25a62..328b530 100644
--- a/src/H5FDmulti.c
+++ b/src/H5FDmulti.c
@@ -66,16 +66,6 @@
assert(LOOPVAR>0 && LOOPVAR<H5FD_MEM_NTYPES); \
if (_seen[LOOPVAR]++) continue;
-#ifdef LATER
-#define MAPPED_MEMBERS(MAP,LOOPVAR) { \
- H5FD_mem_t _unmapped, LOOPVAR; \
- \
- for (_unmapped=H5FD_MEM_SUPER; _unmapped<H5FD_MEM_NTYPES; _unmapped=_unmapped+1) { \
- LOOPVAR = MAP[_unmapped]; \
- if (H5FD_MEM_DEFAULT==LOOPVAR) LOOPVAR=_unmapped; \
- assert(LOOPVAR>0 && LOOPVAR<H5FD_MEM_NTYPES);
-#endif /* LATER */
-
#define ALL_MEMBERS(LOOPVAR) { \
H5FD_mem_t LOOPVAR; \
for (LOOPVAR=H5FD_MEM_DEFAULT; LOOPVAR<H5FD_MEM_NTYPES; LOOPVAR=(H5FD_mem_t)(LOOPVAR+1)) {
@@ -140,6 +130,7 @@ static H5FD_t *H5FD_multi_open(const char *name, unsigned flags,
static herr_t H5FD_multi_close(H5FD_t *_file);
static int H5FD_multi_cmp(const H5FD_t *_f1, const H5FD_t *_f2);
static herr_t H5FD_multi_query(const H5FD_t *_f1, unsigned long *flags);
+static herr_t H5FD_multi_get_type_map(const H5FD_t *file, H5FD_mem_t *type_map);
static haddr_t H5FD_multi_get_eoa(const H5FD_t *_file, H5FD_mem_t type);
static herr_t H5FD_multi_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t eoa);
static haddr_t H5FD_multi_get_eof(const H5FD_t *_file);
@@ -152,6 +143,7 @@ static herr_t H5FD_multi_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, had
static herr_t H5FD_multi_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr,
size_t size, const void *_buf);
static herr_t H5FD_multi_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing);
+static herr_t H5FD_multi_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
/* The class struct */
static const H5FD_class_t H5FD_multi_g = {
@@ -172,6 +164,7 @@ static const H5FD_class_t H5FD_multi_g = {
H5FD_multi_close, /*close */
H5FD_multi_cmp, /*cmp */
H5FD_multi_query, /*query */
+ H5FD_multi_get_type_map, /*get_type_map */
H5FD_multi_alloc, /*alloc */
H5FD_multi_free, /*free */
H5FD_multi_get_eoa, /*get_eoa */
@@ -181,6 +174,7 @@ static const H5FD_class_t H5FD_multi_g = {
H5FD_multi_read, /*read */
H5FD_multi_write, /*write */
H5FD_multi_flush, /*flush */
+ H5FD_multi_truncate, /*truncate */
NULL, /*lock */
NULL, /*unlock */
H5FD_FLMAP_DEFAULT /*fl_map */
@@ -207,9 +201,13 @@ static char *
my_strdup(const char *s)
{
char *x;
- if (!s) return NULL;
- if (NULL==(x=malloc(strlen(s)+1))) return NULL;
+
+ if(!s)
+ return NULL;
+ if(NULL == (x = (char *)malloc(strlen(s) + 1)))
+ return NULL;
strcpy(x, s);
+
return x;
}
@@ -474,7 +472,7 @@ H5Pset_fapl_multi(hid_t fapl_id, const H5FD_mem_t *memb_map,
}
if (!memb_addr) {
for (mt=H5FD_MEM_DEFAULT; mt<H5FD_MEM_NTYPES; mt=(H5FD_mem_t)(mt+1))
- _memb_addr[mt] = (mt?mt-1:0) * HADDR_MAX/H5FD_MEM_NTYPES;
+ _memb_addr[mt] = (hsize_t)(mt ? (mt - 1) : 0) * HADDR_MAX / H5FD_MEM_NTYPES;
memb_addr = _memb_addr;
}
@@ -554,9 +552,9 @@ H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map/*out*/,
if(H5I_GENPROP_LST != H5Iget_type(fapl_id) ||
TRUE != H5Pisa_class(fapl_id, H5P_FILE_ACCESS))
H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADTYPE, "not an access list", -1)
- if (H5FD_MULTI!=H5Pget_driver(fapl_id))
+ if(H5FD_MULTI != H5Pget_driver(fapl_id))
H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADVALUE, "incorrect VFL driver", -1)
- if (NULL==(fa=H5Pget_driver_info(fapl_id)))
+ if(NULL == (fa= (H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id)))
H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADVALUE, "bad VFL driver info", -1)
if (memb_map)
@@ -572,7 +570,7 @@ H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map/*out*/,
if (memb_name) {
for (mt=H5FD_MEM_DEFAULT; mt<H5FD_MEM_NTYPES; mt=(H5FD_mem_t)(mt+1)) {
if (fa->memb_name[mt]) {
- memb_name[mt] = malloc(strlen(fa->memb_name[mt])+1);
+ memb_name[mt] = (char *)malloc(strlen(fa->memb_name[mt])+1);
strcpy(memb_name[mt], fa->memb_name[mt]);
} else
memb_name[mt] = NULL;
@@ -674,7 +672,7 @@ H5Pget_dxpl_multi(hid_t dxpl_id, hid_t *memb_dxpl/*out*/)
H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADTYPE, "not a file access property list", -1)
if (H5FD_MULTI!=H5Pget_driver(dxpl_id))
H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADVALUE, "incorrect VFL driver", -1)
- if (NULL==(dx=H5Pget_driver_info(dxpl_id)))
+ if(NULL == (dx = (H5FD_multi_dxpl_t *)H5Pget_driver_info(dxpl_id)))
H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADVALUE, "bad VFL driver info", -1)
if (memb_dxpl) {
@@ -711,7 +709,7 @@ static hsize_t
H5FD_multi_sb_size(H5FD_t *_file)
{
H5FD_multi_t *file = (H5FD_multi_t*)_file;
- int nseen = 0;
+ unsigned nseen = 0;
hsize_t nbytes = 8; /*size of header*/
/* Clear the error stack */
@@ -797,9 +795,9 @@ H5FD_multi_sb_encode(H5FD_t *_file, char *name/*out*/,
p = buf+8;
assert(sizeof(haddr_t)<=8);
UNIQUE_MEMBERS(file->fa.memb_map, mt) {
- memb_eoa = H5FDget_eoa(file->memb[mt], mt);
memcpy(p, &(file->fa.memb_addr[mt]), sizeof(haddr_t));
p += sizeof(haddr_t);
+ memb_eoa = H5FDget_eoa(file->memb[mt], mt);
memcpy(p, &memb_eoa, sizeof(haddr_t));
p += sizeof(haddr_t);
nseen++;
@@ -818,7 +816,7 @@ H5FD_multi_sb_encode(H5FD_t *_file, char *name/*out*/,
} END_MEMBERS;
return 0;
-}
+} /* end H5FD_multi_sb_encode() */
/*-------------------------------------------------------------------------
@@ -839,8 +837,6 @@ H5FD_multi_sb_encode(H5FD_t *_file, char *name/*out*/,
* Programmer: Robb Matzke
* Monday, August 16, 1999
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -976,7 +972,7 @@ H5FD_multi_sb_decode(H5FD_t *_file, const char *name, const unsigned char *buf)
} END_MEMBERS;
return 0;
-}
+} /* end H5FD_multi_sb_decode() */
/*-------------------------------------------------------------------------
@@ -1030,7 +1026,7 @@ static void *
H5FD_multi_fapl_copy(const void *_old_fa)
{
const H5FD_multi_fapl_t *old_fa = (const H5FD_multi_fapl_t*)_old_fa;
- H5FD_multi_fapl_t *new_fa = malloc(sizeof(H5FD_multi_fapl_t));
+ H5FD_multi_fapl_t *new_fa = (H5FD_multi_fapl_t *)malloc(sizeof(H5FD_multi_fapl_t));
int nerrors = 0;
static const char *func="H5FD_multi_fapl_copy"; /* Function Name for error reporting */
@@ -1046,7 +1042,7 @@ H5FD_multi_fapl_copy(const void *_old_fa)
if (new_fa->memb_fapl[mt]<0) nerrors++;
}
if (old_fa->memb_name[mt]) {
- new_fa->memb_name[mt] = malloc(strlen(old_fa->memb_name[mt])+1);
+ new_fa->memb_name[mt] = (char *)malloc(strlen(old_fa->memb_name[mt])+1);
assert(new_fa->memb_name[mt]);
strcpy(new_fa->memb_name[mt], old_fa->memb_name[mt]);
}
@@ -1122,7 +1118,7 @@ static void *
H5FD_multi_dxpl_copy(const void *_old_dx)
{
const H5FD_multi_dxpl_t *old_dx = (const H5FD_multi_dxpl_t*)_old_dx;
- H5FD_multi_dxpl_t *new_dx = malloc(sizeof(H5FD_multi_dxpl_t));
+ H5FD_multi_dxpl_t *new_dx = (H5FD_multi_dxpl_t *)malloc(sizeof(H5FD_multi_dxpl_t));
int nerrors = 0;
static const char *func="H5FD_multi_dxpl_copy"; /* Function Name for error reporting */
@@ -1227,14 +1223,14 @@ H5FD_multi_open(const char *name, unsigned flags, hid_t fapl_id,
* Initialize the file from the file access properties, using default
* values if necessary.
*/
- if (NULL==(file=calloc((size_t)1, sizeof(H5FD_multi_t))))
+ if(NULL == (file = (H5FD_multi_t *)calloc((size_t)1, sizeof(H5FD_multi_t))))
H5Epush_ret(func, H5E_ERR_CLS, H5E_RESOURCE, H5E_NOSPACE, "memory allocation failed", NULL)
- if (H5P_FILE_ACCESS_DEFAULT==fapl_id || H5FD_MULTI!=H5Pget_driver(fapl_id)) {
+ if(H5P_FILE_ACCESS_DEFAULT==fapl_id || H5FD_MULTI!=H5Pget_driver(fapl_id)) {
close_fapl = fapl_id = H5Pcreate(H5P_FILE_ACCESS);
if(H5Pset_fapl_multi(fapl_id, NULL, NULL, NULL, NULL, TRUE)<0)
H5Epush_goto(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTSET, "can't set property value", error)
}
- fa = H5Pget_driver_info(fapl_id);
+ fa = (H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id);
assert(fa);
ALL_MEMBERS(mt) {
file->fa.memb_map[mt] = fa->memb_map[mt];
@@ -1418,13 +1414,38 @@ H5FD_multi_query(const H5FD_t *_f, unsigned long *flags /* out */)
/* Set the VFL feature flags that this driver supports */
if(flags) {
- *flags=0;
- *flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
- *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
- }
+ *flags = 0;
+ *flags |= H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
+ *flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
+ } /* end if */
return(0);
-}
+} /* end H5FD_multi_query() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_get_type_map
+ *
+ * Purpose: Retrieve the memory type mapping for this file
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, October 9, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_multi_get_type_map(const H5FD_t *_file, H5FD_mem_t *type_map)
+{
+ const H5FD_multi_t *file = (const H5FD_multi_t*)_file;
+
+ /* Copy file's free space type mapping */
+ memcpy(type_map, file->fa.memb_map, sizeof(file->fa.memb_map));
+
+ return(0);
+} /* end H5FD_multi_get_type_map() */
/*-------------------------------------------------------------------------
@@ -1457,7 +1478,7 @@ H5FD_multi_get_eoa(const H5FD_t *_file, H5FD_mem_t type)
const H5FD_multi_t *file = (const H5FD_multi_t*)_file;
haddr_t eoa = 0;
haddr_t memb_eoa = 0;
- static const char *func="H5FD_multi_eof"; /* Function Name for error reporting */
+ static const char *func="H5FD_multi_get_eoa"; /* Function Name for error reporting */
/* Clear the error stack */
H5Eclear2(H5E_DEFAULT);
@@ -1466,8 +1487,8 @@ H5FD_multi_get_eoa(const H5FD_t *_file, H5FD_mem_t type)
* taken out because it makes little sense for MULTI files.
* However, the library sometimes queries it through H5F_get_eoa.
* Here the code finds the biggest EOA for individual file if
- * the query is from H5F_get_eoa (TYPE is H5FD_MEM_DEFAULT).
- */
+ * the query is for TYPE == H5FD_MEM_DEFAULT.
+ */
if(H5FD_MEM_DEFAULT == type) {
UNIQUE_MEMBERS(file->fa.memb_map, mt) {
if (file->memb[mt]) {
@@ -1494,7 +1515,7 @@ H5FD_multi_get_eoa(const H5FD_t *_file, H5FD_mem_t type)
} END_MEMBERS;
} else {
H5FD_mem_t mmt = file->fa.memb_map[type];
- if (H5FD_MEM_DEFAULT==mmt) mmt = type;
+ if (H5FD_MEM_DEFAULT==mmt) mmt = type;
if (file->memb[mmt]) {
H5E_BEGIN_TRY {
@@ -1503,6 +1524,7 @@ H5FD_multi_get_eoa(const H5FD_t *_file, H5FD_mem_t type)
if (HADDR_UNDEF==eoa)
H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "member file has unknown eoa", HADDR_UNDEF)
+ if (eoa>0) eoa += file->fa.memb_addr[mmt];
} else if (file->fa.relax) {
/*
* The member is not open yet (maybe it doesn't exist). Make the
@@ -1516,7 +1538,7 @@ H5FD_multi_get_eoa(const H5FD_t *_file, H5FD_mem_t type)
}
return eoa;
-}
+} /* end H5FD_multi_get_eoa() */
/*-------------------------------------------------------------------------
@@ -1547,20 +1569,28 @@ static herr_t
H5FD_multi_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t eoa)
{
H5FD_multi_t *file = (H5FD_multi_t*)_file;
+ H5FD_mem_t mmt;
herr_t status;
static const char *func="H5FD_multi_set_eoa"; /* Function Name for error reporting */
/* Clear the error stack */
H5Eclear2(H5E_DEFAULT);
+ mmt = file->fa.memb_map[type];
+ if(H5FD_MEM_DEFAULT == mmt)
+ mmt = type;
+
+ assert(eoa >= file->fa.memb_addr[mmt]);
+ assert(eoa < file->memb_next[mmt]);
+
H5E_BEGIN_TRY {
- status = H5FDset_eoa(file->memb[type], type, eoa);
+ status = H5FDset_eoa(file->memb[mmt], mmt, (eoa - file->fa.memb_addr[mmt]));
} H5E_END_TRY;
if (status<0)
H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_BADVALUE, "member H5FDset_eoa failed", -1)
return 0;
-}
+} /* end H5FD_multi_set_eoa() */
/*-------------------------------------------------------------------------
@@ -1592,7 +1622,7 @@ H5FD_multi_get_eof(const H5FD_t *_file)
const H5FD_multi_t *file = (const H5FD_multi_t*)_file;
haddr_t eof=0, tmp_eof;
haddr_t eoa=0, tmp_eoa;
- static const char *func="H5FD_multi_eof"; /* Function Name for error reporting */
+ static const char *func="H5FD_multi_get_eof"; /* Function Name for error reporting */
/* Clear the error stack */
H5Eclear2(H5E_DEFAULT);
@@ -1615,6 +1645,7 @@ H5FD_multi_get_eof(const H5FD_t *_file)
if (HADDR_UNDEF==tmp_eoa)
H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "member file has unknown eoa", HADDR_UNDEF)
+ if (tmp_eoa>0) tmp_eoa += file->fa.memb_addr[mt];
} else if (file->fa.relax) {
/*
* The member is not open yet (maybe it doesn't exist). Make the
@@ -1697,7 +1728,7 @@ H5FD_multi_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
mmt = file->fa.memb_map[type];
if (H5FD_MEM_DEFAULT==mmt) mmt = type;
- if (HADDR_UNDEF==(addr=H5FDalloc(file->memb[mmt], type, dxpl_id, size)))
+ if (HADDR_UNDEF==(addr=H5FDalloc(file->memb[mmt], mmt, dxpl_id, size)))
H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "member file can't alloc", HADDR_UNDEF)
addr += file->fa.memb_addr[mmt];
@@ -1749,7 +1780,7 @@ H5FD_multi_free(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsi
assert(addr>=file->fa.memb_addr[mmt]);
assert(addr+size<=file->memb_next[mmt]);
- return H5FDfree(file->memb[mmt], type, dxpl_id, addr-file->fa.memb_addr[mmt], size);
+ return H5FDfree(file->memb[mmt], mmt, dxpl_id, addr-file->fa.memb_addr[mmt], size);
}
@@ -1785,15 +1816,15 @@ H5FD_multi_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, siz
H5Eclear2(H5E_DEFAULT);
/* Get the data transfer properties */
- if (H5P_FILE_ACCESS_DEFAULT!=dxpl_id && H5FD_MULTI==H5Pget_driver(dxpl_id)) {
- dx = H5Pget_driver_info(dxpl_id);
- }
+ if(H5P_FILE_ACCESS_DEFAULT != dxpl_id && H5FD_MULTI == H5Pget_driver(dxpl_id))
+ dx = (H5FD_multi_dxpl_t *)H5Pget_driver_info(dxpl_id);
/* Find the file to which this address belongs */
- for (mt=H5FD_MEM_SUPER; mt<H5FD_MEM_NTYPES; mt=(H5FD_mem_t)(mt+1)) {
+ for(mt = H5FD_MEM_SUPER; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
mmt = file->fa.memb_map[mt];
- if (H5FD_MEM_DEFAULT==mmt) mmt = mt;
- assert(mmt>0 && mmt<H5FD_MEM_NTYPES);
+ if(H5FD_MEM_DEFAULT == mmt)
+ mmt = mt;
+ assert(mmt > 0 && mmt < H5FD_MEM_NTYPES);
if (file->fa.memb_addr[mmt]>addr) continue;
if (file->fa.memb_addr[mmt]>=start_addr) {
@@ -1840,14 +1871,14 @@ H5FD_multi_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, si
H5Eclear2(H5E_DEFAULT);
/* Get the data transfer properties */
- if (H5P_FILE_ACCESS_DEFAULT!=dxpl_id && H5FD_MULTI==H5Pget_driver(dxpl_id)) {
- dx = H5Pget_driver_info(dxpl_id);
- }
+ if(H5P_FILE_ACCESS_DEFAULT != dxpl_id && H5FD_MULTI == H5Pget_driver(dxpl_id))
+ dx = (H5FD_multi_dxpl_t *)H5Pget_driver_info(dxpl_id);
/* Find the file to which this address belongs */
- for (mt=H5FD_MEM_SUPER; mt<H5FD_MEM_NTYPES; mt=(H5FD_mem_t)(mt+1)) {
+ for(mt = H5FD_MEM_SUPER; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
mmt = file->fa.memb_map[mt];
- if (H5FD_MEM_DEFAULT==mmt) mmt = mt;
+ if(H5FD_MEM_DEFAULT == mmt)
+ mmt = mt;
assert(mmt>0 && mmt<H5FD_MEM_NTYPES);
if (file->fa.memb_addr[mmt]>addr) continue;
@@ -1912,9 +1943,9 @@ H5FD_multi_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing)
if (HADDR_UNDEF!=file->memb_addr[mt]) {
haddr_t eoa = H5FDget_eoa(file->memb[mt], mt);
fprintf(stderr, " %6d %20llu %20llu %20llu %s\n",
- (int)mt, (unsigned long_long)(file->memb_addr[mt]),
- (unsigned long_long)eoa,
- (unsigned long_long)(file->memb_next[mt]),
+ (int)mt, (unsigned long long)(file->memb_addr[mt]),
+ (unsigned long long)eoa,
+ (unsigned long long)(file->memb_next[mt]),
file->memb_name[mt]);
}
}
@@ -1939,6 +1970,46 @@ H5FD_multi_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing)
/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_truncate
+ *
+ * Purpose: Truncates all multi members.
+ *
+ * Return: Success: 0
+ * Failure: -1, as many files truncated as possible.
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, January 31, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_multi_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing)
+{
+ H5FD_multi_t *file = (H5FD_multi_t*)_file;
+ H5FD_mem_t mt;
+ int nerrors=0;
+ static const char *func="H5FD_multi_truncate"; /* Function Name for error reporting */
+
+ /* Clear the error stack */
+ H5Eclear2(H5E_DEFAULT);
+
+ /* Truncate each file */
+ for(mt = H5FD_MEM_SUPER; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
+ if(file->memb[mt]) {
+ H5E_BEGIN_TRY {
+ if(H5FDtruncate(file->memb[mt], dxpl_id, closing) < 0)
+ nerrors++;
+ } H5E_END_TRY;
+ }
+ }
+ if(nerrors)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "error truncating member files", -1)
+
+ return 0;
+} /* end H5FD_multi_truncate() */
+
+
+/*-------------------------------------------------------------------------
* Function: compute_next
*
* Purpose: Compute the memb_next[] values of the file based on the
diff --git a/src/H5FDpkg.h b/src/H5FDpkg.h
index 700ec1d..7c0988e 100644
--- a/src/H5FDpkg.h
+++ b/src/H5FDpkg.h
@@ -48,15 +48,15 @@
/* Package Private Variables */
/*****************************/
-/* Declare a PQ free list to manage the metadata accumulator buffer */
-H5FL_BLK_EXTERN(meta_accum);
-
/******************************/
/* Package Private Prototypes */
/******************************/
H5_DLL herr_t H5FD_init(void);
-H5_DLL herr_t H5FD_free_freelist(H5FD_t *file);
+H5_DLL haddr_t H5FD_alloc_real(H5FD_t *file, hid_t dxpl_id, H5FD_mem_t type,
+ hsize_t size, haddr_t *align_addr, hsize_t *align_size);
+H5_DLL herr_t H5FD_free_real(H5FD_t *file, hid_t dxpl_id, H5FD_mem_t type,
+ haddr_t addr, hsize_t size);
/* Testing routines */
diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h
index 4c8c28e..cb40e5c 100644
--- a/src/H5FDprivate.h
+++ b/src/H5FDprivate.h
@@ -35,6 +35,7 @@
/* Forward declarations for prototype arguments */
struct H5P_genplist_t;
+struct H5F_t;
/* Prototypes */
H5_DLL int H5FD_term_interface(void);
@@ -49,33 +50,34 @@ H5_DLL herr_t H5FD_fapl_close(hid_t driver_id, void *fapl);
H5_DLL herr_t H5FD_dxpl_open(struct H5P_genplist_t *plist, hid_t driver_id, const void *driver_info);
H5_DLL herr_t H5FD_dxpl_copy(hid_t driver_id, const void *dxpl, void **copied_dxpl);
H5_DLL herr_t H5FD_dxpl_close(hid_t driver_id, void *dxpl);
-H5_DLL hid_t H5FD_register(const void *cls, size_t size);
+H5_DLL hid_t H5FD_register(const void *cls, size_t size, hbool_t app_ref);
H5_DLL H5FD_t *H5FD_open(const char *name, unsigned flags, hid_t fapl_id,
haddr_t maxaddr);
H5_DLL herr_t H5FD_close(H5FD_t *file);
H5_DLL int H5FD_cmp(const H5FD_t *f1, const H5FD_t *f2);
H5_DLL int H5FD_query(const H5FD_t *f, unsigned long *flags/*out*/);
-H5_DLL haddr_t H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
-H5_DLL herr_t H5FD_free(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size);
-H5_DLL haddr_t H5FD_realloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr,
- hsize_t old_size, hsize_t new_size);
+H5_DLL haddr_t H5FD_alloc(H5FD_t *file, hid_t dxpl_id, H5FD_mem_t type, struct H5F_t *f,
+ hsize_t size, haddr_t *align_addr, hsize_t *align_size);
+H5_DLL herr_t H5FD_free(H5FD_t *file, hid_t dxpl_id, H5FD_mem_t type, struct H5F_t *f,
+ haddr_t addr, hsize_t size);
+H5_DLL htri_t H5FD_try_extend(H5FD_t *file, H5FD_mem_t type, struct H5F_t *f,
+ haddr_t blk_end, hsize_t extra_requested);
H5_DLL haddr_t H5FD_get_eoa(const H5FD_t *file, H5FD_mem_t type);
H5_DLL herr_t H5FD_set_eoa(H5FD_t *file, H5FD_mem_t type, haddr_t addr);
H5_DLL haddr_t H5FD_get_eof(const H5FD_t *file);
H5_DLL haddr_t H5FD_get_maxaddr(const H5FD_t *file);
-H5_DLL herr_t H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
- void *buf/*out*/);
-H5_DLL herr_t H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
- const void *buf);
-H5_DLL herr_t H5FD_flush(H5FD_t *file, hid_t dxpl_id, unsigned closing);
+H5_DLL herr_t H5FD_get_feature_flags(const H5FD_t *file, unsigned long *feature_flags);
+H5_DLL herr_t H5FD_get_fs_type_map(const H5FD_t *file, H5FD_mem_t *type_map);
+H5_DLL herr_t H5FD_read(H5FD_t *file, hid_t dxpl_id, H5FD_mem_t type,
+ haddr_t addr, size_t size, void *buf/*out*/);
+H5_DLL herr_t H5FD_write(H5FD_t *file, hid_t dxpl_id, H5FD_mem_t type,
+ haddr_t addr, size_t size, const void *buf);
+H5_DLL herr_t H5FD_flush(H5FD_t *file, hid_t dxpl_id, hbool_t closing);
+H5_DLL herr_t H5FD_truncate(H5FD_t *file, hid_t dxpl_id, hbool_t closing);
H5_DLL herr_t H5FD_get_fileno(const H5FD_t *file, unsigned long *filenum);
H5_DLL herr_t H5FD_get_vfd_handle(H5FD_t *file, hid_t fapl, void** file_handle);
-H5_DLL hssize_t H5FD_get_freespace(const H5FD_t *file);
-H5_DLL htri_t H5FD_can_extend(const H5FD_t *file, H5FD_mem_t type, haddr_t addr,
- hsize_t size, hsize_t extra_requested);
-H5_DLL herr_t H5FD_extend(H5FD_t *file, H5FD_mem_t type, haddr_t addr,
- hsize_t size, hsize_t extra_requested);
-H5_DLL herr_t H5FD_aggr_reset(H5FD_t *file, H5FD_blk_aggr_t *aggr, hid_t dxpl_id);
+H5_DLL herr_t H5FD_set_base_addr(H5FD_t *file, haddr_t base_addr);
+H5_DLL haddr_t H5FD_get_base_addr(const H5FD_t *file);
#endif /* !_H5FDprivate_H */
diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h
index ea92649..c8ec658 100644
--- a/src/H5FDpublic.h
+++ b/src/H5FDpublic.h
@@ -26,23 +26,8 @@
#define H5_HAVE_VFL 1 /*define a convenient app feature test*/
#define H5FD_VFD_DEFAULT 0 /* Default VFL driver value */
-/*
- * Types of allocation requests. The values larger than H5FD_MEM_DEFAULT
- * should not change other than adding new types to the end. These numbers
- * might appear in files.
- */
-typedef enum H5FD_mem_t {
- H5FD_MEM_NOLIST = -1, /*must be negative*/
- H5FD_MEM_DEFAULT = 0, /*must be zero*/
- H5FD_MEM_SUPER = 1,
- H5FD_MEM_BTREE = 2,
- H5FD_MEM_DRAW = 3,
- H5FD_MEM_GHEAP = 4,
- H5FD_MEM_LHEAP = 5,
- H5FD_MEM_OHDR = 6,
-
- H5FD_MEM_NTYPES /*must be last*/
-} H5FD_mem_t;
+/* Types of allocation requests: see H5Fpublic.h */
+typedef enum H5F_mem_t H5FD_mem_t;
/* Map "fractal heap" header blocks to 'ohdr' type file memory, since its
* a fair amount of work to add a new kind of file memory and they are similar
@@ -89,6 +74,39 @@ typedef enum H5FD_mem_t {
#define H5FD_MEM_SOHM_TABLE H5FD_MEM_OHDR
#define H5FD_MEM_SOHM_INDEX H5FD_MEM_BTREE
+/* Map "extensible array" header blocks to 'ohdr' type file memory, since its
+ * 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.
+ *
+ * Map "extensible array" super blocks to 'btree' type file memory, since they
+ * are similar enough to B-tree nodes.
+ *
+ * Map "extensible array" data blocks & pages to 'lheap' type file memory, since
+ * they are similar enough to local heap info.
+ *
+ * -QAK
+ */
+#define H5FD_MEM_EARRAY_HDR H5FD_MEM_OHDR
+#define H5FD_MEM_EARRAY_IBLOCK H5FD_MEM_OHDR
+#define H5FD_MEM_EARRAY_SBLOCK H5FD_MEM_BTREE
+#define H5FD_MEM_EARRAY_DBLOCK H5FD_MEM_LHEAP
+#define H5FD_MEM_EARRAY_DBLK_PAGE H5FD_MEM_LHEAP
+
+/* Map "fixed array" header blocks to 'ohdr' type file memory, since its
+ * 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 "fixed array" data blocks & pages to 'lheap' type file memory, since
+ * they are similar enough to local heap info.
+ *
+ */
+#define H5FD_MEM_FARRAY_HDR H5FD_MEM_OHDR
+#define H5FD_MEM_FARRAY_DBLOCK H5FD_MEM_LHEAP
+#define H5FD_MEM_FARRAY_DBLK_PAGE H5FD_MEM_LHEAP
+
/*
* A free-list map which maps all types of allocation requests to a single
* free list. This is useful for drivers that don't really care about
@@ -172,6 +190,26 @@ typedef enum H5FD_mem_t {
* and then sub-allocate "small" raw data requests from that larger block.
*/
#define H5FD_FEAT_AGGREGATE_SMALLDATA 0x00000010
+ /*
+ * Defining the H5FD_FEAT_IGNORE_DRVRINFO for a VFL driver means that
+ * the library will ignore the driver info that is encoded in the file
+ * for the VFL driver. (This will cause the driver info to be eliminated
+ * from the file when it is flushed/closed, if the file is opened R/W).
+ */
+#define H5FD_FEAT_IGNORE_DRVRINFO 0x00000020
+ /*
+ * Defining the H5FD_FEAT_DIRTY_SBLK_LOAD for a VFL driver means that
+ * the library will mark the superblock dirty when the file is opened
+ * R/W. This will cause the driver info to be re-encoded when the file
+ * is flushed/closed.
+ */
+#define H5FD_FEAT_DIRTY_SBLK_LOAD 0x00000040
+ /*
+ * Defining the H5FD_FEAT_POSIX_COMPAT_HANDLE for a VFL driver means that
+ * the handle for the VFD (returned with the 'get_handle' callback) is
+ * of type 'int' and is compatible with POSIX I/O calls.
+ */
+#define H5FD_FEAT_POSIX_COMPAT_HANDLE 0x00000080
/* Forward declaration */
@@ -198,6 +236,7 @@ typedef struct H5FD_class_t {
herr_t (*close)(H5FD_t *file);
int (*cmp)(const H5FD_t *f1, const H5FD_t *f2);
herr_t (*query)(const H5FD_t *f1, unsigned long *flags);
+ herr_t (*get_type_map)(const H5FD_t *file, H5FD_mem_t *type_map);
haddr_t (*alloc)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
herr_t (*free)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id,
haddr_t addr, hsize_t size);
@@ -210,6 +249,7 @@ typedef struct H5FD_class_t {
herr_t (*write)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl,
haddr_t addr, size_t size, const void *buffer);
herr_t (*flush)(H5FD_t *file, hid_t dxpl_id, unsigned closing);
+ herr_t (*truncate)(H5FD_t *file, hid_t dxpl_id, hbool_t closing);
herr_t (*lock)(H5FD_t *file, unsigned char *oid, unsigned lock_type, hbool_t last);
herr_t (*unlock)(H5FD_t *file, unsigned char *oid, hbool_t last);
H5FD_mem_t fl_map[H5FD_MEM_NTYPES];
@@ -222,15 +262,6 @@ typedef struct H5FD_free_t {
struct H5FD_free_t *next;
} H5FD_free_t;
-/* Structure for metadata & "small [raw] data" block aggregation fields */
-typedef struct H5FD_blk_aggr_t {
- unsigned long feature_flag; /* Feature flag type */
- hsize_t alloc_size; /* Size for allocating new blocks */
- hsize_t tot_size; /* Total amount of bytes aggregated into block */
- hsize_t size; /* Current size of block left */
- haddr_t addr; /* Location of block left */
-} H5FD_blk_aggr_t;
-
/*
* The main datatype for each driver. Public fields common to all drivers
* are declared here and the driver appends private fields in memory.
@@ -238,32 +269,14 @@ typedef struct H5FD_blk_aggr_t {
struct H5FD_t {
hid_t driver_id; /*driver ID for this file */
const H5FD_class_t *cls; /*constant class info */
- unsigned long fileno; /* File serial number */
+ unsigned long fileno; /* File 'serial' number */
unsigned long feature_flags; /* VFL Driver feature Flags */
+ haddr_t maxaddr; /* For this file, overrides class */
+ haddr_t base_addr; /* Base address for HDF5 data w/in file */
+
+ /* Space allocation management fields */
hsize_t threshold; /* Threshold for alignment */
hsize_t alignment; /* Allocation alignment */
-
- /* Block aggregation info */
- H5FD_blk_aggr_t meta_aggr; /* Metadata aggregation info */
- /* (if aggregating metadata allocations) */
- H5FD_blk_aggr_t sdata_aggr; /* "Small data" aggregation info */
- /* (if aggregating "small data" allocations) */
-
- /* Metadata accumulator fields */
- unsigned char *meta_accum; /* Buffer to hold the accumulated metadata */
- haddr_t accum_loc; /* File location (offset) of the
- * accumulated metadata */
- size_t accum_size; /* Size of the accumulated
- * metadata buffer used (in
- * bytes) */
- size_t accum_buf_size; /* Size of the accumulated
- * metadata buffer allocated (in
- * bytes) */
- unsigned accum_dirty; /* Flag to indicate that the
- * accumulated metadata is dirty */
- haddr_t maxaddr; /* For this file, overrides class */
- H5FD_free_t *fl[H5FD_MEM_NTYPES]; /* Freelist per allocation type */
- hsize_t maxsize; /* Largest object on FL, or zero */
};
#ifdef __cplusplus
@@ -281,8 +294,6 @@ H5_DLL int H5FDquery(const H5FD_t *f, unsigned long *flags);
H5_DLL haddr_t H5FDalloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
H5_DLL herr_t H5FDfree(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id,
haddr_t addr, hsize_t size);
-H5_DLL haddr_t H5FDrealloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id,
- haddr_t addr, hsize_t old_size, hsize_t new_size);
H5_DLL haddr_t H5FDget_eoa(H5FD_t *file, H5FD_mem_t type);
H5_DLL herr_t H5FDset_eoa(H5FD_t *file, H5FD_mem_t type, haddr_t eoa);
H5_DLL haddr_t H5FDget_eof(H5FD_t *file);
@@ -292,6 +303,7 @@ H5_DLL herr_t H5FDread(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id,
H5_DLL herr_t H5FDwrite(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id,
haddr_t addr, size_t size, const void *buf);
H5_DLL herr_t H5FDflush(H5FD_t *file, hid_t dxpl_id, unsigned closing);
+H5_DLL herr_t H5FDtruncate(H5FD_t *file, hid_t dxpl_id, hbool_t closing);
#ifdef __cplusplus
}
diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c
index b01ba3f..c715aae 100644
--- a/src/H5FDsec2.c
+++ b/src/H5FDsec2.c
@@ -43,9 +43,13 @@
static hid_t H5FD_SEC2_g = 0;
/* File operations */
-#define OP_UNKNOWN 0
-#define OP_READ 1
-#define OP_WRITE 2
+typedef enum {
+ OP_UNKNOWN = 0, /* Unknown last file operation */
+ OP_READ = 1, /* Last file I/O operation was a read */
+ OP_WRITE = 2 /* Last file I/O operation was a write */
+} H5FD_sec2_file_op_t;
+
+#define H5FD_SEC2_MAX_FILENAME_LEN 1024
/*
* The description of a file belonging to this driver. The `eoa' and `eof'
@@ -65,7 +69,8 @@ typedef struct H5FD_sec2_t {
haddr_t eoa; /*end of allocated region */
haddr_t eof; /*end of file; current file size*/
haddr_t pos; /*current file I/O position */
- int op; /*last operation */
+ H5FD_sec2_file_op_t op; /*last operation */
+ char filename[H5FD_SEC2_MAX_FILENAME_LEN]; /* Copy of file name from open operation */
#ifndef _WIN32
/*
* On most systems the combination of device and i-node number uniquely
@@ -90,6 +95,10 @@ typedef struct H5FD_sec2_t {
DWORD fileindexlo;
DWORD fileindexhi;
#endif
+
+ /* Information from properties set by 'h5repart' tool */
+ hbool_t fam_to_sec2; /* Whether to eliminate the family driver info
+ * and convert this file to a single file */
} H5FD_sec2_t;
@@ -101,24 +110,16 @@ typedef struct H5FD_sec2_t {
* file_offset_t: The datatype for file offsets, the second argument of
* the lseek() or lseek64() call.
*
- * file_seek: The function which adjusts the current file position,
- * either lseek() or lseek64().
*/
/* adding for windows NT file system support. */
#ifdef H5_HAVE_LSEEK64
# define file_offset_t off64_t
-# define file_seek lseek64
-# define file_truncate ftruncate64
#elif defined (_WIN32) && !defined(__MWERKS__)
# /*MSVC*/
-# define file_offset_t __int64
-# define file_seek _lseeki64
-# define file_truncate _chsize
+# define file_offset_t __int64
#else
# define file_offset_t off_t
-# define file_seek lseek
-# define file_truncate HDftruncate
#endif
/*
@@ -158,7 +159,7 @@ static herr_t H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, hadd
size_t size, void *buf);
static herr_t H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr,
size_t size, const void *buf);
-static herr_t H5FD_sec2_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing);
+static herr_t H5FD_sec2_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
static const H5FD_class_t H5FD_sec2_g = {
"sec2", /*name */
@@ -178,6 +179,7 @@ static const H5FD_class_t H5FD_sec2_g = {
H5FD_sec2_close, /*close */
H5FD_sec2_cmp, /*cmp */
H5FD_sec2_query, /*query */
+ NULL, /*get_type_map */
NULL, /*alloc */
NULL, /*free */
H5FD_sec2_get_eoa, /*get_eoa */
@@ -186,7 +188,8 @@ static const H5FD_class_t H5FD_sec2_g = {
H5FD_sec2_get_handle, /*get_handle */
H5FD_sec2_read, /*read */
H5FD_sec2_write, /*write */
- H5FD_sec2_flush, /*flush */
+ NULL, /*flush */
+ H5FD_sec2_truncate, /*truncate */
NULL, /*lock */
NULL, /*unlock */
H5FD_FLMAP_SINGLE /*fl_map */
@@ -240,7 +243,7 @@ H5FD_sec2_init(void)
FUNC_ENTER_NOAPI(H5FD_sec2_init, FAIL)
if(H5I_VFL != H5I_get_type(H5FD_SEC2_g))
- H5FD_SEC2_g = H5FD_register(&H5FD_sec2_g, sizeof(H5FD_class_t));
+ H5FD_SEC2_g = H5FD_register(&H5FD_sec2_g, sizeof(H5FD_class_t), FALSE);
/* Set return value */
ret_value = H5FD_SEC2_g;
@@ -260,8 +263,6 @@ done:
* Programmer: Quincey Koziol
* Friday, Jan 30, 2004
*
- * Modification:
- *
*---------------------------------------------------------------------------
*/
void
@@ -270,7 +271,7 @@ H5FD_sec2_term(void)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_sec2_term)
/* Reset VFL ID */
- H5FD_SEC2_g=0;
+ H5FD_SEC2_g = 0;
FUNC_LEAVE_NOAPI_VOID
} /* end H5FD_sec2_term() */
@@ -288,8 +289,6 @@ H5FD_sec2_term(void)
* Programmer: Robb Matzke
* Thursday, February 19, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -329,52 +328,57 @@ done:
*
*-------------------------------------------------------------------------
*/
-/* ARGSUSED */
static H5FD_t *
-H5FD_sec2_open(const char *name, unsigned flags, hid_t UNUSED fapl_id,
- haddr_t maxaddr)
+H5FD_sec2_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
{
- int o_flags;
- int fd=(-1);
- H5FD_sec2_t *file=NULL;
+ H5FD_sec2_t *file = NULL; /* sec2 VFD info */
+ int fd = (-1); /* File descriptor */
+ int o_flags; /* Flags for open() call */
#ifdef _WIN32
HFILE filehandle;
struct _BY_HANDLE_FILE_INFORMATION fileinfo;
#endif
h5_stat_t sb;
- H5FD_t *ret_value;
+ H5FD_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5FD_sec2_open, NULL)
/* Sanity check on file offsets */
- assert(sizeof(file_offset_t)>=sizeof(size_t));
+ HDassert(sizeof(file_offset_t) >= sizeof(size_t));
/* Check arguments */
- if (!name || !*name)
+ if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name")
- if (0==maxaddr || HADDR_UNDEF==maxaddr)
+ if(0 == maxaddr || HADDR_UNDEF == maxaddr)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr")
- if (ADDR_OVERFLOW(maxaddr))
+ if(ADDR_OVERFLOW(maxaddr))
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr")
/* Build the open flags */
o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY;
- if (H5F_ACC_TRUNC & flags) o_flags |= O_TRUNC;
- if (H5F_ACC_CREAT & flags) o_flags |= O_CREAT;
- if (H5F_ACC_EXCL & flags) o_flags |= O_EXCL;
+ if(H5F_ACC_TRUNC & flags)
+ o_flags |= O_TRUNC;
+ if(H5F_ACC_CREAT & flags)
+ o_flags |= O_CREAT;
+ if(H5F_ACC_EXCL & flags)
+ o_flags |= O_EXCL;
/* Open the file */
- if ((fd=HDopen(name, o_flags, 0666))<0)
- HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file")
- if (HDfstat(fd, &sb)<0)
+ if((fd = HDopen(name, o_flags, 0666)) < 0) {
+ int myerrno = errno;
+ time_t mytime = HDtime(NULL);
+
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: time = %s, name = '%s', errno = %d, error message = '%s', flags = %x, o_flags = %x", HDctime(&mytime), name, myerrno, HDstrerror(myerrno), flags, (unsigned)o_flags);
+ } /* end if */
+ if(HDfstat(fd, &sb) < 0)
HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file")
/* Create the new file struct */
- if (NULL==(file=H5FL_CALLOC(H5FD_sec2_t)))
+ if(NULL == (file = H5FL_CALLOC(H5FD_sec2_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct")
file->fd = fd;
- H5_ASSIGN_OVERFLOW(file->eof,sb.st_size,h5_stat_size_t,haddr_t);
+ H5_ASSIGN_OVERFLOW(file->eof, sb.st_size, h5_stat_size_t, haddr_t);
file->pos = HADDR_UNDEF;
file->op = OP_UNKNOWN;
#ifdef _WIN32
@@ -382,7 +386,7 @@ H5FD_sec2_open(const char *name, unsigned flags, hid_t UNUSED fapl_id,
(void)GetFileInformationByHandle((HANDLE)filehandle, &fileinfo);
file->fileindexhi = fileinfo.nFileIndexHigh;
file->fileindexlo = fileinfo.nFileIndexLow;
-#else
+#else /* _WIN32 */
file->device = sb.st_dev;
#ifdef H5_VMS
file->inode[0] = sb.st_ino[0];
@@ -392,19 +396,43 @@ H5FD_sec2_open(const char *name, unsigned flags, hid_t UNUSED fapl_id,
file->inode = sb.st_ino;
#endif /*H5_VMS*/
-#endif
+#endif /* _WIN32 */
+
+ /* Retain a copy of the name used to open the file, for possible error reporting */
+ HDstrncpy(file->filename, name, sizeof(file->filename));
+ file->filename[sizeof(file->filename) - 1] = '\0';
+
+ /* Check for non-default FAPL */
+ if(H5P_FILE_ACCESS_DEFAULT != fapl_id) {
+ H5P_genplist_t *plist; /* Property list pointer */
+
+ /* Get the FAPL */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
+ HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, NULL, "not a file access property list")
+
+ /* This step is for h5repart tool only. If user wants to change file driver from
+ * family to sec2 while using h5repart, this private property should be set so that
+ * in the later step, the library can ignore the family driver information saved
+ * in the superblock.
+ */
+ if(H5P_exist_plist(plist, H5F_ACS_FAMILY_TO_SEC2_NAME) > 0)
+ if(H5P_get(plist, H5F_ACS_FAMILY_TO_SEC2_NAME, &file->fam_to_sec2) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get property of changing family to sec2")
+ } /* end if */
/* Set return value */
- ret_value=(H5FD_t*)file;
+ ret_value = (H5FD_t*)file;
done:
- if(ret_value==NULL) {
- if(fd>=0)
+ if(NULL == ret_value) {
+ if(fd >= 0)
HDclose(fd);
+ if(file)
+ file = H5FL_FREE(H5FD_sec2_t, file);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_sec2_open() */
/*-------------------------------------------------------------------------
@@ -419,26 +447,29 @@ done:
* Programmer: Robb Matzke
* Thursday, July 29, 1999
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
H5FD_sec2_close(H5FD_t *_file)
{
H5FD_sec2_t *file = (H5FD_sec2_t*)_file;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_sec2_close, FAIL)
- if (HDclose(file->fd)<0)
+ /* Sanity check */
+ HDassert(file);
+
+ /* Close the underlying file */
+ if(HDclose(file->fd) < 0)
HSYS_GOTO_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file")
- H5FL_FREE(H5FD_sec2_t,file);
+ /* Release the file info */
+ file = H5FL_FREE(H5FD_sec2_t, file);
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_sec2_close() */
/*-------------------------------------------------------------------------
@@ -510,36 +541,36 @@ done:
* (listed in H5FDpublic.h)
*
* Return: Success: non-negative
- *
* Failure: negative
*
* Programmer: Quincey Koziol
* Friday, August 25, 2000
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
-/* ARGSUSED */
static herr_t
-H5FD_sec2_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */)
+H5FD_sec2_query(const H5FD_t *_file, unsigned long *flags /* out */)
{
- herr_t ret_value=SUCCEED;
+ const H5FD_sec2_t *file = (const H5FD_sec2_t*)_file; /* sec2 VFD info */
- FUNC_ENTER_NOAPI(H5FD_sec2_query, FAIL)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_sec2_query)
/* Set the VFL feature flags that this driver supports */
if(flags) {
*flags = 0;
- *flags|=H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
- *flags|=H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */
- *flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
- *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
- }
+ *flags |= H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
+ *flags |= H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */
+ *flags |= H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
+ *flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
+ *flags |= H5FD_FEAT_POSIX_COMPAT_HANDLE; /* VFD handle is POSIX I/O call compatible */
+
+ /* Check for flags that are set by h5repart */
+ if(file->fam_to_sec2)
+ *flags |= H5FD_FEAT_IGNORE_DRVRINFO; /* Ignore the driver info when file is opened (which eliminates it) */
+ } /* end if */
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5FD_sec2_query() */
/*-------------------------------------------------------------------------
@@ -572,11 +603,11 @@ H5FD_sec2_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type)
FUNC_ENTER_NOAPI(H5FD_sec2_get_eoa, HADDR_UNDEF)
/* Set return value */
- ret_value=file->eoa;
+ ret_value = file->eoa;
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_sec2_get_eoa() */
/*-------------------------------------------------------------------------
@@ -612,7 +643,7 @@ H5FD_sec2_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED type, haddr_t addr)
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_sec2_set_eoa() */
/*-------------------------------------------------------------------------
@@ -661,13 +692,11 @@ done:
* Programmer: Raymond Lu
* Sept. 16, 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
/* ARGSUSED */
static herr_t
-H5FD_sec2_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void** file_handle)
+H5FD_sec2_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void **file_handle)
{
H5FD_sec2_t *file = (H5FD_sec2_t *)_file;
herr_t ret_value = SUCCEED;
@@ -680,7 +709,7 @@ H5FD_sec2_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void** file_handle)
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_sec2_get_handle() */
/*-------------------------------------------------------------------------
@@ -692,80 +721,82 @@ done:
*
* Return: Success: Zero. Result is stored in caller-supplied
* buffer BUF.
- *
* Failure: -1, Contents of buffer BUF are undefined.
*
* Programmer: Robb Matzke
* Thursday, July 29, 1999
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
/* ARGSUSED */
static herr_t
-H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr,
- size_t size, void *buf/*out*/)
+H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id,
+ haddr_t addr, size_t size, void *buf/*out*/)
{
H5FD_sec2_t *file = (H5FD_sec2_t*)_file;
ssize_t nbytes;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_sec2_read, FAIL)
- assert(file && file->pub.cls);
- assert(buf);
+ HDassert(file && file->pub.cls);
+ HDassert(buf);
/* Check for overflow conditions */
- if (HADDR_UNDEF==addr)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined")
- if (REGION_OVERFLOW(addr, size))
- HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
- if (addr+size>file->eoa)
- HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
+ if(!H5F_addr_defined(addr))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined, addr = %llu", (unsigned long long)addr)
+ if(REGION_OVERFLOW(addr, size))
+ HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr)
+ if((addr + size) > file->eoa)
+ HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr)
/* Seek to the correct location */
- if ((addr!=file->pos || OP_READ!=file->op) &&
- file_seek(file->fd, (file_offset_t)addr, SEEK_SET)<0)
+ if((addr != file->pos || OP_READ != file->op) &&
+ HDlseek(file->fd, (file_offset_t)addr, SEEK_SET) < 0)
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
/*
* Read data, being careful of interrupted system calls, partial results,
* and the end of the file.
*/
- while (size>0) {
+ while(size > 0) {
do {
nbytes = HDread(file->fd, buf, size);
- } while (-1==nbytes && EINTR==errno);
- if (-1==nbytes) /* error */
- HSYS_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed")
- if (0==nbytes) {
+ } while(-1 == nbytes && EINTR == errno);
+ if(-1 == nbytes) { /* error */
+ int myerrno = errno;
+ time_t mytime = HDtime(NULL);
+ file_offset_t myoffset = HDlseek(file->fd, (file_offset_t)0, SEEK_CUR);
+
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', buf = %p, size = %lu, offset = %llu", HDctime(&mytime), file->filename, file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long)size, (unsigned long long)myoffset);
+ } /* end if */
+ if(0 == nbytes) {
/* end of file but not end of format address space */
HDmemset(buf, 0, size);
break;
- }
- assert(nbytes>=0);
- assert((size_t)nbytes<=size);
- H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t);
+ } /* end if */
+ HDassert(nbytes >= 0);
+ HDassert((size_t)nbytes <= size);
+ H5_CHECK_OVERFLOW(nbytes, ssize_t, size_t);
size -= (size_t)nbytes;
- H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t);
+ H5_CHECK_OVERFLOW(nbytes, ssize_t, haddr_t);
addr += (haddr_t)nbytes;
- buf = (char*)buf + nbytes;
- }
+ buf = (char *)buf + nbytes;
+ } /* end while */
/* Update current position */
file->pos = addr;
file->op = OP_READ;
done:
- if(ret_value<0) {
+ if(ret_value < 0) {
/* Reset last file I/O information */
file->pos = HADDR_UNDEF;
file->op = OP_UNKNOWN;
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_sec2_read() */
/*-------------------------------------------------------------------------
@@ -776,14 +807,11 @@ done:
* DXPL_ID.
*
* Return: Success: Zero
- *
* Failure: -1
*
* Programmer: Robb Matzke
* Thursday, July 29, 1999
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
/* ARGSUSED */
@@ -793,64 +821,69 @@ H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had
{
H5FD_sec2_t *file = (H5FD_sec2_t*)_file;
ssize_t nbytes;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_sec2_write, FAIL)
- assert(file && file->pub.cls);
- assert(buf);
+ HDassert(file && file->pub.cls);
+ HDassert(buf);
/* Check for overflow conditions */
- if (HADDR_UNDEF==addr)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined")
- if (REGION_OVERFLOW(addr, size))
- HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
- if (addr+size>file->eoa)
- HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
+ if(!H5F_addr_defined(addr))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined, addr = %llu", (unsigned long long)addr)
+ if(REGION_OVERFLOW(addr, size))
+ HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr)
+ if((addr + size) > file->eoa)
+ HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr)
/* Seek to the correct location */
- if ((addr!=file->pos || OP_WRITE!=file->op) &&
- file_seek(file->fd, (file_offset_t)addr, SEEK_SET)<0)
+ if((addr != file->pos || OP_WRITE != file->op) &&
+ HDlseek(file->fd, (file_offset_t)addr, SEEK_SET) < 0)
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
/*
* Write the data, being careful of interrupted system calls and partial
* results
*/
- while (size>0) {
+ while(size > 0) {
do {
nbytes = HDwrite(file->fd, buf, size);
- } while (-1==nbytes && EINTR==errno);
- if (-1==nbytes) /* error */
- HSYS_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed")
- assert(nbytes>0);
- assert((size_t)nbytes<=size);
- H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t);
+ } while(-1 == nbytes && EINTR == errno);
+ if(-1 == nbytes) { /* error */
+ int myerrno = errno;
+ time_t mytime = HDtime(NULL);
+ file_offset_t myoffset = HDlseek(file->fd, (file_offset_t)0, SEEK_CUR);
+
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', buf = %p, size = %lu, offset = %llu", HDctime(&mytime), file->filename, file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long)size, (unsigned long long)myoffset);
+ } /* end if */
+ HDassert(nbytes > 0);
+ HDassert((size_t)nbytes <= size);
+ H5_CHECK_OVERFLOW(nbytes, ssize_t, size_t);
size -= (size_t)nbytes;
- H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t);
+ H5_CHECK_OVERFLOW(nbytes, ssize_t, haddr_t);
addr += (haddr_t)nbytes;
- buf = (const char*)buf + nbytes;
- }
+ buf = (const char *)buf + nbytes;
+ } /* end while */
/* Update current position and eof */
file->pos = addr;
file->op = OP_WRITE;
- if (file->pos>file->eof)
+ if(file->pos > file->eof)
file->eof = file->pos;
done:
- if(ret_value<0) {
+ if(ret_value < 0) {
/* Reset last file I/O information */
file->pos = HADDR_UNDEF;
file->op = OP_UNKNOWN;
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_sec2_write() */
/*-------------------------------------------------------------------------
- * Function: H5FD_sec2_flush
+ * Function: H5FD_sec2_truncate
*
* Purpose: Makes sure that the true file size is the same (or larger)
* than the end-of-address.
@@ -862,23 +895,21 @@ done:
* Programmer: Robb Matzke
* Wednesday, August 4, 1999
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
/* ARGSUSED */
static herr_t
-H5FD_sec2_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing)
+H5FD_sec2_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing)
{
- H5FD_sec2_t *file = (H5FD_sec2_t*)_file;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5FD_sec2_t *file = (H5FD_sec2_t*)_file;
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5FD_sec2_flush, FAIL)
+ FUNC_ENTER_NOAPI(H5FD_sec2_truncate, FAIL)
- assert(file);
+ HDassert(file);
/* Extend the file to make sure it's large enough */
- if (file->eoa!=file->eof) {
+ if(!H5F_addr_eq(file->eoa, file->eof)) {
#ifdef _WIN32
HFILE filehandle; /* Windows file handle */
LARGE_INTEGER li; /* 64-bit integer for SetFilePointer() call */
@@ -889,11 +920,18 @@ H5FD_sec2_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing)
/* Translate 64-bit integers into form Windows wants */
/* [This algorithm is from the Windows documentation for SetFilePointer()] */
li.QuadPart = (LONGLONG)file->eoa;
- (void)SetFilePointer((HANDLE)filehandle,li.LowPart,&li.HighPart,FILE_BEGIN);
- if(SetEndOfFile((HANDLE)filehandle)==0)
+ (void)SetFilePointer((HANDLE)filehandle, li.LowPart, &li.HighPart, FILE_BEGIN);
+ if(SetEndOfFile((HANDLE)filehandle) == 0)
HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
#else /* _WIN32 */
- if (-1==file_truncate(file->fd, (file_offset_t)file->eoa))
+#ifdef H5_VMS
+ /* Reset seek offset to the beginning of the file, so that the file isn't
+ * re-extended later. This may happen on Open VMS. */
+ if(-1 == HDlseek(file->fd, (file_offset_t)0, SEEK_SET))
+ HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
+#endif
+
+ if(-1 == HDftruncate(file->fd, (file_offset_t)file->eoa))
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
#endif /* _WIN32 */
@@ -903,8 +941,8 @@ H5FD_sec2_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing)
/* Reset last file I/O information */
file->pos = HADDR_UNDEF;
file->op = OP_UNKNOWN;
- }
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_sec2_truncate() */
diff --git a/src/H5FDsec2.h b/src/H5FDsec2.h
index 9c3f59d..b7db0d5 100644
--- a/src/H5FDsec2.h
+++ b/src/H5FDsec2.h
@@ -39,3 +39,4 @@ H5_DLL herr_t H5Pset_fapl_sec2(hid_t fapl_id);
#endif
#endif
+
diff --git a/src/H5FDspace.c b/src/H5FDspace.c
index 7bd72cc..9895938 100644
--- a/src/H5FDspace.c
+++ b/src/H5FDspace.c
@@ -42,7 +42,6 @@
#include "H5Fprivate.h" /* File access */
#include "H5FDpkg.h" /* File Drivers */
#include "H5FDmulti.h" /* Usage-partitioned file family */
-#include "H5MMprivate.h" /* Memory management */
/****************/
@@ -66,19 +65,6 @@
/********************/
/* Local Prototypes */
/********************/
-static haddr_t H5FD_alloc_from_free_list(H5FD_t *file, H5FD_mem_t type,
- hsize_t size);
-static haddr_t H5FD_aggr_alloc(H5FD_t *file, H5FD_blk_aggr_t *aggr,
- H5FD_blk_aggr_t *other_aggr, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
-static herr_t H5FD_aggr_adjoin(const H5FD_t *file, H5FD_blk_aggr_t *aggr,
- H5FD_free_t *last);
-static htri_t H5FD_aggr_can_extend(const H5FD_t *file, const H5FD_blk_aggr_t *aggr,
- haddr_t eoa, haddr_t end);
-static herr_t H5FD_aggr_shift(H5FD_blk_aggr_t *aggr, hsize_t extra);
-static herr_t H5FD_aggr_query(const H5FD_t *file, const H5FD_blk_aggr_t *aggr,
- haddr_t *addr, hsize_t *size);
-static haddr_t H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
-static haddr_t H5FD_update_eoa(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
/*********************/
@@ -98,9 +84,6 @@ static haddr_t H5FD_update_eoa(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsi
/* Declare a free list to manage the H5FD_free_t struct */
H5FL_DEFINE(H5FD_free_t);
-/* Declare a PQ free list to manage the metadata accumulator buffer */
-H5FL_BLK_DEFINE(meta_accum);
-
/*--------------------------------------------------------------------------
@@ -126,971 +109,178 @@ H5FD_space_init_interface(void)
/*-------------------------------------------------------------------------
- * Function: H5FD_free_freelist
- *
- * Purpose: Split off from H5FD_close(). Free the elements in the
- * free list for this file driver.
- *
- * Return: Success: SUCCEED
- * Failure: Never fails
- *
- * Programmer: Bill Wendling
- * 17. February 2003
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5FD_free_freelist(H5FD_t *file)
-{
- H5FD_mem_t i;
-#ifdef H5FD_ALLOC_DEBUG
- unsigned nblocks = 0;
- hsize_t nbytes = 0;
-#endif /* H5FD_ALLOC_DEBUG */
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_free_freelist)
-
- /* check args */
- HDassert(file && file->cls);
-
- /*
- * Free all free-lists, leaking any memory thus described. Also leaks
- * file space allocated but not used when metadata aggregation is
- * turned on.
- */
- for(i = H5FD_MEM_DEFAULT; i < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, i)) {
- H5FD_free_t *cur, *next;
-
- for( cur = file->fl[i]; cur; cur = next) {
-#ifdef H5FD_ALLOC_DEBUG
- ++nblocks;
- nbytes += cur->size;
-#endif /* H5FD_ALLOC_DEBUG */
- next = cur->next;
- H5FL_FREE(H5FD_free_t, cur);
- } /* end for */
-
- file->fl[i] = NULL;
- } /* end for */
-
-#ifdef H5FD_ALLOC_DEBUG
- if(nblocks)
- HDfprintf(stderr, "%s: leaked %Hu bytes of file memory in %u blocks\n",
- "H5FD_free_freelist", nbytes, nblocks);
-#endif /* H5FD_ALLOC_DEBUG */
-
- /* Check if we need to reset the metadata accumulator information */
- if(file->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) {
- /* Free the buffer */
- if(file->meta_accum)
- file->meta_accum = H5FL_BLK_FREE(meta_accum, file->meta_accum);
-
- /* Reset the buffer sizes & location */
- file->accum_buf_size = file->accum_size = 0;
- file->accum_loc = HADDR_UNDEF;
- file->accum_dirty = 0;
- } /* end if */
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5FD_free_freelist() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_alloc
- *
- * Purpose: Private version of H5FDalloc().
- *
- * Return: Success: The format address of the new file memory.
- * Failure: The undefined address HADDR_UNDEF
- *
- * Programmer: Robb Matzke
- * Wednesday, August 4, 1999
- *
- *-------------------------------------------------------------------------
- */
-haddr_t
-H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
-{
- haddr_t ret_value = HADDR_UNDEF;
-
- FUNC_ENTER_NOAPI(H5FD_alloc, HADDR_UNDEF)
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
-#endif /* H5FD_ALLOC_DEBUG */
-
- /* check args */
- assert(file);
- assert(file->cls);
- assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
- assert(size > 0);
-
-#ifdef H5F_DEBUG
- if(H5DEBUG(F))
- HDfprintf(H5DEBUG(F), "%s: alignment=%Hd, threshold=%Hd, size=%Hd\n",
- FUNC, file->alignment, file->threshold, size);
-#endif /* H5F_DEBUG */
-
- /* Try to allocate from the free list first */
- if((ret_value = H5FD_alloc_from_free_list(file, type, size)) != HADDR_UNDEF)
- HGOTO_DONE(ret_value)
-
-#ifdef H5F_DEBUG
- if(H5DEBUG(F))
- HDfprintf(H5DEBUG(F), "%s: Could not allocate from freelists\n", FUNC);
-#endif /* H5F_DEBUG */
-
- if(type != H5FD_MEM_DRAW) {
- /* Handle metadata differently from "raw" data */
- if(HADDR_UNDEF == (ret_value = H5FD_aggr_alloc(file, &(file->meta_aggr), &(file->sdata_aggr), type, dxpl_id, size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate metadata")
- } /* end if */
- else {
- /* Allocate "raw" data */
- if(HADDR_UNDEF == (ret_value = H5FD_aggr_alloc(file, &(file->sdata_aggr), &(file->meta_aggr), type, dxpl_id, size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate raw data")
- } /* end else */
-
-done:
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
-#endif /* H5FD_ALLOC_DEBUG */
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_alloc() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_alloc_from_free_list
- *
- * Purpose: Try to allocate SIZE bytes of memory from the free list
- * if possible.
- *
- * This is split from H5FD_alloc().
- *
- * Return: Success: The format address of the new file memory.
- * Failure: The undefined address HADDR_UNDEF
- *
- * Programmer: Bill Wendling
- * 02. December, 2002
- *
- *-------------------------------------------------------------------------
- */
-static haddr_t
-H5FD_alloc_from_free_list(H5FD_t *file, H5FD_mem_t type, hsize_t size)
-{
- H5FD_mem_t mapped_type;
- haddr_t ret_value = HADDR_UNDEF;
-
- FUNC_ENTER_NOAPI(H5FD_alloc_from_free_list, HADDR_UNDEF)
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
-#endif /* H5FD_ALLOC_DEBUG */
-
- assert(file);
- assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
- assert(size > 0);
-
- /* Map the allocation request to a free list */
- if(H5FD_MEM_DEFAULT == file->cls->fl_map[type])
- mapped_type = type;
- else
- mapped_type = file->cls->fl_map[type];
-
- /*
- * Try to satisfy the request from the free list. Only perform the
- * search if the free list has the potential of satisfying the
- * request.
- *
- * Here, aligned requests are requests that are >= threshold and
- * alignment > 1.
- *
- * For non-aligned request, first try to find an exact match,
- * otherwise use the best match which is the smallest size that meets
- * the requested size.
- *
- * For aligned address request, find a block in the following order
- * of preferences:
- *
- * 1. block address is aligned and exact match in size;
- * 2. block address is aligned with smallest size > requested size;
- * 3. block address is not aligned with smallest size >= requested size.
- */
- if(mapped_type >= H5FD_MEM_DEFAULT && (file->maxsize == 0 || size <= file->maxsize)) {
- H5FD_free_t *prev = NULL, *best = NULL;
- H5FD_free_t *cur = file->fl[mapped_type];
- hbool_t found_aligned = FALSE;
- hbool_t need_aligned;
- hsize_t head;
-
- need_aligned = file->alignment > 1 && size >= file->threshold;
-
- while(cur) {
- if(cur->size > file->maxsize)
- file->maxsize = cur->size;
-
- if(need_aligned) {
- if((head = cur->addr % file->alignment) == 0) {
- /*
- * Aligned address
- */
- if(cur->size >= size) {
- if(cur->size == size) {
- /* exact match */
- ret_value = cur->addr;
-
- /*
- * Make certain we don't hand out a block of raw data
- * from the free list which overlaps with the metadata
- * aggregation buffer (if it's turned on)
- */
- if(type == H5FD_MEM_DRAW &&
- (file->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) &&
- H5F_addr_overlap(ret_value, size,
- file->accum_loc, file->accum_size)) {
- ret_value = HADDR_UNDEF;
- } else {
- if(prev)
- prev->next = cur->next;
- else
- file->fl[mapped_type] = cur->next;
-
- H5FL_FREE(H5FD_free_t, cur);
-
- if(size == file->maxsize)
- file->maxsize = 0; /*unknown*/
-
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Exact size match (aligned)\n", FUNC);
-#endif /* H5FD_ALLOC_DEBUG */
- HGOTO_DONE(ret_value)
- }
- }
- else
- /* Favor smallest block, that's closest to the beginning of the file */
- if(!best || !found_aligned || cur->size < best->size ||
- (cur->size == best->size && H5F_addr_lt(cur->addr, best->addr))) {
- best = cur;
- found_aligned = TRUE;
- }
- } /* end if */
- } else {
- /*
- * Non-aligned address
- *
- * Check to see if this block is big enough to skip
- * to the next aligned address and is still big
- * enough for the requested size. The extra
- * (cur->size > head) is for preventing unsigned
- * underflow. (This could be improved by checking for
- * an exact match after excluding the head. Such
- * match is as good as the found_aligned case above.)
- */
- head = file->alignment - head; /* actual head size */
-
- if(!found_aligned && cur->size > head && cur->size-head >= size) {
- /* Favor smallest block, that's closest to the beginning of the file */
- if(!best || cur->size < best->size ||
- (cur->size == best->size && H5F_addr_lt(cur->addr, best->addr)))
- best = cur;
- } /* end if */
- } /* end else */
- } else {
- /* !need_aligned */
- if(cur->size >= size) {
- if(cur->size == size) {
- /* exact match */
- ret_value = cur->addr;
-
- /*
- * Make certain we don't hand out a block of raw data
- * from the free list which overlaps with the metadata
- * aggregation buffer (if it's turned on)
- */
- if(type == H5FD_MEM_DRAW &&
- (file->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) &&
- H5F_addr_overlap(ret_value, size, file->accum_loc,
- file->accum_size)) {
- ret_value = HADDR_UNDEF;
- } else {
- if(prev)
- prev->next = cur->next;
- else
- file->fl[mapped_type] = cur->next;
-
- H5FL_FREE(H5FD_free_t, cur);
-
- if(size == file->maxsize)
- file->maxsize = 0; /*unknown*/
-
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Exact size match (unaligned)\n", FUNC);
-#endif /* H5FD_ALLOC_DEBUG */
- HGOTO_DONE(ret_value)
- }
- } /* end if */
- else {
- /* Favor smallest block, that's closest to the beginning of the file */
- if(!best || cur->size < best->size ||
- (cur->size == best->size && H5F_addr_lt(cur->addr, best->addr)))
- best = cur;
- } /* end else */
- } /* end if */
- } /* end else */
-
- prev = cur;
- cur = cur->next;
- } /* end while */
-
- /* Couldn't find exact match, use best fitting piece found */
- if(best) {
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Splitting %Hu byte sized block\n", FUNC, best->size);
-#endif /* H5FD_ALLOC_DEBUG */
- if(best->size == file->maxsize)
- file->maxsize = 0; /*unknown*/
-
- if(!need_aligned || found_aligned) {
- /* free only tail */
- ret_value = best->addr;
-
- /*
- * Make certain we don't hand out a block of raw data
- * from the free list which overlaps with the metadata
- * aggregation buffer (if it's turned on)
- */
- if(type == H5FD_MEM_DRAW &&
- (file->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) &&
- H5F_addr_overlap(ret_value, size, file->accum_loc,
- file->accum_size)) {
- ret_value = HADDR_UNDEF;
- } else {
- best->addr += size; /* Reduce size of block on free list */
- best->size -= size;
- HGOTO_DONE(ret_value)
- }
- } else {
- /*
- * Split into 3 pieces. Keep the the head and tail in the
- * freelist.
- */
- H5FD_free_t *tmp = NULL;
-
- head = file->alignment - (best->addr % file->alignment);
- ret_value = best->addr + head;
-
- /*
- * Make certain we don't hand out a block of raw data
- * from the free list which overlaps with the metadata
- * aggregation buffer (if it's turned on)
- */
- if(type == H5FD_MEM_DRAW &&
- (file->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) &&
- H5F_addr_overlap(ret_value, size, file->accum_loc, file->accum_size)) {
- ret_value = HADDR_UNDEF;
- } else {
- /* Attempt to allocate memory for temporary node */
- if((tmp = H5FL_MALLOC(H5FD_free_t))==NULL)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "free block allocation failed")
-
- if((tmp->size = (best->size - (head + size)))!=0) {
- tmp->addr = best->addr + (head + size);
- tmp->next = best->next;
- best->next = tmp;
- } else {
- /* no tail piece */
- H5FL_FREE(H5FD_free_t,tmp);
- }
-
- best->size = head;
- HGOTO_DONE(ret_value)
- } /* end else */
- } /* end else */
- } /* end if */
- } /* end if */
-
-done:
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
-#endif /* H5FD_ALLOC_DEBUG */
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_alloc_from_free_list() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_aggr_alloc
+ * Function: H5FD_extend
*
- * Purpose: Try to allocate SIZE bytes of memory from an aggregator
- * block if possible.
+ * Purpose: Extend the EOA space of a file.
*
- * This is split from H5FD_alloc().
+ * NOTE: Returns absolute file offset
*
- * Return: Success: The format address of the new file memory.
+ * Return: Success: The address of the previous EOA.
* Failure: The undefined address HADDR_UNDEF
*
* Programmer: Bill Wendling
- * 2. December, 2002
+ * Wednesday, 04. December, 2002
*
*-------------------------------------------------------------------------
*/
static haddr_t
-H5FD_aggr_alloc(H5FD_t *file, H5FD_blk_aggr_t *aggr, H5FD_blk_aggr_t *other_aggr,
- H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
+H5FD_extend(H5FD_t *file, H5FD_mem_t type, hbool_t new_block, hsize_t size, haddr_t *frag_addr, hsize_t *frag_size)
{
+ hsize_t orig_size = size; /* Original allocation size */
+ haddr_t eoa; /* Address of end-of-allocated space */
+ hsize_t extra; /* Extra space to allocate, to align request */
haddr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5FD_aggr_alloc)
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
-#endif /* H5FD_ALLOC_DEBUG */
+ FUNC_ENTER_NOAPI_NOINIT(H5FD_extend)
/* check args */
HDassert(file);
- HDassert(aggr);
- HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
- HDassert(other_aggr);
- HDassert(other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
- HDassert(other_aggr->feature_flag != aggr->feature_flag);
+ HDassert(file->cls);
HDassert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
HDassert(size > 0);
- /*
- * If the aggregation feature is enabled for this VFL
- * driver, allocate "generic" space and sub-allocate out of
- * that, if possible. Otherwise just allocate through
- * H5FD_real_alloc()
- */
- if(file->feature_flags & aggr->feature_flag) {
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: aggr = {%a, %Hu, %Hu}\n", FUNC, aggr->addr, aggr->tot_size, aggr->size);
-#endif /* H5FD_ALLOC_DEBUG */
- /* Check if the space requested is larger than the space left in the block */
- if(size > aggr->size) {
- haddr_t new_space; /* Address for newly allocated space */
-
- /* Check if the block asked for is too large for 'normal' aggregator block */
- if(size >= aggr->alloc_size) {
- /* Allocate more room for this new block the regular way */
- if(HADDR_UNDEF == (new_space = H5FD_real_alloc(file, type, dxpl_id, size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate aggregation block")
-
- /* Check if the new space is at the end of the current block */
- if((aggr->addr + aggr->size) == new_space) {
- /*
- * Treat the allocation request as if the current block
- * grew by the amount allocated and just update the address.
- *
- * Don't bother updating the block's size since it will
- * just grow and shrink by the same amount.
- *
- * _Do_ add to the total size aggregated.
- *
- */
- ret_value = aggr->addr;
- aggr->addr += size;
- aggr->tot_size += size;
- } /* end if */
- else {
- /* Check if the new space is at the end of the _other_ block */
- if(other_aggr->size > 0 && (other_aggr->addr + other_aggr->size) == new_space) {
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: New block is at end of 'other' block: other_aggr = {%a, %Hu, %Hu}\n", FUNC, other_aggr->addr, other_aggr->tot_size, other_aggr->size);
-#endif /* H5FD_ALLOC_DEBUG */
- /* If the other block has used at least the
- * 'allocation' amount for that block, shift the
- * newly allocated space down over the remainder
- * in the 'other block', shift the 'other block'
- * up by the same amount and free it. (Which
- * should amount to "bubbling" the remainder in
- * the 'other block' to the end of the file and
- * then "popping" the bubble by shrinking the
- * file)
- */
- if((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size) {
- H5FD_mem_t alloc_type = (other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW); /* Type of file memory to work with */
- haddr_t free_addr = (new_space + size) - other_aggr->size; /* Address of free space in 'other block' shifted toward end of the file */
- hsize_t free_size = other_aggr->size; /* Size of the free space in 'other block' */
-
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Freeing 'other' block\n", FUNC);
-#endif /* H5FD_ALLOC_DEBUG */
- /* Reset 'other' block's info */
- other_aggr->addr = 0;
- other_aggr->tot_size = 0;
- other_aggr->size = 0;
-
- /* Shift newly allocated space down */
- new_space -= free_size;
-
- /* Return the unused portion of the 'other' block to a free list */
- if(H5FD_free(file, alloc_type, dxpl_id, free_addr, free_size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block")
- } /* end if */
- } /* end if */
-
- /* Use the new space allocated, leaving the old block */
- ret_value = new_space;
- } /* end else */
- } /* end if */
- else {
- H5FD_mem_t alloc_type = (aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW); /* Type of file memory to work with */
-
- /* Allocate another block */
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Allocating block\n", FUNC);
-#endif /* H5FD_ALLOC_DEBUG */
- if(HADDR_UNDEF == (new_space = H5FD_real_alloc(file, alloc_type, dxpl_id, aggr->alloc_size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate aggregation block")
-
- /* Check if the new space is at the end of the current block */
- if(aggr->addr + aggr->size == new_space) {
- aggr->size += aggr->alloc_size;
- aggr->tot_size += aggr->alloc_size;
- } /* end if */
- else {
- hsize_t new_size; /* Size of new aggregator block */
-
- /* Return the unused portion of the block to a free list */
- if(aggr->size > 0)
- if(H5FD_free(file, alloc_type, dxpl_id, aggr->addr, aggr->size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block")
-
- /* Check if the new space is at the end of the _other_ block */
- if(other_aggr->size > 0 && (other_aggr->addr + other_aggr->size) == new_space) {
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: New block is at end of 'other' block: other_aggr = {%a, %Hu, %Hu}\n", FUNC, other_aggr->addr, other_aggr->tot_size, other_aggr->size);
-#endif /* H5FD_ALLOC_DEBUG */
-#ifdef QAK
- /* If the other block has used at least the
- * 'allocation' amount for that block, give the
- * remaining free space in the 'other' block to
- * the new space allocated for 'this' block.
- */
- if((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size) {
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Absorbing 'other' block\n", FUNC);
-#endif /* H5FD_ALLOC_DEBUG */
- /* Absorb the remaining free space into newly allocated block */
- new_space -= other_aggr->size;
- new_size = aggr->alloc_size + other_aggr->size;
-
- /* Reset the info for the 'other' block */
- other_aggr->addr = 0;
- other_aggr->tot_size = 0;
- other_aggr->size = 0;
- } /* end if */
- else
- new_size = aggr->alloc_size;
-#else /* QAK */
- /* If the other block has used at least the
- * 'allocation' amount for that block, shift the
- * newly allocated space down over the remainder
- * in the 'other block', shift the 'other block'
- * up by the same amount and free it. (Which
- * should amount to "bubbling" the remainder in
- * the 'other block' to the end of the file and
- * then "popping" the bubble by shrinking the
- * file)
- */
- if((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size) {
- H5FD_mem_t other_type = (other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW); /* Type of file memory to work with */
- haddr_t free_addr = (new_space + aggr->alloc_size) - other_aggr->size; /* Address of free space in 'other block' shifted toward end of the file */
- hsize_t free_size = other_aggr->size; /* Size of the free space in 'other block' */
-
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Freeing 'other' block\n", FUNC);
-#endif /* H5FD_ALLOC_DEBUG */
- /* Reset 'other' block's info */
- other_aggr->addr = 0;
- other_aggr->tot_size = 0;
- other_aggr->size = 0;
-
- /* Shift newly allocated space down */
- new_space -= free_size;
-
- /* Return the unused portion of the 'other' block to a free list */
- if(H5FD_free(file, other_type, dxpl_id, free_addr, free_size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block")
- } /* end if */
- new_size = aggr->alloc_size;
-#endif /* QAK */
- } /* end if */
- else
- new_size = aggr->alloc_size;
-
- /* Point the aggregator at the newly allocated block */
- aggr->addr = new_space;
- aggr->size = new_size;
- aggr->tot_size = new_size;
- } /* end else */
-
- /* Allocate space out of the metadata block */
- ret_value = aggr->addr;
- aggr->size -= size;
- aggr->addr += size;
- } /* end else */
- } /* end if */
- else {
- /* Allocate space out of the block */
- ret_value = aggr->addr;
- aggr->size -= size;
- aggr->addr += size;
- }
- } /* end if */
- else {
- /* Allocate data the regular way */
- if(HADDR_UNDEF == (ret_value = H5FD_real_alloc(file, type, dxpl_id, size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate file space")
- } /* end else */
-
-done:
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
-#endif /* H5FD_ALLOC_DEBUG */
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_aggr_alloc() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_aggr_adjoin
- *
- * Purpose: Check if a newly freed block of space in the file adjoins an
- * aggregator block
- *
- * Return: Success: Non-negative
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * Thursday, December 13, 2007
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD_aggr_adjoin(const H5FD_t *file, H5FD_blk_aggr_t *aggr, H5FD_free_t *last)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_aggr_adjoin)
-
- /* Check args */
- HDassert(file);
- HDassert(file->cls);
- HDassert(aggr);
- HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
- HDassert(last);
-
- /* Check if this free block adjoins the aggregator */
- if((file->feature_flags & aggr->feature_flag) && aggr->size > 0) {
- hbool_t adjoins = FALSE; /* Whether the block adjoined the aggregator */
-
- /* Does the newly freed space adjoin the end of the aggregator */
- if((aggr->addr + aggr->size) == last->addr) {
- last->addr = aggr->addr;
- adjoins = TRUE;
- } /* end if */
- /* Does the newly freed space adjoin the beginning of the aggregator */
- else if((last->addr + last->size) == aggr->addr)
- adjoins = TRUE;
-
- /* Reset aggregator information, if adjoined */
- if(adjoins) {
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Adjoined flag = %lx aggregator\n", "H5FD_aggr_adjoin", aggr->feature_flag);
-#endif /* H5FD_ALLOC_DEBUG */
- last->size += aggr->size;
- aggr->addr = 0;
- aggr->size = 0;
- } /* end if */
- } /* end if */
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5FD_aggr_adjoin() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_aggr_can_extend
- *
- * Purpose: Check is an aggregator block can be extended
- *
- * Return: Success: Non-negative
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * Thursday, December 13, 2007
- *
- *-------------------------------------------------------------------------
- */
-static htri_t
-H5FD_aggr_can_extend(const H5FD_t *file, const H5FD_blk_aggr_t *aggr, haddr_t eoa,
- haddr_t end)
-{
- htri_t ret_value = FALSE;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_aggr_can_extend)
+ /* Get current end-of-allocated space address */
+ eoa = file->cls->get_eoa(file, type);
- /* Check args */
- HDassert(file);
- HDassert(aggr);
- HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
-
- /* Check if this aggregator is active */
- if(file->feature_flags & aggr->feature_flag) {
- /* If the aggregator block is at the end of the file, and the block to
- * test adjoins the beginning of the aggregator block, then it's
- * extendable
- */
- if((aggr->addr + aggr->size) == eoa && end == aggr->addr)
- HGOTO_DONE(TRUE)
+ /* Compute extra space to allocate, if this is a new block and should be aligned */
+ extra = 0;
+ if(new_block && file->alignment > 1 && orig_size >= file->threshold) {
+ hsize_t mis_align; /* Amount EOA is misaligned */
+
+ /* Check for EOA already aligned */
+ if((mis_align = (eoa % file->alignment)) > 0) {
+ extra = file->alignment - mis_align;
+ if(frag_addr)
+ *frag_addr = eoa - file->base_addr; /* adjust for file's base address */
+ if(frag_size)
+ *frag_size = extra;
+ } /* end if */
} /* end if */
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_aggr_can_extend() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_aggr_extend
- *
- * Purpose: Shift an aggregator block in the file
- *
- * Return: Success: Non-negative
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * Thursday, December 13, 2007
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD_aggr_shift(H5FD_blk_aggr_t *aggr, hsize_t extra)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_aggr_shift)
-
- /* Check args */
- HDassert(aggr);
- HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
-
- /* Shift the aggregator block by the extra amount */
- aggr->addr += extra;
+ /* Add in extra allocation amount */
+ size += extra;
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5FD_aggr_shift() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_aggr_query
- *
- * Purpose: Query a block aggregator's current address & size info
- *
- * Return: Success: Non-negative
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * Thursday, December 13, 2007
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD_aggr_query(const H5FD_t *file, const H5FD_blk_aggr_t *aggr, haddr_t *addr,
- hsize_t *size)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_aggr_query)
-
- /* Check args */
- HDassert(file);
- HDassert(aggr);
- HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
-
- /* Check if this aggregator is active */
- if(file->feature_flags & aggr->feature_flag) {
- *addr = aggr->addr;
- *size = aggr->size;
- } /* end if */
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5FD_aggr_query() */
+ /* Check for overflow when extending */
+ if(H5F_addr_overflow(eoa, size) || (eoa + size) > file->maxaddr)
+ HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed")
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_aggr_reset
- *
- * Purpose: Reset a block aggregator, returning any space back to file
- *
- * Return: Success: Non-negative
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * Thursday, December 13, 2007
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5FD_aggr_reset(H5FD_t *file, H5FD_blk_aggr_t *aggr, hid_t dxpl_id)
-{
- H5FD_mem_t alloc_type; /* Type of file memory to work with */
- herr_t ret_value = SUCCEED; /* Return value */
+ /* Set the [possibly aligned] address to return */
+ ret_value = eoa + extra;
- FUNC_ENTER_NOAPI(H5FD_aggr_reset, FAIL)
+ /* Extend the end-of-allocated space address */
+ eoa += size;
+ if(file->cls->set_eoa(file, type, eoa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed")
- /* Check args */
- HDassert(file);
- HDassert(aggr);
- HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
-
- /* Set the type of memory in the file */
- alloc_type = (aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW); /* Type of file memory to work with */
-
- /* Check if this aggregator is active */
- if(file->feature_flags & aggr->feature_flag) {
- /* Return the unused portion of the metadata block to a free list */
- if(aggr->size > 0)
- if(H5FD_free(file, alloc_type, dxpl_id, aggr->addr, aggr->size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free aggregator block")
-
- /* Reset aggregator block information */
- aggr->tot_size = 0;
- aggr->addr = 0;
- aggr->size = 0;
- } /* end if */
+ /* Post-condition sanity check */
+ if(new_block && file->alignment && orig_size >= file->threshold)
+ HDassert(!(ret_value % file->alignment));
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_aggr_reset() */
+} /* end H5FD_extend() */
/*-------------------------------------------------------------------------
- * Function: H5FD_real_alloc
+ * Function: H5FD_alloc_real
*
- * Purpose: Double private version of H5FDalloc() :-)
+ * Purpose: Allocate space in the file with the VFD
*
- * Return: Success: The format address of the new file memory.
- * Failure: The undefined address HADDR_UNDEF
+ * Return: Success: The format address of the new file memory.
+ * Failure: The undefined address HADDR_UNDEF
*
- * Programmer: Quincey Koziol
- * Friday, August 25, 2000
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
*
*-------------------------------------------------------------------------
*/
-static haddr_t
-H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
+haddr_t
+H5FD_alloc_real(H5FD_t *file, hid_t dxpl_id, H5FD_mem_t type, hsize_t size, haddr_t *frag_addr, hsize_t *frag_size)
{
- haddr_t ret_value = HADDR_UNDEF;
+ haddr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5FD_real_alloc)
+ FUNC_ENTER_NOAPI(H5FD_alloc_real, HADDR_UNDEF)
#ifdef H5FD_ALLOC_DEBUG
HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
#endif /* H5FD_ALLOC_DEBUG */
/* check args */
- assert(file);
- assert(file->cls);
- assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
- assert(size > 0);
-
- /*
- * Dispatch to driver `alloc' callback or extend the end-of-address
- * marker
- */
+ HDassert(file);
+ HDassert(file->cls);
+ HDassert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
+ HDassert(size > 0);
+
+ /* Dispatch to driver `alloc' callback or extend the end-of-address marker */
if(file->cls->alloc) {
if((ret_value = (file->cls->alloc)(file, type, dxpl_id, size)) == HADDR_UNDEF)
HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "driver allocation request failed")
- } else {
- if((ret_value = H5FD_update_eoa(file, type, dxpl_id, size)) == HADDR_UNDEF)
+ } /* end if */
+ else {
+ if((ret_value = H5FD_extend(file, type, TRUE, size, frag_addr, frag_size)) == HADDR_UNDEF)
HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "driver eoa update request failed")
- }
+ } /* end else */
+
+ /* Convert absolute file offset to relative address */
+ ret_value -= file->base_addr;
done:
#ifdef H5FD_ALLOC_DEBUG
HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
#endif /* H5FD_ALLOC_DEBUG */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_real_alloc() */
+} /* end H5FD_alloc_real() */
/*-------------------------------------------------------------------------
- * Function: H5FD_update_eoa
+ * Function: H5FD_alloc
*
- * Purpose: Update the EOA field of the file's memory.
+ * Purpose: Wrapper for H5FD_alloc, to make certain EOA changes are
+ * reflected in superblock.
*
- * This was split off from the H5FD_real_alloc function to
- * make life easier for all.
+ * Note: When the metadata cache routines are updated to allow
+ * marking an entry dirty without a H5F_t*, this routine should
+ * be changed to take a H5F_super_t* directly.
*
* Return: Success: The format address of the new file memory.
* Failure: The undefined address HADDR_UNDEF
*
- * Programmer: Bill Wendling
- * Wednesday, 04. December, 2002
+ * Programmer: Quincey Koziol
+ * Friday, August 14, 2009
*
*-------------------------------------------------------------------------
*/
-static haddr_t
-H5FD_update_eoa(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
+haddr_t
+H5FD_alloc(H5FD_t *file, hid_t dxpl_id, H5FD_mem_t type, H5F_t *f, hsize_t size,
+ haddr_t *frag_addr, hsize_t *frag_size)
{
- haddr_t eoa, oldeoa = 0;
- hsize_t wasted;
- haddr_t ret_value = HADDR_UNDEF;
+ haddr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5FD_update_eoa)
+ FUNC_ENTER_NOAPI(H5FD_alloc, HADDR_UNDEF)
/* check args */
- assert(file);
- assert(file->cls);
- assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
- assert(size > 0);
-
- eoa = file->cls->get_eoa(file, type);
-
-#ifdef H5F_DEBUG
- if(file->alignment * file->threshold != 1 && H5DEBUG(F))
- HDfprintf(H5DEBUG(F),
- "%s: alignment=%Hd, threshold=%Hd, size=%Hd, Begin eoa=%a\n",
- FUNC, file->alignment, file->threshold, size, eoa);
-#endif /* H5F_DEBUG */
-
- /* Wasted is 0 if not exceeding threshold or eoa happens to be aligned */
- wasted = (size >= file->threshold) ? (eoa % file->alignment) : 0;
- if(wasted) {
- wasted = file->alignment - wasted; /* actual waste */
- oldeoa = eoa; /* save it for later freeing */
-
- /* Advance eoa to the next alignment by allocating the wasted */
- if(H5F_addr_overflow(eoa, size) || (eoa + wasted) > file->maxaddr)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed")
-
- eoa += wasted;
-
- if(file->cls->set_eoa(file, type, eoa) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed")
- } /* end if */
-
- /* allocate the aligned memory */
- if(H5F_addr_overflow(eoa, size) || eoa + size > file->maxaddr)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed")
-
- ret_value = eoa;
- eoa += size;
-
- if(file->cls->set_eoa(file, type, eoa) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed")
+ HDassert(file);
+ HDassert(file->cls);
+ HDassert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
+ HDassert(size > 0);
- /* Free the wasted memory */
- if(wasted) {
- if(H5FD_free(file, type, dxpl_id, oldeoa, wasted) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed")
- } /* end if */
+ /* Call the real 'alloc' routine */
+ ret_value = H5FD_alloc_real(file, dxpl_id, type, size, frag_addr, frag_size);
+ if(!H5F_addr_defined(ret_value))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "real 'alloc' request failed")
-#ifdef H5F_DEBUG
- if(file->alignment * file->threshold != 1 && H5DEBUG(F))
- HDfprintf(H5DEBUG(F),
- "%s: ret_value=%a, wasted=%Hd, Ended eoa=%a\n",
- FUNC, ret_value, wasted, eoa);
-#endif /* H5F_DEBUG */
+ /* Mark superblock dirty in cache, so change to EOA will get encoded */
+ if(H5F_super_dirty(f) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTMARKDIRTY, HADDR_UNDEF, "unable to mark superblock as dirty")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_update_eoa() */
+} /* end H5FD_alloc() */
/*-------------------------------------------------------------------------
- * Function: H5FD_free
+ * Function: H5FD_free_real
*
- * Purpose: Private version of H5FDfree()
+ * Purpose: Release space back to the VFD
*
* Return: Success: Non-negative
* Failure: Negative
@@ -1101,246 +291,60 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5FD_free(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size)
+H5FD_free_real(H5FD_t *file, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, hsize_t size)
{
- H5FD_mem_t mapped_type;
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5FD_free, FAIL)
+ FUNC_ENTER_NOAPI_NOINIT(H5FD_free_real)
/* Check args */
HDassert(file);
HDassert(file->cls);
HDassert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
+ HDassert(size > 0);
#ifdef H5FD_ALLOC_DEBUG
HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type, addr, size);
#endif /* H5FD_ALLOC_DEBUG */
- if(!H5F_addr_defined(addr) || addr > file->maxaddr ||
- H5F_addr_overflow(addr, size) || (addr + size) > file->maxaddr)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid region")
+ /* Sanity checking */
+ if(!H5F_addr_defined(addr))
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid file offset")
- /* Allow 0-sized free's to occur without penalty */
- if(0 == size)
- HGOTO_DONE(SUCCEED)
+ /* Convert address to absolute file offset */
+ addr += file->base_addr;
- /* Map request type to free list */
- if(H5FD_MEM_DEFAULT==file->cls->fl_map[type])
- mapped_type = type;
- else
- mapped_type = file->cls->fl_map[type];
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: mapped_type = %u\n", FUNC, (unsigned)mapped_type);
-#endif /* H5FD_ALLOC_DEBUG */
+ /* More sanity checking */
+ if(addr > file->maxaddr || H5F_addr_overflow(addr, size) || (addr + size) > file->maxaddr)
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid file free space region to free")
- /*
- * If the request maps to a free list then add memory to the free list
- * without ever telling the driver that it was freed. Otherwise let the
- * driver deallocate the memory.
- */
- if(mapped_type >= H5FD_MEM_DEFAULT) {
- H5FD_free_t *last; /* Last merged node */
- H5FD_free_t *last_prev = NULL;/* Pointer to node before merged node */
- H5FD_free_t *curr; /* Current free block being inspected */
- H5FD_free_t *prev; /* Previous free block being inspected */
-
- /* Adjust the metadata accumulator to remove the freed block, if it overlaps */
- if((file->feature_flags&H5FD_FEAT_ACCUMULATE_METADATA)
- && H5F_addr_overlap(addr, size, file->accum_loc, file->accum_size)) {
- size_t overlap_size; /* Size of overlap with accumulator */
-
- /* Check for overlapping the beginning of the accumulator */
- if(H5F_addr_le(addr, file->accum_loc)) {
- /* Check for completely overlapping the accumulator */
- if(H5F_addr_ge(addr + size, file->accum_loc + file->accum_size)) {
- /* Reset the entire accumulator */
- file->accum_loc=HADDR_UNDEF;
- file->accum_size=FALSE;
- file->accum_dirty=FALSE;
- } /* end if */
- /* Block to free must end within the accumulator */
- else {
- size_t new_accum_size; /* Size of new accumulator buffer */
-
- /* Calculate the size of the overlap with the accumulator, etc. */
- H5_ASSIGN_OVERFLOW(overlap_size,(addr+size)-file->accum_loc,haddr_t,size_t);
- new_accum_size=file->accum_size-overlap_size;
-
- /* Move the accumulator buffer information to eliminate the freed block */
- HDmemmove(file->meta_accum,file->meta_accum+overlap_size,new_accum_size);
-
- /* Adjust the accumulator information */
- file->accum_loc+=overlap_size;
- file->accum_size=new_accum_size;
- } /* end else */
- } /* end if */
- /* Block to free must start within the accumulator */
- else {
- /* Calculate the size of the overlap with the accumulator */
- H5_ASSIGN_OVERFLOW(overlap_size,(file->accum_loc+file->accum_size)-addr,haddr_t,size_t);
-
- /* Block to free is in the middle of the accumulator */
- if(H5F_addr_lt((addr + size), file->accum_loc + file->accum_size)) {
- haddr_t tail_addr;
- size_t tail_size;
-
- /* Calculate the address & size of the tail to write */
- tail_addr=addr+size;
- H5_ASSIGN_OVERFLOW(tail_size,(file->accum_loc+file->accum_size)-tail_addr,haddr_t,size_t);
-
- /* Write out the part of the accumulator after the block to free */
- /* (Use the driver's write call directly - to avoid looping back and writing to metadata accumulator) */
- if((file->cls->write)(file, H5FD_MEM_DEFAULT, dxpl_id, tail_addr, tail_size, file->meta_accum+(tail_addr-file->accum_loc)) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file write request failed")
- } /* end if */
-
- /* Adjust the accumulator information */
- file->accum_size=file->accum_size-overlap_size;
- } /* end else */
- } /* end if */
-
- /* Scan through the existing blocks for the mapped type to see if we can extend one */
- curr = file->fl[mapped_type];
- last = prev = NULL;
- while(curr != NULL) {
- /* Check if the block to free adjoins the start of the current block */
- if((addr + size) == curr->addr) {
- /* If we previously found & merged a node, eliminate it from the list & free it */
- if(last != NULL) {
- /* Check if there was a previous block in the list */
- if(last_prev != NULL)
- /* Eliminate the merged block from the list */
- last_prev->next = last->next;
- /* No previous block, this must be the head of the list */
- else
- /* Eliminate the merged block from the list */
- file->fl[mapped_type] = last->next;
-
- /* Check for eliminating the block before the 'current' one */
- if(last == prev)
- prev = last_prev;
-
- /* Free the memory for the merged block */
- H5FL_FREE(H5FD_free_t, last);
- } /* end if */
-
- /* Adjust the address and size of the block found */
- curr->addr = addr;
- curr->size += size;
-
- /* Adjust the information about to memory block to include the merged block */
- addr = curr->addr;
- size = curr->size;
-
- /* Update the information about the merged node */
- last = curr;
- last_prev = prev;
- } /* end if */
- else {
- /* Check if the block to free adjoins the end of the current block */
- if((curr->addr + curr->size) == addr) {
- /* If we previously found & merged a node, eliminate it from the list & free it */
- if(last != NULL) {
- /* Check if there was a previous block in the list */
- if(last_prev != NULL)
- /* Eliminate the merged block from the list */
- last_prev->next = last->next;
- /* No previous block, this must be the head of the list */
- else
- /* Eliminate the merged block from the list */
- file->fl[mapped_type] = last->next;
-
- /* Check for eliminating the block before the 'current' one */
- if(last == prev)
- prev = last_prev;
-
- /* Free the memory for the merged block */
- H5FL_FREE(H5FD_free_t, last);
- } /* end if */
-
- /* Adjust the size of the block found */
- curr->size += size;
-
- /* Adjust the information about to memory block to include the merged block */
- addr = curr->addr;
- size = curr->size;
-
- /* Update the information about the merged node */
- last = curr;
- last_prev = prev;
- } /* end if */
- } /* end else */
-
- /* Advance to next node in list */
- prev = curr;
- curr = curr->next;
- } /* end while */
-
- /* Check if we adjusted an existing block */
- if(last != NULL) {
- /* Move the node found to the front, if it wasn't already there */
- if(last_prev != NULL) {
- last_prev->next = last->next;
- last->next = file->fl[mapped_type];
- file->fl[mapped_type] = last;
- } /* end if */
- } /* end if */
- else {
- /* Allocate a new node to hold the free block's information */
- if(NULL == (last = H5FL_MALLOC(H5FD_free_t)))
- HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate node for free space info")
-
- last->addr = addr;
- last->size = size;
- last->next = file->fl[mapped_type];
- file->fl[mapped_type] = last;
- } /* end else */
+ /* Check for file driver 'free' callback and call it if available */
+ if(file->cls->free) {
#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: mapped_type = %u, last = {%a, %Hu}\n", FUNC, (unsigned)mapped_type, last->addr, last->size);
+HDfprintf(stderr, "%s: Letting VFD free space\n", FUNC);
#endif /* H5FD_ALLOC_DEBUG */
+ if((file->cls->free)(file, type, dxpl_id, addr, size) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "driver free request failed")
+ } /* end if */
+ /* Check if this free block is at the end of file allocated space.
+ * Truncate it if this is true.
+ */
+ else if(file->cls->get_eoa) {
+ haddr_t eoa;
- /* Check if we increased the size of the largest block on the list */
- file->maxsize = MAX(file->maxsize, last->size);
-
- /* Check if this free block adjoins the "metadata aggregator" */
- if(H5FD_aggr_adjoin(file, &(file->meta_aggr), last) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "aggregator deallocation request failed")
-
- /* Check if this free block adjoins the "small data aggregator" */
- if(H5FD_aggr_adjoin(file, &(file->sdata_aggr), last) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "aggregator deallocation request failed")
-
- /* Check if this free block is at the end of file allocated space.
- * Truncate it if this is true. */
- if(file->cls->get_eoa) {
- haddr_t eoa;
-
- eoa = file->cls->get_eoa(file, type);
+ eoa = file->cls->get_eoa(file, type);
#ifdef H5FD_ALLOC_DEBUG
HDfprintf(stderr, "%s: eoa = %a\n", FUNC, eoa);
#endif /* H5FD_ALLOC_DEBUG */
- if(eoa == (last->addr + last->size)) {
+ if(eoa == (addr + size)) {
#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Reducing file size to = %a\n", FUNC, last->addr);
+HDfprintf(stderr, "%s: Reducing file size to = %a\n", FUNC, addr);
#endif /* H5FD_ALLOC_DEBUG */
- if(file->cls->set_eoa(file, type, last->addr) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "set end of space allocation request failed")
-
- /* Remove this free block from the list */
- file->fl[mapped_type] = last->next;
- if(file->maxsize == last->size)
- file->maxsize = 0; /*unknown*/
- H5FL_FREE(H5FD_free_t, last);
- } /* end if */
+ if(file->cls->set_eoa(file, type, addr) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "set end of space allocation request failed")
} /* end if */
- } else if(file->cls->free) {
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Letting VFD free space\n", FUNC);
-#endif /* H5FD_ALLOC_DEBUG */
- if((file->cls->free)(file, type, dxpl_id, addr, size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver free request failed")
- } else {
+ } /* end else-if */
+ else {
/* leak memory */
#ifdef H5FD_ALLOC_DEBUG
HDfprintf(stderr, "%s: LEAKED MEMORY!!! type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type, addr, size);
@@ -1349,390 +353,110 @@ HDfprintf(stderr, "%s: LEAKED MEMORY!!! type = %u, addr = %a, size = %Hu\n", FUN
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_free() */
+} /* end H5FD_free_real() */
/*-------------------------------------------------------------------------
- * Function: H5FD_realloc
- *
- * Purpose: Private version of H5FDrealloc()
- *
- * Return: Success: New address of the block of memory, not
- * necessarily the same as the original address.
- * Failure: HADDR_UNDEF
- *
- * Programmer: Robb Matzke
- * Wednesday, August 4, 1999
- *
- *-------------------------------------------------------------------------
- */
-haddr_t
-H5FD_realloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsize_t old_size,
- hsize_t new_size)
-{
- haddr_t new_addr=old_addr;
- uint8_t _buf[8192];
- uint8_t *buf=_buf;
- haddr_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_realloc, HADDR_UNDEF)
-
- if(new_size == old_size) {
- /*nothing to do*/
- } else if(0 == old_size) {
- /* allocate memory */
- HDassert(!H5F_addr_defined(old_addr));
- if(HADDR_UNDEF == (new_addr = H5FD_alloc(file, type, dxpl_id, new_size)))
- HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed")
- } else if(0==new_size) {
- /* free memory */
- HDassert(H5F_addr_defined(old_addr));
- if(H5FD_free(file, type, dxpl_id, old_addr, old_size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed")
- new_addr = HADDR_UNDEF;
- } else if(new_size<old_size) {
- /* free the end of the block */
- if(H5FD_free(file, type, dxpl_id, old_addr+old_size, old_size-new_size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed")
- } else {
- /* move memory to new location */
- /* Note! This may fail if sizeof(hsize_t)>sizeof(size_t) and the
- * object on disk is too large to read into a memory buffer all at one
- * time. This chunk of code would have to be re-written using a loop
- * to move pieces of the realloced data through a fixed size buffer, etc.
- * -QAK, 6/20/01
- */
- if(HADDR_UNDEF == (new_addr = H5FD_alloc(file, type, dxpl_id, new_size)))
- HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed")
- H5_CHECK_OVERFLOW(old_size,hsize_t,size_t);
- if(old_size > sizeof(_buf) && NULL == (buf = H5MM_malloc((size_t)old_size))) {
- (void)H5FD_free(file, type, dxpl_id, new_addr, new_size);
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "memory allocation failed")
- } /* end if */
- if(H5FD_read(file, type, dxpl_id, old_addr, (size_t)old_size, buf) < 0 ||
- H5FD_write(file, type, dxpl_id, new_addr, (size_t)old_size, buf) < 0) {
- (void)H5FD_free(file, type, dxpl_id, new_addr, new_size);
- if(buf != _buf)
- H5MM_xfree(buf);
- HGOTO_ERROR(H5E_FILE, H5E_READERROR, HADDR_UNDEF, "unable to move file block")
- } /* end if */
-
- if(buf != _buf)
- H5MM_xfree(buf);
- if(H5FD_free(file, type, dxpl_id, old_addr, old_size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed")
- } /* end else */
-
- /* Set return value */
- ret_value = new_addr;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_realloc() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_can_extend
- *
- * Purpose: Check if a block in the file can be extended.
- *
- * Return: Success: TRUE(1)/FALSE(0)
- * Failure: FAIL
- *
- * Programmer: Quincey Koziol
- * Friday, June 11, 2004
+ * Function: H5FD_free
*
- *-------------------------------------------------------------------------
- */
-htri_t
-H5FD_can_extend(const H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested)
-{
- haddr_t end; /* End of block in file */
- haddr_t eoa; /* End of address space in the file */
- htri_t ret_value = FALSE; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_can_extend, FAIL)
-
- /* Retrieve the end of the address space */
- if(HADDR_UNDEF == (eoa = H5FD_get_eoa(file, type)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver get_eoa request failed")
-
- /* Compute end of block */
- end = addr + size;
-
- /* Check if the block is exactly at the end of the file */
- if(end == eoa)
- HGOTO_DONE(TRUE)
- else {
- H5FD_free_t *curr; /* Current free block being inspected */
- H5FD_mem_t mapped_type; /* Memory type, after mapping */
-
- /* Map request type to free list */
- if(H5FD_MEM_DEFAULT==file->cls->fl_map[type])
- mapped_type = type;
- else
- mapped_type = file->cls->fl_map[type];
-
- /* Check if block is inside the metadata or small data aggregator */
- if(mapped_type!=H5FD_MEM_DRAW) {
- /* Check for test block able to extend metadata aggregation block */
- if((ret_value = H5FD_aggr_can_extend(file, &(file->meta_aggr), eoa, end)) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't determine if metadata aggregation block can be extended")
- else if(ret_value > 0)
- HGOTO_DONE(TRUE)
- } /* end if */
- else {
- /* Check for test block able to extend metadata aggregation block */
- if((ret_value = H5FD_aggr_can_extend(file, &(file->sdata_aggr), eoa, end)) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't determine if 'small data' aggregation block can be extended")
- else if(ret_value > 0)
- HGOTO_DONE(TRUE)
- } /* end else */
-
- /* Scan through the existing blocks for the mapped type to see if we can extend one */
- if(mapped_type >= H5FD_MEM_DEFAULT) {
- curr = file->fl[mapped_type];
- while(curr != NULL) {
- if(end == curr->addr) {
- if(extra_requested <= curr->size)
- HGOTO_DONE(TRUE)
- else
- HGOTO_DONE(FALSE)
- } /* end if */
-
- /* Advance to next node in list */
- curr=curr->next;
- } /* end while */
- } /* end if */
- } /* end else */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_can_extend() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_extend
+ * Purpose: Wrapper for H5FD_free_real, to make certain EOA changes are
+ * reflected in superblock.
*
- * Purpose: Extend a block in the file.
+ * Note: When the metadata cache routines are updated to allow
+ * marking an entry dirty without a H5F_t*, this routine should
+ * be changed to take a H5F_super_t* directly.
*
- * Return: Success: Non-negative
- * Failure: Negative
+ * Return: Success: Non-negative
+ * Failure: Negative
*
- * Programmer: Quincey Koziol
- * Saturday, June 12, 2004
+ * Programmer: Quincey Koziol
+ * Friday, August 14, 2009
*
*-------------------------------------------------------------------------
*/
herr_t
-H5FD_extend(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested)
+H5FD_free(H5FD_t *file, hid_t dxpl_id, H5FD_mem_t type, H5F_t *f, haddr_t addr,
+ hsize_t size)
{
- haddr_t eoa; /* End of address space in the file */
- haddr_t end; /* End of block in file */
- hbool_t update_eoma=FALSE; /* Whether we need to update the eoma */
- hbool_t update_eosda=FALSE; /* Whether we need to update the eosda */
- hbool_t at_end=FALSE; /* Block is at end of file */
- H5FD_mem_t mapped_type; /* Memory type, after mapping */
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_extend, FAIL)
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu, extra_requested = %Hu\n", FUNC, (unsigned)type, addr, size, extra_requested);
-#endif /* H5FD_ALLOC_DEBUG */
-
- /* Retrieve the end of the address space */
- if(HADDR_UNDEF==(eoa=H5FD_get_eoa(file, type)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver get_eoa request failed")
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Map request type to free list */
- if(H5FD_MEM_DEFAULT==file->cls->fl_map[type])
- mapped_type = type;
- else
- mapped_type = file->cls->fl_map[type];
+ FUNC_ENTER_NOAPI(H5FD_free, FAIL)
- /* Compute end of block */
- end = addr + size;
+ /* Check args */
+ HDassert(file);
+ HDassert(file->cls);
+ HDassert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
+ HDassert(size > 0);
- /* Check if the block is exactly at the end of the file */
- if(end == eoa)
- at_end = TRUE;
- else {
- /* (Check if block is inside the metadata or small data accumulator) */
- if(mapped_type!=H5FD_MEM_DRAW) {
- /* Check for test block able to extend metadata aggregation block */
- if((ret_value = H5FD_aggr_can_extend(file, &(file->meta_aggr), eoa, end)) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't determine if metadata aggregation block can be extended")
- else if(ret_value > 0)
- update_eoma = TRUE;
- } /* end if */
- else {
- /* Check for test block able to extend metadata aggregation block */
- if((ret_value = H5FD_aggr_can_extend(file, &(file->sdata_aggr), eoa, end)) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't determine if metadata aggregation block can be extended")
- else if(ret_value > 0)
- update_eosda = TRUE;
- } /* end else */
- } /* end else */
+ /* Call the real 'free' routine */
+ if(H5FD_free_real(file, dxpl_id, type, addr, size) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "real 'free' request failed")
- /* Block is at end of file, we are extending the eoma or eosda */
- if(update_eoma || update_eosda || at_end) {
- /* Check for overflowing the file */
- if(H5F_addr_overflow(eoa, extra_requested) || eoa + extra_requested > file->maxaddr)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "file allocation request failed")
-
- /* Extend the file */
- eoa += extra_requested;
- if(file->cls->set_eoa(file, type, eoa) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "file allocation request failed")
-
- /* Update the metadata and/or small data block */
- HDassert(!(update_eoma && update_eosda));
- if(update_eoma)
- H5FD_aggr_shift(&(file->meta_aggr), extra_requested);
- if(update_eosda)
- H5FD_aggr_shift(&(file->sdata_aggr), extra_requested);
- } /* end if */
- /* If the block we are extending isn't at the end of the file, find a free block to extend into */
- else {
- H5FD_free_t *curr; /* Current free block being inspected */
- H5FD_free_t *prev; /* Current free block being inspected */
-
- /* Walk through free list, looking for block to merge with */
- curr = file->fl[mapped_type];
- prev = NULL;
- while(curr!=NULL) {
- /* Found block that ajoins end of block to extend */
- if(end == curr->addr) {
- /* Check if free space is large enough */
- if(extra_requested <= curr->size) {
- /* Check for exact match */
- if(extra_requested == curr->size) {
- /* Unlink node from free list */
- if(prev == NULL)
- file->fl[mapped_type] = curr->next;
- else
- prev->next = curr->next;
-
- /* Free the memory for the used block */
- H5FL_FREE(H5FD_free_t, curr);
- } /* end if */
- else {
- curr->addr += extra_requested;
- curr->size -= extra_requested;
- } /* end else */
-
- /* Leave now */
- break;
- } /* end if */
- else
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "can't extend block")
- } /* end if */
-
- /* Advance to next node in list */
- prev = curr;
- curr = curr->next;
- } /* end while */
-
- /* Couldn't find block to extend */
- if(curr == NULL)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "can't extend block")
- } /* end else */
+ /* Mark superblock dirty in cache, so change to EOA will get encoded */
+ if(H5F_super_dirty(f) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_extend() */
+} /* end H5FD_free() */
/*-------------------------------------------------------------------------
- * Function: H5FD_get_freespace
+ * Function: H5FD_try_extend
*
- * Purpose: Retrieve the amount of free space in a file.
+ * Purpose: Extend a block at the end of the file, if possible.
*
- * Return: Success: Amount of free space in file
- * Failure: Negative
+ * Note: When the metadata cache routines are updated to allow
+ * marking an entry dirty without a H5F_t*, this routine should
+ * be changed to take a H5F_super_t* directly.
+ *
+ * Return: Success: TRUE(1) - Block was extended
+ * FALSE(0) - Block could not be extended
+ * Failure: FAIL
*
* Programmer: Quincey Koziol
- * Monday, October 6, 2003
+ * Thursday, 17. January, 2008
*
- * Note:
- * Raymond Lu
- * 5 January 2007
- * Due to the complexity EOA for Multi driver, this function
- * is made failed for now.
- *
*-------------------------------------------------------------------------
*/
-hssize_t
-H5FD_get_freespace(const H5FD_t *file)
+htri_t
+H5FD_try_extend(H5FD_t *file, H5FD_mem_t type, H5F_t *f, haddr_t blk_end,
+ hsize_t extra_requested)
{
- H5FD_free_t *free_node; /* Pointer to node on free list */
- H5FD_mem_t type; /* Type of memory */
- haddr_t ma_addr = HADDR_UNDEF; /* Base "metadata aggregator" address */
- hsize_t ma_size = 0; /* Size of "metadata aggregator" */
- haddr_t sda_addr = HADDR_UNDEF; /* Base "small data aggregator" address */
- hsize_t sda_size = 0; /* Size of "small data aggregator" */
- haddr_t eoa = 0; /* End of allocated space in the file */
- hssize_t ret_value = 0; /* Return value */
+ haddr_t eoa; /* End of allocated space in file */
+ htri_t ret_value = FALSE; /* Return value */
- FUNC_ENTER_NOAPI(H5FD_get_freespace, FAIL)
+ FUNC_ENTER_NOAPI(H5FD_try_extend, FAIL)
/* check args */
HDassert(file);
HDassert(file->cls);
+ HDassert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
+ HDassert(extra_requested > 0);
+ HDassert(f);
- /* Multi driver doesn't support this function because of the complexity.
- * It doesn't have eoa for the whole file. */
- if(file->driver_id == H5FD_MULTI)
- HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "Multi driver doesn't support this function")
-
- /* Retrieve the 'eoa' for the file */
- eoa = file->cls->get_eoa(file, H5FD_MEM_DEFAULT);
-
- /* Retrieve metadata aggregator info, if available */
- H5FD_aggr_query(file, &(file->meta_aggr), &ma_addr, &ma_size);
-
- /* Retrieve 'small data' aggregator info, if available */
- H5FD_aggr_query(file, &(file->sdata_aggr), &sda_addr, &sda_size);
-
- /* Iterate over all the types of memory, to retrieve amount of free space for each */
- for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t,type)) {
- /* Iterate through the free list, accumulating the amount of free space for this type */
- free_node = file->fl[type];
- while(free_node) {
- /* Check for current node adjoining the metadata & small data aggregators */
- if(H5F_addr_eq(free_node->addr + free_node->size, ma_addr)) {
- ma_addr -= free_node->size;
- ma_size += free_node->size;
- } else if(H5F_addr_eq(free_node->addr + free_node->size, sda_addr)) {
- sda_addr -= free_node->size;
- sda_size += free_node->size;
- } else if(H5F_addr_eq(ma_addr + ma_size, free_node->addr))
- ma_size += free_node->size;
- else if(H5F_addr_eq(sda_addr + sda_size, free_node->addr))
- sda_size += free_node->size;
- else
- ret_value += (hssize_t)free_node->size;
- free_node = free_node->next;
- } /* end while */
- } /* end for */
-
- /* Check for aggregating metadata allocations */
- if(ma_size > 0) {
- /* Add in the reserved space for metadata to the available free space */
- /* (if it's not at the tail of the file) */
- if(H5F_addr_ne(ma_addr + ma_size, eoa))
- ret_value += ma_size;
- } /* end if */
+ /* Retrieve the end of the address space */
+ if(HADDR_UNDEF == (eoa = file->cls->get_eoa(file, type)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "driver get_eoa request failed")
- /* Check for aggregating small data allocations */
- if(sda_size > 0) {
- /* Add in the reserved space for metadata to the available free space */
- /* (if it's not at the tail of the file) */
- if(H5F_addr_ne(sda_addr + sda_size, eoa))
- ret_value += sda_size;
+ /* Adjust block end by base address of the file, to create absolute address */
+ blk_end += file->base_addr;
+
+ /* Check if the block is exactly at the end of the file */
+ if(H5F_addr_eq(blk_end, eoa)) {
+ /* Extend the object by extending the underlying file */
+ if(HADDR_UNDEF == H5FD_extend(file, type, FALSE, extra_requested, NULL, NULL))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTEXTEND, FAIL, "driver extend request failed")
+
+ /* Mark superblock dirty in cache, so change to EOA will get encoded */
+ if(H5F_super_dirty(f) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty")
+
+ /* Indicate success */
+ HGOTO_DONE(TRUE)
} /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_get_freespace() */
+} /* end H5FD_try_extend() */
diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c
index c66b1ab..7fffbd4 100644
--- a/src/H5FDstdio.c
+++ b/src/H5FDstdio.c
@@ -147,8 +147,10 @@ typedef struct H5FD_stdio_t {
#define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \
HADDR_UNDEF==(A)+(Z) || (file_offset_t)((A)+(Z))<(file_offset_t)(A))
+#ifndef H5_HAVE_FSEEKO
/* Define big file as 2GB */
#define BIG_FILE 0x80000000UL
+#endif
/* Prototypes */
static H5FD_t *H5FD_stdio_open(const char *name, unsigned flags,
@@ -166,6 +168,7 @@ static herr_t H5FD_stdio_read(H5FD_t *lf, H5FD_mem_t type, hid_t fapl_id, haddr_
static herr_t H5FD_stdio_write(H5FD_t *lf, H5FD_mem_t type, hid_t fapl_id, haddr_t addr,
size_t size, const void *buf);
static herr_t H5FD_stdio_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing);
+static herr_t H5FD_stdio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
static const H5FD_class_t H5FD_stdio_g = {
"stdio", /*name */
@@ -185,6 +188,7 @@ static const H5FD_class_t H5FD_stdio_g = {
H5FD_stdio_close, /*close */
H5FD_stdio_cmp, /*cmp */
H5FD_stdio_query, /*query */
+ NULL, /*get_type_map */
H5FD_stdio_alloc, /*alloc */
NULL, /*free */
H5FD_stdio_get_eoa, /*get_eoa */
@@ -194,6 +198,7 @@ static const H5FD_class_t H5FD_stdio_g = {
H5FD_stdio_read, /*read */
H5FD_stdio_write, /*write */
H5FD_stdio_flush, /*flush */
+ H5FD_stdio_truncate, /*truncate */
NULL, /*lock */
NULL, /*unlock */
H5FD_FLMAP_SINGLE /*fl_map */
@@ -370,8 +375,10 @@ H5FD_stdio_open( const char *name, unsigned flags, hid_t fapl_id,
H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_CANTOPENFILE, "fopen failed", NULL)
/* Build the return value */
- if(NULL==(file = calloc((size_t)1, sizeof(H5FD_stdio_t))))
+ if(NULL == (file = (H5FD_stdio_t *)calloc((size_t)1, sizeof(H5FD_stdio_t)))) {
+ fclose(f);
H5Epush_ret(func, H5E_ERR_CLS, H5E_RESOURCE, H5E_NOSPACE, "memory allocation failed", NULL)
+ } /* end if */
file->fp = f;
file->op = H5FD_STDIO_OP_SEEK;
file->pos = HADDR_UNDEF;
@@ -539,8 +546,8 @@ H5FD_stdio_query(const H5FD_t *_f, unsigned long *flags /* out */)
/*-------------------------------------------------------------------------
* Function: H5FD_stdio_alloc
*
- * Purpose: Allocates file memory. If fseeko isn't available, makes
- * sure the file size isn't bigger than 2GB because the
+ * Purpose: Allocates file memory. If fseeko isn't available, makes
+ * sure the file size isn't bigger than 2GB because the
* parameter OFFSET of fseek is of the type LONG INT, limiting
* the file size to 2GB.
*
@@ -560,7 +567,9 @@ H5FD_stdio_alloc(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxp
{
H5FD_stdio_t *file = (H5FD_stdio_t*)_file;
haddr_t addr;
+#ifndef H5_HAVE_FSEEKO
static const char *func = "H5FD_stdio_alloc"; /* Function Name for error reporting */
+#endif
haddr_t ret_value; /* Return value */
/* Shut compiler up */
@@ -584,7 +593,7 @@ H5FD_stdio_alloc(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxp
/* If fseeko isn't available, big files (>2GB) won't be supported. */
if((addr + size) > BIG_FILE)
H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "can't write file bigger than 2GB because fseeko isn't available", HADDR_UNDEF)
-#endif
+#endif
file->eoa = addr + size;
@@ -943,19 +952,63 @@ H5FD_stdio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr,
* Programmer: Robb Matzke
* Wednesday, October 22, 1997
*
- * Modifications:
- * Ported to VFL/H5FD layer - QAK, 10/18/99
- *
*-------------------------------------------------------------------------
*/
static herr_t
H5FD_stdio_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing)
{
H5FD_stdio_t *file = (H5FD_stdio_t*)_file;
- static const char *func="H5FD_stdio_flush"; /* Function Name for error reporting */
+ static const char *func = "H5FD_stdio_flush"; /* Function Name for error reporting */
/* Shut compiler up */
- dxpl_id=dxpl_id;
+ dxpl_id = dxpl_id;
+
+ /* Clear the error stack */
+ H5Eclear2(H5E_DEFAULT);
+
+ /* Only try to flush the file if we have write access */
+ if(file->write_access) {
+ /* Flush */
+ if(!closing) {
+ if(fflush(file->fp) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "fflush failed", -1)
+
+ /* Reset last file I/O information */
+ file->pos = HADDR_UNDEF;
+ file->op = H5FD_STDIO_OP_UNKNOWN;
+ } /* end if */
+ } /* end if */
+
+ return(0);
+} /* end H5FD_stdio_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_stdio_truncate
+ *
+ * Purpose: Makes sure that the true file size is the same (or larger)
+ * than the end-of-address.
+ *
+ * Errors:
+ * IO SEEKERROR fseek failed.
+ * IO WRITEERROR fflush or fwrite failed.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, January 31, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_stdio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing)
+{
+ H5FD_stdio_t *file = (H5FD_stdio_t*)_file;
+ static const char *func = "H5FD_stdio_truncate"; /* Function Name for error reporting */
+
+ /* Shut compiler up */
+ dxpl_id = dxpl_id;
+ closing = closing;
/* Clear the error stack */
H5Eclear2(H5E_DEFAULT);
@@ -963,9 +1016,10 @@ H5FD_stdio_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing)
/* Only try to flush the file if we have write access */
if(file->write_access) {
/* Makes sure that the true file size is the same as the end-of-address. */
- if (file->eoa!=file->eof) {
+ if(file->eoa != file->eof) {
+ int fd = fileno(file->fp); /* File descriptor for HDF5 file */
+
#ifdef _WIN32
- int fd=_fileno(file->fp); /* File descriptor for HDF5 file */
HFILE filehandle; /* Windows file handle */
LARGE_INTEGER li; /* 64-bit integer for SetFilePointer() call */
@@ -975,14 +1029,16 @@ H5FD_stdio_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing)
/* Translate 64-bit integers into form Windows wants */
/* [This algorithm is from the Windows documentation for SetFilePointer()] */
li.QuadPart = (LONGLONG)file->eoa;
- (void)SetFilePointer((HANDLE)filehandle,li.LowPart,&li.HighPart,FILE_BEGIN);
- if(SetEndOfFile((HANDLE)filehandle)==0)
- H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "unable to extend file properly", -1)
+ (void)SetFilePointer((HANDLE)filehandle, li.LowPart, &li.HighPart, FILE_BEGIN);
+ if(SetEndOfFile((HANDLE)filehandle) == 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "unable to truncate/extend file properly", -1)
#else /* _WIN32 */
- int fd=fileno(file->fp); /* File descriptor for HDF5 file */
+ /* Reset seek offset to beginning of file, so that file isn't re-extended later */
+ rewind(file->fp);
- if (-1==file_truncate(fd, (file_offset_t)file->eoa))
- H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "unable to extend file properly", -1)
+ /* Truncate file to proper length */
+ if(-1 == file_truncate(fd, (file_offset_t)file->eoa))
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "unable to truncate/extend file properly", -1)
#endif /* _WIN32 */
/* Update the eof value */
@@ -992,23 +1048,15 @@ H5FD_stdio_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing)
file->pos = HADDR_UNDEF;
file->op = H5FD_STDIO_OP_UNKNOWN;
} /* end if */
-
- /*
- * Flush
- */
- if(!closing) {
- if (fflush(file->fp) < 0)
- H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "fflush failed", -1)
- } /* end if */
} /* end if */
else {
/* Double-check for problems */
- if (file->eoa>file->eof)
+ if(file->eoa > file->eof)
H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_TRUNCATED, "eoa>eof!", -1)
} /* end else */
return(0);
-}
+} /* end H5FD_stdio_truncate() */
#ifdef _H5private_H
@@ -1019,3 +1067,4 @@ H5FD_stdio_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing)
*/
#error "Do not use HDF5 private definitions"
#endif
+
diff --git a/src/H5FDwindows.c b/src/H5FDwindows.c
index 08a8e69..aca03c8 100644
--- a/src/H5FDwindows.c
+++ b/src/H5FDwindows.c
@@ -20,11 +20,11 @@
*
* Purpose: We would like to create a driver specifically for Windows
* to utilize the Win32 API, and reduce the maintenence demands
- * for the other file drivers. Our other motivation is that
+ * for the other file drivers. Our other motivation is that
* the Windows system calls of the existing sec2 driver differ
* from those on other platforms, and are not 64-bit compatible.
- * From the start, this will have the structure very similar
- * to our sec2 driver, but make system calls more similar to
+ * From the start, this will have the structure very similar
+ * to our sec2 driver, but make system calls more similar to
* our stdio driver.
*/
@@ -66,7 +66,7 @@ static hid_t H5FD_WINDOWS_g = 0;
*/
typedef struct H5FD_windows_t {
H5FD_t pub; /*public stuff, must be first */
- /*
+ /*
* .NET doesn't support our 64-bit safe stdio functions,
* so we will use io.h functions instead.
*/
@@ -91,12 +91,16 @@ typedef struct H5FD_windows_t {
*/
DWORD fileindexlo;
DWORD fileindexhi;
- DWORD volumeserialnumber;
+ DWORD volumeserialnumber;
+
+ /* Information from properties set by 'h5repart' tool */
+ hbool_t fam_to_sec2; /* Whether to eliminate the family driver info
+ * and convert this file to a single file */
} H5FD_windows_t;
/* These are used by the macros below */
-#define file_offset_t __int64
+#define file_offset_t __int64
#define fseek_offset_t __int64
/*
@@ -128,7 +132,7 @@ static H5FD_t *H5FD_windows_open(const char *name, unsigned flags, hid_t fapl_id
static herr_t H5FD_windows_close(H5FD_t *_file);
static int H5FD_windows_cmp(const H5FD_t *_f1, const H5FD_t *_f2);
static herr_t H5FD_windows_query(const H5FD_t *_f1, unsigned long *flags);
-static haddr_t H5FD_windows_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id,
+static haddr_t H5FD_windows_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id,
hsize_t size);
static haddr_t H5FD_windows_get_eoa(const H5FD_t *_file, H5FD_mem_t type);
static herr_t H5FD_windows_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr);
@@ -139,11 +143,12 @@ static herr_t H5FD_windows_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, h
static herr_t H5FD_windows_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr,
size_t size, const void *buf);
static herr_t H5FD_windows_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing);
+static herr_t H5FD_windows_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
static const H5FD_class_t H5FD_windows_g = {
- "windows", /*name */
- MAXADDR, /*maxaddr */
- H5F_CLOSE_WEAK, /* fc_degree */
+ "windows", /*name */
+ MAXADDR, /*maxaddr */
+ H5F_CLOSE_WEAK, /* fc_degree */
NULL, /*sb_size */
NULL, /*sb_encode */
NULL, /*sb_decode */
@@ -154,22 +159,24 @@ static const H5FD_class_t H5FD_windows_g = {
0, /*dxpl_size */
NULL, /*dxpl_copy */
NULL, /*dxpl_free */
- H5FD_windows_open, /*open */
- H5FD_windows_close, /*close */
- H5FD_windows_cmp, /*cmp */
- H5FD_windows_query, /*query */
+ H5FD_windows_open, /*open */
+ H5FD_windows_close, /*close */
+ H5FD_windows_cmp, /*cmp */
+ H5FD_windows_query, /*query */
+ NULL, /*get_type_map */
NULL, /*alloc */
NULL, /*free */
- H5FD_windows_get_eoa, /*get_eoa */
- H5FD_windows_set_eoa, /*set_eoa */
- H5FD_windows_get_eof, /*get_eof */
- H5FD_windows_get_handle,/*get_handle */
- H5FD_windows_read, /*read */
- H5FD_windows_write, /*write */
- H5FD_windows_flush, /*flush */
- NULL, /*lock */
- NULL, /*unlock */
- H5FD_FLMAP_SINGLE /*fl_map */
+ H5FD_windows_get_eoa, /*get_eoa */
+ H5FD_windows_set_eoa, /*set_eoa */
+ H5FD_windows_get_eof, /*get_eof */
+ H5FD_windows_get_handle, /*get_handle */
+ H5FD_windows_read, /*read */
+ H5FD_windows_write, /*write */
+ H5FD_windows_flush, /*flush */
+ H5FD_windows_truncate, /*truncate */
+ NULL, /*lock */
+ NULL, /*unlock */
+ H5FD_FLMAP_SINGLE /*fl_map */
};
/* Declare a free list to manage the H5FD_windows_t struct */
@@ -219,7 +226,7 @@ H5FD_windows_init(void)
FUNC_ENTER_NOAPI(H5FD_windows_init, FAIL)
if(H5I_VFL != H5I_get_type(H5FD_WINDOWS_g))
- H5FD_WINDOWS_g = H5FD_register(&H5FD_windows_g, sizeof(H5FD_class_t));
+ H5FD_WINDOWS_g = H5FD_register(&H5FD_windows_g, sizeof(H5FD_class_t), FALSE);
/* Set return value */
ret_value = H5FD_WINDOWS_g;
@@ -346,7 +353,7 @@ H5FD_windows_open(const char *name, unsigned flags, hid_t UNUSED fapl_id,
if (H5F_ACC_CREAT & flags) o_flags |= O_CREAT;
if (H5F_ACC_EXCL & flags) o_flags |= O_EXCL;
/* Windows needs O_BINARY to correctly handle eol characters */
- o_flags |= O_BINARY;
+ o_flags |= O_BINARY;
/* Open the file */
if ((fd=_open(name, o_flags, 0666))<0)
@@ -388,7 +395,7 @@ H5FD_windows_open(const char *name, unsigned flags, hid_t UNUSED fapl_id,
H5_ASSIGN_OVERFLOW(file->eof,sb.st_size,h5_stat_size_t,haddr_t);
file->pos = HADDR_UNDEF;
file->op = OP_UNKNOWN;
-
+
#ifndef WINDOWS_USE_STDIO
file->fd = fd;
#else
@@ -398,13 +405,31 @@ H5FD_windows_open(const char *name, unsigned flags, hid_t UNUSED fapl_id,
file->write_access=write_access; /* Note the write_access for later */
#endif /* WINDOWS_USE_STDIO */
- if( (filehandle = (HANDLE)_get_osfhandle(fd)) == INVALID_HANDLE_VALUE)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get file handle for file")
+ if( (filehandle = (HANDLE)_get_osfhandle(fd)) == INVALID_HANDLE_VALUE)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get file handle for file")
if(!GetFileInformationByHandle(filehandle, &fileinfo))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get file information")
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get file information")
file->fileindexhi = fileinfo.nFileIndexHigh;
file->fileindexlo = fileinfo.nFileIndexLow;
- file->volumeserialnumber = fileinfo.dwVolumeSerialNumber;
+ file->volumeserialnumber = fileinfo.dwVolumeSerialNumber;
+
+ /* Check for non-default FAPL */
+ if(H5P_FILE_ACCESS_DEFAULT != fapl_id) {
+ H5P_genplist_t *plist; /* Property list pointer */
+
+ /* Get the FAPL */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
+ HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, NULL, "not a file access property list")
+
+ /* This step is for h5repart tool only. If user wants to change file driver from
+ * family to sec2 while using h5repart, this private property should be set so that
+ * in the later step, the library can ignore the family driver information saved
+ * in the superblock.
+ */
+ if(H5P_exist_plist(plist, H5F_ACS_FAMILY_TO_SEC2_NAME) > 0)
+ if(H5P_get(plist, H5F_ACS_FAMILY_TO_SEC2_NAME, &file->fam_to_sec2) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get property of changing family to sec2")
+ } /* end if */
/* Set return value */
ret_value=(H5FD_t*)file;
@@ -517,17 +542,14 @@ done:
Based on code by Quincey Koziol
* Thursday, May 24 2007
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
-/* ARGSUSED */
static herr_t
-H5FD_windows_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */)
+H5FD_windows_query(const H5FD_t *_file, unsigned long *flags /* out */)
{
- herr_t ret_value=SUCCEED;
+ const H5FD_windows_t *file = (const H5FD_windows_t*)_file; /* windows VFD info */
- FUNC_ENTER_NOAPI(H5FD_windows_query, FAIL)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_windows_query)
/* Set the VFL feature flags that this driver supports */
if(flags) {
@@ -536,11 +558,15 @@ H5FD_windows_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */)
*flags|=H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */
*flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
*flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
- }
+
+ /* Check for flags that are set by h5repart */
+ if(file->fam_to_sec2)
+ *flags |= H5FD_FEAT_IGNORE_DRVRINFO; /* Ignore the driver info when file is opened (which eliminates it) */
+ } /* end if */
done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5FD_windows_query() */
/*-------------------------------------------------------------------------
* Function: H5FD_windows_get_eoa
@@ -815,7 +841,7 @@ H5FD_windows_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
/* end of file but not end of format address space */
HDmemset(buf, 0, size);
break;
- }
+ }
}
#endif /* WINDOWS_USE_STDIO */
assert(nbytes>=0);
@@ -941,22 +967,20 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
}
+
/*-------------------------------------------------------------------------
* Function: H5FD_windows_flush
*
* Purpose: Makes sure that the true file size is the same (or larger)
- * than the end-of-address.
+ * than the end-of-address.
*
* Return: Success: Non-negative
- *
- * Failure: Negative
+ * Failure: Negative
*
* Programmer: Scott Wegner
- * Based on code by Robb Matzke
+ * Based on code by Robb Matzke
* Thursday, May 24 2007
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
/* ARGSUSED */
@@ -964,58 +988,96 @@ static herr_t
H5FD_windows_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned closing)
{
H5FD_windows_t *file = (H5FD_windows_t*)_file;
- herr_t ret_value=SUCCEED; /* Return value */
-#ifndef WINDOWS_USE_STDIO
- LARGE_INTEGER li;
- HANDLE filehandle;
-#else
- int fd;
-#endif /* WINDOWS_USE_STDIO */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_windows_flush, FAIL)
- assert(file);
+ HDassert(file);
+
+ /* Only try to flush if we have write access */
+ if(file->write_access) {
+ /* Flush */
+ if(!closing) {
+#ifdef WINDOWS_USE_STDIO
+ if(fflush(file->fp) == EOF)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "fflush failed")
+#endif /* WINDOWS_USE_STDIO */
- if (file->eoa != file->eof) {
+ /* Reset last file I/O information */
+ file->pos = HADDR_UNDEF;
+ file->op = OP_UNKNOWN;
+ } /* end if */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_windows_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_windows_truncate
+ *
+ * Purpose: Makes sure that the true file size is the same (or larger)
+ * than the end-of-address.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Scott Wegner
+ * Based on code by Robb Matzke
+ * Thursday, May 24 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static herr_t
+H5FD_windows_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing)
+{
+ H5FD_windows_t *file = (H5FD_windows_t*)_file;
#ifndef WINDOWS_USE_STDIO
+ LARGE_INTEGER li;
+ HANDLE filehandle;
+#else
+ int fd;
+#endif /* WINDOWS_USE_STDIO */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_windows_truncate, FAIL)
- /* Extend the file to make sure it's large enough */
- if( (filehandle = (HANDLE)_get_osfhandle(file->fd)) == INVALID_HANDLE_VALUE)
- HGOTO_ERROR(H5E_FILE, H5E_FILEOPEN, FAIL, "unable to get file handle for file")
-
- li.QuadPart = (__int64)file->eoa;
- (void)SetFilePointer((HANDLE)filehandle,li.LowPart,&li.HighPart,FILE_BEGIN);
- if(SetEndOfFile(filehandle) == 0)
- HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
+ HDassert(file);
+ if(file->eoa != file->eof) {
+#ifndef WINDOWS_USE_STDIO
+ /* Extend the file to make sure it's large enough */
+ if((filehandle = (HANDLE)_get_osfhandle(file->fd)) == INVALID_HANDLE_VALUE)
+ HGOTO_ERROR(H5E_FILE, H5E_FILEOPEN, FAIL, "unable to get file handle for file")
+
+ li.QuadPart = (__int64)file->eoa;
+ (void)SetFilePointer((HANDLE)filehandle, li.LowPart, &li.HighPart, FILE_BEGIN);
+ if(SetEndOfFile(filehandle) == 0)
+ HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
#else /* WINDOWS_USE_STDIO */
- /* Only try to flush if we have write access */
- if(!file->write_access)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush without write access")
-
- if((fd = _fileno(file->fp)) == -1)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to get file descriptor for file")
- if(_chsize_s(fd, file->eoa))
- HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
-
- /* Flush */
- if(!closing)
- if (fflush(file->fp) == EOF)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "fflush failed")
+ /* Only try to flush if we have write access */
+ if(!file->write_access)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush without write access")
+
+ if((fd = _fileno(file->fp)) == -1)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to get file descriptor for file")
+ if(_chsize_s(fd, file->eoa))
+ HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
#endif /* WINDOWS_USE_STDIO */
- /* Update the eof value */
- file->eof = file->eoa;
+ /* Update the eof value */
+ file->eof = file->eoa;
- /* Reset last file I/O information */
- file->pos = HADDR_UNDEF;
- file->op = OP_UNKNOWN;
-
- }
+ /* Reset last file I/O information */
+ file->pos = HADDR_UNDEF;
+ file->op = OP_UNKNOWN;
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_windows_truncate() */
#endif /* H5_HAVE_WINDOWS */
diff --git a/src/H5FL.c b/src/H5FL.c
index ee62f94..c72491d 100644
--- a/src/H5FL.c
+++ b/src/H5FL.c
@@ -52,6 +52,8 @@ static size_t H5FL_arr_glb_mem_lim=4*1024*1024; /* Default to 4MB limit on all a
static size_t H5FL_arr_lst_mem_lim=4*65536; /* Default to 256KB limit on each array free list */
static size_t H5FL_blk_glb_mem_lim=16*1024*1024; /* Default to 16MB limit on all block free lists */
static size_t H5FL_blk_lst_mem_lim=1024*1024; /* Default to 1024KB (1MB) limit on each block free list */
+static size_t H5FL_fac_glb_mem_lim=16*1024*1024; /* Default to 16MB limit on all factory free lists */
+static size_t H5FL_fac_lst_mem_lim=1024*1024; /* Default to 1024KB (1MB) limit on each factory free list */
/* A garbage collection node for regular free lists */
typedef struct H5FL_reg_gc_node_t {
@@ -98,6 +100,26 @@ typedef struct H5FL_blk_gc_list_t {
/* The head of the list of PQs to garbage collect */
static H5FL_blk_gc_list_t H5FL_blk_gc_head={0,NULL};
+/* A garbage collection node for factory free lists */
+struct H5FL_fac_gc_node_t {
+ H5FL_fac_head_t *list; /* Pointer to the head of the list to garbage collect */
+ struct H5FL_fac_gc_node_t *next; /* Pointer to the next node in the list of things to garbage collect */
+};
+
+/* The garbage collection head for factory free lists */
+typedef struct H5FL_fac_gc_list_t {
+ size_t mem_freed; /* Amount of free memory on list */
+ struct H5FL_fac_gc_node_t *first; /* Pointer to the first node in the list of things to garbage collect */
+} H5FL_fac_gc_list_t;
+
+/* Data structure to store each block in factory free list */
+struct H5FL_fac_node_t {
+ struct H5FL_fac_node_t *next; /* Pointer to next block in free list */
+};
+
+/* The head of the list of factory things to garbage collect */
+static H5FL_fac_gc_list_t H5FL_fac_gc_head={0,NULL};
+
#ifdef H5FL_TRACK
/* Extra headers needed */
@@ -114,14 +136,18 @@ static herr_t H5FL_arr_gc(void);
static herr_t H5FL_arr_gc_list(H5FL_arr_head_t *head);
static herr_t H5FL_blk_gc(void);
static herr_t H5FL_blk_gc_list(H5FL_blk_head_t *head);
-static herr_t H5FL_blk_unlink(H5FL_blk_head_t *pq);
-
-/* Declare a free list to manage the H5FL_fac_head_t struct */
-H5FL_DEFINE(H5FL_fac_head_t);
+static herr_t H5FL_fac_gc(void);
+static herr_t H5FL_fac_gc_list(H5FL_fac_head_t *head);
/* Declare a free list to manage the H5FL_blk_node_t struct */
H5FL_DEFINE(H5FL_blk_node_t);
+/* Declare a free list to manage the H5FL_fac_gc_node_t struct */
+H5FL_DEFINE(H5FL_fac_gc_node_t);
+
+/* Declare a free list to manage the H5FL_fac_head_t struct */
+H5FL_DEFINE(H5FL_fac_head_t);
+
/*--------------------------------------------------------------------------
NAME
@@ -212,11 +238,11 @@ H5FL_reg_init(H5FL_reg_head_t *head)
FUNC_ENTER_NOAPI_NOINIT(H5FL_reg_init)
/* Allocate a new garbage collection node */
- if (NULL==(new_node = H5MM_malloc(sizeof(H5FL_reg_gc_node_t))))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(NULL == (new_node = (H5FL_reg_gc_node_t *)H5MM_malloc(sizeof(H5FL_reg_gc_node_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Initialize the new garbage collection node */
- new_node->list=head;
+ new_node->list = head;
/* Link in to the garbage collection list */
new_node->next=H5FL_reg_gc_head.first;
@@ -225,15 +251,15 @@ H5FL_reg_init(H5FL_reg_head_t *head)
/* Indicate that the free list is initialized */
head->init=1;
+ /* Make certain that the space allocated is large enough to store a free list pointer (eventually) */
+ if(head->size<sizeof(H5FL_reg_node_t))
+ head->size=sizeof(H5FL_reg_node_t);
+
/* Make certain there's room for tracking information, if any */
#ifdef H5FL_TRACK
head->size += sizeof(H5FL_track_t);
#endif /* H5FL_TRACK */
- /* Make certain that the space allocated is large enough to store a free list pointer (eventually) */
- if(head->size<sizeof(void *))
- head->size=sizeof(void *);
-
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FL_reg_init() */
@@ -259,11 +285,13 @@ H5FL_reg_free(H5FL_reg_head_t *head, void *obj)
{
void *ret_value=NULL; /* Return value */
- FUNC_ENTER_NOAPI(H5FL_reg_free, NULL)
+ /* NOINIT OK here because this must be called after H5FL_reg_malloc/calloc
+ * -NAF */
+ FUNC_ENTER_NOAPI_NOINIT(H5FL_reg_free)
/* Double check parameters */
- assert(head);
- assert(obj);
+ HDassert(head);
+ HDassert(obj);
#ifdef H5FL_TRACK
{
@@ -294,7 +322,7 @@ H5FL_reg_free(H5FL_reg_head_t *head, void *obj)
#endif /* H5FL_DEBUG */
/* Make certain that the free list is initialized */
- assert(head->init);
+ HDassert(head->init);
/* Link into the free list */
((H5FL_reg_node_t *)obj)->next=head->list;
@@ -302,16 +330,15 @@ H5FL_reg_free(H5FL_reg_head_t *head, void *obj)
/* Point free list at the node freed */
head->list=(H5FL_reg_node_t *)obj;
- /* Increment the number of blocks & memory on free list */
+ /* Increment the number of blocks on free list */
head->onlist++;
- head->list_mem+=head->size;
/* Increment the amount of "regular" freed memory globally */
H5FL_reg_gc_head.mem_freed+=head->size;
/* Check for exceeding free list memory use limits */
/* First check this particular list */
- if(head->list_mem>H5FL_reg_lst_mem_lim)
+ if(head->onlist * head->size > H5FL_reg_lst_mem_lim)
if(H5FL_reg_gc_list(head)<0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGC, NULL, "garbage collection failed during free")
@@ -348,7 +375,7 @@ H5FL_reg_malloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS)
FUNC_ENTER_NOAPI(H5FL_reg_malloc, NULL)
/* Double check parameters */
- assert(head);
+ HDassert(head);
/* Make certain the list is initialized first */
if(!head->init)
@@ -365,7 +392,6 @@ H5FL_reg_malloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS)
/* Decrement the number of blocks & memory on free list */
head->onlist--;
- head->list_mem-=head->size;
/* Decrement the amount of global "regular" free list memory in use */
H5FL_reg_gc_head.mem_freed-=(head->size);
@@ -426,7 +452,7 @@ H5FL_reg_calloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS)
FUNC_ENTER_NOAPI(H5FL_reg_calloc, NULL)
/* Double check parameters */
- assert(head);
+ HDassert(head);
/* Allocate the block */
if (NULL==(ret_value = H5FL_reg_malloc(head H5FL_TRACK_INFO_INT)))
@@ -476,17 +502,11 @@ H5FL_reg_gc_list(H5FL_reg_head_t *head)
/* Decrement the count of nodes allocated and free the node */
head->allocated--;
- /* Decrement count of free memory on this list */
- head->list_mem-=head->size;
-
- H5MM_xfree(free_list);
+ H5MM_free(free_list);
- free_list=tmp;
+ free_list = (H5FL_reg_node_t *)tmp;
} /* end while */
- /* Double check that all the memory on this list is recycled */
- assert(head->list_mem==0);
-
/* Indicate no free nodes on the free list */
head->list=NULL;
head->onlist=0;
@@ -535,7 +555,7 @@ H5FL_reg_gc(void)
} /* end while */
/* Double check that all the memory on the free lists is recycled */
- assert(H5FL_reg_gc_head.mem_freed==0);
+ HDassert(H5FL_reg_gc_head.mem_freed==0);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -754,11 +774,11 @@ H5FL_blk_init(H5FL_blk_head_t *head)
FUNC_ENTER_NOAPI_NOINIT(H5FL_blk_init)
/* Allocate a new garbage collection node */
- if (NULL==(new_node = H5MM_malloc(sizeof(H5FL_blk_gc_node_t))))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(NULL == (new_node = (H5FL_blk_gc_node_t *)H5MM_malloc(sizeof(H5FL_blk_gc_node_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Initialize the new garbage collection node */
- new_node->pq=head;
+ new_node->pq = head;
/* Link in to the garbage collection list */
new_node->next=H5FL_blk_gc_head.first;
@@ -797,7 +817,7 @@ H5FL_blk_free_block_avail(H5FL_blk_head_t *head, size_t size)
FUNC_ENTER_NOAPI(H5FL_blk_free_block_avail, FAIL)
/* Double check parameters */
- assert(head);
+ HDassert(head);
/* check if there is a free list for blocks of this size */
/* and if there are any blocks available on the list */
@@ -838,8 +858,8 @@ H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size H5FL_TRACK_PARAMS)
FUNC_ENTER_NOAPI(H5FL_blk_malloc, NULL)
/* Double check parameters */
- assert(head);
- assert(size);
+ HDassert(head);
+ HDassert(size);
/* Make certain the list is initialized first */
if(!head->init)
@@ -864,7 +884,7 @@ H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size H5FL_TRACK_PARAMS)
/* No free list available, or there are no nodes on the list, allocate a new node to give to the user */
else {
/* Allocate new node, with room for the page info header and the actual page data */
- if(NULL==(temp=H5FL_malloc(sizeof(H5FL_blk_list_t) + H5FL_TRACK_SIZE + size)))
+ if(NULL == (temp = (H5FL_blk_list_t *)H5FL_malloc(sizeof(H5FL_blk_list_t) + H5FL_TRACK_SIZE + size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for chunk")
/* Increment the number of blocks allocated */
@@ -928,8 +948,8 @@ H5FL_blk_calloc(H5FL_blk_head_t *head, size_t size H5FL_TRACK_PARAMS)
FUNC_ENTER_NOAPI(H5FL_blk_calloc, NULL)
/* Double check parameters */
- assert(head);
- assert(size);
+ HDassert(head);
+ HDassert(size);
/* Allocate the block */
if (NULL==(ret_value = H5FL_blk_malloc(head,size H5FL_TRACK_INFO_INT)))
@@ -969,11 +989,13 @@ H5FL_blk_free(H5FL_blk_head_t *head, void *block)
size_t free_size; /* Size of the block freed */
void *ret_value=NULL; /* Return value */
- FUNC_ENTER_NOAPI(H5FL_blk_free, NULL)
+ /* NOINIT OK here because this must be called after H5FL_blk_malloc/calloc
+ * -NAF */
+ FUNC_ENTER_NOAPI_NOINIT(H5FL_blk_free)
/* Double check parameters */
- assert(head);
- assert(block);
+ HDassert(head);
+ HDassert(block);
#ifdef H5FL_TRACK
{
@@ -1070,8 +1092,8 @@ H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size H5FL_TRACK_
FUNC_ENTER_NOAPI(H5FL_blk_realloc, NULL)
/* Double check parameters */
- assert(head);
- assert(new_size);
+ HDassert(head);
+ HDassert(new_size);
/* Check if we are actually re-allocating a block */
if(block!=NULL) {
@@ -1119,67 +1141,6 @@ done:
} /* end H5FL_blk_realloc() */
-/*--------------------------------------------------------------------------
- NAME
- H5FL_blk_unlink
- PURPOSE
- Remove a block free list from the global list of initialized block free
- lists.
- USAGE
- void H5FL_blk_unlink(H5FL_blk_head_t *pq)
- H5FL_blk_head_t *pq; IN: Block free list to remove from global list
- RETURNS
- Success: Non-negative
- Failure: Negative
- DESCRIPTION
- Search through the global list of initialized block free lists and remove
- a particular free list.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-static herr_t
-H5FL_blk_unlink(H5FL_blk_head_t *pq)
-{
- H5FL_blk_gc_node_t *last; /* Pointer to the last garbage collection node examined */
- H5FL_blk_gc_node_t *tmp; /* Temporary pointer to a garbage collection node */
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5FL_blk_unlink)
-
- /* Find the node to remove from the global list */
- last=NULL;
- tmp=H5FL_blk_gc_head.first;
- while(tmp!=NULL) {
- /* Check if the list has allocations outstanding */
- if(tmp->pq==pq) {
- /* Unlink node from linked list */
- if(last==NULL)
- H5FL_blk_gc_head.first=H5FL_blk_gc_head.first->next;
- else
- last->next=tmp->next;
-
- /* Free the block node */
- H5MM_xfree(tmp);
-
- /* Leave now */
- break;
- } /* end if */
-
- /* Advance to next node in list */
- last=tmp;
- tmp=tmp->next;
- } /* end while */
-
- if(tmp==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGC, FAIL, "can't release block free list")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5FL_blk_unlink() */
-
-
/*-------------------------------------------------------------------------
* Function: H5FL_blk_gc_list
*
@@ -1221,24 +1182,24 @@ H5FL_blk_gc_list(H5FL_blk_head_t *head)
H5FL_blk_gc_head.mem_freed-=head->head->size;
/* Free the block */
- H5MM_xfree(list);
+ H5MM_free(list);
- list=next;
+ list = (H5FL_blk_list_t *)next;
} /* end while */
/* Free the free list node */
- H5FL_FREE(H5FL_blk_node_t,head->head);
+ (void)H5FL_FREE(H5FL_blk_node_t, head->head);
/* Advance to the next free list */
- head->head=temp;
+ head->head = (H5FL_blk_node_t *)temp;
} /* end while */
/* Indicate no free nodes on the free list */
- head->head=NULL;
- head->onlist=0;
+ head->head = NULL;
+ head->onlist = 0;
/* Double check that all the memory on this list is recycled */
- assert(head->list_mem==0);
+ HDassert(0 == head->list_mem);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5FL_blk_gc_list() */
@@ -1279,7 +1240,7 @@ H5FL_blk_gc(void)
} /* end while */
/* Double check that all the memory on the free lists are recycled */
- assert(H5FL_blk_gc_head.mem_freed==0);
+ HDassert(H5FL_blk_gc_head.mem_freed==0);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1334,7 +1295,7 @@ printf("H5FL_blk_term: head->name=%s, head->allocated=%d\n", H5FL_blk_gc_head.fi
H5FL_blk_gc_head.first->pq->init=0;
/* Free the node from the garbage collection list */
- H5MM_xfree(H5FL_blk_gc_head.first);
+ H5MM_free(H5FL_blk_gc_head.first);
} /* end else */
H5FL_blk_gc_head.first=tmp;
@@ -1373,26 +1334,26 @@ H5FL_arr_init(H5FL_arr_head_t *head)
FUNC_ENTER_NOAPI_NOINIT(H5FL_arr_init)
/* Allocate a new garbage collection node */
- if (NULL==(new_node = H5MM_malloc(sizeof(H5FL_gc_arr_node_t))))
+ if(NULL == (new_node = (H5FL_gc_arr_node_t *)H5MM_malloc(sizeof(H5FL_gc_arr_node_t))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Initialize the new garbage collection node */
- new_node->list=head;
+ new_node->list = head;
/* Link in to the garbage collection list */
new_node->next=H5FL_arr_gc_head.first;
H5FL_arr_gc_head.first=new_node;
/* Allocate room for the free lists */
- if (NULL==(head->list_arr = H5MM_calloc((size_t)head->maxelem*sizeof(H5FL_arr_node_t))))
+ if(NULL == (head->list_arr = (H5FL_arr_node_t *)H5MM_calloc((size_t)head->maxelem*sizeof(H5FL_arr_node_t))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Initialize the size of each array */
- for(u = 0; u<(size_t)head->maxelem; u++)
+ for(u = 0; u < (size_t)head->maxelem; u++)
head->list_arr[u].size = head->base_size + (head->elem_size * u);
/* Indicate that the free list is initialized */
- head->init=1;
+ head->init = 1;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1422,17 +1383,19 @@ H5FL_arr_free(H5FL_arr_head_t *head, void *obj)
size_t free_nelem; /* Number of elements in node being free'd */
void *ret_value=NULL; /* Return value */
- FUNC_ENTER_NOAPI(H5FL_arr_free, NULL)
+ /* NOINIT OK here because this must be called after H5FL_arr_malloc/calloc
+ * -NAF */
+ FUNC_ENTER_NOAPI_NOINIT(H5FL_arr_free)
/* The H5MM_xfree code allows obj to null */
if (!obj)
HGOTO_DONE (NULL)
/* Double check parameters */
- assert(head);
+ HDassert(head);
/* Make certain that the free list is initialized */
- assert(head->init);
+ HDassert(head->init);
/* Get the pointer to the info header in front of the block to free */
temp=(H5FL_arr_list_t *)((unsigned char *)obj-sizeof(H5FL_arr_list_t)); /*lint !e826 Pointer-to-pointer cast is appropriate here */
@@ -1441,7 +1404,7 @@ H5FL_arr_free(H5FL_arr_head_t *head, void *obj)
free_nelem=temp->nelem;
/* Double-check that there is enough room for arrays of this size */
- assert((int)free_nelem<=head->maxelem);
+ HDassert((int)free_nelem<=head->maxelem);
/* Link into the free list */
temp->next=head->list_arr[free_nelem].list;
@@ -1500,8 +1463,8 @@ H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem)
FUNC_ENTER_NOAPI(H5FL_arr_malloc, NULL)
/* Double check parameters */
- assert(head);
- assert(elem);
+ HDassert(head);
+ HDassert(elem);
/* Make certain the list is initialized first */
if(!head->init)
@@ -1509,7 +1472,7 @@ H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem)
HGOTO_ERROR (H5E_RESOURCE, H5E_CANTINIT, NULL, "can't initialize 'array' blocks")
/* Sanity check that the number of elements is supported */
- assert(elem<=(unsigned) head->maxelem);
+ HDassert(elem<=(unsigned) head->maxelem);
/* Get the set of the memory block */
mem_size=head->list_arr[elem].size;
@@ -1532,7 +1495,7 @@ H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem)
} /* end if */
/* Otherwise allocate a node */
else {
- if (NULL==(new_obj = H5FL_malloc(sizeof(H5FL_arr_list_t)+mem_size)))
+ if(NULL == (new_obj = (H5FL_arr_list_t *)H5FL_malloc(sizeof(H5FL_arr_list_t)+mem_size)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Increment the number of blocks allocated in list */
@@ -1573,8 +1536,8 @@ H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem)
FUNC_ENTER_NOAPI(H5FL_arr_calloc, NULL)
/* Double check parameters */
- assert(head);
- assert(elem);
+ HDassert(head);
+ HDassert(elem);
/* Allocate the array */
if (NULL==(ret_value = H5FL_arr_malloc(head,elem)))
@@ -1611,8 +1574,8 @@ H5FL_arr_realloc(H5FL_arr_head_t *head, void * obj, size_t new_elem)
FUNC_ENTER_NOAPI(H5FL_arr_realloc, NULL)
/* Double check parameters */
- assert(head);
- assert(new_elem);
+ HDassert(head);
+ HDassert(new_elem);
/* Check if we are really allocating the object */
if(obj==NULL)
@@ -1621,7 +1584,7 @@ H5FL_arr_realloc(H5FL_arr_head_t *head, void * obj, size_t new_elem)
H5FL_arr_list_t *temp; /* Temp. ptr to the new free list node allocated */
/* Sanity check that the number of elements is supported */
- assert((int)new_elem<=head->maxelem);
+ HDassert((int)new_elem<=head->maxelem);
/* Get the pointer to the info header in front of the block to free */
temp=(H5FL_arr_list_t *)((unsigned char *)obj-sizeof(H5FL_arr_list_t)); /*lint !e826 Pointer-to-pointer cast is appropriate here */
@@ -1683,18 +1646,18 @@ H5FL_arr_gc_list(H5FL_arr_head_t *head)
/* For each free list being garbage collected, walk through the nodes and free them */
arr_free_list=head->list_arr[u].list;
while(arr_free_list!=NULL) {
- tmp=arr_free_list->next;
+ tmp = arr_free_list->next;
/* Decrement the count of nodes allocated and free the node */
head->allocated--;
- H5MM_xfree(arr_free_list);
+ H5MM_free(arr_free_list);
- arr_free_list=tmp;
+ arr_free_list = (H5FL_arr_list_t *)tmp;
} /* end while */
/* Indicate no free nodes on the free list */
- head->list_arr[u].list=NULL;
- head->list_arr[u].onlist=0;
+ head->list_arr[u].list = NULL;
+ head->list_arr[u].onlist = 0;
/* Decrement count of free memory on this "array" list */
head->list_mem-=total_mem;
@@ -1705,7 +1668,7 @@ H5FL_arr_gc_list(H5FL_arr_head_t *head)
} /* end for */
/* Double check that all the memory on this list is recycled */
- assert(head->list_mem==0);
+ HDassert(head->list_mem==0);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5FL_arr_gc_list() */
@@ -1746,7 +1709,7 @@ H5FL_arr_gc(void)
} /* end while */
/* Double check that all the memory on the free lists are recycled */
- assert(H5FL_arr_gc_head.mem_freed==0);
+ HDassert(H5FL_arr_gc_head.mem_freed==0);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1803,7 +1766,7 @@ printf("H5FL_arr_term: head->name=%s, head->allocated=%d\n", H5FL_arr_gc_head.fi
H5FL_arr_gc_head.first->list->init=0;
/* Free the node from the garbage collection list */
- H5MM_xfree(H5FL_arr_gc_head.first);
+ H5MM_free(H5FL_arr_gc_head.first);
} /* end else */
H5FL_arr_gc_head.first=tmp;
@@ -1834,14 +1797,16 @@ printf("H5FL_arr_term: head->name=%s, head->allocated=%d\n", H5FL_arr_gc_head.fi
void *
H5FL_seq_free(H5FL_seq_head_t *head, void *obj)
{
+ /* NOINIT OK here because this must be called after H5FL_seq_malloc/calloc
+ * -NAF */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_seq_free)
/* Double check parameters */
- assert(head);
- assert(obj);
+ HDassert(head);
+ HDassert(obj);
/* Make certain that the free list is initialized */
- assert(head->queue.init);
+ HDassert(head->queue.init);
/* Use block routine */
H5FL_blk_free(&(head->queue),obj);
@@ -1873,8 +1838,8 @@ H5FL_seq_malloc(H5FL_seq_head_t *head, size_t elem H5FL_TRACK_PARAMS)
FUNC_ENTER_NOAPI(H5FL_seq_malloc, NULL)
/* Double check parameters */
- assert(head);
- assert(elem);
+ HDassert(head);
+ HDassert(elem);
/* Use block routine */
ret_value=H5FL_blk_malloc(&(head->queue),head->size*elem H5FL_TRACK_INFO_INT);
@@ -1907,8 +1872,8 @@ H5FL_seq_calloc(H5FL_seq_head_t *head, size_t elem H5FL_TRACK_PARAMS)
FUNC_ENTER_NOAPI(H5FL_seq_calloc, NULL)
/* Double check parameters */
- assert(head);
- assert(elem);
+ HDassert(head);
+ HDassert(elem);
/* Use block routine */
ret_value=H5FL_blk_calloc(&(head->queue),head->size*elem H5FL_TRACK_INFO_INT);
@@ -1941,8 +1906,8 @@ H5FL_seq_realloc(H5FL_seq_head_t *head, void * obj, size_t new_elem H5FL_TRACK_P
FUNC_ENTER_NOAPI(H5FL_seq_realloc, NULL)
/* Double check parameters */
- assert(head);
- assert(new_elem);
+ HDassert(head);
+ HDassert(new_elem);
/* Use block routine */
ret_value=H5FL_blk_realloc(&(head->queue),obj,head->size*new_elem H5FL_TRACK_INFO_INT);
@@ -1964,14 +1929,18 @@ done:
* Wednesday, February 2, 2005
*
* Modifications:
+ * Neil Fortner
+ * Friday, December 19, 2008
+ * Totally rewritten to support new factory implementation
*
*-------------------------------------------------------------------------
*/
H5FL_fac_head_t *
H5FL_fac_init(size_t size)
{
- H5FL_fac_head_t *factory; /* Pointer to new block factory */
- H5FL_fac_head_t *ret_value; /* Return value */
+ H5FL_fac_gc_node_t *new_node; /* Pointer to the node for the new list to garbage collect */
+ H5FL_fac_head_t *factory; /* Pointer to new block factory */
+ H5FL_fac_head_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5FL_fac_init, NULL)
@@ -1979,15 +1948,38 @@ H5FL_fac_init(size_t size)
HDassert(size>0);
/* Allocate room for the new factory */
- if(NULL==(factory=H5FL_MALLOC(H5FL_fac_head_t)))
+ if(NULL == (factory = (H5FL_fac_head_t *)H5FL_CALLOC(H5FL_fac_head_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for factory object")
- /* Initialize block header information */
- HDmemset(&(factory->queue),0,sizeof(H5FL_blk_head_t));
-
/* Set size of blocks for factory */
factory->size=size;
+ /* Allocate a new garbage collection node */
+ if(NULL == (new_node = (H5FL_fac_gc_node_t *)H5FL_MALLOC(H5FL_fac_gc_node_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Initialize the new garbage collection node */
+ new_node->list = factory;
+
+ /* Link in to the garbage collection list */
+ new_node->next=H5FL_fac_gc_head.first;
+ H5FL_fac_gc_head.first=new_node;
+ if(new_node->next)
+ new_node->next->list->prev_gc=new_node;
+ /* The new factory's prev_gc field will be set to NULL */
+
+ /* Make certain that the space allocated is large enough to store a free list pointer (eventually) */
+ if(factory->size<sizeof(H5FL_fac_node_t))
+ factory->size=sizeof(H5FL_fac_node_t);
+
+ /* Make certain there's room for tracking information, if any */
+#ifdef H5FL_TRACK
+ factory->size += sizeof(H5FL_track_t);
+#endif /* H5FL_TRACK */
+
+ /* Indicate that the free list is initialized */
+ factory->init=1;
+
/* Set return value */
ret_value=factory;
@@ -2001,32 +1993,86 @@ done:
*
* Purpose: Release a block back to a factory & put on free list
*
- * Return: Success: Non-negative
- * Failure: Negative
+ * Return: NULL
*
* Programmer: Quincey Koziol
* Wednesday, February 2, 2005
*
* Modifications:
+ * Neil Fortner
+ * Friday, December 19, 2008
+ * Totally rewritten to support new factory implementation
*
*-------------------------------------------------------------------------
*/
void *
H5FL_fac_free(H5FL_fac_head_t *head, void *obj)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_fac_free)
+ void *ret_value=NULL; /* Return value */
+
+ /* NOINIT OK here because this must be called after H5FL_fac_init -NAF */
+ FUNC_ENTER_NOAPI_NOINIT(H5FL_fac_free)
/* Double check parameters */
- assert(head);
- assert(obj);
+ HDassert(head);
+ HDassert(obj);
+
+#ifdef H5FL_TRACK
+ {
+ H5FL_track_t *trk = obj = ((unsigned char *)obj) - sizeof(H5FL_track_t);
+
+ /* Free tracking information about the allocation location */
+ H5CS_close_stack(trk->stack);
+ trk->stack = H5MM_xfree(trk->stack);
+ trk->file = H5MM_xfree(trk->file);
+ trk->func = H5MM_xfree(trk->func);
+
+ /* Remove from "outstanding allocations" list */
+ if(trk == H5FL_out_head_g) {
+ H5FL_out_head_g = H5FL_out_head_g->next;
+ if(H5FL_out_head_g)
+ H5FL_out_head_g->prev = NULL;
+ } /* end if */
+ else {
+ trk->prev->next = trk->next;
+ if(trk->next)
+ trk->next->prev = trk->prev;
+ } /* end else */
+ }
+#endif /* H5FL_TRACK */
+
+#ifdef H5FL_DEBUG
+ HDmemset(obj,255,head->size);
+#endif /* H5FL_DEBUG */
/* Make certain that the free list is initialized */
- assert(head->queue.init);
+ HDassert(head->init);
- /* Use block routine */
- H5FL_blk_free(&(head->queue),obj);
+ /* Link into the free list */
+ ((H5FL_fac_node_t *)obj)->next=head->list;
- FUNC_LEAVE_NOAPI(NULL)
+ /* Point free list at the node freed */
+ head->list=(H5FL_fac_node_t *)obj;
+
+ /* Increment the number of blocks on free list */
+ head->onlist++;
+
+ /* Increment the amount of "factory" freed memory globally */
+ H5FL_fac_gc_head.mem_freed+=head->size;
+
+ /* Check for exceeding free list memory use limits */
+ /* First check this particular list */
+ if(head->onlist * head->size > H5FL_fac_lst_mem_lim)
+ if(H5FL_fac_gc_list(head)<0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGC, NULL, "garbage collection failed during free")
+
+ /* Then check the global amount memory on factory free lists */
+ if(H5FL_fac_gc_head.mem_freed > H5FL_fac_glb_mem_lim)
+ if(H5FL_fac_gc()<0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGC, NULL, "garbage collection failed during free")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FL_fac_free() */
@@ -2042,6 +2088,9 @@ H5FL_fac_free(H5FL_fac_head_t *head, void *obj)
* Wednesday, February 2, 2005
*
* Modifications:
+ * Neil Fortner
+ * Friday, December 19, 2008
+ * Totally rewritten to support new factory implementation
*
*-------------------------------------------------------------------------
*/
@@ -2050,13 +2099,54 @@ H5FL_fac_malloc(H5FL_fac_head_t *head H5FL_TRACK_PARAMS)
{
void *ret_value; /* Pointer to object to return */
- FUNC_ENTER_NOAPI(H5FL_fac_malloc, NULL)
+ /* NOINIT OK here because this must be called after H5FL_fac_init -NAF */
+ FUNC_ENTER_NOAPI_NOINIT(H5FL_fac_malloc)
/* Double check parameters */
- assert(head);
+ HDassert(head);
+ HDassert(head->init);
- /* Use block routine */
- ret_value=H5FL_blk_malloc(&(head->queue),head->size H5FL_TRACK_INFO_INT);
+ /* Check for nodes available on the free list first */
+ if(head->list!=NULL) {
+ /* Get a pointer to the block on the free list */
+ ret_value=(void *)(head->list);
+
+ /* Remove node from free list */
+ head->list=head->list->next;
+
+ /* Decrement the number of blocks & memory on free list */
+ head->onlist--;
+
+ /* Decrement the amount of global "factory" free list memory in use */
+ H5FL_fac_gc_head.mem_freed-=(head->size);
+ } /* end if */
+ /* Otherwise allocate a node */
+ else {
+ if (NULL==(ret_value = H5FL_malloc(head->size)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Increment the number of blocks allocated in list */
+ head->allocated++;
+ } /* end else */
+
+#ifdef H5FL_TRACK
+ /* Copy allocation location information */
+ ((H5FL_track_t *)ret_value)->stack = H5MM_calloc(sizeof(H5CS_t));
+ H5CS_copy_stack(((H5FL_track_t *)ret_value)->stack);
+ ((H5FL_track_t *)ret_value)->file = H5MM_strdup(call_file);
+ ((H5FL_track_t *)ret_value)->func = H5MM_strdup(call_func);
+ ((H5FL_track_t *)ret_value)->line = call_line;
+
+ /* Add to "outstanding allocations" list */
+ ((H5FL_track_t *)ret_value)->prev = NULL;
+ ((H5FL_track_t *)ret_value)->next = H5FL_out_head_g;
+ if(H5FL_out_head_g)
+ H5FL_out_head_g->prev = (H5FL_track_t *)ret_value;
+ H5FL_out_head_g = (H5FL_track_t *)ret_value;
+
+ /* Adjust for allocation tracking information */
+ ret_value = ((unsigned char *)ret_value) + sizeof(H5FL_track_t);
+#endif /* H5FL_TRACK */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -2075,6 +2165,9 @@ done:
* Wednesday, February 2, 2005
*
* Modifications:
+ * Neil Fortner
+ * Friday, December 19, 2008
+ * Totally rewritten to support new factory implementation
*
*-------------------------------------------------------------------------
*/
@@ -2083,17 +2176,115 @@ H5FL_fac_calloc(H5FL_fac_head_t *head H5FL_TRACK_PARAMS)
{
void *ret_value; /* Pointer to object to return */
- FUNC_ENTER_NOAPI(H5FL_fac_calloc, NULL)
+ /* NOINIT OK here because this must be called after H5FL_fac_init -NAF */
+ FUNC_ENTER_NOAPI_NOINIT(H5FL_fac_calloc)
/* Double check parameters */
- assert(head);
+ HDassert(head);
- /* Use block routine */
- ret_value=H5FL_blk_calloc(&(head->queue),head->size H5FL_TRACK_INFO_INT);
+ /* Allocate the block */
+ if (NULL==(ret_value = H5FL_fac_malloc(head H5FL_TRACK_INFO_INT)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Clear to zeros */
+ /* (Accomodate tracking information, if present) */
+ HDmemset(ret_value,0,head->size - H5FL_TRACK_SIZE);
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FL_fac_calloc() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_fac_gc_list
+ *
+ * Purpose: Garbage collect on a particular factory free list
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Neil Fortner
+ * Friday, December 19, 2008
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FL_fac_gc_list(H5FL_fac_head_t *head)
+{
+ H5FL_fac_node_t *free_list; /* Pointer to nodes in free list being garbage collected */
+ void *tmp; /* Temporary node pointer */
+ size_t total_mem; /* Total memory used on list */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_fac_gc_list)
+
+ /* Calculate the total memory used on this list */
+ total_mem=head->onlist*head->size;
+
+ /* For each free list being garbage collected, walk through the nodes and free them */
+ free_list=head->list;
+ while(free_list!=NULL) {
+ tmp=free_list->next;
+
+ /* Decrement the count of nodes allocated and free the node */
+ head->allocated--;
+
+ H5MM_free(free_list);
+
+ free_list = (H5FL_fac_node_t *)tmp;
+ } /* end while */
+
+ /* Indicate no free nodes on the free list */
+ head->list=NULL;
+ head->onlist=0;
+
+ /* Decrement global count of free memory on "factory" lists */
+ H5FL_fac_gc_head.mem_freed-=total_mem;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5FL_fac_gc_list() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_fac_gc
+ *
+ * Purpose: Garbage collect on all the factory free lists
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Neil Fortner
+ * Friday, December 19, 2008
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FL_fac_gc(void)
+{
+ H5FL_fac_gc_node_t *gc_node; /* Pointer into the list of things to garbage collect */
+ herr_t ret_value=SUCCEED; /* return value*/
+
+ FUNC_ENTER_NOAPI_NOINIT(H5FL_fac_gc)
+
+ /* Walk through all the free lists, free()'ing the nodes */
+ gc_node=H5FL_fac_gc_head.first;
+ while(gc_node!=NULL) {
+ /* Release the free nodes on the list */
+ if(H5FL_fac_gc_list(gc_node->list)<0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGC, FAIL, "garbage collection of list failed")
+
+ /* Go on to the next free list to garbage collect */
+ gc_node=gc_node->next;
+ } /* end while */
+
+ /* Double check that all the memory on the free lists is recycled */
+ HDassert(H5FL_fac_gc_head.mem_freed==0);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FL_fac_gc() */
/*-------------------------------------------------------------------------
@@ -2108,32 +2299,53 @@ done:
* Wednesday, February 2, 2005
*
* Modifications:
+ * Neil Fortner
+ * Friday, December 19, 2008
+ * Totally rewritten to support new factory implementation
*
*-------------------------------------------------------------------------
*/
herr_t
H5FL_fac_term(H5FL_fac_head_t *factory)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ H5FL_fac_gc_node_t *tmp; /* Temporary pointer to a garbage collection node */
+ herr_t ret_value = SUCCEED; /* Return value */
+ /* NOINIT OK here because this must be called after H5FL_fac_init -NAF */
FUNC_ENTER_NOAPI_NOINIT(H5FL_fac_term)
/* Sanity check */
HDassert(factory);
/* Garbage collect all the blocks in the factory's free list */
- if(H5FL_blk_gc_list(&(factory->queue))<0)
+ if(H5FL_fac_gc_list(factory)<0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGC, FAIL, "garbage collection of factory failed")
/* Verify that all the blocks have been freed */
- if(factory->queue.allocated>0)
+ if(factory->allocated>0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "factory still has objects allocated")
/* Unlink block free list for factory from global free list */
- H5FL_blk_unlink(&(factory->queue));
+ if(factory->prev_gc) {
+ H5FL_fac_gc_node_t *last = factory->prev_gc; /* Garbage collection node before the one being removed */
+
+ HDassert(last->next->list == factory);
+ tmp = last->next->next;
+ (void)H5FL_FREE(H5FL_fac_gc_node_t, last->next);
+ last->next = tmp;
+ if(tmp)
+ tmp->list->prev_gc = last;
+ } else {
+ HDassert(H5FL_fac_gc_head.first->list == factory);
+ tmp = H5FL_fac_gc_head.first->next;
+ (void)H5FL_FREE(H5FL_fac_gc_node_t, H5FL_fac_gc_head.first);
+ H5FL_fac_gc_head.first = tmp;
+ if(tmp)
+ tmp->list->prev_gc = NULL;
+ } /* end else */
/* Free factory info */
- H5FL_FREE(H5FL_fac_head_t,factory);
+ (void)H5FL_FREE(H5FL_fac_head_t, factory);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -2141,6 +2353,52 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5FL_fac_term_all
+ *
+ * Purpose: Terminate all block factories
+ *
+ * Return: 0. There should never be any outstanding allocations
+ * when this is called.
+ *
+ * Programmer: Neil Fortner
+ * Friday, December 19, 2008
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5FL_fac_term_all(void)
+{
+ H5FL_fac_gc_node_t *tmp; /* Temporary pointer to a garbage collection node */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_fac_term_all)
+
+ /* Free the nodes on the garbage collection list */
+ while(H5FL_fac_gc_head.first != NULL) {
+ tmp=H5FL_fac_gc_head.first->next;
+
+#ifdef H5FL_DEBUG
+printf("H5FL_fac_term: head->size=%d, head->allocated=%d\n", (int)H5FL_fac_gc_head.first->list->size,(int)H5FL_fac_gc_head.first->list->allocated);
+#endif /* H5FL_DEBUG */
+
+ /* The list cannot have any allocations outstanding */
+ HDassert(H5FL_fac_gc_head.first->list->allocated == 0);
+
+ /* Reset the "initialized" flag, in case we restart this list somehow (I don't know how..) */
+ H5FL_fac_gc_head.first->list->init = 0;
+
+ /* Free the node from the garbage collection list */
+ (void)H5FL_FREE(H5FL_fac_gc_node_t, H5FL_fac_gc_head.first);
+
+ H5FL_fac_gc_head.first = tmp;
+ } /* end while */
+
+ FUNC_LEAVE_NOAPI(0)
+} /* end H5FL_fac_term_all() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5FL_garbage_coll
*
* Purpose: Garbage collect on all the free lists
@@ -2160,7 +2418,7 @@ H5FL_garbage_coll(void)
{
herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI_NOINIT(H5FL_garbage_coll)
+ FUNC_ENTER_NOAPI(H5FL_garbage_coll, FAIL)
/* Garbage collect the free lists for array objects */
if(H5FL_arr_gc()<0)
@@ -2174,6 +2432,10 @@ H5FL_garbage_coll(void)
if(H5FL_reg_gc()<0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGC, FAIL, "can't garbage collect regular objects")
+ /* Garbage collect the free lists for factory objects */
+ if(H5FL_fac_gc()<0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGC, FAIL, "can't garbage collect regular objects")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FL_garbage_coll() */
@@ -2204,13 +2466,16 @@ done:
* Programmer: Quincey Koziol
* Wednesday, August 2, 2000
*
- * Modifications:
+ * Modifications: Neil Fortner
+ * Wednesday, April 8, 2009
+ * Added support for factory free lists
*
*-------------------------------------------------------------------------
*/
herr_t
H5FL_set_free_list_limits(int reg_global_lim, int reg_list_lim, int arr_global_lim,
- int arr_list_lim, int blk_global_lim, int blk_list_lim)
+ int arr_list_lim, int blk_global_lim, int blk_list_lim, int fac_global_lim,
+ int fac_list_lim)
{
herr_t ret_value = SUCCEED;
@@ -2229,6 +2494,10 @@ H5FL_set_free_list_limits(int reg_global_lim, int reg_list_lim, int arr_global_l
H5FL_blk_glb_mem_lim=(blk_global_lim==-1 ? UINT_MAX : (size_t)blk_global_lim);
/* limit on each block free list */
H5FL_blk_lst_mem_lim=(blk_list_lim==-1 ? UINT_MAX : (size_t)blk_list_lim);
+ /* limit on all factory free lists */
+ H5FL_fac_glb_mem_lim=(fac_global_lim==-1 ? UINT_MAX : (size_t)fac_global_lim);
+ /* limit on each factory free list */
+ H5FL_fac_lst_mem_lim=(fac_list_lim==-1 ? UINT_MAX : (size_t)fac_list_lim);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -2264,7 +2533,7 @@ H5FL_term_interface(void)
/* Garbage collect any nodes on the free lists */
(void)H5FL_garbage_coll();
- ret_value=H5FL_reg_term()+H5FL_arr_term()+H5FL_blk_term();
+ ret_value=H5FL_reg_term()+H5FL_fac_term_all()+H5FL_arr_term()+H5FL_blk_term();
#ifdef H5FL_TRACK
/* If we haven't freed all the allocated memory, dump out the list now */
diff --git a/src/H5FLprivate.h b/src/H5FLprivate.h
index 1dcced6..ea2ec55 100644
--- a/src/H5FLprivate.h
+++ b/src/H5FLprivate.h
@@ -100,7 +100,6 @@ typedef struct H5FL_reg_head_t {
unsigned init; /* Whether the free list has been initialized */
unsigned allocated; /* Number of blocks allocated */
unsigned onlist; /* Number of blocks on free list */
- size_t list_mem; /* Amount of memory on free list */
const char *name; /* Name of the type */
size_t size; /* Size of the blocks in the list */
H5FL_reg_node_t *list; /* List of free blocks */
@@ -112,13 +111,13 @@ typedef struct H5FL_reg_head_t {
#define H5FL_REG_NAME(t) H5_##t##_reg_free_list
#ifndef H5_NO_REG_FREE_LISTS
/* Common macros for H5FL_DEFINE & H5FL_DEFINE_STATIC */
-#define H5FL_DEFINE_COMMON(t) H5FL_reg_head_t H5FL_REG_NAME(t)={0,0,0,0,#t,sizeof(t),NULL}
+#define H5FL_DEFINE_COMMON(t) H5FL_reg_head_t H5FL_REG_NAME(t)={0,0,0,#t,sizeof(t),NULL}
/* Declare a free list to manage objects of type 't' */
#define H5FL_DEFINE(t) H5_DLL H5FL_DEFINE_COMMON(t)
/* Reference a free list for type 't' defined in another file */
-#define H5FL_EXTERN(t) extern H5_DLL H5FL_reg_head_t H5FL_REG_NAME(t)
+#define H5FL_EXTERN(t) H5_DLLVAR H5FL_reg_head_t H5FL_REG_NAME(t)
/* Declare a static free list to manage objects of type 't' */
#define H5FL_DEFINE_STATIC(t) static H5FL_DEFINE_COMMON(t)
@@ -130,7 +129,7 @@ typedef struct H5FL_reg_head_t {
#define H5FL_CALLOC(t) (t *)H5FL_reg_calloc(&(H5FL_REG_NAME(t)) H5FL_TRACK_INFO)
/* Free an object of type 't' */
-#define H5FL_FREE(t,obj) H5FL_reg_free(&(H5FL_REG_NAME(t)),obj)
+#define H5FL_FREE(t,obj) (t *)H5FL_reg_free(&(H5FL_REG_NAME(t)),obj)
/* Re-allocating an object of type 't' is not defined, because these free-lists
* only support fixed sized types, like structs, etc..
@@ -142,7 +141,7 @@ typedef struct H5FL_reg_head_t {
#define H5FL_DEFINE_COMMON(t) int UNUSED H5FL_REG_NAME(t)
#define H5FL_DEFINE(t) H5_DLL H5FL_DEFINE_COMMON(t)
-#define H5FL_EXTERN(t) extern H5_DLL H5FL_DEFINE_COMMON(t)
+#define H5FL_EXTERN(t) H5_DLLVAR H5FL_DEFINE_COMMON(t)
#define H5FL_DEFINE_STATIC(t) static H5FL_DEFINE_COMMON(t)
#define H5FL_MALLOC(t) (t *)H5MM_malloc(sizeof(t))
#define H5FL_CALLOC(t) (t *)H5MM_calloc(sizeof(t))
@@ -187,7 +186,7 @@ typedef struct H5FL_blk_head_t {
#define H5FL_BLK_DEFINE(t) H5_DLL H5FL_BLK_DEFINE_COMMON(t)
/* Reference a free list for type 't' defined in another file */
-#define H5FL_BLK_EXTERN(t) extern H5_DLL H5FL_blk_head_t H5FL_BLK_NAME(t)
+#define H5FL_BLK_EXTERN(t) H5_DLLVAR H5FL_blk_head_t H5FL_BLK_NAME(t)
/* Declare a static free list to manage objects of type 't' */
#define H5FL_BLK_DEFINE_STATIC(t) static H5FL_BLK_DEFINE_COMMON(t)
@@ -212,7 +211,7 @@ typedef struct H5FL_blk_head_t {
#define H5FL_BLK_DEFINE_COMMON(t) int UNUSED H5FL_BLK_NAME(t)
#define H5FL_BLK_DEFINE(t) H5_DLL H5FL_BLK_DEFINE_COMMON(t)
-#define H5FL_BLK_EXTERN(t) extern H5_DLL H5FL_BLK_DEFINE_COMMON(t)
+#define H5FL_BLK_EXTERN(t) H5_DLLVAR H5FL_BLK_DEFINE_COMMON(t)
#define H5FL_BLK_DEFINE_STATIC(t) static H5FL_BLK_DEFINE_COMMON(t)
#define H5FL_BLK_MALLOC(t,size) (uint8_t *)H5MM_malloc(size)
#define H5FL_BLK_CALLOC(t,size) (uint8_t *)H5MM_calloc(size)
@@ -263,7 +262,7 @@ typedef struct H5FL_arr_head_t {
#define H5FL_BARR_DEFINE(b,t,m) H5_DLL H5FL_ARR_DEFINE_COMMON(sizeof(b),t,m)
/* Reference a free list for arrays of type 't' defined in another file */
-#define H5FL_ARR_EXTERN(t) extern H5_DLL H5FL_arr_head_t H5FL_ARR_NAME(t)
+#define H5FL_ARR_EXTERN(t) H5_DLLVAR H5FL_arr_head_t H5FL_ARR_NAME(t)
/* Declare a static free list to manage arrays of type 't' */
#define H5FL_ARR_DEFINE_STATIC(t,m) static H5FL_ARR_DEFINE_COMMON(0,t,m)
@@ -289,7 +288,7 @@ typedef struct H5FL_arr_head_t {
#define H5FL_ARR_DEFINE(t,m) H5_DLL H5FL_ARR_DEFINE_COMMON(t,m) = 0
#define H5FL_BARR_DEFINE(b,t,m) H5_DLL H5FL_ARR_DEFINE_COMMON(t,m) = sizeof(b)
-#define H5FL_ARR_EXTERN(t) extern H5_DLL H5FL_ARR_DEFINE_COMMON(t,m)
+#define H5FL_ARR_EXTERN(t) H5_DLLVAR H5FL_ARR_DEFINE_COMMON(t,m)
#define H5FL_ARR_DEFINE_STATIC(t,m) static H5FL_ARR_DEFINE_COMMON(t,m) = 0
#define H5FL_BARR_DEFINE_STATIC(b,t,m) static H5FL_ARR_DEFINE_COMMON(t,m) = sizeof(b)
#define H5FL_ARR_MALLOC(t,elem) H5MM_malloc(H5FL_ARR_NAME(t) + ((elem)*sizeof(t)))
@@ -319,7 +318,7 @@ typedef struct H5FL_seq_head_t {
#define H5FL_SEQ_DEFINE(t) H5_DLL H5FL_SEQ_DEFINE_COMMON(t)
/* Reference a free list for sequences of type 't' defined in another file */
-#define H5FL_SEQ_EXTERN(t) extern H5_DLL H5FL_seq_head_t H5FL_SEQ_NAME(t)
+#define H5FL_SEQ_EXTERN(t) H5_DLLVAR H5FL_seq_head_t H5FL_SEQ_NAME(t)
/* Declare a static free list to manage sequences of type 't' */
#define H5FL_SEQ_DEFINE_STATIC(t) static H5FL_SEQ_DEFINE_COMMON(t)
@@ -331,7 +330,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)
@@ -341,7 +340,7 @@ typedef struct H5FL_seq_head_t {
#define H5FL_SEQ_DEFINE_COMMON(t) int UNUSED H5FL_SEQ_NAME(t)
#define H5FL_SEQ_DEFINE(t) H5_DLL H5FL_SEQ_DEFINE_COMMON(t)
-#define H5FL_SEQ_EXTERN(t) extern H5_DLL H5FL_SEQ_DEFINE_COMMON(t)
+#define H5FL_SEQ_EXTERN(t) H5_DLLVAR H5FL_SEQ_DEFINE_COMMON(t)
#define H5FL_SEQ_DEFINE_STATIC(t) static H5FL_SEQ_DEFINE_COMMON(t)
#define H5FL_SEQ_MALLOC(t,elem) (t *)H5MM_malloc((elem)*sizeof(t))
#define H5FL_SEQ_CALLOC(t,elem) (t *)H5MM_calloc((elem)*sizeof(t))
@@ -349,12 +348,21 @@ typedef struct H5FL_seq_head_t {
#define H5FL_SEQ_REALLOC(t,obj,new_elem) (t *)H5MM_realloc(obj,(new_elem)*sizeof(t))
#endif /* H5_NO_SEQ_FREE_LISTS */
+/* Forward declarations of the data structures for free list block factory */
+typedef struct H5FL_fac_gc_node_t H5FL_fac_gc_node_t;
+typedef struct H5FL_fac_node_t H5FL_fac_node_t;
+
/* Data structure for free list block factory */
typedef struct H5FL_fac_head_t {
- H5FL_blk_head_t queue; /* Priority queue of blocks */
- size_t size; /* Size of the blocks managed */
+ unsigned init; /* Whether the free list has been initialized */
+ unsigned allocated; /* Number of blocks allocated */
+ unsigned onlist; /* Number of blocks on free list */
+ size_t size; /* Size of the blocks in the list */
+ H5FL_fac_node_t *list; /* List of free blocks */
+ H5FL_fac_gc_node_t *prev_gc; /* Previous garbage collection node in list */
} H5FL_fac_head_t;
+
/*
* Macros for defining & using free list factories
*
@@ -381,30 +389,42 @@ typedef struct H5FL_fac_head_t {
/*
* Library prototypes.
*/
+ /* Block free lists */
H5_DLL void * H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size H5FL_TRACK_PARAMS);
H5_DLL void * H5FL_blk_calloc(H5FL_blk_head_t *head, size_t size H5FL_TRACK_PARAMS);
H5_DLL void * H5FL_blk_free(H5FL_blk_head_t *head, void *block);
H5_DLL void * H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size H5FL_TRACK_PARAMS);
H5_DLL htri_t H5FL_blk_free_block_avail(H5FL_blk_head_t *head, size_t size);
+
+/* Regular free lists */
H5_DLL void * H5FL_reg_malloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS);
H5_DLL void * H5FL_reg_calloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS);
H5_DLL void * H5FL_reg_free(H5FL_reg_head_t *head, void *obj);
+
+/* Array free lists */
H5_DLL void * H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem);
H5_DLL void * H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem);
H5_DLL void * H5FL_arr_free(H5FL_arr_head_t *head, void *obj);
H5_DLL void * H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, size_t new_elem);
+
+/* Sequence free lists */
H5_DLL void * H5FL_seq_malloc(H5FL_seq_head_t *head, size_t elem H5FL_TRACK_PARAMS);
H5_DLL void * H5FL_seq_calloc(H5FL_seq_head_t *head, size_t elem H5FL_TRACK_PARAMS);
H5_DLL void * H5FL_seq_free(H5FL_seq_head_t *head, void *obj);
H5_DLL void * H5FL_seq_realloc(H5FL_seq_head_t *head, void *obj, size_t new_elem H5FL_TRACK_PARAMS);
+
+/* Factory free lists */
H5_DLL H5FL_fac_head_t *H5FL_fac_init(size_t size);
H5_DLL void * H5FL_fac_malloc(H5FL_fac_head_t *head H5FL_TRACK_PARAMS);
H5_DLL void * H5FL_fac_calloc(H5FL_fac_head_t *head H5FL_TRACK_PARAMS);
H5_DLL void * H5FL_fac_free(H5FL_fac_head_t *head, void *obj);
H5_DLL herr_t H5FL_fac_term(H5FL_fac_head_t *head);
+
+/* General free list routines */
H5_DLL herr_t H5FL_garbage_coll(void);
H5_DLL herr_t H5FL_set_free_list_limits(int reg_global_lim, int reg_list_lim,
- int arr_global_lim, int arr_list_lim, int blk_global_lim, int blk_list_lim);
+ int arr_global_lim, int arr_list_lim, int blk_global_lim, int blk_list_lim,
+ int fac_global_lim, int fac_list_lim);
H5_DLL int H5FL_term_interface(void);
#endif
diff --git a/src/H5FO.c b/src/H5FO.c
index bae7fe2..bbc3b7d 100644
--- a/src/H5FO.c
+++ b/src/H5FO.c
@@ -82,7 +82,7 @@ H5FO_create(const H5F_t *f)
assert(f->shared);
/* Create container used to store open object info */
- if((f->shared->open_objs = H5SL_create(H5SL_TYPE_HADDR, 0.5, (size_t)16)) == NULL)
+ if((f->shared->open_objs = H5SL_create(H5SL_TYPE_HADDR)) == NULL)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to create open object container")
done:
@@ -119,18 +119,18 @@ H5FO_opened(const H5F_t *f, haddr_t addr)
FUNC_ENTER_NOAPI_NOFUNC(H5FO_opened)
/* Sanity check */
- assert(f);
- assert(f->shared);
- assert(f->shared->open_objs);
- assert(H5F_addr_defined(addr));
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->open_objs);
+ HDassert(H5F_addr_defined(addr));
/* Get the object node from the container */
- if((open_obj=H5SL_search(f->shared->open_objs,&addr))!=NULL) {
- ret_value=open_obj->obj;
- assert(ret_value!=NULL);
+ if(NULL != (open_obj = (H5FO_open_obj_t *)H5SL_search(f->shared->open_objs,&addr))) {
+ ret_value = open_obj->obj;
+ HDassert(ret_value != NULL);
} /* end if */
else
- ret_value=NULL;
+ ret_value = NULL;
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FO_opened() */
@@ -218,23 +218,23 @@ H5FO_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
FUNC_ENTER_NOAPI(H5FO_delete,FAIL)
/* Sanity check */
- assert(f);
- assert(f->shared);
- assert(f->shared->open_objs);
- assert(H5F_addr_defined(addr));
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->open_objs);
+ HDassert(H5F_addr_defined(addr));
/* Remove from container */
- if((open_obj=H5SL_remove(f->shared->open_objs,&addr))==NULL)
+ if(NULL == (open_obj = (H5FO_open_obj_t *)H5SL_remove(f->shared->open_objs, &addr)))
HGOTO_ERROR(H5E_CACHE,H5E_CANTRELEASE,FAIL,"can't remove object from container")
/* Check if the object was deleted from the file */
if(open_obj->deleted) {
- if(H5O_delete(f, dxpl_id, addr)<0)
+ if(H5O_delete(f, dxpl_id, addr) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file")
} /* end if */
/* Release the object information */
- H5FL_FREE(H5FO_open_obj_t,open_obj);
+ (void)H5FL_FREE(H5FO_open_obj_t, open_obj);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -275,10 +275,10 @@ H5FO_mark(const H5F_t *f, haddr_t addr, hbool_t deleted)
assert(H5F_addr_defined(addr));
/* Get the object node from the container */
- if((open_obj=H5SL_search(f->shared->open_objs,&addr))!=NULL)
- open_obj->deleted=deleted;
+ if(NULL != (open_obj = (H5FO_open_obj_t *)H5SL_search(f->shared->open_objs, &addr)))
+ open_obj->deleted = deleted;
else
- ret_value=FAIL;
+ ret_value = FAIL;
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FO_mark() */
@@ -290,12 +290,12 @@ H5FO_mark(const H5F_t *f, haddr_t addr, hbool_t deleted)
PURPOSE
Check if an object is marked to be deleted when it is closed
USAGE
- htri_t H5FO_marked(f,addr)
+ hbool_t H5FO_marked(f,addr)
const H5F_t *f; IN: File opened object is in
haddr_t addr; IN: Address of object to delete
RETURNS
- Returns a TRUE/FALSE on success, negative on failure
+ Returns a TRUE/FALSE on success
DESCRIPTION
Checks if the object is currently in the "opened objects" tree and
whether its marks for deletion from the file when it is closed.
@@ -304,23 +304,23 @@ H5FO_mark(const H5F_t *f, haddr_t addr, hbool_t deleted)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-htri_t
+hbool_t
H5FO_marked(const H5F_t *f, haddr_t addr)
{
H5FO_open_obj_t *open_obj; /* Information about open object */
- htri_t ret_value=FAIL; /* Return value */
+ hbool_t ret_value = FALSE; /* Return value */
FUNC_ENTER_NOAPI_NOFUNC(H5FO_marked)
/* Sanity check */
- assert(f);
- assert(f->shared);
- assert(f->shared->open_objs);
- assert(H5F_addr_defined(addr));
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->open_objs);
+ HDassert(H5F_addr_defined(addr));
/* Get the object node from the container */
- if((open_obj=H5SL_search(f->shared->open_objs,&addr))!=NULL)
- ret_value=open_obj->deleted;
+ if(NULL != (open_obj = (H5FO_open_obj_t *)H5SL_search(f->shared->open_objs, &addr)))
+ ret_value = open_obj->deleted;
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FO_marked() */
@@ -400,7 +400,7 @@ H5FO_top_create(H5F_t *f)
HDassert(f);
/* Create container used to store open object info */
- if((f->obj_count = H5SL_create(H5SL_TYPE_HADDR, 0.5, (size_t)16)) == NULL)
+ if((f->obj_count = H5SL_create(H5SL_TYPE_HADDR)) == NULL)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to create open object container")
done:
@@ -441,12 +441,12 @@ H5FO_top_incr(const H5F_t *f, haddr_t addr)
HDassert(H5F_addr_defined(addr));
/* Get the object node from the container */
- if((obj_count = H5SL_search(f->obj_count, &addr)) != NULL) {
+ if(NULL != (obj_count = (H5FO_obj_count_t *)H5SL_search(f->obj_count, &addr))) {
(obj_count->count)++;
} /* end if */
else {
/* Allocate new opened object information structure */
- if((obj_count = H5FL_MALLOC(H5FO_obj_count_t)) == NULL)
+ if(NULL == (obj_count = H5FL_MALLOC(H5FO_obj_count_t)))
HGOTO_ERROR(H5E_CACHE,H5E_NOSPACE,FAIL,"memory allocation failed")
/* Assign information */
@@ -496,17 +496,17 @@ H5FO_top_decr(const H5F_t *f, haddr_t addr)
HDassert(H5F_addr_defined(addr));
/* Get the object node from the container */
- if((obj_count = H5SL_search(f->obj_count, &addr)) != NULL) {
+ if(NULL != (obj_count = (H5FO_obj_count_t *)H5SL_search(f->obj_count, &addr))) {
/* Decrement the reference count for the object */
(obj_count->count)--;
if(obj_count->count == 0) {
/* Remove from container */
- if((obj_count = H5SL_remove(f->obj_count, &addr)) == NULL)
+ if(NULL == (obj_count = (H5FO_obj_count_t *)H5SL_remove(f->obj_count, &addr)))
HGOTO_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "can't remove object from container")
/* Release the object information */
- H5FL_FREE(H5FO_obj_count_t, obj_count);
+ (void)H5FL_FREE(H5FO_obj_count_t, obj_count);
} /* end if */
} /* end if */
else
@@ -550,7 +550,7 @@ H5FO_top_count(const H5F_t *f, haddr_t addr)
HDassert(H5F_addr_defined(addr));
/* Get the object node from the container */
- if((obj_count = H5SL_search(f->obj_count, &addr)) != NULL)
+ if(NULL != (obj_count = (H5FO_obj_count_t *)H5SL_search(f->obj_count, &addr)))
ret_value = obj_count->count;
else
ret_value = 0;
diff --git a/src/H5FOprivate.h b/src/H5FOprivate.h
index 9458a56..4648f02 100644
--- a/src/H5FOprivate.h
+++ b/src/H5FOprivate.h
@@ -41,7 +41,7 @@ H5_DLL void *H5FO_opened(const H5F_t *f, haddr_t addr);
H5_DLL herr_t H5FO_insert(const H5F_t *f, haddr_t addr, void *obj, hbool_t delete_flag);
H5_DLL herr_t H5FO_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr);
H5_DLL herr_t H5FO_mark(const H5F_t *f, haddr_t addr, hbool_t deleted);
-H5_DLL htri_t H5FO_marked(const H5F_t *f, haddr_t addr);
+H5_DLL hbool_t H5FO_marked(const H5F_t *f, haddr_t addr);
H5_DLL herr_t H5FO_dest(const H5F_t *f);
H5_DLL herr_t H5FO_top_create(H5F_t *f);
H5_DLL herr_t H5FO_top_incr(const H5F_t *f, haddr_t addr);
diff --git a/src/H5FS.c b/src/H5FS.c
index 2dd2833..5e3392e 100644
--- a/src/H5FS.c
+++ b/src/H5FS.c
@@ -91,22 +91,25 @@ H5FL_DEFINE(H5FS_t);
* Programmer: Quincey Koziol
* Tuesday, March 7, 2006
*
+ * Modifications:
+ * Vailin Choi, July 29th, 2008
+ * Add two more parameters for handling alignment: alignment & threshhold
+ *
*-------------------------------------------------------------------------
*/
H5FS_t *
H5FS_create(H5F_t *f, hid_t dxpl_id, haddr_t *fs_addr, const H5FS_create_t *fs_create,
- size_t nclasses, const H5FS_section_class_t *classes[], void *cls_init_udata)
+ size_t nclasses, const H5FS_section_class_t *classes[], void *cls_init_udata, hsize_t alignment, hsize_t threshold)
{
H5FS_t *fspace = NULL; /* New free space structure */
H5FS_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5FS_create, NULL)
-#ifdef QAK
+#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: Creating free space manager, nclasses = %Zu\n", FUNC, nclasses);
-#endif /* QAK */
+#endif /* H5FS_DEBUG */
/* Check arguments. */
- HDassert(fs_addr);
HDassert(fs_create->shrink_percent);
HDassert(fs_create->shrink_percent < fs_create->expand_percent);
HDassert(fs_create->max_sect_size);
@@ -118,11 +121,6 @@ HDfprintf(stderr, "%s: Creating free space manager, nclasses = %Zu\n", FUNC, ncl
if(NULL == (fspace = H5FS_new(nclasses, classes, cls_init_udata)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for free space free list")
- /* Allocate space for the free space header */
- if(HADDR_UNDEF == (fspace->addr = H5MF_alloc(f, H5FD_MEM_FSPACE_HDR, dxpl_id, (hsize_t)H5FS_HEADER_SIZE(f))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "file allocation failed for free space header")
- *fs_addr = fspace->addr;
-
/* Initialize creation information for free space manager */
fspace->client = fs_create->client;
fspace->shrink_percent = fs_create->shrink_percent;
@@ -130,17 +128,39 @@ HDfprintf(stderr, "%s: Creating free space manager, nclasses = %Zu\n", FUNC, ncl
fspace->max_sect_addr = fs_create->max_sect_addr;
fspace->max_sect_size = fs_create->max_sect_size;
- /* Cache the new free space header (pinned) */
- if(H5AC_set(f, dxpl_id, H5AC_FSPACE_HDR, fspace->addr, fspace, H5AC__PIN_ENTRY_FLAG) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, NULL, "can't add free space header to cache")
+ fspace->alignment = alignment;
+ fspace->threshold = threshold;
+
+ /* Check if the free space tracker is supposed to be persistant */
+ if(fs_addr) {
+ /* Allocate space for the free space header */
+ if(HADDR_UNDEF == (fspace->addr = H5MF_alloc(f, H5FD_MEM_FSPACE_HDR, dxpl_id, (hsize_t)H5FS_HEADER_SIZE(f))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "file allocation failed for free space header")
+
+ /* Cache the new free space header (pinned) */
+ if(H5AC_set(f, dxpl_id, H5AC_FSPACE_HDR, fspace->addr, fspace, H5AC__PIN_ENTRY_FLAG) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, NULL, "can't add free space header to cache")
+
+ /* Return free space header address to caller, if desired */
+ *fs_addr = fspace->addr;
+ } /* end if */
+
+ /* Set the reference count to 1, since we inserted the entry in the cache pinned */
+ fspace->rc = 1;
/* Set the return value */
ret_value = fspace;
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: fspace = %p, fspace->addr = %a\n", FUNC, fspace, fspace->addr);
+#endif /* H5FS_DEBUG */
done:
if(!ret_value && fspace)
(void)H5FS_cache_hdr_dest(f, fspace);
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value);
+#endif /* H5FS_DEBUG */
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_create() */
@@ -157,21 +177,25 @@ done:
* Programmer: Quincey Koziol
* Tuesday, May 2, 2006
*
+ * Modfications:
+ *
+ * Vailin Choi, July 29th, 2008
+ * Add two more parameters for handling alignment: alignment & threshhold
+ *
*-------------------------------------------------------------------------
*/
H5FS_t *
H5FS_open(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr, size_t nclasses,
- const H5FS_section_class_t *classes[], void *cls_init_udata)
+ const H5FS_section_class_t *classes[], void *cls_init_udata, hsize_t alignment, hsize_t threshold)
{
H5FS_t *fspace = NULL; /* New free space structure */
H5FS_prot_t fs_prot; /* Information for protecting free space manager */
- unsigned fspace_status = 0; /* Free space header's status in the metadata cache */
H5FS_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5FS_open, NULL)
-#ifdef QAK
-HDfprintf(stderr, "%s: Opening free space manager, nclasses = %Zu\n", FUNC, nclasses);
-#endif /* QAK */
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Opening free space manager, fs_addr = %a, nclasses = %Zu\n", FUNC, fs_addr, nclasses);
+#endif /* H5FS_DEBUG */
/* Check arguments. */
HDassert(H5F_addr_defined(fs_addr));
@@ -184,28 +208,25 @@ HDfprintf(stderr, "%s: Opening free space manager, nclasses = %Zu\n", FUNC, ncla
fs_prot.cls_init_udata = cls_init_udata;
/* Protect the free space header */
- if(NULL == (fspace = H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, &fs_prot, NULL, H5AC_READ)))
+ if(NULL == (fspace = (H5FS_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, &fs_prot, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTPROTECT, NULL, "unable to load free space header")
-#ifdef QAK
+#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: fspace->sect_addr = %a\n", FUNC, fspace->sect_addr);
HDfprintf(stderr, "%s: fspace->sect_size = %Hu\n", FUNC, fspace->sect_size);
HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu\n", FUNC, fspace->alloc_sect_size);
HDfprintf(stderr, "%s: fspace->sinfo = %p\n", FUNC, fspace->sinfo);
-#endif /* QAK */
+HDfprintf(stderr, "%s: fspace->rc = %u\n", FUNC, fspace->rc);
+#endif /* H5FS_DEBUG */
- /* Check the free space header's status in the metadata cache */
- if(H5AC_get_entry_status(f, fs_addr, &fspace_status) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, NULL, "unable to check metadata cache status for free space header")
+ /* Increment the reference count on the free space manager header */
+ HDassert(fspace->rc <= 1);
+ if(H5FS_incr(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINC, NULL, "unable to increment ref. count on free space header")
- /* If the free space header isn't already pinned, pin it now */
- /* (could still be pinned from it's section info still hanging around in the cache) */
- if(!(fspace_status & H5AC_ES__IS_PINNED)) {
- /* Pin free space header in the cache */
- if(H5AC_pin_protected_entry(f, fspace) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTPIN, NULL, "unable to pin free space header")
- } /* end if */
+ fspace->alignment = alignment;
+ fspace->threshold = threshold;
- /* Unlock free space header, now pinned */
+ /* Unlock free space header */
if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, fspace, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, NULL, "unable to release free space header")
@@ -239,9 +260,9 @@ H5FS_delete(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr)
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FS_delete, FAIL)
-#ifdef QAK
-HDfprintf(stderr, "%s: Deleting free space manager\n", FUNC);
-#endif /* QAK */
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Deleting free space manager, fs_addr = %a\n", FUNC, fs_addr);
+#endif /* H5FS_DEBUG */
/* Check arguments. */
HDassert(f);
@@ -254,19 +275,22 @@ HDfprintf(stderr, "%s: Deleting free space manager\n", FUNC);
fs_prot.cls_init_udata = NULL;
/* Protect the free space header */
- if(NULL == (fspace = H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, &fs_prot, NULL, H5AC_WRITE)))
+ if(NULL == (fspace = (H5FS_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, &fs_prot, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTPROTECT, FAIL, "unable to protect free space header")
+ /* Sanity check */
+ HDassert(fspace->sinfo == NULL);
+
/* Delete serialized section storage, if there are any */
-#ifdef QAK
+#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: fspace->sect_addr = %a\n", FUNC, fspace->sect_addr);
-#endif /* QAK */
+#endif /* H5FS_DEBUG */
if(fspace->serial_sect_count > 0) {
unsigned sinfo_status = 0; /* Free space section info's status in the metadata cache */
/* Sanity check */
HDassert(H5F_addr_defined(fspace->sect_addr));
- HDassert(fspace->sect_size > 0);
+ HDassert(fspace->alloc_sect_size > 0);
/* Check the free space section info's status in the metadata cache */
if(H5AC_get_entry_status(f, fspace->sect_addr, &sinfo_status) < 0)
@@ -278,32 +302,28 @@ HDfprintf(stderr, "%s: fspace->sect_addr = %a\n", FUNC, fspace->sect_addr);
HDassert(!(sinfo_status & H5AC_ES__IS_PINNED));
HDassert(!(sinfo_status & H5AC_ES__IS_PROTECTED));
-#ifdef QAK
+#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: Expunging free space section info from cache\n", FUNC);
-#endif /* QAK */
+#endif /* H5FS_DEBUG */
/* Evict the free space section info from the metadata cache */
- if(H5AC_expunge_entry(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr) < 0)
+ /* (Free file space) */
+ if(H5AC_expunge_entry(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, H5AC__FREE_FILE_SPACE_FLAG) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "unable to remove free space section info from cache")
-#ifdef QAK
+#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: Done expunging free space section info from cache\n", FUNC);
-#endif /* QAK */
+#endif /* H5FS_DEBUG */
} /* end if */
-
- /* Release the space in the file */
- if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_addr, fspace->alloc_sect_size) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections")
+ else {
+ /* Release the space in the file */
+ if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_addr, fspace->alloc_sect_size) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections")
+ } /* end else */
} /* end if */
- /* Release header's disk space */
- if(H5MF_xfree(f, H5FD_MEM_FSPACE_HDR, dxpl_id, fs_addr, (hsize_t)H5FS_HEADER_SIZE(f))<0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space header")
-
- /* Release the free space header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, fspace, H5AC__DELETED_FLAG) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, FAIL, "unable to release free space header")
- fspace = NULL;
-
done:
+ if(fspace && H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, fspace, H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0)
+ HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, FAIL, "unable to release free space header")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_delete() */
@@ -333,72 +353,140 @@ H5FS_close(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace)
/* Check arguments. */
HDassert(f);
HDassert(fspace);
-#ifdef QAK
-HDfprintf(stderr, "%s: Entering, fspace = %p, fspace->sinfo = %p\n", FUNC, fspace, fspace->sinfo);
-#endif /* QAK */
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Entering, fspace = %p, fspace->addr = %a, fspace->sinfo = %p\n", FUNC, fspace, fspace->addr, fspace->sinfo);
+#endif /* H5FS_DEBUG */
/* Check if section info is valid */
+ /* (i.e. the header "owns" the section info and it's not in the cache) */
if(fspace->sinfo) {
- HDassert(H5F_addr_defined(fspace->sect_addr));
-
- /* Unpin the free space section info in the cache */
- if(H5AC_unpin_entry(f, fspace->sinfo) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin free space section info")
-
- /* If there aren't any sections being managed, free the space for the sections */
-#ifdef QAK
-HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", FUNC, fspace->tot_sect_count);
-#endif /* QAK */
- if(fspace->tot_sect_count == 0) {
- haddr_t old_addr; /* Old section info address */
-
- HDassert(fspace->serial_sect_count == 0);
- HDassert(fspace->ghost_sect_count == 0);
-
- /* Free previous serialized sections disk space */
- old_addr = fspace->sect_addr;
- if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, old_addr, fspace->alloc_sect_size) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections")
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu, fspace->serial_sect_count = %Hu, fspace->sect_addr = %a, fspace->rc = %u\n", FUNC, fspace->tot_sect_count, fspace->serial_sect_count, fspace->sect_addr, fspace->rc);
+HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu, fspace->sect_size = %Hu\n", FUNC, fspace->alloc_sect_size, fspace->sect_size);
+#endif /* H5FS_DEBUG */
+ /* If there are sections to serialize, update them */
+ /* (if the free space manager is persistant) */
+ if(fspace->serial_sect_count > 0 && H5F_addr_defined(fspace->addr)) {
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Real sections to store in file\n", FUNC);
+#endif /* H5FS_DEBUG */
+ if(fspace->sinfo->dirty) {
+ /* Check if the section info is "floating" */
+ if(!H5F_addr_defined(fspace->sect_addr)) {
+ /* Sanity check */
+ HDassert(fspace->sect_size > 0);
+
+ /* Allocate space for the section info in file */
+ if(HADDR_UNDEF == (fspace->sect_addr = H5MF_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_size)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for free space sections")
+ fspace->alloc_sect_size = (size_t)fspace->sect_size;
+
+ /* Mark free space header as dirty */
+ if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
+ } /* end if */
+ } /* end if */
+ else
+ /* Sanity check that section info has address */
+ HDassert(H5F_addr_defined(fspace->sect_addr));
+
+ /* Cache the free space section info */
+ if(H5AC_set(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, fspace->sinfo, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, FAIL, "can't add free space sections to cache")
+ } /* end if */
+ else {
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: NOT storing section info in file\n", FUNC);
+#endif /* H5FS_DEBUG */
+ /* Check if space for the section info is allocated */
+ if(H5F_addr_defined(fspace->sect_addr)) {
+ /* Sanity check */
+ /* (section info should only be in the file if the header is */
+ HDassert(H5F_addr_defined(fspace->addr));
- /* Reset section info */
- fspace->sect_addr = HADDR_UNDEF;
- fspace->alloc_sect_size = fspace->sect_size = 0;
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Section info allocated though\n", FUNC);
+#endif /* H5FS_DEBUG */
+ /* Check if the section info is for the free space in the file */
+ /* (NOTE: This is the "bootstrapping" special case for the
+ * free space manager, to avoid freeing the space for the
+ * section info and re-creating it as a section in the
+ * manager. -QAK)
+ */
+ if(fspace->client == H5FS_CLIENT_FILE_ID) {
+ htri_t status; /* "can absorb" status for section into */
- /* Mark free space header as dirty */
- if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Section info is for file free space\n", FUNC);
+#endif /* H5FS_DEBUG */
+ /* Try to shrink the file or absorb the section info into a block aggregator */
+ if((status = H5MF_try_shrink(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_addr, fspace->alloc_sect_size)) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMERGE, FAIL, "can't check for absorbing section info")
+ else if(status == FALSE) {
+ /* Section info can't "go away", but it's free. Allow
+ * header to record it
+ */
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Section info can't 'go away', header will own it\n", FUNC);
+#endif /* H5FS_DEBUG */
+ } /* end if */
+ else {
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Section info went 'go away'\n", FUNC);
+#endif /* H5FS_DEBUG */
+ /* Reset section info in header */
+ fspace->sect_addr = HADDR_UNDEF;
+ fspace->alloc_sect_size = 0;
+
+ /* Mark free space header as dirty */
+ if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
+ } /* end else */
+ } /* end if */
+ else {
+ haddr_t old_sect_addr = fspace->sect_addr; /* Previous location of section info in file */
+ hsize_t old_alloc_sect_size = fspace->alloc_sect_size; /* Previous size of section info in file */
- /* Evict the section info from the metadata cache */
- if(H5AC_expunge_entry(f, dxpl_id, H5AC_FSPACE_SINFO, old_addr) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTREMOVE, FAIL, "unable to remove free space section info from cache")
- } /* end if */
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Section info is NOT for file free space\n", FUNC);
+#endif /* H5FS_DEBUG */
+ /* Reset section info in header */
+ fspace->sect_addr = HADDR_UNDEF;
+ fspace->alloc_sect_size = 0;
+
+ /* Mark free space header as dirty */
+ if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
+
+ /* Free previous serialized sections disk space */
+ if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, old_sect_addr, old_alloc_sect_size) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space sections")
+ } /* end if */
+ } /* end else */
+
+ /* Destroy section info */
+ if(H5FS_cache_sinfo_dest(f, fspace->sinfo) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTCLOSEOBJ, FAIL, "unable to destroy free space section info")
+ } /* end else */
+
+ /* Reset the header's pointer to the section info */
+ fspace->sinfo = NULL;
} /* end if */
else {
- unsigned sect_status = 0; /* Free space section's status in the metadata cache */
-
- /* Check if we've allocated any section info in the file & if it's still in the cache */
- if(H5F_addr_defined(fspace->sect_addr) && H5AC_get_entry_status(f, fspace->sect_addr, &sect_status) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "unable to check metadata cache status for free space header")
-
- /* If this free list header's section info exists and is still in the
- * cache, don't unpin the header - let the section info do it,
- * when the section info is evicted from the cache. -QAK
- */
- if(!(sect_status & H5AC_ES__IN_CACHE)) {
- /* Unpin the free space header in the cache */
- /* (the section info destructor would unpin it if the section info existed) */
- if(H5AC_unpin_entry(f, fspace) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin free space header")
- } /* end if */
+ /* Just sanity checks... */
+ if(fspace->serial_sect_count > 0)
+ /* Sanity check that section info has address */
+ HDassert(H5F_addr_defined(fspace->sect_addr));
} /* end else */
- /* Reset the header's pointer to the section info, so it will get pinned again
- * if the free space header is still in the metadata cache when the free
- * space manager is re-opened.
- */
- fspace->sinfo = NULL;
+ /* Decrement the reference count on the free space manager header */
+ if(H5FS_decr(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTDEC, FAIL, "unable to decrement ref. count on free space header")
done:
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Leaving, ret_value = %d, fspace->rc = %u\n", FUNC, ret_value, fspace->rc);
+#endif /* H5FS_DEBUG */
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_close() */
@@ -453,6 +541,10 @@ H5FS_new(size_t nclasses, const H5FS_section_class_t *classes[],
if(fspace->sect_cls[u].init_cls)
if((fspace->sect_cls[u].init_cls)(&fspace->sect_cls[u], cls_init_udata) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, NULL, "unable to initialize section class")
+
+ /* Determine maximum class-specific serialization size for each section */
+ if(fspace->sect_cls[u].serial_size > fspace->max_cls_serial_size)
+ fspace->max_cls_serial_size = fspace->sect_cls[u].serial_size;
} /* end for */
} /* end if */
@@ -473,7 +565,7 @@ done:
*
* Purpose: Collect meta storage info used by the free space manager
*
- * Return: Success: non-negative
+ * Return: Success: non-negative
* Failure: negative
*
* Programmer: Vailin Choi
@@ -494,12 +586,318 @@ H5FS_size(const H5F_t *f, const H5FS_t *fspace, hsize_t *meta_size)
HDassert(meta_size);
/* Get the free space size info */
- *meta_size += H5FS_HEADER_SIZE(f) + fspace->alloc_sect_size;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
+ *meta_size += H5FS_HEADER_SIZE(f) + (fspace->sinfo ? fspace->sect_size : fspace->alloc_sect_size);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5FS_size() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_incr
+ *
+ * Purpose: Increment reference count on free space header
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * February 7, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FS_incr(H5F_t *f, H5FS_t *fspace)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FS_incr, FAIL)
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Entering, fpace->addr = %a, fspace->rc = %u\n", FUNC, fspace->addr, fspace->rc);
+#endif /* H5FS_DEBUG */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(fspace);
+
+ /* Check if we should pin the header in the cache */
+ if(fspace->rc == 0 && H5F_addr_defined(fspace->addr))
+ if(H5AC_pin_protected_entry(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTPIN, FAIL, "unable to pin free space header")
+
+ /* Increment reference count on header */
+ fspace->rc++;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FS_incr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_decr
+ *
+ * Purpose: Decrement reference count on free space header
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * February 7, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FS_decr(H5F_t *f, H5FS_t *fspace)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FS_decr, FAIL)
#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Entering, fpace->addr = %a, fspace->rc = %u\n", FUNC, fspace->addr, fspace->rc);
+#endif /* H5FS_DEBUG */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(fspace);
+
+ /* Decrement reference count on header */
+ fspace->rc--;
+
+ /* Check if we should unpin the header in the cache */
+ if(fspace->rc == 0) {
+ if(H5F_addr_defined(fspace->addr)) {
+ if(H5AC_unpin_entry(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin free space header")
+ } /* end if */
+ else {
+ if(H5FS_cache_hdr_dest(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTCLOSEOBJ, FAIL, "unable to destroy free space header")
+ } /* end else */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FS_decr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_dirty
+ *
+ * Purpose: Mark free space header as dirty
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Feb 14 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FS_dirty(H5F_t *f, H5FS_t *fspace)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5FS_dirty)
+#ifdef QAK
+HDfprintf(stderr, "%s: Marking free space header as dirty\n", FUNC);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(fspace);
+
+ /* Check if the free space manager is persistant */
+ if(H5F_addr_defined(fspace->addr))
+ /* Mark header as dirty in cache */
+ if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FS_dirty() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_alloc_hdr()
+ *
+ * Purpose: Allocate space for the free-space manager header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Feb 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FS_alloc_hdr(H5F_t *f, H5FS_t *fspace, haddr_t *fs_addr, hid_t dxpl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FS_alloc_hdr, FAIL)
+
+ /* Check arguments. */
+ HDassert(f);
+ HDassert(fspace);
+
+ if(!H5F_addr_defined(fspace->addr)) {
+ /* Allocate space for the free space header */
+ if(HADDR_UNDEF == (fspace->addr = H5MF_alloc(f, H5FD_MEM_FSPACE_HDR, dxpl_id, (hsize_t)H5FS_HEADER_SIZE(f))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for free space header")
+
+ /* Cache the new free space header (pinned) */
+ if(H5AC_set(f, dxpl_id, H5AC_FSPACE_HDR, fspace->addr, fspace, H5AC__PIN_ENTRY_FLAG) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, FAIL, "can't add free space header to cache")
+ } /* end if */
+
+ if(fs_addr)
+ *fs_addr = fspace->addr;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5FS_alloc_hdr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_alloc_sect()
+ *
+ * Purpose: Allocate space for the free-space manager section info header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Feb 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FS_alloc_sect(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FS_alloc_sect, FAIL)
+
+ /* Check arguments. */
+ HDassert(f);
+ HDassert(fspace);
+
+ if(!H5F_addr_defined(fspace->sect_addr) && fspace->sinfo && fspace->serial_sect_count > 0) {
+ /* Allocate space for section info from aggregator/vfd */
+ /* (The original version called H5MF_alloc(), but that may cause sect_size to change again) */
+ if(HADDR_UNDEF == (fspace->sect_addr = H5MF_aggr_vfd_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_size)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for section info")
+
+ fspace->alloc_sect_size = fspace->sect_size;
+
+ /* Mark free-space header as dirty */
+ if(H5FS_dirty(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
+
+ /* Cache the free-space section info */
+ if(H5AC_set(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, fspace->sinfo, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, FAIL, "can't add free space sections to cache")
+
+ fspace->sinfo = NULL;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5FS_alloc_sect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_free()
+ *
+ * Purpose: Free space for free-space manager header and section info header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Feb 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FS_free(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ haddr_t saved_addr;
+ hsize_t saved_size;
+ unsigned cache_flags;
+ unsigned sinfo_status = 0;
+ unsigned hdr_status = 0;
+
+ FUNC_ENTER_NOAPI(H5FS_free, FAIL)
+
+ /* Check arguments. */
+ HDassert(f);
+ HDassert(fspace);
+
+ cache_flags = H5AC__DELETED_FLAG | H5AC__TAKE_OWNERSHIP_FLAG;;
+
+ if(H5F_addr_defined(fspace->sect_addr)) {
+
+ /* Check whether free-space manager section info is in cache or not */
+ if(H5AC_get_entry_status(f, fspace->sect_addr, &sinfo_status) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "unable to check metadata cache status for free-space section info")
+
+ /* Load free-space manager section info */
+ if(sinfo_status & H5AC_ES__IN_CACHE || !fspace->sinfo) {
+ if(NULL == (fspace->sinfo = (H5FS_sinfo_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, NULL, fspace, H5AC_READ)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, FAIL, "unable to load free space section info")
+
+ /* Unload and release ownership of the free-space manager section info */
+ if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, fspace->sinfo, cache_flags) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, FAIL, "unable to release free space section info")
+ }
+
+ saved_addr = fspace->sect_addr;
+ saved_size = fspace->alloc_sect_size;
+
+ fspace->sect_addr = HADDR_UNDEF;
+ fspace->alloc_sect_size = 0;
+
+ /* Free space for the free-space manager section info */
+ if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, saved_addr, saved_size) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections")
+
+ /* Mark free-space manager header as dirty */
+ if(H5FS_dirty(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
+ }
+
+ if(H5F_addr_defined(fspace->addr)) {
+ /* Check whether free-space manager header is in cache or not */
+ if(H5AC_get_entry_status(f, fspace->addr, &hdr_status) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "unable to check metadata cache status for free-space section info")
+
+ if(hdr_status & H5AC_ES__IN_CACHE) {
+ /* Unpin the free-space manager header */
+ if(H5AC_unpin_entry(f, fspace) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin fractal heap header")
+
+ /* Load the free-space manager header */
+ if(NULL == (fspace = (H5FS_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fspace->addr, NULL, fspace, H5AC_READ)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, FAIL, "unable to load free space section info")
+
+ /* Unload and release ownership of the free-space header */
+ if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, fspace->addr, fspace, cache_flags) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, FAIL, "unable to release free space section info")
+ }
+ saved_addr = fspace->addr;
+ fspace->addr = HADDR_UNDEF;
+
+ /* Free space for the free-space manager header */
+ if(H5MF_xfree(f, H5FD_MEM_FSPACE_HDR, dxpl_id, saved_addr, (hsize_t)H5FS_HEADER_SIZE(f)) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space header")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5FS_free() */
+
+#ifdef H5FS_DEBUG_ASSERT
/*-------------------------------------------------------------------------
* Function: H5FS_assert
@@ -518,16 +916,19 @@ herr_t
H5FS_assert(const H5FS_t *fspace)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_assert)
-#ifdef QAK
-HDfprintf(stderr, "%s: fspace->hdr->tot_sect_count = %Hu\n", "H5FS_assert", fspace->hdr->tot_sect_count);
+#ifndef QAK
+HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", "H5FS_assert", fspace->tot_sect_count);
#endif /* QAK */
- /* Sanity check sections */
- H5FS_sect_assert(fspace);
+ /* Checks for section info, if it's available */
+ if(fspace->sinfo) {
+ /* Sanity check sections */
+ H5FS_sect_assert(fspace);
- /* General assumptions about the section size counts */
- HDassert(fspace->sinfo->tot_size_count >= fspace->sinfo->serial_size_count);
- HDassert(fspace->sinfo->tot_size_count >= fspace->sinfo->ghost_size_count);
+ /* General assumptions about the section size counts */
+ HDassert(fspace->sinfo->tot_size_count >= fspace->sinfo->serial_size_count);
+ HDassert(fspace->sinfo->tot_size_count >= fspace->sinfo->ghost_size_count);
+ } /* end if */
/* General assumptions about the section counts */
HDassert(fspace->tot_sect_count >= fspace->serial_sect_count);
@@ -539,5 +940,4 @@ HDfprintf(stderr, "%s: fspace->hdr->tot_sect_count = %Hu\n", "H5FS_assert", fspa
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5FS_assert() */
-#endif /* H5FS_DEBUG */
-
+#endif /* H5FS_DEBUG_ASSERT */
diff --git a/src/H5FScache.c b/src/H5FScache.c
index 8ace571..8a345fe 100644
--- a/src/H5FScache.c
+++ b/src/H5FScache.c
@@ -36,6 +36,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5FSpkg.h" /* File free space */
+#include "H5MFprivate.h" /* File memory management */
#include "H5Vprivate.h" /* Vectors and arrays */
#include "H5WBprivate.h" /* Wrapped Buffers */
@@ -100,6 +101,7 @@ const H5AC_class_t H5AC_FSPACE_HDR[1] = {{
(H5AC_flush_func_t)H5FS_cache_hdr_flush,
(H5AC_dest_func_t)H5FS_cache_hdr_dest,
(H5AC_clear_func_t)H5FS_cache_hdr_clear,
+ (H5AC_notify_func_t)NULL,
(H5AC_size_func_t)H5FS_cache_hdr_size,
}};
@@ -110,6 +112,7 @@ const H5AC_class_t H5AC_FSPACE_SINFO[1] = {{
(H5AC_flush_func_t)H5FS_cache_sinfo_flush,
(H5AC_dest_func_t)H5FS_cache_sinfo_dest,
(H5AC_clear_func_t)H5FS_cache_sinfo_clear,
+ (H5AC_notify_func_t)NULL,
(H5AC_size_func_t)H5FS_cache_sinfo_size,
}};
@@ -179,7 +182,7 @@ H5FS_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_fs_prot,
size = H5FS_HEADER_SIZE(f);
/* Get a pointer to a buffer that's large enough for header */
- if(NULL == (hdr = H5WB_actual(wb, size)))
+ if(NULL == (hdr = (uint8_t *)H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read header from disk */
@@ -189,16 +192,16 @@ H5FS_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_fs_prot,
p = hdr;
/* Magic number */
- if(HDmemcmp(p, H5FS_HDR_MAGIC, (size_t)H5FS_SIZEOF_MAGIC))
+ if(HDmemcmp(p, H5FS_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, NULL, "wrong free space header signature")
- p += H5FS_SIZEOF_MAGIC;
+ p += H5_SIZEOF_MAGIC;
/* Version */
if(*p++ != H5FS_HDR_VERSION)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, NULL, "wrong free space header version")
/* Client ID */
- fspace->client = *p++;
+ fspace->client = (H5FS_client_t)*p++;
if(fspace->client >= H5FS_NUM_CLIENT_ID)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, NULL, "unknown client ID in free space header")
@@ -293,6 +296,45 @@ H5FS_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5F
HDassert(f);
HDassert(H5F_addr_defined(addr));
HDassert(fspace);
+ HDassert(H5F_addr_defined(fspace->addr));
+
+ /* Check if the header "owns" the section info */
+ if(fspace->sinfo) {
+ /* Sanity check - should not be trying to destroy header if it still
+ * "owns" section info
+ */
+ HDassert(!destroy);
+
+ /* Check if the section info is dirty */
+ if(fspace->sinfo->dirty) {
+ if(fspace->serial_sect_count > 0) {
+ /* Check if we need to allocate space for section info */
+ if(!H5F_addr_defined(fspace->sect_addr)) {
+ /* Sanity check */
+ HDassert(fspace->sect_size > 0);
+
+ /* Allocate space for the section info in file */
+ if(HADDR_UNDEF == (fspace->sect_addr = H5MF_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_size)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for free space sections")
+ fspace->alloc_sect_size = (size_t)fspace->sect_size;
+
+ /* Mark header dirty */
+ /* (don't use cache API, since we're in a callback) */
+ fspace->cache_info.is_dirty = TRUE;
+ } /* end if */
+
+ /* Write section info to file */
+ if(H5FS_cache_sinfo_flush(f, dxpl_id, FALSE, fspace->sect_addr, fspace->sinfo, NULL) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFLUSH, FAIL, "unable to save free space section info to disk")
+ } /* end if */
+
+ /* Mark section info clean */
+ fspace->sinfo->dirty = FALSE;
+ } /* end if */
+ } /* end if */
+ else if(fspace->serial_sect_count > 0)
+ /* Sanity check that section info has address */
+ HDassert(H5F_addr_defined(fspace->sect_addr));
if(fspace->cache_info.is_dirty) {
uint8_t *hdr; /* Pointer to header buffer */
@@ -308,15 +350,15 @@ H5FS_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5F
size = H5FS_HEADER_SIZE(f);
/* Get a pointer to a buffer that's large enough for header */
- if(NULL == (hdr = H5WB_actual(wb, size)))
+ if(NULL == (hdr = (uint8_t *)H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Get temporary pointer to header */
p = hdr;
/* Magic number */
- HDmemcpy(p, H5FS_HDR_MAGIC, (size_t)H5FS_SIZEOF_MAGIC);
- p += H5FS_SIZEOF_MAGIC;
+ HDmemcpy(p, H5FS_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
/* Version # */
*p++ = H5FS_HDR_VERSION;
@@ -400,9 +442,8 @@ done:
*
*-------------------------------------------------------------------------
*/
-/* ARGSUSED */
herr_t
-H5FS_cache_hdr_dest(H5F_t UNUSED *f, H5FS_t *fspace)
+H5FS_cache_hdr_dest(H5F_t *f, H5FS_t *fspace)
{
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -414,6 +455,12 @@ H5FS_cache_hdr_dest(H5F_t UNUSED *f, H5FS_t *fspace)
*/
HDassert(fspace);
+ /* We should not still be holding on to the free space section info */
+ HDassert(!fspace->sinfo);
+
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!fspace->cache_info.free_file_space_on_destroy || H5F_addr_defined(fspace->cache_info.addr));
+
/* Terminate the section classes for this free space list */
for(u = 0; u < fspace->nclasses ; u++) {
/* Call the class termination routine, if there is one */
@@ -422,12 +469,23 @@ H5FS_cache_hdr_dest(H5F_t UNUSED *f, H5FS_t *fspace)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "unable to finalize section class")
} /* end for */
+ /* Check for freeing file space for free space header */
+ if(fspace->cache_info.free_file_space_on_destroy) {
+ /* Sanity check */
+ HDassert(H5F_addr_defined(fspace->addr));
+
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_FSPACE_HDR, H5AC_dxpl_id, fspace->cache_info.addr, (hsize_t)H5FS_HEADER_SIZE(f)) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space header")
+ } /* end if */
+
/* Release the memory for the free space section classes */
if(fspace->sect_cls)
- fspace->sect_cls = H5FL_SEQ_FREE(H5FS_section_class_t, fspace->sect_cls);
+ fspace->sect_cls = (H5FS_section_class_t *)H5FL_SEQ_FREE(H5FS_section_class_t, fspace->sect_cls);
/* Free free space info */
- H5FL_FREE(H5FS_t, fspace);
+ (void)H5FL_FREE(H5FS_t, fspace);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -531,9 +589,6 @@ H5FS_cache_sinfo_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *
H5FS_sinfo_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5FS_cache_sinfo_load)
-#ifdef QAK
-HDfprintf(stderr, "%s: Load free space sections, addr = %a\n", FUNC, addr);
-#endif /* QAK */
/* Check arguments */
HDassert(f);
@@ -543,11 +598,6 @@ HDfprintf(stderr, "%s: Load free space sections, addr = %a\n", FUNC, addr);
/* Allocate a new free space section info */
if(NULL == (sinfo = H5FS_sinfo_new(f, fspace)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
- /* Link free space manager to section info */
- /* (for deserializing sections) */
- HDassert(fspace->sinfo == NULL);
- fspace->sinfo = sinfo;
/* Sanity check address */
if(H5F_addr_ne(addr, fspace->sect_addr))
@@ -566,9 +616,9 @@ HDfprintf(stderr, "%s: Load free space sections, addr = %a\n", FUNC, addr);
p = buf;
/* Magic number */
- if(HDmemcmp(p, H5FS_SINFO_MAGIC, (size_t)H5FS_SIZEOF_MAGIC))
+ if(HDmemcmp(p, H5FS_SINFO_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, NULL, "wrong free space sections signature")
- p += H5FS_SIZEOF_MAGIC;
+ p += H5_SIZEOF_MAGIC;
/* Version */
if(*p++ != H5FS_SINFO_VERSION)
@@ -670,7 +720,7 @@ HDfprintf(stderr, "%s: Load free space sections, addr = %a\n", FUNC, addr);
done:
if(buf)
- H5FL_BLK_FREE(sect_block, buf);
+ (void)H5FL_BLK_FREE(sect_block, buf);
if(!ret_value && sinfo)
(void)H5FS_cache_sinfo_dest(f, sinfo);
@@ -807,7 +857,7 @@ H5FS_cache_sinfo_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H
HDassert(sinfo->fspace);
HDassert(sinfo->fspace->sect_cls);
- if(sinfo->cache_info.is_dirty) {
+ if(sinfo->cache_info.is_dirty || sinfo->dirty) {
H5FS_iter_ud_t udata; /* User data for callbacks */
uint8_t *buf = NULL; /* Temporary raw data buffer */
uint8_t *p; /* Pointer into raw data buffer */
@@ -825,8 +875,8 @@ H5FS_cache_sinfo_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H
p = buf;
/* Magic number */
- HDmemcpy(p, H5FS_SINFO_MAGIC, (size_t)H5FS_SIZEOF_MAGIC);
- p += H5FS_SIZEOF_MAGIC;
+ HDmemcpy(p, H5FS_SINFO_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
/* Version # */
*p++ = H5FS_SINFO_VERSION;
@@ -863,9 +913,10 @@ H5FS_cache_sinfo_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H
if(H5F_block_write(f, H5FD_MEM_FSPACE_SINFO, sinfo->fspace->sect_addr, (size_t)sinfo->fspace->sect_size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFLUSH, FAIL, "unable to save free space sections to disk")
- H5FL_BLK_FREE(sect_block, buf);
+ (void)H5FL_BLK_FREE(sect_block, buf);
sinfo->cache_info.is_dirty = FALSE;
+ sinfo->dirty = FALSE;
} /* end if */
if(destroy)
@@ -888,6 +939,10 @@ done:
* Programmer: Quincey Koziol
* Saturday, March 11, 2006
*
+ * Modifications:
+ * Vailin Choi, July 29th, 2008
+ * Add HDassert() to make sure "free" method exists before calling
+ *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -900,6 +955,7 @@ H5FS_sinfo_free_sect_cb(void *_sect, void UNUSED *key, void *op_data)
HDassert(sect);
HDassert(sinfo);
+ HDassert(sinfo->fspace->sect_cls[sect->type].free);
/* Call the section's class 'free' method on the section */
(*sinfo->fspace->sect_cls[sect->type].free)(sect);
@@ -936,7 +992,7 @@ H5FS_sinfo_free_node_cb(void *item, void UNUSED *key, void *op_data)
H5SL_destroy(fspace_node->sect_list, H5FS_sinfo_free_sect_cb, op_data);
/* Release free space list node */
- H5FL_FREE(H5FS_node_t, fspace_node);
+ (void)H5FL_FREE(H5FS_node_t, fspace_node);
FUNC_LEAVE_NOAPI(0)
} /* H5FS_sinfo_free_node_cb() */
@@ -955,7 +1011,6 @@ H5FS_sinfo_free_node_cb(void *item, void UNUSED *key, void *op_data)
*
*-------------------------------------------------------------------------
*/
-/* ARGSUSED */
herr_t
H5FS_cache_sinfo_dest(H5F_t *f, H5FS_sinfo_t *sinfo)
{
@@ -971,6 +1026,20 @@ H5FS_cache_sinfo_dest(H5F_t *f, H5FS_sinfo_t *sinfo)
HDassert(sinfo->fspace);
HDassert(sinfo->bins);
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!sinfo->cache_info.free_file_space_on_destroy || H5F_addr_defined(sinfo->cache_info.addr));
+
+ /* Check for freeing file space for free space section info */
+ if(sinfo->cache_info.free_file_space_on_destroy) {
+ /* Sanity check */
+ HDassert(sinfo->fspace->alloc_sect_size > 0);
+
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, H5AC_dxpl_id, sinfo->cache_info.addr, (hsize_t)sinfo->fspace->alloc_sect_size) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space section info")
+ } /* end if */
+
/* Clear out lists of nodes */
for(u = 0; u < sinfo->nbins; u++)
if(sinfo->bins[u].bin_list) {
@@ -979,22 +1048,24 @@ H5FS_cache_sinfo_dest(H5F_t *f, H5FS_sinfo_t *sinfo)
} /* end if */
/* Release bins for skip lists */
- sinfo->bins = H5FL_SEQ_FREE(H5FS_bin_t, sinfo->bins);
+ sinfo->bins = (H5FS_bin_t *)H5FL_SEQ_FREE(H5FS_bin_t, sinfo->bins);
/* Release skip list for merging sections */
if(sinfo->merge_list)
if(H5SL_close(sinfo->merge_list) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTCLOSEOBJ, FAIL, "can't destroy section merging skip list")
- /* Unpin the free space header in the cache */
+ /* Decrement the reference count on free space header */
/* (make certain this is last action with section info, to allow for header
* disappearing immediately)
*/
- if(H5AC_unpin_entry(f, sinfo->fspace) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin free space header")
+ sinfo->fspace->sinfo = NULL;
+ if(H5FS_decr(f, sinfo->fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTDEC, FAIL, "unable to decrement ref. count on free space header")
+ sinfo->fspace = NULL;
/* Release free space section info */
- H5FL_FREE(H5FS_sinfo_t, sinfo);
+ (void)H5FL_FREE(H5FS_sinfo_t, sinfo);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1063,7 +1134,7 @@ H5FS_cache_sinfo_size(const H5F_t UNUSED *f, const H5FS_sinfo_t *sinfo, size_t *
HDassert(size_ptr);
/* Set size value */
- H5_ASSIGN_OVERFLOW(/* To: */ *size_ptr, /* From: */ sinfo->fspace->sect_size, /* From: */ hsize_t, /* To: */ size_t);
+ H5_ASSIGN_OVERFLOW(/* To: */ *size_ptr, /* From: */ sinfo->fspace->alloc_sect_size, /* From: */ hsize_t, /* To: */ size_t);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5FS_cache_sinfo_size() */
diff --git a/src/H5FSdbg.c b/src/H5FSdbg.c
index 0ac7b3b..8cf64ef 100644
--- a/src/H5FSdbg.c
+++ b/src/H5FSdbg.c
@@ -30,6 +30,7 @@
#define H5FS_PACKAGE /*suppress error about including H5FSpkg */
#define H5HF_DEBUGGING /* Need access to fractal heap debugging routines */
+#define H5MF_DEBUGGING /* Need access to file space debugging routines */
/***********/
/* Headers */
@@ -38,6 +39,7 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5FSpkg.h" /* File free space */
#include "H5HFprivate.h" /* Fractal heaps */
+#include "H5MFprivate.h" /* File memory management */
/****************/
/* Local Macros */
@@ -85,6 +87,10 @@
* koziol@ncsa.uiuc.edu
* May 9 2006
*
+ * Modifications:
+ * Vailin Choi, July 29th, 2008
+ * Add H5FS_CLIENT_FILE_ID for File Memory Management
+ *
*-------------------------------------------------------------------------
*/
herr_t
@@ -113,7 +119,7 @@ H5FS_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int
/*
* Load the free space header.
*/
- if(NULL == (fspace = H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, addr, &fs_prot, NULL, H5AC_READ)))
+ if(NULL == (fspace = (H5FS_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, addr, &fs_prot, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, FAIL, "unable to load free space header")
/* Print opening message */
@@ -124,7 +130,8 @@ H5FS_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int
*/
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
"Free space client:",
- (fspace->client == H5FS_CLIENT_FHEAP_ID ? "Fractal heap" : "Unknown"));
+ (fspace->client == H5FS_CLIENT_FHEAP_ID ? "Fractal heap" :
+ (fspace->client == H5FS_CLIENT_FILE_ID ? "File" : "Unknown")));
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
"Total free space tracked:",
fspace->tot_space);
@@ -252,14 +259,17 @@ H5FS_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, FILE *stream, int
/*
* Load the free space header.
*/
- if(NULL == (fspace = H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, &fs_prot, NULL, H5AC_READ)))
+ if(NULL == (fspace = (H5FS_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, &fs_prot, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, FAIL, "unable to load free space header")
/* Retrieve the client id */
client = fspace->client;
/* Release the free space header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, fspace, H5AC__NO_FLAGS_SET) < 0)
+ /* (set the "deleted" flag for the unprotect, so the cache entry is removed
+ * and reloaded later, with the correct client information -QAK)
+ */
+ if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, fspace, H5AC__DELETED_FLAG) < 0)
HDONE_ERROR(H5E_FSPACE, H5E_PROTECT, FAIL, "unable to release free space header")
fspace = NULL;
@@ -275,6 +285,11 @@ H5FS_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, FILE *stream, int
HGOTO_ERROR(H5E_FSPACE, H5E_SYSTEM, FAIL, "unable to dump fractal heap free space sections")
break;
+ case H5FS_CLIENT_FILE_ID:
+ if(H5MF_sects_debug(f, dxpl_id, fs_addr, stream, indent + 3, MAX(0, fwidth - 3)) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_SYSTEM, FAIL, "unable to dump file free space sections")
+ break;
+
default:
HDfprintf(stream, "Unknown client!\n");
break;
diff --git a/src/H5FSpkg.h b/src/H5FSpkg.h
index 9119902..1786b44 100644
--- a/src/H5FSpkg.h
+++ b/src/H5FSpkg.h
@@ -28,9 +28,15 @@
#ifndef _H5FSpkg_H
#define _H5FSpkg_H
-/* Uncomment this macro to enable extra sanity checking */
+/* Uncomment this macro to enable debugging output for free space manager */
/* #define H5FS_DEBUG */
+/* Uncomment this macro to enable debugging output for free space sections */
+/* #define H5FS_SINFO_DEBUG */
+
+/* Uncomment this macro to enable extra sanity checking */
+/* #define H5FS_DEBUG_ASSERT */
+
/* Get package's private header */
#include "H5FSprivate.h" /* File free space */
@@ -42,19 +48,12 @@
/* Package Private Macros */
/**************************/
-/* Size of signature information (on disk) */
-#define H5FS_SIZEOF_MAGIC 4
-
-/* Free space signatures */
-#define H5FS_HDR_MAGIC "FSHD" /* Header */
-#define H5FS_SINFO_MAGIC "FSSE" /* Serialized sections */
-
/* Size of checksum information (on disk) */
#define H5FS_SIZEOF_CHKSUM 4
/* "Standard" size of prefix information for free space metadata */
#define H5FS_METADATA_PREFIX_SIZE ( \
- H5FS_SIZEOF_MAGIC /* Signature */ \
+ H5_SIZEOF_MAGIC /* Signature */ \
+ 1 /* Version */ \
+ H5FS_SIZEOF_CHKSUM /* Metadata checksum */ \
)
@@ -117,7 +116,7 @@ typedef struct H5FS_node_t {
H5SL_t *sect_list; /* Skip list to hold pointers to actual free list section node */
} H5FS_node_t;
-/* Information about sections managed */
+/* Free space section info */
typedef struct H5FS_sinfo_t {
/* Information for H5AC cache functions, _must_ be first field in structure */
H5AC_info_t cache_info;
@@ -126,6 +125,7 @@ typedef struct H5FS_sinfo_t {
H5FS_bin_t *bins; /* Array of lists of lists of free sections */
/* Computed/cached values */
+ hbool_t dirty; /* Whether this info in memory is out of sync w/info in file */
unsigned nbins; /* Number of bins */
size_t serial_size; /* Total size of all serializable sections */
size_t tot_size_count; /* Total number of differently sized sections */
@@ -140,7 +140,7 @@ typedef struct H5FS_sinfo_t {
H5SL_t *merge_list; /* Skip list to hold sections for detecting merges */
} H5FS_sinfo_t;
-/* Main free space info */
+/* Free space header info */
struct H5FS_t {
/* Information for H5AC cache functions, _must_ be first field in structure */
H5AC_info_t cache_info;
@@ -166,8 +166,17 @@ struct H5FS_t {
hsize_t alloc_sect_size; /* Allocated size of the section info in the file */
/* Computed/cached values */
+ unsigned rc; /* Count of outstanding references to struct */
haddr_t addr; /* Address of free space header on disk */
H5FS_sinfo_t *sinfo; /* Section information */
+ unsigned sinfo_lock_count; /* # of times the section info has been locked */
+ hbool_t sinfo_protected; /* Whether the section info was protected when locked */
+ hbool_t sinfo_modified; /* Whether the section info has been modified while locked */
+ H5AC_protect_t sinfo_accmode; /* Access mode for protecting the section info */
+ size_t max_cls_serial_size; /* Max. additional size of serialized form of section */
+ hsize_t threshold; /* Threshold for alignment */
+ hsize_t alignment; /* Alignment */
+
/* Memory data structures (not stored directly) */
H5FS_section_class_t *sect_cls; /* Array of section classes for this free list */
@@ -204,16 +213,13 @@ H5FL_EXTERN(H5FS_t);
/* Free space manager header routines */
H5_DLL H5FS_t *H5FS_new(size_t nclasses, const H5FS_section_class_t *classes[],
void *cls_init_udata);
+H5_DLL herr_t H5FS_incr(H5F_t *f, H5FS_t *fspace);
+H5_DLL herr_t H5FS_decr(H5F_t *f, H5FS_t *fspace);
+H5_DLL herr_t H5FS_dirty(H5F_t *f, H5FS_t *fspace);
/* Free space section routines */
H5_DLL H5FS_sinfo_t *H5FS_sinfo_new(H5F_t *f, H5FS_t *fspace);
-/* Debugging routines for dumping file structures */
-H5_DLL herr_t H5FS_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
- FILE *stream, int indent, int fwidth);
-H5_DLL herr_t H5FS_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
- FILE *stream, int indent, int fwidth, haddr_t fs_addr, haddr_t client_addr);
-
/* Metadata cache callbacks */
H5_DLL herr_t H5FS_cache_hdr_dest(H5F_t *f, H5FS_t *hdr);
H5_DLL herr_t H5FS_cache_sinfo_dest(H5F_t *f, H5FS_sinfo_t *sinfo);
@@ -224,5 +230,11 @@ H5_DLL herr_t H5FS_assert(const H5FS_t *fspace);
H5_DLL herr_t H5FS_sect_assert(const H5FS_t *fspace);
#endif /* H5FS_DEBUG */
+/* Testing routines */
+#ifdef H5FS_TESTING
+H5_DLL herr_t H5FS_get_cparam_test(const H5FS_t *fh, H5FS_create_t *cparam);
+H5_DLL int H5FS_cmp_cparam_test(const H5FS_create_t *cparam1, const H5FS_create_t *cparam2);
+#endif /* H5FS_TESTING */
+
#endif /* _H5FSpkg_H */
diff --git a/src/H5FSprivate.h b/src/H5FSprivate.h
index bf24b8a..145c374 100644
--- a/src/H5FSprivate.h
+++ b/src/H5FSprivate.h
@@ -43,10 +43,14 @@
* serialized to the file.
*/
#define H5FS_CLS_SEPAR_OBJ 0x02 /* Objects in this class shouldn't
- * participate in merge operations
+ * participate in merge operations.
*/
#define H5FS_CLS_MERGE_SYM 0x04 /* Objects in this class only merge
- * with other objects in this class
+ * with other objects in this class.
+ */
+#define H5FS_CLS_ADJUST_OK 0x08 /* Objects in this class can be merged
+ * without requiring a can_adjust/adjust
+ * callback pair.
*/
/* Flags for H5FS_add() */
@@ -103,6 +107,7 @@ typedef struct H5FS_section_class_t {
herr_t (*shrink)(H5FS_section_info_t **, void *); /* Routine to shrink container */
herr_t (*free)(H5FS_section_info_t *); /* Routine to free node */
herr_t (*valid)(const struct H5FS_section_class_t *, const H5FS_section_info_t *); /* Routine to check if a section is valid */
+ H5FS_section_info_t *(*split)(H5FS_section_info_t *, hsize_t); /* Routine to create the split section */
herr_t (*debug)(const H5FS_section_info_t *, FILE *, int , int ); /* Routine to dump debugging information about a section */
} H5FS_section_class_t;
@@ -123,6 +128,7 @@ struct H5FS_section_info_t {
/* Free space client IDs for identifying user of free space */
typedef enum H5FS_client_t {
H5FS_CLIENT_FHEAP_ID = 0, /* Free space is used by fractal heap */
+ H5FS_CLIENT_FILE_ID, /* Free space is used by file */
H5FS_NUM_CLIENT_ID /* Number of free space client IDs (must be last) */
} H5FS_client_t;
@@ -135,6 +141,19 @@ typedef struct H5FS_create_t {
hsize_t max_sect_size; /* Maximum size of section to track */
} H5FS_create_t;
+/* Free space statistics info */
+typedef struct H5FS_stat_t {
+ hsize_t tot_space; /* Total amount of space tracked */
+ hsize_t tot_sect_count; /* Total # of sections tracked */
+ hsize_t serial_sect_count; /* # of serializable sections tracked */
+ hsize_t ghost_sect_count; /* # of un-serializable sections tracked */
+ haddr_t addr; /* Address of free space header on disk */
+ hsize_t hdr_size; /* Size of the free-space header on disk */
+ haddr_t sect_addr; /* Address of the section info in the file */
+ hsize_t alloc_sect_size; /* Allocated size of the section info in the file */
+ hsize_t sect_size; /* Size of the section info in the file */
+} H5FS_stat_t;
+
/* Typedef for iteration operations */
typedef herr_t (*H5FS_operator_t)(const H5FS_section_info_t *sect,
void *operator_data/*in,out*/);
@@ -155,26 +174,41 @@ H5FL_SEQ_EXTERN(H5FS_section_class_t);
/* Free space manager routines */
H5_DLL H5FS_t *H5FS_create(H5F_t *f, hid_t dxpl_id, haddr_t *fs_addr,
const H5FS_create_t *fs_create, size_t nclasses,
- const H5FS_section_class_t *classes[], void *cls_init_udata);
+ const H5FS_section_class_t *classes[], void *cls_init_udata, hsize_t alignment, hsize_t threshold);
H5_DLL H5FS_t *H5FS_open(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr,
- size_t nclasses, const H5FS_section_class_t *classes[], void *cls_init_udata);
+ size_t nclasses, const H5FS_section_class_t *classes[], void *cls_init_udata, hsize_t alignment, hsize_t threshold);
H5_DLL herr_t H5FS_size(const H5F_t *f, const H5FS_t *fspace, hsize_t *meta_size);
H5_DLL herr_t H5FS_delete(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr);
H5_DLL herr_t H5FS_close(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace);
+H5_DLL herr_t H5FS_alloc_hdr(H5F_t *f, H5FS_t *fspace, haddr_t *fs_addr, hid_t dxpl_id);
+H5_DLL herr_t H5FS_alloc_sect(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id);
+H5_DLL herr_t H5FS_free(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id);
/* Free space section routines */
H5_DLL herr_t H5FS_sect_add(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
H5FS_section_info_t *node, unsigned flags, void *op_data);
+H5_DLL htri_t H5FS_sect_try_merge(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
+ H5FS_section_info_t *sect, unsigned flags, void *op_data);
+H5_DLL htri_t H5FS_sect_try_extend(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
+ haddr_t addr, hsize_t size, hsize_t extra_requested);
H5_DLL herr_t H5FS_sect_remove(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
H5FS_section_info_t *node);
H5_DLL htri_t H5FS_sect_find(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
hsize_t request, H5FS_section_info_t **node);
H5_DLL herr_t H5FS_sect_iterate(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5FS_operator_t op, void *op_data);
-H5_DLL herr_t H5FS_get_sect_count(const H5FS_t *fspace, hsize_t *nsects);
+H5_DLL herr_t H5FS_sect_stats(const H5FS_t *fspace, hsize_t *tot_space,
+ hsize_t *nsects);
H5_DLL herr_t H5FS_sect_change_class(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
H5FS_section_info_t *sect, unsigned new_class);
+/* Statistics routine */
+H5_DLL herr_t H5FS_stat_info(const H5F_t *f, const H5FS_t *frsp, H5FS_stat_t *stats);
+
/* Debugging routines for dumping file structures */
+H5_DLL herr_t H5FS_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ FILE *stream, int indent, int fwidth);
+H5_DLL herr_t H5FS_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ FILE *stream, int indent, int fwidth, haddr_t fs_addr, haddr_t client_addr);
H5_DLL herr_t H5FS_sect_debug(const H5FS_t *fspace, const H5FS_section_info_t *sect,
FILE *stream, int indent, int fwidth);
diff --git a/src/H5FSsection.c b/src/H5FSsection.c
index de2fbc5..30885a9 100644
--- a/src/H5FSsection.c
+++ b/src/H5FSsection.c
@@ -42,12 +42,6 @@
/* Local Macros */
/****************/
-/* Default starting size of section buffer */
-#define H5FS_SINFO_SIZE_DEFAULT 64
-
-/* Max. height of the skip list holding free list nodes */
-#define H5FS_DEFAULT_SKIPLIST_HEIGHT 16
-
/******************/
/* Local Typedefs */
@@ -69,26 +63,26 @@ typedef struct {
/********************/
/* Local Prototypes */
/********************/
-static herr_t H5FS_sect_increase(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
- const H5FS_section_class_t *cls, unsigned flags);
-static herr_t H5FS_sect_decrease(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
- const H5FS_section_class_t *cls);
+static herr_t H5FS_sect_increase(H5FS_t *fspace, const H5FS_section_class_t *cls,
+ unsigned flags);
+static herr_t H5FS_sect_decrease(H5FS_t *fspace, const H5FS_section_class_t *cls);
static herr_t H5FS_size_node_decr(H5FS_sinfo_t *sinfo, unsigned bin, H5FS_node_t *fspace_node,
const H5FS_section_class_t *cls);
static herr_t H5FS_sect_unlink_size(H5FS_sinfo_t *sinfo, const H5FS_section_class_t *cls,
H5FS_section_info_t *sect);
-static herr_t H5FS_sect_unlink_rest(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
+static herr_t H5FS_sect_unlink_rest(H5FS_t *fspace,
const H5FS_section_class_t *cls, H5FS_section_info_t *sect);
+static herr_t H5FS_sect_remove_real(H5FS_t *fspace, H5FS_section_info_t *sect);
static herr_t H5FS_sect_link_size(H5FS_sinfo_t *sinfo, const H5FS_section_class_t *cls,
H5FS_section_info_t *sect);
-static herr_t H5FS_sect_link_rest(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
- const H5FS_section_class_t *cls, H5FS_section_info_t *sect, unsigned flags);
-static herr_t H5FS_sect_link(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
+static herr_t H5FS_sect_link_rest(H5FS_t *fspace, const H5FS_section_class_t *cls,
H5FS_section_info_t *sect, unsigned flags);
-static herr_t H5FS_sect_merge(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
- H5FS_section_info_t **sect, void *op_data);
+static herr_t H5FS_sect_link(H5FS_t *fspace, H5FS_section_info_t *sect,
+ unsigned flags);
+static herr_t H5FS_sect_merge(H5FS_t *fspace, H5FS_section_info_t **sect,
+ void *op_data);
static htri_t H5FS_sect_find_node(H5FS_t *fspace, hsize_t request, H5FS_section_info_t **node);
-static herr_t H5FS_sect_serialize_size(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace);
+static herr_t H5FS_sect_serialize_size(H5FS_t *fspace);
/*********************/
@@ -140,6 +134,9 @@ H5FS_sinfo_new(H5F_t *f, H5FS_t *fspace)
/* Check arguments. */
HDassert(f);
HDassert(fspace);
+#ifdef H5FS_SINFO_DEBUG
+HDfprintf(stderr, "%s: fspace->addr = %a\n", FUNC, fspace->addr);
+#endif /* H5FS_SINFO_DEBUG */
/* Allocate the free space header */
if(NULL == (sinfo = H5FL_CALLOC(H5FS_sinfo_t)))
@@ -150,113 +147,371 @@ H5FS_sinfo_new(H5F_t *f, H5FS_t *fspace)
sinfo->sect_prefix_size = H5FS_SINFO_PREFIX_SIZE(f);
sinfo->sect_off_size = (fspace->max_sect_addr + 7) / 8;
sinfo->sect_len_size = H5V_limit_enc_size((uint64_t)fspace->max_sect_size);
- sinfo->fspace = fspace;
-#ifdef QAK
+#ifdef H5FS_SINFO_DEBUG
+HDfprintf(stderr, "%s: fspace->max_sect_size = %Hu\n", FUNC, fspace->max_sect_size);
+HDfprintf(stderr, "%s: fspace->max_sect_addr = %u\n", FUNC, fspace->max_sect_addr);
HDfprintf(stderr, "%s: sinfo->nbins = %u\n", FUNC, sinfo->nbins);
HDfprintf(stderr, "%s: sinfo->sect_off_size = %u, sinfo->sect_len_size = %u\n", FUNC, sinfo->sect_off_size, sinfo->sect_len_size);
-#endif /* QAK */
+#endif /* H5FS_SINFO_DEBUG */
/* Allocate space for the section size bins */
if(NULL == (sinfo->bins = H5FL_SEQ_CALLOC(H5FS_bin_t, (size_t)sinfo->nbins)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for free space section bin array")
+ /* Increment the reference count on the free space manager header */
+ if(H5FS_incr(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINC, NULL, "unable to increment ref. count on free space header")
+ sinfo->fspace = fspace;
+
+ /* Link free space manager to section info */
+ /* (for deserializing sections) */
+ HDassert(fspace->sinfo == NULL);
+ fspace->sinfo = sinfo;
+
/* Set return value */
ret_value = sinfo;
done:
+ if(ret_value == NULL && sinfo) {
+ /* Release bins for skip lists */
+ if(sinfo->bins)
+ sinfo->bins = H5FL_SEQ_FREE(H5FS_bin_t, sinfo->bins);
+
+ /* Release free space section info */
+ sinfo = H5FL_FREE(H5FS_sinfo_t, sinfo);
+ } /* end if */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_sinfo_new() */
/*-------------------------------------------------------------------------
- * Function: H5FS_sinfo_pin
+ * Function: H5FS_sinfo_lock
*
- * Purpose: Pin the section info for the free space manager in memory
- * Either loads section info from disk, or creates new section info
+ * Purpose: Make certain the section info for the free space manager is
+ * in memory.
*
- * Return: Success: non-NULL, pointer to section info struct
- * Failure: NULL
+ * Either uses existing section info owned by the free space
+ * header, loads section info from disk, or creates new section
+ * info
+ *
+ * Return: Success: non-negative
+ * Failure: negative
*
* Programmer: Quincey Koziol
- * Monday, July 31, 2006
+ * Thursday, February 7, 2008
*
*-------------------------------------------------------------------------
*/
-static H5FS_sinfo_t *
-H5FS_sinfo_pin(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace)
+static herr_t
+H5FS_sinfo_lock(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5AC_protect_t accmode)
{
- H5FS_sinfo_t *sinfo; /* Section information struct created */
- H5FS_sinfo_t *ret_value; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5FS_sinfo_pin)
-#ifdef QAK
-HDfprintf(stderr, "%s: Called, fspace->sect_addr = %a\n", FUNC, fspace->sect_addr);
-#endif /* QAK */
+ FUNC_ENTER_NOAPI_NOINIT(H5FS_sinfo_lock)
+#ifdef H5FS_SINFO_DEBUG
+HDfprintf(stderr, "%s: Called, fspace->addr = %a, fspace->sinfo = %p, fspace->sect_addr = %a\n", FUNC, fspace->addr, fspace->sinfo, fspace->sect_addr);
+HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu, fspace->sect_size = %Hu\n", FUNC, fspace->alloc_sect_size, fspace->sect_size);
+#endif /* H5FS_SINFO_DEBUG */
/* Check arguments. */
HDassert(f);
HDassert(fspace);
- /* Create new section info, if it doesn't exist yet */
- if(!H5F_addr_defined(fspace->sect_addr)) {
-#ifdef QAK
-HDfprintf(stderr, "%s: Allocating new section info\n", FUNC);
-#endif /* QAK */
- /* Sanity check */
- HDassert(fspace->tot_sect_count == 0);
- HDassert(fspace->serial_sect_count == 0);
- HDassert(fspace->ghost_sect_count == 0);
+ /* If the free space header doesn't already "own" the section info, load
+ * section info or create it
+ */
+ if(fspace->sinfo) {
+ /* Check if the section info was protected & we want a different access mode */
+ if(fspace->sinfo_protected && accmode != fspace->sinfo_accmode) {
+ /* Check if we need to switch from read-only access to read-write */
+ if(H5AC_WRITE == accmode) {
+ /* Unprotect the read-only section info */
+ if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, fspace->sinfo, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, FAIL, "unable to release free space section info")
+
+ /* Re-protect the section info with read-write access */
+ if(NULL == (fspace->sinfo = (H5FS_sinfo_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, NULL, fspace, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTPROTECT, FAIL, "unable to load free space sections")
+
+ /* Switch the access mode we have */
+ fspace->sinfo_accmode = H5AC_WRITE;
+ } /* end if */
+ } /* end if */
+ } /* end if */
+ else {
+ /* If the section address is defined, load it from the file */
+ if(H5F_addr_defined(fspace->sect_addr)) {
+ /* Sanity check */
+ HDassert(fspace->sinfo_protected == FALSE);
+ HDassert(H5F_addr_defined(fspace->addr));
+
+#ifdef H5FS_SINFO_DEBUG
+HDfprintf(stderr, "%s: Reading in existing sections, fspace->sect_addr = %a\n", FUNC, fspace->sect_addr);
+#endif /* H5FS_SINFO_DEBUG */
+ /* Protect the free space sections */
+ if(NULL == (fspace->sinfo = (H5FS_sinfo_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, NULL, fspace, accmode)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTPROTECT, FAIL, "unable to load free space sections")
+
+ /* Remember that we protected the section info & the access mode */
+ fspace->sinfo_protected = TRUE;
+ fspace->sinfo_accmode = accmode;
+ } /* end if */
+ else {
+#ifdef H5FS_SINFO_DEBUG
+HDfprintf(stderr, "%s: Creating new section info\n", FUNC);
+#endif /* H5FS_SINFO_DEBUG */
+ /* Sanity check */
+ HDassert(fspace->tot_sect_count == 0);
+ HDassert(fspace->serial_sect_count == 0);
+ HDassert(fspace->ghost_sect_count == 0);
+
+ /* Allocate and initialize free space section info */
+ if(NULL == (fspace->sinfo = H5FS_sinfo_new(f, fspace)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTCREATE, FAIL, "can't create section info")
+
+ /* Set initial size of section info to 0 */
+ fspace->sect_size = fspace->alloc_sect_size = 0;
+ } /* end if */
+ } /* end if */
+ HDassert(fspace->rc == 2);
- /* Allocate and initialize free space section info */
- if(NULL == (sinfo = H5FS_sinfo_new(f, fspace)))
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTCREATE, NULL, "can't create section info")
+ /* Increment the section info lock count */
+ fspace->sinfo_lock_count++;
- /* Allocate space for the section info */
- fspace->sect_size = H5FS_SINFO_SIZE_DEFAULT;
- fspace->alloc_sect_size = (size_t)fspace->sect_size;
- if(HADDR_UNDEF == (fspace->sect_addr = H5MF_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->alloc_sect_size)))
- HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, NULL, "file allocation failed for free space sections")
-#ifdef QAK
-HDfprintf(stderr, "%s: New section info, addr = %a, size = %Hu\n", FUNC, fspace->sect_addr, fspace->alloc_sect_size);
-#endif /* QAK */
+done:
+#ifdef H5FS_SINFO_DEBUG
+HDfprintf(stderr, "%s: Leaving, fspace->addr = %a, fspace->sinfo = %p, fspace->sect_addr = %a\n", FUNC, fspace->addr, fspace->sinfo, fspace->sect_addr);
+HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu, fspace->sect_size = %Hu\n", FUNC, fspace->alloc_sect_size, fspace->sect_size);
+#endif /* H5FS_SINFO_DEBUG */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5FS_sinfo_lock() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_sinfo_unlock
+ *
+ * Purpose: Release the section info, either giving ownership back to
+ * the cache or letting the free space header keep it.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, February 7, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FS_sinfo_unlock(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, hbool_t modified)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5FS_sinfo_unlock)
+#ifdef H5FS_SINFO_DEBUG
+HDfprintf(stderr, "%s: Called, modified = %t, fspace->addr = %a, fspace->sect_addr = %a\n", FUNC, modified, fspace->addr, fspace->sect_addr);
+HDfprintf(stderr, "%s: fspace->sinfo_lock_count = %u, fspace->sinfo_modified = %t, fspace->sinfo_protected = %t\n", FUNC, fspace->sinfo_lock_count, fspace->sinfo_modified, fspace->sinfo_protected);
+HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu, fspace->sect_size = %Hu\n", FUNC, fspace->alloc_sect_size, fspace->sect_size);
+#endif /* H5FS_SINFO_DEBUG */
+
+ /* Check arguments. */
+ HDassert(f);
+ HDassert(fspace);
+ HDassert(fspace->rc == 2);
+ HDassert(fspace->sinfo);
+
+ /* Check if we modified any section */
+ if(modified) {
+ /* Check if the section info was protected with a different access mode */
+ if(fspace->sinfo_protected && fspace->sinfo_accmode != H5AC_WRITE)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTDIRTY, FAIL, "attempt to modify read-only section info")
+
+ /* If we modified the section info, mark it dirty */
+ fspace->sinfo->dirty = TRUE;
- /* Cache the new free space section info (pinned) */
- if(H5AC_set(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, sinfo, H5AC__PIN_ENTRY_FLAG) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, NULL, "can't add free space sections to cache")
+ /* Remember that the section info was modified while locked */
+ fspace->sinfo_modified = TRUE;
- /* Mark free space header as dirty */
- if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, NULL, "unable to mark free space header as dirty")
+ /* Assume that the modification will affect the statistics in the header
+ * and mark that dirty also
+ */
+ if(H5FS_dirty(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
} /* end if */
- else {
+
+ /* Decrement the lock count on the section info */
+ fspace->sinfo_lock_count--;
+
+ /* Check if section info lock count dropped to zero */
+ if(fspace->sinfo_lock_count == 0) {
+ hbool_t release_sinfo_space = FALSE; /* Flag to indicate section info space in file should be released */
+
+ /* Check if we actually protected the section info */
+ if(fspace->sinfo_protected) {
+ unsigned cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting heap */
+
+ /* Sanity check */
+ HDassert(H5F_addr_defined(fspace->addr));
+
+ /* Check if we've made new changes to the section info while locked */
+ if(fspace->sinfo_modified) {
+ /* Note that we've modified the section info */
+ cache_flags |= H5AC__DIRTIED_FLAG;
+
+ /* Check if the section info size in the file has changed */
+ if(fspace->sect_size != fspace->alloc_sect_size)
+ cache_flags |= H5AC__SIZE_CHANGED_FLAG | H5AC__DELETED_FLAG | H5AC__TAKE_OWNERSHIP_FLAG;
+ } /* end if */
+
+ /* Sanity check */
+ HDassert(H5F_addr_defined(fspace->sect_addr));
+
+ /* Unprotect section info in cache */
+ /* (Possibly dirty) */
+ /* (Possibly taking ownership from the cache) */
+#ifdef H5FS_SINFO_DEBUG
+HDfprintf(stderr, "%s: Unprotecting section info, cache_flags = %u\n", FUNC, cache_flags);
+#endif /* H5FS_SINFO_DEBUG */
+ if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, fspace->sinfo, cache_flags) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, FAIL, "unable to release free space section info")
+
+ /* Reset the protected flag on the section info */
+ fspace->sinfo_protected = FALSE;
+
+ /* Check if header is taking ownership of section info */
+ if((cache_flags & H5AC__TAKE_OWNERSHIP_FLAG)) {
+#ifdef H5FS_SINFO_DEBUG
+HDfprintf(stderr, "%s: Taking ownership of section info\n", FUNC);
+#endif /* H5FS_SINFO_DEBUG */
+ /* Set flag to release section info space in file */
+ release_sinfo_space = TRUE;
+ } /* end if */
+ else {
+#ifdef H5FS_SINFO_DEBUG
+HDfprintf(stderr, "%s: Relinquishing section info ownership\n", FUNC);
+#endif /* H5FS_SINFO_DEBUG */
+ /* Free space header relinquished ownership of section info */
+ fspace->sinfo = NULL;
+ } /* end else */
+ } /* end if */
+ else {
+ /* Check if the section info was modified */
+ if(fspace->sinfo_modified) {
+ /* Check if we need to release section info in the file */
+ if(H5F_addr_defined(fspace->sect_addr))
+ /* Set flag to release section info space in file */
+ release_sinfo_space = TRUE;
+ else
+ HDassert(fspace->alloc_sect_size == 0);
+ } /* end if */
+ else {
+ /* Sanity checks... */
+ if(H5F_addr_defined(fspace->sect_addr))
+ HDassert(fspace->alloc_sect_size == fspace->sect_size);
+ else
+ HDassert(fspace->alloc_sect_size == 0);
+ } /* end else */
+ } /* end else */
+
+ /* Reset the "section info modified" flag */
+ fspace->sinfo_modified = FALSE;
+
+ /* Check if header needs to release section info in the file */
+ if(release_sinfo_space) {
+ haddr_t old_sect_addr = fspace->sect_addr; /* Previous location of section info in file */
+ hsize_t old_alloc_sect_size = fspace->alloc_sect_size; /* Previous size of section info in file */
+
+ /* Sanity check */
+ HDassert(H5F_addr_defined(fspace->addr));
+
+ /* Reset section info in header */
+ fspace->sect_addr = HADDR_UNDEF;
+ fspace->alloc_sect_size = 0;
+
+ /* If we haven't already marked the header dirty, do so now */
+ if(!modified)
+ if(H5FS_dirty(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
+
+#ifdef H5FS_SINFO_DEBUG
+HDfprintf(stderr, "%s: Freeing section info on disk, old_sect_addr = %a, old_alloc_sect_size = %Hu\n", FUNC, old_sect_addr, old_alloc_sect_size);
+#endif /* H5FS_SINFO_DEBUG */
+ /* Release space for section info in file */
+ if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, old_sect_addr, old_alloc_sect_size) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space sections")
+ } /* end if */
+ } /* end if */
+
+done:
+#ifdef H5FS_SINFO_DEBUG
+HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value);
+#endif /* H5FS_SINFO_DEBUG */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5FS_sinfo_unlock() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_sect_serialize_size
+ *
+ * Purpose: Determine serialized size of all sections in free space manager
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Monday, May 8, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FS_sect_serialize_size(H5FS_t *fspace)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_sect_serialize_size)
+
+ /* Check arguments. */
+ HDassert(fspace);
#ifdef QAK
-HDfprintf(stderr, "%s: Reading in existing sections, fspace->sect_addr = %a\n", FUNC, fspace->sect_addr);
+HDfprintf(stderr, "%s: Check 1.0 - fspace->sect_size = %Hu\n", "H5FS_sect_serialize_size", fspace->sect_size);
+HDfprintf(stderr, "%s: fspace->serial_sect_count = %Zu\n", "H5FS_sect_serialize_size", fspace->serial_sect_count);
+HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu\n", "H5FS_sect_serialize_size", fspace->alloc_sect_size);
+HDfprintf(stderr, "%s: fspace->sinfo->serial_size_count = %Zu\n", "H5FS_sect_serialize_size", fspace->sinfo->serial_size_count);
#endif /* QAK */
- /* Protect the free space sections */
- if(NULL == (sinfo = H5AC_protect(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, NULL, fspace, H5AC_WRITE)))
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTPROTECT, NULL, "unable to load free space sections")
- /* Pin them in the cache */
- if(H5AC_pin_protected_entry(f, sinfo) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTPIN, NULL, "unable to pin free space sections")
+ /* Compute the size of the buffer required to serialize all the sections */
+ if(fspace->serial_sect_count > 0) {
+ size_t sect_buf_size; /* Section buffer size */
- /* Unlock free space sections, now pinned */
- if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, sinfo, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, NULL, "unable to release free space sections")
- } /* end else */
+ /* Serialized sections prefix */
+ sect_buf_size = fspace->sinfo->sect_prefix_size;
+
+ /* Count for each differently sized serializable section */
#ifdef QAK
-HDfprintf(stderr, "%s: sinfo->serial_size_count = %Zu\n", FUNC, sinfo->serial_size_count);
+HDfprintf(stderr, "%s: fspace->sinfo->serial_size_count = %Zu\n", "H5FS_sect_serialize_size", fspace->sinfo->serial_size_count);
+HDfprintf(stderr, "%s: fspace->serial_sect_count = %Hu\n", "H5FS_sect_serialize_size", fspace->serial_sect_count);
#endif /* QAK */
+ sect_buf_size += fspace->sinfo->serial_size_count * H5V_limit_enc_size((uint64_t)fspace->serial_sect_count);
- /* Update pointer to free space header for section info */
- sinfo->fspace = fspace;
+ /* Size for each differently sized serializable section */
+ sect_buf_size += fspace->sinfo->serial_size_count * fspace->sinfo->sect_len_size;
- /* Set return value */
- ret_value = sinfo;
+ /* Offsets of each section in address space */
+ sect_buf_size += fspace->serial_sect_count * fspace->sinfo->sect_off_size;
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5FS_sinfo_pin() */
+ /* Class of each section */
+ sect_buf_size += fspace->serial_sect_count * 1 /* byte */;
+
+ /* Extra space required to serialize each section */
+ sect_buf_size += fspace->sinfo->serial_size;
+
+ /* Update section size in header */
+ fspace->sect_size = sect_buf_size;
+ } /* end if */
+ else
+ /* Reset section size in header */
+ fspace->sect_size = fspace->sinfo->sect_prefix_size;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5FS_sect_serialize_size() */
/*-------------------------------------------------------------------------
@@ -266,7 +521,6 @@ done:
* on disk
*
* Return: Success: non-negative
- *
* Failure: negative
*
* Programmer: Quincey Koziol
@@ -275,8 +529,8 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5FS_sect_increase(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
- const H5FS_section_class_t *cls, unsigned flags)
+H5FS_sect_increase(H5FS_t *fspace, const H5FS_section_class_t *cls,
+ unsigned flags)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -312,15 +566,11 @@ HDfprintf(stderr, "%s: cls->serial_size = %Zu\n", FUNC, cls->serial_size);
/* Update the free space sections' serialized size */
/* (if we're not deserializing the sections from disk) */
if(!(flags & H5FS_ADD_DESERIALIZING)) {
- if(H5FS_sect_serialize_size(f, dxpl_id, fspace) < 0)
+ if(H5FS_sect_serialize_size(fspace) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTCOMPUTE, FAIL, "can't adjust free space section size on disk")
} /* end if */
} /* end else */
- /* Mark free space header as dirty */
- if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
-
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_sect_increase() */
@@ -342,7 +592,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5FS_sect_decrease(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, const H5FS_section_class_t *cls)
+H5FS_sect_decrease(H5FS_t *fspace, const H5FS_section_class_t *cls)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -376,14 +626,10 @@ HDfprintf(stderr, "%s: cls->serial_size = %Zu\n", FUNC, cls->serial_size);
fspace->sinfo->serial_size -= cls->serial_size;
/* Update the free space sections' serialized size */
- if(H5FS_sect_serialize_size(f, dxpl_id, fspace) < 0)
+ if(H5FS_sect_serialize_size(fspace) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTCOMPUTE, FAIL, "can't adjust free space section size on disk")
} /* end else */
- /* Mark free space header as dirty */
- if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
-
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_sect_decrease() */
@@ -457,7 +703,7 @@ HDfprintf(stderr, "%s: sinfo->bins[%u].sect_count = %Zu\n", FUNC, bin, sinfo->bi
HDassert(fspace_node->serial_count == 0);
/* Remove size tracking list from bin */
- tmp_fspace_node = H5SL_remove(sinfo->bins[bin].bin_list, &fspace_node->sect_size);
+ tmp_fspace_node = (H5FS_node_t *)H5SL_remove(sinfo->bins[bin].bin_list, &fspace_node->sect_size);
if(tmp_fspace_node == NULL || tmp_fspace_node != fspace_node)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTREMOVE, FAIL, "can't remove free space node from skip list")
@@ -466,7 +712,7 @@ HDfprintf(stderr, "%s: sinfo->bins[%u].sect_count = %Zu\n", FUNC, bin, sinfo->bi
HGOTO_ERROR(H5E_FSPACE, H5E_CANTCLOSEOBJ, FAIL, "can't destroy size tracking node's skip list")
/* Release free space list node */
- H5FL_FREE(H5FS_node_t, fspace_node);
+ (void)H5FL_FREE(H5FS_node_t, fspace_node);
/* Decrement total number of section sizes managed */
sinfo->tot_size_count--;
@@ -515,11 +761,11 @@ H5FS_sect_unlink_size(H5FS_sinfo_t *sinfo, const H5FS_section_class_t *cls,
HGOTO_ERROR(H5E_FSPACE, H5E_NOTFOUND, FAIL, "node's bin is empty?")
/* Find space node for section's size */
- if((fspace_node = H5SL_search(sinfo->bins[bin].bin_list, &sect->size)) == NULL)
+ if((fspace_node = (H5FS_node_t *)H5SL_search(sinfo->bins[bin].bin_list, &sect->size)) == NULL)
HGOTO_ERROR(H5E_FSPACE, H5E_NOTFOUND, FAIL, "can't find section size node")
/* Remove the section's node from the list */
- tmp_sect_node = H5SL_remove(fspace_node->sect_list, &sect->addr);
+ tmp_sect_node = (H5FS_section_info_t *)H5SL_remove(fspace_node->sect_list, &sect->addr);
if(tmp_sect_node == NULL || tmp_sect_node != sect)
HGOTO_ERROR(H5E_FSPACE, H5E_NOTFOUND, FAIL, "can't find section node on size list")
@@ -549,15 +795,14 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5FS_sect_unlink_rest(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
- const H5FS_section_class_t *cls, H5FS_section_info_t *sect)
+H5FS_sect_unlink_rest(H5FS_t *fspace, const H5FS_section_class_t *cls,
+ H5FS_section_info_t *sect)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5FS_sect_unlink_rest)
/* Check arguments. */
- HDassert(f);
HDassert(fspace);
HDassert(fspace->sinfo);
HDassert(cls);
@@ -570,13 +815,13 @@ H5FS_sect_unlink_rest(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
#ifdef QAK
HDfprintf(stderr, "%s: removing object from merge list, sect->type = %u\n", FUNC, (unsigned)sect->type);
#endif /* QAK */
- tmp_sect_node = H5SL_remove(fspace->sinfo->merge_list, &sect->addr);
+ tmp_sect_node = (H5FS_section_info_t *)H5SL_remove(fspace->sinfo->merge_list, &sect->addr);
if(tmp_sect_node == NULL || tmp_sect_node != sect)
HGOTO_ERROR(H5E_FSPACE, H5E_NOTFOUND, FAIL, "can't find section node on size list")
} /* end if */
/* Update section info & check if we need less room for the serialized free space sections */
- if(H5FS_sect_decrease(f, dxpl_id, fspace, cls) < 0)
+ if(H5FS_sect_decrease(fspace, cls) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't increase free space section size on disk")
/* Decrement amount of free space managed */
@@ -585,17 +830,13 @@ HDfprintf(stderr, "%s: fspace->tot_space = %Hu\n", FUNC, fspace->tot_space);
#endif /* QAK */
fspace->tot_space -= sect->size;
- /* Mark free space sections as changed */
- if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace->sinfo) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space sections as dirty")
-
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_sect_unlink_rest() */
/*-------------------------------------------------------------------------
- * Function: H5FS_sect_remove
+ * Function: H5FS_sect_remove_real
*
* Purpose: Remove a section from the free space manager
*
@@ -607,17 +848,15 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5FS_sect_remove(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
- H5FS_section_info_t *sect)
+static herr_t
+H5FS_sect_remove_real(H5FS_t *fspace, H5FS_section_info_t *sect)
{
const H5FS_section_class_t *cls; /* Class of section */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5FS_sect_remove)
+ FUNC_ENTER_NOAPI_NOINIT(H5FS_sect_remove_real)
/* Check arguments. */
- HDassert(f);
HDassert(fspace);
HDassert(fspace->sinfo);
HDassert(sect);
@@ -630,11 +869,56 @@ H5FS_sect_remove(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "can't remove section from size tracking data structures")
/* Update rest of free space manager data structures for node removal */
- if(H5FS_sect_unlink_rest(f, dxpl_id, fspace, cls, sect) < 0)
+ if(H5FS_sect_unlink_rest(fspace, cls, sect) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "can't remove section from non-size tracking data structures")
done:
FUNC_LEAVE_NOAPI(ret_value)
+} /* H5FS_sect_remove_real() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_sect_remove
+ *
+ * Purpose: Remove a section from the free space manager
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, May 17, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FS_sect_remove(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
+ H5FS_section_info_t *sect)
+{
+ hbool_t sinfo_valid = FALSE; /* Whether the section info is valid */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5FS_sect_remove)
+
+ /* Check arguments. */
+ HDassert(f);
+ HDassert(fspace);
+ HDassert(sect);
+
+ /* Get a pointer to the section info */
+ if(H5FS_sinfo_lock(f, dxpl_id, fspace, H5AC_WRITE) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't get section info")
+ sinfo_valid = TRUE;
+
+ /* Perform actual section removal */
+ if(H5FS_sect_remove_real(fspace, sect) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTREMOVE, FAIL, "can't remove section")
+
+done:
+ /* Release the section info */
+ if(sinfo_valid && H5FS_sinfo_unlock(f, dxpl_id, fspace, TRUE) < 0)
+ HDONE_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't release section info")
+
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_sect_remove() */
@@ -674,12 +958,12 @@ HDfprintf(stderr, "%s: sect->size = %Hu, sect->addr = %a\n", FUNC, sect->size, s
bin = H5V_log2_gen(sect->size);
HDassert(bin < sinfo->nbins);
if(sinfo->bins[bin].bin_list == NULL) {
- if(NULL == (sinfo->bins[bin].bin_list = H5SL_create(H5SL_TYPE_HSIZE, 0.5, (size_t)H5FS_DEFAULT_SKIPLIST_HEIGHT)))
+ if(NULL == (sinfo->bins[bin].bin_list = H5SL_create(H5SL_TYPE_HSIZE)))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTCREATE, FAIL, "can't create skip list for free space nodes")
} /* end if */
else {
/* Check for node list of the correct size already */
- fspace_node = H5SL_search(sinfo->bins[bin].bin_list, &sect->size);
+ fspace_node = (H5FS_node_t *)H5SL_search(sinfo->bins[bin].bin_list, &sect->size);
} /* end else */
/* Check if we need to create a new skip list for nodes of this size */
@@ -691,7 +975,7 @@ HDfprintf(stderr, "%s: sect->size = %Hu, sect->addr = %a\n", FUNC, sect->size, s
/* Initialize the free list size node */
fspace_node->sect_size = sect->size;
fspace_node->serial_count = fspace_node->ghost_count = 0;
- if(NULL == (fspace_node->sect_list = H5SL_create(H5SL_TYPE_HADDR, 0.5, (size_t)H5FS_DEFAULT_SKIPLIST_HEIGHT)))
+ if(NULL == (fspace_node->sect_list = H5SL_create(H5SL_TYPE_HADDR)))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTCREATE, FAIL, "can't create skip list for free space nodes")
/* Insert new free space size node into bin's list */
@@ -752,7 +1036,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5FS_sect_link_rest(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, const H5FS_section_class_t *cls,
+H5FS_sect_link_rest(H5FS_t *fspace, const H5FS_section_class_t *cls,
H5FS_section_info_t *sect, unsigned flags)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -760,7 +1044,6 @@ H5FS_sect_link_rest(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, const H5FS_section_
FUNC_ENTER_NOAPI_NOINIT(H5FS_sect_link_rest)
/* Check arguments. */
- HDassert(f);
HDassert(fspace);
HDassert(fspace->sinfo);
HDassert(sect);
@@ -771,14 +1054,14 @@ H5FS_sect_link_rest(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, const H5FS_section_
HDfprintf(stderr, "%s: inserting object into merge list, sect->type = %u\n", FUNC, (unsigned)sect->type);
#endif /* QAK */
if(fspace->sinfo->merge_list == NULL)
- if(NULL == (fspace->sinfo->merge_list = H5SL_create(H5SL_TYPE_HADDR, 0.5, (size_t)H5FS_DEFAULT_SKIPLIST_HEIGHT)))
+ if(NULL == (fspace->sinfo->merge_list = H5SL_create(H5SL_TYPE_HADDR)))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTCREATE, FAIL, "can't create skip list for merging free space sections")
if(H5SL_insert(fspace->sinfo->merge_list, sect, &sect->addr) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't insert free space node into merging skip list")
} /* end if */
/* Update section info & check if we need more room for the serialized free space sections */
- if(H5FS_sect_increase(f, dxpl_id, fspace, cls, flags) < 0)
+ if(H5FS_sect_increase(fspace, cls, flags) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't increase free space section size on disk")
/* Increment amount of free space managed */
@@ -804,8 +1087,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5FS_sect_link(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
- H5FS_section_info_t *sect, unsigned flags)
+H5FS_sect_link(H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flags)
{
const H5FS_section_class_t *cls; /* Class of section */
herr_t ret_value = SUCCEED; /* Return value */
@@ -813,7 +1095,6 @@ H5FS_sect_link(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
FUNC_ENTER_NOAPI_NOINIT(H5FS_sect_link)
/* Check arguments. */
- HDassert(f);
HDassert(fspace);
HDassert(fspace->sinfo);
HDassert(sect);
@@ -832,7 +1113,7 @@ HDfprintf(stderr, "%s: Check 1.0 - fspace->tot_space = %Hu\n", FUNC, fspace->tot
HDfprintf(stderr, "%s: Check 2.0 - fspace->tot_space = %Hu\n", FUNC, fspace->tot_space);
#endif /* QAK */
/* Update rest of free space manager data structures for section addition */
- if(H5FS_sect_link_rest(f, dxpl_id, fspace, cls, sect, flags) < 0)
+ if(H5FS_sect_link_rest(fspace, cls, sect, flags) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't add section to non-size tracking data structures")
#ifdef QAK
HDfprintf(stderr, "%s: Check 3.0 - fspace->tot_space = %Hu\n", FUNC, fspace->tot_space);
@@ -850,21 +1131,26 @@ done:
* free space.
*
* Return: Success: non-negative
- *
* Failure: negative
*
* Programmer: Quincey Koziol
* Wednesday, May 17, 2006
*
+ * Modifications: Vailin Choi; Sept 25th 2008
+ * Changes to the "shrinking" part--
+ * 1. Get last section node in merge-list instead of "less-than"
+ * node for further iteration
+ * 2. Remove "can-be-shrunk" section from free-space instead of
+ * "less-than" section
+ *
*-------------------------------------------------------------------------
*/
static herr_t
-H5FS_sect_merge(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
- H5FS_section_info_t **sect, void *op_data)
+H5FS_sect_merge(H5FS_t *fspace, H5FS_section_info_t **sect, void *op_data)
{
H5FS_section_class_t *sect_cls; /* Section's class */
- H5FS_section_info_t *tmp_sect_node; /* Temporary free space section */
hbool_t modified; /* Flag to indicate merge or shrink occurred */
+ hbool_t remove_sect = FALSE; /* Whether a section should be removed before shrinking */
htri_t status; /* Status value */
herr_t ret_value = SUCCEED; /* Return value */
@@ -879,43 +1165,54 @@ H5FS_sect_merge(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
/* Loop until no more merging */
if(fspace->sinfo->merge_list) {
do {
+ H5SL_node_t *less_sect_node; /* Skip list node for section less than new section */
+ H5SL_node_t *greater_sect_node; /* Skip list node for section greater than new section */
+ H5FS_section_info_t *tmp_sect; /* Temporary free space section */
H5FS_section_class_t *tmp_sect_cls; /* Temporary section's class */
+ hbool_t greater_sect_node_valid = FALSE; /* Indicate if 'greater than' section node is valid */
/* Reset 'modification occurred' flag */
modified = FALSE;
/* Look for neighboring section before new section */
- tmp_sect_node = H5SL_less(fspace->sinfo->merge_list, &(*sect)->addr);
+ less_sect_node = H5SL_below(fspace->sinfo->merge_list, &(*sect)->addr);
/* Check for node before new node able to merge with new node */
- if(tmp_sect_node) {
+ if(less_sect_node) {
+ /* Check for node greater than section */
+ greater_sect_node = H5SL_next(less_sect_node);
+ greater_sect_node_valid = TRUE;
+
+ /* Get section for 'less than' skip list node */
+ tmp_sect = (H5FS_section_info_t *)H5SL_item(less_sect_node);
+
/* Get classes for right & left sections */
- tmp_sect_cls = &fspace->sect_cls[tmp_sect_node->type];
+ tmp_sect_cls = &fspace->sect_cls[tmp_sect->type];
sect_cls = &fspace->sect_cls[(*sect)->type];
/* Check if sections of the left most class can merge with sections
* of another class & whether the sections are the same type,
* then check for 'can merge' callback
*/
- if((!(tmp_sect_cls->flags & H5FS_CLS_MERGE_SYM) || (tmp_sect_node->type == (*sect)->type))
+ if((!(tmp_sect_cls->flags & H5FS_CLS_MERGE_SYM) || (tmp_sect->type == (*sect)->type))
&& tmp_sect_cls->can_merge) {
/* Determine if the sections can merge */
- if((status = (*tmp_sect_cls->can_merge)(tmp_sect_node, *sect, op_data)) < 0)
+ if((status = (*tmp_sect_cls->can_merge)(tmp_sect, *sect, op_data)) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTMERGE, FAIL, "can't check for merging sections")
if(status > 0) {
/* Sanity check */
HDassert(tmp_sect_cls->merge);
/* Remove 'less than' node from data structures */
- if(H5FS_sect_remove(f, dxpl_id, fspace, tmp_sect_node) < 0)
+ if(H5FS_sect_remove_real(fspace, tmp_sect) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't remove section from internal data structures")
/* Merge the two sections together */
- if((*tmp_sect_cls->merge)(tmp_sect_node, *sect, op_data) < 0)
+ if((*tmp_sect_cls->merge)(tmp_sect, *sect, op_data) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't merge two sections")
/* Retarget section pointer to 'less than' node that was merged into */
- *sect = tmp_sect_node;
+ *sect = tmp_sect;
/* Indicate successful merge occurred */
modified = TRUE;
@@ -923,35 +1220,39 @@ H5FS_sect_merge(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
} /* end if */
} /* end if */
- /* Look for section after new (or merged) section */
- tmp_sect_node = H5SL_greater(fspace->sinfo->merge_list, &(*sect)->addr);
+ /* Look for section after new (or merged) section, if not already determined */
+ if(!greater_sect_node_valid)
+ greater_sect_node = H5SL_above(fspace->sinfo->merge_list, &(*sect)->addr);
/* Check for node after new node able to merge with new node */
- if(tmp_sect_node) {
+ if(greater_sect_node) {
+ /* Get section for 'greater than' skip list node */
+ tmp_sect = (H5FS_section_info_t *)H5SL_item(greater_sect_node);
+
/* Get classes for right & left sections */
sect_cls = &fspace->sect_cls[(*sect)->type];
- tmp_sect_cls = &fspace->sect_cls[tmp_sect_node->type];
+ tmp_sect_cls = &fspace->sect_cls[tmp_sect->type];
/* Check if sections of the left most class can merge with sections
* of another class & whether the sections are the same type,
* then check for 'can merge' callback
*/
- if((!(sect_cls->flags & H5FS_CLS_MERGE_SYM) || ((*sect)->type == tmp_sect_node->type))
+ if((!(sect_cls->flags & H5FS_CLS_MERGE_SYM) || ((*sect)->type == tmp_sect->type))
&& sect_cls->can_merge) {
/* Determine if the sections can merge */
- if((status = (*sect_cls->can_merge)(*sect, tmp_sect_node, op_data)) < 0)
+ if((status = (*sect_cls->can_merge)(*sect, tmp_sect, op_data)) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTMERGE, FAIL, "can't check for merging sections")
if(status > 0) {
/* Sanity check */
HDassert(sect_cls->merge);
/* Remove 'greater than' node from data structures */
- if(H5FS_sect_remove(f, dxpl_id, fspace, tmp_sect_node) < 0)
+ if(H5FS_sect_remove_real(fspace, tmp_sect) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't remove section from internal data structures")
/* Merge the two sections together */
- if((*sect_cls->merge)(*sect, tmp_sect_node, op_data) < 0)
+ if((*sect_cls->merge)(*sect, tmp_sect, op_data) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't merge two sections")
/* Indicate successful merge occurred */
@@ -959,7 +1260,7 @@ H5FS_sect_merge(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
} /* end if */
} /* end if */
} /* end if */
- } while(modified);
+ } while(modified);
} /* end if */
HDassert(*sect);
#ifdef QAK
@@ -980,15 +1281,14 @@ HDfprintf(stderr, "%s: Done merging, (*sect) = {%a, %Hu, %u, %s}\n", FUNC, (*sec
#ifdef QAK
HDfprintf(stderr, "%s: Can shrink!\n", FUNC);
#endif /* QAK */
- /* Look for neighboring section before new section */
- if(fspace->sinfo->merge_list) {
- tmp_sect_node = H5SL_less(fspace->sinfo->merge_list, &(*sect)->addr);
- /* Make certain there isn't a section after the new section */
- HDassert(H5SL_greater(fspace->sinfo->merge_list, &(*sect)->addr) == NULL);
- } /* end if */
- else
- tmp_sect_node = NULL;
+ /* Remove SECT from free-space manager */
+ /* (only possible to happen on second+ pass through loop) */
+ if(remove_sect) {
+ if(H5FS_sect_remove_real(fspace, *sect) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't remove section from internal data structures")
+ remove_sect = FALSE;
+ } /* end if */
/* Shrink the container */
/* (callback can indicate that it has discarded the section by setting *sect to NULL) */
@@ -996,20 +1296,34 @@ HDfprintf(stderr, "%s: Can shrink!\n", FUNC);
if((*sect_cls->shrink)(sect, op_data) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't shrink free space container")
- /* Check if the new section was removed */
- if(*sect == NULL && tmp_sect_node) {
- /* Remove 'less than' node from data structures */
- if(H5FS_sect_remove(f, dxpl_id, fspace, tmp_sect_node) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't remove section from internal data structures")
-
- *sect = tmp_sect_node;
- } /* end if */
+ /* If this section was shrunk away, we may need to shrink another section */
+ if(*sect == NULL) {
+ /* Check for sections on merge list */
+ if(fspace->sinfo->merge_list) {
+ H5SL_node_t *last_node; /* Last node in merge list */
+
+ /* Check for last node in the merge list */
+ if(NULL != (last_node = H5SL_last(fspace->sinfo->merge_list))) {
+ /* Get the pointer to the last section, from the last node */
+ *sect = (H5FS_section_info_t *)H5SL_item(last_node);
+ HDassert(*sect);
+
+ /* Indicate that this section needs to be removed if it causes a shrink */
+ remove_sect = TRUE;
+ } /* end if */
+ } /* end if */
+ } /* end if */
/* Indicate successful merge occurred */
modified = TRUE;
} /* end if */
} /* end if */
} while(modified && *sect);
+
+ /* Check for section that was shrunk away and next section not shrinking */
+ if(remove_sect && (*sect != NULL))
+ *sect = NULL;
+
#ifdef QAK
HDfprintf(stderr, "%s: Done shrinking\n", FUNC);
if(*sect)
@@ -1045,13 +1359,15 @@ H5FS_sect_add(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5FS_section_info_t *sect
unsigned flags, void *op_data)
{
H5FS_section_class_t *cls; /* Section's class */
+ hbool_t sinfo_valid = FALSE; /* Whether the section info is valid */
+ hbool_t sinfo_modified = FALSE; /* Whether the section info was modified */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FS_sect_add, FAIL)
-#ifdef QAK
+#ifdef H5FS_SINFO_DEBUG
HDfprintf(stderr, "%s: *sect = {%a, %Hu, %u, %s}\n", FUNC, sect->addr, sect->size, sect->type, (sect->state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED"));
-#endif /* QAK */
+#endif /* H5FS_SINFO_DEBUG */
/* Check arguments. */
HDassert(fspace);
@@ -1059,11 +1375,10 @@ HDfprintf(stderr, "%s: *sect = {%a, %Hu, %u, %s}\n", FUNC, sect->addr, sect->siz
HDassert(H5F_addr_defined(sect->addr));
HDassert(sect->size);
- /* Check if we need to go get the sections */
- if(fspace->sinfo == NULL) {
- if(NULL == (fspace->sinfo = H5FS_sinfo_pin(f, dxpl_id, fspace)))
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTDECODE, FAIL, "can't pin sections")
- } /* end if */
+ /* Get a pointer to the section info */
+ if(H5FS_sinfo_lock(f, dxpl_id, fspace, H5AC_WRITE) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't get section info")
+ sinfo_valid = TRUE;
/* Call "add" section class callback, if there is one */
cls = &fspace->sect_cls[sect->type];
@@ -1074,12 +1389,12 @@ HDfprintf(stderr, "%s: *sect = {%a, %Hu, %u, %s}\n", FUNC, sect->addr, sect->siz
/* Check for merging returned space with existing section node */
if(flags & H5FS_ADD_RETURNED_SPACE) {
-#ifdef QAK
+#ifdef H5FS_SINFO_DEBUG
HDfprintf(stderr, "%s: Returning space\n", FUNC);
-#endif /* QAK */
+#endif /* H5FS_SINFO_DEBUG */
/* Attempt to merge returned section with existing sections */
- if(H5FS_sect_merge(f, dxpl_id, fspace, &sect, op_data) < 0)
+ if(H5FS_sect_merge(fspace, &sect, op_data) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTMERGE, FAIL, "can't merge sections")
} /* end if */
@@ -1088,29 +1403,230 @@ HDfprintf(stderr, "%s: Returning space\n", FUNC);
* be NULL at this point - QAK)
*/
if(sect)
- if(H5FS_sect_link(f, dxpl_id, fspace, sect, flags) < 0)
+ if(H5FS_sect_link(fspace, sect, flags) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't insert free space section into skip list")
-#ifdef QAK
-HDfprintf(stderr, "%s: fspace->hdr->tot_space = %Hu\n", FUNC, fspace->hdr->tot_space);
-#endif /* QAK */
+#ifdef H5FS_SINFO_DEBUG
+HDfprintf(stderr, "%s: fspace->tot_space = %Hu\n", FUNC, fspace->tot_space);
+#endif /* H5FS_SINFO_DEBUG */
/* Mark free space sections as changed */
/* (if adding sections while deserializing sections, don't set the flag) */
- if(!(flags & H5FS_ADD_DESERIALIZING)) {
- if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace->sinfo) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space sections as dirty")
- } /* end if */
+ if(!(flags & H5FS_ADD_DESERIALIZING))
+ sinfo_modified = TRUE;
done:
-#ifdef H5FS_DEBUG
+ /* Release the section info */
+ if(sinfo_valid && H5FS_sinfo_unlock(f, dxpl_id, fspace, sinfo_modified) < 0)
+ HDONE_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't release section info")
+
+#ifdef H5FS_DEBUG_ASSERT
if(!(flags & (H5FS_ADD_DESERIALIZING | H5FS_ADD_SKIP_VALID)))
H5FS_assert(fspace);
-#endif /* H5FS_DEBUG */
+#endif /* H5FS_DEBUG_ASSERT */
+#ifdef H5FS_SINFO_DEBUG
+HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value);
+#endif /* H5FS_SINFO_DEBUG */
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_sect_add() */
/*-------------------------------------------------------------------------
+ * Function: H5FS_sect_try_extend
+ *
+ * Purpose: Try to extend a block using space from a section on the free list
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, January 8, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5FS_sect_try_extend(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, haddr_t addr,
+ hsize_t size, hsize_t extra_requested)
+{
+ hbool_t sinfo_valid = FALSE; /* Whether the section info is valid */
+ hbool_t sinfo_modified = FALSE; /* Whether the section info was modified */
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FS_sect_try_extend, FAIL)
+
+#ifdef H5FS_SINFO_DEBUG
+HDfprintf(stderr, "%s: addr = %a, size = %Hu, extra_requested = %hu\n", FUNC, addr, size, extra_requested);
+#endif /* H5FS_SINFO_DEBUG */
+
+ /* Check arguments. */
+ HDassert(f);
+ HDassert(fspace);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(size > 0);
+ HDassert(extra_requested > 0);
+
+ /* Check for any sections on free space list */
+#ifdef H5FS_SINFO_DEBUG
+HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", FUNC, fspace->tot_sect_count);
+HDfprintf(stderr, "%s: fspace->serial_sect_count = %Hu\n", FUNC, fspace->serial_sect_count);
+HDfprintf(stderr, "%s: fspace->ghost_sect_count = %Hu\n", FUNC, fspace->ghost_sect_count);
+#endif /* H5FS_SINFO_DEBUG */
+ if(fspace->tot_sect_count > 0) {
+ H5FS_section_info_t *sect; /* Temporary free space section */
+
+ /* Get a pointer to the section info */
+ if(H5FS_sinfo_lock(f, dxpl_id, fspace, H5AC_WRITE) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't get section info")
+ sinfo_valid = TRUE;
+
+
+/*
+
+Pseudo-code for algorithm:
+
+_section_ = <Get pointer to section with address > _region.addr_>
+if(_section_)
+ if(_section_ adjoins _region_ && _section.size_ >= _extra_requested_)
+ <remove section from data structures>
+ if(_section.size_ > _extra_requested_)
+ if(<can adjust _section_>)
+ <adjust _section_ by _extra_requested_>
+ <add adjusted section back to data structures>
+ else
+ <re-add UNadjusted section back to data structures>
+ <error>
+ <mark free space sections as changed in metadata cache>
+
+*/
+ /* Look for a section after block to extend */
+ if((sect = (H5FS_section_info_t *)H5SL_greater(fspace->sinfo->merge_list, &addr))) {
+ /* Check if this section adjoins the block and is large enough to
+ * fulfill extension request.
+ *
+ * (Note: we assume that the section is fully merged with any
+ * possible neighboring nodes and is not at the end of the file
+ * (or it would have been eliminated), etc)
+ */
+ if(sect->size >= extra_requested && (addr + size) == sect->addr) {
+ H5FS_section_class_t *cls; /* Section's class */
+
+ /* Remove section from data structures */
+ if(H5FS_sect_remove_real(fspace, sect) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't remove section from internal data structures")
+
+ /* Get class for section */
+ cls = &fspace->sect_cls[sect->type];
+
+ /* Check for the section needing to be adjusted and re-added */
+ /* (Note: we should probably add a can_adjust/adjust callback
+ * to the section class structure, but we don't need it
+ * for the current usage, so I've deferred messing with
+ * it. - QAK - 2008/01/08)
+ */
+ if(sect->size > extra_requested) {
+ /* Sanity check (for now) */
+ HDassert(cls->flags & H5FS_CLS_ADJUST_OK);
+
+ /* Adjust section by amount requested */
+ sect->addr += extra_requested;
+ sect->size -= extra_requested;
+
+ /* Re-add adjusted section to free sections data structures */
+ if(H5FS_sect_link(fspace, sect, 0) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't insert free space section into skip list")
+ } /* end if */
+ else {
+ /* Sanity check */
+ HDassert(sect->size == extra_requested);
+
+ /* Exact match, so just free section */
+ if((*cls->free)(sect) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "can't free section")
+ } /* end else */
+
+ /* Note that we modified the section info */
+ sinfo_modified = TRUE;
+
+ /* Indicate success */
+ HGOTO_DONE(TRUE);
+ } /* end if */
+ } /* end if */
+ } /* end if */
+
+done:
+ /* Release the section info */
+ if(sinfo_valid && H5FS_sinfo_unlock(f, dxpl_id, fspace, sinfo_modified) < 0)
+ HDONE_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't release section info")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5FS_sect_try_extend() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_sect_try_merge
+ *
+ * Purpose: Try to merge/shrink a block
+ *
+ * Return: TRUE: merged/shrunk
+ * FALSE: not merged/not shrunk
+ * Failure: negative
+ *
+ * Programmer: Vailin Choi; June 10, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5FS_sect_try_merge(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5FS_section_info_t *sect,
+ unsigned flags, void *op_data)
+{
+ hbool_t sinfo_valid = FALSE; /* Whether the section info is valid */
+ hbool_t sinfo_modified = FALSE; /* Whether the section info was modified */
+ hsize_t saved_fs_size; /* copy the free-space section size */
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FS_sect_try_merge, FAIL)
+
+ /* Check arguments. */
+ HDassert(f);
+ HDassert(fspace);
+ HDassert(sect);
+ HDassert(H5F_addr_defined(sect->addr));
+ HDassert(sect->size);
+
+ /* Get a pointer to the section info */
+ if(H5FS_sinfo_lock(f, dxpl_id, fspace, H5AC_WRITE) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't get section info")
+ sinfo_valid = TRUE;
+ saved_fs_size = sect->size;
+
+ /* Attempt to merge/shrink section with existing sections */
+ if(H5FS_sect_merge(fspace, &sect, op_data) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMERGE, FAIL, "can't merge sections")
+
+ /* Check if section is shrunk and/or merged away completely */
+ if(!sect) {
+ sinfo_modified = TRUE;
+ HGOTO_DONE(TRUE)
+ } /* end if */
+ else {
+ /* Check if section is merged */
+ if(sect->size > saved_fs_size) {
+ if(H5FS_sect_link(fspace, sect, flags) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't insert free space section into skip list")
+ sinfo_modified = TRUE;
+ HGOTO_DONE(TRUE)
+ } /* end if */
+ } /* end else */
+
+done:
+ /* Release the section info */
+ if(sinfo_valid && H5FS_sinfo_unlock(f, dxpl_id, fspace, sinfo_modified) < 0)
+ HDONE_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't release section info")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5FS_sect_try_merge() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5FS_sect_find_node
*
* Purpose: Locate a section of free space (in existing free space list
@@ -1123,6 +1639,11 @@ if(!(flags & (H5FS_ADD_DESERIALIZING | H5FS_ADD_SKIP_VALID)))
* Programmer: Quincey Koziol
* Monday, March 20, 2006
*
+ * Modifications:
+ * Vailin Choi, July 29th, 2008
+ * Modified to handle alignment by going through each bin to find
+ * a section that is big enough to fulfill "request+fragment for alignment"
+ *
*-------------------------------------------------------------------------
*/
static htri_t
@@ -1132,6 +1653,10 @@ H5FS_sect_find_node(H5FS_t *fspace, hsize_t request, H5FS_section_info_t **node)
unsigned bin; /* Bin to put the free space section in */
htri_t ret_value = FALSE; /* Return value */
+ H5SL_node_t *curr_size_node=NULL;
+ const H5FS_section_class_t *cls; /* Class of section */
+ hsize_t alignment;
+
FUNC_ENTER_NOAPI_NOINIT(H5FS_sect_find_node)
/* Check arguments. */
@@ -1144,43 +1669,113 @@ H5FS_sect_find_node(H5FS_t *fspace, hsize_t request, H5FS_section_info_t **node)
/* Determine correct bin which holds items of at least the section's size */
bin = H5V_log2_gen(request);
HDassert(bin < fspace->sinfo->nbins);
- while(bin < fspace->sinfo->nbins && fspace->sinfo->bins[bin].bin_list == NULL)
- bin++;
-
- /* Find the first free space section that is large enough to fulfill request */
- /* (Since the bins use skip lists to track the sizes of the address-ordered
- * lists, this is actually a "best fit" algorithm)
- */
#ifdef QAK
HDfprintf(stderr, "%s: fspace->sinfo->nbins = %u\n", FUNC, fspace->sinfo->nbins);
HDfprintf(stderr, "%s: bin = %u\n", FUNC, bin);
#endif /* QAK */
- if(bin < fspace->sinfo->nbins)
- do {
- /* Look for large enough free space section in this bin */
- if(fspace->sinfo->bins[bin].bin_list)
- /* Check for large enough list of sections on list */
- if((fspace_node = H5SL_greater(fspace->sinfo->bins[bin].bin_list, &request))) {
- const H5FS_section_class_t *cls; /* Class of section */
+ alignment = fspace->alignment;
+ if(!((alignment > 1) && (request >= fspace->threshold)))
+ alignment = 0; /* no alignment */
- /* Take first node off of the list (ie. node w/lowest address) */
- if(NULL == (*node = H5SL_remove_first(fspace_node->sect_list)))
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTREMOVE, FAIL, "can't remove free space node from skip list")
-
- /* Get section's class */
- cls = &fspace->sect_cls[(*node)->type];
+ do {
+ /* Check if there's any sections in this bin */
+ if(fspace->sinfo->bins[bin].bin_list) {
+
+ if (!alignment) { /* no alignment */
+ /* Find the first free space section that is large enough to fulfill request */
+ /* (Since the bins use skip lists to track the sizes of the address-ordered
+ * lists, this is actually a "best fit" algorithm)
+ */
+ /* Look for large enough free space section in this bin */
+ if((fspace_node = (H5FS_node_t *)H5SL_greater(fspace->sinfo->bins[bin].bin_list, &request))) {
+ /* Take first node off of the list (ie. node w/lowest address) */
+ if(NULL == (*node = (H5FS_section_info_t *)H5SL_remove_first(fspace_node->sect_list)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTREMOVE, FAIL, "can't remove free space node from skip list")
+
+ /* Get section's class */
+ cls = &fspace->sect_cls[(*node)->type];
+ /* Decrement # of sections in section size node */
+ if(H5FS_size_node_decr(fspace->sinfo, bin, fspace_node, cls) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTREMOVE, FAIL, "can't remove free space size node from skip list")
+ if(H5FS_sect_unlink_rest(fspace, cls, *node) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "can't remove section from non-size tracking data structures")
+ /* Indicate that we found a node for the request */
+ HGOTO_DONE(TRUE)
+ } /* end if */
+ } /* end if */
+ else { /* alignment is set */
+ /* get the first node of a certain size in this bin */
+ curr_size_node = H5SL_first(fspace->sinfo->bins[bin].bin_list);
+ while (curr_size_node != NULL) {
+ H5FS_node_t *curr_fspace_node=NULL;
+ H5SL_node_t *curr_sect_node=NULL;
+
+ /* Get the free space node for free space sections of the same size */
+ curr_fspace_node = (H5FS_node_t *)H5SL_item(curr_size_node);
+
+ /* Get the Skip list which holds pointers to actual free list sections */
+ curr_sect_node = (H5SL_node_t *)H5SL_first(curr_fspace_node->sect_list);
- /* Decrement # of sections in section size node */
- if(H5FS_size_node_decr(fspace->sinfo, bin, fspace_node, cls) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTREMOVE, FAIL, "can't remove free space size node from skip list")
+ while(curr_sect_node != NULL) {
+ H5FS_section_info_t *curr_sect=NULL;
+ hsize_t mis_align=0, frag_size=0;
+ H5FS_section_info_t *split_sect=NULL;
+
+ /* Get section node */
+ curr_sect = (H5FS_section_info_t *)H5SL_item(curr_sect_node);
+
+ HDassert(H5F_addr_defined(curr_sect->addr));
+ HDassert(curr_fspace_node->sect_size == curr_sect->size);
+
+ cls = &fspace->sect_cls[curr_sect->type];
+
+ HDassert(alignment);
+ HDassert(cls);
+
+ if ((mis_align = curr_sect->addr % alignment))
+ frag_size = alignment - mis_align;
+
+ if ((curr_sect->size >= (request + frag_size)) && (cls->split)) {
+ /* remove the section with aligned address */
+ if(NULL == (*node = (H5FS_section_info_t *)H5SL_remove(curr_fspace_node->sect_list, &curr_sect->addr)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTREMOVE, FAIL, "can't remove free space node from skip list")
+ /* Decrement # of sections in section size node */
+ if(H5FS_size_node_decr(fspace->sinfo, bin, curr_fspace_node, cls) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTREMOVE, FAIL, "can't remove free space size node from skip list")
+
+ if(H5FS_sect_unlink_rest(fspace, cls, *node) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "can't remove section from non-size tracking data structures")
+
+ /*
+ * The split() callback splits NODE into 2 sections:
+ * split_sect is the unused fragment for aligning NODE
+ * NODE's addr & size are updated to point to the remaining aligned section
+ * split_sect is re-added to free-space
+ */
+ if (mis_align) {
+ split_sect = cls->split(*node, frag_size);
+ if((H5FS_sect_link(fspace, split_sect, 0) < 0))
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't insert free space section into skip list")
+ /* sanity check */
+ HDassert(split_sect->addr < (*node)->addr);
+ HDassert(request <= (*node)->size);
+ }
+ /* Indicate that we found a node for the request */
+ HGOTO_DONE(TRUE)
+ }
- /* Indicate that we found a node for the request */
- HGOTO_DONE(TRUE)
- } /* end if */
+ /* Get the next section node in the list */
+ curr_sect_node = H5SL_next(curr_sect_node);
+ } /* end while of curr_sect_node */
- /* Advance to next larger bin */
- bin++;
- } while(bin < fspace->sinfo->nbins);
+ /* Get the next size node in the bin */
+ curr_size_node = H5SL_next(curr_size_node);
+ } /* end while of curr_size_node */
+ } /* else of alignment */
+ } /* if bin_list */
+ /* Advance to next larger bin */
+ bin++;
+ } while(bin < fspace->sinfo->nbins);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1200,12 +1795,18 @@ done:
* Programmer: Quincey Koziol
* Tuesday, March 7, 2006
*
+ * Modifications:
+ * Vailin Choi, July 29th 2008
+ * Move H5FS_sect_unlink_rest() to H5FS_sect_find_node()
+ *
*-------------------------------------------------------------------------
*/
htri_t
H5FS_sect_find(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, hsize_t request,
H5FS_section_info_t **node)
{
+ hbool_t sinfo_valid = FALSE; /* Whether the section info is valid */
+ hbool_t sinfo_modified = FALSE; /* Whether the section info was modified */
htri_t ret_value = FALSE; /* Return value */
FUNC_ENTER_NOAPI(H5FS_sect_find, FAIL)
@@ -1227,11 +1828,10 @@ HDfprintf(stderr, "%s: fspace->serial_sect_count = %Hu\n", FUNC, fspace->serial_
HDfprintf(stderr, "%s: fspace->ghost_sect_count = %Hu\n", FUNC, fspace->ghost_sect_count);
#endif /* QAK */
if(fspace->tot_sect_count > 0) {
- /* Check if we need to go get the sections */
- if(fspace->sinfo == NULL) {
- if(NULL == (fspace->sinfo = H5FS_sinfo_pin(f, dxpl_id, fspace)))
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTDECODE, FAIL, "can't pin sections")
- } /* end if */
+ /* Get a pointer to the section info */
+ if(H5FS_sinfo_lock(f, dxpl_id, fspace, H5AC_WRITE) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't get section info")
+ sinfo_valid = TRUE;
/* Look for node in bins */
if((ret_value = H5FS_sect_find_node(fspace, request, node)) < 0)
@@ -1239,209 +1839,27 @@ HDfprintf(stderr, "%s: fspace->ghost_sect_count = %Hu\n", FUNC, fspace->ghost_se
/* Decrement # of sections on free list, if we found an object */
if(ret_value > 0) {
- const H5FS_section_class_t *cls; /* Class of section */
-
- /* Get section's class */
- cls = &fspace->sect_cls[(*node)->type];
-
- /* Update rest of free space manager data structures for node removal */
- if(H5FS_sect_unlink_rest(f, dxpl_id, fspace, cls, *node) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "can't remove section from non-size tracking data structures")
+ /* Note that we've modified the section info */
+ sinfo_modified = TRUE;
#ifdef QAK
HDfprintf(stderr, "%s: (*node)->size = %Hu, (*node)->addr = %a, (*node)->type = %u\n", FUNC, (*node)->size, (*node)->addr, (*node)->type);
#endif /* QAK */
- } /* end if */
+ }
} /* end if */
done:
-#ifdef H5FS_DEBUG
+ /* Release the section info */
+ if(sinfo_valid && H5FS_sinfo_unlock(f, dxpl_id, fspace, sinfo_modified) < 0)
+ HDONE_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't release section info")
+
+#ifdef H5FS_DEBUG_ASSERT
H5FS_assert(fspace);
-#endif /* H5FS_DEBUG */
+#endif /* H5FS_DEBUG_ASSERT */
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_sect_find() */
/*-------------------------------------------------------------------------
- * Function: H5FS_sect_serialize_size
- *
- * Purpose: Determine serialized size of all sections in free space manager
- * And adjust space on disk for storing serialized sections
- *
- * Return: Success: non-negative
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Monday, May 8, 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FS_sect_serialize_size(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5FS_sect_serialize_size)
-
- /* Check arguments. */
- HDassert(fspace);
-#ifdef QAK
-HDfprintf(stderr, "%s: Check 1.0 - fspace->sect_size = %Hu\n", FUNC, fspace->sect_size);
-HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu\n", FUNC, fspace->alloc_sect_size);
-HDfprintf(stderr, "%s: fspace->sinfo->serial_size_count = %Zu\n", FUNC, fspace->sinfo->serial_size_count);
-#endif /* QAK */
-
- /* Compute the size of the buffer required to serialize all the sections */
- if(fspace->serial_sect_count > 0) {
- size_t sect_buf_size; /* Section buffer size */
-
- /* Serialized sections prefix */
- sect_buf_size = fspace->sinfo->sect_prefix_size;
-
- /* Count for each differently sized serializable section */
-#ifdef QAK
-HDfprintf(stderr, "%s: fspace->sinfo->serial_size_count = %Zu\n", FUNC, fspace->sinfo->serial_size_count);
-HDfprintf(stderr, "%s: fspace->serial_sect_count = %Hu\n", FUNC, fspace->serial_sect_count);
-#endif /* QAK */
- sect_buf_size += fspace->sinfo->serial_size_count * H5V_limit_enc_size((uint64_t)fspace->serial_sect_count);
-
- /* Size for each differently sized serializable section */
- sect_buf_size += fspace->sinfo->serial_size_count * fspace->sinfo->sect_len_size;
-
- /* Offsets of each section in address space */
- sect_buf_size += fspace->serial_sect_count * fspace->sinfo->sect_off_size;
-
- /* Class of each section */
- sect_buf_size += fspace->serial_sect_count * 1;
-
- /* Extra space required to serialize each section */
- sect_buf_size += fspace->sinfo->serial_size;
-
- /* Update section size in header */
- fspace->sect_size = sect_buf_size;
- } /* end if */
- else
- /* Reset section size in header */
- fspace->sect_size = H5FS_SINFO_SIZE_DEFAULT;
-
-#ifdef QAK
-HDfprintf(stderr, "%s: Check 2.0 - fspace->sect_size = %Hu\n", FUNC, fspace->sect_size);
-HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu\n", FUNC, fspace->alloc_sect_size);
-#endif /* QAK */
- if(fspace->sect_size > fspace->alloc_sect_size) {
- size_t new_size; /* New size of space for serialized sections */
- haddr_t old_addr; /* Old address of serialized sections */
-
-/* Currently, the old block data is "thrown away" after the space is reallocated,
- * so avoid data copy in H5MF_realloc() call by just free'ing the space and
- * allocating new space.
- *
- * This also keeps the file smaller, by freeing the space and then
- * allocating new space, instead of vice versa (in H5MF_realloc).
- *
- * QAK - 5/ 8/2006
- */
- /* Free previous serialized sections disk space */
- old_addr = fspace->sect_addr;
- if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, old_addr, fspace->alloc_sect_size) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space sections")
-
- /* Compute new size */
- H5_ASSIGN_OVERFLOW(/* To: */ new_size, /* From: */ fspace->alloc_sect_size, /* From: */ hsize_t, /* To: */ size_t);
- while(new_size < fspace->sect_size)
- new_size *= (double)fspace->expand_percent / 100.0;
- fspace->alloc_sect_size = new_size;
-
- /* Allocate space for the new serialized sections on disk */
-#ifdef QAK
-HDfprintf(stderr, "%s: Allocating space for larger serialized sections, new_size = %Zu\n", FUNC, new_size);
-HDfprintf(stderr, "%s: fspace->sect_size = %Hu\n", FUNC, fspace->sect_size);
-#endif /* QAK */
- if(HADDR_UNDEF == (fspace->sect_addr = H5MF_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, (hsize_t)fspace->alloc_sect_size)))
- HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for free space sections")
-#ifdef QAK
-HDfprintf(stderr, "%s: old_addr = %a, fspace->sect_addr = %a\n", FUNC, old_addr, fspace->sect_addr);
-#endif /* QAK */
-
- /* Move object in cache, if it actually was relocated */
- if(H5F_addr_ne(fspace->sect_addr, old_addr)) {
- if(H5AC_rename(f, H5AC_FSPACE_SINFO, old_addr, fspace->sect_addr) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTRENAME, FAIL, "unable to move free space section info")
- } /* end if */
- else {
- /* Mark free space section as dirty */
- if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace->sinfo) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space section info as dirty")
- } /* end else */
-
- /* Mark free space header as dirty */
- if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
- } /* end if */
- else {
- size_t decrease_threshold; /* Size threshold for decreasing serialized section size */
- haddr_t old_addr; /* Old address of serialized sections */
-
- /* Compute the threshold for decreasing the sections' serialized size */
- decrease_threshold = (size_t)(((size_t)fspace->alloc_sect_size * (double)fspace->shrink_percent) / 100.0);
-
- if(fspace->alloc_sect_size > H5FS_SINFO_SIZE_DEFAULT &&
- fspace->sect_size < decrease_threshold) {
- size_t new_size = 0; /* New size of space for serialized sections */
-
-/* Currently, the old block data is "thrown away" after the space is reallocated,
- * so avoid data copy in H5MF_realloc() call by just free'ing the space and
- * allocating new space.
- *
- * This also keeps the file smaller, by freeing the space and then
- * allocating new space, instead of vice versa (in H5MF_realloc).
- *
- * QAK - 5/ 8/2006
- */
- /* Free previous serialized sections disk space */
- old_addr = fspace->sect_addr;
- if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, old_addr, fspace->alloc_sect_size) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space sections")
-
- /* Compute new size */
- while(fspace->sect_size < decrease_threshold) {
- new_size = decrease_threshold;
-
- decrease_threshold *= (double)fspace->shrink_percent / 100.0;
- } /* end while */
- if(new_size < H5FS_SINFO_SIZE_DEFAULT)
- new_size = H5FS_SINFO_SIZE_DEFAULT;
- fspace->alloc_sect_size = new_size;
-
- /* Allocate space for the new serialized sections on disk */
-#ifdef QAK
-HDfprintf(stderr, "%s: Allocating space for smaller serialized sections, new_size = %Zu\n", FUNC, new_size);
-#endif /* QAK */
- if(HADDR_UNDEF == (fspace->sect_addr = H5MF_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, (hsize_t)fspace->alloc_sect_size)))
- HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for free space sections")
-
- /* Move object in cache, if it actually was relocated */
- if(H5F_addr_ne(fspace->sect_addr, old_addr)) {
- if(H5AC_rename(f, H5AC_FSPACE_SINFO, old_addr, fspace->sect_addr) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTRENAME, FAIL, "unable to move free space section info")
- } /* end if */
- else {
- /* Mark free space section as dirty */
- if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace->sinfo) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space section info as dirty")
- } /* end else */
-
- /* Mark free space header as dirty */
- if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
- } /* end if */
- } /* end else */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5FS_sect_serialize_size() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5FS_iterate_sect_cb
*
* Purpose: Skip list iterator callback to iterate over free space sections
@@ -1535,7 +1953,8 @@ done:
herr_t
H5FS_sect_iterate(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5FS_operator_t op, void *op_data)
{
- H5FS_iter_ud_t udata; /* User data for callbacks */
+ H5FS_iter_ud_t udata; /* User data for callbacks */
+ hbool_t sinfo_valid = FALSE; /* Whether the section info is valid */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5FS_sect_iterate)
@@ -1544,14 +1963,8 @@ H5FS_sect_iterate(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5FS_operator_t op, v
HDassert(fspace);
HDassert(op);
- /* Check if we need to go get the sections */
- if(fspace->sinfo == NULL) {
- if(NULL == (fspace->sinfo = H5FS_sinfo_pin(f, dxpl_id, fspace)))
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTDECODE, FAIL, "can't pin sections")
- } /* end if */
-
#ifdef QAK
-HDfprintf(stderr, "%s: fspace->hdr->sect_count = %Hu\n", FUNC, fspace->hdr->sect_count);
+HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", FUNC, fspace->tot_sect_count);
#endif /* QAK */
/* Set up user data for iterator */
@@ -1563,6 +1976,11 @@ HDfprintf(stderr, "%s: fspace->hdr->sect_count = %Hu\n", FUNC, fspace->hdr->sect
if(fspace->tot_sect_count) {
unsigned bin; /* Current bin we are on */
+ /* Get a pointer to the section info */
+ if(H5FS_sinfo_lock(f, dxpl_id, fspace, H5AC_READ) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't get section info")
+ sinfo_valid = TRUE;
+
/* Iterate over all the bins */
#ifdef QAK
HDfprintf(stderr, "%s: Iterate over section bins\n", FUNC);
@@ -1578,17 +1996,20 @@ HDfprintf(stderr, "%s: Iterate over section bins\n", FUNC);
} /* end if */
done:
+ /* Release the section info */
+ if(sinfo_valid && H5FS_sinfo_unlock(f, dxpl_id, fspace, FALSE) < 0)
+ HDONE_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't release section info")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_sect_iterate() */
/*-------------------------------------------------------------------------
- * Function: H5FS_get_sect_count
+ * Function: H5FS_sect_stats
*
- * Purpose: Retrieve the number of sections managed
+ * Purpose: Retrieve info about the sections managed
*
* Return: Success: non-negative
- *
* Failure: negative
*
* Programmer: Quincey Koziol
@@ -1597,19 +2018,21 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5FS_get_sect_count(const H5FS_t *fspace, hsize_t *nsects)
+H5FS_sect_stats(const H5FS_t *fspace, hsize_t *tot_space, hsize_t *nsects)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5FS_get_sect_count)
+ FUNC_ENTER_NOAPI_NOFUNC(H5FS_sect_stats)
/* Check arguments. */
HDassert(fspace);
- HDassert(nsects);
- /* Get the section count */
- *nsects = fspace->tot_sect_count;
+ /* Get the stats desired */
+ if(tot_space)
+ *tot_space = fspace->tot_space;
+ if(nsects)
+ *nsects = fspace->tot_sect_count;
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5FS_get_sect_count() */
+} /* H5FS_sect_stats() */
/*-------------------------------------------------------------------------
@@ -1634,17 +2057,22 @@ H5FS_sect_change_class(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
const H5FS_section_class_t *old_cls; /* Old class of section */
const H5FS_section_class_t *new_cls; /* New class of section */
unsigned old_class; /* Old class ID of section */
+ hbool_t sinfo_valid = FALSE; /* Whether the section info is valid */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5FS_sect_change_class)
/* Check arguments. */
HDassert(fspace);
- HDassert(fspace->sinfo);
HDassert(sect);
HDassert(sect->type < fspace->nclasses);
HDassert(new_class < fspace->nclasses);
+ /* Get a pointer to the section info */
+ if(H5FS_sinfo_lock(f, dxpl_id, fspace, H5AC_WRITE) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't get section info")
+ sinfo_valid = TRUE;
+
/* Get class info */
old_class = sect->type;
old_cls = &fspace->sect_cls[sect->type];
@@ -1678,7 +2106,7 @@ HDfprintf(stderr, "%s: to_ghost = %u\n", FUNC, to_ghost);
HDassert(fspace->sinfo->bins[bin].bin_list);
/* Get space node for section's size */
- fspace_node = H5SL_search(fspace->sinfo->bins[bin].bin_list, &sect->size);
+ fspace_node = (H5FS_node_t *)H5SL_search(fspace->sinfo->bins[bin].bin_list, &sect->size);
HDassert(fspace_node);
/* Adjust serializable/ghost counts */
@@ -1741,7 +2169,7 @@ HDfprintf(stderr, "%s: to_mergable = %u\n", FUNC, to_mergable);
HDfprintf(stderr, "%s: inserting object into merge list, sect->type = %u\n", FUNC, (unsigned)sect->type);
#endif /* QAK */
if(fspace->sinfo->merge_list == NULL)
- if(NULL == (fspace->sinfo->merge_list = H5SL_create(H5SL_TYPE_HADDR, 0.5, (size_t)H5FS_DEFAULT_SKIPLIST_HEIGHT)))
+ if(NULL == (fspace->sinfo->merge_list = H5SL_create(H5SL_TYPE_HADDR)))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTCREATE, FAIL, "can't create skip list for merging free space sections")
if(H5SL_insert(fspace->sinfo->merge_list, sect, &sect->addr) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't insert free space node into merging skip list")
@@ -1752,7 +2180,7 @@ HDfprintf(stderr, "%s: inserting object into merge list, sect->type = %u\n", FUN
#ifdef QAK
HDfprintf(stderr, "%s: removing object from merge list, sect->type = %u\n", FUNC, (unsigned)sect->type);
#endif /* QAK */
- tmp_sect_node = H5SL_remove(fspace->sinfo->merge_list, &sect->addr);
+ tmp_sect_node = (H5FS_section_info_t *)H5SL_remove(fspace->sinfo->merge_list, &sect->addr);
if(tmp_sect_node == NULL || tmp_sect_node != sect)
HGOTO_ERROR(H5E_FSPACE, H5E_NOTFOUND, FAIL, "can't find section node on size list")
} /* end else */
@@ -1766,18 +2194,18 @@ HDfprintf(stderr, "%s: removing object from merge list, sect->type = %u\n", FUNC
fspace->sinfo->serial_size += fspace->sect_cls[new_class].serial_size;
/* Update current space used for free space sections */
- if(H5FS_sect_serialize_size(f, dxpl_id, fspace) < 0)
+ if(H5FS_sect_serialize_size(fspace) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTCOMPUTE, FAIL, "can't adjust free space section size on disk")
-
- /* Mark free space sections as dirty */
- if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace->sinfo) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space sections as dirty")
done:
+ /* Release the section info */
+ if(sinfo_valid && H5FS_sinfo_unlock(f, dxpl_id, fspace, TRUE) < 0)
+ HDONE_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't release section info")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_sect_change_class() */
-#ifdef H5FS_DEBUG
+#ifdef H5FS_DEBUG_ASSERT
/*-------------------------------------------------------------------------
* Function: H5FS_sect_assert
@@ -1798,8 +2226,8 @@ H5FS_sect_assert(const H5FS_t *fspace)
hsize_t separate_obj; /* The number of separate objects managed */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_sect_assert)
-#ifdef QAK
-HDfprintf(stderr, "%s: fspace->hdr->tot_sect_count = %Hu\n", "H5FS_sect_assert", fspace->hdr->tot_sect_count);
+#ifndef QAK
+HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", "H5FS_sect_assert", fspace->tot_sect_count);
#endif /* QAK */
/* Initialize state */
@@ -1927,5 +2355,5 @@ HDfprintf(stderr, "%s: sect->size = %Hu, sect->addr = %a, sect->type = %u\n", "H
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5FS_sect_assert() */
-#endif /* H5FS_DEBUG */
+#endif /* H5FS_DEBUG_ASSERT */
diff --git a/src/H5FSstat.c b/src/H5FSstat.c
new file mode 100644
index 0000000..18635c1
--- /dev/null
+++ b/src/H5FSstat.c
@@ -0,0 +1,105 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Purpose: Free-space metadata statistics functions.
+ *
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5FS_PACKAGE /*suppress error about including H5FSpkg */
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FSpkg.h" /* Free-space manager */
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_stat_info
+ *
+ * Purpose: Retrieve metadata statistics for the free-space manager
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: does not fail
+ *
+ * Programmer: Vailin Choi
+ * August 25th, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FS_stat_info(const H5F_t *f, const H5FS_t *frsp, H5FS_stat_t *stats)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_stat_info)
+
+ /* Check arguments. */
+ HDassert(frsp);
+ HDassert(stats);
+
+ /* Report statistics for free space */
+ stats->tot_space = frsp->tot_space;
+ stats->tot_sect_count = frsp->tot_sect_count;
+ stats->serial_sect_count = frsp->serial_sect_count;
+ stats->ghost_sect_count = frsp->ghost_sect_count;
+ stats->addr = frsp->addr;
+ stats->hdr_size = H5FS_HEADER_SIZE(f);
+ stats->sect_addr = frsp->sect_addr;
+ stats->alloc_sect_size = frsp->alloc_sect_size;
+ stats->sect_size = frsp->sect_size;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5FS_stat_info() */
diff --git a/src/H5FStest.c b/src/H5FStest.c
new file mode 100644
index 0000000..af9eaec
--- /dev/null
+++ b/src/H5FStest.c
@@ -0,0 +1,154 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Purpose: Free-space manager testing functions.
+ *
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5FS_PACKAGE /*suppress error about including H5FSpkg */
+#define H5FS_TESTING /*suppress warning about H5FS testing funcs */
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FSpkg.h" /* Free-space manager */
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_get_cparam_test
+ *
+ * Purpose: Retrieve the parameters used to create the free-space manager
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: similar to H5HF_get_cparam_test()
+ * Vailin Choi; August 25th, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FS_get_cparam_test(const H5FS_t *frsp, H5FS_create_t *cparam)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_get_cparam_test)
+
+ /* Check arguments. */
+ HDassert(frsp);
+ HDassert(cparam);
+
+ cparam->client = frsp->client;
+ cparam->shrink_percent = frsp->shrink_percent;
+ cparam->expand_percent = frsp->expand_percent;
+ cparam->max_sect_addr = frsp->max_sect_addr;
+ cparam->max_sect_size = frsp->max_sect_size;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5FS_get_cparam_test() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_cmp_cparam_test
+ *
+ * Purpose: Compare the parameters used to create the fractal heap
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: similar to H5HF_cmp_cparam_test()
+ * Vailin Choi; August 25th, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5FS_cmp_cparam_test(const H5FS_create_t *cparam1, const H5FS_create_t *cparam2)
+{
+ int ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_cmp_cparam_test)
+
+ /* Check arguments. */
+ HDassert(cparam1);
+ HDassert(cparam2);
+
+ if(cparam1->client < cparam2->client)
+ HGOTO_DONE(-1)
+ else if(cparam1->client > cparam2->client)
+ HGOTO_DONE(1)
+
+ if(cparam1->shrink_percent < cparam2->shrink_percent)
+ HGOTO_DONE(-1)
+ else if(cparam1->shrink_percent > cparam2->shrink_percent)
+ HGOTO_DONE(1)
+
+ if(cparam1->expand_percent < cparam2->expand_percent)
+ HGOTO_DONE(-1)
+ else if(cparam1->expand_percent > cparam2->expand_percent)
+ HGOTO_DONE(1)
+
+ if(cparam1->max_sect_size < cparam2->max_sect_size)
+ HGOTO_DONE(-1)
+ else if(cparam1->max_sect_size > cparam2->max_sect_size)
+ HGOTO_DONE(1)
+
+ if(cparam1->max_sect_addr < cparam2->max_sect_addr)
+ HGOTO_DONE(-1)
+ else if(cparam1->max_sect_addr > cparam2->max_sect_addr)
+ HGOTO_DONE(1)
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5FS_cmp_cparam_test */
diff --git a/src/H5Faccum.c b/src/H5Faccum.c
new file mode 100644
index 0000000..e525a08
--- /dev/null
+++ b/src/H5Faccum.c
@@ -0,0 +1,702 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Faccum.c
+ * Jan 10 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: File metadata "accumulator" routines. (Used to
+ * cache small metadata I/Os and group them into a
+ * single larger I/O)
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5FDprivate.h" /* File drivers */
+#include "H5Vprivate.h" /* Vectors and arrays */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* Metadata accumulator controls */
+#define H5F_ACCUM_THROTTLE 8
+#define H5F_ACCUM_THRESHOLD 2048
+#define H5F_ACCUM_MAX_SIZE (1024 *1024) /* Max. accum. buf size (max. I/Os will be 1/2 this size) */
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/* Enumerated type to indicate how data will be added to accumulator */
+typedef enum {
+ H5F_ACCUM_PREPEND, /* Data will be prepended to accumulator */
+ H5F_ACCUM_APPEND /* Data will be appended to accumulator */
+} H5F_accum_adjust_t;
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a PQ free list to manage the metadata accumulator buffer */
+H5FL_BLK_DEFINE_STATIC(meta_accum);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_accum_read
+ *
+ * Purpose: Attempts to read some data from the metadata accumulator for
+ * a file into a buffer.
+ *
+ * Note: We can't change (or add to) the metadata accumulator, because
+ * this might be a speculative read and could possibly read raw
+ * data into the metadata accumulator.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jan 10 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5F_accum_read(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr,
+ size_t size, void *buf/*out*/)
+{
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5F_accum_read, FAIL)
+
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(buf);
+
+ /* Check if this information is in the metadata accumulator */
+ if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && type != H5FD_MEM_DRAW
+ && size < H5F_ACCUM_MAX_SIZE) {
+ /* Current read overlaps with metadata accumulator */
+ if(H5F_addr_overlap(addr, size, f->shared->accum.loc, f->shared->accum.size)) {
+ unsigned char *read_buf = (unsigned char *)buf; /* Pointer to the buffer being read in */
+ size_t amount_read; /* Amount to read at a time */
+ hsize_t read_off; /* Offset to read from */
+
+ /* Read the part before the metadata accumulator */
+ if(addr < f->shared->accum.loc) {
+ /* Set the amount to read */
+ H5_ASSIGN_OVERFLOW(amount_read, (f->shared->accum.loc - addr), hsize_t, size_t);
+
+ /* Dispatch to driver */
+ if(H5FD_read(f->shared->lf, dxpl_id, type, addr, amount_read, read_buf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed")
+
+ /* Adjust the buffer, address & size */
+ read_buf += amount_read;
+ addr += amount_read;
+ size -= amount_read;
+ } /* end if */
+
+ /* Copy the part overlapping the metadata accumulator */
+ if(size > 0 && (addr >= f->shared->accum.loc && addr < (f->shared->accum.loc + f->shared->accum.size))) {
+ /* Set the offset to "read" from */
+ read_off = addr - f->shared->accum.loc;
+
+ /* Set the amount to "read" */
+#ifndef NDEBUG
+{
+ hsize_t tempamount_read; /* Amount to read at a time */
+
+ tempamount_read = f->shared->accum.size - read_off;
+ H5_CHECK_OVERFLOW(tempamount_read, hsize_t, size_t);
+ amount_read = MIN(size, (size_t)tempamount_read);
+}
+#else /* NDEBUG */
+ amount_read = MIN(size, (size_t)(f->shared->accum.size - read_off));
+#endif /* NDEBUG */
+
+ /* Copy the data out of the buffer */
+ HDmemcpy(read_buf, f->shared->accum.buf + read_off, amount_read);
+
+ /* Adjust the buffer, address & size */
+ read_buf += amount_read;
+ addr += amount_read;
+ size -= amount_read;
+ } /* end if */
+
+ /* Read the part after the metadata accumulator */
+ if(size > 0 && addr >= (f->shared->accum.loc + f->shared->accum.size)) {
+ /* Dispatch to driver */
+ if(H5FD_read(f->shared->lf, dxpl_id, type, addr, size, read_buf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed")
+
+ /* Adjust the buffer, address & size */
+ read_buf += size;
+ addr += size;
+ size -= size;
+ } /* end if */
+
+ /* Make certain we've read it all */
+ HDassert(size == 0);
+ } /* end if */
+ /* Current read doesn't overlap with metadata accumulator, read it from file */
+ else {
+ /* Dispatch to driver */
+ if(H5FD_read(f->shared->lf, dxpl_id, type, addr, size, buf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed")
+ } /* end else */
+
+ /* Indicate success */
+ HGOTO_DONE(TRUE);
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_accum_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_accum_adjust
+ *
+ * Purpose: Adjust accumulator size, if necessary
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jun 11 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_accum_adjust(H5F_meta_accum_t *accum, H5FD_t *lf, hid_t dxpl_id,
+ H5F_accum_adjust_t adjust, size_t size)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5F_accum_adjust)
+
+ HDassert(accum);
+ HDassert(lf);
+ HDassert(size > 0);
+ HDassert(size <= H5F_ACCUM_MAX_SIZE);
+
+ /* Check if we need more buffer space */
+ if((size + accum->size) > accum->alloc_size) {
+ size_t new_size; /* New size of accumulator */
+
+ /* Adjust the buffer size to be a power of 2 that is large enough to hold data */
+ new_size = (size_t)1 << (1 + H5V_log2_gen((uint64_t)((size + accum->size) - 1)));
+
+ /* Check for accumulator getting too big */
+ if(new_size > H5F_ACCUM_MAX_SIZE) {
+ size_t shrink_size; /* Amount to shrink accumulator by */
+ size_t remnant_size; /* Amount left in accumulator */
+
+ /* Cap the accumulator's growth, leaving some room */
+
+ /* Determine the amounts to work with */
+ if(size > (H5F_ACCUM_MAX_SIZE / 2)) {
+ new_size = H5F_ACCUM_MAX_SIZE;
+ shrink_size = accum->size;
+ remnant_size = 0;
+ } /* end if */
+ else {
+ new_size = (H5F_ACCUM_MAX_SIZE / 2);
+ shrink_size = (H5F_ACCUM_MAX_SIZE / 2);
+ remnant_size = accum->size - shrink_size;
+ } /* end else */
+
+ /* Check if we need to flush accumulator data to file */
+ if(accum->dirty) {
+ /* Check whether to accumulator will be prepended or appended */
+ if(H5F_ACCUM_PREPEND == adjust) {
+ /* Write out upper part of the existing metadata accumulator, with dispatch to driver */
+ if(H5FD_write(lf, dxpl_id, H5FD_MEM_DEFAULT, (accum->loc + remnant_size), shrink_size, (accum->buf + remnant_size)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed")
+ } /* end if */
+ else {
+ /* Sanity check */
+ HDassert(H5F_ACCUM_APPEND == adjust);
+
+ /* Write out lower part of the existing metadata accumulator, with dispatch to driver */
+ if(H5FD_write(lf, dxpl_id, H5FD_MEM_DEFAULT, accum->loc, shrink_size, accum->buf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed")
+
+ /* Move remnant of accumulator down */
+ HDmemmove(accum->buf, (accum->buf + shrink_size), remnant_size);
+
+ /* Adjust accumulator's location */
+ accum->loc += shrink_size;
+ } /* end else */
+
+ /* Reset accumulator dirty flag (in case of error) */
+ accum->dirty = FALSE;
+ } /* end if */
+
+ /* Trim the accumulator's use of its buffer */
+ accum->size = remnant_size;
+ } /* end if */
+
+ /* Check for accumulator needing to be reallocated */
+ if(new_size > accum->alloc_size) {
+ unsigned char *new_buf; /* New buffer to hold the accumulated metadata */
+
+ /* Reallocate the metadata accumulator buffer */
+ if(NULL == (new_buf = H5FL_BLK_REALLOC(meta_accum, accum->buf, new_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer")
+
+ /* Update accumulator info */
+ accum->buf = new_buf;
+ accum->alloc_size = new_size;
+#ifdef H5_CLEAR_MEMORY
+HDmemset(accum->buf + accum->size, 0, (accum->alloc_size - (accum->size + size)));
+#endif /* H5_CLEAR_MEMORY */
+ } /* end if */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_accum_adjust() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_accum_write
+ *
+ * Purpose: Attempts to read some data from the metadata accumulator for
+ * a file into a buffer.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jan 10 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5F_accum_write(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr,
+ size_t size, const void *buf)
+{
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5F_accum_write, FAIL)
+
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->intent & H5F_ACC_RDWR);
+ HDassert(buf);
+
+ /* Check for accumulating metadata */
+ if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && type != H5FD_MEM_DRAW
+ && size < H5F_ACCUM_MAX_SIZE) {
+ /* Check if there is already metadata in the accumulator */
+ if(f->shared->accum.size > 0) {
+ /* Check if the new metadata adjoins the beginning of the current accumulator */
+ if((addr + size) == f->shared->accum.loc) {
+ /* Check if we need to adjust accumulator size */
+ if(H5F_accum_adjust(&f->shared->accum, f->shared->lf, dxpl_id, H5F_ACCUM_PREPEND, size) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator")
+
+ /* Move the existing metadata to the proper location */
+ HDmemmove(f->shared->accum.buf + size, f->shared->accum.buf, f->shared->accum.size);
+
+ /* Copy the new metadata at the front */
+ HDmemcpy(f->shared->accum.buf, buf, size);
+
+ /* Set the new size & location of the metadata accumulator */
+ f->shared->accum.loc = addr;
+ f->shared->accum.size += size;
+
+ /* Mark it as written to */
+ f->shared->accum.dirty = TRUE;
+ } /* end if */
+ /* Check if the new metadata adjoins the end of the current accumulator */
+ else if(addr == (f->shared->accum.loc + f->shared->accum.size)) {
+ /* Check if we need to adjust accumulator size */
+ if(H5F_accum_adjust(&f->shared->accum, f->shared->lf, dxpl_id, H5F_ACCUM_APPEND, size) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator")
+
+ /* Copy the new metadata to the end */
+ HDmemcpy(f->shared->accum.buf + f->shared->accum.size, buf, size);
+
+ /* Set the new size of the metadata accumulator */
+ f->shared->accum.size += size;
+
+ /* Mark it as written to */
+ f->shared->accum.dirty = TRUE;
+ } /* end if */
+ /* Check if the piece of metadata being written overlaps the metadata accumulator */
+ else if(H5F_addr_overlap(addr, size, f->shared->accum.loc, f->shared->accum.size)) {
+ size_t add_size; /* New size of the accumulator buffer */
+
+ /* Check if the new metadata is entirely within the current accumulator */
+ if(addr >= f->shared->accum.loc && (addr + size) <= (f->shared->accum.loc + f->shared->accum.size)) {
+ /* Copy the new metadata to the proper location within the accumulator */
+ HDmemcpy(f->shared->accum.buf + (addr - f->shared->accum.loc), buf, size);
+
+ /* Mark it as written to */
+ f->shared->accum.dirty = TRUE;
+ } /* end if */
+ /* Check if the new metadata overlaps the beginning of the current accumulator */
+ else if(addr < f->shared->accum.loc && (addr + size) <= (f->shared->accum.loc + f->shared->accum.size)) {
+ size_t old_offset; /* Offset of old data within the accumulator buffer */
+
+ /* Calculate the amount we will need to add to the accumulator size, based on the amount of overlap */
+ H5_ASSIGN_OVERFLOW(add_size, (f->shared->accum.loc - addr), hsize_t, size_t);
+
+ /* Check if we need to adjust accumulator size */
+ if(H5F_accum_adjust(&f->shared->accum, f->shared->lf, dxpl_id, H5F_ACCUM_PREPEND, add_size) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator")
+
+ /* Calculate the proper offset of the existing metadata */
+ H5_ASSIGN_OVERFLOW(old_offset, (addr + size) - f->shared->accum.loc, hsize_t, size_t);
+
+ /* Move the existing metadata to the proper location */
+ HDmemmove(f->shared->accum.buf + size, f->shared->accum.buf + old_offset, (f->shared->accum.size - old_offset));
+
+ /* Copy the new metadata at the front */
+ HDmemcpy(f->shared->accum.buf, buf, size);
+
+ /* Set the new size & location of the metadata accumulator */
+ f->shared->accum.loc = addr;
+ f->shared->accum.size += add_size;
+
+ /* Mark it as written to */
+ f->shared->accum.dirty = TRUE;
+ } /* end if */
+ /* Check if the new metadata overlaps the end of the current accumulator */
+ else if(addr >= f->shared->accum.loc && (addr + size) > (f->shared->accum.loc + f->shared->accum.size)) {
+ /* Calculate the amount we will need to add to the accumulator size, based on the amount of overlap */
+ H5_ASSIGN_OVERFLOW(add_size, (addr + size) - (f->shared->accum.loc + f->shared->accum.size), hsize_t, size_t);
+
+ /* Check if we need to adjust accumulator size */
+ if(H5F_accum_adjust(&f->shared->accum, f->shared->lf, dxpl_id, H5F_ACCUM_APPEND, add_size) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator")
+
+ /* Copy the new metadata to the end */
+ HDmemcpy(f->shared->accum.buf + (addr - f->shared->accum.loc), buf, size);
+
+ /* Set the new size of the metadata accumulator */
+ f->shared->accum.size += add_size;
+
+ /* Mark it as written to */
+ f->shared->accum.dirty = TRUE;
+ } /* end if */
+ else {
+ HDassert(0 && "New metadata overlapped both beginning and end of existing metadata accumulator!");
+ } /* end else */
+ } /* end if */
+ /* New piece of metadata doesn't adjoin or overlap the existing accumulator */
+ else {
+ /* Write out the existing metadata accumulator, with dispatch to driver */
+ if(f->shared->accum.dirty) {
+ if(H5FD_write(f->shared->lf, dxpl_id, H5FD_MEM_DEFAULT, f->shared->accum.loc, f->shared->accum.size, f->shared->accum.buf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed")
+
+ /* Reset accumulator dirty flag */
+ f->shared->accum.dirty = FALSE;
+ } /* end if */
+
+ /* Cache the new piece of metadata */
+ /* Check if we need to resize the buffer */
+ if(size > f->shared->accum.alloc_size) {
+ size_t new_size; /* New size of accumulator */
+
+ /* Adjust the buffer size to be a power of 2 that is large enough to hold data */
+ new_size = (size_t)1 << (1 + H5V_log2_gen((uint64_t)(size - 1)));
+
+ /* Grow the metadata accumulator buffer */
+ if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, new_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer")
+
+ /* Note the new buffer size */
+ f->shared->accum.alloc_size = new_size;
+#ifdef H5_CLEAR_MEMORY
+{
+size_t clear_size = MAX(f->shared->accum.size, size);
+HDmemset(f->shared->accum.buf + clear_size, 0, (f->shared->accum.alloc_size - clear_size));
+}
+#endif /* H5_CLEAR_MEMORY */
+ } /* end if */
+ else {
+ /* Check if we should shrink the accumulator buffer */
+ if(size < (f->shared->accum.alloc_size / H5F_ACCUM_THROTTLE) &&
+ f->shared->accum.alloc_size > H5F_ACCUM_THRESHOLD) {
+ size_t tmp_size = (f->shared->accum.alloc_size / H5F_ACCUM_THROTTLE); /* New size of accumulator buffer */
+
+ /* Shrink the accumulator buffer */
+ if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, tmp_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer")
+
+ /* Note the new buffer size */
+ f->shared->accum.alloc_size = tmp_size;
+ } /* end if */
+ } /* end else */
+
+ /* Update the metadata accumulator information */
+ f->shared->accum.loc = addr;
+ f->shared->accum.size = size;
+ f->shared->accum.dirty = TRUE;
+
+ /* Store the piece of metadata in the accumulator */
+ HDmemcpy(f->shared->accum.buf, buf, size);
+ } /* end else */
+ } /* end if */
+ /* No metadata in the accumulator, grab this piece and keep it */
+ else {
+ /* Check if we need to reallocate the buffer */
+ if(size > f->shared->accum.alloc_size) {
+ size_t new_size; /* New size of accumulator */
+
+ /* Adjust the buffer size to be a power of 2 that is large enough to hold data */
+ new_size = (size_t)1 << (1 + H5V_log2_gen((uint64_t)(size - 1)));
+
+ /* Reallocate the metadata accumulator buffer */
+ if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, new_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer")
+
+ /* Note the new buffer size */
+ f->shared->accum.alloc_size = new_size;
+ } /* end if */
+
+ /* Update the metadata accumulator information */
+ f->shared->accum.loc = addr;
+ f->shared->accum.size = size;
+ f->shared->accum.dirty = TRUE;
+
+ /* Store the piece of metadata in the accumulator */
+ HDmemcpy(f->shared->accum.buf, buf, size);
+ } /* end else */
+
+ /* Indicate success */
+ HGOTO_DONE(TRUE);
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_accum_write() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_accum_free
+ *
+ * Purpose: Check for free space invalidating [part of] a metadata
+ * accumulator.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jan 10 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_accum_free(H5F_t *f, hid_t dxpl_id, H5FD_mem_t UNUSED type, haddr_t addr,
+ hsize_t size)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5F_accum_free, FAIL)
+
+ /* check arguments */
+ HDassert(f);
+
+ /* Adjust the metadata accumulator to remove the freed block, if it overlaps */
+ if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA)
+ && H5F_addr_overlap(addr, size, f->shared->accum.loc, f->shared->accum.size)) {
+ size_t overlap_size; /* Size of overlap with accumulator */
+
+ /* Sanity check */
+ /* (The metadata accumulator should not intersect w/raw data */
+ HDassert(H5FD_MEM_DRAW != type);
+
+ /* Check for overlapping the beginning of the accumulator */
+ if(H5F_addr_le(addr, f->shared->accum.loc)) {
+ /* Check for completely overlapping the accumulator */
+ if(H5F_addr_ge(addr + size, f->shared->accum.loc + f->shared->accum.size)) {
+ /* Reset the accumulator, but don't free buffer */
+ f->shared->accum.loc = HADDR_UNDEF;
+ f->shared->accum.size = 0;
+ f->shared->accum.dirty = FALSE;
+ } /* end if */
+ /* Block to free must end within the accumulator */
+ else {
+ size_t new_accum_size; /* Size of new accumulator buffer */
+
+ /* Calculate the size of the overlap with the accumulator, etc. */
+ H5_ASSIGN_OVERFLOW(overlap_size, (addr + size) - f->shared->accum.loc, haddr_t, size_t);
+ new_accum_size = f->shared->accum.size - overlap_size;
+
+ /* Move the accumulator buffer information to eliminate the freed block */
+ HDmemmove(f->shared->accum.buf, f->shared->accum.buf + overlap_size, new_accum_size);
+
+ /* Adjust the accumulator information */
+ f->shared->accum.loc += overlap_size;
+ f->shared->accum.size = new_accum_size;
+ } /* end else */
+ } /* end if */
+ /* Block to free must start within the accumulator */
+ else {
+ /* Calculate the size of the overlap with the accumulator */
+ H5_ASSIGN_OVERFLOW(overlap_size, (f->shared->accum.loc + f->shared->accum.size) - addr, haddr_t, size_t);
+
+ /* Block to free is in the middle of the accumulator */
+ if(H5F_addr_lt((addr + size), f->shared->accum.loc + f->shared->accum.size)) {
+ haddr_t tail_addr;
+ size_t tail_size;
+
+ /* Calculate the address & size of the tail to write */
+ tail_addr = addr + size;
+ H5_ASSIGN_OVERFLOW(tail_size, (f->shared->accum.loc + f->shared->accum.size) - tail_addr, haddr_t, size_t);
+
+ /* Write out the part of the accumulator after the block to free */
+ if(H5FD_write(f->shared->lf, dxpl_id, H5FD_MEM_DEFAULT, tail_addr, tail_size, f->shared->accum.buf + (tail_addr - f->shared->accum.loc)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed")
+ } /* end if */
+
+ /* Adjust the accumulator information */
+ f->shared->accum.size = f->shared->accum.size - overlap_size;
+ } /* end else */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_accum_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_accum_flush
+ *
+ * Purpose: Flush the metadata accumulator to the file
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jan 10 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_accum_flush(H5F_t *f, hid_t dxpl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5F_accum_flush, FAIL)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ /* Check if we need to flush out the metadata accumulator */
+ if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && f->shared->accum.dirty && f->shared->accum.size > 0) {
+ /* Flush the metadata contents */
+ if(H5FD_write(f->shared->lf, dxpl_id, H5FD_MEM_DEFAULT, f->shared->accum.loc, f->shared->accum.size, f->shared->accum.buf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed")
+
+ /* Reset the dirty flag */
+ f->shared->accum.dirty = FALSE;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_accum_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_accum_reset
+ *
+ * Purpose: Reset the metadata accumulator for the file
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jan 10 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_accum_reset(H5F_t *f, hid_t dxpl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5F_accum_reset, FAIL)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ /* Flush any dirty data in accumulator */
+ if(H5F_accum_flush(f, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "can't flush metadata accumulator")
+
+ /* Check if we need to reset the metadata accumulator information */
+ if(f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) {
+ /* Sanity check */
+ HDassert(!f->closing || FALSE == f->shared->accum.dirty);
+
+ /* Free the buffer */
+ if(f->shared->accum.buf)
+ f->shared->accum.buf = H5FL_BLK_FREE(meta_accum, f->shared->accum.buf);
+
+ /* Reset the buffer sizes & location */
+ f->shared->accum.alloc_size = f->shared->accum.size = 0;
+ f->shared->accum.loc = HADDR_UNDEF;
+ f->shared->accum.dirty = FALSE;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_accum_reset() */
+
diff --git a/src/H5Fdbg.c b/src/H5Fdbg.c
index edc138f..ba55b8f 100644
--- a/src/H5Fdbg.c
+++ b/src/H5Fdbg.c
@@ -51,7 +51,6 @@ H5F_debug(H5F_t *f, FILE *stream, int indent, int fwidth)
{
H5P_genplist_t *plist; /* File creation property list */
hsize_t userblock_size; /* Userblock size */
- unsigned super_vers; /* Superblock version # */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5F_debug, FAIL)
@@ -63,31 +62,31 @@ H5F_debug(H5F_t *f, FILE *stream, int indent, int fwidth)
HDassert(fwidth >= 0);
/* Get property list */
- if(NULL == (plist = H5I_object(f->shared->fcpl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(f->shared->fcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
/* Retrieve file creation properties */
if(H5P_get(plist, H5F_CRT_USER_BLOCK_NAME, &userblock_size) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get userblock size")
- if(H5P_get(plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get superblock version")
/* debug */
HDfprintf(stream, "%*sFile Super Block...\n", indent, "");
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
- "File name:", f->name);
+ "File name (as opened):", H5F_OPEN_NAME(f));
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "File name (after resolving symlinks):", H5F_ACTUAL_NAME(f));
HDfprintf(stream, "%*s%-*s 0x%08x\n", indent, "", fwidth,
"File access flags", f->shared->flags);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"File open reference count:", f->shared->nrefs);
HDfprintf(stream, "%*s%-*s %a (abs)\n", indent, "", fwidth,
- "Address of super block:", f->shared->super_addr);
+ "Address of super block:", f->shared->sblock->base_addr);
HDfprintf(stream, "%*s%-*s %Hu bytes\n", indent, "", fwidth,
"Size of userblock:", userblock_size);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Superblock version number:", super_vers);
+ "Superblock version number:", f->shared->sblock->super_vers);
/* Hard-wired versions */
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
@@ -102,15 +101,13 @@ H5F_debug(H5F_t *f, FILE *stream, int indent, int fwidth)
HDfprintf(stream, "%*s%-*s %u bytes\n", indent, "", fwidth,
"Size of file lengths (hsize_t type):", (unsigned) f->shared->sizeof_size);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Symbol table leaf node 1/2 rank:", f->shared->sym_leaf_k);
+ "Symbol table leaf node 1/2 rank:", f->shared->sblock->sym_leaf_k);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Symbol table internal node 1/2 rank:", f->shared->btree_k[H5B_SNODE_ID]);
+ "Symbol table internal node 1/2 rank:", f->shared->sblock->btree_k[H5B_SNODE_ID]);
HDfprintf(stream, "%*s%-*s 0x%02x\n", indent, "", fwidth,
- "File status flags:", (unsigned)(f->shared->status_flags));
- HDfprintf(stream, "%*s%-*s %a (abs)\n", indent, "", fwidth,
- "Base address:", f->shared->base_addr);
+ "File status flags:", (unsigned)(f->shared->sblock->status_flags));
HDfprintf(stream, "%*s%-*s %a (rel)\n", indent, "", fwidth,
- "Superblock extension address:", f->shared->extension_addr);
+ "Superblock extension address:", f->shared->sblock->ext_addr);
HDfprintf(stream, "%*s%-*s %a (rel)\n", indent, "", fwidth,
"Shared object header message table address:", f->shared->sohm_addr);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
@@ -119,26 +116,31 @@ H5F_debug(H5F_t *f, FILE *stream, int indent, int fwidth)
"Number of shared object header message indexes:", (unsigned) f->shared->sohm_nindexes);
HDfprintf(stream, "%*s%-*s %a (rel)\n", indent, "", fwidth,
- "Address of driver information block:", f->shared->driver_addr);
+ "Address of driver information block:", f->shared->sblock->driver_addr);
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
"Root group symbol table entry:",
f->shared->root_grp ? "" : "(none)");
if(f->shared->root_grp) {
- H5O_loc_t *root_oloc; /* Root object location */
- H5G_entry_t root_ent; /* Constructed root symbol table entry */
-
- /* Reset the root group entry */
- H5G_ent_reset(&root_ent);
-
- /* Build up a simulated root group symbol table entry */
- root_oloc = H5G_oloc(f->shared->root_grp);
- HDassert(root_oloc);
- root_ent.type = H5G_NOTHING_CACHED;
- root_ent.header = root_oloc->addr;
-
- /* Display root group symbol table entry info */
- H5G_ent_debug(&root_ent, stream, indent + 3, MAX(0, fwidth - 3), NULL);
+ if(f->shared->sblock->root_ent) /* Use real root group symbol table entry */
+ H5G_ent_debug(f->shared->sblock->root_ent, stream, indent + 3, MAX(0, fwidth - 3), NULL);
+ else {
+ H5O_loc_t *root_oloc; /* Root object location */
+ H5G_entry_t root_ent; /* Constructed root symbol table entry */
+
+ /* Reset the root group entry */
+ H5G_ent_reset(&root_ent);
+
+ /* Build up a simulated root group symbol table entry */
+ root_oloc = H5G_oloc(f->shared->root_grp);
+ HDassert(root_oloc);
+ root_ent.type = H5G_NOTHING_CACHED;
+ root_ent.header = root_oloc->addr;
+ root_ent.file = f;
+
+ /* Display root group symbol table entry info */
+ H5G_ent_debug(&root_ent, stream, indent + 3, MAX(0, fwidth - 3), NULL);
+ } /* end else */
} /* end if */
done:
diff --git a/src/H5Fdeprec.c b/src/H5Fdeprec.c
new file mode 100644
index 0000000..7e1136c
--- /dev/null
+++ b/src/H5Fdeprec.c
@@ -0,0 +1,173 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Fdeprec.c
+ * October 1 2009
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Deprecated functions from the H5F interface. These
+ * functions are here for compatibility purposes and may be
+ * removed in the future. Applications should switch to the
+ * newer APIs.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+
+/* Interface initialization */
+#define H5_INTERFACE_INIT_FUNC H5F_init_deprec_interface
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5Iprivate.h" /* IDs */
+#include "H5SMprivate.h" /* Shared object header messages */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*--------------------------------------------------------------------------
+NAME
+ H5F_init_deprec_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5F_init_deprec_interface()
+RETURNS
+ Non-negative on success/Negative on failure
+DESCRIPTION
+ Initializes any interface-specific data or routines. (Just calls
+ H5F_init() currently).
+
+--------------------------------------------------------------------------*/
+static herr_t
+H5F_init_deprec_interface(void)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_init_deprec_interface)
+
+ FUNC_LEAVE_NOAPI(H5F_init())
+} /* H5F_init_deprec_interface() */
+
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+
+/*-------------------------------------------------------------------------
+ * Function: H5Fget_info1
+ *
+ * Purpose: Gets general information about the file, including:
+ * 1. Get storage size for superblock extension if there is one.
+ * 2. Get the amount of btree and heap storage for entries
+ * in the SOHM table if there is one.
+ * 3. The amount of free space tracked in the file.
+ *
+ * Return: Success: non-negative on success
+ * Failure: Negative
+ *
+ * Programmer: Vailin Choi
+ * July 11, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Fget_info1(hid_t obj_id, H5F_info1_t *finfo)
+{
+ H5F_t *f; /* Top file in mount hierarchy */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Fget_info1, FAIL)
+ H5TRACE2("e", "i*x", obj_id, finfo);
+
+ /* Check args */
+ if(!finfo)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct")
+
+ /* For file IDs, get the file object directly */
+ /* (This prevents the H5G_loc() call from returning the file pointer for
+ * the top file in a mount hierarchy)
+ */
+ if(H5I_get_type(obj_id) == H5I_FILE ) {
+ if(NULL == (f = (H5F_t *)H5I_object(obj_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
+ } /* end if */
+ else {
+ H5G_loc_t loc; /* Object location */
+
+ /* Get symbol table entry */
+ if(H5G_loc(obj_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object ID")
+ f = loc.oloc->file;
+ } /* end else */
+ HDassert(f->shared);
+
+ /* Reset file info struct */
+ HDmemset(finfo, 0, sizeof(*finfo));
+
+ /* Get the size of the superblock extension */
+ if(H5F_super_size(f, H5AC_ind_dxpl_id, NULL, &finfo->super_ext_size) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve superblock extension size")
+
+ /* Check for SOHM info */
+ if(H5F_addr_defined(f->shared->sohm_addr))
+ if(H5SM_ih_size(f, H5AC_ind_dxpl_id, &finfo->sohm.hdr_size, &finfo->sohm.msgs_info) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve SOHM index & heap storage info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Fget_info1() */
+
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
+
diff --git a/src/H5Ffake.c b/src/H5Ffake.c
index 42a33e0..e96aedf 100644
--- a/src/H5Ffake.c
+++ b/src/H5Ffake.c
@@ -67,7 +67,7 @@ H5F_init_fake_interface(void)
*-------------------------------------------------------------------------
*/
H5F_t *
-H5F_fake_alloc(size_t sizeof_size)
+H5F_fake_alloc(uint8_t sizeof_size)
{
H5F_t *f = NULL; /* Pointer to fake file struct */
H5F_t *ret_value; /* Return value */
@@ -120,8 +120,8 @@ H5F_fake_free(H5F_t *f)
if(f) {
/* Destroy shared file struct */
if(f->shared)
- f->shared = H5FL_FREE(H5F_file_t, f->shared);
- H5FL_FREE(H5F_t, f);
+ f->shared = (H5F_file_t *)H5FL_FREE(H5F_file_t, f->shared);
+ (void)H5FL_FREE(H5F_t, f);
} /* end if */
FUNC_LEAVE_NOAPI(SUCCEED)
diff --git a/src/H5Fio.c b/src/H5Fio.c
new file mode 100644
index 0000000..407f950
--- /dev/null
+++ b/src/H5Fio.c
@@ -0,0 +1,173 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Fio.c
+ * Jan 10 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: File I/O routines.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5FDprivate.h" /* File drivers */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_block_read
+ *
+ * Purpose: Reads some data from a file/server/etc into a buffer.
+ * The data is contiguous. The address is relative to the base
+ * address for the file.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Jul 10 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size,
+ hid_t dxpl_id, void *buf/*out*/)
+{
+ htri_t accumulated; /* Whether the data was accepted by the metadata accumulator */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5F_block_read, FAIL)
+
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(buf);
+
+ /* Check for attempting I/O on 'temporary' file address */
+ if(H5F_addr_le(f->shared->tmp_addr, (addr + size)))
+ HGOTO_ERROR(H5E_IO, H5E_BADRANGE, FAIL, "attempting I/O in temporary file space")
+
+ /* Check if this I/O can be satisfied by the metadata accumulator */
+ if((accumulated = H5F_accum_read(f, dxpl_id, type, addr, size, buf)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "read from metadata accumulator failed")
+ else if(accumulated == FALSE) {
+ /* Read the data */
+ if(H5FD_read(f->shared->lf, dxpl_id, type, addr, size, buf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed")
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_block_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_block_write
+ *
+ * Purpose: Writes some data from memory to a file/server/etc. The
+ * data is contiguous. The address is relative to the base
+ * address.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Jul 10 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_block_write(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size,
+ hid_t dxpl_id, const void *buf)
+{
+ htri_t accumulated; /* Whether the data was accepted by the metadata accumulator */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5F_block_write, FAIL)
+#ifdef QAK
+HDfprintf(stderr, "%s: write to addr = %a, size = %Zu\n", FUNC, addr, size);
+#endif /* QAK */
+
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->intent & H5F_ACC_RDWR);
+ HDassert(buf);
+
+ /* Check for attempting I/O on 'temporary' file address */
+ if(H5F_addr_le(f->shared->tmp_addr, (addr + size)))
+ HGOTO_ERROR(H5E_IO, H5E_BADRANGE, FAIL, "attempting I/O in temporary file space")
+
+ /* Check for accumulating metadata */
+ if((accumulated = H5F_accum_write(f, dxpl_id, type, addr, size, buf)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write to metadata accumulator failed")
+ else if(accumulated == FALSE) {
+ /* Write the data */
+ if(H5FD_write(f->shared->lf, dxpl_id, type, addr, size, buf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed")
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_block_write() */
+
diff --git a/src/H5Fmount.c b/src/H5Fmount.c
index b922446..f70a7c6 100644
--- a/src/H5Fmount.c
+++ b/src/H5Fmount.c
@@ -79,8 +79,10 @@ H5F_close_mounts(H5F_t *f)
HDassert(f);
- /* Unmount all child files */
- for (u = 0; u < f->shared->mtab.nmounts; u++) {
+ /* Unmount all child files. Loop backwards to avoid having to adjust u when
+ * a file is unmounted. Note that we rely on unsigned u "wrapping around"
+ * to terminate the loop. */
+ for (u = f->shared->mtab.nmounts - 1; u < f->shared->mtab.nmounts; u--) {
/* Only unmount children mounted to this top level file structure */
if(f->shared->mtab.child[u].file->parent == f) {
/* Detach the child file from the parent file */
@@ -93,10 +95,16 @@ H5F_close_mounts(H5F_t *f)
/* Close the child file */
if(H5F_try_close(f->shared->mtab.child[u].file) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close child file")
+
+ /* Eliminate the mount point from the table */
+ HDmemmove(f->shared->mtab.child + u, f->shared->mtab.child + u + 1,
+ (f->shared->mtab.nmounts - u - 1) * sizeof(f->shared->mtab.child[0]));
+ f->shared->mtab.nmounts--;
+ f->nmounts--;
}
} /* end if */
- f->shared->mtab.nmounts -= f->nmounts;
- f->nmounts = 0;
+
+ HDassert(f->nmounts == 0);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -159,7 +167,7 @@ H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child,
* user from doing this.
*/
if(mp_loc.oloc->holding_file != FALSE)
- HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount path cannot contain links to external files")
+ HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount path cannot contain links to external files")
/* Open the mount point group */
if(NULL == (mount_point = H5G_open(&mp_loc, dxpl_id)))
@@ -215,8 +223,8 @@ H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child,
/* Make room in the table */
if(parent->shared->mtab.nmounts >= parent->shared->mtab.nalloc) {
unsigned n = MAX(16, 2 * parent->shared->mtab.nalloc);
- H5F_mount_t *x = H5MM_realloc(parent->shared->mtab.child,
- n * sizeof(parent->shared->mtab.child[0]));
+ H5F_mount_t *x = (H5F_mount_t *)H5MM_realloc(parent->shared->mtab.child, n * sizeof(parent->shared->mtab.child[0]));
+
if(!x)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for mount table")
parent->shared->mtab.child = x;
@@ -331,7 +339,7 @@ H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id)
for(u = 0; u < parent->shared->mtab.nmounts; u++) {
if(parent->shared->mtab.child[u].file->shared == child->shared) {
/* Found the correct index */
- child_idx = u;
+ child_idx = (int)u;
break;
} /* end if */
} /* end for */
@@ -360,7 +368,7 @@ H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id)
HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "not a mount point")
/* Found the correct index, set the info about the child */
- child_idx = md;
+ child_idx = (int)md;
H5G_loc_free(&mp_loc);
mp_loc_setup = FALSE;
mp_loc.oloc = mnt_oloc;
@@ -389,8 +397,8 @@ H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name")
/* Eliminate the mount point from the table */
- HDmemmove(parent->shared->mtab.child + child_idx, parent->shared->mtab.child + child_idx + 1,
- (parent->shared->mtab.nmounts-child_idx) * sizeof(parent->shared->mtab.child[0]));
+ HDmemmove(parent->shared->mtab.child + (unsigned)child_idx, (parent->shared->mtab.child + (unsigned)child_idx) + 1,
+ ((parent->shared->mtab.nmounts - (unsigned)child_idx) - 1) * sizeof(parent->shared->mtab.child[0]));
parent->shared->mtab.nmounts -= 1;
parent->nmounts -= 1;
@@ -463,7 +471,7 @@ H5Fmount(hid_t loc_id, const char *name, hid_t child_id, hid_t plist_id)
{
H5G_loc_t loc;
H5F_t *child = NULL;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Fmount, FAIL)
H5TRACE4("e", "i*sii", loc_id, name, child_id, plist_id);
@@ -473,7 +481,7 @@ H5Fmount(hid_t loc_id, const char *name, hid_t child_id, hid_t plist_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
- if(NULL == (child = H5I_object_verify(child_id,H5I_FILE)))
+ if(NULL == (child = (H5F_t *)H5I_object_verify(child_id, H5I_FILE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
if(H5P_DEFAULT == plist_id)
plist_id = H5P_FILE_MOUNT_DEFAULT;
@@ -619,3 +627,80 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_mount_count_ids() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_flush_mounts_recurse
+ *
+ * Purpose: Flush a mount hierarchy, recursively
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Fri, August 21, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_flush_mounts_recurse(H5F_t *f, hid_t dxpl_id)
+{
+ unsigned nerrors = 0; /* Errors from recursive flushes */
+ unsigned u; /* Index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5F_flush_mounts_recurse)
+
+ /* Sanity check */
+ HDassert(f);
+
+ /* Flush all child files, not stopping for errors */
+ for(u = 0; u < f->shared->mtab.nmounts; u++)
+ if(H5F_flush_mounts_recurse(f->shared->mtab.child[u].file, dxpl_id) < 0)
+ nerrors++;
+
+ /* Call the "real" flush routine, for this file */
+ if(H5F_flush(f, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information")
+
+ /* Check flush errors for children - errors are already on the stack */
+ if(nerrors)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's child mounts")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_flush_mounts_recurse() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_flush_mounts
+ *
+ * Purpose: Flush a mount hierarchy
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Fri, August 21, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_flush_mounts(H5F_t *f, hid_t dxpl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5F_flush_mounts, FAIL)
+
+ /* Sanity check */
+ HDassert(f);
+
+ /* Find the top file in the mount hierarchy */
+ while(f->parent)
+ f = f->parent;
+
+ /* Flush the mounted file hierarchy */
+ if(H5F_flush_mounts_recurse(f, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush mounted file hierarchy")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_flush_mounts() */
+
diff --git a/src/H5Fmpi.c b/src/H5Fmpi.c
new file mode 100644
index 0000000..c90ad7c
--- /dev/null
+++ b/src/H5Fmpi.c
@@ -0,0 +1,181 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Fmpi.c
+ * Jan 10 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: MPI-related routines.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5FDmpi.h" /* MPI-based file drivers */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+#ifdef H5_HAVE_PARALLEL
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_mpi_get_rank
+ *
+ * Purpose: Retrieves the rank of an MPI process.
+ *
+ * Return: Success: The rank (non-negative)
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, January 30, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5F_mpi_get_rank(const H5F_t *f)
+{
+ int ret_value;
+
+ FUNC_ENTER_NOAPI(H5F_mpi_get_rank, FAIL)
+
+ assert(f && f->shared);
+
+ /* Dispatch to driver */
+ if ((ret_value=H5FD_mpi_get_rank(f->shared->lf)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "driver get_rank request failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_mpi_get_rank() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_mpi_get_comm
+ *
+ * Purpose: Retrieves the file's communicator
+ *
+ * Return: Success: The communicator (non-negative)
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, January 30, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+MPI_Comm
+H5F_mpi_get_comm(const H5F_t *f)
+{
+ MPI_Comm ret_value;
+
+ FUNC_ENTER_NOAPI(H5F_mpi_get_comm, MPI_COMM_NULL)
+
+ assert(f && f->shared);
+
+ /* Dispatch to driver */
+ if ((ret_value=H5FD_mpi_get_comm(f->shared->lf))==MPI_COMM_NULL)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, MPI_COMM_NULL, "driver get_comm request failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_mpi_get_comm() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_mpi_get_size
+ *
+ * Purpose: Retrieves the size of an MPI process.
+ *
+ * Return: Success: The size (positive)
+ *
+ * Failure: Negative
+ *
+ * Programmer: John Mainzer
+ * Friday, May 6, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5F_mpi_get_size(const H5F_t *f)
+{
+ int ret_value;
+
+ FUNC_ENTER_NOAPI(H5F_mpi_get_size, FAIL)
+
+ assert(f && f->shared);
+
+ /* Dispatch to driver */
+ if ((ret_value=H5FD_mpi_get_size(f->shared->lf)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "driver get_size request failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_mpi_get_size() */
+#endif /* H5_HAVE_PARALLEL */
+
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 594ed50..73962bb 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -38,10 +38,12 @@
#include "H5private.h" /* Generic Functions */
#include "H5FLprivate.h" /* Free Lists */
#include "H5FOprivate.h" /* File objects */
+#include "H5FSprivate.h" /* File free space */
#include "H5Gprivate.h" /* Groups */
#include "H5Oprivate.h" /* Object header messages */
#include "H5RCprivate.h" /* Reference counted object functions */
+
/*
* Feature: Define this constant on the compiler command-line if you want to
* see some debugging messages on the debug stream.
@@ -60,7 +62,94 @@
#define H5F_SUPER_ALL_FLAGS (H5F_SUPER_WRITE_ACCESS | H5F_SUPER_FILE_OK)
/* Mask for removing private file access flags */
-#define H5F_ACC_PUBLIC_FLAGS 0x00ffu
+#define H5F_ACC_PUBLIC_FLAGS 0x001fu
+
+/* Free space section+aggregator merge flags */
+#define H5F_FS_MERGE_METADATA 0x01 /* Section can merge with metadata aggregator */
+#define H5F_FS_MERGE_RAWDATA 0x02 /* Section can merge with small 'raw' data aggregator */
+
+/* Macro to abstract checking whether file is using a free space manager */
+#define H5F_HAVE_FREE_SPACE_MANAGER(F) \
+ ((F)->shared->fs_strategy == H5F_FILE_SPACE_ALL || \
+ (F)->shared->fs_strategy == H5F_FILE_SPACE_ALL_PERSIST)
+
+/* Macros for encoding/decoding superblock */
+#define H5F_MAX_DRVINFOBLOCK_SIZE 1024 /* Maximum size of superblock driver info buffer */
+#define H5F_DRVINFOBLOCK_HDR_SIZE 16 /* Size of superblock driver info header */
+
+/* Superblock sizes for various versions */
+#define H5F_SIZEOF_CHKSUM 4 /* Checksum size in the file */
+
+/* Fixed-size portion at the beginning of all superblocks */
+#define H5F_SUPERBLOCK_FIXED_SIZE ( H5F_SIGNATURE_LEN \
+ + 1) /* superblock version */
+
+/* Macros for computing variable-size superblock size */
+#define H5F_SUPERBLOCK_VARLEN_SIZE_COMMON \
+ (2 /* freespace, and root group versions */ \
+ + 1 /* reserved */ \
+ + 3 /* shared header vers, size of address, size of lengths */ \
+ + 1 /* reserved */ \
+ + 4 /* group leaf k, group internal k */ \
+ + 4) /* consistency flags */
+#define H5F_SUPERBLOCK_VARLEN_SIZE_V0(f) \
+ ( H5F_SUPERBLOCK_VARLEN_SIZE_COMMON /* Common variable-length info */ \
+ + H5F_SIZEOF_ADDR(f) /* base address */ \
+ + H5F_SIZEOF_ADDR(f) /* <unused> */ \
+ + H5F_SIZEOF_ADDR(f) /* EOF address */ \
+ + H5F_SIZEOF_ADDR(f) /* driver block address */ \
+ + H5G_SIZEOF_ENTRY(f)) /* root group ptr */
+#define H5F_SUPERBLOCK_VARLEN_SIZE_V1(f) \
+ ( H5F_SUPERBLOCK_VARLEN_SIZE_COMMON /* Common variable-length info */ \
+ + 2 /* indexed B-tree internal k */ \
+ + 2 /* reserved */ \
+ + H5F_SIZEOF_ADDR(f) /* base address */ \
+ + H5F_SIZEOF_ADDR(f) /* <unused> */ \
+ + H5F_SIZEOF_ADDR(f) /* EOF address */ \
+ + H5F_SIZEOF_ADDR(f) /* driver block address */ \
+ + H5G_SIZEOF_ENTRY(f)) /* root group ptr */
+#define H5F_SUPERBLOCK_VARLEN_SIZE_V2(f) \
+ ( 2 /* size of address, size of lengths */ \
+ + 1 /* consistency flags */ \
+ + H5F_SIZEOF_ADDR(f) /* base address */ \
+ + H5F_SIZEOF_ADDR(f) /* superblock extension address */ \
+ + H5F_SIZEOF_ADDR(f) /* EOF address */ \
+ + H5F_SIZEOF_ADDR(f) /* root group object header address */ \
+ + H5F_SIZEOF_CHKSUM) /* superblock checksum (keep this last) */
+#define H5F_SUPERBLOCK_VARLEN_SIZE(v, f) ( \
+ (v == 0 ? H5F_SUPERBLOCK_VARLEN_SIZE_V0(f) : 0) \
+ + (v == 1 ? H5F_SUPERBLOCK_VARLEN_SIZE_V1(f) : 0) \
+ + (v == 2 ? H5F_SUPERBLOCK_VARLEN_SIZE_V2(f) : 0))
+
+/* Total size of superblock, depends on superblock version */
+#define H5F_SUPERBLOCK_SIZE(v, f) ( H5F_SUPERBLOCK_FIXED_SIZE \
+ + H5F_SUPERBLOCK_VARLEN_SIZE(v, f))
+
+
+/* Structure for metadata & "small [raw] data" block aggregation fields */
+struct H5F_blk_aggr_t {
+ unsigned long feature_flag; /* Feature flag type */
+ hsize_t alloc_size; /* Size for allocating new blocks */
+ hsize_t tot_size; /* Total amount of bytes aggregated into block */
+ hsize_t size; /* Current size of block left */
+ haddr_t addr; /* Location of block left */
+};
+
+/* Structure for metadata accumulator fields */
+typedef struct H5F_meta_accum_t {
+ unsigned char *buf; /* Buffer to hold the accumulated metadata */
+ haddr_t loc; /* File location (offset) of the accumulated metadata */
+ size_t size; /* Size of the accumulated metadata buffer used (in bytes) */
+ size_t alloc_size; /* Size of the accumulated metadata buffer allocated (in bytes) */
+ hbool_t dirty; /* Flag to indicate that the accumulated metadata is dirty */
+} H5F_meta_accum_t;
+
+/* Enum for free space manager state */
+typedef enum H5F_fs_state_t {
+ H5F_FS_STATE_CLOSED, /* Free space manager is closed */
+ H5F_FS_STATE_OPEN, /* Free space manager has been opened */
+ H5F_FS_STATE_DELETING /* Free space manager is being deleted */
+} H5F_fs_state_t;
/* A record of the mount table */
typedef struct H5F_mount_t {
@@ -78,6 +167,23 @@ typedef struct H5F_mtab_t {
H5F_mount_t *child; /* An array of mount records */
} H5F_mtab_t;
+/* Structure specifically to store superblock. This was originally
+ * maintained entirely within H5F_file_t, but is now extracted
+ * here because the superblock is now handled by the cache */
+typedef struct H5F_super_t {
+ H5AC_info_t cache_info; /* Cache entry information structure */
+ unsigned super_vers; /* Superblock version */
+ uint8_t status_flags; /* File status flags */
+ unsigned sym_leaf_k; /* Size of leaves in symbol tables */
+ unsigned btree_k[H5B_NUM_BTREE_ID]; /* B-tree key values for each type */
+ haddr_t base_addr; /* Absolute base address for rel.addrs. */
+ /* (superblock for file is at this offset) */
+ haddr_t ext_addr; /* Relative address of superblock extension */
+ haddr_t driver_addr; /* File driver information block address */
+ haddr_t root_addr; /* Root group address */
+ H5G_entry_t *root_ent; /* Root group symbol table entry */
+} H5F_super_t;
+
/*
* Define the structure to store the file information for HDF5 files. One of
* these structures is allocated per file, not per H5Fopen(). That is, set of
@@ -87,23 +193,18 @@ typedef struct H5F_mtab_t {
*/
typedef struct H5F_file_t {
H5FD_t *lf; /* Lower level file handle for I/O */
+ H5F_super_t *sblock; /* Pointer to (pinned) superblock for file */
unsigned nrefs; /* Ref count for times file is opened */
- uint8_t status_flags; /* File status flags */
- unsigned flags; /* Access Permissions for file */
- H5F_mtab_t mtab; /* File mount table */
+ unsigned flags; /* Access Permissions for file */
+ H5F_mtab_t mtab; /* File mount table */
/* Cached values from FCPL/superblock */
- unsigned sym_leaf_k; /* Size of leaves in symbol tables */
- unsigned btree_k[H5B_NUM_BTREE_ID]; /* B-tree key values for each type */
- size_t sizeof_addr; /* Size of addresses in file */
- size_t sizeof_size; /* Size of offsets in file */
- haddr_t super_addr; /* Absolute address of super block */
- haddr_t base_addr; /* Absolute base address for rel.addrs. */
- haddr_t extension_addr; /* Relative address of superblock extension */
+ uint8_t sizeof_addr; /* Size of addresses in file */
+ uint8_t sizeof_size; /* Size of offsets in file */
haddr_t sohm_addr; /* Relative address of shared object header message table */
unsigned sohm_vers; /* Version of shared message table on disk */
unsigned sohm_nindexes; /* Number of shared messages indexes in the table */
- haddr_t driver_addr; /* File driver information block address*/
+ unsigned long feature_flags; /* VFL Driver feature Flags */
haddr_t maxaddr; /* Maximum address for file */
H5AC_t *cache; /* The object cache */
@@ -114,7 +215,7 @@ typedef struct H5F_file_t {
/* not change thereafter. */
hid_t fcpl_id; /* File creation property list ID */
H5F_close_degree_t fc_degree; /* File close behavior degree */
- size_t rdcc_nelmts; /* Size of raw data chunk cache (elmts) */
+ size_t rdcc_nslots; /* Size of raw data chunk cache (slots) */
size_t rdcc_nbytes; /* Size of raw data chunk cache (bytes) */
double rdcc_w0; /* Preempt read chunks first? [0.0..1.0]*/
size_t sieve_buf_size; /* Size of the data sieve buffer allocated (in bytes) */
@@ -123,35 +224,51 @@ typedef struct H5F_file_t {
unsigned gc_ref; /* Garbage-collect references? */
hbool_t latest_format; /* Always use the latest format? */
hbool_t store_msg_crt_idx; /* Store creation index for object header messages? */
- hbool_t fam_to_sec2; /* Is h5repart changing driver from family to sec2? */
- int ncwfs; /* Num entries on cwfs list */
+ int ncwfs; /* Num entries on cwfs list */
struct H5HG_heap_t **cwfs; /* Global heap cache */
struct H5G_t *root_grp; /* Open root group */
H5FO_t *open_objs; /* Open objects in file */
H5RC_t *grp_btree_shared; /* Ref-counted group B-tree node info */
+
+ /* File space allocation information */
+ H5F_file_space_type_t fs_strategy; /* File space handling strategy */
+ hsize_t fs_threshold; /* Free space section threshold */
+ hbool_t use_tmp_space; /* Whether temp. file space allocation is allowed */
+ haddr_t tmp_addr; /* Next address to use for temp. space in the file */
+ unsigned fs_aggr_merge[H5FD_MEM_NTYPES]; /* Flags for whether free space can merge with aggregator(s) */
+ H5F_fs_state_t fs_state[H5FD_MEM_NTYPES]; /* State of free space manager for each type */
+ haddr_t fs_addr[H5FD_MEM_NTYPES]; /* Address of free space manager info for each type */
+ H5FS_t *fs_man[H5FD_MEM_NTYPES]; /* Free space manager for each file space type */
+ H5FD_mem_t fs_type_map[H5FD_MEM_NTYPES]; /* Mapping of "real" file space type into tracked type */
+ H5F_blk_aggr_t meta_aggr; /* Metadata aggregation info */
+ /* (if aggregating metadata allocations) */
+ H5F_blk_aggr_t sdata_aggr; /* "Small data" aggregation info */
+ /* (if aggregating "small data" allocations) */
+
+ /* Metadata accumulator information */
+ H5F_meta_accum_t accum; /* Metadata accumulator info */
} H5F_file_t;
/*
* This is the top-level file descriptor. One of these structures is
* allocated every time H5Fopen() is called although they may contain pointers
- * to shared H5F_file_t structs. The reference count (nrefs) indicates the
- * number of times the file has been opened (the application can only open a
- * file once explicitly, but the library can open the file a second time to
- * indicate that the file is mounted on some other file).
+ * to shared H5F_file_t structs.
*/
struct H5F_t {
unsigned intent; /* The flags passed to H5F_open()*/
- char *name; /* Name used to open file */
+ char *open_name; /* Name used to open file */
+ char *actual_name; /* Actual name of the file, after resolving symlinks, etc. */
char *extpath; /* Path for searching target external link file */
H5F_file_t *shared; /* The shared file info */
unsigned nopen_objs; /* Number of open object headers*/
H5FO_t *obj_count; /* # of time each object is opened through top file structure */
hid_t file_id; /* ID of this file */
hbool_t closing; /* File is in the process of being closed */
- struct H5F_t *parent; /* Parent file that this file is mounted to */
+ struct H5F_t *parent; /* Parent file that this file is mounted to */
unsigned nmounts; /* Number of children mounted to this file */
};
+
/*****************************/
/* Package Private Variables */
/*****************************/
@@ -162,6 +279,8 @@ H5FL_EXTERN(H5F_t);
/* Declare a free list to manage the H5F_file_t struct */
H5FL_EXTERN(H5F_file_t);
+H5_DLLVAR const H5AC_class_t H5AC_SUPERBLOCK[1];
+
/******************************/
/* Package Private Prototypes */
@@ -170,18 +289,34 @@ H5FL_EXTERN(H5F_file_t);
/* General routines */
H5_DLL herr_t H5F_init(void);
H5_DLL haddr_t H5F_locate_signature(H5FD_t *file, hid_t dxpl_id);
+H5_DLL herr_t H5F_flush(H5F_t *f, hid_t dxpl_id);
/* File mount related routines */
H5_DLL herr_t H5F_close_mounts(H5F_t *f);
H5_DLL int H5F_term_unmount_cb(void *obj_ptr, hid_t obj_id, void *key);
H5_DLL herr_t H5F_mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nopen_objs);
+H5_DLL herr_t H5F_flush_mounts(H5F_t *f, hid_t dxpl_id);
/* Superblock related routines */
H5_DLL herr_t H5F_super_init(H5F_t *f, hid_t dxpl_id);
-H5_DLL herr_t H5F_super_write(H5F_t *f, hid_t dxpl_id);
-H5_DLL herr_t H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc);
-H5_DLL herr_t H5F_super_ext_size(H5F_t *f, hid_t dxpl_id, hsize_t *super_ext_info);
+H5_DLL herr_t H5F_super_read(H5F_t *f, hid_t dxpl_id);
+H5_DLL herr_t H5F_super_size(H5F_t *f, hid_t dxpl_id, hsize_t *super_size, hsize_t *super_ext_size);
+
+/* Superblock extension related routines */
+H5_DLL herr_t H5F_super_ext_open(H5F_t *f, haddr_t ext_addr, H5O_loc_t *ext_ptr);
+H5_DLL herr_t H5F_super_ext_write_msg(H5F_t *f, hid_t dxpl_id, void *mesg, unsigned id, hbool_t may_create);
+H5_DLL herr_t H5F_super_ext_remove_msg(H5F_t *f, hid_t dxpl_id, unsigned id);
+H5_DLL herr_t H5F_super_ext_close(H5F_t *f, H5O_loc_t *ext_ptr);
+/* Metadata accumulator routines */
+H5_DLL htri_t H5F_accum_read(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type,
+ haddr_t addr, size_t size, void *buf);
+H5_DLL htri_t H5F_accum_write(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type,
+ haddr_t addr, size_t size, const void *buf);
+H5_DLL herr_t H5F_accum_free(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type,
+ haddr_t addr, hsize_t size);
+H5_DLL herr_t H5F_accum_flush(H5F_t *f, hid_t dxpl_id);
+H5_DLL herr_t H5F_accum_reset(H5F_t *f, hid_t dxpl_id);
/* Shared file list related routines */
H5_DLL herr_t H5F_sfile_add(H5F_file_t *shared);
@@ -192,6 +327,8 @@ H5_DLL herr_t H5F_sfile_remove(H5F_file_t *shared);
#ifdef H5F_TESTING
H5_DLL herr_t H5F_get_sohm_mesg_count_test(hid_t fid, unsigned type_id,
size_t *mesg_count);
+H5_DLL herr_t H5F_check_cached_stab_test(hid_t file_id);
+H5_DLL herr_t H5F_get_maxaddr_test(hid_t file_id, haddr_t *maxaddr);
#endif /* H5F_TESTING */
#endif /* _H5Fpkg_H */
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index db79453..10c2976 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -28,6 +28,7 @@
/* Private headers needed by this file */
+
/****************************/
/* Library Private Typedefs */
/****************************/
@@ -35,16 +36,9 @@
/* Main file structure */
typedef struct H5F_t H5F_t;
-/*===----------------------------------------------------------------------===
- * Flush Flags
- *===----------------------------------------------------------------------===
- *
- * Flags passed into the flush routines which indicate what type of
- * flush we want to do. They can be ORed together.
- */
-#define H5F_FLUSH_NONE (0U) /* No flags specified */
-#define H5F_FLUSH_INVALIDATE (1U << 0) /* Invalidate cached data */
-#define H5F_FLUSH_CLOSING (1U << 1) /* Closing the file */
+/* Block aggregation structure */
+typedef struct H5F_blk_aggr_t H5F_blk_aggr_t;
+
/*
* Encode and decode macros for file meta-data.
@@ -214,7 +208,7 @@ typedef struct H5F_t H5F_t;
HADDR_UNDEF==(X)+(haddr_t)(Z) || \
(X)+(haddr_t)(Z)<(X))
#define H5F_addr_hash(X,M) ((unsigned)((X)%(M)))
-#define H5F_addr_defined(X) (X!=HADDR_UNDEF)
+#define H5F_addr_defined(X) ((X)!=HADDR_UNDEF)
/* The H5F_addr_eq() macro guarantees that Y is not HADDR_UNDEF by making
* certain that X is not HADDR_UNDEF and then checking that X equals Y
*/
@@ -233,62 +227,63 @@ typedef struct H5F_t H5F_t;
#define H5F_addr_ge(X,Y) ((X)!=HADDR_UNDEF && \
(Y)!=HADDR_UNDEF && \
(X)>=(Y))
-#define H5F_addr_cmp(X,Y) (H5F_addr_eq(X,Y)?0: \
- (H5F_addr_lt(X, Y)?-1:1))
+#define H5F_addr_cmp(X,Y) (H5F_addr_eq((X), (Y)) ? 0 : \
+ (H5F_addr_lt((X), (Y)) ? -1 : 1))
#define H5F_addr_pow2(N) ((haddr_t)1<<(N))
-#define H5F_addr_overlap(O1,L1,O2,L2) ((O1<O2 && (O1+L1)>O2) || \
- (O1>=O2 && O1<(O2+L2)))
+#define H5F_addr_overlap(O1,L1,O2,L2) (((O1) < (O2) && ((O1) + (L1)) > (O2)) || \
+ ((O1) >= (O2) && (O1) < ((O2) + (L2))))
/* If the module using this macro is allowed access to the private variables, access them directly */
#ifdef H5F_PACKAGE
-/* The FCPL itself */
+#define H5F_INTENT(F) ((F)->intent)
#define H5F_FCPL(F) ((F)->shared->fcpl_id)
-/* size of size_t and off_t as they exist on disk */
#define H5F_SIZEOF_ADDR(F) ((F)->shared->sizeof_addr)
#define H5F_SIZEOF_SIZE(F) ((F)->shared->sizeof_size)
-/* Size of symbol table leafs */
-#define H5F_SYM_LEAF_K(F) ((F)->shared->sym_leaf_k)
-/* B-tree key value size */
-#define H5F_KVALUE(F,T) ((F)->shared->btree_k[(T)->id])
-/* Raw data cache values */
-#define H5F_RDCC_NELMTS(F) ((F)->shared->rdcc_nelmts)
+#define H5F_SYM_LEAF_K(F) ((F)->shared->sblock->sym_leaf_k)
+#define H5F_KVALUE(F,T) ((F)->shared->sblock->btree_k[(T)->id])
+#define H5F_RDCC_NSLOTS(F) ((F)->shared->rdcc_nslots)
#define H5F_RDCC_NBYTES(F) ((F)->shared->rdcc_nbytes)
#define H5F_RDCC_W0(F) ((F)->shared->rdcc_w0)
-/* Check for file driver feature enabled */
-#define H5F_HAS_FEATURE(F,FL) ((F)->shared->lf->feature_flags & (FL))
-/* B-tree node raw page */
+#define H5F_BASE_ADDR(F) ((F)->shared->sblock->base_addr)
#define H5F_GRP_BTREE_SHARED(F) ((F)->shared->grp_btree_shared)
-/* Base address of file */
-#define H5F_BASE_ADDR(F) ((F)->shared->base_addr)
-/* Sieve buffer size for datasets */
#define H5F_SIEVE_BUF_SIZE(F) ((F)->shared->sieve_buf_size)
#define H5F_GC_REF(F) ((F)->shared->gc_ref)
#define H5F_USE_LATEST_FORMAT(F) ((F)->shared->latest_format)
-#define H5F_INTENT(F) ((F)->intent)
+#define H5F_OPEN_NAME(F) ((F)->open_name)
+#define H5F_ACTUAL_NAME(F) ((F)->actual_name)
#define H5F_EXTPATH(F) ((F)->extpath)
#define H5F_GET_FC_DEGREE(F) ((F)->shared->fc_degree)
#define H5F_STORE_MSG_CRT_IDX(F) ((F)->shared->store_msg_crt_idx)
+#define H5F_HAS_FEATURE(F,FL) ((F)->shared->lf->feature_flags & (FL))
+#define H5F_DRIVER_ID(F) ((F)->shared->lf->driver_id)
#define H5F_GET_FILENO(F,FILENUM) ((FILENUM) = (F)->shared->lf->fileno)
+#define H5F_USE_TMP_SPACE(F) ((F)->shared->use_tmp_space)
+#define H5F_IS_TMP_ADDR(F, ADDR) (H5F_addr_le((F)->shared->tmp_addr, (ADDR)))
#else /* H5F_PACKAGE */
+#define H5F_INTENT(F) (H5F_get_intent(F))
#define H5F_FCPL(F) (H5F_get_fcpl(F))
#define H5F_SIZEOF_ADDR(F) (H5F_sizeof_addr(F))
#define H5F_SIZEOF_SIZE(F) (H5F_sizeof_size(F))
#define H5F_SYM_LEAF_K(F) (H5F_sym_leaf_k(F))
#define H5F_KVALUE(F,T) (H5F_Kvalue(F,T))
-#define H5F_RDCC_NELMTS(F) (H5F_rdcc_nelmts(F))
+#define H5F_RDCC_NSLOTS(F) (H5F_rdcc_nslots(F))
#define H5F_RDCC_NBYTES(F) (H5F_rdcc_nbytes(F))
#define H5F_RDCC_W0(F) (H5F_rdcc_w0(F))
-#define H5F_HAS_FEATURE(F,FL) (H5F_has_feature(F,FL))
-#define H5F_GRP_BTREE_SHARED(F) (H5F_grp_btree_shared(F))
#define H5F_BASE_ADDR(F) (H5F_get_base_addr(F))
+#define H5F_GRP_BTREE_SHARED(F) (H5F_grp_btree_shared(F))
#define H5F_SIEVE_BUF_SIZE(F) (H5F_sieve_buf_size(F))
#define H5F_GC_REF(F) (H5F_gc_ref(F))
#define H5F_USE_LATEST_FORMAT(F) (H5F_use_latest_format(F))
-#define H5F_INTENT(F) (H5F_get_intent(F))
+#define H5F_OPEN_NAME(F) (H5F_get_open_name(F))
+#define H5F_ACTUAL_NAME(F) (H5F_get_actual_name(F))
#define H5F_EXTPATH(F) (H5F_get_extpath(F))
#define H5F_GET_FC_DEGREE(F) (H5F_get_fc_degree(F))
-#define H5F_STORE_MSG_CRT_IDX(F) (H5F_store_msg_crt_idx(F))
-#define H5F_GET_FILENO(F,FILENUM) (H5F_get_filenum((F), &(FILENUM)))
+#define H5F_STORE_MSG_CRT_IDX(F) (H5F_store_msg_crt_idx(F))
+#define H5F_HAS_FEATURE(F,FL) (H5F_has_feature(F,FL))
+#define H5F_DRIVER_ID(F) (H5F_get_driver_id(F))
+#define H5F_GET_FILENO(F,FILENUM) (H5F_get_fileno((F), &(FILENUM)))
+#define H5F_USE_TMP_SPACE(F) (H5F_use_tmp_space(F))
+#define H5F_IS_TMP_ADDR(F, ADDR) (H5F_is_tmp_addr((F), (ADDR)))
#endif /* H5F_PACKAGE */
@@ -361,12 +356,14 @@ typedef struct H5F_t H5F_t;
#define H5F_CRT_SHMSG_INDEX_MINSIZE_NAME "shmsg_message_minsize" /* Minimum size of messages in each index */
#define H5F_CRT_SHMSG_LIST_MAX_NAME "shmsg_list_max" /* Shared message list maximum size */
#define H5F_CRT_SHMSG_BTREE_MIN_NAME "shmsg_btree_min" /* Shared message B-tree minimum size */
+#define H5F_CRT_FILE_SPACE_STRATEGY_NAME "file_space_strategy" /* File space handling strategy */
+#define H5F_CRT_FREE_SPACE_THRESHOLD_NAME "free_space_threshold" /* Free space section threshold */
/* ========= File Access properties ============ */
#define H5F_ACS_META_CACHE_INIT_CONFIG_NAME "mdc_initCacheCfg" /* Initial metadata cache resize configuration */
-#define H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME "rdcc_nelmts" /* Size of raw data chunk cache(elements) */
+#define H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME "rdcc_nslots" /* Size of raw data chunk cache(slots) */
#define H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME "rdcc_nbytes" /* Size of raw data chunk cache(bytes) */
#define H5F_ACS_PREEMPT_READ_CHUNKS_NAME "rdcc_w0" /* Preemption read chunks first */
#define H5F_ACS_ALIGN_THRHD_NAME "threshold" /* Threshold for alignment */
@@ -383,6 +380,7 @@ typedef struct H5F_t H5F_t;
#define H5F_ACS_FAMILY_TO_SEC2_NAME "family_to_sec2" /* Whether to convert family to sec2 driver. (private property only used by h5repart) */
#define H5F_ACS_MULTI_TYPE_NAME "multi_type" /* Data type in multi file driver */
#define H5F_ACS_LATEST_FORMAT_NAME "latest_format" /* 'Use latest format version' flag */
+#define H5F_ACS_WANT_POSIX_FD_NAME "want_posix_fd" /* Internal: query the file descriptor from the core VFD, instead of the memory address */
/* ======================== File Mount properties ====================*/
#define H5F_MNT_SYM_LOCAL_NAME "local" /* Whether absolute symlinks local to file. */
@@ -405,13 +403,69 @@ typedef struct H5F_t H5F_t;
/* B-tree internal 'K' values */
#define HDF5_BTREE_SNODE_IK_DEF 16
-#define HDF5_BTREE_ISTORE_IK_DEF 32 /* Note! this value is assumed
+#define HDF5_BTREE_CHUNK_IK_DEF 32 /* Note! this value is assumed
to be 32 for version 0
of the superblock and
if it is changed, the code
must compensate. -QAK
*/
+/* Default file space handling strategy */
+#define H5F_FILE_SPACE_STRATEGY_DEF H5F_FILE_SPACE_ALL
+/* Default free space section threshold used by free-space managers */
+#define H5F_FREE_SPACE_THRESHOLD_DEF 1
+
+/* Macros to define signatures of all objects in the file */
+
+/* Size of signature information (on disk) */
+/* (all on-disk signatures should be this length) */
+#define H5_SIZEOF_MAGIC 4
+
+/* v1 B-tree node signature */
+#define H5B_MAGIC "TREE"
+
+/* v2 B-tree signatures */
+#define H5B2_HDR_MAGIC "BTHD" /* Header */
+#define H5B2_INT_MAGIC "BTIN" /* Internal node */
+#define H5B2_LEAF_MAGIC "BTLF" /* Leaf node */
+
+/* Extensible array signatures */
+#define H5EA_HDR_MAGIC "EAHD" /* Header */
+#define H5EA_IBLOCK_MAGIC "EAIB" /* Index block */
+#define H5EA_SBLOCK_MAGIC "EASB" /* Super block */
+#define H5EA_DBLOCK_MAGIC "EADB" /* Data block */
+
+/* Fixed array signatures */
+#define H5FA_HDR_MAGIC "FAHD" /* Header */
+#define H5FA_DBLOCK_MAGIC "FADB" /* Data block */
+
+/* Free space signatures */
+#define H5FS_HDR_MAGIC "FSHD" /* Header */
+#define H5FS_SINFO_MAGIC "FSSE" /* Serialized sections */
+
+/* Symbol table node signature */
+#define H5G_NODE_MAGIC "SNOD"
+
+/* Fractal heap signatures */
+#define H5HF_HDR_MAGIC "FRHP" /* Header */
+#define H5HF_IBLOCK_MAGIC "FHIB" /* Indirect block */
+#define H5HF_DBLOCK_MAGIC "FHDB" /* Direct block */
+
+/* Global heap signature */
+#define H5HG_MAGIC "GCOL"
+
+/* Local heap signature */
+#define H5HL_MAGIC "HEAP"
+
+/* Object header signatures */
+#define H5O_HDR_MAGIC "OHDR" /* Header */
+#define H5O_CHK_MAGIC "OCHK" /* Continuation chunk */
+
+/* Shared Message signatures */
+#define H5SM_TABLE_MAGIC "SMTB" /* Shared Message Table */
+#define H5SM_LIST_MAGIC "SMLI" /* Shared Message List */
+
+
/* Forward declarations for prototype arguments */
struct H5B_class_t;
struct H5RC_t;
@@ -420,46 +474,49 @@ struct H5RC_t;
H5_DLL H5F_t *H5F_open(const char *name, unsigned flags, hid_t fcpl_id,
hid_t fapl_id, hid_t dxpl_id);
H5_DLL herr_t H5F_try_close(H5F_t *f);
+H5_DLL unsigned H5F_incr_nopen_objs(H5F_t *f);
+H5_DLL unsigned H5F_decr_nopen_objs(H5F_t *f);
/* Functions than retrieve values from the file struct */
-H5_DLL hid_t H5F_get_driver_id(const H5F_t *f);
-H5_DLL hid_t H5F_get_access_plist(H5F_t *f);
H5_DLL unsigned H5F_get_intent(const H5F_t *f);
+H5_DLL hid_t H5F_get_access_plist(H5F_t *f, hbool_t app_ref);
H5_DLL char *H5F_get_extpath(const H5F_t *f);
-H5_DLL herr_t H5F_get_fileno(const H5F_t *f, unsigned long *filenum);
-H5_DLL hid_t H5F_get_id(H5F_t *file);
-H5_DLL unsigned H5F_get_obj_count(const H5F_t *f, unsigned types);
-H5_DLL unsigned H5F_get_obj_ids(const H5F_t *f, unsigned types, int max_objs, hid_t *obj_id_list);
-H5_DLL haddr_t H5F_get_base_addr(const H5F_t *f);
-H5_DLL haddr_t H5F_get_eoa(const H5F_t *f);
-#ifdef H5_HAVE_PARALLEL
-H5_DLL int H5F_mpi_get_rank(const H5F_t *f);
-H5_DLL MPI_Comm H5F_mpi_get_comm(const H5F_t *f);
-H5_DLL int H5F_mpi_get_size(const H5F_t *f);
-#endif /* H5_HAVE_PARALLEL */
-H5_DLL unsigned H5F_incr_nopen_objs(H5F_t *f);
-H5_DLL unsigned H5F_decr_nopen_objs(H5F_t *f);
+H5_DLL char *H5F_get_open_name(const H5F_t *f);
+H5_DLL char *H5F_get_actual_name(const H5F_t *f);
+H5_DLL hid_t H5F_get_id(H5F_t *file, hbool_t app_ref);
+H5_DLL size_t H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref);
+H5_DLL size_t H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list, hbool_t app_ref);
-/* Functions than check file mounting information */
-H5_DLL hbool_t H5F_is_mount(const H5F_t *file);
-H5_DLL hbool_t H5F_has_mount(const H5F_t *file);
-
-/* Functions than retrieve values set from the FCPL */
+/* Functions than retrieve values set/cached from the superblock/FCPL */
H5_DLL hid_t H5F_get_fcpl(const H5F_t *f);
-H5_DLL size_t H5F_sizeof_addr(const H5F_t *f);
-H5_DLL size_t H5F_sizeof_size(const H5F_t *f);
+H5_DLL uint8_t H5F_sizeof_addr(const H5F_t *f);
+H5_DLL uint8_t H5F_sizeof_size(const H5F_t *f);
H5_DLL unsigned H5F_sym_leaf_k(const H5F_t *f);
H5_DLL unsigned H5F_Kvalue(const H5F_t *f, const struct H5B_class_t *type);
-H5_DLL hbool_t H5F_has_feature(const H5F_t *f, unsigned feature);
H5_DLL size_t H5F_rdcc_nbytes(const H5F_t *f);
-H5_DLL size_t H5F_rdcc_nelmts(const H5F_t *f);
+H5_DLL size_t H5F_rdcc_nslots(const H5F_t *f);
H5_DLL double H5F_rdcc_w0(const H5F_t *f);
+H5_DLL haddr_t H5F_get_base_addr(const H5F_t *f);
H5_DLL struct H5RC_t *H5F_grp_btree_shared(const H5F_t *f);
H5_DLL size_t H5F_sieve_buf_size(const H5F_t *f);
H5_DLL unsigned H5F_gc_ref(const H5F_t *f);
H5_DLL hbool_t H5F_use_latest_format(const H5F_t *f);
H5_DLL H5F_close_degree_t H5F_get_fc_degree(const H5F_t *f);
H5_DLL hbool_t H5F_store_msg_crt_idx(const H5F_t *f);
+H5_DLL hbool_t H5F_is_tmp_addr(const H5F_t *f, haddr_t addr);
+H5_DLL hbool_t H5F_use_tmp_space(const H5F_t *f);
+
+/* Functions that retrieve values from VFD layer */
+H5_DLL hbool_t H5F_has_feature(const H5F_t *f, unsigned feature);
+H5_DLL hid_t H5F_get_driver_id(const H5F_t *f);
+H5_DLL herr_t H5F_get_fileno(const H5F_t *f, unsigned long *filenum);
+H5_DLL haddr_t H5F_get_eoa(const H5F_t *f, H5FD_mem_t type);
+H5_DLL herr_t H5F_get_vfd_handle(const H5F_t *file, hid_t fapl,
+ void **file_handle);
+
+/* Functions than check file mounting information */
+H5_DLL hbool_t H5F_is_mount(const H5F_t *file);
+H5_DLL hbool_t H5F_has_mount(const H5F_t *file);
/* Functions that operate on blocks of bytes wrt super block */
H5_DLL herr_t H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr,
@@ -468,10 +525,10 @@ H5_DLL herr_t H5F_block_write(const H5F_t *f, H5FD_mem_t type, haddr_t addr,
size_t size, hid_t dxpl_id, const void *buf);
/* Address-related functions */
-H5_DLL void H5F_addr_encode(const H5F_t *f, uint8_t **pp/*in,out*/,
- haddr_t addr);
-H5_DLL void H5F_addr_decode(const H5F_t *f, const uint8_t **pp/*in,out*/,
- haddr_t *addr_p/*out*/);
+H5_DLL void H5F_addr_encode(const H5F_t *f, uint8_t **pp, haddr_t addr);
+H5_DLL void H5F_addr_encode_len(size_t addr_len, uint8_t **pp, haddr_t addr);
+H5_DLL void H5F_addr_decode(const H5F_t *f, const uint8_t **pp, haddr_t *addr_p);
+H5_DLL void H5F_addr_decode_len(size_t addr_len, const uint8_t **pp, haddr_t *addr_p);
/* File access property list callbacks */
H5_DLL herr_t H5P_facc_close(hid_t dxpl_id, void *close_data);
@@ -480,9 +537,19 @@ H5_DLL herr_t H5P_facc_close(hid_t dxpl_id, void *close_data);
H5_DLL herr_t H5F_sfile_assert_num(unsigned n);
/* Routines for creating & destroying "fake" file structures */
-H5_DLL H5F_t *H5F_fake_alloc(size_t sizeof_size);
+H5_DLL H5F_t *H5F_fake_alloc(uint8_t sizeof_size);
H5_DLL herr_t H5F_fake_free(H5F_t *f);
+/* Superblock related routines */
+H5_DLL herr_t H5F_super_dirty(H5F_t *f);
+
+/* Parallel I/O (i.e. MPI) related routines */
+#ifdef H5_HAVE_PARALLEL
+H5_DLL int H5F_mpi_get_rank(const H5F_t *f);
+H5_DLL MPI_Comm H5F_mpi_get_comm(const H5F_t *f);
+H5_DLL int H5F_mpi_get_size(const H5F_t *f);
+#endif /* H5_HAVE_PARALLEL */
+
/* Debugging functions */
H5_DLL herr_t H5F_debug(H5F_t *f, FILE * stream, int indent, int fwidth);
diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h
index c5c07f8..df66985 100644
--- a/src/H5Fpublic.h
+++ b/src/H5Fpublic.h
@@ -50,6 +50,10 @@
#define H5F_ACC_DEBUG (H5CHECK 0x0008u) /*print debug info */
#define H5F_ACC_CREAT (H5CHECK 0x0010u) /*create non-existing files */
+/* Value passed to H5Pset_elink_acc_flags to cause flags to be taken from the
+ * parent file. */
+#define H5F_ACC_DEFAULT (H5CHECK 0xffffu) /*ignore setting on lapl */
+
/* Flags for H5Fget_obj_count() & H5Fget_obj_ids() calls */
#define H5F_OBJ_FILE (0x0001u) /* File objects */
#define H5F_OBJ_DATASET (0x0002u) /* Dataset objects */
@@ -75,8 +79,7 @@
/* The difference between a single file and a set of mounted files */
typedef enum H5F_scope_t {
H5F_SCOPE_LOCAL = 0, /*specified file handle only */
- H5F_SCOPE_GLOBAL = 1, /*entire virtual file */
- H5F_SCOPE_DOWN = 2 /*for internal use only */
+ H5F_SCOPE_GLOBAL = 1 /*entire virtual file */
} H5F_scope_t;
/* Unlimited file size for H5Pset_external() */
@@ -98,14 +101,47 @@ typedef enum H5F_close_degree_t {
} H5F_close_degree_t;
/* Current "global" information about file */
-/* (just size info currently) */
-typedef struct H5F_info_t {
- hsize_t super_ext_size; /* Superblock extension size */
+typedef struct H5F_info2_t {
+ struct {
+ unsigned version; /* Superblock version # */
+ hsize_t super_size; /* Superblock size */
+ hsize_t super_ext_size; /* Superblock extension size */
+ } super;
+ struct {
+ unsigned version; /* Version # of file free space management */
+ hsize_t meta_size; /* Free space manager metadata size */
+ hsize_t tot_space; /* Amount of free space in the file */
+ } free;
struct {
+ unsigned version; /* Version # of shared object header info */
hsize_t hdr_size; /* Shared object header message header size */
H5_ih_info_t msgs_info; /* Shared object header message index & heap size */
} sohm;
-} H5F_info_t;
+} H5F_info2_t;
+
+/*
+ * Types of allocation requests. The values larger than H5FD_MEM_DEFAULT
+ * should not change other than adding new types to the end. These numbers
+ * might appear in files.
+ */
+typedef enum H5F_mem_t {
+ H5FD_MEM_NOLIST = -1, /*must be negative*/
+ H5FD_MEM_DEFAULT = 0, /*must be zero*/
+ H5FD_MEM_SUPER = 1,
+ H5FD_MEM_BTREE = 2,
+ H5FD_MEM_DRAW = 3,
+ H5FD_MEM_GHEAP = 4,
+ H5FD_MEM_LHEAP = 5,
+ H5FD_MEM_OHDR = 6,
+
+ H5FD_MEM_NTYPES /*must be last*/
+} H5F_mem_t;
+
+/* Free space section information */
+typedef struct H5F_sect_info_t {
+ haddr_t addr; /* Address of free space section */
+ hsize_t size; /* Size of free space section */
+} H5F_sect_info_t;
/* Library's file format versions */
typedef enum H5F_libver_t {
@@ -113,6 +149,18 @@ typedef enum H5F_libver_t {
H5F_LIBVER_LATEST /* Use the latest possible format available for storing objects*/
} H5F_libver_t;
+/* File space handling strategy */
+typedef enum H5F_file_space_type_t {
+ H5F_FILE_SPACE_DEFAULT = 0, /* Default (or current) free space strategy setting */
+ H5F_FILE_SPACE_ALL_PERSIST = 1, /* Persistent free space managers, aggregators, virtual file driver */
+ H5F_FILE_SPACE_ALL = 2, /* Non-persistent free space managers, aggregators, virtual file driver */
+ /* This is the library default */
+ H5F_FILE_SPACE_AGGR_VFD = 3, /* Aggregators, Virtual file driver */
+ H5F_FILE_SPACE_VFD = 4, /* Virtual file driver */
+ H5F_FILE_SPACE_NTYPES /* must be last */
+} H5F_file_space_type_t;
+
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -129,8 +177,8 @@ H5_DLL herr_t H5Fclose(hid_t file_id);
H5_DLL hid_t H5Fget_create_plist(hid_t file_id);
H5_DLL hid_t H5Fget_access_plist(hid_t file_id);
H5_DLL herr_t H5Fget_intent(hid_t file_id, unsigned * intent);
-H5_DLL int H5Fget_obj_count(hid_t file_id, unsigned types);
-H5_DLL int H5Fget_obj_ids(hid_t file_id, unsigned types, int max_objs, hid_t *obj_id_list);
+H5_DLL ssize_t H5Fget_obj_count(hid_t file_id, unsigned types);
+H5_DLL ssize_t H5Fget_obj_ids(hid_t file_id, unsigned types, size_t max_objs, hid_t *obj_id_list);
H5_DLL herr_t H5Fget_vfd_handle(hid_t file_id, hid_t fapl, void **file_handle);
H5_DLL herr_t H5Fmount(hid_t loc, const char *name, hid_t child, hid_t plist);
H5_DLL herr_t H5Funmount(hid_t loc, const char *name);
@@ -148,7 +196,35 @@ H5_DLL herr_t H5Fget_mdc_size(hid_t file_id,
int * cur_num_entries_ptr);
H5_DLL herr_t H5Freset_mdc_hit_rate_stats(hid_t file_id);
H5_DLL ssize_t H5Fget_name(hid_t obj_id, char *name, size_t size);
-H5_DLL herr_t H5Fget_info(hid_t obj_id, H5F_info_t *bh_info);
+H5_DLL herr_t H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo);
+H5_DLL ssize_t H5Fget_free_sections(hid_t file_id, H5F_mem_t type,
+ size_t nsects, H5F_sect_info_t *sect_info/*out*/);
+
+/* Symbols defined for compatibility with previous versions of the HDF5 API.
+ *
+ * Use of these symbols is deprecated.
+ */
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+
+/* Macros */
+
+
+/* Typedefs */
+
+/* Current "global" information about file */
+typedef struct H5F_info1_t {
+ hsize_t super_ext_size; /* Superblock extension size */
+ struct {
+ hsize_t hdr_size; /* Shared object header message header size */
+ H5_ih_info_t msgs_info; /* Shared object header message index & heap size */
+ } sohm;
+} H5F_info1_t;
+
+
+/* Function prototypes */
+H5_DLL herr_t H5Fget_info1(hid_t obj_id, H5F_info1_t *finfo);
+
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
#ifdef __cplusplus
}
diff --git a/src/H5Fquery.c b/src/H5Fquery.c
new file mode 100644
index 0000000..c5ecf6b
--- /dev/null
+++ b/src/H5Fquery.c
@@ -0,0 +1,838 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Fquery.c
+ * Jan 10 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: File structure query routines.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5FDprivate.h" /* File drivers */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_intent
+ *
+ * Purpose: Quick and dirty routine to retrieve the file's 'intent' flags
+ * (Mainly added to stop non-file routines from poking about in the
+ * H5F_t data structure)
+ *
+ * Return: 'intent' on success/abort on failure (shouldn't fail)
+ *
+ * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
+ * September 29, 2000
+ *
+ *-------------------------------------------------------------------------
+ */
+unsigned
+H5F_get_intent(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_intent)
+
+ HDassert(f);
+
+ FUNC_LEAVE_NOAPI(f->intent)
+} /* end H5F_get_intent() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_open_name
+ *
+ * Purpose: Retrieve the name used to open a file.
+ *
+ * Return: Success: The name of the file.
+ * Failure: ? (should not happen)
+ *
+ * Programmer: Neil Fortner
+ * December 15 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+char *
+H5F_get_open_name(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_open_name)
+
+ HDassert(f);
+ HDassert(f->open_name);
+
+ FUNC_LEAVE_NOAPI(f->open_name)
+} /* end H5F_get_open_name() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_actual_name
+ *
+ * Purpose: Retrieve the actual name of a file, after resolving symlinks, etc.
+ *
+ * Return: Success: The name of the file.
+ * Failure: ? (should not happen)
+ *
+ * Programmer: Quincey Koziol
+ * November 25 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+char *
+H5F_get_actual_name(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_actual_name)
+
+ HDassert(f);
+ HDassert(f->actual_name);
+
+ FUNC_LEAVE_NOAPI(f->actual_name)
+} /* end H5F_get_actual_name() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_extpath
+ *
+ * Purpose: Retrieve the file's 'extpath' flags
+ * This is used by H5L_extern_traverse() to retrieve the main file's location
+ * when searching the target file.
+ *
+ * Return: 'extpath' on success/abort on failure (shouldn't fail)
+ *
+ * Programmer: Vailin Choi, April 2, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+char *
+H5F_get_extpath(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_extpath)
+
+ HDassert(f);
+ HDassert(f->extpath);
+
+ FUNC_LEAVE_NOAPI(f->extpath)
+} /* end H5F_get_extpath() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_fcpl
+ *
+ * Purpose: Retrieve the value of a file's FCPL.
+ *
+ * Return: Success: The FCPL for the file.
+ *
+ * Failure: ? (should not happen)
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * May 25 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5F_get_fcpl(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_fcpl)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->fcpl_id)
+} /* end H5F_get_fcpl() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_sizeof_addr
+ *
+ * Purpose: Quick and dirty routine to retrieve the size of the file's size_t
+ * (Mainly added to stop non-file routines from poking about in the
+ * H5F_t data structure)
+ *
+ * Return: 'sizeof_addr' on success/abort on failure (shouldn't fail)
+ *
+ * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
+ * September 29, 2000
+ *
+ *-------------------------------------------------------------------------
+ */
+uint8_t
+H5F_sizeof_addr(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_sizeof_addr)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->sizeof_addr)
+} /* end H5F_sizeof_addr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_sizeof_size
+ *
+ * Purpose: Quick and dirty routine to retrieve the size of the file's off_t
+ * (Mainly added to stop non-file routines from poking about in the
+ * H5F_t data structure)
+ *
+ * Return: 'sizeof_size' on success/abort on failure (shouldn't fail)
+ *
+ * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
+ * September 29, 2000
+ *
+ *-------------------------------------------------------------------------
+ */
+uint8_t
+H5F_sizeof_size(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_sizeof_size)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->sizeof_size)
+} /* H5F_sizeof_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_sym_leaf_k
+ *
+ * Purpose: Replaced a macro to retrieve the symbol table leaf size,
+ * now that the generic properties are being used to store
+ * the values.
+ *
+ * Return: Success: Non-negative, and the symbol table leaf size is
+ * returned.
+ *
+ * Failure: Negative (should not happen)
+ *
+ * Programmer: Raymond Lu
+ * slu@ncsa.uiuc.edu
+ * Oct 14 2001
+ *
+ *-------------------------------------------------------------------------
+ */
+unsigned
+H5F_sym_leaf_k(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_sym_leaf_k)
+
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->sblock);
+
+ FUNC_LEAVE_NOAPI(f->shared->sblock->sym_leaf_k)
+} /* end H5F_sym_leaf_k() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_Kvalue
+ *
+ * Purpose: Replaced a macro to retrieve a B-tree key value for a certain
+ * type, now that the generic properties are being used to store
+ * the B-tree values.
+ *
+ * Return: Success: Non-negative, and the B-tree key value is
+ * returned.
+ *
+ * Failure: Negative (should not happen)
+ *
+ * Programmer: Raymond Lu
+ * slu@ncsa.uiuc.edu
+ * Oct 14 2001
+ *
+ *-------------------------------------------------------------------------
+ */
+unsigned
+H5F_Kvalue(const H5F_t *f, const H5B_class_t *type)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_Kvalue)
+
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->sblock);
+ HDassert(type);
+
+ FUNC_LEAVE_NOAPI(f->shared->sblock->btree_k[type->id])
+} /* end H5F_Kvalue() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_rdcc_nslots
+ *
+ * Purpose: Replaced a macro to retrieve the raw data cache number of slots,
+ * now that the generic properties are being used to store
+ * the values.
+ *
+ * Return: Success: Non-negative, and the raw data cache number of
+ * of slots is returned.
+ *
+ * Failure: Negative (should not happen)
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jun 1 2004
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5F_rdcc_nslots(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_rdcc_nslots)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->rdcc_nslots)
+} /* end H5F_rdcc_nelmts() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_rdcc_nbytes
+ *
+ * Purpose: Replaced a macro to retrieve the raw data cache number of bytes,
+ * now that the generic properties are being used to store
+ * the values.
+ *
+ * Return: Success: Non-negative, and the raw data cache number of
+ * of bytes is returned.
+ *
+ * Failure: Negative (should not happen)
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jun 1 2004
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5F_rdcc_nbytes(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_rdcc_nbytes)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->rdcc_nbytes)
+} /* end H5F_rdcc_nbytes() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_rdcc_w0
+ *
+ * Purpose: Replaced a macro to retrieve the raw data cache 'w0' value
+ * now that the generic properties are being used to store
+ * the values.
+ *
+ * Return: Success: Non-negative, and the raw data cache 'w0' value
+ * is returned.
+ *
+ * Failure: Negative (should not happen)
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jun 2 2004
+ *
+ *-------------------------------------------------------------------------
+ */
+double
+H5F_rdcc_w0(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_rdcc_w0)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->rdcc_w0)
+} /* end H5F_rdcc_w0() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_base_addr
+ *
+ * Purpose: Quick and dirty routine to retrieve the file's 'base_addr' value
+ * (Mainly added to stop non-file routines from poking about in the
+ * H5F_t data structure)
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu <slu@ncsa.uiuc.edu>
+ * December 20, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+haddr_t
+H5F_get_base_addr(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_base_addr)
+
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->sblock);
+
+ FUNC_LEAVE_NOAPI(f->shared->sblock->base_addr)
+} /* end H5F_get_base_addr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_grp_btree_shared
+ *
+ * Purpose: Replaced a macro to retrieve the shared B-tree node info
+ * now that the generic properties are being used to store
+ * the values.
+ *
+ * Return: Success: Non-void, and the shared B-tree node info
+ * is returned.
+ *
+ * Failure: void (should not happen)
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jul 5 2004
+ *
+ *-------------------------------------------------------------------------
+ */
+H5RC_t *
+H5F_grp_btree_shared(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_grp_btree_shared)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->grp_btree_shared)
+} /* end H5F_grp_btree_shared() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_sieve_buf_size
+ *
+ * Purpose: Replaced a macro to retrieve the dataset sieve buffer size
+ * now that the generic properties are being used to store
+ * the values.
+ *
+ * Return: Success: Non-void, and the dataset sieve buffer size
+ * is returned.
+ *
+ * Failure: void (should not happen)
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jul 8 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5F_sieve_buf_size(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_sieve_buf_size)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->sieve_buf_size)
+} /* end H5F_sieve_buf_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_gc_ref
+ *
+ * Purpose: Replaced a macro to retrieve the "garbage collect
+ * references flag" now that the generic properties are being used
+ * to store the values.
+ *
+ * Return: Success: The "garbage collect references flag"
+ * is returned.
+ *
+ * Failure: (should not happen)
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jul 8 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+unsigned
+H5F_gc_ref(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_gc_ref)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->gc_ref)
+} /* end H5F_gc_ref() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_use_latest_format
+ *
+ * Purpose: Retrieve the 'use the latest version of the format' flag for
+ * the file.
+ *
+ * Return: Success: Non-negative, the 'use the latest format' flag
+ *
+ * Failure: (can't happen)
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 2 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5F_use_latest_format(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_use_latest_format)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->latest_format)
+} /* end H5F_use_latest_format() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_fc_degree
+ *
+ * Purpose: Retrieve the 'file close degree' for the file.
+ *
+ * Return: Success: Non-negative, the 'file close degree'
+ *
+ * Failure: (can't happen)
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Mar 5 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+H5F_close_degree_t
+H5F_get_fc_degree(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_fc_degree)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->fc_degree)
+} /* end H5F_get_fc_degree() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_store_msg_crt_idx
+ *
+ * Purpose: Retrieve the 'store message creation index' flag for the file.
+ *
+ * Return: Success: Non-negative, the 'store message creation index' flag
+ *
+ * Failure: (can't happen)
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Mar 6 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5F_store_msg_crt_idx(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_store_msg_crt_idx)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->store_msg_crt_idx)
+} /* end H5F_store_msg_crt_idx() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_has_feature
+ *
+ * Purpose: Check if a file has a particular feature enabled
+ *
+ * Return: Success: Non-negative - TRUE or FALSE
+ * Failure: Negative (should not happen)
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * May 31 2004
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5F_has_feature(const H5F_t *f, unsigned feature)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_has_feature)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI((hbool_t)(f->shared->lf->feature_flags&feature))
+} /* end H5F_has_feature() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_driver_id
+ *
+ * Purpose: Quick and dirty routine to retrieve the file's 'driver_id' value
+ * (Mainly added to stop non-file routines from poking about in the
+ * H5F_t data structure)
+ *
+ * Return: 'driver_id' on success/abort on failure (shouldn't fail)
+ *
+ * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
+ * October 10, 2000
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5F_get_driver_id(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_driver_id)
+
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->lf);
+
+ FUNC_LEAVE_NOAPI(f->shared->lf->driver_id)
+} /* end H5F_get_driver_id() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_fileno
+ *
+ * Purpose: Quick and dirty routine to retrieve the file's 'fileno' value
+ * (Mainly added to stop non-file routines from poking about in the
+ * H5F_t data structure)
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
+ * March 27, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_get_fileno(const H5F_t *f, unsigned long *filenum)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5F_get_fileno, FAIL)
+
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->lf);
+ HDassert(filenum);
+
+ /* Retrieve the file's serial number */
+ if(H5FD_get_fileno(f->shared->lf, filenum) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "can't retrieve fileno")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_get_fileno() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_eoa
+ *
+ * Purpose: Quick and dirty routine to retrieve the file's 'eoa' value
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
+ * June 1, 2004
+ *
+ *-------------------------------------------------------------------------
+ */
+haddr_t
+H5F_get_eoa(const H5F_t *f, H5FD_mem_t type)
+{
+ haddr_t ret_value;
+
+ FUNC_ENTER_NOAPI(H5F_get_eoa, HADDR_UNDEF)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ /* Dispatch to driver */
+ if(HADDR_UNDEF == (ret_value = H5FD_get_eoa(f->shared->lf, type)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "driver get_eoa request failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_get_eoa() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_vfd_handle
+ *
+ * Purpose: Returns a pointer to the file handle of the low-level file
+ * driver. This is the private function for H5Fget_vfd_handle.
+ *
+ * Return: Success: Non-negative.
+ * Failure: negative.
+ *
+ * Programmer: Raymond Lu
+ * Sep. 16, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void **file_handle)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5F_get_vfd_handle, FAIL)
+
+ /* Sanity check */
+ HDassert(file);
+ HDassert(file_handle);
+
+ /* Get the VFD handle */
+ if(H5FD_get_vfd_handle(file->shared->lf, fapl, file_handle) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file handle for file driver")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_get_vfd_handle() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_is_tmp_addr
+ *
+ * Purpose: Quick and dirty routine to determine if an address is in
+ * the 'temporary' file space.
+ * (Mainly added to stop non-file routines from poking about in the
+ * H5F_t data structure)
+ *
+ * Return: TRUE/FALSE on success/abort on failure (shouldn't fail)
+ *
+ * Programmer: Quincey Koziol <koziol@hdfgroup.org>
+ * June 11, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5F_is_tmp_addr(const H5F_t *f, haddr_t addr)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_is_tmp_addr)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(H5F_addr_le(f->shared->tmp_addr, addr))
+} /* end H5F_is_tmp_addr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_use_tmp_space
+ *
+ * Purpose: Quick and dirty routine to determine if using temporary
+ * file space is allowed for this file.
+ * (Mainly added to stop non-file routines from poking about in the
+ * H5F_t data structure)
+ *
+ * Return: TRUE/FALSE on success/abort on failure (shouldn't fail)
+ *
+ * Programmer: Quincey Koziol <koziol@hdfgroup.org>
+ * July 1, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5F_use_tmp_space(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_use_tmp_space)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->use_tmp_space)
+} /* end H5F_use_tmp_space() */
+
diff --git a/src/H5Fsfile.c b/src/H5Fsfile.c
index 354b307..708fbf7 100644
--- a/src/H5Fsfile.c
+++ b/src/H5Fsfile.c
@@ -219,7 +219,7 @@ H5F_sfile_remove(H5F_file_t *shared)
/* Release the shared file node struct */
/* (the shared file info itself is freed elsewhere) */
- H5FL_FREE(H5F_sfile_node_t, curr);
+ (void)H5FL_FREE(H5F_sfile_node_t, curr);
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c
index 12a2d81..f96009c 100644
--- a/src/H5Fsuper.c
+++ b/src/H5Fsuper.c
@@ -26,12 +26,13 @@
/***********/
/* Headers */
/***********/
-#include "H5private.h" /* Generic Functions */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5Fpkg.h" /* File access */
-#include "H5FDprivate.h" /* File drivers */
-#include "H5Iprivate.h" /* IDs */
-#include "H5Pprivate.h" /* Property lists */
+#include "H5private.h" /* Generic Functions */
+#include "H5ACprivate.h" /* Metadata cache */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5FDprivate.h" /* File drivers */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Pprivate.h" /* Property lists */
#include "H5SMprivate.h" /* Shared Object Header Messages */
@@ -39,61 +40,6 @@
/* Local Macros */
/****************/
-/* Superblock sizes for various versions */
-#define H5F_SIZEOF_CHKSUM 4 /* Checksum size in the file */
-
-/* Fixed-size portion at the beginning of all superblocks */
-#define H5F_SUPERBLOCK_FIXED_SIZE ( H5F_SIGNATURE_LEN \
- + 1) /* superblock version */
-
-/* Macros for computing variable-size superblock size */
-#define H5F_SUPERBLOCK_VARLEN_SIZE_COMMON \
- (2 /* freespace, and root group versions */ \
- + 1 /* reserved */ \
- + 3 /* shared header vers, size of address, size of lengths */ \
- + 1 /* reserved */ \
- + 4 /* group leaf k, group internal k */ \
- + 4) /* consistency flags */
-#define H5F_SUPERBLOCK_VARLEN_SIZE_V0(f) \
- ( H5F_SUPERBLOCK_VARLEN_SIZE_COMMON /* Common variable-length info */ \
- + H5F_SIZEOF_ADDR(f) /* base address */ \
- + H5F_SIZEOF_ADDR(f) /* <unused> */ \
- + H5F_SIZEOF_ADDR(f) /* EOF address */ \
- + H5F_SIZEOF_ADDR(f) /* driver block address */ \
- + H5G_SIZEOF_ENTRY(f)) /* root group ptr */
-#define H5F_SUPERBLOCK_VARLEN_SIZE_V1(f) \
- ( H5F_SUPERBLOCK_VARLEN_SIZE_COMMON /* Common variable-length info */ \
- + 2 /* indexed B-tree internal k */ \
- + 2 /* reserved */ \
- + H5F_SIZEOF_ADDR(f) /* base address */ \
- + H5F_SIZEOF_ADDR(f) /* <unused> */ \
- + H5F_SIZEOF_ADDR(f) /* EOF address */ \
- + H5F_SIZEOF_ADDR(f) /* driver block address */ \
- + H5G_SIZEOF_ENTRY(f)) /* root group ptr */
-#define H5F_SUPERBLOCK_VARLEN_SIZE_V2(f) \
- ( 2 /* size of address, size of lengths */ \
- + 1 /* consistency flags */ \
- + H5F_SIZEOF_ADDR(f) /* base address */ \
- + H5F_SIZEOF_ADDR(f) /* superblock extension address */ \
- + H5F_SIZEOF_ADDR(f) /* EOF address */ \
- + H5F_SIZEOF_ADDR(f) /* root group object header address */ \
- + H5F_SIZEOF_CHKSUM) /* superblock checksum (keep this last) */
-#define H5F_SUPERBLOCK_VARLEN_SIZE(v, f) ( \
- (v == 0 ? H5F_SUPERBLOCK_VARLEN_SIZE_V0(f) : 0) \
- + (v == 1 ? H5F_SUPERBLOCK_VARLEN_SIZE_V1(f) : 0) \
- + (v == 2 ? H5F_SUPERBLOCK_VARLEN_SIZE_V2(f) : 0))
-
-/* Total size of superblock, depends on superblock version */
-#define H5F_SUPERBLOCK_SIZE(v, f) ( H5F_SUPERBLOCK_FIXED_SIZE \
- + H5F_SUPERBLOCK_VARLEN_SIZE(v, f))
-
-/* Driver info block macros */
-#define H5F_DRVINFOBLOCK_HDR_SIZE 16
-
-/* Maximum size of super-block buffers */
-#define H5F_MAX_SUPERBLOCK_SIZE 134
-#define H5F_MAX_DRVINFOBLOCK_SIZE 1024
-
/******************/
/* Local Typedefs */
@@ -108,6 +54,7 @@
/********************/
/* Local Prototypes */
/********************/
+static herr_t H5F_super_ext_create(H5F_t *f, hid_t dxpl_id, H5O_loc_t *ext_ptr);
/*********************/
@@ -119,6 +66,9 @@
/* Library Private Variables */
/*****************************/
+/* Declare a free list to manage the H5F_super_t struct */
+H5FL_DEFINE(H5F_super_t);
+
/*******************/
/* Local Variables */
@@ -187,9 +137,9 @@ H5F_locate_signature(H5FD_t *file, hid_t dxpl_id)
*/
for(n = 8; n < maxpow; n++) {
addr = (8 == n) ? 0 : (haddr_t)1 << n;
- if(H5FD_set_eoa(file, H5FD_MEM_SUPER, addr+H5F_SIGNATURE_LEN) < 0)
+ if(H5FD_set_eoa(file, H5FD_MEM_SUPER, addr + H5F_SIGNATURE_LEN) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, HADDR_UNDEF, "unable to set EOA value for file signature")
- if(H5FD_read(file, H5FD_MEM_SUPER, dxpl_id, addr, (size_t)H5F_SIGNATURE_LEN, buf) < 0)
+ if(H5FD_read(file, dxpl_id, H5FD_MEM_SUPER, addr, (size_t)H5F_SIGNATURE_LEN, buf) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, HADDR_UNDEF, "unable to read file signature")
if(!HDmemcmp(buf, H5F_SIGNATURE, (size_t)H5F_SIGNATURE_LEN))
break;
@@ -213,421 +163,181 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5F_super_read
+ * Function: H5F_super_ext_create
*
- * Purpose: Reads the superblock from the file or from the BUF. If
- * ADDR is a valid address, then it reads it from the file.
- * If not, then BUF must be non-NULL for it to read from the
- * BUF.
+ * Purpose: Create the superblock extension
*
- * Return: Success: SUCCEED
- * Failure: FAIL
+ * Return: Success: non-negative on success
+ * Failure: Negative
*
- * Programmer: Bill Wendling
- * wendling@ncsa.uiuc.edu
- * Sept 12, 2003
+ * Programmer: Vailin Choi; Feb 2009
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc)
+static herr_t
+H5F_super_ext_create(H5F_t *f, hid_t dxpl_id, H5O_loc_t *ext_ptr)
{
- uint8_t sbuf[H5F_MAX_SUPERBLOCK_SIZE]; /* Buffer for superblock */
- H5P_genplist_t *c_plist; /* File creation property list */
- H5F_file_t *shared; /* shared part of `file' */
- H5FD_t *lf; /* file driver part of `shared' */
- haddr_t stored_eoa; /*relative end-of-addr in file */
- haddr_t eof; /*end of file address */
- size_t sizeof_addr; /* Size of offsets in the file (in bytes) */
- size_t sizeof_size; /* Size of lengths in the file (in bytes) */
- const size_t fixed_size = H5F_SUPERBLOCK_FIXED_SIZE; /*fixed sizeof superblock */
- size_t variable_size; /*variable sizeof superblock */
- uint8_t *p; /* Temporary pointer into encoding buffer */
- unsigned super_vers; /* Superblock version */
- herr_t ret_value = SUCCEED;
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5F_super_read, FAIL)
+ FUNC_ENTER_NOAPI_NOINIT(H5F_super_ext_create)
- /* Short cuts */
- shared = f->shared;
- lf = shared->lf;
+ /* Sanity check */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->sblock);
+ HDassert(!H5F_addr_defined(f->shared->sblock->ext_addr));
+ HDassert(ext_ptr);
- /* Get the shared file creation property list */
- if(NULL == (c_plist = H5I_object(shared->fcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
+ H5O_loc_reset(ext_ptr);
+ if(H5O_create(f, dxpl_id, 0, H5P_GROUP_CREATE_DEFAULT, ext_ptr) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "unable to create superblock extension")
- /* Find the superblock */
- if(HADDR_UNDEF == (shared->super_addr = H5F_locate_signature(lf, dxpl_id)))
- HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "unable to find file signature")
+ /* Record the address of the superblock extension */
+ f->shared->sblock->ext_addr = ext_ptr->addr;
- /* Read fixed-size portion of the superblock */
- p = sbuf;
- if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, shared->super_addr + fixed_size) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "set end of space allocation request failed")
- if(H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, shared->super_addr, fixed_size, p) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "unable to read superblock")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F_super_ext_create() */
- /* Skip over signature (already checked when locating the superblock) */
- p += H5F_SIGNATURE_LEN;
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_super_ext_open
+ *
+ * Purpose: Open an existing superblock extension
+ *
+ * Return: Success: non-negative on success
+ * Failure: Negative
+ *
+ * Programmer: Vailin Choi; Feb 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_super_ext_open(H5F_t *f, haddr_t ext_addr, H5O_loc_t *ext_ptr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Superblock version */
- super_vers = *p++;
- if(super_vers > HDF5_SUPERBLOCK_VERSION_LATEST)
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad superblock version number")
- if(H5P_set(c_plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set superblock version")
+ FUNC_ENTER_NOAPI_NOINIT(H5F_super_ext_open)
/* Sanity check */
- HDassert(((size_t)(p - sbuf)) == fixed_size);
-
- /* Determine the size of the variable-length part of the superblock */
- variable_size = H5F_SUPERBLOCK_VARLEN_SIZE(super_vers, f);
- HDassert(variable_size > 0);
- HDassert(fixed_size + variable_size <= sizeof(sbuf));
-
- /* Read in variable-sized portion of superblock */
- if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, shared->super_addr + fixed_size + variable_size) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "set end of space allocation request failed")
- if(H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, shared->super_addr + fixed_size, variable_size, p) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read superblock")
-
- /* Check for older version of superblock format */
- if(super_vers < HDF5_SUPERBLOCK_VERSION_2) {
- uint32_t status_flags; /* File status flags */
- unsigned btree_k[H5B_NUM_BTREE_ID]; /* B-tree internal node 'K' values */
- unsigned sym_leaf_k; /* Symbol table leaf node's 'K' value */
-
- /* Freespace version (hard-wired) */
- if(HDF5_FREESPACE_VERSION != *p++)
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad free space version number")
-
- /* Root group version number (hard-wired) */
- if(HDF5_OBJECTDIR_VERSION != *p++)
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad object directory version number")
-
- /* Skip over reserved byte */
- p++;
-
- /* Shared header version number (hard-wired) */
- if(HDF5_SHAREDHEADER_VERSION != *p++)
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad shared-header format version number")
-
- /* Size of file addresses */
- sizeof_addr = *p++;
- if(sizeof_addr != 2 && sizeof_addr != 4 &&
- sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32)
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad byte number in an address")
- if(H5P_set(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &sizeof_addr) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set byte number in an address")
- shared->sizeof_addr = sizeof_addr; /* Keep a local copy also */
-
- /* Size of file sizes */
- sizeof_size = *p++;
- if(sizeof_size != 2 && sizeof_size != 4 &&
- sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32)
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad byte number for object size")
- if(H5P_set(c_plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set byte number for object size")
- shared->sizeof_size = sizeof_size; /* Keep a local copy also */
-
- /* Skip over reserved byte */
- p++;
-
- /* Various B-tree sizes */
- UINT16DECODE(p, sym_leaf_k);
- if(sym_leaf_k == 0)
- HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "bad symbol table leaf node 1/2 rank")
- if(H5P_set(c_plist, H5F_CRT_SYM_LEAF_NAME, &sym_leaf_k) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set rank for symbol table leaf nodes")
- shared->sym_leaf_k = sym_leaf_k; /* Keep a local copy also */
-
- /* Need 'get' call to set other array values */
- if(H5P_get(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get rank for btree internal nodes")
- UINT16DECODE(p, btree_k[H5B_SNODE_ID]);
- if(btree_k[H5B_SNODE_ID] == 0)
- HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "bad 1/2 rank for btree internal nodes")
- /*
- * Delay setting the value in the property list until we've checked
- * for the indexed storage B-tree internal 'K' value later.
- */
-
- /* File status flags (not really used yet) */
- UINT32DECODE(p, status_flags);
- HDassert(status_flags <= 255);
- shared->status_flags = status_flags;
- if(shared->status_flags & ~H5F_SUPER_ALL_FLAGS)
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad flag value for superblock")
-
- /*
- * If the superblock version # is greater than 0, read in the indexed
- * storage B-tree internal 'K' value
- */
- if(super_vers > HDF5_SUPERBLOCK_VERSION_DEF) {
- UINT16DECODE(p, btree_k[H5B_ISTORE_ID]);
- /* Reserved bytes are present only in version 1 */
- if(super_vers == HDF5_SUPERBLOCK_VERSION_1)
- p += 2; /* reserved */
- } /* end if */
- else
- btree_k[H5B_ISTORE_ID] = HDF5_BTREE_ISTORE_IK_DEF;
-
- /* Set the B-tree internal node values, etc */
- if(H5P_set(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set rank for btree internal nodes")
- HDmemcpy(shared->btree_k, btree_k, sizeof(unsigned) * (size_t)H5B_NUM_BTREE_ID); /* Keep a local copy also */
+ HDassert(f);
+ HDassert(H5F_addr_defined(ext_addr));
+ HDassert(ext_ptr);
- /* Remainder of "variable-sized" portion of superblock */
- H5F_addr_decode(f, (const uint8_t **)&p, &shared->base_addr/*out*/);
- H5F_addr_decode(f, (const uint8_t **)&p, &shared->extension_addr/*out*/);
- H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/);
- H5F_addr_decode(f, (const uint8_t **)&p, &shared->driver_addr/*out*/);
- if(H5G_obj_ent_decode(f, (const uint8_t **)&p, root_loc->oloc/*out*/) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read root symbol entry")
+ /* Set up "fake" object location for superblock extension */
+ H5O_loc_reset(ext_ptr);
+ ext_ptr->file = f;
+ ext_ptr->addr = ext_addr;
- /*
- * Check if superblock address is different from base address and
- * adjust base address and "end of address" address if so.
- */
- if(!H5F_addr_eq(shared->super_addr, shared->base_addr)) {
- /* Check if the superblock moved earlier in the file */
- if(H5F_addr_lt(shared->super_addr, shared->base_addr))
- stored_eoa -= (shared->base_addr - shared->super_addr);
- else
- /* The superblock moved later in the file */
- stored_eoa += (shared->super_addr - shared->base_addr);
+ /* Open the superblock extension object header */
+ if(H5O_open(ext_ptr) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open superblock extension")
- shared->base_addr = shared->super_addr;
- } /* end if */
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F_super_ext_open() */
- /* This step is for h5repart tool only. If user wants to change file driver
- * from family to sec2 while using h5repart, set the driver address to
- * undefined to let the library ignore the family driver information saved
- * in the superblock.
- */
- if(shared->fam_to_sec2)
- shared->driver_addr = HADDR_UNDEF;
-
- /* Decode the optional driver information block */
- if(H5F_addr_defined(shared->driver_addr)) {
- uint8_t dbuf[H5F_MAX_DRVINFOBLOCK_SIZE]; /* Buffer for driver info block */
- char drv_name[9]; /* Name of driver */
- unsigned drv_vers; /* Version of driver info block */
- haddr_t drv_addr = shared->base_addr + shared->driver_addr;
- size_t drv_variable_size; /* Size of variable-length portion of driver info block, in bytes */
-
- /* Read in fixed-sized portion of driver info block */
- p = dbuf;
- if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, drv_addr + H5F_DRVINFOBLOCK_HDR_SIZE) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "set end of space allocation request failed")
- if(H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, drv_addr, (size_t)H5F_DRVINFOBLOCK_HDR_SIZE, p) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read driver information block")
-
- /* Version number */
- drv_vers = *p++;
- if(drv_vers != HDF5_DRIVERINFO_VERSION_0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "bad driver information block version number")
-
- p += 3; /* reserved bytes */
-
- /* Driver info size */
- UINT32DECODE(p, drv_variable_size);
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_super_ext_close
+ *
+ * Purpose: Close superblock extension
+ *
+ * Return: Success: non-negative on success
+ * Failure: Negative
+ *
+ * Programmer: Vailin Choi; Feb 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_super_ext_close(H5F_t *f, H5O_loc_t *ext_ptr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Sanity check */
- HDassert(H5F_DRVINFOBLOCK_HDR_SIZE + drv_variable_size <= sizeof(dbuf));
-
- /* Driver name and/or version */
- HDstrncpy(drv_name, (const char *)p, (size_t)8);
- drv_name[8] = '\0';
- p += 8; /* advance past name/version */
-
- /* Check if driver matches driver information saved. Unfortunately, we can't push this
- * function to each specific driver because we're checking if the driver is correct.
- */
- if(!HDstrncmp(drv_name, "NCSAfami", (size_t)8) && HDstrcmp(lf->cls->name, "family"))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "family driver should be used")
- if(!HDstrncmp(drv_name, "NCSAmult", (size_t)8) && HDstrcmp(lf->cls->name, "multi"))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "multi driver should be used")
-
- /* Read in variable-sized portion of driver info block */
- if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, drv_addr + H5F_DRVINFOBLOCK_HDR_SIZE + drv_variable_size) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "set end of space allocation request failed")
- if(H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, drv_addr + H5F_DRVINFOBLOCK_HDR_SIZE, drv_variable_size, p) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read file driver information")
-
- /* Decode driver information */
- if(H5FD_sb_decode(lf, drv_name, p) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to decode driver information")
- } /* end if */
- } /* end if */
- else {
- haddr_t root_addr; /* Address of root group */
- uint32_t computed_chksum; /* Computed checksum */
- uint32_t read_chksum; /* Checksum read from file */
-
- /* Size of file addresses */
- sizeof_addr = *p++;
- if(sizeof_addr != 2 && sizeof_addr != 4 &&
- sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32)
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad byte number in an address")
- if(H5P_set(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &sizeof_addr) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set byte number in an address")
- shared->sizeof_addr = sizeof_addr; /* Keep a local copy also */
-
- /* Size of file sizes */
- sizeof_size = *p++;
- if(sizeof_size != 2 && sizeof_size != 4 &&
- sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32)
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad byte number for object size")
- if(H5P_set(c_plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set byte number for object size")
- shared->sizeof_size = sizeof_size; /* Keep a local copy also */
-
- /* File status flags (not really used yet) */
- shared->status_flags = *p++;
- if(shared->status_flags & ~H5F_SUPER_ALL_FLAGS)
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad flag value for superblock")
-
- /* Base, superblock extension, end of file & root group object header addresses */
- H5F_addr_decode(f, (const uint8_t **)&p, &shared->base_addr/*out*/);
- H5F_addr_decode(f, (const uint8_t **)&p, &shared->extension_addr/*out*/);
- H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/);
- H5F_addr_decode(f, (const uint8_t **)&p, &root_addr/*out*/);
-
- /* Compute checksum for superblock */
- computed_chksum = H5_checksum_metadata(sbuf, (size_t)(p - sbuf), 0);
-
- /* Decode checksum */
- UINT32DECODE(p, read_chksum);
-
- /* Verify correct checksum */
- if(read_chksum != computed_chksum)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "bad checksum on driver information block")
-
- /* Create root group object location */
- H5O_loc_reset(root_loc->oloc);
- root_loc->oloc->file = f;
- root_loc->oloc->addr = root_addr;
+ FUNC_ENTER_NOAPI_NOINIT(H5F_super_ext_close)
- /*
- * Check if superblock address is different from base address and
- * adjust base address and "end of address" address if so.
- */
- if(!H5F_addr_eq(shared->super_addr, shared->base_addr)) {
- /* Check if the superblock moved earlier in the file */
- if(H5F_addr_lt(shared->super_addr, shared->base_addr))
- stored_eoa -= (shared->base_addr - shared->super_addr);
- else
- /* The superblock moved later in the file */
- stored_eoa += (shared->super_addr - shared->base_addr);
+ /* Sanity check */
+ HDassert(f);
+ HDassert(ext_ptr);
- shared->base_addr = shared->super_addr;
- } /* end if */
- } /* end else */
+ /* Twiddle the number of open objects to avoid closing the file. */
+ f->nopen_objs++;
+ if(H5O_close(ext_ptr) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "unable to close superblock extension")
+ f->nopen_objs--;
- /*
- * The user-defined data is the area of the file before the base
- * address.
- */
- if(H5P_set(c_plist, H5F_CRT_USER_BLOCK_NAME, &shared->base_addr) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set userblock size")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F_super_ext_close() */
- /*
- * Make sure that the data is not truncated. One case where this is
- * possible is if the first file of a family of files was opened
- * individually.
- */
- if(HADDR_UNDEF == (eof = H5FD_get_eof(lf)))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size")
- if(eof < stored_eoa)
- HGOTO_ERROR(H5E_FILE, H5E_TRUNCATED, FAIL, "truncated file")
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_super_read
+ *
+ * Purpose: Reads the superblock from the file or from the BUF. If
+ * ADDR is a valid address, then it reads it from the file.
+ * If not, then BUF must be non-NULL for it to read from the
+ * BUF.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Bill Wendling
+ * wendling@ncsa.uiuc.edu
+ * Sept 12, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_super_read(H5F_t *f, hid_t dxpl_id)
+{
+ H5F_super_t * sblock = NULL; /* superblock structure */
+ unsigned sblock_flags = H5AC__NO_FLAGS_SET; /* flags used in superblock unprotect call */
+ haddr_t super_addr; /* Absolute address of superblock */
+ H5AC_protect_t rw; /* read/write permissions for file */
+ hbool_t dirtied = FALSE; /* Bool for sblock protect call */
+ herr_t ret_value = SUCCEED; /* return value */
- /*
- * Tell the file driver how much address space has already been
- * allocated so that it knows how to allocate additional memory.
- */
- if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, stored_eoa) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to set end-of-address marker for file")
+ FUNC_ENTER_NOAPI(H5F_super_read, FAIL)
- /* Read the file's superblock extension, if there is one. */
- if(H5F_addr_defined(shared->extension_addr)) {
- H5O_loc_t ext_loc; /* "Object location" for superblock extension */
- H5O_btreek_t btreek; /* v1 B-tree 'K' value message from superblock extension */
- H5O_drvinfo_t drvinfo; /* Driver info message from superblock extension */
+ /* Find the superblock */
+ if(HADDR_UNDEF == (super_addr = H5F_locate_signature(f->shared->lf, dxpl_id)))
+ HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "unable to find file signature")
- /* Sanity check - superblock extension should only be defined for
- * superblock version >= 2.
- */
- HDassert(super_vers >= HDF5_SUPERBLOCK_VERSION_2);
+ /* Check for userblock present */
+ if(H5F_addr_gt(super_addr, 0)) {
+ /* Set the base address for the file in the VFD now */
+ if(H5FD_set_base_addr(f->shared->lf, super_addr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "failed to set base address for file driver")
+ } /* end if */
- /* Set up "fake" object location for superblock extension */
- H5O_loc_reset(&ext_loc);
- ext_loc.file = f;
- ext_loc.addr = shared->extension_addr;
+ /* Determine file intent for superblock protect */
+ if(H5F_INTENT(f) & H5F_ACC_RDWR)
+ rw = H5AC_WRITE;
+ else
+ rw = H5AC_READ;
- /* Open the superblock extension */
- if(H5O_open(&ext_loc) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENFILE, FAIL, "unable to open superblock extension")
+ /* Look up the superblock */
+ if(NULL == (sblock = (H5F_super_t *)H5AC_protect(f, dxpl_id, H5AC_SUPERBLOCK, (haddr_t)0, NULL, &dirtied, rw)))
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load superblock")
+
+ /* Mark the superblock dirty if it was modified during loading or VFD indicated to do so */
+ if((H5AC_WRITE == rw) && (dirtied || H5F_HAS_FEATURE(f, H5FD_FEAT_DIRTY_SBLK_LOAD)))
+ sblock_flags |= H5AC__DIRTIED_FLAG;
- /* Read in the shared OH message information if there is any */
- if(H5SM_get_info(&ext_loc, c_plist, dxpl_id) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read SOHM table information")
+ /* Pin the superblock in the cache */
+ if(H5AC_pin_protected_entry(f, sblock) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTPIN, FAIL, "unable to pin superblock")
- /* Read in v1 B-tree 'K' value message, if it exists */
- if(NULL == H5O_msg_read(&ext_loc, H5O_BTREEK_ID, &btreek, dxpl_id)) {
- /* Reset error from "failed" message read */
- H5E_clear_stack(NULL);
-
- /* No non-default v1 B-tree 'K' value info in file, use defaults */
- shared->btree_k[H5B_ISTORE_ID] = HDF5_BTREE_ISTORE_IK_DEF;
- shared->btree_k[H5B_SNODE_ID] = HDF5_BTREE_SNODE_IK_DEF;
- shared->sym_leaf_k = H5F_CRT_SYM_LEAF_DEF;
- } /* end if */
- else {
- /* Set non-default v1 B-tree 'K' value info from file */
- shared->btree_k[H5B_ISTORE_ID] = btreek.btree_k[H5B_ISTORE_ID];
- shared->btree_k[H5B_SNODE_ID] = btreek.btree_k[H5B_SNODE_ID];
- shared->sym_leaf_k = btreek.sym_leaf_k;
-
- /* Set non-default v1 B-tree 'K' values in the property list */
- if(H5P_set(c_plist, H5F_CRT_BTREE_RANK_NAME, btreek.btree_k) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set rank for btree internal nodes")
- if(H5P_set(c_plist, H5F_CRT_SYM_LEAF_NAME, &btreek.sym_leaf_k) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set rank for symbol table leaf nodes")
- } /* end else */
-
- /* Read in driver info message, if it exists */
- if(NULL == H5O_msg_read(&ext_loc, H5O_DRVINFO_ID, &drvinfo, dxpl_id)) {
- /* Reset error from "failed" message read */
- H5E_clear_stack(NULL);
- } /* end if */
- else {
- /* Check if driver matches driver information saved. Unfortunately, we can't push this
- * function to each specific driver because we're checking if the driver is correct.
- */
- if(!HDstrncmp(drvinfo.name, "NCSAfami", (size_t)8) && HDstrcmp(lf->cls->name, "family"))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "family driver should be used")
- if(!HDstrncmp(drvinfo.name, "NCSAmult", (size_t)8) && HDstrcmp(lf->cls->name, "multi"))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "multi driver should be used")
-
- /* Decode driver information */
- if(H5FD_sb_decode(lf, drvinfo.name, drvinfo.buf) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to decode driver information")
-
- /* Reset driver info message */
- H5O_msg_reset(H5O_DRVINFO_ID, &drvinfo);
- } /* end else */
-
- /* Close the extension. Twiddle the number of open objects to avoid
- * closing the file (since this will be the only open object).
- */
- f->nopen_objs++;
- if(H5O_close(&ext_loc) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENFILE, FAIL, "unable to close superblock extension")
- f->nopen_objs--;
- } /* end if */
+ /* Set the pointer to the pinned superblock */
+ f->shared->sblock = sblock;
done:
+ /* Release the superblock */
+ if(sblock && H5AC_unprotect(f, dxpl_id, H5AC_SUPERBLOCK, (haddr_t)0, sblock, sblock_flags) < 0)
+ HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close superblock")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_super_read() */
@@ -651,22 +361,69 @@ done:
herr_t
H5F_super_init(H5F_t *f, hid_t dxpl_id)
{
- H5P_genplist_t *plist; /* File creation property list */
- hsize_t userblock_size; /* Size of userblock, in bytes */
- size_t superblock_size; /* Size of superblock, in bytes */
- size_t driver_size; /* Size of driver info block (bytes) */
- hsize_t alloc_size; /* Size to allocate on disk */
- unsigned super_vers; /* Superblock version */
- haddr_t super_addr; /* Address of superblock */
+ H5F_super_t *sblock = NULL; /* Superblock cache structure */
+ hbool_t sblock_in_cache = FALSE; /* Whether the superblock has been inserted into the metadata cache */
+ H5P_genplist_t *plist; /* File creation property list */
+ hsize_t userblock_size; /* Size of userblock, in bytes */
+ hsize_t superblock_size; /* Size of superblock, in bytes */
+ size_t driver_size; /* Size of driver info block (bytes) */
+ unsigned super_vers = HDF5_SUPERBLOCK_VERSION_DEF; /* Superblock version for file */
hbool_t need_ext; /* Whether the superblock extension is needed */
- herr_t ret_value = SUCCEED;
+ herr_t ret_value = SUCCEED; /* Return Value */
FUNC_ENTER_NOAPI(H5F_super_init, FAIL)
+ /* Allocate space for the superblock */
+ if(NULL == (sblock = H5FL_CALLOC(H5F_super_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Initialize various address information */
+ sblock->base_addr = HADDR_UNDEF;
+ sblock->ext_addr = HADDR_UNDEF;
+ sblock->driver_addr = HADDR_UNDEF;
+ sblock->root_addr = HADDR_UNDEF;
+
/* Get the shared file creation property list */
- if(NULL == (plist = H5I_object(f->shared->fcpl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(f->shared->fcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
+ /* Initialize sym_leaf_k */
+ if(H5P_get(plist, H5F_CRT_SYM_LEAF_NAME, &sblock->sym_leaf_k) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get byte number for object size")
+
+ /* Initialize btree_k */
+ if(H5P_get(plist, H5F_CRT_BTREE_RANK_NAME, &sblock->btree_k[0]) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get rank for btree internal nodes")
+
+ /* Bump superblock version if we are to use the latest version of the format */
+ if(f->shared->latest_format)
+ super_vers = HDF5_SUPERBLOCK_VERSION_LATEST;
+ /* Bump superblock version to create superblock extension for SOHM info */
+ else if(f->shared->sohm_nindexes > 0)
+ super_vers = HDF5_SUPERBLOCK_VERSION_2;
+ /* Bump superblock version to create superblock extension for
+ * non-default file space strategy or non-default free-space threshold
+ */
+ else if(f->shared->fs_strategy != H5F_FILE_SPACE_STRATEGY_DEF ||
+ f->shared->fs_threshold != H5F_FREE_SPACE_THRESHOLD_DEF)
+ super_vers = HDF5_SUPERBLOCK_VERSION_2;
+ /* Check for non-default indexed storage B-tree internal 'K' value
+ * and set the version # of the superblock to 1 if it is a non-default
+ * value.
+ */
+ else if(sblock->btree_k[H5B_CHUNK_ID] != HDF5_BTREE_CHUNK_IK_DEF)
+ super_vers = HDF5_SUPERBLOCK_VERSION_1;
+
+ /* If a newer superblock version is required, set it here */
+ if(super_vers != HDF5_SUPERBLOCK_VERSION_DEF) {
+ H5P_genplist_t *c_plist; /* Property list */
+
+ if(NULL == (c_plist = (H5P_genplist_t *)H5I_object(f->shared->fcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property list")
+ if(H5P_set(c_plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set superblock version")
+ } /* end if */
+
/*
* The superblock starts immediately after the user-defined
* header, which we have already insured is a proper size. The
@@ -675,13 +432,30 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id)
*/
if(H5P_get(plist, H5F_CRT_USER_BLOCK_NAME, &userblock_size) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get userblock size")
- f->shared->super_addr = userblock_size;
- f->shared->base_addr = f->shared->super_addr;
- f->shared->status_flags = 0;
- /* Grab superblock version from property list */
- if(H5P_get(plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get superblock version")
+ /* Sanity check the userblock size vs. the file's allocation alignment */
+ if(userblock_size > 0) {
+ if(userblock_size < f->shared->alignment)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "userblock size must be > file object alignment")
+ if(0 != (userblock_size % f->shared->alignment))
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "userblock size must be an integral multiple of file object alignment")
+ } /* end if */
+
+ sblock->base_addr = userblock_size;
+ sblock->status_flags = 0;
+
+ /* Reserve space for the userblock */
+ if(H5FD_set_eoa(f->shared->lf, H5FD_MEM_SUPER, userblock_size) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to set EOA value for userblock")
+
+ /* Set the base address for the file in the VFD now, after allocating
+ * space for userblock.
+ */
+ if(H5FD_set_base_addr(f->shared->lf, sblock->base_addr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "failed to set base address for file driver")
+
+ /* Save a local copy of the superblock version number */
+ sblock->super_vers = super_vers;
/* Compute the size of the superblock */
superblock_size = H5F_SUPERBLOCK_SIZE(super_vers, f);
@@ -695,7 +469,7 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id)
* The file driver information block begins immediately after the
* superblock. (relative to base address in file)
*/
- f->shared->driver_addr = superblock_size;
+ sblock->driver_addr = superblock_size;
} /* end if */
/*
@@ -704,15 +478,20 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id)
* superblock need to be at the beginning of the file and only the first
* allocation request is required to return memory at format address zero.
*/
- H5_CHECK_OVERFLOW(f->shared->base_addr, haddr_t, hsize_t);
- alloc_size = (hsize_t)f->shared->base_addr + superblock_size;
if(super_vers < HDF5_SUPERBLOCK_VERSION_2)
- alloc_size += driver_size;
- super_addr = H5FD_alloc(f->shared->lf, H5FD_MEM_SUPER, dxpl_id, alloc_size);
- if(HADDR_UNDEF == super_addr)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate file space for userblock and/or superblock")
- if(0 != super_addr)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "file driver failed to allocate userblock and/or superblock at address zero")
+ superblock_size += driver_size;
+
+ /* Reserve space in the file for the superblock, instead of allocating it */
+ if(H5FD_set_eoa(f->shared->lf, H5FD_MEM_SUPER, superblock_size) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to set EOA value for superblock")
+
+ /* Insert superblock into cache, pinned */
+ if(H5AC_set(f, dxpl_id, H5AC_SUPERBLOCK, (haddr_t)0, sblock, H5AC__PIN_ENTRY_FLAG) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "can't add superblock to cache")
+ sblock_in_cache = TRUE;
+
+ /* Keep a copy of the superblock info */
+ f->shared->sblock = sblock;
/*
* Determine if we will need a superblock extension
@@ -723,15 +502,21 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id)
HDassert(super_vers >= HDF5_SUPERBLOCK_VERSION_2);
need_ext = TRUE;
} /* end if */
- /* If we're going to use a version of the superblock format which allows
+ /* Files with non-default free space settings always need the superblock extension */
+ else if(f->shared->fs_strategy != H5F_FILE_SPACE_STRATEGY_DEF ||
+ f->shared->fs_threshold != H5F_FREE_SPACE_THRESHOLD_DEF) {
+ HDassert(super_vers >= HDF5_SUPERBLOCK_VERSION_2);
+ need_ext = TRUE;
+ } /* end if */
+ /* If we're going to use a version of the superblock format which allows
* for the superblock extension, check for non-default values to store
* in it.
*/
else if(super_vers >= HDF5_SUPERBLOCK_VERSION_2) {
/* Check for non-default v1 B-tree 'K' values to store */
- if(f->shared->btree_k[H5B_SNODE_ID] != HDF5_BTREE_SNODE_IK_DEF ||
- f->shared->btree_k[H5B_ISTORE_ID] != HDF5_BTREE_ISTORE_IK_DEF ||
- f->shared->sym_leaf_k != H5F_CRT_SYM_LEAF_DEF)
+ if(sblock->btree_k[H5B_SNODE_ID] != HDF5_BTREE_SNODE_IK_DEF ||
+ sblock->btree_k[H5B_CHUNK_ID] != HDF5_BTREE_CHUNK_IK_DEF ||
+ sblock->sym_leaf_k != H5F_CRT_SYM_LEAF_DEF)
need_ext = TRUE;
/* Check for driver info to store */
else if(driver_size > 0)
@@ -754,12 +539,8 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id)
* be tuned if more information is added to the superblock
* extension.
*/
- H5O_loc_reset(&ext_loc);
- if(H5O_create(f, dxpl_id, 0, H5P_GROUP_CREATE_DEFAULT, &ext_loc) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "unable to create superblock extension")
-
- /* Record the address of the superblock extension */
- f->shared->extension_addr = ext_loc.addr;
+ if(H5F_super_ext_create(f, dxpl_id, &ext_loc) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to start file's superblock extension")
/* Create the Shared Object Header Message table and register it with
* the metadata cache, if this file supports shared messages.
@@ -771,15 +552,15 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id)
} /* end if */
/* Check for non-default v1 B-tree 'K' values to store */
- if(f->shared->btree_k[H5B_SNODE_ID] != HDF5_BTREE_SNODE_IK_DEF ||
- f->shared->btree_k[H5B_ISTORE_ID] != HDF5_BTREE_ISTORE_IK_DEF ||
- f->shared->sym_leaf_k != H5F_CRT_SYM_LEAF_DEF) {
+ if(sblock->btree_k[H5B_SNODE_ID] != HDF5_BTREE_SNODE_IK_DEF ||
+ sblock->btree_k[H5B_CHUNK_ID] != HDF5_BTREE_CHUNK_IK_DEF ||
+ sblock->sym_leaf_k != H5F_CRT_SYM_LEAF_DEF) {
H5O_btreek_t btreek; /* v1 B-tree 'K' value message for superblock extension */
/* Write v1 B-tree 'K' value information to the superblock extension */
- btreek.btree_k[H5B_ISTORE_ID] = f->shared->btree_k[H5B_ISTORE_ID];
- btreek.btree_k[H5B_SNODE_ID] = f->shared->btree_k[H5B_SNODE_ID];
- btreek.sym_leaf_k = f->shared->sym_leaf_k;
+ btreek.btree_k[H5B_CHUNK_ID] = sblock->btree_k[H5B_CHUNK_ID];
+ btreek.btree_k[H5B_SNODE_ID] = sblock->btree_k[H5B_SNODE_ID];
+ btreek.sym_leaf_k = sblock->sym_leaf_k;
if(H5O_msg_create(&ext_loc, H5O_BTREEK_ID, H5O_MSG_FLAG_CONSTANT | H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, &btreek, dxpl_id) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update v1 B-tree 'K' value header message")
} /* end if */
@@ -799,212 +580,281 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id)
/* Write driver info information to the superblock extension */
drvinfo.len = driver_size;
drvinfo.buf = dbuf;
- if(H5O_msg_create(&ext_loc, H5O_DRVINFO_ID, H5O_MSG_FLAG_CONSTANT | H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, &drvinfo, dxpl_id) < 0)
+ if(H5O_msg_create(&ext_loc, H5O_DRVINFO_ID, H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, &drvinfo, dxpl_id) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update driver info header message")
} /* end if */
- /* Twiddle the number of open objects to avoid closing the file
- * (since this will be the only open object currently).
- */
- f->nopen_objs++;
- if(H5O_close(&ext_loc) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close superblock extension")
- f->nopen_objs--;
+ /* Check for non-default free space settings */
+ if(f->shared->fs_strategy != H5F_FILE_SPACE_STRATEGY_DEF ||
+ f->shared->fs_threshold != H5F_FREE_SPACE_THRESHOLD_DEF) {
+ H5O_fsinfo_t fsinfo; /* Free space manager info message */
+
+ /* Write free-space manager info message to superblock extension object header if needed */
+ fsinfo.strategy = f->shared->fs_strategy;
+ fsinfo.threshold = f->shared->fs_threshold;
+ if(H5O_msg_create(&ext_loc, H5O_FSINFO_ID, H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, &fsinfo, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update free-space info header message")
+ } /* end if */
+
+ /* Close superblock extension */
+ if(H5F_super_ext_close(f, &ext_loc) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension")
} /* end if */
done:
+ /* Cleanup on failure */
+ if(ret_value < 0) {
+ /* Check if the superblock has been allocated yet */
+ if(sblock) {
+ /* Check if we've cached it already */
+ if(sblock_in_cache) {
+ /* Unpin superblock in cache */
+ if(H5AC_unpin_entry(f, sblock) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTUNPIN, FAIL, "unable to unpin superblock")
+
+ /* Evict the superblock from the cache */
+ if(H5AC_expunge_entry(f, dxpl_id, H5AC_SUPERBLOCK, (haddr_t)0, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTEXPUNGE, FAIL, "unable to expunge superblock")
+ } /* end if */
+ else
+ /* Free superblock */
+ sblock = (H5F_super_t *)H5FL_FREE(H5F_super_t, sblock);
+
+ /* Reset variables in file structure */
+ f->shared->sblock = NULL;
+ } /* end if */
+ } /* end if */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_super_init() */
/*-------------------------------------------------------------------------
- * Function: H5F_super_write
+ * Function: H5F_super_dirty
*
- * Purpose: Writes the superblock for the file.
+ * Purpose: Mark the file's superblock dirty
*
- * Return: Success: SUCCEED
- * Failure: FAIL
+ * Return: Success: non-negative on success
+ * Failure: Negative
*
- * Programmer: Bill Wendling
- * wendling@ncsa.uiuc.edu
- * Sept 12, 2003
+ * Programmer: Quincey Koziol
+ * August 14, 2009
*
*-------------------------------------------------------------------------
*/
herr_t
-H5F_super_write(H5F_t *f, hid_t dxpl_id)
+H5F_super_dirty(H5F_t *f)
{
- H5P_genplist_t *plist; /* File creation property list */
- uint8_t buf[H5F_MAX_SUPERBLOCK_SIZE + H5F_MAX_DRVINFOBLOCK_SIZE]; /* Superblock & driver info blockencoding buffer */
- uint8_t *p; /* Ptr into encoding buffer */
- size_t superblock_size; /* Size of superblock, in bytes */
- size_t driver_size; /* Size of driver info block (bytes)*/
- unsigned super_vers; /* Superblock version */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI(H5F_super_write, FAIL)
-
- /* Get the shared file creation property list */
- if(NULL == (plist = H5I_object(f->shared->fcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Grab values from property list */
- if(H5P_get(plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get superblock version")
-
- /* Encode the common portion of the file superblock for all versions */
- p = buf;
- HDmemcpy(p, H5F_SIGNATURE, (size_t)H5F_SIGNATURE_LEN);
- p += H5F_SIGNATURE_LEN;
- *p++ = (uint8_t)super_vers;
-
- /* Check for older version of superblock format */
- if(super_vers < HDF5_SUPERBLOCK_VERSION_2) {
- *p++ = (uint8_t)HDF5_FREESPACE_VERSION; /* (hard-wired) */
- *p++ = (uint8_t)HDF5_OBJECTDIR_VERSION; /* (hard-wired) */
- *p++ = 0; /* reserved*/
-
- *p++ = (uint8_t)HDF5_SHAREDHEADER_VERSION; /* (hard-wired) */
- HDassert(H5F_SIZEOF_ADDR(f) <= 255);
- *p++ = (uint8_t)H5F_SIZEOF_ADDR(f);
- HDassert(H5F_SIZEOF_SIZE(f) <= 255);
- *p++ = (uint8_t)H5F_SIZEOF_SIZE(f);
- *p++ = 0; /* reserved */
-
- UINT16ENCODE(p, f->shared->sym_leaf_k);
- UINT16ENCODE(p, f->shared->btree_k[H5B_SNODE_ID]);
- UINT32ENCODE(p, (uint32_t)f->shared->status_flags);
+ FUNC_ENTER_NOAPI(H5F_super_dirty, FAIL)
- /*
- * Versions of the superblock >0 have the indexed storage B-tree
- * internal 'K' value stored
- */
- if(super_vers > HDF5_SUPERBLOCK_VERSION_DEF) {
- UINT16ENCODE(p, f->shared->btree_k[H5B_ISTORE_ID]);
- *p++ = 0; /*reserved */
- *p++ = 0; /*reserved */
- } /* end if */
+ /* Sanity check */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->sblock);
- H5F_addr_encode(f, &p, f->shared->base_addr);
- H5F_addr_encode(f, &p, f->shared->extension_addr);
- H5F_addr_encode(f, &p, H5FD_get_eoa(f->shared->lf, H5FD_MEM_SUPER));
- H5F_addr_encode(f, &p, f->shared->driver_addr);
- if(H5G_obj_ent_encode(f, &p, H5G_oloc(f->shared->root_grp)) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to encode root group information")
+ /* Mark superblock dirty in cache, so change to EOA will get encoded */
+ if(H5AC_mark_pinned_or_protected_entry_dirty(f, f->shared->sblock) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty")
- /* Encode the driver information block. */
- H5_ASSIGN_OVERFLOW(driver_size, H5FD_sb_size(f->shared->lf), hsize_t, size_t);
- if(driver_size > 0) {
- char driver_name[9]; /* Name of driver, for driver info block */
- uint8_t *dbuf = p; /* Pointer to beginning of driver info */
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F_super_dirty() */
- /* Encode the driver information block */
- *p++ = HDF5_DRIVERINFO_VERSION_0; /* Version */
- *p++ = 0; /* reserved */
- *p++ = 0; /* reserved */
- *p++ = 0; /* reserved */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_super_size
+ *
+ * Purpose: Get storage size of the superblock and superblock extension
+ *
+ * Return: Success: non-negative on success
+ * Failure: Negative
+ *
+ * Programmer: Vailin Choi
+ * July 11, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_super_size(H5F_t *f, hid_t dxpl_id, hsize_t *super_size, hsize_t *super_ext_size)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Driver info size, excluding header */
- UINT32ENCODE(p, driver_size);
+ FUNC_ENTER_NOAPI(H5F_super_size, FAIL)
- /* Encode driver-specific data */
- if(H5FD_sb_encode(f->shared->lf, driver_name, dbuf + H5F_DRVINFOBLOCK_HDR_SIZE) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to encode driver information")
+ /* Sanity check */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->sblock);
- /* Store driver name (set in 'H5FD_sb_encode' call above) */
- HDmemcpy(p, driver_name, (size_t)8);
+ /* Set the superblock size */
+ if(super_size)
+ *super_size = H5F_SUPERBLOCK_SIZE(f->shared->sblock->super_vers, f);
- /* Advance buffer pointer past name & variable-sized portion of driver info */
- /* (for later use in computing the superblock size) */
- p += 8 + driver_size;
+ /* Set the superblock extension size */
+ if(super_ext_size) {
+ if(H5F_addr_defined(f->shared->sblock->ext_addr)) {
+ H5O_loc_t ext_loc; /* "Object location" for superblock extension */
+ H5O_hdr_info_t hdr_info; /* Object info for superblock extension */
+
+ /* Set up "fake" object location for superblock extension */
+ H5O_loc_reset(&ext_loc);
+ ext_loc.file = f;
+ ext_loc.addr = f->shared->sblock->ext_addr;
+
+ /* Get object header info for superblock extension */
+ if(H5O_get_hdr_info(&ext_loc, dxpl_id, &hdr_info) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve superblock extension info")
+
+ /* Set the superblock extension size */
+ *super_ext_size = hdr_info.space.total;
} /* end if */
+ else
+ /* Set the superblock extension size to zero */
+ *super_ext_size = (hsize_t)0;
} /* end if */
- else {
- uint32_t chksum; /* Checksum temporary variable */
- H5O_loc_t *root_oloc; /* Pointer to root group's object location */
- /* Size of file addresses & offsets, and status flags */
- HDassert(H5F_SIZEOF_ADDR(f) <= 255);
- *p++ = (uint8_t)H5F_SIZEOF_ADDR(f);
- HDassert(H5F_SIZEOF_SIZE(f) <= 255);
- *p++ = (uint8_t)H5F_SIZEOF_SIZE(f);
- *p++ = f->shared->status_flags;
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F_super_size() */
- /* Base, superblock extension & end of file addresses */
- H5F_addr_encode(f, &p, f->shared->base_addr);
- H5F_addr_encode(f, &p, f->shared->extension_addr);
- H5F_addr_encode(f, &p, H5FD_get_eoa(f->shared->lf, H5FD_MEM_SUPER));
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_super_ext_write_msg()
+ *
+ * Purpose: Write the message with ID to the superblock extension
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Feb 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_super_ext_write_msg(H5F_t *f, hid_t dxpl_id, void *mesg, unsigned id, hbool_t may_create)
+{
+ hbool_t sblock_dirty = FALSE; /* Whether superblock was dirtied */
+ H5O_loc_t ext_loc; /* "Object location" for superblock extension */
+ htri_t status; /* Indicate whether the message exists or not */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Retrieve information for root group */
- if(NULL == (root_oloc = H5G_oloc(f->shared->root_grp)))
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to retrieve root group information")
+ FUNC_ENTER_NOAPI(H5F_super_ext_write_msg, FAIL)
- /* Encode address of root group's object header */
- H5F_addr_encode(f, &p, root_oloc->addr);
+ /* Sanity checks */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->sblock);
- /* Compute superblock checksum */
- chksum = H5_checksum_metadata(buf, (H5F_SUPERBLOCK_SIZE(super_vers, f) - H5F_SIZEOF_CHKSUM), 0);
+ /* Open/create the superblock extension object header */
+ if(H5F_addr_defined(f->shared->sblock->ext_addr)) {
+ if(H5F_super_ext_open(f, f->shared->sblock->ext_addr, &ext_loc) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open file's superblock extension")
+ } /* end if */
+ else {
+ HDassert(may_create);
+ if(H5F_super_ext_create(f, dxpl_id, &ext_loc) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "unable to create file's superblock extension")
+ sblock_dirty = TRUE;
+ } /* end else */
+ HDassert(H5F_addr_defined(ext_loc.addr));
- /* Superblock checksum */
- UINT32ENCODE(p, chksum);
+ /* Check if message with ID does not exist in the object header */
+ if((status = H5O_msg_exists(&ext_loc, id, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to check object header for message or message exists")
- /* Sanity check */
- HDassert((size_t)(p - buf) == H5F_SUPERBLOCK_SIZE(super_vers, f));
- } /* end else */
+ /* Check for creating vs. writing */
+ if(may_create) {
+ if(status)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "Message should not exist")
- /* Retrieve the total size of the superblock info */
- H5_ASSIGN_OVERFLOW(superblock_size, (p - buf), int, size_t);
+ /* Create the message with ID in the superblock extension */
+ if(H5O_msg_create(&ext_loc, id, H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, mesg, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to create the message in object header")
+ } /* end if */
+ else {
+ if(!status)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "Message should exist")
- /* Double check we didn't overrun the block (unlikely) */
- HDassert(superblock_size <= sizeof(buf));
+ /* Update the message with ID in the superblock extension */
+ if(H5O_msg_write(&ext_loc, id, H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, mesg, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to write the message in object header")
+ } /* end else */
- /* Write superblock */
- if(H5FD_write(f->shared->lf, H5FD_MEM_SUPER, dxpl_id, f->shared->super_addr, superblock_size, buf) < 0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write superblock")
+ /* Close the superblock extension object header */
+ if(H5F_super_ext_close(f, &ext_loc) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension")
done:
+ /* Mark superblock dirty in cache, if necessary */
+ if(sblock_dirty)
+ if(H5AC_mark_pinned_or_protected_entry_dirty(f, f->shared->sblock) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty")
+
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5F_super_write() */
+} /* H5F_super_ext_write_msg() */
/*-------------------------------------------------------------------------
- * Function: H5F_super_ext_size
- * Get storage size of the superblock extension
+ * Function: H5F_super_ext_remove_msg
*
- * Return: Success: non-negative on success
- * Failure: Negative
+ * Purpose: Remove the message with ID from the superblock extension
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Feb 2009
*
- * Programmer: Vailin Choi
- * July 11, 2007
*
*-------------------------------------------------------------------------
*/
herr_t
-H5F_super_ext_size(H5F_t *f, hid_t dxpl_id, hsize_t *super_ext_size)
+H5F_super_ext_remove_msg(H5F_t *f, hid_t dxpl_id, unsigned id)
{
- H5O_loc_t ext_loc; /* "Object location" for superblock extension */
- H5O_info_t oinfo; /* Object info for superblock extension */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5F_super_ext_size, FAIL)
-
- /* Sanity check */
- HDassert(f);
- HDassert(super_ext_size);
-
- /* Set up "fake" object location for superblock extension */
- H5O_loc_reset(&ext_loc);
- ext_loc.file = f;
- ext_loc.addr = f->shared->extension_addr;
-
- /* Get object header info for superblock extension */
- if(H5O_get_info(&ext_loc, dxpl_id, FALSE, &oinfo) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve superblock extension info")
-
- /* Set the superblock extension size */
- *super_ext_size = oinfo.hdr.space.total;
+ htri_t status; /* Indicate whether the message exists or not */
+ H5O_loc_t ext_loc; /* "Object location" for superblock extension */
+ int null_count = 0; /* # of null messages */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5F_super_ext_remove_msg, FAIL)
+
+ /* Make sure that the superblock extension object header exists */
+ HDassert(H5F_addr_defined(f->shared->sblock->ext_addr));
+
+ /* Open superblock extension object header */
+ if(H5F_super_ext_open(f, f->shared->sblock->ext_addr, &ext_loc) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "error in starting file's superblock extension")
+
+ /* Check if message with ID exists in the object header */
+ if((status = H5O_msg_exists(&ext_loc, id, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to check object header for message")
+ else if(status) { /* message exists */
+ H5O_hdr_info_t hdr_info; /* Object header info for superblock extension */
+
+ /* Remove the message */
+ if(H5O_msg_remove(&ext_loc, id, H5O_ALL, TRUE, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete free-space manager info message")
+
+ /* Get info for the superblock extension's object header */
+ if(H5O_get_hdr_info(&ext_loc, dxpl_id, &hdr_info) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to retrieve superblock extension info")
+
+ /* If the object header is an empty base chunk, remove superblock extension */
+ if(hdr_info.nchunks == 1) {
+ if((null_count = H5O_msg_count(&ext_loc, H5O_NULL_ID, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to count messages")
+ else if((unsigned)null_count == hdr_info.nmesgs) {
+ HDassert(H5F_addr_defined(ext_loc.addr));
+ if(H5O_delete(f, dxpl_id, ext_loc.addr) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to count messages")
+ f->shared->sblock->ext_addr = HADDR_UNDEF;
+ } /* end if */
+ } /* end if */
+ } /* end if */
+ /* Close superblock extension object header */
+ if(H5F_super_ext_close(f, &ext_loc) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5F_super_ext_size() */
+} /* H5F_super_ext_remove_msg() */
diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c
new file mode 100644
index 0000000..d2aaef8
--- /dev/null
+++ b/src/H5Fsuper_cache.c
@@ -0,0 +1,920 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5FDprivate.h" /* File drivers */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5Gpkg.h" /* Groups */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Pprivate.h" /* Property lists */
+#include "H5SMprivate.h" /* Shared Object Header Messages */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* Maximum size of super-block buffers */
+#define H5F_MAX_SUPERBLOCK_SIZE 134
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* Metadata cache (H5AC) callbacks */
+static H5F_super_t *H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1, void *udata2);
+static herr_t H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5F_super_t *sblock);
+static herr_t H5F_sblock_dest(H5F_t *f, H5F_super_t * sblock);
+static herr_t H5F_sblock_clear(H5F_t *f, H5F_super_t *sblock, hbool_t destroy);
+static herr_t H5F_sblock_size(const H5F_t *f, const H5F_super_t *sblock, size_t *size_ptr);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* H5F inherits cache-like properties from H5AC */
+const H5AC_class_t H5AC_SUPERBLOCK[1] = {{
+ H5AC_SUPERBLOCK_ID,
+ (H5AC_load_func_t)H5F_sblock_load,
+ (H5AC_flush_func_t)H5F_sblock_flush,
+ (H5AC_dest_func_t)H5F_sblock_dest,
+ (H5AC_clear_func_t)H5F_sblock_clear,
+ (H5AC_notify_func_t)NULL,
+ (H5AC_size_func_t)H5F_sblock_size,
+}};
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/* Declare extern the free list to manage the H5F_super_t struct */
+H5FL_EXTERN(H5F_super_t);
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_sblock_load
+ *
+ * Purpose: Loads the superblock from the file, and deserializes
+ * its information into the H5F_super_t structure.
+ *
+ * Return: Success: SUCCEED
+ * Failure: NULL
+ *
+ * Programmer: Mike McGreevy
+ * mamcgree@hdfgroup.org
+ * April 8, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5F_super_t *
+H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, const void UNUSED *udata1,
+ void *udata2/*out*/)
+{
+ H5F_super_t *sblock = NULL; /* File's superblock */
+ haddr_t base_addr = HADDR_UNDEF; /* Base address of file */
+ uint8_t sbuf[H5F_MAX_SUPERBLOCK_SIZE]; /* Buffer for superblock */
+ H5P_genplist_t *c_plist; /* File creation property list */
+ H5F_file_t *shared; /* shared part of `file' */
+ H5FD_t *lf; /* file driver part of `shared' */
+ haddr_t stored_eoa; /*relative end-of-addr in file */
+ haddr_t eof; /*end of file address */
+ uint8_t sizeof_addr; /* Size of offsets in the file (in bytes) */
+ uint8_t sizeof_size; /* Size of lengths in the file (in bytes) */
+ const size_t fixed_size = H5F_SUPERBLOCK_FIXED_SIZE; /*fixed sizeof superblock */
+ size_t variable_size; /*variable sizeof superblock */
+ uint8_t *p; /* Temporary pointer into encoding buffer */
+ unsigned super_vers; /* Superblock version */
+ hbool_t *dirtied = (hbool_t *)udata2; /* Set up dirtied out value */
+ H5F_super_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5F_sblock_load)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_eq(addr, 0));
+
+ /* Short cuts */
+ shared = f->shared;
+ lf = shared->lf;
+
+ /* Get the shared file creation property list */
+ if(NULL == (c_plist = (H5P_genplist_t *)H5I_object(shared->fcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get property list")
+
+ /* Get the base address for the file in the VFD */
+ if(HADDR_UNDEF == (base_addr = H5FD_get_base_addr(lf)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "failed to get base address for file driver")
+
+ /* Allocate space for the superblock */
+ if(NULL == (sblock = H5FL_CALLOC(H5F_super_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Read fixed-size portion of the superblock */
+ p = sbuf;
+ if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, fixed_size) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
+ if(H5FD_read(lf, dxpl_id, H5FD_MEM_SUPER, (haddr_t)0, fixed_size, p) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock")
+
+ /* Skip over signature (already checked when locating the superblock) */
+ p += H5F_SIGNATURE_LEN;
+
+ /* Superblock version */
+ super_vers = *p++;
+ if(super_vers > HDF5_SUPERBLOCK_VERSION_LATEST)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad superblock version number")
+ if(H5P_set(c_plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set superblock version")
+
+ /* Record the superblock version */
+ sblock->super_vers = super_vers;
+
+ /* Sanity check */
+ HDassert(((size_t)(p - sbuf)) == fixed_size);
+
+ /* Determine the size of the variable-length part of the superblock */
+ variable_size = H5F_SUPERBLOCK_VARLEN_SIZE(super_vers, f);
+ HDassert(variable_size > 0);
+ HDassert(fixed_size + variable_size <= sizeof(sbuf));
+
+ /* Read in variable-sized portion of superblock */
+ if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, fixed_size + variable_size) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
+ if(H5FD_read(lf, dxpl_id, H5FD_MEM_SUPER, (haddr_t)fixed_size, variable_size, p) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read superblock")
+
+ /* Check for older version of superblock format */
+ if(super_vers < HDF5_SUPERBLOCK_VERSION_2) {
+ uint32_t status_flags; /* File status flags */
+ unsigned btree_k[H5B_NUM_BTREE_ID]; /* B-tree internal node 'K' values */
+ unsigned sym_leaf_k; /* Symbol table leaf node's 'K' value */
+
+ /* Freespace version (hard-wired) */
+ if(HDF5_FREESPACE_VERSION != *p++)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad free space version number")
+
+ /* Root group version number (hard-wired) */
+ if(HDF5_OBJECTDIR_VERSION != *p++)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad object directory version number")
+
+ /* Skip over reserved byte */
+ p++;
+
+ /* Shared header version number (hard-wired) */
+ if(HDF5_SHAREDHEADER_VERSION != *p++)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad shared-header format version number")
+
+ /* Size of file addresses */
+ sizeof_addr = *p++;
+ if(sizeof_addr != 2 && sizeof_addr != 4 &&
+ sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number in an address")
+ if(H5P_set(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &sizeof_addr) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number in an address")
+ shared->sizeof_addr = sizeof_addr; /* Keep a local copy also */
+
+ /* Size of file sizes */
+ sizeof_size = *p++;
+ if(sizeof_size != 2 && sizeof_size != 4 &&
+ sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number for object size")
+ if(H5P_set(c_plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number for object size")
+ shared->sizeof_size = sizeof_size; /* Keep a local copy also */
+
+ /* Skip over reserved byte */
+ p++;
+
+ /* Various B-tree sizes */
+ UINT16DECODE(p, sym_leaf_k);
+ if(sym_leaf_k == 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad symbol table leaf node 1/2 rank")
+ if(H5P_set(c_plist, H5F_CRT_SYM_LEAF_NAME, &sym_leaf_k) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set rank for symbol table leaf nodes")
+ sblock->sym_leaf_k = sym_leaf_k; /* Keep a local copy also */
+
+ /* Need 'get' call to set other array values */
+ if(H5P_get(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to get rank for btree internal nodes")
+ UINT16DECODE(p, btree_k[H5B_SNODE_ID]);
+ if(btree_k[H5B_SNODE_ID] == 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad 1/2 rank for btree internal nodes")
+ /*
+ * Delay setting the value in the property list until we've checked
+ * for the indexed storage B-tree internal 'K' value later.
+ */
+
+ /* File status flags (not really used yet) */
+ UINT32DECODE(p, status_flags);
+ HDassert(status_flags <= 255);
+ sblock->status_flags = (uint8_t)status_flags;
+ if(sblock->status_flags & ~H5F_SUPER_ALL_FLAGS)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad flag value for superblock")
+
+ /*
+ * If the superblock version # is greater than 0, read in the indexed
+ * storage B-tree internal 'K' value
+ */
+ if(super_vers > HDF5_SUPERBLOCK_VERSION_DEF) {
+ UINT16DECODE(p, btree_k[H5B_CHUNK_ID]);
+ /* Reserved bytes are present only in version 1 */
+ if(super_vers == HDF5_SUPERBLOCK_VERSION_1)
+ p += 2; /* reserved */
+ } /* end if */
+ else
+ btree_k[H5B_CHUNK_ID] = HDF5_BTREE_CHUNK_IK_DEF;
+
+ /* Set the B-tree internal node values, etc */
+ if(H5P_set(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set rank for btree internal nodes")
+ HDmemcpy(sblock->btree_k, btree_k, sizeof(unsigned) * (size_t)H5B_NUM_BTREE_ID); /* Keep a local copy also */
+
+ /* Remainder of "variable-sized" portion of superblock */
+ H5F_addr_decode(f, (const uint8_t **)&p, &sblock->base_addr/*out*/);
+ H5F_addr_decode(f, (const uint8_t **)&p, &sblock->ext_addr/*out*/);
+ H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/);
+ H5F_addr_decode(f, (const uint8_t **)&p, &sblock->driver_addr/*out*/);
+
+ /* Allocate space for the root group symbol table entry */
+ HDassert(!sblock->root_ent);
+ if(NULL == (sblock->root_ent = (H5G_entry_t *)H5MM_calloc(sizeof(H5G_entry_t))))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate space for root group symbol table entry")
+
+ /* decode the root group symbol table entry */
+ if(H5G_ent_decode(f, (const uint8_t **)&p, sblock->root_ent) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, NULL, "can't decode root group symbol table entry")
+
+ /* Set the root group address to the correct value */
+ sblock->root_addr = sblock->root_ent->header;
+
+ /*
+ * Check if superblock address is different from base address and
+ * adjust base address and "end of address" address if so.
+ */
+ if(!H5F_addr_eq(base_addr, sblock->base_addr)) {
+ /* Check if the superblock moved earlier in the file */
+ if(H5F_addr_lt(base_addr, sblock->base_addr))
+ stored_eoa -= (sblock->base_addr - base_addr);
+ else
+ /* The superblock moved later in the file */
+ stored_eoa += (base_addr - sblock->base_addr);
+
+ /* Adjust base address for offsets of the HDF5 data in the file */
+ sblock->base_addr = base_addr;
+
+ /* Set the base address for the file in the VFD now */
+ if(H5FD_set_base_addr(lf, sblock->base_addr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "failed to set base address for file driver")
+
+ /* Indicate that the superblock should be marked dirty */
+ *dirtied = TRUE;
+ } /* end if */
+
+ /* This step is for h5repart tool only. If user wants to change file driver
+ * from family to sec2 while using h5repart, set the driver address to
+ * undefined to let the library ignore the family driver information saved
+ * in the superblock.
+ */
+ if(H5F_HAS_FEATURE(f, H5FD_FEAT_IGNORE_DRVRINFO)) {
+ /* Eliminate the driver info */
+ sblock->driver_addr = HADDR_UNDEF;
+
+ /* Indicate that the superblock should be marked dirty */
+ *dirtied = TRUE;
+ } /* end if */
+
+ /* Decode the optional driver information block */
+ if(H5F_addr_defined(sblock->driver_addr)) {
+ uint8_t dbuf[H5F_MAX_DRVINFOBLOCK_SIZE]; /* Buffer for driver info block */
+ char drv_name[9]; /* Name of driver */
+ unsigned drv_vers; /* Version of driver info block */
+ size_t drv_variable_size; /* Size of variable-length portion of driver info block, in bytes */
+
+ /* Read in fixed-sized portion of driver info block */
+ p = dbuf;
+ if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, sblock->driver_addr + H5F_DRVINFOBLOCK_HDR_SIZE) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
+ if(H5FD_read(lf, dxpl_id, H5FD_MEM_SUPER, sblock->driver_addr, (size_t)H5F_DRVINFOBLOCK_HDR_SIZE, p) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read driver information block")
+
+ /* Version number */
+ drv_vers = *p++;
+ if(drv_vers != HDF5_DRIVERINFO_VERSION_0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad driver information block version number")
+
+ p += 3; /* reserved bytes */
+
+ /* Driver info size */
+ UINT32DECODE(p, drv_variable_size);
+
+ /* Sanity check */
+ HDassert(H5F_DRVINFOBLOCK_HDR_SIZE + drv_variable_size <= sizeof(dbuf));
+
+ /* Driver name and/or version */
+ HDstrncpy(drv_name, (const char *)p, (size_t)8);
+ drv_name[8] = '\0';
+ p += 8; /* advance past name/version */
+
+ /* Check if driver matches driver information saved. Unfortunately, we can't push this
+ * function to each specific driver because we're checking if the driver is correct.
+ */
+ if(!HDstrncmp(drv_name, "NCSAfami", (size_t)8) && HDstrcmp(lf->cls->name, "family"))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "family driver should be used")
+ if(!HDstrncmp(drv_name, "NCSAmult", (size_t)8) && HDstrcmp(lf->cls->name, "multi"))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "multi driver should be used")
+
+ /* Read in variable-sized portion of driver info block */
+ if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, sblock->driver_addr + H5F_DRVINFOBLOCK_HDR_SIZE + drv_variable_size) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
+ if(H5FD_read(lf, dxpl_id, H5FD_MEM_SUPER, sblock->driver_addr + H5F_DRVINFOBLOCK_HDR_SIZE, drv_variable_size, p) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read file driver information")
+
+ /* Decode driver information */
+ if(H5FD_sb_decode(lf, drv_name, p) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to decode driver information")
+ } /* end if */
+ } /* end if */
+ else {
+ uint32_t computed_chksum; /* Computed checksum */
+ uint32_t read_chksum; /* Checksum read from file */
+
+ /* Size of file addresses */
+ sizeof_addr = *p++;
+ if(sizeof_addr != 2 && sizeof_addr != 4 &&
+ sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number in an address")
+ if(H5P_set(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &sizeof_addr) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number in an address")
+ shared->sizeof_addr = sizeof_addr; /* Keep a local copy also */
+
+ /* Size of file sizes */
+ sizeof_size = *p++;
+ if(sizeof_size != 2 && sizeof_size != 4 &&
+ sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number for object size")
+ if(H5P_set(c_plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number for object size")
+ shared->sizeof_size = sizeof_size; /* Keep a local copy also */
+
+ /* File status flags (not really used yet) */
+ sblock->status_flags = *p++;
+ if(sblock->status_flags & ~H5F_SUPER_ALL_FLAGS)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad flag value for superblock")
+
+ /* Base, superblock extension, end of file & root group object header addresses */
+ H5F_addr_decode(f, (const uint8_t **)&p, &sblock->base_addr/*out*/);
+ H5F_addr_decode(f, (const uint8_t **)&p, &sblock->ext_addr/*out*/);
+ H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/);
+ H5F_addr_decode(f, (const uint8_t **)&p, &sblock->root_addr/*out*/);
+
+ /* Compute checksum for superblock */
+ computed_chksum = H5_checksum_metadata(sbuf, (size_t)(p - sbuf), 0);
+
+ /* Decode checksum */
+ UINT32DECODE(p, read_chksum);
+
+ /* Verify correct checksum */
+ if(read_chksum != computed_chksum)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad checksum on driver information block")
+
+ /*
+ * Check if superblock address is different from base address and
+ * adjust base address and "end of address" address if so.
+ */
+ if(!H5F_addr_eq(base_addr, sblock->base_addr)) {
+ /* Check if the superblock moved earlier in the file */
+ if(H5F_addr_lt(base_addr, sblock->base_addr))
+ stored_eoa -= (sblock->base_addr - base_addr);
+ else
+ /* The superblock moved later in the file */
+ stored_eoa += (base_addr - sblock->base_addr);
+
+ /* Adjust base address for offsets of the HDF5 data in the file */
+ sblock->base_addr = base_addr;
+
+ /* Set the base address for the file in the VFD now */
+ if(H5FD_set_base_addr(lf, sblock->base_addr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "failed to set base address for file driver")
+
+ /* Indicate that the superblock should be marked dirty */
+ *dirtied = TRUE;
+ } /* end if */
+
+ /* Get the B-tree internal node values, etc */
+ if(H5P_get(c_plist, H5F_CRT_BTREE_RANK_NAME, sblock->btree_k) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to get rank for btree internal nodes")
+ } /* end else */
+
+ /*
+ * The user-defined data is the area of the file before the base
+ * address.
+ */
+ if(H5P_set(c_plist, H5F_CRT_USER_BLOCK_NAME, &sblock->base_addr) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set userblock size")
+
+ /*
+ * Make sure that the data is not truncated. One case where this is
+ * possible is if the first file of a family of files was opened
+ * individually.
+ */
+ if(HADDR_UNDEF == (eof = H5FD_get_eof(lf)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to determine file size")
+
+ /* (Account for the stored EOA being absolute offset -QAK) */
+ if((eof + sblock->base_addr) < stored_eoa)
+ HGOTO_ERROR(H5E_FILE, H5E_TRUNCATED, NULL, "truncated file")
+
+ /*
+ * Tell the file driver how much address space has already been
+ * allocated so that it knows how to allocate additional memory.
+ */
+ /* (Account for the stored EOA being absolute offset -NAF) */
+ if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, stored_eoa - sblock->base_addr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to set end-of-address marker for file")
+
+ /* Read the file's superblock extension, if there is one. */
+ if(H5F_addr_defined(sblock->ext_addr)) {
+ H5O_loc_t ext_loc; /* "Object location" for superblock extension */
+ H5O_btreek_t btreek; /* v1 B-tree 'K' value message from superblock extension */
+ H5O_drvinfo_t drvinfo; /* Driver info message from superblock extension */
+ size_t u; /* Local index variable */
+ htri_t status; /* Status for message existing */
+
+ /* Sanity check - superblock extension should only be defined for
+ * superblock version >= 2.
+ */
+ HDassert(super_vers >= HDF5_SUPERBLOCK_VERSION_2);
+
+ /* Check for superblock extension being located "outside" the stored
+ * 'eoa' value, which can occur with the split/multi VFD.
+ */
+ if(H5F_addr_gt(sblock->ext_addr, stored_eoa)) {
+ /* Set the 'eoa' for the object header memory type large enough
+ * to give some room for a reasonably sized superblock extension.
+ * (This is _rather_ a kludge -QAK)
+ */
+ if(H5FD_set_eoa(lf, H5FD_MEM_OHDR, (haddr_t)(sblock->ext_addr + 1024)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to set end-of-address marker for file")
+ } /* end if */
+
+ /* Open the superblock extension */
+ if(H5F_super_ext_open(f, sblock->ext_addr, &ext_loc) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, NULL, "unable to open file's superblock extension")
+
+ /* Check for the extension having a 'driver info' message */
+ if((status = H5O_msg_exists(&ext_loc, H5O_DRVINFO_ID, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to read object header")
+ if(status) {
+ /* Check for ignoring the driver info for this file */
+ if(H5F_HAS_FEATURE(f, H5FD_FEAT_IGNORE_DRVRINFO)) {
+ /* Indicate that the superblock should be marked dirty */
+ *dirtied = TRUE;
+ } /* end if */
+ else {
+ /* Retrieve the 'driver info' structure */
+ if(NULL == H5O_msg_read(&ext_loc, H5O_DRVINFO_ID, &drvinfo, dxpl_id))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "driver info message not present")
+
+ /* Check if driver matches driver information saved. Unfortunately, we can't push this
+ * function to each specific driver because we're checking if the driver is correct.
+ */
+ if(!HDstrncmp(drvinfo.name, "NCSAfami", (size_t)8) && HDstrcmp(lf->cls->name, "family"))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "family driver should be used")
+ if(!HDstrncmp(drvinfo.name, "NCSAmult", (size_t)8) && HDstrcmp(lf->cls->name, "multi"))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "multi driver should be used")
+
+ /* Decode driver information */
+ if(H5FD_sb_decode(lf, drvinfo.name, drvinfo.buf) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to decode driver information")
+
+ /* Reset driver info message */
+ H5O_msg_reset(H5O_DRVINFO_ID, &drvinfo);
+ } /* end else */
+ } /* end if */
+
+ /* Read in the shared OH message information if there is any */
+ if(H5SM_get_info(&ext_loc, c_plist, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read SOHM table information")
+
+ /* Check for the extension having a 'v1 B-tree "K"' message */
+ if((status = H5O_msg_exists(&ext_loc, H5O_BTREEK_ID, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to read object header")
+ if(status) {
+ /* Retrieve the 'v1 B-tree "K"' structure */
+ if(NULL == H5O_msg_read(&ext_loc, H5O_BTREEK_ID, &btreek, dxpl_id))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "v1 B-tree 'K' info message not present")
+
+ /* Set non-default v1 B-tree 'K' value info from file */
+ sblock->btree_k[H5B_CHUNK_ID] = btreek.btree_k[H5B_CHUNK_ID];
+ sblock->btree_k[H5B_SNODE_ID] = btreek.btree_k[H5B_SNODE_ID];
+ sblock->sym_leaf_k = btreek.sym_leaf_k;
+
+ /* Set non-default v1 B-tree 'K' values in the property list */
+ if(H5P_set(c_plist, H5F_CRT_BTREE_RANK_NAME, btreek.btree_k) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set rank for btree internal nodes")
+ if(H5P_set(c_plist, H5F_CRT_SYM_LEAF_NAME, &btreek.sym_leaf_k) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set rank for symbol table leaf nodes")
+ } /* end if */
+ else {
+ /* No non-default v1 B-tree 'K' value info in file, use defaults */
+ sblock->btree_k[H5B_CHUNK_ID] = HDF5_BTREE_CHUNK_IK_DEF;
+ sblock->btree_k[H5B_SNODE_ID] = HDF5_BTREE_SNODE_IK_DEF;
+ sblock->sym_leaf_k = H5F_CRT_SYM_LEAF_DEF;
+ } /* end if */
+
+ /* Check for the extension having a 'free-space manager info' message */
+ if((status = H5O_msg_exists(&ext_loc, H5O_FSINFO_ID, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to check object header")
+ if(status) {
+ H5O_fsinfo_t fsinfo; /* Free-space manager info message from superblock extension */
+
+ /* Retrieve the 'free-space manager info' structure */
+ if(NULL == H5O_msg_read(&ext_loc, H5O_FSINFO_ID, &fsinfo, dxpl_id))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "unable to get free-space manager info message")
+
+ if(shared->fs_strategy != fsinfo.strategy) {
+ shared->fs_strategy = fsinfo.strategy;
+
+ /* Set non-default strategy in the property list */
+ if(H5P_set(c_plist, H5F_CRT_FILE_SPACE_STRATEGY_NAME, &fsinfo.strategy) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "unable to set file space strategy")
+ } /* end if */
+ if(shared->fs_threshold != fsinfo.threshold) {
+ shared->fs_threshold = fsinfo.threshold;
+
+ /* Set non-default threshold in the property list */
+ if(H5P_set(c_plist, H5F_CRT_FREE_SPACE_THRESHOLD_NAME, &fsinfo.threshold) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "unable to set file space strategy")
+ } /* end if */
+
+ /* set free-space manager addresses */
+ shared->fs_addr[0] = HADDR_UNDEF;
+ for(u = 1; u < NELMTS(f->shared->fs_addr); u++)
+ shared->fs_addr[u] = fsinfo.fs_addr[u-1];
+ } /* end if */
+ else {
+ for(u = 0; u < NELMTS(f->shared->fs_addr); u++)
+ shared->fs_addr[u] = HADDR_UNDEF;
+ } /* end else */
+
+ /* Close superblock extension */
+ if(H5F_super_ext_close(f, &ext_loc) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, NULL, "unable to close file's superblock extension")
+ } /* end if */
+
+ /* Set return value */
+ ret_value = sblock;
+
+done:
+ /* Release the [possibly partially initialized] superblock on errors */
+ if(!ret_value && sblock)
+ if(H5F_sblock_dest(f, sblock) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTFREE, NULL, "unable to destroy superblock data")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_sblock_load() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_sblock_flush
+ *
+ * Purpose: Flushes the superblock.
+ *
+ * Return: Success: SUCCEED
+ * Failure: NULL
+ *
+ * Programmer: Mike McGreevy
+ * mamcgree@hdfgroup.org
+ * April 8, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t UNUSED addr,
+ H5F_super_t *sblock)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5F_sblock_flush)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_eq(addr, 0));
+ HDassert(sblock);
+
+ if(sblock->cache_info.is_dirty) {
+ uint8_t buf[H5F_MAX_SUPERBLOCK_SIZE + H5F_MAX_DRVINFOBLOCK_SIZE]; /* Superblock & driver info blockencoding buffer */
+ uint8_t *p; /* Ptr into encoding buffer */
+ haddr_t rel_eoa; /* Relative EOA for file */
+ size_t superblock_size; /* Size of superblock, in bytes */
+ size_t driver_size; /* Size of driver info block (bytes)*/
+
+ /* Encode the common portion of the file superblock for all versions */
+ p = buf;
+ HDmemcpy(p, H5F_SIGNATURE, (size_t)H5F_SIGNATURE_LEN);
+ p += H5F_SIGNATURE_LEN;
+ *p++ = (uint8_t)sblock->super_vers;
+
+ /* Check for older version of superblock format */
+ if(sblock->super_vers < HDF5_SUPERBLOCK_VERSION_2) {
+ *p++ = (uint8_t)HDF5_FREESPACE_VERSION; /* (hard-wired) */
+ *p++ = (uint8_t)HDF5_OBJECTDIR_VERSION; /* (hard-wired) */
+ *p++ = 0; /* reserved*/
+
+ *p++ = (uint8_t)HDF5_SHAREDHEADER_VERSION; /* (hard-wired) */
+ HDassert(H5F_SIZEOF_ADDR(f) <= 255);
+ *p++ = (uint8_t)H5F_SIZEOF_ADDR(f);
+ HDassert(H5F_SIZEOF_SIZE(f) <= 255);
+ *p++ = (uint8_t)H5F_SIZEOF_SIZE(f);
+ *p++ = 0; /* reserved */
+
+ UINT16ENCODE(p, sblock->sym_leaf_k);
+ UINT16ENCODE(p, sblock->btree_k[H5B_SNODE_ID]);
+ UINT32ENCODE(p, (uint32_t)sblock->status_flags);
+
+ /*
+ * Versions of the superblock >0 have the indexed storage B-tree
+ * internal 'K' value stored
+ */
+ if(sblock->super_vers > HDF5_SUPERBLOCK_VERSION_DEF) {
+ UINT16ENCODE(p, sblock->btree_k[H5B_CHUNK_ID]);
+ *p++ = 0; /*reserved */
+ *p++ = 0; /*reserved */
+ } /* end if */
+
+ H5F_addr_encode(f, &p, sblock->base_addr);
+ H5F_addr_encode(f, &p, sblock->ext_addr);
+ rel_eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_SUPER);
+ H5F_addr_encode(f, &p, (rel_eoa + sblock->base_addr));
+ H5F_addr_encode(f, &p, sblock->driver_addr);
+
+ /* Encode the root group object entry, including the cached stab info */
+ if(H5G_ent_encode(f, &p, sblock->root_ent) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTENCODE, FAIL, "can't encode root group symbol table entry")
+
+ /* Encode the driver information block. */
+ H5_ASSIGN_OVERFLOW(driver_size, H5FD_sb_size(f->shared->lf), hsize_t, size_t);
+
+ /* Checking whether driver block address is defined here is to handle backward
+ * compatibility. If the file was created with v1.6 library or earlier and no
+ * driver info block was written in the superblock, we don't write it either even
+ * though there's some driver info. Otherwise, the driver block extended will
+ * overwrite the (meta)data right after the superblock. This situation happens to
+ * the family driver particularly. SLU - 2009/3/24
+ */
+ if(driver_size > 0 && H5F_addr_defined(sblock->driver_addr)) {
+ char driver_name[9]; /* Name of driver, for driver info block */
+ uint8_t *dbuf = p; /* Pointer to beginning of driver info */
+
+ /* Encode the driver information block */
+ *p++ = HDF5_DRIVERINFO_VERSION_0; /* Version */
+ *p++ = 0; /* reserved */
+ *p++ = 0; /* reserved */
+ *p++ = 0; /* reserved */
+
+ /* Driver info size, excluding header */
+ UINT32ENCODE(p, driver_size);
+
+ /* Encode driver-specific data */
+ if(H5FD_sb_encode(f->shared->lf, driver_name, dbuf + H5F_DRVINFOBLOCK_HDR_SIZE) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to encode driver information")
+
+ /* Store driver name (set in 'H5FD_sb_encode' call above) */
+ HDmemcpy(p, driver_name, (size_t)8);
+
+ /* Advance buffer pointer past name & variable-sized portion of driver info */
+ /* (for later use in computing the superblock size) */
+ p += 8 + driver_size;
+ } /* end if */
+ } /* end if */
+ else {
+ uint32_t chksum; /* Checksum temporary variable */
+ H5O_loc_t *root_oloc; /* Pointer to root group's object location */
+
+ /* Size of file addresses & offsets, and status flags */
+ HDassert(H5F_SIZEOF_ADDR(f) <= 255);
+ *p++ = (uint8_t)H5F_SIZEOF_ADDR(f);
+ HDassert(H5F_SIZEOF_SIZE(f) <= 255);
+ *p++ = (uint8_t)H5F_SIZEOF_SIZE(f);
+ *p++ = sblock->status_flags;
+
+ /* Base, superblock extension & end of file addresses */
+ H5F_addr_encode(f, &p, sblock->base_addr);
+ H5F_addr_encode(f, &p, sblock->ext_addr);
+ rel_eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_SUPER);
+ H5F_addr_encode(f, &p, (rel_eoa + sblock->base_addr));
+
+ /* Retrieve information for root group */
+ if(NULL == (root_oloc = H5G_oloc(f->shared->root_grp)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to retrieve root group information")
+
+ /* Encode address of root group's object header */
+ H5F_addr_encode(f, &p, root_oloc->addr);
+
+ /* Compute superblock checksum */
+ chksum = H5_checksum_metadata(buf, (H5F_SUPERBLOCK_SIZE(sblock->super_vers, f) - H5F_SIZEOF_CHKSUM), 0);
+
+ /* Superblock checksum */
+ UINT32ENCODE(p, chksum);
+
+ /* Sanity check */
+ HDassert((size_t)(p - buf) == H5F_SUPERBLOCK_SIZE(sblock->super_vers, f));
+ } /* end else */
+
+ /* Retrieve the total size of the superblock info */
+ H5_ASSIGN_OVERFLOW(superblock_size, (p - buf), int, size_t);
+
+ /* Double check we didn't overrun the block (unlikely) */
+ HDassert(superblock_size <= sizeof(buf));
+
+ /* Write superblock */
+ /* (always at relative address 0) */
+ if(H5FD_write(f->shared->lf, dxpl_id, H5FD_MEM_SUPER, (haddr_t)0, superblock_size, buf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write superblock")
+
+ /* Check for newer version of superblock format & superblock extension */
+ if(sblock->super_vers >= HDF5_SUPERBLOCK_VERSION_2 && H5F_addr_defined(sblock->ext_addr)) {
+ /* Check for ignoring the driver info for this file */
+ if(!H5F_HAS_FEATURE(f, H5FD_FEAT_IGNORE_DRVRINFO)) {
+ /* Check for driver info message */
+ H5_ASSIGN_OVERFLOW(driver_size, H5FD_sb_size(f->shared->lf), hsize_t, size_t);
+ if(driver_size > 0) {
+ H5O_drvinfo_t drvinfo; /* Driver info */
+ H5O_loc_t ext_loc; /* "Object location" for superblock extension */
+ uint8_t dbuf[H5F_MAX_DRVINFOBLOCK_SIZE]; /* Driver info block encoding buffer */
+
+ /* Sanity check */
+ HDassert(driver_size <= H5F_MAX_DRVINFOBLOCK_SIZE);
+
+ /* Encode driver-specific data */
+ if(H5FD_sb_encode(f->shared->lf, drvinfo.name, dbuf) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to encode driver information")
+
+ /* Open the superblock extension's object header */
+ if(H5F_super_ext_open(f, sblock->ext_addr, &ext_loc) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open file's superblock extension")
+
+ /* Write driver info information to the superblock extension */
+ drvinfo.len = driver_size;
+ drvinfo.buf = dbuf;
+ if(H5O_msg_write(&ext_loc, H5O_DRVINFO_ID, H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, &drvinfo, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "unable to update driver info header message")
+
+ /* Close the superblock extension object header */
+ if(H5F_super_ext_close(f, &ext_loc) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close file's superblock extension")
+ } /* end if */
+ } /* end if */
+ } /* end if */
+
+ /* Reset the dirty flag. */
+ sblock->cache_info.is_dirty = FALSE;
+ } /* end if */
+
+ if(destroy)
+ if(H5F_sblock_dest(f, sblock) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CLOSEERROR, FAIL, "can't close superblock")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_sblock_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_sblock_dest
+ *
+ * Purpose: Frees memory used by the superblock.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mike McGreevy
+ * April 8, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_sblock_dest(H5F_t UNUSED *f, H5F_super_t* sblock)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_sblock_dest)
+
+ /* Sanity check */
+ HDassert(sblock);
+
+ /* Free root group symbol table entry, if any */
+ sblock->root_ent = (H5G_entry_t *)H5MM_xfree(sblock->root_ent);
+
+ /* Free superblock */
+ sblock = (H5F_super_t *)H5FL_FREE(H5F_super_t, sblock);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5F_sblock_dest() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_sblock_clear
+ *
+ * Purpose: Mark the superblock as no longer being dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mike McGreevy
+ * April 8, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_sblock_clear(H5F_t *f, H5F_super_t *sblock, hbool_t destroy)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5F_sblock_clear)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(sblock);
+
+ /* Reset the dirty flag. */
+ sblock->cache_info.is_dirty = FALSE;
+
+ if(destroy)
+ if(H5F_sblock_dest(f, sblock) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "unable to delete superblock")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_sblock_clear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_sblock_size
+ *
+ * Purpose: Returns the size of the superblock encoded on disk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mike McGreevy
+ * April 8, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_sblock_size(const H5F_t *f, const H5F_super_t *sblock, size_t *size_ptr)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_sblock_size)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(sblock);
+ HDassert(size_ptr);
+
+ /* Set size value */
+ *size_ptr = H5F_SUPERBLOCK_SIZE(sblock->super_vers, f);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5F_sblock_size() */
+
diff --git a/src/H5Ftest.c b/src/H5Ftest.c
index 67ea5f7..e2ee606 100644
--- a/src/H5Ftest.c
+++ b/src/H5Ftest.c
@@ -32,6 +32,8 @@
#define H5F_TESTING /*suppress warning about H5F testing funcs*/
#define H5SM_PACKAGE /*suppress error about including H5SMpkg */
#define H5SM_TESTING /*suppress warning about H5SM testing funcs*/
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+#define H5G_TESTING /*suppress warning about H5G testing funcs*/
/***********/
@@ -40,6 +42,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
+#include "H5Gpkg.h" /* Groups */
#include "H5Iprivate.h" /* IDs */
#include "H5SMpkg.h" /* Shared object header messages */
@@ -102,7 +105,7 @@ H5F_get_sohm_mesg_count_test(hid_t file_id, unsigned type_id,
FUNC_ENTER_NOAPI_NOINIT(H5F_get_sohm_mesg_count_test)
/* Check arguments */
- if(NULL == (file = H5I_object_verify(file_id, H5I_FILE)))
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
/* Retrieve count for message type */
@@ -113,3 +116,73 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_get_sohm_mesg_count_test() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_check_cached_stab_test
+ *
+ * Purpose: Check that a file's superblock contains a cached symbol
+ * table entry, that the entry matches that in the root
+ * group's object header, and check that the addresses are
+ * valid.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Neil Fortner
+ * Mar 31, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_check_cached_stab_test(hid_t file_id)
+{
+ H5F_t *file; /* File info */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5F_check_cached_stab_test)
+
+ /* Check arguments */
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
+
+ /* Verify the cached stab info */
+ if(H5G_verify_cached_stab_test(H5G_oloc(file->shared->root_grp), file->shared->sblock->root_ent) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to verify cached symbol table info")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_check_cached_stab_test() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_maxaddr_test
+ *
+ * Purpose: Retrieve the maximum address for a file
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Jun 10, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_get_maxaddr_test(hid_t file_id, haddr_t *maxaddr)
+{
+ H5F_t *file; /* File info */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5F_get_maxaddr_test)
+
+ /* Check arguments */
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
+
+ /* Retrieve maxaddr for file */
+ *maxaddr = file->shared->maxaddr;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_get_maxaddr_test() */
+
diff --git a/src/H5G.c b/src/H5G.c
index 3a57fa7..204245a 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -209,7 +209,7 @@ H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id,
/* Create the new group & get its ID */
if(NULL == (grp = H5G_create_named(&loc, name, lcpl_id, gcpl_id, gapl_id, H5AC_dxpl_id)))
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group")
- if((ret_value = H5I_register(H5I_GROUP, grp)) < 0)
+ if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
done:
@@ -267,7 +267,7 @@ H5G_create_named(const H5G_loc_t *loc, const char *name, hid_t lcpl_id,
HDassert(ocrt_info.new_obj);
/* Set the return value */
- ret_value = ocrt_info.new_obj;
+ ret_value = (H5G_t *)ocrt_info.new_obj;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -340,7 +340,7 @@ H5Gcreate_anon(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id)
/* Create the new group & get its ID */
if(NULL == (grp = H5G_create(loc.oloc->file, gcpl_id, H5AC_dxpl_id)))
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group")
- if((ret_value = H5I_register(H5I_GROUP, grp)) < 0)
+ if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
done:
@@ -397,7 +397,7 @@ H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
/* Register an ID for the group */
- if((ret_value = H5I_register(H5I_GROUP, grp)) < 0)
+ if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
done:
@@ -429,8 +429,10 @@ done:
hid_t
H5Gget_create_plist(hid_t group_id)
{
- htri_t ginfo_exists = 0;
- htri_t linfo_exists = 0;
+ H5O_linfo_t linfo; /* Link info message */
+ htri_t ginfo_exists;
+ htri_t linfo_exists;
+ htri_t pline_exists;
H5G_t *grp = NULL;
H5P_genplist_t *gcpl_plist;
H5P_genplist_t *new_plist;
@@ -441,15 +443,15 @@ H5Gget_create_plist(hid_t group_id)
H5TRACE1("i", "i", group_id);
/* Check args */
- if(NULL == (grp = H5I_object_verify(group_id, H5I_GROUP)))
+ if(NULL == (grp = (H5G_t *)H5I_object_verify(group_id, H5I_GROUP)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
/* Copy the default group creation property list */
- if(NULL == (gcpl_plist = H5I_object(H5P_LST_GROUP_CREATE_g)))
+ if(NULL == (gcpl_plist = (H5P_genplist_t *)H5I_object(H5P_LST_GROUP_CREATE_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get default group creation property list")
- if((new_gcpl_id = H5P_copy_plist(gcpl_plist)) < 0)
+ if((new_gcpl_id = H5P_copy_plist(gcpl_plist, TRUE)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to copy the creation property list")
- if(NULL == (new_plist = H5I_object(new_gcpl_id)))
+ if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_gcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
/* Retrieve any object creation properties */
@@ -472,27 +474,36 @@ H5Gget_create_plist(hid_t group_id)
} /* end if */
/* Check for the group having a link info message */
- if((linfo_exists = H5O_msg_exists(&(grp->oloc), H5O_LINFO_ID, H5AC_ind_dxpl_id)) < 0)
+ if((linfo_exists = H5G_obj_get_linfo(&(grp->oloc), &linfo, H5AC_ind_dxpl_id)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header")
if(linfo_exists) {
- H5O_linfo_t linfo; /* Link info message */
-
- /* Read the link info */
- if(NULL == H5G_obj_get_linfo(&(grp->oloc), &linfo, H5AC_ind_dxpl_id))
- HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link info")
-
/* Set the link info for the property list */
if(H5P_set(new_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set link info")
} /* end if */
+ /* Check for the group having a pipeline message */
+ if((pline_exists = H5O_msg_exists(&(grp->oloc), H5O_PLINE_ID, H5AC_ind_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read object header")
+ if(pline_exists) {
+ H5O_pline_t pline; /* Pipeline message */
+
+ /* Read the pipeline */
+ if(NULL == H5O_msg_read(&(grp->oloc), H5O_PLINE_ID, &pline, H5AC_ind_dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link pipeline")
+
+ /* Set the pipeline for the property list */
+ if(H5P_set(new_plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set link pipeline")
+ } /* end if */
+
/* Set the return value */
ret_value = new_gcpl_id;
done:
if(ret_value < 0) {
if(new_gcpl_id > 0)
- (void)H5I_dec_ref(new_gcpl_id);
+ (void)H5I_dec_ref(new_gcpl_id, TRUE);
} /* end if */
FUNC_LEAVE_API(ret_value)
@@ -702,7 +713,7 @@ H5Gclose(hid_t group_id)
* Decrement the counter on the group atom. It will be freed if the count
* reaches zero.
*/
- if(H5I_dec_ref(group_id) < 0)
+ if(H5I_dec_ref(group_id, TRUE) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group")
done:
@@ -803,7 +814,7 @@ H5G_term_interface(void)
if(H5_interface_initialize_g) {
if((n = H5I_nmembers(H5I_GROUP)))
- H5I_clear_type(H5I_GROUP, FALSE);
+ H5I_clear_type(H5I_GROUP, FALSE, FALSE);
else {
/* Destroy the group object id group */
H5I_dec_type_ref(H5I_GROUP);
@@ -822,123 +833,6 @@ H5G_term_interface(void)
/*-------------------------------------------------------------------------
- * Function: H5G_mkroot
- *
- * Purpose: Creates a root group in an empty file and opens it. If a
- * root group is already open then this function immediately
- * returns. If ENT is non-null then it's the symbol table
- * entry for an existing group which will be opened as the root
- * group. Otherwise a new root group is created and then
- * opened.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 11 1997
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *loc)
-{
- H5O_loc_t new_root_oloc; /* New root object location */
- H5G_name_t new_root_path; /* New root path */
- H5G_loc_t new_root_loc; /* New root location information */
- H5G_loc_t root_loc; /* Root location information */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5G_mkroot, FAIL)
-
- /* check args */
- HDassert(f);
-
- /* Check if the root group is already initialized */
- if(f->shared->root_grp)
- HGOTO_DONE(SUCCEED)
-
- /* Create information needed for group nodes */
- if(H5G_node_init(f) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group node info")
-
- /*
- * If there is no root object then create one. The root group always starts
- * with a hard link count of one since it's pointed to by the superblock.
- */
- if(loc == NULL) {
- H5P_genplist_t *fc_plist; /* File creation property list */
- H5O_ginfo_t ginfo; /* Group info parameters */
- H5O_linfo_t linfo; /* Link info parameters */
-
- /* Get the file creation property list */
- /* (Which is a sub-class of the group creation property class) */
- if(NULL == (fc_plist = H5I_object(f->shared->fcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
-
- /* Get the group info property */
- if(H5P_get(fc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get group info")
-
- /* Get the link info property */
- if(H5P_get(fc_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get link info")
-
- /* Set up group location for root group */
- new_root_loc.oloc = &new_root_oloc;
- new_root_loc.path = &new_root_path;
- H5G_loc_reset(&new_root_loc);
- loc = &new_root_loc;
-
- /* Create root group */
- if(H5G_obj_create(f, dxpl_id, &ginfo, &linfo, f->shared->fcpl_id, loc->oloc/*out*/) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry")
- if(1 != H5O_link(loc->oloc, 1, dxpl_id))
- HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "internal error (wrong link count)")
- } /* end if */
- else {
- /*
- * Open the root object as a group.
- */
- if(H5O_open(loc->oloc) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open root group")
- } /* end else */
-
- /* Create the path names for the root group's entry */
- H5G_name_init(loc->path, "/");
-
- /*
- * Create the group pointer. Also decrement the open object count so we
- * don't count the root group as an open object. The root group will
- * never be closed.
- */
- if(NULL == (f->shared->root_grp = H5FL_CALLOC(H5G_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- if(NULL == (f->shared->root_grp->shared = H5FL_CALLOC(H5G_shared_t))) {
- H5FL_FREE(H5G_t, f->shared->root_grp);
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- } /* end if */
-
- /* Shallow copy (take ownership) of the group object info */
- root_loc.oloc = &(f->shared->root_grp->oloc);
- root_loc.path = &(f->shared->root_grp->path);
- if(H5G_loc_copy(&root_loc, loc, H5_COPY_SHALLOW) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "can't copy group object location")
-
- f->shared->root_grp->shared->fo_count = 1;
- /* The only other open object should be the superblock extension, if it
- * exists. Don't count either the superblock extension or the root group
- * in the number of open objects in the file.
- */
- HDassert((1 == f->nopen_objs) ||
- (2 == f->nopen_objs && HADDR_UNDEF != f->shared->extension_addr));
- f->nopen_objs--;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_mkroot() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5G_create
*
* Purpose: Creates a new empty group with the specified name. The name
@@ -960,9 +854,6 @@ H5G_t *
H5G_create(H5F_t *file, hid_t gcpl_id, hid_t dxpl_id)
{
H5G_t *grp = NULL; /*new group */
- H5P_genplist_t *gc_plist; /* Property list created */
- H5O_ginfo_t ginfo; /* Group info */
- H5O_linfo_t linfo; /* Link info */
unsigned oloc_init = 0; /* Flag to indicate that the group object location was created successfully */
H5G_t *ret_value; /* Return value */
@@ -979,20 +870,8 @@ H5G_create(H5F_t *file, hid_t gcpl_id, hid_t dxpl_id)
if(NULL == (grp->shared = H5FL_CALLOC(H5G_shared_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- /* Get the property list */
- if(NULL == (gc_plist = H5I_object(gcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list")
-
- /* Get the group info property */
- if(H5P_get(gc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get group info")
-
- /* Get the link info property */
- if(H5P_get(gc_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get group info")
-
/* Create the group object header */
- if(H5G_obj_create(file, dxpl_id, &ginfo, &linfo, gcpl_id, &(grp->oloc)/*out*/) < 0)
+ if(H5G_obj_create(file, dxpl_id, gcpl_id, &(grp->oloc)/*out*/) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create group object header")
oloc_init = 1; /* Indicate that the object location information is valid */
@@ -1004,7 +883,7 @@ H5G_create(H5F_t *file, hid_t gcpl_id, hid_t dxpl_id)
/* Set the count of times the object is opened */
grp->shared->fo_count = 1;
-
+
/* Set return value */
ret_value = grp;
@@ -1019,8 +898,8 @@ done:
} /* end if */
if(grp != NULL) {
if(grp->shared != NULL)
- H5FL_FREE(H5G_shared_t, grp->shared);
- H5FL_FREE(H5G_t,grp);
+ (void)H5FL_FREE(H5G_shared_t, grp->shared);
+ (void)H5FL_FREE(H5G_t,grp);
} /* end if */
} /* end if */
@@ -1130,7 +1009,7 @@ H5G_open(const H5G_loc_t *loc, hid_t dxpl_id)
HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "can't copy path")
/* Check if group was already open */
- if((shared_fo = H5FO_opened(grp->oloc.file, grp->oloc.addr)) == NULL) {
+ if((shared_fo = (H5G_shared_t *)H5FO_opened(grp->oloc.file, grp->oloc.addr)) == NULL) {
/* Clear any errors from H5FO_opened() */
H5E_clear_stack(NULL);
@@ -1141,7 +1020,7 @@ H5G_open(const H5G_loc_t *loc, hid_t dxpl_id)
/* Add group to list of open objects in file */
if(H5FO_insert(grp->oloc.file, grp->oloc.addr, grp->shared, FALSE) < 0) {
- H5FL_FREE(H5G_shared_t, grp->shared);
+ (void)H5FL_FREE(H5G_shared_t, grp->shared);
HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group into list of open objects")
} /* end if */
@@ -1178,7 +1057,7 @@ done:
if(!ret_value && grp) {
H5O_loc_free(&(grp->oloc));
H5G_name_free(&(grp->path));
- H5FL_FREE(H5G_t,grp);
+ (void)H5FL_FREE(H5G_t,grp);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -1230,7 +1109,7 @@ done:
if(obj_opened)
H5O_close(&(grp->oloc));
if(grp->shared)
- H5FL_FREE(H5G_shared_t, grp->shared);
+ (void)H5FL_FREE(H5G_shared_t, grp->shared);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -1272,7 +1151,7 @@ H5G_close(H5G_t *grp)
HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't remove group from list of open objects")
if(H5O_close(&(grp->oloc)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close")
- H5FL_FREE(H5G_shared_t, grp->shared);
+ (void)H5FL_FREE(H5G_shared_t, grp->shared);
} else {
/* Decrement the ref. count for this object in the top file */
if(H5FO_top_decr(grp->oloc.file, grp->oloc.addr) < 0)
@@ -1294,11 +1173,11 @@ H5G_close(H5G_t *grp)
} /* end else */
if(H5G_name_free(&(grp->path)) < 0) {
- H5FL_FREE(H5G_t,grp);
+ (void)H5FL_FREE(H5G_t, grp);
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't free group entry name")
} /* end if */
- H5FL_FREE(H5G_t,grp);
+ (void)H5FL_FREE(H5G_t, grp);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1329,8 +1208,8 @@ H5G_free(H5G_t *grp)
HDassert(grp && grp->shared);
- H5FL_FREE(H5G_shared_t, grp->shared);
- H5FL_FREE(H5G_t, grp);
+ (void)H5FL_FREE(H5G_shared_t, grp->shared);
+ (void)H5FL_FREE(H5G_t, grp);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1338,36 +1217,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5G_rootof
- *
- * Purpose: Return a pointer to the root group of the file. If the file
- * is part of a virtual file then the root group of the virtual
- * file is returned.
- *
- * Return: Success: Ptr to the root group of the file. Do not
- * free the pointer -- it points directly into
- * the file struct.
- *
- * Failure: NULL
- *
- * Programmer: Robb Matzke
- * Tuesday, October 13, 1998
- *
- *-------------------------------------------------------------------------
- */
-H5G_t *
-H5G_rootof(H5F_t *f)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_rootof)
-
- while(f->parent)
- f = f->parent;
-
- FUNC_LEAVE_NOAPI(f->shared->root_grp)
-} /* end H5G_rootof() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5G_oloc
*
* Purpose: Returns a pointer to the object location for a group.
@@ -1622,6 +1471,9 @@ H5G_iterate_cb(const H5O_link_t *lnk, void *_udata)
ret_value = (udata->lnk_op.op_func.op_new)(udata->gid, lnk->name, &info, udata->op_data);
}
break;
+
+ default:
+ HDassert(0 && "Unknown link op type?!?");
} /* end switch */
done:
@@ -1649,7 +1501,7 @@ H5G_iterate(hid_t loc_id, const char *group_name,
{
H5G_loc_t loc; /* Location of parent for group */
hid_t gid = -1; /* ID of group to iterate over */
- H5G_t *grp; /* Pointer to group data structure to iterate over */
+ H5G_t *grp = NULL; /* Pointer to group data structure to iterate over */
H5G_iter_appcall_ud_t udata; /* User data for callback */
herr_t ret_value; /* Return value */
@@ -1668,7 +1520,7 @@ H5G_iterate(hid_t loc_id, const char *group_name,
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(NULL == (grp = H5G_open_name(&loc, group_name, lapl_id, dxpl_id)))
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
- if((gid = H5I_register(H5I_GROUP, grp)) < 0)
+ if((gid = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
/* Set up user data for callback */
@@ -1683,7 +1535,7 @@ H5G_iterate(hid_t loc_id, const char *group_name,
done:
/* Release the group opened */
if(gid > 0) {
- if(H5I_dec_ref(gid) < 0)
+ if(H5I_dec_ref(gid, TRUE) < 0)
HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group")
} /* end if */
else if(grp && H5G_close(grp) < 0)
@@ -1710,7 +1562,7 @@ H5G_free_visit_visited(void *item, void UNUSED *key, void UNUSED *operator_data/
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_free_visit_visited)
- H5FL_FREE(H5_obj_t, item);
+ (void)H5FL_FREE(H5_obj_t, item);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5G_free_visit_visited() */
@@ -1759,13 +1611,13 @@ H5G_visit_cb(const H5O_link_t *lnk, void *_udata)
/* Attempt to allocate larger buffer for path */
if(NULL == (new_path = H5MM_realloc(udata->path, len_needed)))
HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, H5_ITER_ERROR, "can't allocate path string")
- udata->path = new_path;
+ udata->path = (char *)new_path;
udata->path_buf_size = len_needed;
} /* end if */
/* Build the link's relative path name */
HDassert(udata->path[old_path_len] == '\0');
- HDstrcpy(&(udata->path[old_path_len]), lnk->name);
+ HDstrcpy(&(udata->path[old_path_len]), lnk->name);
udata->curr_path_len += link_name_len;
/* Construct the link info from the link message */
@@ -1825,14 +1677,17 @@ H5G_visit_cb(const H5O_link_t *lnk, void *_udata)
H5G_loc_t *old_loc = udata->curr_loc; /* Pointer to previous group location info */
H5_index_t idx_type = udata->idx_type; /* Type of index to use */
H5O_linfo_t linfo; /* Link info message */
+ htri_t linfo_exists; /* Whether the link info message exists */
/* Add the path separator to the current path */
HDassert(udata->path[udata->curr_path_len] == '\0');
- HDstrcpy(&(udata->path[udata->curr_path_len]), "/");
+ HDstrcpy(&(udata->path[udata->curr_path_len]), "/");
udata->curr_path_len++;
-
+
/* Attempt to get the link info for this group */
- if(H5G_obj_get_linfo(&obj_oloc, &linfo, udata->dxpl_id)) {
+ if((linfo_exists = H5G_obj_get_linfo(&obj_oloc, &linfo, udata->dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5_ITER_ERROR, "can't check for link info message")
+ if(linfo_exists) {
/* Check for creation order tracking, if creation order index lookup requested */
if(idx_type == H5_INDEX_CRT_ORDER) {
/* Check if creation order is tracked */
@@ -1844,9 +1699,6 @@ H5G_visit_cb(const H5O_link_t *lnk, void *_udata)
HDassert(idx_type == H5_INDEX_NAME);
} /* end if */
else {
- /* Clear error stack from not finding the link info message */
- H5E_clear_stack(NULL);
-
/* Can only perform name lookups on groups with symbol tables */
if(idx_type != H5_INDEX_NAME)
/* Switch to name order for this group */
@@ -1915,6 +1767,7 @@ H5G_visit(hid_t loc_id, const char *group_name, H5_index_t idx_type,
{
H5G_iter_visit_ud_t udata; /* User data for callback */
H5O_linfo_t linfo; /* Link info message */
+ htri_t linfo_exists; /* Whether the link info message exists */
hid_t gid = (-1); /* Group ID */
H5G_t *grp = NULL; /* Group opened */
H5G_loc_t loc; /* Location of group passed in */
@@ -1934,7 +1787,7 @@ H5G_visit(hid_t loc_id, const char *group_name, H5_index_t idx_type,
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
/* Register an ID for the starting group */
- if((gid = H5I_register(H5I_GROUP, grp)) < 0)
+ if((gid = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
/* Get the location of the starting group */
@@ -1958,7 +1811,7 @@ H5G_visit(hid_t loc_id, const char *group_name, H5_index_t idx_type,
udata.curr_path_len = 0;
/* Create skip list to store visited object information */
- if((udata.visited = H5SL_create(H5SL_TYPE_OBJ, 0.5, (size_t)16)) == NULL)
+ if((udata.visited = H5SL_create(H5SL_TYPE_OBJ)) == NULL)
HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "can't create skip list for visited objects")
/* Get the group's reference count and type */
@@ -1984,7 +1837,9 @@ H5G_visit(hid_t loc_id, const char *group_name, H5_index_t idx_type,
} /* end if */
/* Attempt to get the link info for this group */
- if(H5G_obj_get_linfo(&(grp->oloc), &linfo, dxpl_id)) {
+ if((linfo_exists = H5G_obj_get_linfo(&(grp->oloc), &linfo, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check for link info message")
+ if(linfo_exists) {
/* Check for creation order tracking, if creation order index lookup requested */
if(idx_type == H5_INDEX_CRT_ORDER) {
/* Check if creation order is tracked */
@@ -1996,9 +1851,6 @@ H5G_visit(hid_t loc_id, const char *group_name, H5_index_t idx_type,
HDassert(idx_type == H5_INDEX_NAME);
} /* end if */
else {
- /* Clear error stack from not finding the link info message */
- H5E_clear_stack(NULL);
-
/* Can only perform name lookups on groups with symbol tables */
if(idx_type != H5_INDEX_NAME)
/* Switch to name order for this group */
@@ -2017,7 +1869,7 @@ done:
/* Release the group opened */
if(gid > 0) {
- if(H5I_dec_ref(gid) < 0)
+ if(H5I_dec_ref(gid, TRUE) < 0)
HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group")
} /* end if */
else if(grp && H5G_close(grp) < 0)
diff --git a/src/H5Gbtree2.c b/src/H5Gbtree2.c
index 2e2f215..5ae9db1 100644
--- a/src/H5Gbtree2.c
+++ b/src/H5Gbtree2.c
@@ -78,23 +78,21 @@ typedef struct H5G_fh_ud_cmp_t {
/* v2 B-tree driver callbacks for 'creation order' index */
static herr_t H5G_dense_btree2_corder_store(void *native, const void *udata);
-static herr_t H5G_dense_btree2_corder_retrieve(void *udata, const void *native);
static herr_t H5G_dense_btree2_corder_compare(const void *rec1, const void *rec2);
-static herr_t H5G_dense_btree2_corder_encode(const H5F_t *f, uint8_t *raw,
- const void *native);
-static herr_t H5G_dense_btree2_corder_decode(const H5F_t *f, const uint8_t *raw,
- void *native);
+static herr_t H5G_dense_btree2_corder_encode(uint8_t *raw, const void *native,
+ void *ctx);
+static herr_t H5G_dense_btree2_corder_decode(const uint8_t *raw, void *native,
+ void *ctx);
static herr_t H5G_dense_btree2_corder_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
int indent, int fwidth, const void *record, const void *_udata);
/* v2 B-tree driver callbacks for 'name' index */
static herr_t H5G_dense_btree2_name_store(void *native, const void *udata);
-static herr_t H5G_dense_btree2_name_retrieve(void *udata, const void *native);
static herr_t H5G_dense_btree2_name_compare(const void *rec1, const void *rec2);
-static herr_t H5G_dense_btree2_name_encode(const H5F_t *f, uint8_t *raw,
- const void *native);
-static herr_t H5G_dense_btree2_name_decode(const H5F_t *f, const uint8_t *raw,
- void *native);
+static herr_t H5G_dense_btree2_name_encode(uint8_t *raw, const void *native,
+ void *ctx);
+static herr_t H5G_dense_btree2_name_decode(const uint8_t *raw, void *native,
+ void *ctx);
static herr_t H5G_dense_btree2_name_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
int indent, int fwidth, const void *record, const void *_udata);
@@ -106,27 +104,35 @@ static herr_t H5G_dense_fh_name_cmp(const void *obj, size_t obj_len, void *op_da
/* Package Variables */
/*********************/
/* v2 B-tree class for indexing 'name' field of links */
-const H5B2_class_t H5G_BT2_NAME[1]={{ /* B-tree class information */
+const H5B2_class_t H5G_BT2_NAME[1]={{ /* B-tree class information */
H5B2_GRP_DENSE_NAME_ID, /* Type of B-tree */
+ "H5B2_GRP_DENSE_NAME_ID", /* Name of B-tree class */
sizeof(H5G_dense_bt2_name_rec_t), /* Size of native record */
+ NULL, /* Create client callback context */
+ NULL, /* Destroy client callback context */
H5G_dense_btree2_name_store, /* Record storage callback */
- H5G_dense_btree2_name_retrieve, /* Record retrieval callback */
H5G_dense_btree2_name_compare, /* Record comparison callback */
H5G_dense_btree2_name_encode, /* Record encoding callback */
H5G_dense_btree2_name_decode, /* Record decoding callback */
- H5G_dense_btree2_name_debug /* Record debugging callback */
+ H5G_dense_btree2_name_debug, /* Record debugging callback */
+ NULL, /* Create debugging context */
+ NULL /* Destroy debugging context */
}};
/* v2 B-tree class for indexing 'creation order' field of links */
const H5B2_class_t H5G_BT2_CORDER[1]={{ /* B-tree class information */
H5B2_GRP_DENSE_CORDER_ID, /* Type of B-tree */
+ "H5B2_GRP_DENSE_CORDER_ID", /* Name of B-tree class */
sizeof(H5G_dense_bt2_corder_rec_t), /* Size of native record */
+ NULL, /* Create client callback context */
+ NULL, /* Destroy client callback context */
H5G_dense_btree2_corder_store, /* Record storage callback */
- H5G_dense_btree2_corder_retrieve, /* Record retrieval callback */
H5G_dense_btree2_corder_compare, /* Record comparison callback */
H5G_dense_btree2_corder_encode, /* Record encoding callback */
H5G_dense_btree2_corder_decode, /* Record decoding callback */
- H5G_dense_btree2_corder_debug /* Record debugging callback */
+ H5G_dense_btree2_corder_debug, /* Record debugging callback */
+ NULL, /* Create debugging context */
+ NULL /* Destroy debugging context */
}};
/*****************************/
@@ -164,7 +170,7 @@ H5G_dense_fh_name_cmp(const void *obj, size_t UNUSED obj_len, void *_udata)
FUNC_ENTER_NOAPI_NOINIT(H5G_dense_fh_name_cmp)
/* Decode link information */
- if(NULL == (lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj)))
+ if(NULL == (lnk = (H5O_link_t *)H5O_msg_decode(udata->f, udata->dxpl_id, NULL, H5O_LINK_ID, (const unsigned char *)obj)))
HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode link")
/* Compare the string values */
@@ -214,30 +220,6 @@ H5G_dense_btree2_name_store(void *_nrecord, const void *_udata)
/*-------------------------------------------------------------------------
- * Function: H5G_dense_btree2_name_retrieve
- *
- * Purpose: Retrieve native information from record for v2 B-tree
- *
- * Return: Success: non-negative
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Monday, September 11, 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5G_dense_btree2_name_retrieve(void *udata, const void *nrecord)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_dense_btree2_name_retrieve)
-
- *(H5G_dense_bt2_name_rec_t *)udata = *(const H5G_dense_bt2_name_rec_t *)nrecord;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5G_dense_btree2_name_retrieve() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5G_dense_btree2_name_compare
*
* Purpose: Compare two native information records, according to some key
@@ -324,7 +306,7 @@ for(u = 0; u < H5G_DENSE_FHEAP_ID_LEN; u++)
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_dense_btree2_name_encode(const H5F_t UNUSED *f, uint8_t *raw, const void *_nrecord)
+H5G_dense_btree2_name_encode(uint8_t *raw, const void *_nrecord, void UNUSED *ctx)
{
const H5G_dense_bt2_name_rec_t *nrecord = (const H5G_dense_bt2_name_rec_t *)_nrecord;
@@ -352,7 +334,7 @@ H5G_dense_btree2_name_encode(const H5F_t UNUSED *f, uint8_t *raw, const void *_n
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_dense_btree2_name_decode(const H5F_t UNUSED *f, const uint8_t *raw, void *_nrecord)
+H5G_dense_btree2_name_decode(const uint8_t *raw, void *_nrecord, void UNUSED *ctx)
{
H5G_dense_bt2_name_rec_t *nrecord = (H5G_dense_bt2_name_rec_t *)_nrecord;
@@ -389,8 +371,8 @@ H5G_dense_btree2_name_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dx
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_dense_btree2_name_debug)
- HDfprintf(stream, "%*s%-*s {%lx, ", indent, "", fwidth, "Record:",
- nrecord->hash);
+ HDfprintf(stream, "%*s%-*s {%x, ", indent, "", fwidth, "Record:",
+ (unsigned)nrecord->hash);
for(u = 0; u < H5G_DENSE_FHEAP_ID_LEN; u++)
HDfprintf(stderr, "%02x%s", nrecord->id[u], (u < (H5G_DENSE_FHEAP_ID_LEN - 1) ? " " : "}\n"));
@@ -428,30 +410,6 @@ H5G_dense_btree2_corder_store(void *_nrecord, const void *_udata)
/*-------------------------------------------------------------------------
- * Function: H5G_dense_btree2_corder_retrieve
- *
- * Purpose: Retrieve native information from record for v2 B-tree
- *
- * Return: Success: non-negative
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Monday, October 30, 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5G_dense_btree2_corder_retrieve(void *udata, const void *nrecord)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_dense_btree2_corder_retrieve)
-
- *(H5G_dense_bt2_corder_rec_t *)udata = *(const H5G_dense_bt2_corder_rec_t *)nrecord;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5G_dense_btree2_corder_retrieve() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5G_dense_btree2_corder_compare
*
* Purpose: Compare two native information records, according to some key
@@ -514,7 +472,7 @@ for(u = 0; u < H5G_DENSE_FHEAP_ID_LEN; u++)
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_dense_btree2_corder_encode(const H5F_t UNUSED *f, uint8_t *raw, const void *_nrecord)
+H5G_dense_btree2_corder_encode(uint8_t *raw, const void *_nrecord, void UNUSED *ctx)
{
const H5G_dense_bt2_corder_rec_t *nrecord = (const H5G_dense_bt2_corder_rec_t *)_nrecord;
@@ -542,7 +500,7 @@ H5G_dense_btree2_corder_encode(const H5F_t UNUSED *f, uint8_t *raw, const void *
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_dense_btree2_corder_decode(const H5F_t UNUSED *f, const uint8_t *raw, void *_nrecord)
+H5G_dense_btree2_corder_decode(const uint8_t *raw, void *_nrecord, void UNUSED *ctx)
{
H5G_dense_bt2_corder_rec_t *nrecord = (H5G_dense_bt2_corder_rec_t *)_nrecord;
@@ -579,8 +537,8 @@ H5G_dense_btree2_corder_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_dense_btree2_corder_debug)
- HDfprintf(stream, "%*s%-*s {%Hu, ", indent, "", fwidth, "Record:",
- nrecord->corder);
+ HDfprintf(stream, "%*s%-*s {%llu, ", indent, "", fwidth, "Record:",
+ (unsigned long long)nrecord->corder);
for(u = 0; u < H5G_DENSE_FHEAP_ID_LEN; u++)
HDfprintf(stderr, "%02x%s", nrecord->id[u], (u < (H5G_DENSE_FHEAP_ID_LEN - 1) ? " " : "}\n"));
diff --git a/src/H5Gcache.c b/src/H5Gcache.c
new file mode 100644
index 0000000..1b352ca
--- /dev/null
+++ b/src/H5Gcache.c
@@ -0,0 +1,438 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Gcache.c
+ * Feb 5 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Implement group metadata cache methods.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Gpkg.h" /* Groups */
+#include "H5MFprivate.h" /* File memory management */
+#include "H5WBprivate.h" /* Wrapped Buffers */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+#define H5G_NODE_VERS 1 /* Symbol table node version number */
+#define H5G_NODE_BUF_SIZE 512 /* Size of stack buffer for serialized nodes */
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* Metadata cache (H5AC) callbacks */
+static H5G_node_t *H5G_node_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata1,
+ void *_udata2);
+static herr_t H5G_node_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
+ H5G_node_t *sym, unsigned UNUSED * flags_ptr);
+static herr_t H5G_node_dest(H5F_t *f, H5G_node_t *sym);
+static herr_t H5G_node_clear(H5F_t *f, H5G_node_t *sym, hbool_t destroy);
+static herr_t H5G_node_size(const H5F_t *f, const H5G_node_t *sym, size_t *size_ptr);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Symbol table nodes inherit cache-like properties from H5AC */
+const H5AC_class_t H5AC_SNODE[1] = {{
+ H5AC_SNODE_ID,
+ (H5AC_load_func_t)H5G_node_load,
+ (H5AC_flush_func_t)H5G_node_flush,
+ (H5AC_dest_func_t)H5G_node_dest,
+ (H5AC_clear_func_t)H5G_node_clear,
+ (H5AC_notify_func_t)NULL,
+ (H5AC_size_func_t)H5G_node_size,
+}};
+
+
+/* Declare extern the free list to manage the H5G_node_t struct */
+H5FL_EXTERN(H5G_node_t);
+
+/* Declare extern the free list to manage sequences of H5G_entry_t's */
+H5FL_SEQ_EXTERN(H5G_entry_t);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_node_load
+ *
+ * Purpose: Loads a symbol table node from the file.
+ *
+ * Return: Success: Ptr to the new table.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Jun 23 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5G_node_t *
+H5G_node_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_udata1,
+ void UNUSED * _udata2)
+{
+ H5G_node_t *sym = NULL;
+ size_t size;
+ H5WB_t *wb = NULL; /* Wrapped buffer for node data */
+ uint8_t node_buf[H5G_NODE_BUF_SIZE]; /* Buffer for node */
+ uint8_t *node; /* Pointer to node buffer */
+ const uint8_t *p;
+ H5G_node_t *ret_value; /*for error handling */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_node_load)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(!_udata1);
+ HDassert(NULL == _udata2);
+
+ /*
+ * Initialize variables.
+ */
+
+ /* Wrap the local buffer for serialized node info */
+ if(NULL == (wb = H5WB_wrap(node_buf, sizeof(node_buf))))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't wrap buffer")
+
+ /* Compute the size of the serialized symbol table node on disk */
+ size = H5G_node_size_real(f);
+
+ /* Get a pointer to a buffer that's large enough for node */
+ if(NULL == (node = (uint8_t *)H5WB_actual(wb, size)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't get actual buffer")
+
+ /* Read the serialized symbol table node. */
+ if(H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, node) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_READERROR, NULL, "unable to read symbol table node")
+
+ /* Get temporary pointer to serialized node */
+ p = node;
+
+ /* magic */
+ if(HDmemcmp(p, H5G_NODE_MAGIC, (size_t)H5_SIZEOF_MAGIC))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "bad symbol table node signature")
+ p += 4;
+
+ /* version */
+ if(H5G_NODE_VERS != *p++)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "bad symbol table node version")
+
+ /* reserved */
+ p++;
+
+ /* Allocate symbol table data structures */
+ if(NULL == (sym = H5FL_CALLOC(H5G_node_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ if(NULL == (sym->entry = H5FL_SEQ_CALLOC(H5G_entry_t, (size_t)(2 * H5F_SYM_LEAF_K(f)))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* number of symbols */
+ UINT16DECODE(p, sym->nsyms);
+
+ /* entries */
+ if(H5G_ent_decode_vec(f, &p, sym->entry, sym->nsyms) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "unable to decode symbol table entries")
+
+ /* Set return value */
+ ret_value = sym;
+
+done:
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
+ if(!ret_value)
+ if(sym && H5G_node_dest(f, sym) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTFREE, NULL, "unable to destroy symbol table node")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_node_load() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_node_flush
+ *
+ * Purpose: Flush a symbol table node to disk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Jun 23 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_node_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5G_node_t *sym, unsigned UNUSED * flags_ptr)
+{
+ H5WB_t *wb = NULL; /* Wrapped buffer for node data */
+ uint8_t node_buf[H5G_NODE_BUF_SIZE]; /* Buffer for node */
+ unsigned u;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_node_flush)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(sym);
+
+ /*
+ * Look for dirty entries and set the node dirty flag.
+ */
+ for(u = 0; u < sym->nsyms; u++)
+ if(sym->entry[u].dirty) {
+ /* Set the node's dirty flag */
+ sym->cache_info.is_dirty = TRUE;
+
+ /* Reset the entry's dirty flag */
+ sym->entry[u].dirty = FALSE;
+ } /* end if */
+
+ /*
+ * Write the symbol node to disk.
+ */
+ if(sym->cache_info.is_dirty) {
+ uint8_t *node; /* Pointer to node buffer */
+ uint8_t *p; /* Pointer into raw data buffer */
+ size_t size;
+
+ /* Wrap the local buffer for serialized node info */
+ if(NULL == (wb = H5WB_wrap(node_buf, sizeof(node_buf))))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wrap buffer")
+
+ /* Compute the size of the serialized symbol table node on disk */
+ size = H5G_node_size_real(f);
+
+ /* Get a pointer to a buffer that's large enough for node */
+ if(NULL == (node = (uint8_t *)H5WB_actual(wb, size)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't get actual buffer")
+
+ /* Get temporary pointer to serialized symbol table node */
+ p = node;
+
+ /* magic number */
+ HDmemcpy(p, H5G_NODE_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += 4;
+
+ /* version number */
+ *p++ = H5G_NODE_VERS;
+
+ /* reserved */
+ *p++ = 0;
+
+ /* number of symbols */
+ UINT16ENCODE(p, sym->nsyms);
+
+ /* entries */
+ if(H5G_ent_encode_vec(f, &p, sym->entry, sym->nsyms) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "can't serialize")
+ HDmemset(p, 0, size - (size_t)(p - node));
+
+ /* Write the serialized symbol table node. */
+ if(H5F_block_write(f, H5FD_MEM_BTREE, addr, size, dxpl_id, node) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "unable to write symbol table node to the file")
+
+ /* Reset the node's dirty flag */
+ sym->cache_info.is_dirty = FALSE;
+ } /* end if */
+
+ /*
+ * Destroy the symbol node? This might happen if the node is being
+ * preempted from the cache.
+ */
+ if(destroy)
+ if(H5G_node_dest(f, sym) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to destroy symbol table node")
+
+done:
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_node_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_node_dest
+ *
+ * Purpose: Destroy a symbol table node in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jan 15 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_node_dest(H5F_t *f, H5G_node_t *sym)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_node_dest)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(sym);
+
+ /* Verify that node is clean */
+ HDassert(sym->cache_info.is_dirty == FALSE);
+
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!sym->cache_info.free_file_space_on_destroy || H5F_addr_defined(sym->cache_info.addr));
+
+ /* Check for freeing file space for symbol table node */
+ if(sym->cache_info.free_file_space_on_destroy) {
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, sym->cache_info.addr, (hsize_t)H5G_node_size_real(f)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to free symbol table node")
+ } /* end if */
+
+ /* Release resources */
+ if(sym->entry)
+ sym->entry = (H5G_entry_t *)H5FL_SEQ_FREE(H5G_entry_t, sym->entry);
+ sym = H5FL_FREE(H5G_node_t, sym);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_node_dest() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_node_clear
+ *
+ * Purpose: Mark a symbol table node in memory as non-dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Mar 20 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_node_clear(H5F_t *f, H5G_node_t *sym, hbool_t destroy)
+{
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_node_clear)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(sym);
+
+ /* Look for dirty entries and reset their dirty flag. */
+ for(u = 0; u < sym->nsyms; u++)
+ sym->entry[u].dirty = FALSE;
+ sym->cache_info.is_dirty = FALSE;
+
+ /*
+ * Destroy the symbol node? This might happen if the node is being
+ * preempted from the cache.
+ */
+ if(destroy)
+ if(H5G_node_dest(f, sym) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to destroy symbol table node")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_node_clear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_node_size
+ *
+ * Purpose: Compute the size in bytes of the specified instance of
+ * H5G_node_t 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: John Mainzer
+ * 5/13/04
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_node_size(const H5F_t *f, const H5G_node_t UNUSED *sym, size_t *size_ptr)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_size)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(size_ptr);
+
+ *size_ptr = H5G_node_size_real(f);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5G_node_size() */
+
diff --git a/src/H5Gcompact.c b/src/H5Gcompact.c
index b0340a7..26773cb 100644
--- a/src/H5Gcompact.c
+++ b/src/H5Gcompact.c
@@ -145,7 +145,7 @@ H5G_compact_build_table(const H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t
H5O_mesg_operator_t op; /* Message operator */
/* Allocate the link table */
- if((ltable->lnks = H5MM_malloc(sizeof(H5O_link_t) * ltable->nlinks)) == NULL)
+ if((ltable->lnks = (H5O_link_t *)H5MM_malloc(sizeof(H5O_link_t) * ltable->nlinks)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Set up user data for iteration */
@@ -406,7 +406,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5G_compact_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo,
+H5G_compact_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo,
H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk,
H5G_lib_iterate_t op, void *op_data)
{
@@ -489,7 +489,7 @@ done:
*
* Purpose: Look up an object relative to a group, using link messages.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Non-negative (TRUE/FALSE) on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
@@ -497,13 +497,13 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+htri_t
H5G_compact_lookup(H5O_loc_t *oloc, const char *name, H5O_link_t *lnk,
hid_t dxpl_id)
{
H5G_iter_lkp_t udata; /* User data for iteration callback */
H5O_mesg_operator_t op; /* Message operator */
- herr_t ret_value = SUCCEED; /* Return value */
+ htri_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5G_compact_lookup, FAIL)
@@ -522,9 +522,8 @@ H5G_compact_lookup(H5O_loc_t *oloc, const char *name, H5O_link_t *lnk,
if(H5O_msg_iterate(oloc, H5O_LINK_ID, &op, &udata, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over link messages")
- /* Check if we found the link we were looking for */
- if(!udata.found)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
+ /* Determine if we found the link we were looking for */
+ ret_value = (htri_t)udata.found;
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Gdense.c b/src/H5Gdense.c
index ed53a47..9a8e764 100644
--- a/src/H5Gdense.c
+++ b/src/H5Gdense.c
@@ -267,12 +267,15 @@ typedef struct {
*-------------------------------------------------------------------------
*/
herr_t
-H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo)
+H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo,
+ const H5O_pline_t *pline)
{
H5HF_create_t fheap_cparam; /* Fractal heap creation parameters */
- H5HF_t *fheap; /* Fractal heap handle */
+ H5B2_create_t bt2_cparam; /* v2 B-tree creation parameters */
+ H5HF_t *fheap = NULL; /* Fractal heap handle */
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for names */
+ H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order */
size_t fheap_id_len; /* Fractal heap ID length */
- size_t bt2_rrec_size; /* v2 B-tree raw record size */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_dense_create, FAIL)
@@ -293,6 +296,8 @@ H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo)
fheap_cparam.managed.start_root_rows = H5G_FHEAP_MAN_START_ROOT_ROWS;
fheap_cparam.checksum_dblocks = H5G_FHEAP_CHECKSUM_DBLOCKS;
fheap_cparam.max_man_size = H5G_FHEAP_MAX_MAN_SIZE;
+ if(pline)
+ fheap_cparam.pline = *pline;
/* Create fractal heap for storing links */
if(NULL == (fheap = H5HF_create(f, dxpl_id, &fheap_cparam)))
@@ -300,7 +305,7 @@ H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo)
/* Retrieve the heap's address in the file */
if(H5HF_get_heap_addr(fheap, &(linfo->fheap_addr)) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTGETSIZE, FAIL, "can't get fractal heap address")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get fractal heap address")
#ifdef QAK
HDfprintf(stderr, "%s: linfo->fheap_addr = %a\n", FUNC, linfo->fheap_addr);
#endif /* QAK */
@@ -313,18 +318,20 @@ HDfprintf(stderr, "%s: linfo->fheap_addr = %a\n", FUNC, linfo->fheap_addr);
HDfprintf(stderr, "%s: fheap_id_len = %Zu\n", FUNC, fheap_id_len);
#endif /* QAK */
- /* Close the fractal heap */
- if(H5HF_close(fheap, dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
-
/* Create the name index v2 B-tree */
- bt2_rrec_size = 4 + /* Name's hash value */
+ HDmemset(&bt2_cparam, 0, sizeof(bt2_cparam));
+ bt2_cparam.cls = H5G_BT2_NAME;
+ bt2_cparam.node_size = (size_t)H5G_NAME_BT2_NODE_SIZE;
+ bt2_cparam.rrec_size = 4 + /* Name's hash value */
fheap_id_len; /* Fractal heap ID */
- if(H5B2_create(f, dxpl_id, H5G_BT2_NAME,
- (size_t)H5G_NAME_BT2_NODE_SIZE, bt2_rrec_size,
- H5G_NAME_BT2_SPLIT_PERC, H5G_NAME_BT2_MERGE_PERC,
- &(linfo->name_bt2_addr)) < 0)
+ bt2_cparam.split_percent = H5G_NAME_BT2_SPLIT_PERC;
+ bt2_cparam.merge_percent = H5G_NAME_BT2_MERGE_PERC;
+ if(NULL == (bt2_name = H5B2_create(f, dxpl_id, &bt2_cparam, NULL)))
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create v2 B-tree for name index")
+
+ /* Retrieve the v2 B-tree's address in the file */
+ if(H5B2_get_addr(bt2_name, &(linfo->name_bt2_addr)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get v2 B-tree address for name index")
#ifdef QAK
HDfprintf(stderr, "%s: linfo->name_bt2_addr = %a\n", FUNC, linfo->name_bt2_addr);
#endif /* QAK */
@@ -332,19 +339,33 @@ HDfprintf(stderr, "%s: linfo->name_bt2_addr = %a\n", FUNC, linfo->name_bt2_addr)
/* Check if we should create a creation order index v2 B-tree */
if(linfo->index_corder) {
/* Create the creation order index v2 B-tree */
- bt2_rrec_size = 8 + /* Creation order value */
+ HDmemset(&bt2_cparam, 0, sizeof(bt2_cparam));
+ bt2_cparam.cls = H5G_BT2_CORDER;
+ bt2_cparam.node_size = (size_t)H5G_CORDER_BT2_NODE_SIZE;
+ bt2_cparam.rrec_size = 8 + /* Creation order value */
fheap_id_len; /* Fractal heap ID */
- if(H5B2_create(f, dxpl_id, H5G_BT2_CORDER,
- (size_t)H5G_CORDER_BT2_NODE_SIZE, bt2_rrec_size,
- H5G_CORDER_BT2_SPLIT_PERC, H5G_CORDER_BT2_MERGE_PERC,
- &(linfo->corder_bt2_addr)) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create v2 B-tree for name index")
+ bt2_cparam.split_percent = H5G_CORDER_BT2_SPLIT_PERC;
+ bt2_cparam.merge_percent = H5G_CORDER_BT2_MERGE_PERC;
+ if(NULL == (bt2_corder = H5B2_create(f, dxpl_id, &bt2_cparam, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create v2 B-tree for creation order index")
+
+ /* Retrieve the v2 B-tree's address in the file */
+ if(H5B2_get_addr(bt2_corder, &(linfo->corder_bt2_addr)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get v2 B-tree address for creation order index")
#ifdef QAK
HDfprintf(stderr, "%s: linfo->corder_bt2_addr = %a\n", FUNC, linfo->corder_bt2_addr);
#endif /* QAK */
} /* end if */
done:
+ /* Close the open objects */
+ if(fheap && H5HF_close(fheap, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index")
+ if(bt2_corder && H5B2_close(bt2_corder, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_dense_create() */
@@ -368,6 +389,8 @@ H5G_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
{
H5G_bt2_ud_ins_t udata; /* User data for v2 B-tree insertion */
H5HF_t *fheap = NULL; /* Fractal heap handle */
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
+ H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */
size_t link_size; /* Size of serialized link in the heap */
H5WB_t *wb = NULL; /* Wrapped buffer for link data */
uint8_t link_buf[H5G_LINK_BUF_SIZE]; /* Buffer for serializing link */
@@ -403,7 +426,7 @@ HDfprintf(stderr, "%s: HDstrlen(lnk->name) = %Zu, link_size = %Zu\n", FUNC, HDst
HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Create serialized form of link */
- if(H5O_msg_encode(f, H5O_LINK_ID, FALSE, link_ptr, lnk) < 0)
+ if(H5O_msg_encode(f, H5O_LINK_ID, FALSE, (unsigned char *)link_ptr, lnk) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "can't encode link")
/* Open the fractal heap */
@@ -414,6 +437,10 @@ HDfprintf(stderr, "%s: HDstrlen(lnk->name) = %Zu, link_size = %Zu\n", FUNC, HDst
if(H5HF_insert(fheap, dxpl_id, link_size, link_ptr, udata.id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert link into fractal heap")
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(f, dxpl_id, linfo->name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
/* Create the callback information for v2 B-tree record insertion */
udata.common.f = f;
udata.common.dxpl_id = dxpl_id;
@@ -426,14 +453,18 @@ HDfprintf(stderr, "%s: HDstrlen(lnk->name) = %Zu, link_size = %Zu\n", FUNC, HDst
/* udata.id already set in H5HF_insert() call */
/* Insert link into 'name' tracking v2 B-tree */
- if(H5B2_insert(f, dxpl_id, H5G_BT2_NAME, linfo->name_bt2_addr, &udata) < 0)
+ if(H5B2_insert(bt2_name, dxpl_id, &udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert record into v2 B-tree")
/* Check if we should create a creation order index v2 B-tree record */
if(linfo->index_corder) {
- /* Insert the record into the creation order index v2 B-tree */
+ /* Open the creation order index v2 B-tree */
HDassert(H5F_addr_defined(linfo->corder_bt2_addr));
- if(H5B2_insert(f, dxpl_id, H5G_BT2_CORDER, linfo->corder_bt2_addr, &udata) < 0)
+ if(NULL == (bt2_corder = H5B2_open(f, dxpl_id, linfo->corder_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index")
+
+ /* Insert the record into the creation order index v2 B-tree */
+ if(H5B2_insert(bt2_corder, dxpl_id, &udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert record into v2 B-tree")
} /* end if */
@@ -441,6 +472,10 @@ done:
/* Release resources */
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index")
+ if(bt2_corder && H5B2_close(bt2_corder, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index")
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
@@ -490,7 +525,7 @@ done:
*
* Purpose: Look up a link within a group that uses dense link storage
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Non-negative (TRUE/FALSE) on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
@@ -498,13 +533,14 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+htri_t
H5G_dense_lookup(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
const char *name, H5O_link_t *lnk)
{
H5G_bt2_ud_common_t udata; /* User data for v2 B-tree link lookup */
H5HF_t *fheap = NULL; /* Fractal heap handle */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
+ htri_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5G_dense_lookup, FAIL)
@@ -520,6 +556,10 @@ H5G_dense_lookup(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->fheap_addr)))
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(f, dxpl_id, linfo->name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
/* Construct the user data for v2 B-tree callback */
udata.f = f;
udata.dxpl_id = dxpl_id;
@@ -530,13 +570,15 @@ H5G_dense_lookup(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
udata.found_op_data = lnk;
/* Find & copy the named link in the 'name' index */
- if(H5B2_find(f, dxpl_id, H5G_BT2_NAME, linfo->name_bt2_addr, &udata, NULL, NULL) < 0)
+ if((ret_value = H5B2_find(bt2_name, dxpl_id, &udata, NULL, NULL)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to locate link in name index")
done:
/* Release resources */
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_dense_lookup() */
@@ -566,7 +608,7 @@ H5G_dense_lookup_by_idx_fh_cb(const void *obj, size_t UNUSED obj_len, void *_uda
FUNC_ENTER_NOAPI_NOINIT(H5G_dense_lookup_by_idx_fh_cb)
/* Decode link information & keep a copy */
- if(NULL == (tmp_lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj)))
+ if(NULL == (tmp_lnk = (H5O_link_t *)H5O_msg_decode(udata->f, udata->dxpl_id, NULL, H5O_LINK_ID, (const unsigned char *)obj)))
HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode link")
/* Copy link information */
@@ -641,7 +683,7 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
{
H5HF_t *fheap = NULL; /* Fractal heap handle */
H5G_link_table_t ltable = {0, NULL}; /* Table of links */
- const H5B2_class_t *bt2_class = NULL; /* Class of v2 B-tree */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */
herr_t ret_value = SUCCEED; /* Return value */
@@ -656,29 +698,32 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
/* Determine the address of the index to use */
if(idx_type == H5_INDEX_NAME) {
- /* Check if "native" order is OK - since names are hashed, getting them
- * in strictly increasing or decreasing order requires building a
- * table and sorting it.
+ /* Since names are hashed, getting them in strictly increasing or
+ * decreasing order requires building a table and sorting it.
+ * If the order is native, use the B-tree for names.
*/
- if(order == H5_ITER_NATIVE) {
- bt2_addr = linfo->name_bt2_addr;
- bt2_class = H5G_BT2_NAME;
- HDassert(H5F_addr_defined(bt2_addr));
- } /* end if */
- else
- bt2_addr = HADDR_UNDEF;
+ bt2_addr = HADDR_UNDEF;
} /* end if */
else {
HDassert(idx_type == H5_INDEX_CRT_ORDER);
/* This address may not be defined if creation order is tracked, but
* there's no index on it. If there's no v2 B-tree that indexes
- * the links, a table will be built.
+ * the links and the order is native, use the B-tree for names.
+ * Otherwise, build a table.
*/
bt2_addr = linfo->corder_bt2_addr;
- bt2_class = H5G_BT2_CORDER;
} /* end else */
+ /* If the order is native and there's no B-tree for indexing the links,
+ * use the B-tree for names instead of building a table to speed up the
+ * process.
+ */
+ if(order == H5_ITER_NATIVE && !H5F_addr_defined(bt2_addr)) {
+ bt2_addr = linfo->name_bt2_addr;
+ HDassert(H5F_addr_defined(bt2_addr));
+ } /* end if */
+
/* If there is an index defined for the field, use it */
if(H5F_addr_defined(bt2_addr)) {
H5G_bt2_ud_lbi_t udata; /* User data for v2 B-tree link lookup */
@@ -687,6 +732,10 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->fheap_addr)))
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+ /* Open the index v2 B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for index")
+
/* Construct the user data for v2 B-tree callback */
udata.f = f;
udata.dxpl_id = dxpl_id;
@@ -694,7 +743,7 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
udata.lnk = lnk;
/* Find & copy the link in the appropriate index */
- if(H5B2_index(f, dxpl_id, bt2_class, bt2_addr, order, n, H5G_dense_lookup_by_idx_bt2_cb, &udata) < 0)
+ if(H5B2_index(bt2, dxpl_id, order, n, H5G_dense_lookup_by_idx_bt2_cb, &udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to locate link in index")
} /* end if */
else { /* Otherwise, we need to build a table of the links and sort it */
@@ -715,6 +764,8 @@ done:
/* Release resources */
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for index")
if(ltable.lnks && H5G_link_release_table(&ltable) < 0)
HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table")
@@ -800,7 +851,7 @@ H5G_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
H5G_dense_bt_ud_t udata; /* User data for iteration callback */
/* Allocate the table to store the links */
- if((ltable->lnks = H5MM_malloc(sizeof(H5O_link_t) * ltable->nlinks)) == NULL)
+ if((ltable->lnks = (H5O_link_t *)H5MM_malloc(sizeof(H5O_link_t) * ltable->nlinks)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Set up user data for iteration */
@@ -852,7 +903,7 @@ H5G_dense_iterate_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata)
* HDF5 routine, it could attempt to re-protect that direct block for the
* heap, causing the HDF5 routine called to fail - QAK)
*/
- if(NULL == (udata->lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj)))
+ if(NULL == (udata->lnk = (H5O_link_t *)H5O_msg_decode(udata->f, udata->dxpl_id, NULL, H5O_LINK_ID, (const unsigned char *)obj)))
HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode link")
done:
@@ -938,7 +989,7 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
{
H5HF_t *fheap = NULL; /* Fractal heap handle */
H5G_link_table_t ltable = {0, NULL}; /* Table of links */
- const H5B2_class_t *bt2_class = NULL; /* Class of v2 B-tree */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */
herr_t ret_value; /* Return value */
@@ -953,37 +1004,47 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
/* Determine the address of the index to use */
if(idx_type == H5_INDEX_NAME) {
- /* Check if "native" order is OK - since names are hashed, getting them
- * in strictly increasing or decreasing order requires building a
- * table and sorting it.
+ /* Since names are hashed, getting them in strictly increasing or
+ * decreasing order requires building a table and sorting it. If
+ * the order is native, use the B-tree for names.
*/
- if(order == H5_ITER_NATIVE) {
- HDassert(H5F_addr_defined(linfo->name_bt2_addr));
- bt2_addr = linfo->name_bt2_addr;
- bt2_class = H5G_BT2_NAME;
- } /* end if */
- else
- bt2_addr = HADDR_UNDEF;
+ bt2_addr = HADDR_UNDEF;
} /* end if */
else {
HDassert(idx_type == H5_INDEX_CRT_ORDER);
/* This address may not be defined if creation order is tracked, but
* there's no index on it. If there's no v2 B-tree that indexes
- * the links, a table will be built.
+ * the links and the order is native, use the B-tree for names.
+ * Otherwise, build a table.
*/
bt2_addr = linfo->corder_bt2_addr;
- bt2_class = H5G_BT2_CORDER;
} /* end else */
+ /* If the order is native and there's no B-tree for indexing the links,
+ * use the B-tree for names instead of building a table to speed up the
+ * process.
+ */
+ if(order == H5_ITER_NATIVE && !H5F_addr_defined(bt2_addr)) {
+ HDassert(H5F_addr_defined(linfo->name_bt2_addr));
+ bt2_addr = linfo->name_bt2_addr;
+ } /* end if */
+
/* Check on iteration order */
- if(order == H5_ITER_NATIVE && H5F_addr_defined(bt2_addr)) {
+ if(order == H5_ITER_NATIVE) {
H5G_bt2_ud_it_t udata; /* User data for iterator callback */
+ /* Sanity check */
+ HDassert(H5F_addr_defined(bt2_addr));
+
/* Open the fractal heap */
if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->fheap_addr)))
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+ /* Open the index v2 B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for index")
+
/* Construct the user data for v2 B-tree iterator callback */
udata.f = f;
udata.dxpl_id = dxpl_id;
@@ -995,7 +1056,7 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
/* Iterate over the records in the v2 B-tree's "native" order */
/* (by hash of name) */
- if((ret_value = H5B2_iterate(f, dxpl_id, bt2_class, bt2_addr, H5G_dense_iterate_bt2_cb, &udata)) < 0)
+ if((ret_value = H5B2_iterate(bt2, dxpl_id, H5G_dense_iterate_bt2_cb, &udata)) < 0)
HERROR(H5E_SYM, H5E_BADITER, "link iteration failed");
/* Update the last link examined, if requested */
@@ -1016,6 +1077,8 @@ done:
/* Release resources */
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for index")
if(ltable.lnks && H5G_link_release_table(&ltable) < 0)
HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table")
@@ -1047,7 +1110,7 @@ H5G_dense_get_name_by_idx_fh_cb(const void *obj, size_t UNUSED obj_len, void *_u
FUNC_ENTER_NOAPI_NOINIT(H5G_dense_get_name_by_idx_fh_cb)
/* Decode link information */
- if(NULL == (lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj)))
+ if(NULL == (lnk = (H5O_link_t *)H5O_msg_decode(udata->f, udata->dxpl_id, NULL, H5O_LINK_ID, (const unsigned char *)obj)))
HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode link")
/* Get the length of the name */
@@ -1130,10 +1193,10 @@ H5G_dense_get_name_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo,
H5_index_t idx_type, H5_iter_order_t order, hsize_t n, char *name,
size_t size)
{
- H5HF_t *fheap = NULL; /* Fractal heap handle */
+ H5HF_t *fheap = NULL; /* Fractal heap handle */
H5G_link_table_t ltable = {0, NULL}; /* Table of links */
- const H5B2_class_t *bt2_class = NULL; /* Class of v2 B-tree */
- haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
+ haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */
ssize_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5G_dense_get_name_by_idx, FAIL)
@@ -1146,29 +1209,32 @@ H5G_dense_get_name_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo,
/* Determine the address of the index to use */
if(idx_type == H5_INDEX_NAME) {
- /* Check if "native" order is OK - since names are hashed, getting them
- * in strictly increasing or decreasing order requires building a
- * table and sorting it.
+ /* Since names are hashed, getting them in strictly increasing or
+ * decreasing order requires building a table and sorting it. If
+ * the order is native, use the B-tree for names.
*/
- if(order == H5_ITER_NATIVE) {
- bt2_addr = linfo->name_bt2_addr;
- bt2_class = H5G_BT2_NAME;
- HDassert(H5F_addr_defined(bt2_addr));
- } /* end if */
- else
- bt2_addr = HADDR_UNDEF;
+ bt2_addr = HADDR_UNDEF;
} /* end if */
else {
HDassert(idx_type == H5_INDEX_CRT_ORDER);
/* This address may not be defined if creation order is tracked, but
* there's no index on it. If there's no v2 B-tree that indexes
- * the links, a table will be built.
+ * the links and the order is native, use the B-tree for names.
+ * Otherwise, build a table.
*/
bt2_addr = linfo->corder_bt2_addr;
- bt2_class = H5G_BT2_CORDER;
} /* end else */
+ /* If the order is native and there's no B-tree for indexing the links,
+ * use the B-tree for names instead of building a table to speed up the
+ * process.
+ */
+ if(order == H5_ITER_NATIVE && !H5F_addr_defined(bt2_addr)) {
+ bt2_addr = linfo->name_bt2_addr;
+ HDassert(H5F_addr_defined(bt2_addr));
+ } /* end if */
+
/* If there is an index defined for the field, use it */
if(H5F_addr_defined(bt2_addr)) {
H5G_bt2_ud_gnbi_t udata; /* User data for v2 B-tree callback */
@@ -1177,6 +1243,10 @@ H5G_dense_get_name_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo,
if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->fheap_addr)))
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+ /* Open the index v2 B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for index")
+
/* Set up the user data for the v2 B-tree 'record remove' callback */
udata.f = f;
udata.dxpl_id = dxpl_id;
@@ -1185,7 +1255,7 @@ H5G_dense_get_name_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo,
udata.name_size = size;
/* Retrieve the name according to the v2 B-tree's index order */
- if(H5B2_index(f, dxpl_id, bt2_class, bt2_addr, order, n, H5G_dense_get_name_by_idx_bt2_cb, &udata) < 0)
+ if(H5B2_index(bt2, dxpl_id, order, n, H5G_dense_get_name_by_idx_bt2_cb, &udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTLIST, FAIL, "can't locate object in v2 B-tree")
/* Set return value */
@@ -1215,6 +1285,8 @@ done:
/* Release resources */
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for index")
if(ltable.lnks && H5G_link_release_table(&ltable) < 0)
HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table")
@@ -1240,25 +1312,29 @@ H5G_dense_remove_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata)
{
H5G_fh_ud_rm_t *udata = (H5G_fh_ud_rm_t *)_udata; /* User data for fractal heap 'op' callback */
H5O_link_t *lnk = NULL; /* Pointer to link created from heap object */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5G_dense_remove_fh_cb)
/* Decode link information */
- if(NULL == (lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj)))
+ if(NULL == (lnk = (H5O_link_t *)H5O_msg_decode(udata->f, udata->dxpl_id, NULL, H5O_LINK_ID, (const unsigned char *)obj)))
HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode link")
/* Check for removing the link from the creation order index */
if(H5F_addr_defined(udata->corder_bt2_addr)) {
H5G_bt2_ud_common_t bt2_udata; /* Info for B-tree callbacks */
+ /* Open the creation order index v2 B-tree */
+ if(NULL == (bt2 = H5B2_open(udata->f, udata->dxpl_id, udata->corder_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index")
+
/* Set up the user data for the v2 B-tree 'record remove' callback */
HDassert(lnk->corder_valid);
bt2_udata.corder = lnk->corder;
/* Remove the record from the name index v2 B-tree */
- if(H5B2_remove(udata->f, udata->dxpl_id, H5G_BT2_CORDER, udata->corder_bt2_addr,
- &bt2_udata, NULL, NULL) < 0)
+ if(H5B2_remove(bt2, udata->dxpl_id, &bt2_udata, NULL, NULL) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, FAIL, "unable to remove link from creation order index v2 B-tree")
} /* end if */
@@ -1273,7 +1349,9 @@ H5G_dense_remove_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata)
HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete link")
done:
- /* Release the space allocated for the link */
+ /* Release resources */
+ if(bt2 && H5B2_close(bt2, udata->dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index")
if(lnk)
H5O_msg_free(H5O_LINK_ID, lnk);
@@ -1344,7 +1422,8 @@ H5G_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
H5RS_str_t *grp_full_path_r, const char *name)
{
H5HF_t *fheap = NULL; /* Fractal heap handle */
- H5G_bt2_ud_rm_t udata; /* User data for v2 B-tree record removal */
+ H5G_bt2_ud_rm_t udata; /* User data for v2 B-tree record removal */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_dense_remove, FAIL)
@@ -1360,6 +1439,10 @@ H5G_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->fheap_addr)))
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, linfo->name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
/* Set up the user data for the v2 B-tree 'record remove' callback */
udata.common.f = f;
udata.common.dxpl_id = dxpl_id;
@@ -1374,13 +1457,15 @@ H5G_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
udata.replace_names = TRUE;
/* Remove the record from the name index v2 B-tree */
- if(H5B2_remove(f, dxpl_id, H5G_BT2_NAME, linfo->name_bt2_addr, &udata, H5G_dense_remove_bt2_cb, &udata) < 0)
+ if(H5B2_remove(bt2, dxpl_id, &udata, H5G_dense_remove_bt2_cb, &udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, FAIL, "unable to remove link from name index v2 B-tree")
done:
/* Release resources */
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_dense_remove() */
@@ -1408,7 +1493,7 @@ H5G_dense_remove_by_idx_fh_cb(const void *obj, size_t UNUSED obj_len, void *_uda
FUNC_ENTER_NOAPI_NOINIT(H5G_dense_remove_by_idx_fh_cb)
/* Decode link information */
- if(NULL == (udata->lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj)))
+ if(NULL == (udata->lnk = (H5O_link_t *)H5O_msg_decode(udata->f, udata->dxpl_id, NULL, H5O_LINK_ID, (const unsigned char *)obj)))
HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, H5_ITER_ERROR, "can't decode link")
/* Can't operate on link here because the fractal heap block is locked */
@@ -1436,6 +1521,7 @@ H5G_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata)
{
H5G_bt2_ud_rmbi_t *bt2_udata = (H5G_bt2_ud_rmbi_t *)_bt2_udata; /* User data for callback */
H5G_fh_ud_rmbi_t fh_udata; /* User data for fractal heap 'op' callback */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
const uint8_t *heap_id; /* Heap ID for link */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1471,22 +1557,15 @@ H5G_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata)
/* Check for removing the link from the "other" index (creation order, when name used and vice versa) */
if(H5F_addr_defined(bt2_udata->other_bt2_addr)) {
H5G_bt2_ud_common_t other_bt2_udata; /* Info for B-tree callbacks */
- const H5B2_class_t *other_bt2_class; /* Class of "other" v2 B-tree */
/* Determine the index being used */
if(bt2_udata->idx_type == H5_INDEX_NAME) {
- /* Set the class of the "other" index */
- other_bt2_class = H5G_BT2_CORDER;
-
/* Set up the user data for the v2 B-tree 'record remove' callback */
other_bt2_udata.corder = fh_udata.lnk->corder;
} /* end if */
else {
HDassert(bt2_udata->idx_type == H5_INDEX_CRT_ORDER);
- /* Set the class of the "other" index */
- other_bt2_class = H5G_BT2_NAME;
-
/* Set up the user data for the v2 B-tree 'record remove' callback */
other_bt2_udata.f = bt2_udata->f;
other_bt2_udata.dxpl_id = bt2_udata->dxpl_id;
@@ -1497,12 +1576,15 @@ H5G_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata)
other_bt2_udata.found_op_data = NULL;
} /* end else */
+ /* Open the index v2 B-tree */
+ if(NULL == (bt2 = H5B2_open(bt2_udata->f, bt2_udata->dxpl_id, bt2_udata->other_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for 'other' index")
+
/* Set the common information for the v2 B-tree remove operation */
/* Remove the record from the name index v2 B-tree */
- if(H5B2_remove(bt2_udata->f, bt2_udata->dxpl_id, other_bt2_class, bt2_udata->other_bt2_addr,
- &other_bt2_udata, NULL, NULL) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, H5_ITER_ERROR, "unable to remove link from creation order index v2 B-tree")
+ if(H5B2_remove(bt2, bt2_udata->dxpl_id, &other_bt2_udata, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, H5_ITER_ERROR, "unable to remove link from 'other' index v2 B-tree")
} /* end if */
/* Replace open objects' names */
@@ -1522,6 +1604,10 @@ H5G_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata)
HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, FAIL, "unable to remove link from fractal heap")
done:
+ /* Release resources */
+ if(bt2 && H5B2_close(bt2, bt2_udata->dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for 'other' index")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_dense_remove_by_idx_bt2_cb() */
@@ -1547,7 +1633,7 @@ H5G_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
{
H5HF_t *fheap = NULL; /* Fractal heap handle */
H5G_link_table_t ltable = {0, NULL}; /* Table of links */
- const H5B2_class_t *bt2_class = NULL; /* Class of v2 B-tree */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1561,29 +1647,32 @@ H5G_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
/* Determine the address of the index to use */
if(idx_type == H5_INDEX_NAME) {
- /* Check if "native" order is OK - since names are hashed, getting them
- * in strictly increasing or decreasing order requires building a
- * table and sorting it.
+ /* Since names are hashed, getting them in strictly increasing or
+ * decreasing order requires building a table and sorting it. If
+ * the order is native, use the B-tree for names.
*/
- if(order == H5_ITER_NATIVE) {
- bt2_addr = linfo->name_bt2_addr;
- bt2_class = H5G_BT2_NAME;
- HDassert(H5F_addr_defined(bt2_addr));
- } /* end if */
- else
- bt2_addr = HADDR_UNDEF;
+ bt2_addr = HADDR_UNDEF;
} /* end if */
else {
HDassert(idx_type == H5_INDEX_CRT_ORDER);
/* This address may not be defined if creation order is tracked, but
* there's no index on it. If there's no v2 B-tree that indexes
- * the links, a table will be built.
+ * the links and the order is native, use the B-tree for names.
+ * Otherwise, build a table.
*/
bt2_addr = linfo->corder_bt2_addr;
- bt2_class = H5G_BT2_CORDER;
} /* end else */
+ /* If the order is native and there's no B-tree for indexing the links,
+ * use the B-tree for names instead of building a table to speed up the
+ * process.
+ */
+ if(order == H5_ITER_NATIVE && !H5F_addr_defined(bt2_addr)) {
+ bt2_addr = linfo->name_bt2_addr;
+ HDassert(H5F_addr_defined(bt2_addr));
+ } /* end if */
+
/* If there is an index defined for the field, use it */
if(H5F_addr_defined(bt2_addr)) {
H5G_bt2_ud_rmbi_t udata; /* User data for v2 B-tree record removal */
@@ -1592,6 +1681,10 @@ H5G_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->fheap_addr)))
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+ /* Open the index v2 B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for index")
+
/* Set up the user data for the v2 B-tree 'remove by index' callback */
udata.f = f;
udata.dxpl_id = dxpl_id;
@@ -1601,8 +1694,7 @@ H5G_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
udata.grp_full_path_r = grp_full_path_r;
/* Remove the record from the name index v2 B-tree */
- if(H5B2_remove_by_idx(f, dxpl_id, bt2_class, bt2_addr,
- order, n, H5G_dense_remove_by_idx_bt2_cb, &udata) < 0)
+ if(H5B2_remove_by_idx(bt2, dxpl_id, order, n, H5G_dense_remove_by_idx_bt2_cb, &udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, FAIL, "unable to remove link from indexed v2 B-tree")
} /* end if */
else { /* Otherwise, we need to build a table of the links and sort it */
@@ -1623,6 +1715,8 @@ done:
/* Release resources */
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for index")
if(ltable.lnks && H5G_link_release_table(&ltable) < 0)
HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table")
@@ -1682,7 +1776,7 @@ H5G_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, hbool_t adj_link)
udata.replace_names = FALSE;
/* Delete the name index, adjusting the ref. count on links removed */
- if(H5B2_delete(f, dxpl_id, H5G_BT2_NAME, linfo->name_bt2_addr, H5G_dense_remove_bt2_cb, &udata) < 0)
+ if(H5B2_delete(f, dxpl_id, linfo->name_bt2_addr, NULL, H5G_dense_remove_bt2_cb, &udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree for name index")
/* Close the fractal heap */
@@ -1691,7 +1785,7 @@ H5G_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, hbool_t adj_link)
} /* end if */
else {
/* Delete the name index, without adjusting the ref. count on the links */
- if(H5B2_delete(f, dxpl_id, H5G_BT2_NAME, linfo->name_bt2_addr, NULL, NULL) < 0)
+ if(H5B2_delete(f, dxpl_id, linfo->name_bt2_addr, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree for name index")
} /* end else */
linfo->name_bt2_addr = HADDR_UNDEF;
@@ -1700,7 +1794,7 @@ H5G_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, hbool_t adj_link)
if(linfo->index_corder) {
/* Delete the creation order index, without adjusting the ref. count on the links */
HDassert(H5F_addr_defined(linfo->corder_bt2_addr));
- if(H5B2_delete(f, dxpl_id, H5G_BT2_CORDER, linfo->corder_bt2_addr, NULL, NULL) < 0)
+ if(H5B2_delete(f, dxpl_id, linfo->corder_bt2_addr, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree for creation order index")
linfo->corder_bt2_addr = HADDR_UNDEF;
} /* end if */
diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c
index 16531a7..a18339b 100644
--- a/src/H5Gdeprec.c
+++ b/src/H5Gdeprec.c
@@ -218,15 +218,15 @@ H5Gcreate1(hid_t loc_id, const char *name, size_t size_hint)
H5O_ginfo_t ginfo; /* Group info property */
/* Get the default property list */
- if(NULL == (gc_plist = H5I_object(H5P_GROUP_CREATE_DEFAULT)))
+ if(NULL == (gc_plist = (H5P_genplist_t *)H5I_object(H5P_GROUP_CREATE_DEFAULT)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
/* Make a copy of the default property list */
- if((tmp_gcpl = H5P_copy_plist(gc_plist)) < 0)
+ if((tmp_gcpl = H5P_copy_plist(gc_plist, FALSE)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to copy the creation property list")
/* Get pointer to the copied property list */
- if(NULL == (gc_plist = H5I_object(tmp_gcpl)))
+ if(NULL == (gc_plist = (H5P_genplist_t *)H5I_object(tmp_gcpl)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
/* Get the group info property */
@@ -245,12 +245,12 @@ H5Gcreate1(hid_t loc_id, const char *name, size_t size_hint)
if(NULL == (grp = H5G_create_named(&loc, name, H5P_LINK_CREATE_DEFAULT,
tmp_gcpl, H5P_GROUP_ACCESS_DEFAULT, H5AC_dxpl_id)))
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group")
- if((ret_value = H5I_register(H5I_GROUP, grp)) < 0)
+ if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
done:
if(tmp_gcpl > 0 && tmp_gcpl != H5P_GROUP_CREATE_DEFAULT)
- if(H5I_dec_ref(tmp_gcpl) < 0)
+ if(H5I_dec_ref(tmp_gcpl, TRUE) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release property list")
if(ret_value < 0)
@@ -299,7 +299,7 @@ H5Gopen1(hid_t loc_id, const char *name)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
/* Register an atom for the group */
- if((ret_value = H5I_register(H5I_GROUP, grp)) < 0)
+ if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
done:
@@ -890,7 +890,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk,
+H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk,
H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/)
{
H5G_trav_goi_t *udata = (H5G_trav_goi_t *)_udata; /* User data passed in */
@@ -900,7 +900,7 @@ H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_
/* Check if the name in this group resolved to a valid link */
if(lnk == NULL && obj_loc == NULL)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "'%s' doesn't exist", name)
/* Only modify user's buffer if it's available */
if(udata->statbuf) {
@@ -1136,6 +1136,7 @@ static H5G_obj_t
H5G_obj_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id)
{
H5O_linfo_t linfo; /* Link info message */
+ htri_t linfo_exists; /* Whether the link info message exists */
H5G_obj_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5G_obj_get_type_by_idx, H5G_UNKNOWN)
@@ -1144,7 +1145,9 @@ H5G_obj_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id)
HDassert(oloc);
/* Attempt to get the link info for this group */
- if(H5G_obj_get_linfo(oloc, &linfo, dxpl_id)) {
+ if((linfo_exists = H5G_obj_get_linfo(oloc, &linfo, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5G_UNKNOWN, "can't check for link info message")
+ if(linfo_exists) {
if(H5F_addr_defined(linfo.fheap_addr)) {
/* Get the object's name from the dense link storage */
if((ret_value = H5G_dense_get_type_by_idx(oloc->file, dxpl_id, &linfo, idx)) < 0)
@@ -1157,9 +1160,6 @@ H5G_obj_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id)
} /* end else */
} /* end if */
else {
- /* Clear error stack from not finding the link info message */
- H5E_clear_stack(NULL);
-
/* Get the object's type from the symbol table */
if((ret_value = H5G_stab_get_type_by_idx(oloc, idx, dxpl_id)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5G_UNKNOWN, "can't locate type")
diff --git a/src/H5Gent.c b/src/H5Gent.c
index d56d3c0..2b499fe 100644
--- a/src/H5Gent.c
+++ b/src/H5Gent.c
@@ -28,15 +28,10 @@
#include "H5FLprivate.h" /* Free Lists */
#include "H5Gpkg.h" /* Groups */
#include "H5HLprivate.h" /* Local Heaps */
-#include "H5Iprivate.h" /* IDs */
-#include "H5MMprivate.h" /* Memory Management */
/* Private macros */
/* Private prototypes */
-static herr_t H5G_ent_encode(const H5F_t *f, uint8_t **pp, const H5G_entry_t *ent);
-static herr_t H5G_ent_decode(const H5F_t *f, const uint8_t **pp,
- H5G_entry_t *ent/*out*/);
/* Declare extern the PQ free list for the wrapped strings */
H5FL_BLK_EXTERN(str_buf);
@@ -48,9 +43,6 @@ H5FL_BLK_EXTERN(str_buf);
* Purpose: Same as H5G_ent_decode() except it does it for an array of
* symbol table entries.
*
- * Errors:
- * SYM CANTDECODE Can't decode.
- *
* Return: Success: Non-negative, with *pp pointing to the first byte
* after the last symbol.
*
@@ -60,31 +52,29 @@ H5FL_BLK_EXTERN(str_buf);
* matzke@llnl.gov
* Jul 18 1997
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5G_ent_decode_vec(const H5F_t *f, const uint8_t **pp, H5G_entry_t *ent, unsigned n)
{
- unsigned u;
- herr_t ret_value=SUCCEED; /* Return value */
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5G_ent_decode_vec, FAIL);
+ FUNC_ENTER_NOAPI(H5G_ent_decode_vec, FAIL)
/* check arguments */
- assert(f);
- assert(pp);
- assert(ent);
+ HDassert(f);
+ HDassert(pp);
+ HDassert(ent);
/* decode entries */
- for (u = 0; u < n; u++)
- if (H5G_ent_decode(f, pp, ent + u) < 0)
+ for(u = 0; u < n; u++)
+ if(H5G_ent_decode(f, pp, ent + u) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode")
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_ent_decode_vec() */
/*-------------------------------------------------------------------------
@@ -92,8 +82,6 @@ done:
*
* Purpose: Decodes a symbol table entry pointed to by `*pp'.
*
- * Errors:
- *
* Return: Success: Non-negative with *pp pointing to the first byte
* following the symbol table entry.
*
@@ -103,25 +91,23 @@ done:
* matzke@llnl.gov
* Jul 18 1997
*
- * Modifications:
- * Robb Matzke, 17 Jul 1998
- * Added a 4-byte padding field for alignment and future expansion.
- *
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5G_ent_decode(const H5F_t *f, const uint8_t **pp, H5G_entry_t *ent)
{
const uint8_t *p_ret = *pp;
uint32_t tmp;
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_ent_decode)
+ FUNC_ENTER_NOAPI(H5G_ent_decode, FAIL)
/* check arguments */
HDassert(f);
HDassert(pp);
HDassert(ent);
+ /* Set the entry's file pointer */
ent->file = f;
/* decode header */
@@ -129,31 +115,31 @@ H5G_ent_decode(const H5F_t *f, const uint8_t **pp, H5G_entry_t *ent)
H5F_addr_decode(f, pp, &(ent->header));
UINT32DECODE(*pp, tmp);
*pp += 4; /*reserved*/
- ent->type=(H5G_cache_type_t)tmp;
+ ent->type = (H5G_cache_type_t)tmp;
/* decode scratch-pad */
- switch (ent->type) {
+ switch(ent->type) {
case H5G_NOTHING_CACHED:
break;
case H5G_CACHED_STAB:
- assert(2 * H5F_SIZEOF_ADDR(f) <= H5G_SIZEOF_SCRATCH);
+ HDassert(2 * H5F_SIZEOF_ADDR(f) <= H5G_SIZEOF_SCRATCH);
H5F_addr_decode(f, pp, &(ent->cache.stab.btree_addr));
H5F_addr_decode(f, pp, &(ent->cache.stab.heap_addr));
break;
case H5G_CACHED_SLINK:
- UINT32DECODE (*pp, ent->cache.slink.lval_offset);
+ UINT32DECODE(*pp, ent->cache.slink.lval_offset);
break;
default:
- /* Error or unknown type. Bail out. */
- return -1;
- }
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unknown symbol table entry cache type")
+ } /* end switch */
*pp = p_ret + H5G_SIZEOF_ENTRY(f);
- FUNC_LEAVE_NOAPI(SUCCEED)
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_ent_decode() */
@@ -163,9 +149,6 @@ H5G_ent_decode(const H5F_t *f, const uint8_t **pp, H5G_entry_t *ent)
* Purpose: Same as H5G_ent_encode() except it does it for an array of
* symbol table entries.
*
- * Errors:
- * SYM CANTENCODE Can't encode.
- *
* Return: Success: Non-negative, with *pp pointing to the first byte
* after the last symbol.
*
@@ -175,31 +158,29 @@ H5G_ent_decode(const H5F_t *f, const uint8_t **pp, H5G_entry_t *ent)
* matzke@llnl.gov
* Jul 18 1997
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5G_ent_encode_vec(const H5F_t *f, uint8_t **pp, const H5G_entry_t *ent, unsigned n)
{
- unsigned u;
- herr_t ret_value=SUCCEED; /* Return value */
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5G_ent_encode_vec, FAIL);
+ FUNC_ENTER_NOAPI(H5G_ent_encode_vec, FAIL)
/* check arguments */
- assert(f);
- assert(pp);
- assert(ent);
+ HDassert(f);
+ HDassert(pp);
+ HDassert(ent);
/* encode entries */
- for (u = 0; u < n; u++)
- if (H5G_ent_encode(f, pp, ent + u) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "can't encode");
+ for(u = 0; u < n; u++)
+ if(H5G_ent_encode(f, pp, ent + u) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "can't encode")
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5G_ent_encode_vec() */
/*-------------------------------------------------------------------------
@@ -208,8 +189,6 @@ done:
* Purpose: Encodes the specified symbol table entry into the buffer
* pointed to by *pp.
*
- * Errors:
- *
* Return: Success: Non-negative, with *pp pointing to the first byte
* after the symbol table entry.
*
@@ -219,26 +198,22 @@ done:
* matzke@llnl.gov
* Jul 18 1997
*
- * Modifications:
- *
- * Robb Matzke, 8 Aug 1997
- * Writes zeros for the bytes that aren't used so the file doesn't
- * contain junk.
- *
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5G_ent_encode(const H5F_t *f, uint8_t **pp, const H5G_entry_t *ent)
{
- uint8_t *p_ret = *pp + H5G_SIZEOF_ENTRY(f);
+ uint8_t *p_ret = *pp + H5G_SIZEOF_ENTRY(f);
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_ent_encode);
+ FUNC_ENTER_NOAPI(H5G_ent_encode, FAIL)
/* check arguments */
- assert(f);
- assert(pp);
+ HDassert(f);
+ HDassert(pp);
- if (ent) {
+ /* Check for actual entry to encode */
+ if(ent) {
/* encode header */
H5F_ENCODE_LENGTH(f, *pp, ent->name_off);
H5F_addr_encode(f, pp, ent->header);
@@ -246,38 +221,39 @@ H5G_ent_encode(const H5F_t *f, uint8_t **pp, const H5G_entry_t *ent)
UINT32ENCODE(*pp, 0); /*reserved*/
/* encode scratch-pad */
- switch (ent->type) {
+ switch(ent->type) {
case H5G_NOTHING_CACHED:
break;
case H5G_CACHED_STAB:
- assert(2 * H5F_SIZEOF_ADDR(f) <= H5G_SIZEOF_SCRATCH);
+ HDassert(2 * H5F_SIZEOF_ADDR(f) <= H5G_SIZEOF_SCRATCH);
H5F_addr_encode(f, pp, ent->cache.stab.btree_addr);
H5F_addr_encode(f, pp, ent->cache.stab.heap_addr);
break;
case H5G_CACHED_SLINK:
- UINT32ENCODE (*pp, ent->cache.slink.lval_offset);
+ UINT32ENCODE(*pp, ent->cache.slink.lval_offset);
break;
default:
- /* Unknown cached type. Bail out. */
- return -1;
- }
- } else {
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unknown symbol table entry cache type")
+ } /* end switch */
+ } /* end if */
+ else {
H5F_ENCODE_LENGTH(f, *pp, 0);
H5F_addr_encode(f, pp, HADDR_UNDEF);
UINT32ENCODE(*pp, H5G_NOTHING_CACHED);
UINT32ENCODE(*pp, 0); /*reserved*/
- }
+ } /* end else */
/* fill with zero */
while(*pp < p_ret)
*(*pp)++ = 0;
*pp = p_ret;
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_ent_encode() */
/*-------------------------------------------------------------------------
@@ -495,7 +471,7 @@ H5G_ent_debug(const H5G_entry_t *ent, FILE *stream, int indent, int fwidth,
"Link value offset:",
(unsigned long)(ent->cache.slink.lval_offset));
if(heap) {
- lval = H5HL_offset_into(ent->file, heap, ent->cache.slink.lval_offset);
+ lval = (const char *)H5HL_offset_into(ent->file, heap, ent->cache.slink.lval_offset);
HDfprintf(stream, "%*s%-*s %s\n", nested_indent, "", nested_fwidth,
"Link value:",
lval);
diff --git a/src/H5Gint.c b/src/H5Gint.c
index 61598c2..0dc9c03 100644
--- a/src/H5Gint.c
+++ b/src/H5Gint.c
@@ -94,9 +94,16 @@ DESCRIPTION
static herr_t
H5G_init_int_interface(void)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_init_int_interface)
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_LEAVE_NOAPI(H5G_init())
+ FUNC_ENTER_NOAPI(H5G_init_int_interface, FAIL)
+
+ /* Funnel all work to H5G_init() */
+ if(H5G_init() < 0)
+ HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "interface initialization failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5G_init_int_interface() */
diff --git a/src/H5Glink.c b/src/H5Glink.c
index 75a3e83..488c05b 100644
--- a/src/H5Glink.c
+++ b/src/H5Glink.c
@@ -41,6 +41,7 @@
#include "H5Iprivate.h" /* IDs */
#include "H5Lprivate.h" /* Links */
#include "H5MMprivate.h" /* Memory management */
+#include "H5Ppublic.h" /* Property Lists */
/****************/
@@ -240,7 +241,7 @@ H5G_ent_to_link(H5F_t *f, H5O_link_t *lnk, const H5HL_t *heap,
if(ent->type == H5G_CACHED_SLINK) {
const char *s; /* Pointer to link value */
- s = H5HL_offset_into(f, heap, ent->cache.slink.lval_offset);
+ s = (const char *)H5HL_offset_into(f, heap, ent->cache.slink.lval_offset);
HDassert(s);
/* Copy the link value */
@@ -295,7 +296,7 @@ H5G_ent_to_info(H5F_t *f, H5L_info_t *info, const H5HL_t *heap,
if(ent->type == H5G_CACHED_SLINK) {
const char *s; /* Pointer to link value */
- s = H5HL_offset_into(f, heap, ent->cache.slink.lval_offset);
+ s = (const char *)H5HL_offset_into(f, heap, ent->cache.slink.lval_offset);
HDassert(s);
/* Get the link value size */
@@ -319,7 +320,7 @@ H5G_ent_to_info(H5F_t *f, H5L_info_t *info, const H5HL_t *heap,
/*-------------------------------------------------------------------------
* Function: H5G_link_to_info
*
- * Purpose: Retrieve information from a link object
+ * Purpose: Retrieve information from a link object
*
* Return: Non-negative on success/Negative on failure
*
@@ -376,7 +377,7 @@ H5G_link_to_info(const H5O_link_t *lnk, H5L_info_t *info)
if((cb_ret = (link_class->query_func)(lnk->name, lnk->u.ud.udata, lnk->u.ud.size, NULL, (size_t)0)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "query buffer size callback returned failure")
- info->u.val_size = cb_ret;
+ info->u.val_size = (size_t)cb_ret;
} /* end if */
else
info->u.val_size = 0;
@@ -392,7 +393,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5G_link_to_loc
*
- * Purpose: Build group location from group and link object
+ * Purpose: Build group location from group and link object
*
* Return: Non-negative on success/Negative on failure
*
@@ -486,7 +487,7 @@ H5G_link_copy_file(H5F_t *dst_file, hid_t dxpl_id, const H5O_link_t *_src_lnk,
/* Check if the object pointed by the soft link exists in the source file */
if(H5G_loc_info(&grp_loc, tmp_src_lnk.u.soft.name, FALSE, &oinfo, H5P_DEFAULT, dxpl_id) >= 0) {
/* Convert soft link to hard link */
- tmp_src_lnk.u.soft.name = H5MM_xfree(tmp_src_lnk.u.soft.name);
+ tmp_src_lnk.u.soft.name = (char *)H5MM_xfree(tmp_src_lnk.u.soft.name);
tmp_src_lnk.type = H5L_TYPE_HARD;
tmp_src_lnk.u.hard.addr = oinfo.addr;
src_lnk = &tmp_src_lnk;
@@ -608,7 +609,7 @@ H5G_link_iterate_table(const H5G_link_table_t *ltable, hsize_t skip,
size_t u; /* Local index variable */
herr_t ret_value = H5_ITER_CONT; /* Return value */
- FUNC_ENTER_NOAPI(H5G_link_iterate_table, FAIL)
+ FUNC_ENTER_NOAPI_NOERR(H5G_link_iterate_table, -)
/* Sanity check */
HDassert(ltable);
diff --git a/src/H5Gloc.c b/src/H5Gloc.c
index fc02539..47214a4 100644
--- a/src/H5Gloc.c
+++ b/src/H5Gloc.c
@@ -161,7 +161,7 @@ H5G_loc(hid_t loc_id, H5G_loc_t *loc)
H5F_t *f;
/* Get the file struct */
- if(NULL == (f = H5I_object(loc_id)))
+ if(NULL == (f = (H5F_t *)H5I_object(loc_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file ID")
/* Construct a group location for root group of the file */
@@ -183,7 +183,7 @@ H5G_loc(hid_t loc_id, H5G_loc_t *loc)
{
H5G_t *group;
- if(NULL == (group = H5I_object(loc_id)))
+ if(NULL == (group = (H5G_t *)H5I_object(loc_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid group ID")
if(NULL == (loc->oloc = H5G_oloc(group)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of group")
@@ -196,7 +196,7 @@ H5G_loc(hid_t loc_id, H5G_loc_t *loc)
{
H5T_t *dt;
- if(NULL == (dt = H5I_object(loc_id)))
+ if(NULL == (dt = (H5T_t *)H5I_object(loc_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid type ID")
if(NULL == (loc->oloc = H5T_oloc(dt)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of datatype")
@@ -212,7 +212,7 @@ H5G_loc(hid_t loc_id, H5G_loc_t *loc)
{
H5D_t *dset;
- if(NULL == (dset = H5I_object(loc_id)))
+ if(NULL == (dset = (H5D_t *)H5I_object(loc_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid data ID")
if(NULL == (loc->oloc = H5D_oloc(dset)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of dataset")
@@ -225,7 +225,7 @@ H5G_loc(hid_t loc_id, H5G_loc_t *loc)
{
H5A_t *attr;
- if(NULL == (attr = H5I_object(loc_id)))
+ if(NULL == (attr = (H5A_t *)H5I_object(loc_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid attribute ID")
if(NULL == (loc->oloc = H5A_oloc(attr)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of attribute")
@@ -409,7 +409,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_loc_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name,
+H5G_loc_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char *name,
const H5O_link_t UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
H5G_own_loc_t *own_loc/*out*/)
{
@@ -420,7 +420,7 @@ H5G_loc_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name,
/* Check if the name in this group resolved to a valid object */
if(obj_loc == NULL)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object doesn't exist")
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object '%s' doesn't exist", name)
/* Take ownership of the object's group location */
/* (Group traversal callbacks are responsible for either taking ownership
@@ -727,6 +727,7 @@ H5G_loc_set_comment_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name,
{
H5G_loc_sc_t *udata = (H5G_loc_sc_t *)_udata; /* User data passed in */
H5O_name_t comment; /* Object header "comment" message */
+ htri_t exists; /* Whether a "comment" message already exists */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5G_loc_set_comment_cb)
@@ -735,9 +736,14 @@ H5G_loc_set_comment_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name,
if(obj_loc == NULL)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
+ /* Check for existing comment message */
+ if((exists = H5O_msg_exists(obj_loc->oloc, H5O_NAME_ID, udata->dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read object header")
+
/* Remove the previous comment message if any */
- if(H5O_msg_remove(obj_loc->oloc, H5O_NAME_ID, 0, TRUE, udata->dxpl_id) < 0)
- H5E_clear_stack(NULL);
+ if(exists)
+ if(H5O_msg_remove(obj_loc->oloc, H5O_NAME_ID, 0, TRUE, udata->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete existing comment object header message")
/* Add the new message */
if(udata->comment && *udata->comment) {
@@ -830,7 +836,7 @@ H5G_loc_get_comment_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name,
} else {
if(udata->comment && udata->bufsize)
HDstrncpy(udata->comment, comment.s, udata->bufsize);
- udata->comment_size = HDstrlen(comment.s);
+ udata->comment_size = (ssize_t)HDstrlen(comment.s);
H5O_msg_reset(H5O_NAME_ID, &comment);
} /* end else */
diff --git a/src/H5Gname.c b/src/H5Gname.c
index c5fc2c1..581b649 100644
--- a/src/H5Gname.c
+++ b/src/H5Gname.c
@@ -452,17 +452,17 @@ H5G_get_name(hid_t id, char *name/*out*/, size_t size, hid_t lapl_id,
hid_t file;
/* Retrieve file ID for name search */
- if((file = H5I_get_file_id(id)) < 0)
+ if((file = H5I_get_file_id(id, FALSE)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve file ID")
/* Search for name of object */
if((len = H5G_get_name_by_addr(file, lapl_id, dxpl_id, loc.oloc, name, size)) < 0) {
- H5I_dec_ref(file);
+ H5I_dec_ref(file, FALSE);
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't determine name")
} /* end if */
-
+
/* Close file ID used for search */
- if(H5I_dec_ref(file) < 0)
+ if(H5I_dec_ref(file, FALSE) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTCLOSEFILE, FAIL, "can't determine name")
} /* end else */
@@ -470,7 +470,7 @@ H5G_get_name(hid_t id, char *name/*out*/, size_t size, hid_t lapl_id,
ret_value = len;
} /* end if */
-done:
+done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_get_name() */
@@ -578,7 +578,6 @@ H5G_name_move_path(H5RS_str_t **path_r_ptr, const char *full_suffix, const char
if(full_suffix_len < path_len) {
const char *dst_suffix; /* Destination suffix that changes */
const char *src_suffix; /* Source suffix that changes */
- const char *path_prefix; /* Prefix for path */
size_t path_prefix_len; /* Length of path prefix */
const char *path_prefix2; /* 2nd prefix for path */
size_t path_prefix2_len; /* Length of 2nd path prefix */
@@ -589,7 +588,6 @@ H5G_name_move_path(H5RS_str_t **path_r_ptr, const char *full_suffix, const char
/* Compute path prefix before full suffix*/
- path_prefix = path;
path_prefix_len = path_len - full_suffix_len;
/* Determine the common prefix for src & dst paths */
@@ -914,7 +912,7 @@ done:
*/
herr_t
H5G_name_replace(const H5O_link_t *lnk, H5G_names_op_t op, H5F_t *src_file,
- H5RS_str_t *src_full_path_r, H5F_t *dst_file, H5RS_str_t *dst_full_path_r,
+ H5RS_str_t *src_full_path_r, H5F_t *dst_file, H5RS_str_t *dst_full_path_r,
hid_t dxpl_id)
{
herr_t ret_value = SUCCEED;
@@ -1009,15 +1007,15 @@ H5G_name_replace(const H5O_link_t *lnk, H5G_names_op_t op, H5F_t *src_file,
/* Search through group IDs */
if(search_group)
- H5I_search(H5I_GROUP, H5G_name_replace_cb, &names);
+ H5I_search(H5I_GROUP, H5G_name_replace_cb, &names, FALSE);
/* Search through dataset IDs */
if(search_dataset)
- H5I_search(H5I_DATASET, H5G_name_replace_cb, &names);
+ H5I_search(H5I_DATASET, H5G_name_replace_cb, &names, FALSE);
/* Search through datatype IDs */
if(search_datatype)
- H5I_search(H5I_DATATYPE, H5G_name_replace_cb, &names);
+ H5I_search(H5I_DATATYPE, H5G_name_replace_cb, &names, FALSE);
} /* end if */
} /* end if */
@@ -1086,8 +1084,8 @@ H5G_get_name_by_addr_cb(hid_t gid, const char *path, const H5L_info_t *linfo,
HGOTO_DONE(H5_ITER_STOP)
} /* end if */
} /* end if */
-
-done:
+
+done:
if(obj_found && H5G_loc_free(&obj_loc) < 0)
HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, H5_ITER_ERROR, "can't free location")
@@ -1137,7 +1135,7 @@ H5G_get_name_by_addr(hid_t file, hid_t lapl_id, hid_t dxpl_id, const H5O_loc_t *
udata.lapl_id = lapl_id;
udata.dxpl_id = dxpl_id;
udata.path = NULL;
-
+
/* Visit all the links in the file */
if((status = H5G_visit(file, "/", H5_INDEX_NAME, H5_ITER_NATIVE, H5G_get_name_by_addr_cb, &udata, lapl_id, dxpl_id)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "group traversal failed while looking for object name")
@@ -1147,10 +1145,8 @@ H5G_get_name_by_addr(hid_t file, hid_t lapl_id, hid_t dxpl_id, const H5O_loc_t *
/* Check for finding the object */
if(found_obj) {
- size_t full_path_len = HDstrlen(udata.path) + 1; /* Length of path + 1 (for "/") */
-
/* Set the length of the full path */
- ret_value = full_path_len;
+ ret_value = (ssize_t)(HDstrlen(udata.path) + 1); /* Length of path + 1 (for "/") */
/* If there's a buffer provided, copy into it, up to the limit of its size */
if(name) {
@@ -1166,8 +1162,8 @@ H5G_get_name_by_addr(hid_t file, hid_t lapl_id, hid_t dxpl_id, const H5O_loc_t *
} /* end if */
else
ret_value = 0;
-
-done:
+
+done:
/* Release resources */
H5MM_xfree(udata.path);
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index 3dcf7a1..ce41727 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -39,7 +39,7 @@
#include "H5HLprivate.h" /* Local Heaps */
#include "H5MFprivate.h" /* File memory management */
#include "H5MMprivate.h" /* Memory management */
-#include "H5WBprivate.h" /* Wrapped Buffers */
+#include "H5Ppublic.h" /* Property Lists */
/* Private typedefs */
@@ -51,39 +51,12 @@ typedef struct H5G_node_key_t {
size_t offset; /*offset into heap for name */
} H5G_node_key_t;
-/*
- * A symbol table node is a collection of symbol table entries. It can
- * be thought of as the lowest level of the B-link tree that points to
- * a collection of symbol table entries that belong to a specific symbol
- * table or group.
- */
-typedef struct H5G_node_t {
- H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */
- /* first field in structure */
- unsigned nsyms; /*number of symbols */
- H5G_entry_t *entry; /*array of symbol table entries */
-} H5G_node_t;
-
/* Private macros */
-#define H5G_NODE_VERS 1 /*symbol table node version number */
-#define H5G_NODE_SIZEOF_HDR(F) (H5G_NODE_SIZEOF_MAGIC + 4)
-/* Size of stack buffer for serialized nodes */
-#define H5G_NODE_BUF_SIZE 512
+#define H5G_NODE_SIZEOF_HDR(F) (H5_SIZEOF_MAGIC + 4)
/* PRIVATE PROTOTYPES */
-static herr_t H5G_node_serialize(H5F_t *f, H5G_node_t *sym, size_t size, uint8_t *buf);
-static size_t H5G_node_size_real(const H5F_t *f);
-
-/* Metadata cache callbacks */
-static H5G_node_t *H5G_node_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata1,
- void *_udata2);
-static herr_t H5G_node_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
- H5G_node_t *sym, unsigned UNUSED * flags_ptr);
-static herr_t H5G_node_dest(H5F_t *f, H5G_node_t *sym);
-static herr_t H5G_node_clear(H5F_t *f, H5G_node_t *sym, hbool_t destroy);
-static herr_t H5G_node_size(const H5F_t *f, const H5G_node_t *sym, size_t *size_ptr);
/* B-tree callbacks */
static H5RC_t *H5G_node_get_shared(const H5F_t *f, const void *_udata);
@@ -94,7 +67,7 @@ static int H5G_node_cmp2(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata,
void *_rt_key);
static int H5G_node_cmp3(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata,
void *_rt_key);
-static herr_t H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_lt_key,
+static htri_t H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_lt_key,
void *_udata);
static H5B_ins_t H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
hbool_t *lt_key_changed, void *_md_key,
@@ -112,16 +85,6 @@ static herr_t H5G_node_debug_key(FILE *stream, H5F_t *f, hid_t dxpl_id,
int indent, int fwidth, const void *key,
const void *udata);
-/* H5G inherits cache-like properties from H5AC */
-const H5AC_class_t H5AC_SNODE[1] = {{
- H5AC_SNODE_ID,
- (H5AC_load_func_t)H5G_node_load,
- (H5AC_flush_func_t)H5G_node_flush,
- (H5AC_dest_func_t)H5G_node_dest,
- (H5AC_clear_func_t)H5G_node_clear,
- (H5AC_size_func_t)H5G_node_size,
-}};
-
/* H5G inherits B-tree like properties from H5B */
H5B_class_t H5B_SNODE[1] = {{
H5B_SNODE_ID, /*id */
@@ -141,10 +104,10 @@ H5B_class_t H5B_SNODE[1] = {{
}};
/* Declare a free list to manage the H5G_node_t struct */
-H5FL_DEFINE_STATIC(H5G_node_t);
+H5FL_DEFINE(H5G_node_t);
/* Declare a free list to manage sequences of H5G_entry_t's */
-H5FL_SEQ_DEFINE_STATIC(H5G_entry_t);
+H5FL_SEQ_DEFINE(H5G_entry_t);
/*-------------------------------------------------------------------------
@@ -273,7 +236,7 @@ H5G_node_debug_key(FILE *stream, H5F_t *f, hid_t UNUSED dxpl_id, int indent,
HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Name:");
- s = H5HL_offset_into(f, udata->heap, key->offset);
+ s = (const char *)H5HL_offset_into(f, udata->heap, key->offset);
HDfprintf(stream, "%s\n", s);
} /* end if */
else
@@ -298,7 +261,7 @@ H5G_node_debug_key(FILE *stream, H5F_t *f, hid_t UNUSED dxpl_id, int indent,
*
*-------------------------------------------------------------------------
*/
-static size_t
+size_t
H5G_node_size_real(const H5F_t *f)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_size_real);
@@ -309,355 +272,6 @@ H5G_node_size_real(const H5F_t *f)
/*-------------------------------------------------------------------------
- * Function: H5G_node_load
- *
- * Purpose: Loads a symbol table node from the file.
- *
- * Return: Success: Ptr to the new table.
- * Failure: NULL
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Jun 23 1997
- *
- *-------------------------------------------------------------------------
- */
-static H5G_node_t *
-H5G_node_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_udata1,
- void UNUSED * _udata2)
-{
- H5G_node_t *sym = NULL;
- size_t size;
- H5WB_t *wb = NULL; /* Wrapped buffer for node data */
- uint8_t node_buf[H5G_NODE_BUF_SIZE]; /* Buffer for node */
- uint8_t *node; /* Pointer to node buffer */
- const uint8_t *p;
- H5G_node_t *ret_value; /*for error handling */
-
- FUNC_ENTER_NOAPI_NOINIT(H5G_node_load)
-
- /*
- * Check arguments.
- */
- HDassert(f);
- HDassert(H5F_addr_defined(addr));
- HDassert(!_udata1);
- HDassert(NULL == _udata2);
-
- /*
- * Initialize variables.
- */
-
- /* Wrap the local buffer for serialized node info */
- if(NULL == (wb = H5WB_wrap(node_buf, sizeof(node_buf))))
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't wrap buffer")
-
- /* Compute the size of the serialized symbol table node on disk */
- size = H5G_node_size_real(f);
-
- /* Get a pointer to a buffer that's large enough for node */
- if(NULL == (node = H5WB_actual(wb, size)))
- HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't get actual buffer")
-
- /* Read the serialized symbol table node. */
- if(H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, node) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_READERROR, NULL, "unable to read symbol table node")
-
- /* Get temporary pointer to serialized node */
- p = node;
-
- /* magic */
- if(HDmemcmp(p, H5G_NODE_MAGIC, (size_t)H5G_NODE_SIZEOF_MAGIC))
- HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "bad symbol table node signature")
- p += 4;
-
- /* version */
- if(H5G_NODE_VERS != *p++)
- HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "bad symbol table node version")
-
- /* reserved */
- p++;
-
- /* Allocate symbol table data structures */
- if(NULL == (sym = H5FL_CALLOC(H5G_node_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- if(NULL == (sym->entry = H5FL_SEQ_CALLOC(H5G_entry_t, (size_t)(2 * H5F_SYM_LEAF_K(f)))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
- /* number of symbols */
- UINT16DECODE(p, sym->nsyms);
-
- /* entries */
- if(H5G_ent_decode_vec(f, &p, sym->entry, sym->nsyms) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "unable to decode symbol table entries")
-
- /* Set return value */
- ret_value = sym;
-
-done:
- /* Release resources */
- if(wb && H5WB_unwrap(wb) < 0)
- HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
- if(!ret_value)
- if(sym && H5G_node_dest(f, sym) < 0)
- HDONE_ERROR(H5E_SYM, H5E_CANTFREE, NULL, "unable to destroy symbol table node")
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_node_load() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_node_flush
- *
- * Purpose: Flush a symbol table node to disk.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Jun 23 1997
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5G_node_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5G_node_t *sym, unsigned UNUSED * flags_ptr)
-{
- H5WB_t *wb = NULL; /* Wrapped buffer for node data */
- uint8_t node_buf[H5G_NODE_BUF_SIZE]; /* Buffer for node */
- unsigned u;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5G_node_flush)
-
- /*
- * Check arguments.
- */
- HDassert(f);
- HDassert(H5F_addr_defined(addr));
- HDassert(sym);
-
- /*
- * Look for dirty entries and set the node dirty flag.
- */
- for(u = 0; u < sym->nsyms; u++)
- if(sym->entry[u].dirty) {
- /* Set the node's dirty flag */
- sym->cache_info.is_dirty = TRUE;
-
- /* Reset the entry's dirty flag */
- sym->entry[u].dirty = FALSE;
- } /* end if */
-
- /*
- * Write the symbol node to disk.
- */
- if(sym->cache_info.is_dirty) {
- uint8_t *node; /* Pointer to node buffer */
- size_t size;
-
- /* Wrap the local buffer for serialized node info */
- if(NULL == (wb = H5WB_wrap(node_buf, sizeof(node_buf))))
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wrap buffer")
-
- /* Compute the size of the serialized symbol table node on disk */
- size = H5G_node_size_real(f);
-
- /* Get a pointer to a buffer that's large enough for node */
- if(NULL == (node = H5WB_actual(wb, size)))
- HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't get actual buffer")
-
- /* Serialize symbol table node into buffer */
- if(H5G_node_serialize(f, sym, size, node) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTSERIALIZE, FAIL, "node serialization failed")
-
- /* Write the serialized symbol table node. */
- if(H5F_block_write(f, H5FD_MEM_BTREE, addr, size, dxpl_id, node) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "unable to write symbol table node to the file")
-
- /* Reset the node's dirty flag */
- sym->cache_info.is_dirty = FALSE;
- } /* end if */
-
- /*
- * Destroy the symbol node? This might happen if the node is being
- * preempted from the cache.
- */
- if(destroy)
- if(H5G_node_dest(f, sym) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to destroy symbol table node")
-
-done:
- /* Release resources */
- if(wb && H5WB_unwrap(wb) < 0)
- HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_node_flush() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_node_serialize
- *
- * Purpose: Serialize the symbol table node
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Bill Wendling
- * wendling@ncsa.uiuc.edu
- * Sept. 16, 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5G_node_serialize(H5F_t *f, H5G_node_t *sym, size_t size, uint8_t *buf)
-{
- uint8_t *p;
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI_NOINIT(H5G_node_serialize);
-
- /* check args */
- assert(f);
- assert(sym);
- assert(buf);
-
- p = buf;
-
- /* magic number */
- HDmemcpy(p, H5G_NODE_MAGIC, (size_t)H5G_NODE_SIZEOF_MAGIC);
- p += 4;
-
- /* version number */
- *p++ = H5G_NODE_VERS;
-
- /* reserved */
- *p++ = 0;
-
- /* number of symbols */
- UINT16ENCODE(p, sym->nsyms);
-
- /* entries */
- if(H5G_ent_encode_vec(f, &p, sym->entry, sym->nsyms) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "can't serialize")
- HDmemset(p, 0, size - (p - buf));
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_node_serialize() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_node_dest
- *
- * Purpose: Destroy a symbol table node in memory.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Jan 15 2003
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5G_node_dest(H5F_t UNUSED *f, H5G_node_t *sym)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_dest)
-
- /* Check arguments */
- HDassert(sym);
-
- /* Verify that node is clean */
- HDassert(sym->cache_info.is_dirty == FALSE);
-
- if(sym->entry)
- sym->entry = H5FL_SEQ_FREE(H5G_entry_t, sym->entry);
- H5FL_FREE(H5G_node_t, sym);
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5G_node_dest() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_node_clear
- *
- * Purpose: Mark a symbol table node in memory as non-dirty.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Mar 20 2003
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5G_node_clear(H5F_t *f, H5G_node_t *sym, hbool_t destroy)
-{
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI_NOINIT(H5G_node_clear)
-
- /*
- * Check arguments.
- */
- HDassert(sym);
-
- /* Look for dirty entries and reset their dirty flag. */
- for(u = 0; u < sym->nsyms; u++)
- sym->entry[u].dirty = FALSE;
- sym->cache_info.is_dirty = FALSE;
-
- /*
- * Destroy the symbol node? This might happen if the node is being
- * preempted from the cache.
- */
- if(destroy)
- if(H5G_node_dest(f, sym) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to destroy symbol table node")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_node_clear() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_node_size
- *
- * Purpose: Compute the size in bytes of the specified instance of
- * H5G_node_t 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: John Mainzer
- * 5/13/04
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5G_node_size(const H5F_t *f, const H5G_node_t UNUSED *sym, size_t *size_ptr)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_size)
-
- /*
- * Check arguments.
- */
- HDassert(f);
- HDassert(size_ptr);
-
- *size_ptr = H5G_node_size_real(f);
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5G_node_size() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5G_node_create
*
* Purpose: Creates a new empty symbol table node. This function is
@@ -680,11 +294,11 @@ static herr_t
H5G_node_create(H5F_t *f, hid_t dxpl_id, H5B_ins_t UNUSED op, void *_lt_key,
void UNUSED *_udata, void *_rt_key, haddr_t *addr_p/*out*/)
{
- H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key;
- H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key;
- H5G_node_t *sym = NULL;
- hsize_t size = 0;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5G_node_key_t *lt_key = (H5G_node_key_t *)_lt_key;
+ H5G_node_key_t *rt_key = (H5G_node_key_t *)_rt_key;
+ H5G_node_t *sym = NULL;
+ hsize_t size = 0;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5G_node_create)
@@ -700,9 +314,9 @@ H5G_node_create(H5F_t *f, hid_t dxpl_id, H5B_ins_t UNUSED op, void *_lt_key,
HDassert(size);
if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, size)))
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to allocate file space")
+ if(NULL == (sym->entry = H5FL_SEQ_CALLOC(H5G_entry_t, (size_t)(2 * H5F_SYM_LEAF_K(f)))))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTALLOC, FAIL, "memory allocation failed")
- if(NULL == ( sym->entry = H5FL_SEQ_CALLOC(H5G_entry_t, (size_t)(2 * H5F_SYM_LEAF_K(f)))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
if(H5AC_set(f, dxpl_id, H5AC_SNODE, *addr_p, sym, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to cache symbol table leaf node")
/*
@@ -720,8 +334,8 @@ done:
if(ret_value < 0) {
if(sym != NULL) {
if(sym->entry != NULL)
- H5FL_SEQ_FREE(H5G_entry_t, sym->entry);
- H5FL_FREE(H5G_node_t, sym);
+ sym->entry = H5FL_SEQ_FREE(H5G_entry_t, sym->entry);
+ sym = H5FL_FREE(H5G_node_t, sym);
} /* end if */
} /* end if */
@@ -771,7 +385,7 @@ H5G_node_cmp2(H5F_t *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_udata,
HDassert(rt_key);
/* Get base address of heap */
- base = H5HL_offset_into(f, udata->heap, (size_t)0);
+ base = (const char *)H5HL_offset_into(f, udata->heap, (size_t)0);
HDassert(base);
/* Get pointers to string names */
@@ -831,7 +445,7 @@ H5G_node_cmp3(H5F_t *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_udata,
HDassert(rt_key);
/* Get base address of heap */
- base = H5HL_offset_into(f, udata->heap, (size_t)0);
+ base = (const char *)H5HL_offset_into(f, udata->heap, (size_t)0);
HDassert(base);
/* left side */
@@ -864,8 +478,8 @@ H5G_node_cmp3(H5F_t *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_udata,
* entry field. Otherwise the entry is copied from the
* UDATA entry field to the symbol table.
*
- * Return: Success: Non-negative if found and data returned through
- * the UDATA pointer.
+ * Return: Success: Non-negative (TRUE/FALSE) if found and data
+ * returned through the UDATA pointer.
*
* Failure: Negative if not found.
*
@@ -875,7 +489,7 @@ H5G_node_cmp3(H5F_t *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_udata,
*
*-------------------------------------------------------------------------
*/
-static herr_t
+static htri_t
H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_lt_key,
void *_udata)
{
@@ -884,8 +498,8 @@ H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_lt_key
unsigned lt = 0, idx = 0, rt;
int cmp = 1;
const char *s;
- const char *base; /* Base of heap */
- herr_t ret_value = SUCCEED; /* Return value */
+ const char *base; /* Base of heap */
+ htri_t ret_value = TRUE; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5G_node_found)
@@ -899,11 +513,11 @@ H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_lt_key
/*
* Load the symbol table node for exclusive access.
*/
- if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to protect symbol table node")
/* Get base address of heap */
- base = H5HL_offset_into(f, udata->common.heap, (size_t)0);
+ base = (const char *)H5HL_offset_into(f, udata->common.heap, (size_t)0);
HDassert(base);
/*
@@ -922,7 +536,7 @@ H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_lt_key
} /* end while */
if(cmp)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found")
+ HGOTO_DONE(FALSE)
/* Call user's callback operator */
if((udata->op)(&sn->entry[idx], udata->op_data) < 0)
@@ -1005,11 +619,11 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr,
/*
* Load the symbol node.
*/
- if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to protect symbol table node")
/* Get base address of heap */
- base = H5HL_offset_into(f, udata->common.heap, (size_t)0);
+ base = (const char *)H5HL_offset_into(f, udata->common.heap, (size_t)0);
HDassert(base);
/*
@@ -1017,7 +631,7 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr,
*/
rt = sn->nsyms;
while(lt < rt) {
- idx = (lt + rt) / 2;
+ idx = (int)((lt + rt) / 2);
s = base + sn->entry[idx].name_off;
/* Check if symbol is already present */
@@ -1025,9 +639,9 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr,
HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_INS_ERROR, "symbol is already present in symbol table")
if (cmp < 0)
- rt = idx;
+ rt = (unsigned)idx;
else
- lt = idx + 1;
+ lt = (unsigned)(idx + 1);
} /* end while */
idx += cmp > 0 ? 1 : 0;
@@ -1048,7 +662,7 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr,
if(H5G_node_create(f, dxpl_id, H5B_INS_FIRST, NULL, NULL, NULL, new_node_p/*out*/) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_INS_ERROR, "unable to split symbol table node")
- if(NULL == (snrt = H5AC_protect(f, dxpl_id, H5AC_SNODE, *new_node_p, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (snrt = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, *new_node_p, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to split symbol table node")
HDmemcpy(snrt->entry, sn->entry + H5F_SYM_LEAF_K(f),
@@ -1070,15 +684,17 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr,
insert_into = sn;
if(idx == (int)H5F_SYM_LEAF_K(f))
md_key->offset = ent.name_off;
- } else {
+ } /* end if */
+ else {
idx -= H5F_SYM_LEAF_K(f);
insert_into = snrt;
- if(idx == (int)H5F_SYM_LEAF_K (f)) {
+ if(idx == (int)H5F_SYM_LEAF_K(f)) {
rt_key->offset = ent.name_off;
*rt_key_changed = TRUE;
} /* end if */
} /* end else */
- } else {
+ } /* end if */
+ else {
/* Where to insert the new entry? */
ret_value = H5B_INS_NOOP;
sn_flags |= H5AC__DIRTIED_FLAG;
@@ -1165,7 +781,7 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
HDassert(udata && udata->common.heap);
/* Load the symbol table */
- if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to protect symbol table node")
/* "Normal" removal of a single entry from the symbol table node */
@@ -1175,7 +791,7 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
const char *base; /* Base of heap */
/* Get base address of heap */
- base = H5HL_offset_into(f, udata->common.heap, (size_t)0);
+ base = (const char *)H5HL_offset_into(f, udata->common.heap, (size_t)0);
/* Find the name with a binary search */
rt = sn->nsyms;
@@ -1195,8 +811,8 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "name not found")
/* Get a pointer to the name of the link */
- if(NULL == (lnk.name = H5HL_offset_into(f, udata->common.heap, sn->entry[idx].name_off)))
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get link name")
+ if(NULL == (lnk.name = (char *)H5HL_offset_into(f, udata->common.heap, sn->entry[idx].name_off)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5B_INS_ERROR, "unable to get link name")
/* Set up rest of link structure */
lnk.corder_valid = FALSE;
@@ -1204,7 +820,7 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
lnk.cset = H5T_CSET_ASCII;
if(sn->entry[idx].type == H5G_CACHED_SLINK) {
lnk.type = H5L_TYPE_SOFT;
- lnk.u.soft.name = H5HL_offset_into(f, udata->common.heap, sn->entry[idx].cache.slink.lval_offset);
+ lnk.u.soft.name = (char *)H5HL_offset_into(f, udata->common.heap, sn->entry[idx].cache.slink.lval_offset);
} /* end if */
else {
lnk.type = H5L_TYPE_HARD;
@@ -1214,7 +830,7 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
/* Replace any object names */
if(H5G_link_name_replace(f, dxpl_id, udata->grp_full_path_r, &lnk) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object type")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5B_INS_ERROR, "unable to get object type")
/* Decrement the ref. count for hard links */
if(lnk.type == H5L_TYPE_HARD) {
@@ -1253,14 +869,8 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
*rt_key = *lt_key;
*rt_key_changed = TRUE;
sn->nsyms = 0;
- if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)H5G_node_size_real(f)) < 0
- || H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__DIRTIED_FLAG | H5C__DELETED_FLAG) < 0) {
- sn = NULL;
- HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to free symbol table node")
- } /* end if */
- sn = NULL;
+ sn_flags |= H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG;
ret_value = H5B_INS_REMOVE;
-
} else if(0 == idx) {
/*
* We are about to remove the left-most entry from the symbol table
@@ -1272,7 +882,6 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
HDmemmove(sn->entry + idx, sn->entry + idx + 1,
(sn->nsyms-idx) * sizeof(H5G_entry_t));
ret_value = H5B_INS_NOOP;
-
} else if (idx + 1 == sn->nsyms) {
/*
* We are about to remove the right-most entry from the symbol table
@@ -1284,7 +893,6 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
rt_key->offset = sn->entry[sn->nsyms - 1].name_off;
*rt_key_changed = TRUE;
ret_value = H5B_INS_NOOP;
-
} else {
/*
* We are about to remove an entry from the middle of a symbol table
@@ -1325,12 +933,7 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
*rt_key = *lt_key;
*rt_key_changed = TRUE;
sn->nsyms = 0;
- if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)H5G_node_size_real(f)) < 0
- || H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__DIRTIED_FLAG | H5C__DELETED_FLAG) < 0) {
- sn = NULL;
- HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to free symbol table node")
- } /* end if */
- sn = NULL;
+ sn_flags |= H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG;
ret_value = H5B_INS_REMOVE;
} /* end else */
@@ -1375,7 +978,7 @@ H5G_node_iterate(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t ad
HDassert(udata && udata->heap);
/* Protect the symbol table node & local heap while we iterate over entries */
- if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node")
/*
@@ -1389,7 +992,7 @@ H5G_node_iterate(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t ad
const char *name; /* Pointer to link name in heap */
/* Get the pointer to the name of the link in the heap */
- name = H5HL_offset_into(f, udata->heap, ents[u].name_off);
+ name = (const char *)H5HL_offset_into(f, udata->heap, ents[u].name_off);
HDassert(name);
/* Convert the entry to a link */
@@ -1452,7 +1055,7 @@ H5G_node_sumup(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr
HDassert(num_objs);
/* Find the object node and add the number of symbol entries. */
- if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node")
*num_objs += sn->nsyms;
@@ -1497,7 +1100,7 @@ H5G_node_by_idx(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t add
HDassert(udata);
/* Get a pointer to the symbol table node */
- if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node");
/* Find the node, locate the object symbol table entry and retrieve the name */
@@ -1635,7 +1238,7 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr,
HDassert(udata);
/* load the symbol table into memory from the source file */
- if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node")
/* get the base address of the heap */
@@ -1703,7 +1306,7 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr,
/* Construct link information for eventual insertion */
lnk.type = H5L_TYPE_SOFT;
- lnk.u.soft.name = H5HL_offset_into(f, heap, src_ent->cache.slink.lval_offset);
+ lnk.u.soft.name = (char *)H5HL_offset_into(f, heap, src_ent->cache.slink.lval_offset);
} /* else if */
else
HDassert(0 && "Unknown entry type");
@@ -1715,7 +1318,7 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr,
/* lnk.name = name; */ /* This will be set in callback */
/* Determine name of source object */
- name = H5HL_offset_into(f, heap, src_ent->name_off);
+ name = (const char *)H5HL_offset_into(f, heap, src_ent->name_off);
HDassert(name);
/* Insert the new object in the destination file's group */
@@ -1770,7 +1373,7 @@ H5G_node_build_table(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_
* Save information about the symbol table node since we can't lock it
* because we're about to call an application function.
*/
- if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node")
/* Check if the link table needs to be extended */
@@ -1779,7 +1382,7 @@ H5G_node_build_table(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_
H5O_link_t *x; /* Pointer to larger array of links */
/* Re-allocate the link table */
- if((x = H5MM_realloc(udata->ltable->lnks, sizeof(H5O_link_t) * na)) == NULL)
+ if(NULL == (x = (H5O_link_t *)H5MM_realloc(udata->ltable->lnks, sizeof(H5O_link_t) * na)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed")
udata->ltable->lnks = x;
} /* end if */
@@ -1790,7 +1393,7 @@ H5G_node_build_table(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_
unsigned linkno; /* Link allocated */
/* Get pointer to link's name in the heap */
- name = H5HL_offset_into(f, udata->heap, sn->entry[u].name_off);
+ name = (const char *)H5HL_offset_into(f, udata->heap, sn->entry[u].name_off);
HDassert(name);
/* Determine the link to operate on in the table */
@@ -1884,7 +1487,7 @@ H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent,
* If we couldn't load the symbol table node, then try loading the
* B-tree node.
*/
- if (NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ))) {
+ if (NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ))) {
H5G_bt_common_t udata; /*data to pass through B-tree */
H5E_clear_stack(NULL); /* discard that error */
@@ -1909,7 +1512,7 @@ H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent,
fprintf(stream, "%*sSymbol %u:\n", indent - 3, "", u);
if(heap) {
- const char *s = H5HL_offset_into(f, heap, sn->entry[u].name_off);
+ const char *s = (const char *)H5HL_offset_into(f, heap, sn->entry[u].name_off);
if(s)
fprintf(stream, "%*s%-*s `%s'\n", indent, "", fwidth, "Name:", s);
diff --git a/src/H5Gobj.c b/src/H5Gobj.c
index 467a471..271501f 100644
--- a/src/H5Gobj.c
+++ b/src/H5Gobj.c
@@ -125,25 +125,88 @@ static herr_t H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo,
*-------------------------------------------------------------------------
*/
herr_t
-H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo,
- const H5O_linfo_t *linfo, hid_t gcpl_id, H5O_loc_t *oloc/*out*/)
+H5G_obj_create(H5F_t *f, hid_t dxpl_id, hid_t gcpl_id, H5O_loc_t *oloc/*out*/)
+{
+ H5P_genplist_t *gc_plist; /* Group creation property list */
+ H5O_ginfo_t ginfo; /* Group info */
+ H5O_linfo_t linfo; /* Link info */
+ H5O_pline_t pline; /* Pipeline */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_obj_create, FAIL)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(oloc);
+
+ /* Get the property list */
+ if(NULL == (gc_plist = (H5P_genplist_t *)H5I_object(gcpl_id)))
+ HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "not a property list")
+
+ /* Get the group info property */
+ if(H5P_get(gc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get group info")
+
+ /* Get the link info property */
+ if(H5P_get(gc_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get group info")
+
+ /* Get the pipeline property */
+ if(H5P_get(gc_plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get group info")
+
+ /* Call the "real" group creation routine now */
+ if(H5G_obj_create_real(f, dxpl_id, &ginfo, &linfo, &pline, gcpl_id, oloc) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "unable to create group")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_obj_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_obj_create_real
+ *
+ * Purpose: Create an object header for a group and update object location info
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 29 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo,
+ const H5O_linfo_t *linfo, const H5O_pline_t *pline, hid_t gcpl_id,
+ H5O_loc_t *oloc/*out*/)
{
size_t hdr_size; /* Size of object header to request */
hbool_t use_latest_format; /* Flag indicating the new group format should be used */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5G_obj_create, FAIL)
+ FUNC_ENTER_NOAPI(H5G_obj_create_real, FAIL)
/*
* Check arguments.
*/
HDassert(f);
HDassert(ginfo);
+ HDassert(linfo);
+ HDassert(pline);
HDassert(oloc);
+ /* Check for invalid access request */
+ if(0 == (f->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "no write intent on file")
+
/* Check for using the latest version of the group format */
/* (add more checks for creating "new format" groups when needed) */
- if(H5F_USE_LATEST_FORMAT(f) || linfo->track_corder)
+ if(H5F_USE_LATEST_FORMAT(f) || linfo->track_corder
+ || (pline && pline->nused))
use_latest_format = TRUE;
else
use_latest_format = FALSE;
@@ -160,6 +223,7 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo,
char null_char = '\0'; /* Character for creating null string */
size_t ginfo_size; /* Size of the group info message */
size_t linfo_size; /* Size of the link info message */
+ size_t pline_size = 0; /* Size of the pipeline message */
size_t link_size; /* Size of a link message */
/* Calculate message size infomation, for creating group's object header */
@@ -169,6 +233,11 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo,
ginfo_size = H5O_msg_size_f(f, gcpl_id, H5O_GINFO_ID, ginfo, (size_t)0);
HDassert(ginfo_size);
+ if(pline && pline->nused) {
+ pline_size = H5O_msg_size_f(f, gcpl_id, H5O_PLINE_ID, pline, (size_t)0);
+ HDassert(pline_size);
+ } /* end if */
+
lnk.type = H5L_TYPE_HARD;
lnk.corder = 0;
lnk.corder_valid = linfo->track_corder;
@@ -180,10 +249,11 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo,
/* Compute size of header to use for creation */
hdr_size = linfo_size +
ginfo_size +
+ pline_size +
(ginfo->est_num_entries * link_size);
} /* end if */
- else
- hdr_size = 4 + 2 * H5F_SIZEOF_ADDR(f);
+ else
+ hdr_size = (size_t)(4 + 2 * H5F_SIZEOF_ADDR(f));
/*
* Create group's object header. It has a zero link count
@@ -196,12 +266,17 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo,
/* Check for format of group to create */
if(use_latest_format) {
/* Insert link info message */
- if(H5O_msg_create(oloc, H5O_LINFO_ID, 0, 0, linfo, dxpl_id) < 0)
+ if(H5O_msg_create(oloc, H5O_LINFO_ID, 0, H5O_UPDATE_TIME, linfo, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message")
/* Insert group info message */
- if(H5O_msg_create(oloc, H5O_GINFO_ID, H5O_MSG_FLAG_CONSTANT, H5O_UPDATE_TIME, ginfo, dxpl_id) < 0)
+ if(H5O_msg_create(oloc, H5O_GINFO_ID, H5O_MSG_FLAG_CONSTANT, 0, ginfo, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message")
+
+ /* Insert pipeline message */
+ if(pline && pline->nused)
+ if(H5O_msg_create(oloc, H5O_PLINE_ID, H5O_MSG_FLAG_CONSTANT, 0, pline, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message")
} /* end if */
else {
H5O_stab_t stab; /* Symbol table message */
@@ -213,98 +288,7 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo,
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_obj_create() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_obj_ent_decode
- *
- * Purpose: Decodes a symbol table entry into a object location
- *
- * Return: Success: Non-negative with *pp pointing to the first byte
- * following the symbol table entry.
- *
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Sep 26 2005
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5G_obj_ent_decode(H5F_t *f, const uint8_t **pp, H5O_loc_t *oloc)
-{
- const uint8_t *p_ret = *pp;
-
- FUNC_ENTER_NOAPI_NOFUNC(H5G_obj_ent_decode)
-
- /* check arguments */
- HDassert(f);
- HDassert(pp);
- HDassert(oloc);
-
- /* Set file pointer for root object location */
- oloc->file = f;
- oloc->holding_file = FALSE;
-
- /* decode header */
- *pp += H5F_SIZEOF_SIZE(f); /* Skip over local heap address */
- H5F_addr_decode(f, pp, &(oloc->addr));
- *pp += 4; /* Skip over "cache type" */
- *pp += 4; /* Reserved */
-
- /* Set decode pointer */
- *pp = p_ret + H5G_SIZEOF_ENTRY(f);
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5G_obj_ent_decode() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_obj_ent_encode
- *
- * Purpose: Encodes the specified object location into a symbol table
- * entry in the buffer pointed to by *pp.
- *
- * Return: Success: Non-negative, with *pp pointing to the first byte
- * after the symbol table entry.
- *
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Sep 26 2005
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5G_obj_ent_encode(const H5F_t *f, uint8_t **pp, const H5O_loc_t *oloc)
-{
- uint8_t *p_ret = *pp + H5G_SIZEOF_ENTRY(f);
-
- FUNC_ENTER_NOAPI_NOFUNC(H5G_obj_ent_encode)
-
- /* check arguments */
- HDassert(f);
- HDassert(pp);
-
- /* encode header */
- H5F_ENCODE_LENGTH(f, *pp, 0); /* No name for root group */
- if(oloc)
- H5F_addr_encode(f, pp, oloc->addr);
- else
- H5F_addr_encode(f, pp, HADDR_UNDEF);
- UINT32ENCODE(*pp, H5G_NOTHING_CACHED);
- UINT32ENCODE(*pp, 0); /*reserved*/
-
- /* fill with zero */
- while(*pp < p_ret)
- *(*pp)++ = 0;
- *pp = p_ret;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5G_obj_ent_encode() */
+} /* end H5G_obj_create_real() */
/*-------------------------------------------------------------------------
@@ -313,8 +297,8 @@ H5G_obj_ent_encode(const H5F_t *f, uint8_t **pp, const H5O_loc_t *oloc)
* Purpose: Retrieves the "link info" message for an object. Also
* sets the number of links correctly, if it isn't set up yet.
*
- * Return: Success: Ptr to message in native format.
- * Failure: NULL
+ * Return: Success: TRUE/FALSE whether message was found & retrieved
+ * Failure: FAIL if error occurred
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
@@ -322,38 +306,52 @@ H5G_obj_ent_encode(const H5F_t *f, uint8_t **pp, const H5O_loc_t *oloc)
*
*-------------------------------------------------------------------------
*/
-H5O_linfo_t *
+htri_t
H5G_obj_get_linfo(const H5O_loc_t *grp_oloc, H5O_linfo_t *linfo, hid_t dxpl_id)
{
- H5O_linfo_t *ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5G_obj_get_linfo, NULL)
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_obj_get_linfo, FAIL)
/* check arguments */
HDassert(grp_oloc);
+ HDassert(linfo);
+
+ /* Check for the group having a link info message */
+ if((ret_value = H5O_msg_exists(grp_oloc, H5O_LINFO_ID, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read object header")
+ if(ret_value) {
+ /* Retrieve the "link info" structure */
+ if(NULL == H5O_msg_read(grp_oloc, H5O_LINFO_ID, linfo, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "link info message not present")
- /* Retrieve the "link info" structure */
- if((ret_value = H5O_msg_read(grp_oloc, H5O_LINFO_ID, linfo, dxpl_id))) {
/* Check if we don't know how many links there are */
- if(ret_value->nlinks == HSIZET_MAX) {
+ if(linfo->nlinks == HSIZET_MAX) {
/* Check if we are using "dense" link storage */
- if(H5F_addr_defined(ret_value->fheap_addr)) {
+ if(H5F_addr_defined(linfo->fheap_addr)) {
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(grp_oloc->file, dxpl_id, linfo->name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
/* Retrieve # of records in "name" B-tree */
/* (should be same # of records in all indices) */
- if(H5B2_get_nrec(grp_oloc->file, dxpl_id, H5G_BT2_NAME, ret_value->name_bt2_addr, &ret_value->nlinks) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "can't retrieve # of records in index")
+ if(H5B2_get_nrec(bt2_name, &linfo->nlinks) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve # of records in index")
} /* end if */
else {
/* Retrieve # of links from object header */
- if(H5O_get_nlinks(grp_oloc, dxpl_id, &ret_value->nlinks) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "can't retrieve # of links for object")
+ if(H5O_get_nlinks(grp_oloc, dxpl_id, &linfo->nlinks) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve # of links for object")
} /* end if */
} /* end if */
} /* end if */
- else
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "link info message not present")
done:
+ /* Release resources */
+ if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_obj_get_linfo() */
@@ -451,7 +449,10 @@ herr_t
H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk,
hbool_t adj_link, hid_t dxpl_id)
{
+ H5O_pline_t tmp_pline; /* Pipeline message */
+ H5O_pline_t *pline = NULL; /* Pointer to pipeline message */
H5O_linfo_t linfo; /* Link info message */
+ htri_t linfo_exists; /* Whether the link info message exists */
hbool_t use_old_format; /* Whether to use 'old format' (symbol table) for insertions or not */
hbool_t use_new_dense = FALSE; /* Whether to use "dense" form of 'new format' group */
herr_t ret_value = SUCCEED; /* Return value */
@@ -465,7 +466,9 @@ H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk,
/* Check if we have information about the number of objects in this group */
/* (by attempting to get the link info message for this group) */
- if(H5G_obj_get_linfo(grp_oloc, &linfo, dxpl_id)) {
+ if((linfo_exists = H5G_obj_get_linfo(grp_oloc, &linfo, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check for link info message")
+ if(linfo_exists) {
H5O_ginfo_t ginfo; /* Group info message */
size_t link_msg_size; /* Size of new link message in the file */
@@ -499,11 +502,21 @@ H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk,
else if(linfo.nlinks < ginfo.max_compact && link_msg_size < H5O_MESG_MAX_SIZE)
use_new_dense = FALSE;
else {
+ htri_t pline_exists; /* Whether the pipeline message exists */
H5G_obj_oh_it_ud1_t udata; /* User data for iteration */
H5O_mesg_operator_t op; /* Message operator */
+ /* Get the pipeline message, if it exists */
+ if((pline_exists = H5O_msg_exists(grp_oloc, H5O_PLINE_ID, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read object header")
+ if(pline_exists) {
+ if(NULL == H5O_msg_read(grp_oloc, H5O_PLINE_ID, &tmp_pline, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link pipeline")
+ pline = &tmp_pline;
+ } /* end if */
+
/* The group doesn't currently have "dense" storage for links */
- if(H5G_dense_create(grp_oloc->file, dxpl_id, &linfo) < 0)
+ if(H5G_dense_create(grp_oloc->file, dxpl_id, &linfo, pline) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create 'dense' form of new format group")
/* Set up user data for object header message iteration */
@@ -525,9 +538,6 @@ H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk,
} /* end else */
} /* end if */
else {
- /* Clear error stack from not finding the link info message */
- H5E_clear_stack(NULL);
-
/* Check for new-style link information */
if(obj_lnk->cset != H5T_CSET_ASCII || obj_lnk->type > H5L_TYPE_BUILTIN_MAX) {
H5O_linfo_t new_linfo = H5G_CRT_LINK_INFO_DEF; /* Link information */
@@ -611,6 +621,10 @@ H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk,
} /* end if */
done:
+ /* Free any space used by the pipeline message */
+ if(pline && H5O_msg_reset(H5O_PLINE_ID, pline) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "can't release pipeline")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_obj_insert() */
@@ -636,6 +650,7 @@ H5G_obj_iterate(const H5O_loc_t *grp_oloc,
H5G_lib_iterate_t op, void *op_data, hid_t dxpl_id)
{
H5O_linfo_t linfo; /* Link info message */
+ htri_t linfo_exists; /* Whether the link info message exists */
herr_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5G_obj_iterate, FAIL)
@@ -645,7 +660,9 @@ H5G_obj_iterate(const H5O_loc_t *grp_oloc,
HDassert(op);
/* Attempt to get the link info for this group */
- if(H5G_obj_get_linfo(grp_oloc, &linfo, dxpl_id)) {
+ if((linfo_exists = H5G_obj_get_linfo(grp_oloc, &linfo, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check for link info message")
+ if(linfo_exists) {
/* Check for going out of bounds */
if(skip > 0 && (size_t)skip >= linfo.nlinks)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "index out of bound")
@@ -669,9 +686,6 @@ H5G_obj_iterate(const H5O_loc_t *grp_oloc,
} /* end else */
} /* end if */
else {
- /* Clear error stack from not finding the link info message */
- H5E_clear_stack(NULL);
-
/* Can only perform name lookups on groups with symbol tables */
if(idx_type != H5_INDEX_NAME)
HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "no creation order index to query")
@@ -707,6 +721,7 @@ H5G_obj_info(H5O_loc_t *oloc, H5G_info_t *grp_info, hid_t dxpl_id)
H5G_name_t grp_path; /* Group hier. path */
H5O_loc_t grp_oloc; /* Group object location */
H5O_linfo_t linfo; /* Link info message */
+ htri_t linfo_exists; /* Whether the link info message exists */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_obj_info, FAIL)
@@ -732,7 +747,9 @@ H5G_obj_info(H5O_loc_t *oloc, H5G_info_t *grp_info, hid_t dxpl_id)
grp_info->mounted = H5G_MOUNTED(grp);
/* Attempt to get the link info for this group */
- if(H5G_obj_get_linfo(oloc, &linfo, dxpl_id)) {
+ if((linfo_exists = H5G_obj_get_linfo(oloc, &linfo, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check for link info message")
+ if(linfo_exists) {
/* Retrieve the information about the links */
grp_info->nlinks = linfo.nlinks;
grp_info->max_corder = linfo.max_corder;
@@ -744,9 +761,6 @@ H5G_obj_info(H5O_loc_t *oloc, H5G_info_t *grp_info, hid_t dxpl_id)
grp_info->storage_type = H5G_STORAGE_TYPE_COMPACT;
} /* end if */
else {
- /* Clear error stack from not finding the link info message */
- H5E_clear_stack(NULL);
-
/* Get the number of objects in this group by iterating over symbol table */
if(H5G_stab_count(oloc, &grp_info->nlinks, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "can't count objects")
@@ -783,6 +797,7 @@ H5G_obj_get_name_by_idx(H5O_loc_t *oloc, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, char* name, size_t size, hid_t dxpl_id)
{
H5O_linfo_t linfo; /* Link info message */
+ htri_t linfo_exists; /* Whether the link info message exists */
ssize_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5G_obj_get_name_by_idx, FAIL)
@@ -791,7 +806,9 @@ H5G_obj_get_name_by_idx(H5O_loc_t *oloc, H5_index_t idx_type,
HDassert(oloc && oloc->file);
/* Attempt to get the link info for this group */
- if(H5G_obj_get_linfo(oloc, &linfo, dxpl_id)) {
+ if((linfo_exists = H5G_obj_get_linfo(oloc, &linfo, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check for link info message")
+ if(linfo_exists) {
/* Check for creation order tracking, if creation order index lookup requested */
if(idx_type == H5_INDEX_CRT_ORDER) {
/* Check if creation order is tracked */
@@ -812,9 +829,6 @@ H5G_obj_get_name_by_idx(H5O_loc_t *oloc, H5_index_t idx_type,
} /* end else */
} /* end if */
else {
- /* Clear error stack from not finding the link info message */
- H5E_clear_stack(NULL);
-
/* Can only perform name lookups on groups with symbol tables */
if(idx_type != H5_INDEX_NAME)
HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "no creation order index to query")
@@ -888,8 +902,8 @@ H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, hid_t dxpl_id)
HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over links")
/* Get a pointer to the object header itself */
- if((oh = H5O_protect(oloc, dxpl_id)) == NULL)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to protect group object header")
+ if(NULL == (oh = H5O_pin(oloc, dxpl_id)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTPIN, FAIL, "unable to pin group object header")
/* Inspect links in table for ones that can't be converted back
* into link message form (currently only links which can't fit
@@ -907,8 +921,8 @@ H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, hid_t dxpl_id)
for(u = 0; u < linfo->nlinks; u++)
if(H5O_msg_append_oh(oloc->file, dxpl_id, oh, H5O_LINK_ID, 0, H5O_UPDATE_TIME, &(ltable.lnks[u])) < 0) {
/* Release object header */
- if(H5O_unprotect(oloc, oh) < 0)
- HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to unprotect group object header")
+ if(H5O_unpin(oloc, oh) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTUNPIN, FAIL, "unable to unpin group object header")
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message")
} /* end if */
@@ -919,8 +933,8 @@ H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, hid_t dxpl_id)
} /* end if */
/* Release object header */
- if(H5O_unprotect(oloc, oh) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to unprotect group object header")
+ if(H5O_unpin(oloc, oh) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTUNPIN, FAIL, "unable to unpin group object header")
/* Free link table information */
if(H5G_link_release_table(&ltable) < 0)
@@ -955,6 +969,7 @@ herr_t
H5G_obj_remove(H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name, hid_t dxpl_id)
{
H5O_linfo_t linfo; /* Link info message */
+ htri_t linfo_exists; /* Whether the link info message exists */
hbool_t use_old_format; /* Whether to use 'old format' (symbol table) for deletion or not */
herr_t ret_value = SUCCEED; /* Return value */
@@ -965,7 +980,9 @@ H5G_obj_remove(H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name, h
HDassert(name && *name);
/* Attempt to get the link info for this group */
- if(H5G_obj_get_linfo(oloc, &linfo, dxpl_id)) {
+ if((linfo_exists = H5G_obj_get_linfo(oloc, &linfo, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check for link info message")
+ if(linfo_exists) {
/* Using the new format for groups */
use_old_format = FALSE;
@@ -982,9 +999,6 @@ H5G_obj_remove(H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name, h
} /* end else */
} /* end if */
else {
- /* Clear error stack from not finding the link info message */
- H5E_clear_stack(NULL);
-
/* Using the old format for groups */
use_old_format = TRUE;
@@ -1021,6 +1035,7 @@ H5G_obj_remove_by_idx(H5O_loc_t *grp_oloc, H5RS_str_t *grp_full_path_r,
H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t dxpl_id)
{
H5O_linfo_t linfo; /* Link info message */
+ htri_t linfo_exists; /* Whether the link info message exists */
hbool_t use_old_format; /* Whether to use 'old format' (symbol table) for deletion or not */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1030,7 +1045,9 @@ H5G_obj_remove_by_idx(H5O_loc_t *grp_oloc, H5RS_str_t *grp_full_path_r,
HDassert(grp_oloc && grp_oloc->file);
/* Attempt to get the link info for this group */
- if(H5G_obj_get_linfo(grp_oloc, &linfo, dxpl_id)) {
+ if((linfo_exists = H5G_obj_get_linfo(grp_oloc, &linfo, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check for link info message")
+ if(linfo_exists) {
/* Check for creation order tracking, if creation order index lookup requested */
if(idx_type == H5_INDEX_CRT_ORDER) {
/* Check if creation order is tracked */
@@ -1054,9 +1071,6 @@ H5G_obj_remove_by_idx(H5O_loc_t *grp_oloc, H5RS_str_t *grp_full_path_r,
} /* end else */
} /* end if */
else {
- /* Clear error stack from not finding the link info message */
- H5E_clear_stack(NULL);
-
/* Can only perform name lookups on groups with symbol tables */
if(idx_type != H5_INDEX_NAME)
HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "no creation order index to query")
@@ -1093,12 +1107,13 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+htri_t
H5G_obj_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk,
hid_t dxpl_id)
{
H5O_linfo_t linfo; /* Link info message */
- herr_t ret_value = SUCCEED; /* Return value */
+ htri_t linfo_exists; /* Whether the link info message exists */
+ htri_t ret_value = FALSE; /* Return value */
FUNC_ENTER_NOAPI(H5G_obj_lookup, FAIL)
@@ -1107,25 +1122,24 @@ H5G_obj_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk,
HDassert(name && *name);
/* Attempt to get the link info message for this group */
- if(H5G_obj_get_linfo(grp_oloc, &linfo, dxpl_id)) {
+ if((linfo_exists = H5G_obj_get_linfo(grp_oloc, &linfo, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check for link info message")
+ if(linfo_exists) {
/* Check for dense link storage */
if(H5F_addr_defined(linfo.fheap_addr)) {
/* Get the object's info from the dense link storage */
- if(H5G_dense_lookup(grp_oloc->file, dxpl_id, &linfo, name, lnk) < 0)
+ if((ret_value = H5G_dense_lookup(grp_oloc->file, dxpl_id, &linfo, name, lnk)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object")
} /* end if */
else {
/* Get the object's info from the link messages */
- if(H5G_compact_lookup(grp_oloc, name, lnk, dxpl_id) < 0)
+ if((ret_value = H5G_compact_lookup(grp_oloc, name, lnk, dxpl_id)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object")
} /* end else */
} /* end if */
else {
- /* Clear error stack from not finding the link info message */
- H5E_clear_stack(NULL);
-
/* Get the object's info from the symbol table */
- if(H5G_stab_lookup(grp_oloc, name, lnk, dxpl_id) < 0)
+ if((ret_value = H5G_stab_lookup(grp_oloc, name, lnk, dxpl_id)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object")
} /* end else */
@@ -1153,6 +1167,7 @@ H5G_obj_lookup_by_idx(H5O_loc_t *grp_oloc, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, H5O_link_t *lnk, hid_t dxpl_id)
{
H5O_linfo_t linfo; /* Link info message */
+ htri_t linfo_exists; /* Whether the link info message exists */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_obj_lookup_by_idx, FAIL)
@@ -1161,7 +1176,9 @@ H5G_obj_lookup_by_idx(H5O_loc_t *grp_oloc, H5_index_t idx_type,
HDassert(grp_oloc && grp_oloc->file);
/* Attempt to get the link info message for this group */
- if(H5G_obj_get_linfo(grp_oloc, &linfo, dxpl_id)) {
+ if((linfo_exists = H5G_obj_get_linfo(grp_oloc, &linfo, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check for link info message")
+ if(linfo_exists) {
/* Check for creation order tracking, if creation order index lookup requested */
if(idx_type == H5_INDEX_CRT_ORDER) {
/* Check if creation order is tracked */
@@ -1182,9 +1199,6 @@ H5G_obj_lookup_by_idx(H5O_loc_t *grp_oloc, H5_index_t idx_type,
} /* end else */
} /* end if */
else {
- /* Clear error stack from not finding the link info message */
- H5E_clear_stack(NULL);
-
/* Can only perform name lookups on groups with symbol tables */
if(idx_type != H5_INDEX_NAME)
HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "no creation order index to query")
diff --git a/src/H5Goh.c b/src/H5Goh.c
index 3ccdf16..ea51179 100644
--- a/src/H5Goh.c
+++ b/src/H5Goh.c
@@ -45,11 +45,16 @@
/* Local Prototypes */
/********************/
+static void *H5O_group_get_copy_file_udata(void);
+static void H5O_group_free_copy_file_udata(void *udata);
static htri_t H5O_group_isa(H5O_t *loc);
-static hid_t H5O_group_open(const H5G_loc_t *obj_loc, hid_t dxpl_id);
+static hid_t H5O_group_open(const H5G_loc_t *obj_loc, hid_t lapl_id,
+ hid_t dxpl_id, hbool_t app_ref);
static void *H5O_group_create(H5F_t *f, void *_crt_info, H5G_loc_t *obj_loc,
hid_t dxpl_id);
static H5O_loc_t *H5O_group_get_oloc(hid_t obj_id);
+static herr_t H5O_group_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
+ H5_ih_info_t *bh_info);
/*********************/
@@ -70,14 +75,84 @@ static H5O_loc_t *H5O_group_get_oloc(hid_t obj_id);
const H5O_obj_class_t H5O_OBJ_GROUP[1] = {{
H5O_TYPE_GROUP, /* object type */
"group", /* object name, for debugging */
- NULL, /* get 'copy file' user data */
- NULL, /* free 'copy file' user data */
+ H5O_group_get_copy_file_udata, /* get 'copy file' user data */
+ H5O_group_free_copy_file_udata, /* free 'copy file' user data */
H5O_group_isa, /* "isa" message */
H5O_group_open, /* open an object of this class */
H5O_group_create, /* create an object of this class */
- H5O_group_get_oloc /* get an object header location for an object */
+ H5O_group_get_oloc, /* get an object header location for an object */
+ H5O_group_bh_info /* get the index & heap info for an object */
}};
+/* Declare the external free list to manage the H5O_ginfo_t struct */
+H5FL_DEFINE(H5G_copy_file_ud_t);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_group_get_copy_file_udata
+ *
+ * Purpose: Allocates the user data needed for copying a group's
+ * object header from file to file.
+ *
+ * Return: Success: Non-NULL pointer to user data
+ *
+ * Failure: NULL
+ *
+ * Programmer: Neil Fortner
+ * Thursday, July 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_group_get_copy_file_udata(void)
+{
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_group_get_copy_file_udata)
+
+ /* Allocate space for the 'copy file' user data for copying groups.
+ * Currently this is only a ginfo, so there is no specific struct type for
+ * this operation. */
+ if(NULL == (ret_value = H5FL_CALLOC(H5G_copy_file_ud_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_group_get_copy_file_udata() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_group_free_copy_file_udata
+ *
+ * Purpose: Release the user data needed for copying a group's
+ * object header from file to file.
+ *
+ * Return: <none>
+ *
+ * Programmer: Neil Fortner
+ * Thursday, July 30, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+H5O_group_free_copy_file_udata(void *_udata)
+{
+ H5G_copy_file_ud_t *udata = (H5G_copy_file_ud_t *)_udata;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_group_free_copy_file_udata)
+
+ /* Sanity check */
+ HDassert(udata);
+
+ /* Free the ginfo struct (including nested data structs) */
+ H5O_msg_free(H5O_PLINE_ID, udata->common.src_pline);
+
+ /* Release space for 'copy file' user data (ginfo struct) */
+ (void)H5FL_FREE(H5G_copy_file_ud_t, udata);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5O_group_free_copy_file_udata() */
+
/*-------------------------------------------------------------------------
* Function: H5O_group_isa
@@ -109,9 +184,9 @@ H5O_group_isa(struct H5O_t *oh)
/* Check for any of the messages that indicate a group */
if((stab_exists = H5O_msg_exists_oh(oh, H5O_STAB_ID)) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header")
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read object header")
if((linfo_exists = H5O_msg_exists_oh(oh, H5O_LINFO_ID)) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header")
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read object header")
ret_value = (stab_exists > 0 || linfo_exists > 0);
@@ -134,7 +209,7 @@ done:
*-------------------------------------------------------------------------
*/
static hid_t
-H5O_group_open(const H5G_loc_t *obj_loc, hid_t dxpl_id)
+H5O_group_open(const H5G_loc_t *obj_loc, hid_t UNUSED lapl_id, hid_t dxpl_id, hbool_t app_ref)
{
H5G_t *grp = NULL; /* Group opened */
hid_t ret_value; /* Return value */
@@ -148,7 +223,7 @@ H5O_group_open(const H5G_loc_t *obj_loc, hid_t dxpl_id)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
/* Register an ID for the group */
- if((ret_value = H5I_register(H5I_GROUP, grp)) < 0)
+ if((ret_value = H5I_register(H5I_GROUP, grp, app_ref)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
done:
@@ -231,7 +306,7 @@ H5O_group_get_oloc(hid_t obj_id)
FUNC_ENTER_NOAPI_NOINIT(H5O_group_get_oloc)
/* Get the group */
- if(NULL == (grp = H5I_object(obj_id)))
+ if(NULL == (grp = (H5G_t *)H5I_object(obj_id)))
HGOTO_ERROR(H5E_OHDR, H5E_BADATOM, NULL, "couldn't get object from ID")
/* Get the group's object header location */
@@ -256,14 +331,16 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5O_group_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info)
{
- H5O_linfo_t linfo; /* Link info message */
- H5HF_t *fheap = NULL; /* Fractal heap handle */
- herr_t ret_value = SUCCEED; /* Return value */
+ htri_t exists; /* Flag if header message of interest exists */
+ H5HF_t *fheap = NULL; /* Fractal heap handle */
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
+ H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5O_group_bh_info, FAIL)
+ FUNC_ENTER_NOAPI_NOINIT(H5O_group_bh_info)
/* Sanity check */
HDassert(f);
@@ -271,52 +348,68 @@ H5O_group_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info)
HDassert(bh_info);
/* Check for "new style" group info */
- if(NULL == H5O_msg_read_real(f, dxpl_id, oh, H5O_LINFO_ID, &linfo)) {
- H5O_stab_t stab; /* Info about symbol table */
-
- /* Must be "old style" group, clear error stack */
- H5E_clear_stack(NULL);
+ if((exists = H5O_msg_exists_oh(oh, H5O_LINFO_ID)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read object header")
+ if(exists > 0) {
+ H5O_linfo_t linfo; /* Link info message */
+
+ /* Get "new style" group info */
+ if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_LINFO_ID, &linfo))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't read LINFO message")
+
+ /* Check if name index available */
+ if(H5F_addr_defined(linfo.name_bt2_addr)) {
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(f, dxpl_id, linfo.name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
+ /* Get name index B-tree size */
+ if(H5B2_size(bt2_name, dxpl_id, &bh_info->index_size) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info for name index")
+ } /* end if */
- /* Get symbol table message */
- if(NULL == H5O_msg_read_real(f, dxpl_id, oh, H5O_STAB_ID, &stab))
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't find LINFO nor STAB messages")
-
- /* Get symbol table size info */
- if(H5G_stab_bh_size(f, dxpl_id, &stab, bh_info) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve symbol table size info")
- } /* end if */
- else { /* LINFO */
- /* Get creation order B-tree size, if available */
- if(H5F_addr_defined(linfo.corder_bt2_addr))
- if(H5B2_iterate_size(f, dxpl_id, H5G_BT2_CORDER, linfo.corder_bt2_addr, &bh_info->index_size) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info")
+ /* Check if creation order index available */
+ if(H5F_addr_defined(linfo.corder_bt2_addr)) {
+ /* Open the creation order index v2 B-tree */
+ if(NULL == (bt2_corder = H5B2_open(f, dxpl_id, linfo.corder_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index")
- /* Get name order B-tree size, if available */
- if(H5F_addr_defined(linfo.name_bt2_addr))
- if(H5B2_iterate_size(f, dxpl_id, H5G_BT2_NAME, linfo.name_bt2_addr, &bh_info->index_size) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info")
+ /* Get creation order index B-tree size */
+ if(H5B2_size(bt2_corder, dxpl_id, &bh_info->index_size) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info for creation order index")
+ } /* end if */
/* Get fractal heap size, if available */
if(H5F_addr_defined(linfo.fheap_addr)) {
/* Open the fractal heap for links */
if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo.fheap_addr)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
/* Get heap storage size */
if(H5HF_size(fheap, dxpl_id, &bh_info->heap_size) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve fractal heap storage info")
-
- /* Release the fractal heap */
- if(H5HF_close(fheap, dxpl_id) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
- fheap = NULL;
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve fractal heap storage info")
} /* end if */
+ } /* end if */
+ else {
+ H5O_stab_t stab; /* Info about symbol table */
+
+ /* Must be "old style" group, get symbol table message */
+ if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_STAB_ID, &stab))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't find LINFO nor STAB messages")
+
+ /* Get symbol table size info */
+ if(H5G_stab_bh_size(f, dxpl_id, &stab, bh_info) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve symbol table size info")
} /* end else */
done:
/* Release resources */
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ HDONE_ERROR(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap")
+ if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index")
+ if(bt2_corder && H5B2_close(bt2_corder, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for creation order index")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_group_bh_info() */
diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h
index 03304db..355b5fd 100644
--- a/src/H5Gpkg.h
+++ b/src/H5Gpkg.h
@@ -100,14 +100,27 @@ typedef union H5G_cache_t {
* also appears in the object header to which this symbol table entry
* points.
*/
-typedef struct H5G_entry_t {
+struct H5G_entry_t {
hbool_t dirty; /*entry out-of-date? */
H5G_cache_type_t type; /*type of information cached */
H5G_cache_t cache; /*cached data from object header */
size_t name_off; /*offset of name within name heap */
haddr_t header; /*file address of object header */
H5F_t *file; /*file to which this obj hdr belongs */
-} H5G_entry_t;
+};
+
+/*
+ * A symbol table node is a collection of symbol table entries. It can
+ * be thought of as the lowest level of the B-link tree that points to
+ * a collection of symbol table entries that belong to a specific symbol
+ * table or group.
+ */
+typedef struct H5G_node_t {
+ H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */
+ /* first field in structure */
+ unsigned nsyms; /*number of symbols */
+ H5G_entry_t *entry; /*array of symbol table entries */
+} H5G_node_t;
/*
* Shared information for all open group objects
@@ -131,13 +144,15 @@ struct H5G_t {
typedef herr_t (*H5G_lib_iterate_t)(const H5O_link_t *lnk, void *op_data);
/* Describe kind of callback to make for each link */
-typedef struct {
- enum {
+typedef enum H5G_link_iterate_op_type_t {
#ifndef H5_NO_DEPRECATED_SYMBOLS
- H5G_LINK_OP_OLD, /* "Old" application callback */
+ H5G_LINK_OP_OLD, /* "Old" application callback */
#endif /* H5_NO_DEPRECATED_SYMBOLS */
- H5G_LINK_OP_NEW /* "New" application callback */
- } op_type;
+ H5G_LINK_OP_NEW /* "New" application callback */
+} H5G_link_iterate_op_type_t;
+
+typedef struct {
+ H5G_link_iterate_op_type_t op_type;
union {
#ifndef H5_NO_DEPRECATED_SYMBOLS
H5G_iterate_t op_old; /* "Old" application callback for each link */
@@ -327,6 +342,12 @@ H5_DLLVAR const H5B2_class_t H5G_BT2_NAME[1];
/* The v2 B-tree class for indexing 'creation order' field on links */
H5_DLLVAR const H5B2_class_t H5G_BT2_CORDER[1];
+/* Free list for managing H5G_t structs */
+H5FL_EXTERN(H5G_t);
+
+/* Free list for managing H5G_shared_t structs */
+H5FL_EXTERN(H5G_shared_t);
+
/******************************/
/* Package Private Prototypes */
/******************************/
@@ -389,6 +410,10 @@ H5_DLL herr_t H5G_stab_lookup(H5O_loc_t *grp_oloc, const char *name,
H5O_link_t *lnk, hid_t dxpl_id);
H5_DLL herr_t H5G_stab_lookup_by_idx(H5O_loc_t *grp_oloc, H5_iter_order_t order,
hsize_t n, H5O_link_t *lnk, hid_t dxpl_id);
+#ifndef H5_STRICT_FORMAT_CHECKS
+H5_DLL herr_t H5G_stab_valid(H5O_loc_t *grp_oloc, hid_t dxpl_id,
+ H5O_stab_t *alt_stab);
+#endif /* H5_STRICT_FORMAT_CHECKS */
#ifndef H5_NO_DEPRECATED_SYMBOLS
H5_DLL H5G_obj_t H5G_stab_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx,
hid_t dxpl_id);
@@ -412,6 +437,7 @@ H5_DLL herr_t H5G_ent_debug(const H5G_entry_t *ent, FILE * stream, int indent,
/* Functions that understand symbol table nodes */
H5_DLL herr_t H5G_node_init(H5F_t *f);
+H5_DLL size_t H5G_node_size_real(const H5F_t *f);
H5_DLL int H5G_node_iterate(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr,
const void *_rt_key, void *_udata);
H5_DLL int H5G_node_sumup(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr,
@@ -462,7 +488,7 @@ H5_DLL herr_t H5G_compact_remove_by_idx(const H5O_loc_t *oloc, hid_t dxpl_id,
H5_DLL herr_t H5G_compact_iterate(const H5O_loc_t *oloc, hid_t dxpl_id,
const H5O_linfo_t *linfo, H5_index_t idx_type, H5_iter_order_t order,
hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op, void *op_data);
-H5_DLL herr_t H5G_compact_lookup(H5O_loc_t *grp_oloc, const char *name,
+H5_DLL htri_t H5G_compact_lookup(H5O_loc_t *grp_oloc, const char *name,
H5O_link_t *lnk, hid_t dxpl_id);
H5_DLL herr_t H5G_compact_lookup_by_idx(H5O_loc_t *oloc, hid_t dxpl_id,
const H5O_linfo_t *linfo, H5_index_t idx_type, H5_iter_order_t order,
@@ -475,10 +501,11 @@ H5_DLL H5G_obj_t H5G_compact_get_type_by_idx(H5O_loc_t *oloc, hid_t dxpl_id,
/* Functions that understand "dense" link storage */
H5_DLL herr_t H5G_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
H5_index_t idx_type, H5_iter_order_t order, H5G_link_table_t *ltable);
-H5_DLL herr_t H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo);
+H5_DLL herr_t H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo,
+ const H5O_pline_t *pline);
H5_DLL herr_t H5G_dense_insert(H5F_t *f, hid_t dxpl_id,
const H5O_linfo_t *linfo, const H5O_link_t *lnk);
-H5_DLL herr_t H5G_dense_lookup(H5F_t *f, hid_t dxpl_id,
+H5_DLL htri_t H5G_dense_lookup(H5F_t *f, hid_t dxpl_id,
const H5O_linfo_t *linfo, const char *name, H5O_link_t *lnk);
H5_DLL herr_t H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id,
const H5O_linfo_t *linfo, H5_index_t idx_type, H5_iter_order_t order,
@@ -502,10 +529,13 @@ H5_DLL H5G_obj_t H5G_dense_get_type_by_idx(H5F_t *f, hid_t dxpl_id,
#endif /* H5_NO_DEPRECATED_SYMBOLS */
/* Functions that understand group objects */
-H5_DLL herr_t H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo,
- const H5O_linfo_t *linfo, hid_t gcpl_id, H5O_loc_t *oloc/*out*/);
-H5_DLL H5O_linfo_t * H5G_obj_get_linfo(const H5O_loc_t *grp_oloc,
- H5O_linfo_t *linfo, hid_t dxpl_id);
+H5_DLL herr_t H5G_obj_create(H5F_t *f, hid_t dxpl_id, hid_t gcpl_id,
+ H5O_loc_t *oloc/*out*/);
+H5_DLL herr_t H5G_obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo,
+ const H5O_linfo_t *linfo, const H5O_pline_t *pline, hid_t gcpl_id,
+ H5O_loc_t *oloc/*out*/);
+H5_DLL htri_t H5G_obj_get_linfo(const H5O_loc_t *grp_oloc, H5O_linfo_t *linfo,
+ hid_t dxpl_id);
H5_DLL herr_t H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name,
H5O_link_t *obj_lnk, hbool_t adj_link, hid_t dxpl_id);
H5_DLL herr_t H5G_obj_iterate(const H5O_loc_t *grp_oloc,
@@ -518,7 +548,7 @@ H5_DLL herr_t H5G_obj_remove(H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r,
const char *name, hid_t dxpl_id);
H5_DLL herr_t H5G_obj_remove_by_idx(H5O_loc_t *grp_oloc, H5RS_str_t *grp_full_path_r,
H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t dxpl_id);
-H5_DLL herr_t H5G_obj_lookup(H5O_loc_t *grp_oloc, const char *name,
+H5_DLL htri_t H5G_obj_lookup(H5O_loc_t *grp_oloc, const char *name,
H5O_link_t *lnk, hid_t dxpl_id);
H5_DLL herr_t H5G_obj_lookup_by_idx(H5O_loc_t *grp_oloc, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, H5O_link_t *lnk, hid_t dxpl_id);
@@ -547,6 +577,7 @@ H5_DLL htri_t H5G_is_new_dense_test(hid_t gid);
H5_DLL herr_t H5G_new_dense_info_test(hid_t gid, hsize_t *name_count, hsize_t *corder_count);
H5_DLL herr_t H5G_lheap_size_test(hid_t gid, size_t *lheap_size);
H5_DLL herr_t H5G_user_path_test(hid_t obj_id, char *user_path, size_t *user_path_len, unsigned *user_path_hidden);
+H5_DLL herr_t H5G_verify_cached_stab_test(H5O_loc_t *grp_oloc, H5G_entry_t *ent);
#endif /* H5G_TESTING */
#endif /* _H5Gpkg_H */
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index ab6abc1..dec40f3 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -43,9 +43,6 @@
# undef H5G_DEBUG
#endif
-#define H5G_NODE_MAGIC "SNOD" /*symbol table node magic number */
-#define H5G_NODE_SIZEOF_MAGIC 4 /*sizeof symbol node magic number */
-
/*
* The disk size for a symbol table entry...
*/
@@ -132,10 +129,8 @@ typedef struct {
} H5G_name_t;
/* Forward declarations (for prototypes & struct definitions) */
-struct H5P_genplist_t;
struct H5O_loc_t;
struct H5O_link_t;
-struct H5O_t;
/*
* The "location" of an object in a group hierarchy. This points to an object
@@ -146,14 +141,20 @@ typedef struct {
H5G_name_t *path; /* Group hierarchy path */
} H5G_loc_t;
+/* Callback information for copying groups */
+typedef struct H5G_copy_file_ud_t {
+ H5O_copy_file_ud_common_t common; /* Shared information (must be first) */
+} H5G_copy_file_ud_t;
+
typedef struct H5G_t H5G_t;
typedef struct H5G_shared_t H5G_shared_t;
+typedef struct H5G_entry_t H5G_entry_t;
/*
* Library prototypes... These are the ones that other packages routinely
* call.
*/
-H5_DLL herr_t H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc);
+H5_DLL herr_t H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root);
H5_DLL struct H5O_loc_t *H5G_oloc(H5G_t *grp);
H5_DLL H5G_t *H5G_rootof(H5F_t *f);
H5_DLL H5G_name_t * H5G_nameof(H5G_t *grp);
@@ -183,10 +184,8 @@ H5_DLL herr_t H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream
/*
* These functions operate on group object locations.
*/
-H5_DLL herr_t H5G_obj_ent_decode(H5F_t *f, const uint8_t **pp,
- struct H5O_loc_t *oloc);
-H5_DLL herr_t H5G_obj_ent_encode(const H5F_t *f, uint8_t **pp,
- const struct H5O_loc_t *oloc);
+H5_DLL herr_t H5G_ent_encode(const H5F_t *f, uint8_t **pp, const H5G_entry_t *ent);
+H5_DLL herr_t H5G_ent_decode(const H5F_t *f, const uint8_t **pp, H5G_entry_t *ent);
/*
* These functions operate on group hierarchy names.
diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h
index 5ba7050..5b8b054 100644
--- a/src/H5Gpublic.h
+++ b/src/H5Gpublic.h
@@ -86,7 +86,7 @@ H5_DLL herr_t H5Gget_info_by_idx(hid_t loc_id, const char *group_name,
H5_DLL herr_t H5Gclose(hid_t group_id);
/* Symbols defined for compatibility with previous versions of the HDF5 API.
- *
+ *
* Use of these symbols is deprecated.
*/
#ifndef H5_NO_DEPRECATED_SYMBOLS
diff --git a/src/H5Groot.c b/src/H5Groot.c
new file mode 100644
index 0000000..7dc98d1
--- /dev/null
+++ b/src/H5Groot.c
@@ -0,0 +1,269 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Gobj.c
+ * Apr 8 2009
+ * Neil Fortner <nfortne2@hdfgroup.org>
+ *
+ * Purpose: Functions for operating on the root group.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5Gpkg.h" /* Groups */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Pprivate.h" /* Property Lists */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_rootof
+ *
+ * Purpose: Return a pointer to the root group of the file. If the file
+ * is part of a virtual file then the root group of the virtual
+ * file is returned.
+ *
+ * Return: Success: Ptr to the root group of the file. Do not
+ * free the pointer -- it points directly into
+ * the file struct.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, October 13, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+H5G_t *
+H5G_rootof(H5F_t *f)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_rootof)
+
+ while(f->parent)
+ f = f->parent;
+
+ FUNC_LEAVE_NOAPI(f->shared->root_grp)
+} /* end H5G_rootof() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_mkroot
+ *
+ * Purpose: Creates a root group in an empty file and opens it. If a
+ * root group is already open then this function immediately
+ * returns. If ENT is non-null then it's the symbol table
+ * entry for an existing group which will be opened as the root
+ * group. Otherwise a new root group is created and then
+ * opened.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 11 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root)
+{
+ H5G_loc_t root_loc; /* Root location information */
+ htri_t stab_exists = -1; /* Whether the symbol table exists */
+ hbool_t sblock_dirty = FALSE; /* Whether superblock was dirtied */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_mkroot, FAIL)
+
+ /* check args */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->sblock);
+
+ /* Check if the root group is already initialized */
+ if(f->shared->root_grp)
+ HGOTO_DONE(SUCCEED)
+
+ /* Create information needed for group nodes */
+ if(H5G_node_init(f) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group node info")
+
+ /*
+ * Create the group pointer
+ */
+ if(NULL == (f->shared->root_grp = H5FL_CALLOC(H5G_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(NULL == (f->shared->root_grp->shared = H5FL_CALLOC(H5G_shared_t))) {
+ (void)H5FL_FREE(H5G_t, f->shared->root_grp);
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ } /* end if */
+
+ /* Initialize the root_loc structure to point to fields in the newly created
+ * f->shared->root_grp structure */
+ root_loc.oloc = &(f->shared->root_grp->oloc);
+ root_loc.path = &(f->shared->root_grp->path);
+ H5G_loc_reset(&root_loc);
+
+ /*
+ * If there is no root object then create one. The root group always starts
+ * with a hard link count of one since it's pointed to by the superblock.
+ */
+ if(create_root) {
+ /* Create root group */
+ /* (Pass the FCPL which is a sub-class of the group creation property class) */
+ if(H5G_obj_create(f, dxpl_id, f->shared->fcpl_id, root_loc.oloc/*out*/) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry")
+ if(1 != H5O_link(root_loc.oloc, 1, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "internal error (wrong link count)")
+
+ /* Mark superblock dirty, so root group info is flushed */
+ sblock_dirty = TRUE;
+
+ /* Create the root group symbol table entry */
+ HDassert(!f->shared->sblock->root_ent);
+ if(f->shared->sblock->super_vers < HDF5_SUPERBLOCK_VERSION_2) {
+ /* Allocate space for the root group symbol table entry */
+ if(NULL == (f->shared->sblock->root_ent = (H5G_entry_t *)H5MM_calloc(sizeof(H5G_entry_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate space for symbol table entry")
+
+ /* Initialize the root group symbol table entry */
+ f->shared->sblock->root_ent->dirty = TRUE;
+ f->shared->sblock->root_ent->type = H5G_NOTHING_CACHED; /* We will cache the stab later */
+ f->shared->sblock->root_ent->name_off = 0; /* No name (yet) */
+ f->shared->sblock->root_ent->header = root_loc.oloc->addr;
+ f->shared->sblock->root_ent->file = root_loc.oloc->file;
+ } /* end if */
+ } /* end if */
+ else {
+ /* Create root group object location from f */
+ root_loc.oloc->addr = f->shared->sblock->root_addr;
+ root_loc.oloc->file = f;
+
+ /*
+ * Open the root object as a group.
+ */
+ if(H5O_open(root_loc.oloc) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open root group")
+
+ /* Actions to take if the symbol table information is cached */
+ if(f->shared->sblock->root_ent && f->shared->sblock->root_ent->type == H5G_CACHED_STAB) {
+ /* Check for the situation where the symbol table is cached but does
+ * not exist. This can happen if, for example, an external link is
+ * added to the root group. */
+ if((stab_exists = H5O_msg_exists(root_loc.oloc, H5O_STAB_ID, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check if symbol table message exists")
+
+ /* Remove the cache if the stab does not exist */
+ if(!stab_exists)
+ f->shared->sblock->root_ent->type = H5G_NOTHING_CACHED;
+#ifndef H5_STRICT_FORMAT_CHECKS
+ /* If symbol table information is cached, check if we should replace the
+ * symbol table message with the cached symbol table information */
+ else if(H5F_INTENT(f) & H5F_ACC_RDWR) {
+ H5O_stab_t cached_stab;
+
+ /* Retrieve the cached symbol table information */
+ cached_stab.btree_addr = f->shared->sblock->root_ent->cache.stab.btree_addr;
+ cached_stab.heap_addr = f->shared->sblock->root_ent->cache.stab.heap_addr;
+
+ /* Check if the symbol table message is valid, and replace with the
+ * cached symbol table if necessary */
+ if(H5G_stab_valid(root_loc.oloc, dxpl_id, &cached_stab) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to verify symbol table")
+ } /* end if */
+#endif /* H5_STRICT_FORMAT_CHECKS */
+ } /* end if */
+ } /* end else */
+
+ /* Cache the root group's symbol table information in the root group symbol
+ * table entry. It will have been allocated by now if it needs to be
+ * present, so we don't need to check the superblock version. We do this if
+ * we have write access, the root entry has been allocated (i.e.
+ * super_vers < 2) and the stab info is not already cached. */
+ if((H5F_INTENT(f) & H5F_ACC_RDWR) && stab_exists != FALSE && f->shared->sblock->root_ent
+ && f->shared->sblock->root_ent->type != H5G_CACHED_STAB) {
+ H5O_stab_t stab; /* Symbol table */
+
+ /* Check if the stab message exists. It's possible for the root group
+ * to use the latest version while the superblock is an old version.
+ * If stab_exists is not -1 then we have already checked. */
+ if(stab_exists == -1 && (stab_exists = H5O_msg_exists(root_loc.oloc, H5O_STAB_ID, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check if symbol table message exists")
+
+ if(stab_exists) {
+ /* Read the root group's symbol table message */
+ if(NULL == H5O_msg_read(root_loc.oloc, H5O_STAB_ID, &stab, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "unable to read symbol table message")
+
+ /* Update the root group symbol table entry */
+ f->shared->sblock->root_ent->type = H5G_CACHED_STAB;
+ f->shared->sblock->root_ent->cache.stab.btree_addr = stab.btree_addr;
+ f->shared->sblock->root_ent->cache.stab.heap_addr = stab.heap_addr;
+
+ /* Mark superblock dirty, so root group info is flushed */
+ sblock_dirty = TRUE;
+ } /* end if */
+ } /* end if */
+
+ /* Create the path names for the root group's entry */
+ H5G_name_init(root_loc.path, "/");
+
+ f->shared->root_grp->shared->fo_count = 1;
+ /* The only other open object should be the superblock extension, if it
+ * exists. Don't count either the superblock extension or the root group
+ * in the number of open objects in the file.
+ */
+ HDassert((1 == f->nopen_objs) ||
+ (2 == f->nopen_objs && HADDR_UNDEF != f->shared->sblock->ext_addr));
+ f->nopen_objs--;
+
+done:
+ /* In case of error, free various memory locations that may have been
+ * allocated */
+ if(ret_value < 0) {
+ if(f->shared->root_grp) {
+ if(f->shared->root_grp->shared)
+ f->shared->root_grp->shared = H5FL_FREE(H5G_shared_t, f->shared->root_grp->shared);
+ f->shared->root_grp = H5FL_FREE(H5G_t, f->shared->root_grp);
+ } /* end if */
+ if(f->shared->sblock)
+ f->shared->sblock->root_ent = (H5G_entry_t *)H5MM_xfree(f->shared->sblock->root_ent);
+ H5G_name_free(root_loc.path);
+ } /* end if */
+
+ /* Mark superblock dirty in cache, if necessary */
+ if(sblock_dirty)
+ if(H5AC_mark_pinned_or_protected_entry_dirty(f, f->shared->sblock) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_mkroot() */
+
diff --git a/src/H5Gstab.c b/src/H5Gstab.c
index 33df402..ab40fad 100644
--- a/src/H5Gstab.c
+++ b/src/H5Gstab.c
@@ -651,7 +651,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5G_stab_get_name_by_idx_cb
*
- * Purpose: Callback for B-tree iteration 'by index' info query to
+ * Purpose: Callback for B-tree iteration 'by index' info query to
* retrieve the name of a link
*
* Return: Success: Non-negative
@@ -677,7 +677,7 @@ H5G_stab_get_name_by_idx_cb(const H5G_entry_t *ent, void *_udata)
/* Get name offset in heap */
name_off = ent->name_off;
- name = H5HL_offset_into(udata->common.f, udata->heap, name_off);
+ name = (const char *)H5HL_offset_into(udata->common.f, udata->heap, name_off);
HDassert(name);
udata->name = H5MM_strdup(name);
HDassert(udata->name);
@@ -810,7 +810,7 @@ done:
*
* Purpose: Look up an object relative to a group, using symbol table
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Non-negative (TRUE/FALSE) on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
@@ -818,7 +818,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+htri_t
H5G_stab_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk,
hid_t dxpl_id)
{
@@ -826,7 +826,7 @@ H5G_stab_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk,
H5G_bt_lkp_t bt_udata; /* Data to pass through B-tree */
H5G_stab_fnd_ud_t udata; /* 'User data' to give to callback */
H5O_stab_t stab; /* Symbol table message */
- herr_t ret_value = SUCCEED; /* Return value */
+ htri_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5G_stab_lookup, FAIL)
@@ -856,7 +856,7 @@ H5G_stab_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk,
bt_udata.op_data = &udata;
/* Search the B-tree */
- if(H5B_find(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, &bt_udata) < 0)
+ if((ret_value = H5B_find(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, &bt_udata)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found")
done:
@@ -871,7 +871,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5G_stab_lookup_by_idx_cb
*
- * Purpose: Callback for B-tree iteration 'by index' info query to
+ * Purpose: Callback for B-tree iteration 'by index' info query to
* retrieve the link
*
* Return: Success: Non-negative
@@ -896,7 +896,7 @@ H5G_stab_lookup_by_idx_cb(const H5G_entry_t *ent, void *_udata)
HDassert(udata && udata->heap);
/* Get a pointer to the link name */
- name = H5HL_offset_into(udata->common.f, udata->heap, ent->name_off);
+ name = (const char *)H5HL_offset_into(udata->common.f, udata->heap, ent->name_off);
HDassert(name);
/* Convert the entry to a link */
@@ -982,12 +982,88 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_stab_lookup_by_idx() */
+#ifndef H5_STRICT_FORMAT_CHECKS
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_valid
+ *
+ * Purpose: Verify that a group's symbol table message is valid. If
+ * provided, the addresses in alt_stab will be tried if the
+ * addresses in the group's stab message are invalid, and
+ * the stab message will be updated if necessary.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * nfortne2@hdfgroup.org
+ * Mar 17, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_stab_valid(H5O_loc_t *grp_oloc, hid_t dxpl_id, H5O_stab_t *alt_stab)
+{
+ H5O_stab_t stab; /* Current symbol table */
+ H5HL_t *heap = NULL; /* Pointer to local heap */
+ hbool_t changed = FALSE; /* Whether stab has been modified */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_stab_valid, FAIL)
+
+ /* Read the symbol table message */
+ if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "unable to read symbol table message");
+
+ /* Check if the symbol table message's b-tree address is valid */
+ if(H5B_valid(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr) < 0) {
+ /* Address is invalid, try the b-tree address in the alternate symbol
+ * table message */
+ if(!alt_stab || H5B_valid(grp_oloc->file, dxpl_id, H5B_SNODE, alt_stab->btree_addr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "unable to locate b-tree")
+ else {
+ /* The alternate symbol table's b-tree address is valid. Adjust the
+ * symbol table message in the group. */
+ stab.btree_addr = alt_stab->btree_addr;
+ changed = TRUE;
+ } /* end else */
+ } /* end if */
+
+ /* Check if the symbol table message's heap address is valid */
+ if(NULL == (heap = H5HL_protect(grp_oloc->file, dxpl_id, stab.heap_addr, H5AC_READ))) {
+ /* Address is invalid, try the heap address in the alternate symbol
+ * table message */
+ if(!alt_stab || NULL == (heap = H5HL_protect(grp_oloc->file, dxpl_id, alt_stab->heap_addr, H5AC_READ)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "unable to locate heap")
+ else {
+ /* The alternate symbol table's heap address is valid. Adjust the
+ * symbol table message in the group. */
+ stab.heap_addr = alt_stab->heap_addr;
+ changed = TRUE;
+ } /* end else */
+ } /* end if */
+
+ /* Update the symbol table message and clear errors if necessary */
+ if(changed) {
+ H5E_clear_stack(NULL);
+ if(H5O_msg_write(grp_oloc, H5O_STAB_ID, 0, H5O_UPDATE_TIME | H5O_UPDATE_FORCE, &stab, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to correct symbol table message")
+ } /* end if */
+
+done:
+ /* Release resources */
+ if(heap && H5HL_unprotect(grp_oloc->file, dxpl_id, heap, stab.heap_addr) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_valid */
+#endif /* H5_STRICT_FORMAT_CHECKS */
+
#ifndef H5_NO_DEPRECATED_SYMBOLS
/*-------------------------------------------------------------------------
* Function: H5G_stab_get_type_by_idx_cb
*
- * Purpose: Callback for B-tree iteration 'by index' info query to
+ * Purpose: Callback for B-tree iteration 'by index' info query to
* retrieve the type of an object
*
* Return: Success: Non-negative
diff --git a/src/H5Gtest.c b/src/H5Gtest.c
index 2921bf0..26de267 100644
--- a/src/H5Gtest.c
+++ b/src/H5Gtest.c
@@ -102,7 +102,7 @@ H5G_is_empty_test(hid_t gid)
FUNC_ENTER_NOAPI(H5G_is_empty_test, FAIL)
/* Get group structure */
- if(NULL == (grp = H5I_object_verify(gid, H5I_GROUP)))
+ if(NULL == (grp = (H5G_t *)H5I_object_verify(gid, H5I_GROUP)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
/* "New format" checks */
@@ -133,7 +133,7 @@ H5G_is_empty_test(hid_t gid)
HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "both symbol table and link info messages found")
/* Get the link info */
- if(NULL == H5G_obj_get_linfo(&(grp->oloc), &linfo, H5AC_dxpl_id))
+ if(H5G_obj_get_linfo(&(grp->oloc), &linfo, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link info")
/* Check for 'dense' link storage file addresses being defined */
@@ -213,7 +213,7 @@ H5G_has_links_test(hid_t gid, unsigned *nmsgs)
FUNC_ENTER_NOAPI(H5G_has_links_test, FAIL)
/* Get group structure */
- if(NULL == (grp = H5I_object_verify(gid, H5I_GROUP)))
+ if(NULL == (grp = (H5G_t *)H5I_object_verify(gid, H5I_GROUP)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
/* Check if the group has any link messages */
@@ -271,7 +271,7 @@ H5G_has_stab_test(hid_t gid)
FUNC_ENTER_NOAPI(H5G_has_stab_test, FAIL)
/* Get group structure */
- if(NULL == (grp = H5I_object_verify(gid, H5I_GROUP)))
+ if(NULL == (grp = (H5G_t *)H5I_object_verify(gid, H5I_GROUP)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
/* Check if the group has a symbol table message */
@@ -321,7 +321,7 @@ H5G_is_new_dense_test(hid_t gid)
FUNC_ENTER_NOAPI(H5G_is_new_dense_test, FAIL)
/* Get group structure */
- if(NULL == (grp = H5I_object_verify(gid, H5I_GROUP)))
+ if(NULL == (grp = (H5G_t *)H5I_object_verify(gid, H5I_GROUP)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
/* Check if the group has a symbol table message */
@@ -343,7 +343,7 @@ H5G_is_new_dense_test(hid_t gid)
H5O_linfo_t linfo; /* Link info message */
/* Get the link info */
- if(NULL == H5G_obj_get_linfo(&(grp->oloc), &linfo, H5AC_dxpl_id))
+ if(H5G_obj_get_linfo(&(grp->oloc), &linfo, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link info")
/* Check for 'dense' link storage file addresses being defined */
@@ -382,6 +382,8 @@ done:
herr_t
H5G_new_dense_info_test(hid_t gid, hsize_t *name_count, hsize_t *corder_count)
{
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
+ H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */
H5O_linfo_t linfo; /* Link info message */
H5G_t *grp = NULL; /* Pointer to group */
herr_t ret_value = SUCCEED; /* Return value */
@@ -389,11 +391,11 @@ H5G_new_dense_info_test(hid_t gid, hsize_t *name_count, hsize_t *corder_count)
FUNC_ENTER_NOAPI(H5G_new_dense_info_test, FAIL)
/* Get group structure */
- if(NULL == (grp = H5I_object_verify(gid, H5I_GROUP)))
+ if(NULL == (grp = (H5G_t *)H5I_object_verify(gid, H5I_GROUP)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
/* Get the link info */
- if(NULL == H5G_obj_get_linfo(&(grp->oloc), &linfo, H5AC_dxpl_id))
+ if(H5G_obj_get_linfo(&(grp->oloc), &linfo, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link info")
/* Check for 'dense' link storage file addresses being defined */
@@ -402,20 +404,34 @@ H5G_new_dense_info_test(hid_t gid, hsize_t *name_count, hsize_t *corder_count)
if(!H5F_addr_defined(linfo.name_bt2_addr))
HGOTO_DONE(FAIL)
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(grp->oloc.file, H5AC_dxpl_id, linfo.name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
/* Retrieve # of records in name index */
- if(H5B2_get_nrec(grp->oloc.file, H5AC_dxpl_id, H5G_BT2_NAME, linfo.name_bt2_addr, name_count) < 0)
+ if(H5B2_get_nrec(bt2_name, name_count) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index")
/* Check if there is a creation order index */
if(H5F_addr_defined(linfo.corder_bt2_addr)) {
+ /* Open the creation order index v2 B-tree */
+ if(NULL == (bt2_corder = H5B2_open(grp->oloc.file, H5AC_dxpl_id, linfo.corder_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index")
+
/* Retrieve # of records in creation order index */
- if(H5B2_get_nrec(grp->oloc.file, H5AC_dxpl_id, H5G_BT2_CORDER, linfo.corder_bt2_addr, corder_count) < 0)
+ if(H5B2_get_nrec(bt2_corder, corder_count) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from creation order index")
} /* end if */
else
*corder_count = 0;
done:
+ /* Release resources */
+ if(bt2_name && H5B2_close(bt2_name, H5AC_dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index")
+ if(bt2_corder && H5B2_close(bt2_corder, H5AC_dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for creation order index")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5G_new_dense_info_test() */
@@ -449,7 +465,7 @@ H5G_lheap_size_test(hid_t gid, size_t *lheap_size)
FUNC_ENTER_NOAPI(H5G_lheap_size_test, FAIL)
/* Get group structure */
- if(NULL == (grp = H5I_object_verify(gid, H5I_GROUP)))
+ if(NULL == (grp = (H5G_t *)H5I_object_verify(gid, H5I_GROUP)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
/* Make certain the group has a symbol table message */
@@ -529,14 +545,14 @@ H5G_user_path_test(hid_t obj_id, char *user_path, size_t *user_path_len, unsigne
/* Retrieve a copy of the user path and put it into the buffer */
if(obj_path->user_path_r) {
- size_t len = H5RS_len(obj_path->user_path_r);
+ ssize_t len = H5RS_len(obj_path->user_path_r);
/* Set the user path, if given */
if(user_path)
HDstrcpy(user_path, H5RS_get_str(obj_path->user_path_r));
/* Set the length of the path */
- *user_path_len = len;
+ *user_path_len = (size_t)len;
/* Set the user path hidden flag */
*obj_hidden = obj_path->obj_hidden;
@@ -550,3 +566,59 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5G_user_path_test() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_verify_cached_stab_test
+ *
+ * Purpose: Check that a that the provided group entry contains a
+ * cached symbol table entry, that the entry matches that in
+ * the provided group's object header, and check that the
+ * addresses are valid.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Neil Fortner
+ * Mar 31, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_verify_cached_stab_test(H5O_loc_t *grp_oloc, H5G_entry_t *ent)
+{
+ H5O_stab_t stab; /* Symbol table */
+ H5HL_t *heap = NULL; /* Pointer to local heap */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_verify_cached_stab_test)
+
+ /* Verify that stab info is cached in ent */
+ if(ent->type != H5G_CACHED_STAB)
+ HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "symbol table information is not cached")
+
+ /* Read the symbol table message from the group */
+ if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, H5AC_ind_dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "unable to read symbol table message")
+
+ /* Verify that the cached symbol table info matches the symbol table message
+ * in the object header */
+ if((ent->cache.stab.btree_addr != stab.btree_addr)
+ || (ent->cache.stab.heap_addr != stab.heap_addr))
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "cached stab info does not match object header")
+
+ /* Verify that the btree address is valid */
+ if(H5B_valid(grp_oloc->file, H5AC_ind_dxpl_id, H5B_SNODE, stab.btree_addr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "b-tree address is invalid")
+
+ /* Verify that the heap address is valid */
+ if(NULL == (heap = H5HL_protect(grp_oloc->file, H5AC_ind_dxpl_id, stab.heap_addr, H5AC_READ)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "heap address is invalid")
+
+done:
+ /* Release resources */
+ if(heap && H5HL_unprotect(grp_oloc->file, H5AC_ind_dxpl_id, heap, stab.heap_addr) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_verify_cached_stab_test() */
+
diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c
index dcc77c2..4c287d5 100644
--- a/src/H5Gtraverse.c
+++ b/src/H5Gtraverse.c
@@ -89,7 +89,7 @@ H5G_traverse_term_interface(void)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_traverse_term_interface)
/* Free the global component buffer */
- H5G_comp_g = H5MM_xfree(H5G_comp_g);
+ H5G_comp_g = (char *)H5MM_xfree(H5G_comp_g);
H5G_comp_alloc_g = 0;
FUNC_LEAVE_NOAPI(SUCCEED)
@@ -194,27 +194,27 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk,
/* Create a group to pass to the user-defined callback */
if((grp = H5G_open(&grp_loc_copy, dxpl_id)) == NULL)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
- if((cur_grp = H5I_register(H5I_GROUP, grp)) < 0)
+ if((cur_grp = H5I_register(H5I_GROUP, grp, FALSE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
/* Check for generic default property list and use link access default if so */
if(_lapl_id == H5P_DEFAULT) {
HDassert(H5P_LINK_ACCESS_DEFAULT != -1);
- if(NULL == (lapl = H5I_object(H5P_LINK_ACCESS_DEFAULT)))
+ if(NULL == (lapl = (H5P_genplist_t *)H5I_object(H5P_LINK_ACCESS_DEFAULT)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "unable to get default property list")
} /* end if */
else {
/* Get the underlying property list passed in */
- if(NULL == (lapl = H5I_object(_lapl_id)))
+ if(NULL == (lapl = (H5P_genplist_t *)H5I_object(_lapl_id)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "unable to get property list from ID")
} /* end else */
/* Copy the property list passed in */
- if((lapl_id = H5P_copy_plist(lapl)) < 0)
+ if((lapl_id = H5P_copy_plist(lapl, FALSE)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "unable to copy property list")
/* Get the underlying property list copy */
- if(NULL == (lapl = H5I_object(lapl_id)))
+ if(NULL == (lapl = (H5P_genplist_t *)H5I_object(lapl_id)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "unable to get property list from ID")
/* Record number of soft links left to traverse in the property list. */
@@ -228,22 +228,22 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk,
/* Get the oloc from the ID the user callback returned */
switch(H5I_get_type(cb_return)) {
case H5I_GROUP:
- if((new_oloc = H5G_oloc(H5I_object(cb_return))) == NULL)
+ if((new_oloc = H5G_oloc((H5G_t *)H5I_object(cb_return))) == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location from group ID")
break;
case H5I_DATASET:
- if((new_oloc = H5D_oloc(H5I_object(cb_return))) ==NULL)
+ if((new_oloc = H5D_oloc((H5D_t *)H5I_object(cb_return))) ==NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location from dataset ID")
break;
case H5I_DATATYPE:
- if((new_oloc = H5T_oloc(H5I_object(cb_return))) ==NULL)
+ if((new_oloc = H5T_oloc((H5T_t *)H5I_object(cb_return))) ==NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location from datatype ID")
break;
case H5I_FILE:
- if((temp_file = H5I_object(cb_return)) == NULL)
+ if((temp_file = (H5F_t *)H5I_object(cb_return)) == NULL)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "couldn't get file from ID")
if((new_oloc = H5G_oloc(temp_file->shared->root_grp)) ==NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get root group location from file ID")
@@ -266,22 +266,22 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk,
/* We have a copy of the location and we're holding the file open.
* Close the open ID the user passed back.
*/
- if(H5I_dec_ref(cb_return) < 0)
+ if(H5I_dec_ref(cb_return, FALSE) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
cb_return = (-1);
done:
/* Close location given to callback. */
if(cur_grp > 0)
- if(H5I_dec_ref(cur_grp) < 0)
+ if(H5I_dec_ref(cur_grp, FALSE) < 0)
HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for current location")
if(ret_value < 0 && cb_return > 0)
- if(H5I_dec_ref(cb_return) < 0)
+ if(H5I_dec_ref(cb_return, FALSE) < 0)
HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
/* Close the LAPL, if we copied one */
- if(lapl_id > 0 && H5I_dec_ref(lapl_id) < 0)
+ if(lapl_id > 0 && H5I_dec_ref(lapl_id, FALSE) < 0)
HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close copied link access property list")
FUNC_LEAVE_NOAPI(ret_value)
@@ -422,7 +422,7 @@ H5G_traverse_mount(H5G_loc_t *obj_loc/*in,out*/)
if(0 == cmp) {
/* Get the child file */
child = parent->shared->mtab.child[md].file;
-
+
/* Get the location for the root group in the child's file */
oloc = H5G_oloc(child->shared->root_grp);
@@ -624,7 +624,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
size_t new_alloc; /* New component buffer size */
new_alloc = MAX3(1024, (2 * H5G_comp_alloc_g), (HDstrlen(name) + 1));
- if(NULL == (new_comp = H5MM_realloc(H5G_comp_g, new_alloc)))
+ if(NULL == (new_comp = (char *)H5MM_realloc(H5G_comp_g, new_alloc)))
HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "unable to allocate component buffer")
H5G_comp_g = new_comp;
H5G_comp_alloc_g = new_alloc;
@@ -633,7 +633,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
/* Traverse the path */
while((name = H5G_component(name, &nchars)) && *name) {
const char *s; /* Temporary string pointer */
- herr_t lookup_status; /* Status from object lookup */
+ htri_t lookup_status; /* Status from object lookup */
/*
* Copy the component name into a null-terminated buffer so
@@ -661,11 +661,11 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
} /* end if */
/* Get information for object in current group */
- /* (Defer issuing error for bad lookup until later) */
- lookup_status = H5G_obj_lookup(grp_loc.oloc, H5G_comp_g, &lnk/*out*/, dxpl_id);
+ if((lookup_status = H5G_obj_lookup(grp_loc.oloc, H5G_comp_g, &lnk/*out*/, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't look up component")
/* If the lookup was OK, build object location and traverse special links, etc. */
- if(lookup_status >= 0) {
+ if(lookup_status) {
/* Sanity check link and indicate it's valid */
HDassert(lnk.type >= H5L_TYPE_HARD);
HDassert(!HDstrcmp(H5G_comp_g, lnk.name));
@@ -688,14 +688,14 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
H5G_loc_t *cb_loc; /* Pointer to object location for callback */
/* Set callback parameters appropriately, based on link being found */
- if(lookup_status < 0) {
+ if(lookup_status) {
+ cb_lnk = &lnk;
+ cb_loc = &obj_loc;
+ } /* end if */
+ else {
HDassert(!obj_loc_valid);
cb_lnk = NULL;
cb_loc = NULL;
- } /* end if */
- else {
- cb_lnk = &lnk;
- cb_loc = &obj_loc;
} /* end else */
/* Call 'operator' routine */
@@ -706,51 +706,74 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
} /* end if */
/* Handle lookup failures now */
- if(lookup_status < 0) {
+ if(!lookup_status) {
/* If an intermediate group doesn't exist & flag is set, create the group */
if(target & H5G_CRT_INTMD_GROUP) {
const H5O_ginfo_t def_ginfo = H5G_CRT_GROUP_INFO_DEF; /* Default group info settings */
const H5O_linfo_t def_linfo = H5G_CRT_LINK_INFO_DEF; /* Default link info settings */
+ const H5O_pline_t def_pline = H5O_CRT_PIPELINE_DEF; /* Default filter pipeline settings */
H5O_ginfo_t par_ginfo; /* Group info settings for parent group */
H5O_linfo_t par_linfo; /* Link info settings for parent group */
+ H5O_pline_t par_pline; /* Filter pipeline settings for parent group */
H5O_linfo_t tmp_linfo; /* Temporary link info settings */
+ htri_t exists; /* Whether a group or link info message exists */
const H5O_ginfo_t *ginfo; /* Group info settings for new group */
const H5O_linfo_t *linfo; /* Link info settings for new group */
+ const H5O_pline_t *pline; /* Filter pipeline settings for new group */
- /* Get the group info for parent group */
+ /* Check for the parent group having a group info message */
/* (OK if not found) */
- if(NULL == H5O_msg_read(grp_loc.oloc, H5O_GINFO_ID, &par_ginfo, dxpl_id)) {
- /* Clear error stack from not finding the group info message */
- H5E_clear_stack(NULL);
-
- /* Use default group info settings */
- ginfo = &def_ginfo;
+ if((exists = H5O_msg_exists(grp_loc.oloc, H5O_GINFO_ID, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read object header")
+ if(exists) {
+ /* Get the group info for parent group */
+ if(NULL == H5O_msg_read(grp_loc.oloc, H5O_GINFO_ID, &par_ginfo, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "group info message not present")
+
+ /* Use parent group info settings */
+ ginfo = &par_ginfo;
} /* end if */
else
- ginfo = &par_ginfo;
+ /* Use default group info settings */
+ ginfo = &def_ginfo;
- /* Get the link info for parent group */
+ /* Check for the parent group having a link info message */
/* (OK if not found) */
- if(NULL == H5G_obj_get_linfo(grp_loc.oloc, &par_linfo, dxpl_id)) {
- /* Clear error stack from not finding the link info message */
- H5E_clear_stack(NULL);
-
- /* Use default link info settings */
- linfo = &def_linfo;
- } /* end if */
- else {
- /* Only keep the creation order information from the parent
+ /* Get the link info for parent group */
+ if((exists = H5G_obj_get_linfo(grp_loc.oloc, &par_linfo, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read object header")
+ if(exists) {
+ /* Only keep the creation order information from the parent
* group's link info
*/
HDmemcpy(&tmp_linfo, &def_linfo, sizeof(H5O_linfo_t));
tmp_linfo.track_corder = par_linfo.track_corder;
tmp_linfo.index_corder = par_linfo.index_corder;
linfo = &tmp_linfo;
- } /* end else */
+ } /* end if */
+ else
+ /* Use default link info settings */
+ linfo = &def_linfo;
+
+ /* Check for the parent group having a filter pipeline message */
+ /* (OK if not found) */
+ if((exists = H5O_msg_exists(grp_loc.oloc, H5O_PLINE_ID, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read object header")
+ if(exists) {
+ /* Get the filter pipeline for parent group */
+ if(NULL == H5O_msg_read(grp_loc.oloc, H5O_PLINE_ID, &par_pline, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "filter pipeline message not present")
+
+ /* Use parent filter pipeline settings */
+ pline = &par_pline;
+ } /* end if */
+ else
+ /* Use default filter pipeline settings */
+ pline = &def_pline;
/* Create the intermediate group */
/* XXX: Should we allow user to control the group creation params here? -QAK */
- if(H5G_obj_create(grp_oloc.file, dxpl_id, ginfo, linfo, H5P_GROUP_CREATE_DEFAULT, obj_loc.oloc/*out*/) < 0)
+ if(H5G_obj_create_real(grp_oloc.file, dxpl_id, ginfo, linfo, pline, H5P_GROUP_CREATE_DEFAULT, obj_loc.oloc/*out*/) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry")
/* Insert new group into current group's symbol table */
@@ -814,7 +837,7 @@ done:
H5G_loc_free(&obj_loc);
if(group_copy && !(own_loc & H5G_OWN_GRP_LOC))
H5G_loc_free(&grp_loc);
-
+
/* If there's valid information in the link, reset it */
if(link_valid)
H5O_msg_reset(H5O_LINK_ID, &lnk);
@@ -862,7 +885,7 @@ H5G_traverse(const H5G_loc_t *loc, const char *name, unsigned target, H5G_traver
if(lapl_id == H5P_DEFAULT)
nlinks = H5L_NUM_LINKS;
else {
- if(NULL == (lapl = H5I_object(lapl_id)))
+ if(NULL == (lapl = (H5P_genplist_t *)H5I_object(lapl_id)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
if(H5P_get(lapl, H5L_ACS_NLINKS_NAME, &nlinks) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get number of links")
diff --git a/src/H5HF.c b/src/H5HF.c
index cf989e1..0856d89 100644
--- a/src/H5HF.c
+++ b/src/H5HF.c
@@ -172,10 +172,10 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
/* Allocate fractal heap wrapper */
if(NULL == (fh = H5FL_MALLOC(H5HF_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap info")
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed for fractal heap info")
/* Lock the heap header into memory */
- if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (hdr = (H5HF_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to load fractal heap header")
/* Point fractal heap wrapper at header and bump it's ref count */
@@ -196,10 +196,9 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
done:
if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap header")
- if(!ret_value) {
- if(fh)
- (void)H5HF_close(fh, dxpl_id);
- } /* end if */
+ if(!ret_value && fh)
+ if(H5HF_close(fh, dxpl_id) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTCLOSEOBJ, NULL, "unable to close fractal heap")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_create() */
@@ -238,7 +237,7 @@ H5HF_open(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr)
#ifdef QAK
HDfprintf(stderr, "%s: fh_addr = %a\n", FUNC, fh_addr);
#endif /* QAK */
- if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (hdr = (H5HF_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load fractal heap header")
#ifdef QAK
HDfprintf(stderr, "%s: hdr->rc = %u, hdr->fspace = %p\n", FUNC, hdr->rc, hdr->fspace);
@@ -250,7 +249,7 @@ HDfprintf(stderr, "%s: hdr->rc = %u, hdr->fspace = %p\n", FUNC, hdr->rc, hdr->fs
/* Create fractal heap info */
if(NULL == (fh = H5FL_MALLOC(H5HF_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap info")
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed for fractal heap info")
/* Point fractal heap wrapper at header */
fh->hdr = hdr;
@@ -270,10 +269,9 @@ HDfprintf(stderr, "%s: hdr->rc = %u, hdr->fspace = %p\n", FUNC, hdr->rc, hdr->fs
done:
if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap header")
- if(!ret_value) {
- if(fh)
- (void)H5HF_close(fh, dxpl_id);
- } /* end if */
+ if(!ret_value && fh)
+ if(H5HF_close(fh, dxpl_id) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTCLOSEOBJ, NULL, "unable to close fractal heap")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_open() */
@@ -324,7 +322,7 @@ H5HF_get_id_len(H5HF_t *fh, size_t *id_len_p)
*-------------------------------------------------------------------------
*/
herr_t
-H5HF_get_heap_addr(H5HF_t *fh, haddr_t *heap_addr_p)
+H5HF_get_heap_addr(const H5HF_t *fh, haddr_t *heap_addr_p)
{
FUNC_ENTER_NOAPI_NOFUNC(H5HF_get_heap_addr)
@@ -635,7 +633,7 @@ done:
*
* Purpose: Perform an operation directly on a heap object
*
- * Note: The library routines currently assume that the 'op' callback
+ * Note: The library routines currently assume that the 'op' callback
* won't modify the object. This can easily be changed later for
* "managed" heap objects, and, with some difficulty, for 'huge'
* and 'tiny' heap objects.
@@ -847,6 +845,9 @@ HDfprintf(stderr, "%s; After iterator reset fh->hdr->rc = %Zu\n", FUNC, fh->hdr-
} /* end if */
/* Decrement the reference count on the heap header */
+ /* (don't put in H5HF_hdr_fuse_decr() as the heap header may be evicted
+ * immediately -QAK)
+ */
if(H5HF_hdr_decr(fh->hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared heap header")
@@ -855,7 +856,7 @@ HDfprintf(stderr, "%s; After iterator reset fh->hdr->rc = %Zu\n", FUNC, fh->hdr-
H5HF_hdr_t *hdr; /* Another pointer to fractal heap header */
/* Lock the heap header into memory */
- if(NULL == (hdr = H5AC_protect(fh->f, dxpl_id, H5AC_FHEAP_HDR, heap_addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (hdr = (H5HF_hdr_t *)H5AC_protect(fh->f, dxpl_id, H5AC_FHEAP_HDR, heap_addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header")
/* Set the shared heap header's file context for this operation */
@@ -867,7 +868,7 @@ HDfprintf(stderr, "%s; After iterator reset fh->hdr->rc = %Zu\n", FUNC, fh->hdr-
} /* end if */
/* Release the fractal heap wrapper */
- H5FL_FREE(H5HF_t, fh);
+ (void)H5FL_FREE(H5HF_t, fh);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -905,13 +906,16 @@ H5HF_delete(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr)
#ifdef QAK
HDfprintf(stderr, "%s: fh_addr = %a\n", FUNC, fh_addr);
#endif /* QAK */
- if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (hdr = (H5HF_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header")
/* Check for files using shared heap header */
if(hdr->file_rc)
hdr->pending_delete = TRUE;
else {
+ /* Set the shared heap header's file context for this operation */
+ hdr->f = f;
+
/* Delete heap now, starting with header (unprotects header) */
if(H5HF_hdr_delete(hdr, dxpl_id) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "unable to delete fractal heap")
diff --git a/src/H5HFbtree2.c b/src/H5HFbtree2.c
index eabb740..3f208e7 100644
--- a/src/H5HFbtree2.c
+++ b/src/H5HFbtree2.c
@@ -49,6 +49,12 @@
/* Local Typedefs */
/******************/
+/* v2 B-tree client callback context */
+typedef struct H5HF_huge_bt2_ctx_t {
+ uint8_t sizeof_size; /* Size of file sizes */
+ uint8_t sizeof_addr; /* Size of file addresses */
+} H5HF_huge_bt2_ctx_t;
+
/********************/
/* Package Typedefs */
@@ -59,105 +65,114 @@
/* Local Prototypes */
/********************/
-/* v2 B-tree function callbacks */
-herr_t H5HF_huge_bt2_indir_found(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_indir_remove(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_filt_indir_found(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_filt_indir_remove(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_dir_remove(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_filt_dir_found(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_filt_dir_remove(const void *nrecord, void *op_data);
/* v2 B-tree driver callbacks */
-static herr_t H5HF_huge_btree2_indir_store(void *native, const void *udata);
-static herr_t H5HF_huge_btree2_indir_retrieve(void *udata, const void *native);
-static herr_t H5HF_huge_btree2_indir_compare(const void *rec1, const void *rec2);
-static herr_t H5HF_huge_btree2_indir_encode(const H5F_t *f, uint8_t *raw,
- const void *native);
-static herr_t H5HF_huge_btree2_indir_decode(const H5F_t *f, const uint8_t *raw,
- void *native);
-static herr_t H5HF_huge_btree2_indir_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
+
+static void *H5HF_huge_bt2_crt_context(void *udata);
+static herr_t H5HF_huge_bt2_dst_context(void *ctx);
+static void *H5HF_huge_bt2_crt_dbg_context(H5F_t *f, hid_t dxpl_id, haddr_t addr);
+
+static herr_t H5HF_huge_bt2_indir_store(void *native, const void *udata);
+static herr_t H5HF_huge_bt2_indir_compare(const void *rec1, const void *rec2);
+static herr_t H5HF_huge_bt2_indir_encode(uint8_t *raw, const void *native,
+ void *ctx);
+static herr_t H5HF_huge_bt2_indir_decode(const uint8_t *raw, void *native,
+ void *ctx);
+static herr_t H5HF_huge_bt2_indir_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
int indent, int fwidth, const void *record, const void *_udata);
-static herr_t H5HF_huge_btree2_filt_indir_store(void *native, const void *udata);
-static herr_t H5HF_huge_btree2_filt_indir_retrieve(void *udata, const void *native);
-static herr_t H5HF_huge_btree2_filt_indir_compare(const void *rec1, const void *rec2);
-static herr_t H5HF_huge_btree2_filt_indir_encode(const H5F_t *f, uint8_t *raw,
- const void *native);
-static herr_t H5HF_huge_btree2_filt_indir_decode(const H5F_t *f, const uint8_t *raw,
- void *native);
-static herr_t H5HF_huge_btree2_filt_indir_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
+static herr_t H5HF_huge_bt2_filt_indir_store(void *native, const void *udata);
+static herr_t H5HF_huge_bt2_filt_indir_compare(const void *rec1, const void *rec2);
+static herr_t H5HF_huge_bt2_filt_indir_encode(uint8_t *raw, const void *native,
+ void *ctx);
+static herr_t H5HF_huge_bt2_filt_indir_decode(const uint8_t *raw, void *native,
+ void *ctx);
+static herr_t H5HF_huge_bt2_filt_indir_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
int indent, int fwidth, const void *record, const void *_udata);
-static herr_t H5HF_huge_btree2_dir_store(void *native, const void *udata);
-static herr_t H5HF_huge_btree2_dir_retrieve(void *udata, const void *native);
-static herr_t H5HF_huge_btree2_dir_compare(const void *rec1, const void *rec2);
-static herr_t H5HF_huge_btree2_dir_encode(const H5F_t *f, uint8_t *raw,
- const void *native);
-static herr_t H5HF_huge_btree2_dir_decode(const H5F_t *f, const uint8_t *raw,
- void *native);
-static herr_t H5HF_huge_btree2_dir_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
+static herr_t H5HF_huge_bt2_dir_store(void *native, const void *udata);
+static herr_t H5HF_huge_bt2_dir_compare(const void *rec1, const void *rec2);
+static herr_t H5HF_huge_bt2_dir_encode(uint8_t *raw, const void *native,
+ void *ctx);
+static herr_t H5HF_huge_bt2_dir_decode(const uint8_t *raw, void *native,
+ void *ctx);
+static herr_t H5HF_huge_bt2_dir_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
int indent, int fwidth, const void *record, const void *_udata);
-static herr_t H5HF_huge_btree2_filt_dir_store(void *native, const void *udata);
-static herr_t H5HF_huge_btree2_filt_dir_retrieve(void *udata, const void *native);
-static herr_t H5HF_huge_btree2_filt_dir_compare(const void *rec1, const void *rec2);
-static herr_t H5HF_huge_btree2_filt_dir_encode(const H5F_t *f, uint8_t *raw,
- const void *native);
-static herr_t H5HF_huge_btree2_filt_dir_decode(const H5F_t *f, const uint8_t *raw,
- void *native);
-static herr_t H5HF_huge_btree2_filt_dir_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
+static herr_t H5HF_huge_bt2_filt_dir_store(void *native, const void *udata);
+static herr_t H5HF_huge_bt2_filt_dir_compare(const void *rec1, const void *rec2);
+static herr_t H5HF_huge_bt2_filt_dir_encode(uint8_t *raw, const void *native,
+ void *ctx);
+static herr_t H5HF_huge_bt2_filt_dir_decode(const uint8_t *raw, void *native,
+ void *ctx);
+static herr_t H5HF_huge_bt2_filt_dir_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
int indent, int fwidth, const void *record, const void *_udata);
/*********************/
/* Package Variables */
/*********************/
/* v2 B-tree class for indirectly accessed 'huge' objects */
-const H5B2_class_t H5HF_BT2_INDIR[1]={{ /* B-tree class information */
- H5B2_FHEAP_HUGE_INDIR_ID, /* Type of B-tree */
- sizeof(H5HF_huge_bt2_indir_rec_t), /* Size of native record */
- H5HF_huge_btree2_indir_store, /* Record storage callback */
- H5HF_huge_btree2_indir_retrieve, /* Record retrieval callback */
- H5HF_huge_btree2_indir_compare, /* Record comparison callback */
- H5HF_huge_btree2_indir_encode, /* Record encoding callback */
- H5HF_huge_btree2_indir_decode, /* Record decoding callback */
- H5HF_huge_btree2_indir_debug /* Record debugging callback */
+const H5B2_class_t H5HF_HUGE_BT2_INDIR[1]={{ /* B-tree class information */
+ H5B2_FHEAP_HUGE_INDIR_ID, /* Type of B-tree */
+ "H5B2_FHEAP_HUGE_INDIR_ID", /* Name of B-tree class */
+ sizeof(H5HF_huge_bt2_indir_rec_t), /* Size of native record */
+ H5HF_huge_bt2_crt_context, /* Create client callback context */
+ H5HF_huge_bt2_dst_context, /* Destroy client callback context */
+ H5HF_huge_bt2_indir_store, /* Record storage callback */
+ H5HF_huge_bt2_indir_compare, /* Record comparison callback */
+ H5HF_huge_bt2_indir_encode, /* Record encoding callback */
+ H5HF_huge_bt2_indir_decode, /* Record decoding callback */
+ H5HF_huge_bt2_indir_debug, /* Record debugging callback */
+ H5HF_huge_bt2_crt_dbg_context, /* Create debugging context */
+ H5HF_huge_bt2_dst_context /* Destroy debugging context */
}};
/* v2 B-tree class for indirectly accessed, filtered 'huge' objects */
-const H5B2_class_t H5HF_BT2_FILT_INDIR[1]={{ /* B-tree class information */
- H5B2_FHEAP_HUGE_FILT_INDIR_ID, /* Type of B-tree */
- sizeof(H5HF_huge_bt2_filt_indir_rec_t), /* Size of native record */
- H5HF_huge_btree2_filt_indir_store, /* Record storage callback */
- H5HF_huge_btree2_filt_indir_retrieve, /* Record retrieval callback */
- H5HF_huge_btree2_filt_indir_compare, /* Record comparison callback */
- H5HF_huge_btree2_filt_indir_encode, /* Record encoding callback */
- H5HF_huge_btree2_filt_indir_decode, /* Record decoding callback */
- H5HF_huge_btree2_filt_indir_debug /* Record debugging callback */
+const H5B2_class_t H5HF_HUGE_BT2_FILT_INDIR[1]={{ /* B-tree class information */
+ H5B2_FHEAP_HUGE_FILT_INDIR_ID, /* Type of B-tree */
+ "H5B2_FHEAP_HUGE_FILT_INDIR_ID", /* Name of B-tree class */
+ sizeof(H5HF_huge_bt2_filt_indir_rec_t), /* Size of native record */
+ H5HF_huge_bt2_crt_context, /* Create client callback context */
+ H5HF_huge_bt2_dst_context, /* Destroy client callback context */
+ H5HF_huge_bt2_filt_indir_store, /* Record storage callback */
+ H5HF_huge_bt2_filt_indir_compare, /* Record comparison callback */
+ H5HF_huge_bt2_filt_indir_encode, /* Record encoding callback */
+ H5HF_huge_bt2_filt_indir_decode, /* Record decoding callback */
+ H5HF_huge_bt2_filt_indir_debug, /* Record debugging callback */
+ H5HF_huge_bt2_crt_dbg_context, /* Create debugging context */
+ H5HF_huge_bt2_dst_context /* Destroy debugging context */
}};
/* v2 B-tree class for directly accessed 'huge' objects */
-const H5B2_class_t H5HF_BT2_DIR[1]={{ /* B-tree class information */
- H5B2_FHEAP_HUGE_DIR_ID, /* Type of B-tree */
- sizeof(H5HF_huge_bt2_dir_rec_t), /* Size of native record */
- H5HF_huge_btree2_dir_store, /* Record storage callback */
- H5HF_huge_btree2_dir_retrieve, /* Record retrieval callback */
- H5HF_huge_btree2_dir_compare, /* Record comparison callback */
- H5HF_huge_btree2_dir_encode, /* Record encoding callback */
- H5HF_huge_btree2_dir_decode, /* Record decoding callback */
- H5HF_huge_btree2_dir_debug /* Record debugging callback */
+const H5B2_class_t H5HF_HUGE_BT2_DIR[1]={{ /* B-tree class information */
+ H5B2_FHEAP_HUGE_DIR_ID, /* Type of B-tree */
+ "H5B2_FHEAP_HUGE_DIR_ID", /* Name of B-tree class */
+ sizeof(H5HF_huge_bt2_dir_rec_t), /* Size of native record */
+ H5HF_huge_bt2_crt_context, /* Create client callback context */
+ H5HF_huge_bt2_dst_context, /* Destroy client callback context */
+ H5HF_huge_bt2_dir_store, /* Record storage callback */
+ H5HF_huge_bt2_dir_compare, /* Record comparison callback */
+ H5HF_huge_bt2_dir_encode, /* Record encoding callback */
+ H5HF_huge_bt2_dir_decode, /* Record decoding callback */
+ H5HF_huge_bt2_dir_debug, /* Record debugging callback */
+ H5HF_huge_bt2_crt_dbg_context, /* Create debugging context */
+ H5HF_huge_bt2_dst_context /* Destroy debugging context */
}};
/* v2 B-tree class for directly accessed, filtered 'huge' objects */
-const H5B2_class_t H5HF_BT2_FILT_DIR[1]={{ /* B-tree class information */
- H5B2_FHEAP_HUGE_FILT_DIR_ID, /* Type of B-tree */
- sizeof(H5HF_huge_bt2_filt_dir_rec_t),/* Size of native record */
- H5HF_huge_btree2_filt_dir_store, /* Record storage callback */
- H5HF_huge_btree2_filt_dir_retrieve, /* Record retrieval callback */
- H5HF_huge_btree2_filt_dir_compare, /* Record comparison callback */
- H5HF_huge_btree2_filt_dir_encode, /* Record encoding callback */
- H5HF_huge_btree2_filt_dir_decode, /* Record decoding callback */
- H5HF_huge_btree2_filt_dir_debug /* Record debugging callback */
+const H5B2_class_t H5HF_HUGE_BT2_FILT_DIR[1]={{ /* B-tree class information */
+ H5B2_FHEAP_HUGE_FILT_DIR_ID, /* Type of B-tree */
+ "H5B2_FHEAP_HUGE_FILT_DIR_ID", /* Name of B-tree class */
+ sizeof(H5HF_huge_bt2_filt_dir_rec_t), /* Size of native record */
+ H5HF_huge_bt2_crt_context, /* Create client callback context */
+ H5HF_huge_bt2_dst_context, /* Destroy client callback context */
+ H5HF_huge_bt2_filt_dir_store, /* Record storage callback */
+ H5HF_huge_bt2_filt_dir_compare, /* Record comparison callback */
+ H5HF_huge_bt2_filt_dir_encode, /* Record encoding callback */
+ H5HF_huge_bt2_filt_dir_decode, /* Record decoding callback */
+ H5HF_huge_bt2_filt_dir_debug, /* Record debugging callback */
+ H5HF_huge_bt2_crt_dbg_context, /* Create debugging context */
+ H5HF_huge_bt2_dst_context /* Destroy debugging context */
}};
/*****************************/
@@ -169,6 +184,126 @@ const H5B2_class_t H5HF_BT2_FILT_DIR[1]={{ /* B-tree class information */
/* Local Variables */
/*******************/
+/* Declare a free list to manage the H5HF_huge_bt2_ctx_t struct */
+H5FL_DEFINE_STATIC(H5HF_huge_bt2_ctx_t);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_huge_bt2_crt_context
+ *
+ * Purpose: Create client callback context
+ *
+ * Note: Common to all 'huge' v2 B-tree clients
+ *
+ * Return: Success: non-NULL
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, November 26, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5HF_huge_bt2_crt_context(void *_f)
+{
+ H5F_t *f = (H5F_t *)_f; /* User data for building callback context */
+ H5HF_huge_bt2_ctx_t *ctx; /* Callback context structure */
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_bt2_crt_context)
+
+ /* Sanity check */
+ HDassert(f);
+
+ /* Allocate callback context */
+ if(NULL == (ctx = H5FL_MALLOC(H5HF_huge_bt2_ctx_t)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate callback context")
+
+ /* Determine the size of addresses & lengths in the file */
+ ctx->sizeof_addr = H5F_SIZEOF_ADDR(f);
+ ctx->sizeof_size = H5F_SIZEOF_SIZE(f);
+
+ /* Set return value */
+ ret_value = ctx;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HF_huge_bt2_crt_context() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_huge_bt2_dst_context
+ *
+ * Purpose: Destroy client callback context
+ *
+ * Note: Common to all 'huge' v2 B-tree clients
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, November 26, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HF_huge_bt2_dst_context(void *_ctx)
+{
+ H5HF_huge_bt2_ctx_t *ctx = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_dst_context)
+
+ /* Sanity check */
+ HDassert(ctx);
+
+ /* Release callback context */
+ ctx = H5FL_FREE(H5HF_huge_bt2_ctx_t, ctx);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5HF_huge_bt2_dst_context() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_huge_bt2_crt_dbg_context
+ *
+ * Purpose: Create context for debugging callback
+ *
+ * Return: Success: non-NULL
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, December 1, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5HF_huge_bt2_crt_dbg_context(H5F_t *f, hid_t UNUSED dxpl_id, haddr_t UNUSED addr)
+{
+ H5HF_huge_bt2_ctx_t *ctx; /* Callback context structure */
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_bt2_crt_dbg_context)
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+
+ /* Allocate callback context */
+ if(NULL == (ctx = H5FL_MALLOC(H5HF_huge_bt2_ctx_t)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate callback context")
+
+ /* Determine the size of addresses & lengths in the file */
+ ctx->sizeof_addr = H5F_SIZEOF_ADDR(f);
+ ctx->sizeof_size = H5F_SIZEOF_SIZE(f);
+
+ /* Set return value */
+ ret_value = ctx;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HF_huge_bt2_crt_dbg_context() */
+
/*-------------------------------------------------------------------------
* Function: H5HF_huge_bt2_indir_found
@@ -236,7 +371,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_indir_store
+ * Function: H5HF_huge_bt2_indir_store
*
* Purpose: Store native information into record for v2 B-tree
*
@@ -249,42 +384,18 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_indir_store(void *nrecord, const void *udata)
+H5HF_huge_bt2_indir_store(void *nrecord, const void *udata)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_indir_store)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_indir_store)
*(H5HF_huge_bt2_indir_rec_t *)nrecord = *(const H5HF_huge_bt2_indir_rec_t *)udata;
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_indir_store() */
+} /* H5HF_huge_bt2_indir_store() */
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_indir_retrieve
- *
- * Purpose: Retrieve native information from record for v2 B-tree
- *
- * Return: Success: non-negative
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Monday, August 7, 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5HF_huge_btree2_indir_retrieve(void *udata, const void *nrecord)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_indir_retrieve)
-
- *(H5HF_huge_bt2_indir_rec_t *)udata = *(const H5HF_huge_bt2_indir_rec_t *)nrecord;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_indir_retrieve() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_indir_compare
+ * Function: H5HF_huge_bt2_indir_compare
*
* Purpose: Compare two native information records, according to some key
*
@@ -298,25 +409,25 @@ H5HF_huge_btree2_indir_retrieve(void *udata, const void *nrecord)
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_indir_compare(const void *_rec1, const void *_rec2)
+H5HF_huge_bt2_indir_compare(const void *_rec1, const void *_rec2)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_indir_compare)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_indir_compare)
#ifdef QAK
{
const H5HF_huge_bt2_indir_rec_t *rec1 = (const H5HF_huge_bt2_indir_rec_t *)_rec1;
const H5HF_huge_bt2_indir_rec_t *rec2 = (const H5HF_huge_bt2_indir_rec_t *)_rec2;
-HDfprintf(stderr, "%s: rec1 = {%a, %Hu, %Hu}\n", "H5HF_huge_btree2_indir_compare", rec1->addr, rec1->len, rec1->id);
-HDfprintf(stderr, "%s: rec2 = {%a, %Hu, %Hu}\n", "H5HF_huge_btree2_indir_compare", rec2->addr, rec2->len, rec2->id);
+HDfprintf(stderr, "%s: rec1 = {%a, %Hu, %Hu}\n", "H5HF_huge_bt2_indir_compare", rec1->addr, rec1->len, rec1->id);
+HDfprintf(stderr, "%s: rec2 = {%a, %Hu, %Hu}\n", "H5HF_huge_bt2_indir_compare", rec2->addr, rec2->len, rec2->id);
}
#endif /* QAK */
FUNC_LEAVE_NOAPI((herr_t)(((const H5HF_huge_bt2_indir_rec_t *)_rec1)->id - ((const H5HF_huge_bt2_indir_rec_t *)_rec2)->id))
-} /* H5HF_huge_btree2_indir_compare() */
+} /* H5HF_huge_bt2_indir_compare() */
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_indir_encode
+ * Function: H5HF_huge_bt2_indir_encode
*
* Purpose: Encode native information into raw form for storing on disk
*
@@ -329,23 +440,27 @@ HDfprintf(stderr, "%s: rec2 = {%a, %Hu, %Hu}\n", "H5HF_huge_btree2_indir_compare
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_indir_encode(const H5F_t *f, uint8_t *raw, const void *_nrecord)
+H5HF_huge_bt2_indir_encode(uint8_t *raw, const void *_nrecord, void *_ctx)
{
+ H5HF_huge_bt2_ctx_t *ctx = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
const H5HF_huge_bt2_indir_rec_t *nrecord = (const H5HF_huge_bt2_indir_rec_t *)_nrecord;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_indir_encode)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_indir_encode)
+
+ /* Sanity check */
+ HDassert(ctx);
/* Encode the record's fields */
- H5F_addr_encode(f, &raw, nrecord->addr);
- H5F_ENCODE_LENGTH(f, raw, nrecord->len);
- H5F_ENCODE_LENGTH(f, raw, nrecord->id);
+ H5F_addr_encode_len(ctx->sizeof_addr, &raw, nrecord->addr);
+ H5F_ENCODE_LENGTH_LEN(raw, nrecord->len, ctx->sizeof_size);
+ H5F_ENCODE_LENGTH_LEN(raw, nrecord->id, ctx->sizeof_size);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_indir_encode() */
+} /* H5HF_huge_bt2_indir_encode() */
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_indir_decode
+ * Function: H5HF_huge_bt2_indir_decode
*
* Purpose: Decode raw disk form of record into native form
*
@@ -358,23 +473,27 @@ H5HF_huge_btree2_indir_encode(const H5F_t *f, uint8_t *raw, const void *_nrecord
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_indir_decode(const H5F_t *f, const uint8_t *raw, void *_nrecord)
+H5HF_huge_bt2_indir_decode(const uint8_t *raw, void *_nrecord, void *_ctx)
{
+ H5HF_huge_bt2_ctx_t *ctx = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
H5HF_huge_bt2_indir_rec_t *nrecord = (H5HF_huge_bt2_indir_rec_t *)_nrecord;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_indir_decode)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_indir_decode)
+
+ /* Sanity check */
+ HDassert(ctx);
/* Decode the record's fields */
- H5F_addr_decode(f, &raw, &nrecord->addr);
- H5F_DECODE_LENGTH(f, raw, nrecord->len);
- H5F_DECODE_LENGTH(f, raw, nrecord->id);
+ H5F_addr_decode_len(ctx->sizeof_addr, &raw, &nrecord->addr);
+ H5F_DECODE_LENGTH_LEN(raw, nrecord->len, ctx->sizeof_size);
+ H5F_DECODE_LENGTH_LEN(raw, nrecord->id, ctx->sizeof_size);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_indir_decode() */
+} /* H5HF_huge_bt2_indir_decode() */
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_indir_debug
+ * Function: H5HF_huge_bt2_indir_debug
*
* Purpose: Debug native form of record
*
@@ -387,19 +506,19 @@ H5HF_huge_btree2_indir_decode(const H5F_t *f, const uint8_t *raw, void *_nrecord
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_indir_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
+H5HF_huge_bt2_indir_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
int indent, int fwidth, const void *_nrecord,
const void UNUSED *_udata)
{
const H5HF_huge_bt2_indir_rec_t *nrecord = (const H5HF_huge_bt2_indir_rec_t *)_nrecord;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_indir_debug)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_indir_debug)
HDfprintf(stream, "%*s%-*s {%a, %Hu, %Hu}\n", indent, "", fwidth, "Record:",
nrecord->addr, nrecord->len, nrecord->id);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_indir_debug() */
+} /* H5HF_huge_bt2_indir_debug() */
/*-------------------------------------------------------------------------
@@ -470,7 +589,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_filt_indir_store
+ * Function: H5HF_huge_bt2_filt_indir_store
*
* Purpose: Store native information into record for v2 B-tree
*
@@ -483,42 +602,18 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_filt_indir_store(void *nrecord, const void *udata)
+H5HF_huge_bt2_filt_indir_store(void *nrecord, const void *udata)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_indir_store)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_filt_indir_store)
*(H5HF_huge_bt2_filt_indir_rec_t *)nrecord = *(const H5HF_huge_bt2_filt_indir_rec_t *)udata;
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_filt_indir_store() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_filt_indir_retrieve
- *
- * Purpose: Retrieve native information from record for v2 B-tree
- *
- * Return: Success: non-negative
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Monday, August 7, 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5HF_huge_btree2_filt_indir_retrieve(void *udata, const void *nrecord)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_indir_retrieve)
-
- *(H5HF_huge_bt2_filt_indir_rec_t *)udata = *(const H5HF_huge_bt2_filt_indir_rec_t *)nrecord;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_filt_indir_retrieve() */
+} /* H5HF_huge_bt2_filt_indir_store() */
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_filt_indir_compare
+ * Function: H5HF_huge_bt2_filt_indir_compare
*
* Purpose: Compare two native information records, according to some key
*
@@ -532,25 +627,25 @@ H5HF_huge_btree2_filt_indir_retrieve(void *udata, const void *nrecord)
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_filt_indir_compare(const void *_rec1, const void *_rec2)
+H5HF_huge_bt2_filt_indir_compare(const void *_rec1, const void *_rec2)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_indir_compare)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_filt_indir_compare)
#ifdef QAK
{
const H5HF_huge_bt2_filt_indir_rec_t *rec1 = (const H5HF_huge_bt2_filt_indir_rec_t *)_rec1;
const H5HF_huge_bt2_filt_indir_rec_t *rec2 = (const H5HF_huge_bt2_filt_indir_rec_t *)_rec2;
-HDfprintf(stderr, "%s: rec1 = {%a, %Hu, %x, %Hu, %Hu}\n", "H5HF_huge_btree2_filt_indir_compare", rec1->addr, rec1->len, rec1->filter_mask, rec1->obj_size, rec1->id);
-HDfprintf(stderr, "%s: rec2 = {%a, %Hu, %x, %Hu, %Hu}\n", "H5HF_huge_btree2_filt_indir_compare", rec2->addr, rec2->len, rec2->filter_mask, rec2->obj_size, rec2->id);
+HDfprintf(stderr, "%s: rec1 = {%a, %Hu, %x, %Hu, %Hu}\n", "H5HF_huge_bt2_filt_indir_compare", rec1->addr, rec1->len, rec1->filter_mask, rec1->obj_size, rec1->id);
+HDfprintf(stderr, "%s: rec2 = {%a, %Hu, %x, %Hu, %Hu}\n", "H5HF_huge_bt2_filt_indir_compare", rec2->addr, rec2->len, rec2->filter_mask, rec2->obj_size, rec2->id);
}
#endif /* QAK */
FUNC_LEAVE_NOAPI((herr_t)(((const H5HF_huge_bt2_filt_indir_rec_t *)_rec1)->id - ((const H5HF_huge_bt2_filt_indir_rec_t *)_rec2)->id))
-} /* H5HF_huge_btree2_filt_indir_compare() */
+} /* H5HF_huge_bt2_filt_indir_compare() */
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_filt_indir_encode
+ * Function: H5HF_huge_bt2_filt_indir_encode
*
* Purpose: Encode native information into raw form for storing on disk
*
@@ -563,25 +658,29 @@ HDfprintf(stderr, "%s: rec2 = {%a, %Hu, %x, %Hu, %Hu}\n", "H5HF_huge_btree2_filt
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_filt_indir_encode(const H5F_t *f, uint8_t *raw, const void *_nrecord)
+H5HF_huge_bt2_filt_indir_encode(uint8_t *raw, const void *_nrecord, void *_ctx)
{
+ H5HF_huge_bt2_ctx_t *ctx = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
const H5HF_huge_bt2_filt_indir_rec_t *nrecord = (const H5HF_huge_bt2_filt_indir_rec_t *)_nrecord;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_indir_encode)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_filt_indir_encode)
+
+ /* Sanity check */
+ HDassert(ctx);
/* Encode the record's fields */
- H5F_addr_encode(f, &raw, nrecord->addr);
- H5F_ENCODE_LENGTH(f, raw, nrecord->len);
+ H5F_addr_encode_len(ctx->sizeof_addr, &raw, nrecord->addr);
+ H5F_ENCODE_LENGTH_LEN(raw, nrecord->len, ctx->sizeof_size);
UINT32ENCODE(raw, nrecord->filter_mask);
- H5F_ENCODE_LENGTH(f, raw, nrecord->obj_size);
- H5F_ENCODE_LENGTH(f, raw, nrecord->id);
+ H5F_ENCODE_LENGTH_LEN(raw, nrecord->obj_size, ctx->sizeof_size);
+ H5F_ENCODE_LENGTH_LEN(raw, nrecord->id, ctx->sizeof_size);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_filt_indir_encode() */
+} /* H5HF_huge_bt2_filt_indir_encode() */
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_filt_indir_decode
+ * Function: H5HF_huge_bt2_filt_indir_decode
*
* Purpose: Decode raw disk form of record into native form
*
@@ -594,25 +693,29 @@ H5HF_huge_btree2_filt_indir_encode(const H5F_t *f, uint8_t *raw, const void *_nr
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_filt_indir_decode(const H5F_t *f, const uint8_t *raw, void *_nrecord)
+H5HF_huge_bt2_filt_indir_decode(const uint8_t *raw, void *_nrecord, void *_ctx)
{
+ H5HF_huge_bt2_ctx_t *ctx = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
H5HF_huge_bt2_filt_indir_rec_t *nrecord = (H5HF_huge_bt2_filt_indir_rec_t *)_nrecord;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_indir_decode)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_filt_indir_decode)
+
+ /* Sanity check */
+ HDassert(ctx);
/* Decode the record's fields */
- H5F_addr_decode(f, &raw, &nrecord->addr);
- H5F_DECODE_LENGTH(f, raw, nrecord->len);
+ H5F_addr_decode_len(ctx->sizeof_addr, &raw, &nrecord->addr);
+ H5F_DECODE_LENGTH_LEN(raw, nrecord->len, ctx->sizeof_size);
UINT32DECODE(raw, nrecord->filter_mask);
- H5F_DECODE_LENGTH(f, raw, nrecord->obj_size);
- H5F_DECODE_LENGTH(f, raw, nrecord->id);
+ H5F_DECODE_LENGTH_LEN(raw, nrecord->obj_size, ctx->sizeof_size);
+ H5F_DECODE_LENGTH_LEN(raw, nrecord->id, ctx->sizeof_size);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_filt_indir_decode() */
+} /* H5HF_huge_bt2_filt_indir_decode() */
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_filt_indir_debug
+ * Function: H5HF_huge_bt2_filt_indir_debug
*
* Purpose: Debug native form of record
*
@@ -625,19 +728,19 @@ H5HF_huge_btree2_filt_indir_decode(const H5F_t *f, const uint8_t *raw, void *_nr
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_filt_indir_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
+H5HF_huge_bt2_filt_indir_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
int indent, int fwidth, const void *_nrecord,
const void UNUSED *_udata)
{
const H5HF_huge_bt2_filt_indir_rec_t *nrecord = (const H5HF_huge_bt2_filt_indir_rec_t *)_nrecord;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_indir_debug)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_filt_indir_debug)
HDfprintf(stream, "%*s%-*s {%a, %Hu, %x, %Hu, %Hu}\n", indent, "", fwidth, "Record:",
nrecord->addr, nrecord->len, nrecord->filter_mask, nrecord->obj_size, nrecord->id);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_filt_indir_debug() */
+} /* H5HF_huge_bt2_filt_indir_debug() */
/*-------------------------------------------------------------------------
@@ -675,7 +778,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_dir_store
+ * Function: H5HF_huge_bt2_dir_store
*
* Purpose: Store native information into record for v2 B-tree
*
@@ -688,42 +791,18 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_dir_store(void *nrecord, const void *udata)
+H5HF_huge_bt2_dir_store(void *nrecord, const void *udata)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_dir_store)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_dir_store)
*(H5HF_huge_bt2_dir_rec_t *)nrecord = *(const H5HF_huge_bt2_dir_rec_t *)udata;
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_dir_store() */
+} /* H5HF_huge_bt2_dir_store() */
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_dir_retrieve
- *
- * Purpose: Retrieve native information from record for v2 B-tree
- *
- * Return: Success: non-negative
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Monday, August 7, 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5HF_huge_btree2_dir_retrieve(void *udata, const void *nrecord)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_dir_retrieve)
-
- *(H5HF_huge_bt2_dir_rec_t *)udata = *(const H5HF_huge_bt2_dir_rec_t *)nrecord;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_dir_retrieve() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_dir_compare
+ * Function: H5HF_huge_bt2_dir_compare
*
* Purpose: Compare two native information records, according to some key
*
@@ -737,17 +816,17 @@ H5HF_huge_btree2_dir_retrieve(void *udata, const void *nrecord)
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_dir_compare(const void *_rec1, const void *_rec2)
+H5HF_huge_bt2_dir_compare(const void *_rec1, const void *_rec2)
{
const H5HF_huge_bt2_dir_rec_t *rec1 = (const H5HF_huge_bt2_dir_rec_t *)_rec1;
const H5HF_huge_bt2_dir_rec_t *rec2 = (const H5HF_huge_bt2_dir_rec_t *)_rec2;
herr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_dir_compare)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_dir_compare)
#ifdef QAK
-HDfprintf(stderr, "%s: rec1 = {%a, %Hu}\n", "H5HF_huge_btree2_dir_compare", rec1->addr, rec1->len);
-HDfprintf(stderr, "%s: rec2 = {%a, %Hu}\n", "H5HF_huge_btree2_dir_compare", rec2->addr, rec2->len);
+HDfprintf(stderr, "%s: rec1 = {%a, %Hu}\n", "H5HF_huge_bt2_dir_compare", rec1->addr, rec1->len);
+HDfprintf(stderr, "%s: rec2 = {%a, %Hu}\n", "H5HF_huge_bt2_dir_compare", rec2->addr, rec2->len);
#endif /* QAK */
if(rec1->addr < rec2->addr)
ret_value = -1;
@@ -761,11 +840,11 @@ HDfprintf(stderr, "%s: rec2 = {%a, %Hu}\n", "H5HF_huge_btree2_dir_compare", rec2
ret_value = 0;
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5HF_huge_btree2_dir_compare() */
+} /* H5HF_huge_bt2_dir_compare() */
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_dir_encode
+ * Function: H5HF_huge_bt2_dir_encode
*
* Purpose: Encode native information into raw form for storing on disk
*
@@ -778,22 +857,26 @@ HDfprintf(stderr, "%s: rec2 = {%a, %Hu}\n", "H5HF_huge_btree2_dir_compare", rec2
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_dir_encode(const H5F_t *f, uint8_t *raw, const void *_nrecord)
+H5HF_huge_bt2_dir_encode(uint8_t *raw, const void *_nrecord, void *_ctx)
{
+ H5HF_huge_bt2_ctx_t *ctx = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
const H5HF_huge_bt2_dir_rec_t *nrecord = (const H5HF_huge_bt2_dir_rec_t *)_nrecord;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_dir_encode)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_dir_encode)
+
+ /* Sanity check */
+ HDassert(ctx);
/* Encode the record's fields */
- H5F_addr_encode(f, &raw, nrecord->addr);
- H5F_ENCODE_LENGTH(f, raw, nrecord->len);
+ H5F_addr_encode_len(ctx->sizeof_addr, &raw, nrecord->addr);
+ H5F_ENCODE_LENGTH_LEN(raw, nrecord->len, ctx->sizeof_size);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_dir_encode() */
+} /* H5HF_huge_bt2_dir_encode() */
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_dir_decode
+ * Function: H5HF_huge_bt2_dir_decode
*
* Purpose: Decode raw disk form of record into native form
*
@@ -806,22 +889,26 @@ H5HF_huge_btree2_dir_encode(const H5F_t *f, uint8_t *raw, const void *_nrecord)
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_dir_decode(const H5F_t *f, const uint8_t *raw, void *_nrecord)
+H5HF_huge_bt2_dir_decode(const uint8_t *raw, void *_nrecord, void *_ctx)
{
+ H5HF_huge_bt2_ctx_t *ctx = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
H5HF_huge_bt2_dir_rec_t *nrecord = (H5HF_huge_bt2_dir_rec_t *)_nrecord;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_dir_decode)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_dir_decode)
+
+ /* Sanity check */
+ HDassert(ctx);
/* Decode the record's fields */
- H5F_addr_decode(f, &raw, &nrecord->addr);
- H5F_DECODE_LENGTH(f, raw, nrecord->len);
+ H5F_addr_decode_len(ctx->sizeof_addr, &raw, &nrecord->addr);
+ H5F_DECODE_LENGTH_LEN(raw, nrecord->len, ctx->sizeof_size);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_dir_decode() */
+} /* H5HF_huge_bt2_dir_decode() */
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_dir_debug
+ * Function: H5HF_huge_bt2_dir_debug
*
* Purpose: Debug native form of record
*
@@ -834,19 +921,19 @@ H5HF_huge_btree2_dir_decode(const H5F_t *f, const uint8_t *raw, void *_nrecord)
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_dir_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
+H5HF_huge_bt2_dir_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
int indent, int fwidth, const void *_nrecord,
const void UNUSED *_udata)
{
const H5HF_huge_bt2_dir_rec_t *nrecord = (const H5HF_huge_bt2_dir_rec_t *)_nrecord;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_dir_debug)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_dir_debug)
HDfprintf(stream, "%*s%-*s {%a, %Hu}\n", indent, "", fwidth, "Record:",
nrecord->addr, nrecord->len);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_dir_debug() */
+} /* H5HF_huge_bt2_dir_debug() */
/*-------------------------------------------------------------------------
@@ -916,7 +1003,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_filt_dir_store
+ * Function: H5HF_huge_bt2_filt_dir_store
*
* Purpose: Store native information into record for v2 B-tree
*
@@ -929,42 +1016,18 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_filt_dir_store(void *nrecord, const void *udata)
+H5HF_huge_bt2_filt_dir_store(void *nrecord, const void *udata)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_dir_store)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_filt_dir_store)
*(H5HF_huge_bt2_filt_dir_rec_t *)nrecord = *(const H5HF_huge_bt2_filt_dir_rec_t *)udata;
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_filt_dir_store() */
+} /* H5HF_huge_bt2_filt_dir_store() */
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_filt_dir_retrieve
- *
- * Purpose: Retrieve native information from record for v2 B-tree
- *
- * Return: Success: non-negative
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Tuesday, August 15, 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5HF_huge_btree2_filt_dir_retrieve(void *udata, const void *nrecord)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_dir_retrieve)
-
- *(H5HF_huge_bt2_filt_dir_rec_t *)udata = *(const H5HF_huge_bt2_filt_dir_rec_t *)nrecord;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_filt_dir_retrieve() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_filt_dir_compare
+ * Function: H5HF_huge_bt2_filt_dir_compare
*
* Purpose: Compare two native information records, according to some key
*
@@ -978,17 +1041,17 @@ H5HF_huge_btree2_filt_dir_retrieve(void *udata, const void *nrecord)
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_filt_dir_compare(const void *_rec1, const void *_rec2)
+H5HF_huge_bt2_filt_dir_compare(const void *_rec1, const void *_rec2)
{
const H5HF_huge_bt2_filt_dir_rec_t *rec1 = (const H5HF_huge_bt2_filt_dir_rec_t *)_rec1;
const H5HF_huge_bt2_filt_dir_rec_t *rec2 = (const H5HF_huge_bt2_filt_dir_rec_t *)_rec2;
herr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_dir_compare)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_filt_dir_compare)
#ifdef QAK
-HDfprintf(stderr, "%s: rec1 = {%a, %Hu, %x, %Hu}\n", "H5HF_huge_btree2_filt_dir_compare", rec1->addr, rec1->len, rec1->filter_mask, rec1->obj_size);
-HDfprintf(stderr, "%s: rec2 = {%a, %Hu, %x, %Hu}\n", "H5HF_huge_btree2_filt_dir_compare", rec2->addr, rec2->len, rec2->filter_mask, rec2->obj_size);
+HDfprintf(stderr, "%s: rec1 = {%a, %Hu, %x, %Hu}\n", "H5HF_huge_bt2_filt_dir_compare", rec1->addr, rec1->len, rec1->filter_mask, rec1->obj_size);
+HDfprintf(stderr, "%s: rec2 = {%a, %Hu, %x, %Hu}\n", "H5HF_huge_bt2_filt_dir_compare", rec2->addr, rec2->len, rec2->filter_mask, rec2->obj_size);
#endif /* QAK */
if(rec1->addr < rec2->addr)
ret_value = -1;
@@ -1002,11 +1065,11 @@ HDfprintf(stderr, "%s: rec2 = {%a, %Hu, %x, %Hu}\n", "H5HF_huge_btree2_filt_dir_
ret_value = 0;
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5HF_huge_btree2_filt_dir_compare() */
+} /* H5HF_huge_bt2_filt_dir_compare() */
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_filt_dir_encode
+ * Function: H5HF_huge_bt2_filt_dir_encode
*
* Purpose: Encode native information into raw form for storing on disk
*
@@ -1019,24 +1082,28 @@ HDfprintf(stderr, "%s: rec2 = {%a, %Hu, %x, %Hu}\n", "H5HF_huge_btree2_filt_dir_
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_filt_dir_encode(const H5F_t *f, uint8_t *raw, const void *_nrecord)
+H5HF_huge_bt2_filt_dir_encode(uint8_t *raw, const void *_nrecord, void *_ctx)
{
+ H5HF_huge_bt2_ctx_t *ctx = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
const H5HF_huge_bt2_filt_dir_rec_t *nrecord = (const H5HF_huge_bt2_filt_dir_rec_t *)_nrecord;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_dir_encode)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_filt_dir_encode)
+
+ /* Sanity check */
+ HDassert(ctx);
/* Encode the record's fields */
- H5F_addr_encode(f, &raw, nrecord->addr);
- H5F_ENCODE_LENGTH(f, raw, nrecord->len);
+ H5F_addr_encode_len(ctx->sizeof_addr, &raw, nrecord->addr);
+ H5F_ENCODE_LENGTH_LEN(raw, nrecord->len, ctx->sizeof_size);
UINT32ENCODE(raw, nrecord->filter_mask);
- H5F_ENCODE_LENGTH(f, raw, nrecord->obj_size);
+ H5F_ENCODE_LENGTH_LEN(raw, nrecord->obj_size, ctx->sizeof_size);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_filt_dir_encode() */
+} /* H5HF_huge_bt2_filt_dir_encode() */
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_filt_dir_decode
+ * Function: H5HF_huge_bt2_filt_dir_decode
*
* Purpose: Decode raw disk form of record into native form
*
@@ -1049,24 +1116,28 @@ H5HF_huge_btree2_filt_dir_encode(const H5F_t *f, uint8_t *raw, const void *_nrec
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_filt_dir_decode(const H5F_t *f, const uint8_t *raw, void *_nrecord)
+H5HF_huge_bt2_filt_dir_decode(const uint8_t *raw, void *_nrecord, void *_ctx)
{
+ H5HF_huge_bt2_ctx_t *ctx = (H5HF_huge_bt2_ctx_t *)_ctx; /* Callback context structure */
H5HF_huge_bt2_filt_dir_rec_t *nrecord = (H5HF_huge_bt2_filt_dir_rec_t *)_nrecord;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_dir_decode)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_filt_dir_decode)
+
+ /* Sanity check */
+ HDassert(ctx);
/* Decode the record's fields */
- H5F_addr_decode(f, &raw, &nrecord->addr);
- H5F_DECODE_LENGTH(f, raw, nrecord->len);
+ H5F_addr_decode_len(ctx->sizeof_addr, &raw, &nrecord->addr);
+ H5F_DECODE_LENGTH_LEN(raw, nrecord->len, ctx->sizeof_size);
UINT32DECODE(raw, nrecord->filter_mask);
- H5F_DECODE_LENGTH(f, raw, nrecord->obj_size);
+ H5F_DECODE_LENGTH_LEN(raw, nrecord->obj_size, ctx->sizeof_size);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_filt_dir_decode() */
+} /* H5HF_huge_bt2_filt_dir_decode() */
/*-------------------------------------------------------------------------
- * Function: H5HF_huge_btree2_filt_dir_debug
+ * Function: H5HF_huge_bt2_filt_dir_debug
*
* Purpose: Debug native form of record
*
@@ -1079,16 +1150,16 @@ H5HF_huge_btree2_filt_dir_decode(const H5F_t *f, const uint8_t *raw, void *_nrec
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_huge_btree2_filt_dir_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
+H5HF_huge_bt2_filt_dir_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
int indent, int fwidth, const void *_nrecord, const void UNUSED *_udata)
{
const H5HF_huge_bt2_filt_dir_rec_t *nrecord = (const H5HF_huge_bt2_filt_dir_rec_t *)_nrecord;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_dir_debug)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_filt_dir_debug)
HDfprintf(stream, "%*s%-*s {%a, %Hu, %x, %Hu}\n", indent, "", fwidth, "Record:",
nrecord->addr, nrecord->len, nrecord->filter_mask, nrecord->obj_size);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_huge_btree2_filt_dir_debug() */
+} /* H5HF_huge_bt2_filt_dir_debug() */
diff --git a/src/H5HFcache.c b/src/H5HFcache.c
index 908188e..57d5524 100644
--- a/src/H5HFcache.c
+++ b/src/H5HFcache.c
@@ -30,6 +30,7 @@
#define H5HF_PACKAGE /*suppress error about including H5HFpkg */
+
/***********/
/* Headers */
/***********/
@@ -41,6 +42,7 @@
#include "H5Vprivate.h" /* Vectors and arrays */
#include "H5WBprivate.h" /* Wrapped Buffers */
+
/****************/
/* Local Macros */
/****************/
@@ -89,6 +91,7 @@ static herr_t H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy,
static herr_t H5HF_cache_dblock_clear(H5F_t *f, H5HF_direct_t *dblock, hbool_t destroy);
static herr_t H5HF_cache_dblock_size(const H5F_t *f, const H5HF_direct_t *dblock, size_t *size_ptr);
+
/*********************/
/* Package Variables */
/*********************/
@@ -100,6 +103,7 @@ const H5AC_class_t H5AC_FHEAP_HDR[1] = {{
(H5AC_flush_func_t)H5HF_cache_hdr_flush,
(H5AC_dest_func_t)H5HF_cache_hdr_dest,
(H5AC_clear_func_t)H5HF_cache_hdr_clear,
+ (H5AC_notify_func_t)NULL,
(H5AC_size_func_t)H5HF_cache_hdr_size,
}};
@@ -110,6 +114,7 @@ const H5AC_class_t H5AC_FHEAP_IBLOCK[1] = {{
(H5AC_flush_func_t)H5HF_cache_iblock_flush,
(H5AC_dest_func_t)H5HF_cache_iblock_dest,
(H5AC_clear_func_t)H5HF_cache_iblock_clear,
+ (H5AC_notify_func_t)NULL,
(H5AC_size_func_t)H5HF_cache_iblock_size,
}};
@@ -120,6 +125,7 @@ const H5AC_class_t H5AC_FHEAP_DBLOCK[1] = {{
(H5AC_flush_func_t)H5HF_cache_dblock_flush,
(H5AC_dest_func_t)H5HF_cache_dblock_dest,
(H5AC_clear_func_t)H5HF_cache_dblock_clear,
+ (H5AC_notify_func_t)NULL,
(H5AC_size_func_t)H5HF_cache_dblock_size,
}};
@@ -285,10 +291,10 @@ H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *ud
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't wrap buffer")
/* Compute the 'base' size of the fractal heap header on disk */
- size = H5HF_HEADER_SIZE(hdr);
+ size = (size_t)H5HF_HEADER_SIZE(hdr);
/* Get a pointer to a buffer that's large enough for serialized header */
- if(NULL == (buf = H5WB_actual(wb, size)))
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read header from disk */
@@ -299,9 +305,9 @@ H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *ud
p = buf;
/* Magic number */
- if(HDmemcmp(p, H5HF_HDR_MAGIC, (size_t)H5HF_SIZEOF_MAGIC))
+ if(HDmemcmp(p, H5HF_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong fractal heap header signature")
- p += H5HF_SIZEOF_MAGIC;
+ p += H5_SIZEOF_MAGIC;
/* Version */
if(*p++ != H5HF_HDR_VERSION)
@@ -352,18 +358,18 @@ H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *ud
H5O_pline_t *pline; /* Pipeline information from the header on disk */
/* Compute the offset of the filter info in the header */
- filter_info_off = p - (const uint8_t *)buf;
+ filter_info_off = (size_t)(p - (const uint8_t *)buf);
/* Compute the size of the extra filter information */
- filter_info_size = hdr->sizeof_size /* Size of size for filtered root direct block */
- + 4 /* Size of filter mask for filtered root direct block */
- + hdr->filter_len; /* Size of encoded I/O filter info */
+ filter_info_size = (size_t)(hdr->sizeof_size /* Size of size for filtered root direct block */
+ + (unsigned)4 /* Size of filter mask for filtered root direct block */
+ + hdr->filter_len); /* Size of encoded I/O filter info */
/* Compute the heap header's size */
hdr->heap_size = size + filter_info_size;
/* Re-size current buffer */
- if(NULL == (buf = H5WB_actual(wb, hdr->heap_size)))
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, hdr->heap_size)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read in I/O filter information */
@@ -381,7 +387,7 @@ H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *ud
UINT32DECODE(p, hdr->pline_root_direct_filter_mask);
/* Decode I/O filter information */
- if(NULL == (pline = (H5O_pline_t *)H5O_msg_decode(hdr->f, dxpl_id, H5O_PLINE_ID, p)))
+ if(NULL == (pline = (H5O_pline_t *)H5O_msg_decode(hdr->f, dxpl_id, NULL, H5O_PLINE_ID, p)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTDECODE, NULL, "can't decode I/O pipeline filters")
p += hdr->filter_len;
@@ -392,7 +398,7 @@ H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *ud
/* Release the space allocated for the I/O pipeline filters */
H5O_msg_free(H5O_PLINE_ID, pline);
} /* end if */
- else
+ else
/* Set the heap header's size */
hdr->heap_size = size;
@@ -422,7 +428,8 @@ done:
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
if(!ret_value && hdr)
- (void)H5HF_cache_hdr_dest(f, hdr);
+ if(H5HF_hdr_free(hdr) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTRELEASE, NULL, "unable to release fractal heap header")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_cache_hdr_load() */ /*lint !e818 Can't make udata a pointer to const */
@@ -462,9 +469,6 @@ H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5H
uint8_t heap_flags; /* Status flags for heap */
uint32_t metadata_chksum; /* Computed metadata checksum value */
- /* Sanity check */
- HDassert(hdr->dirty);
-
/* Set the shared heap header's file context for this operation */
hdr->f = f;
@@ -476,15 +480,15 @@ H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5H
size = hdr->heap_size;
/* Get a pointer to a buffer that's large enough for serialized header */
- if(NULL == (buf = H5WB_actual(wb, size)))
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Get temporary pointer to serialized header */
p = buf;
/* Magic number */
- HDmemcpy(p, H5HF_HDR_MAGIC, (size_t)H5HF_SIZEOF_MAGIC);
- p += H5HF_SIZEOF_MAGIC;
+ HDmemcpy(p, H5HF_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
/* Version # */
*p++ = H5HF_HDR_VERSION;
@@ -549,7 +553,6 @@ H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5H
if(H5F_block_write(f, H5FD_MEM_FHEAP_HDR, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFLUSH, FAIL, "unable to save fractal heap header to disk")
- hdr->dirty = FALSE;
hdr->cache_info.is_dirty = FALSE;
} /* end if */
@@ -579,11 +582,12 @@ done:
*
*-------------------------------------------------------------------------
*/
-/* ARGSUSED */
herr_t
-H5HF_cache_hdr_dest(H5F_t UNUSED *f, H5HF_hdr_t *hdr)
+H5HF_cache_hdr_dest(H5F_t *f, H5HF_hdr_t *hdr)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_hdr_dest)
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_hdr_dest)
/*
* Check arguments.
@@ -591,17 +595,22 @@ H5HF_cache_hdr_dest(H5F_t UNUSED *f, H5HF_hdr_t *hdr)
HDassert(hdr);
HDassert(hdr->rc == 0);
- /* Free the block size lookup table for the doubling table */
- H5HF_dtable_dest(&hdr->man_dtable);
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!hdr->cache_info.free_file_space_on_destroy || H5F_addr_defined(hdr->cache_info.addr));
- /* Release any I/O pipeline filter information */
- if(hdr->pline.nused)
- H5O_msg_reset(H5O_PLINE_ID, &(hdr->pline));
+ /* Check for freeing file space for heap header */
+ if(hdr->cache_info.free_file_space_on_destroy) {
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_FHEAP_HDR, H5AC_dxpl_id, hdr->cache_info.addr, (hsize_t)hdr->heap_size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap header")
+ } /* end if */
/* Free the shared info itself */
- H5FL_FREE(H5HF_hdr_t, hdr);
-
- FUNC_LEAVE_NOAPI(SUCCEED)
+ if(H5HF_hdr_free(hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "unable to release fractal heap header")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_cache_hdr_dest() */
@@ -716,7 +725,6 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows
/* Allocate space for the fractal heap indirect block */
if(NULL == (iblock = H5FL_CALLOC(H5HF_indirect_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- HDmemset(&iblock->cache_info, 0, sizeof(H5AC_info_t));
/* Get the pointer to the shared heap header */
hdr = par_info->hdr;
@@ -743,7 +751,7 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows
iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock);
/* Get a pointer to a buffer that's large enough for serialized indirect block */
- if(NULL == (buf = H5WB_actual(wb, iblock->size)))
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, iblock->size)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read indirect block from disk */
@@ -754,9 +762,9 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows
p = buf;
/* Magic number */
- if(HDmemcmp(p, H5HF_IBLOCK_MAGIC, (size_t)H5HF_SIZEOF_MAGIC))
+ if(HDmemcmp(p, H5HF_IBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong fractal heap indirect block signature")
- p += H5HF_SIZEOF_MAGIC;
+ p += H5_SIZEOF_MAGIC;
/* Version */
if(*p++ != H5HF_IBLOCK_VERSION)
@@ -900,9 +908,6 @@ H5HF_cache_iblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_iblock_flush)
-#ifdef QAK
-HDfprintf(stderr, "%s: Flushing indirect block, addr = %a, destroy = %u\n", FUNC, addr, (unsigned)destroy);
-#endif /* QAK */
/* check arguments */
HDassert(f);
@@ -931,15 +936,15 @@ HDfprintf(stderr, "%s: Flushing indirect block, addr = %a, destroy = %u\n", FUNC
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't wrap buffer")
/* Get a pointer to a buffer that's large enough for serialized indirect block */
- if(NULL == (buf = H5WB_actual(wb, iblock->size)))
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, iblock->size)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Get temporary pointer to buffer for serialized indirect block */
p = buf;
/* Magic number */
- HDmemcpy(p, H5HF_IBLOCK_MAGIC, (size_t)H5HF_SIZEOF_MAGIC);
- p += H5HF_SIZEOF_MAGIC;
+ HDmemcpy(p, H5HF_IBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
/* Version # */
*p++ = H5HF_IBLOCK_VERSION;
@@ -1000,6 +1005,54 @@ HDfprintf(stderr, "%s: Flushing indirect block, addr = %a, destroy = %u\n", FUNC
HDassert(max_child == iblock->max_child);
#endif /* NDEBUG */
+ /* Check for needing to re-allocate indirect block from 'temp.' to 'normal' file space */
+ if(H5F_IS_TMP_ADDR(f, addr)) {
+ /* Sanity check */
+ HDassert(H5F_addr_eq(iblock->addr, addr));
+
+ /* Allocate 'normal' space for the new indirect block on disk */
+ if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
+
+ /* Sanity check */
+ HDassert(!H5F_addr_eq(iblock->addr, addr));
+
+ /* Let the metadata cache know the block moved */
+ if(H5AC_rename(f, H5AC_FHEAP_IBLOCK, iblock->addr, addr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRENAME, FAIL, "unable to move indirect block")
+
+ /* Update the internal address for the block */
+ iblock->addr = addr;
+
+ /* Check for root indirect block */
+ if(NULL == iblock->parent) {
+ /* Update information about indirect block's location */
+ hdr->man_dtable.table_addr = addr;
+
+ /* Mark that heap header was modified */
+ if(H5HF_hdr_dirty(hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty")
+ } /* end if */
+ else {
+ H5HF_indirect_t *par_iblock; /* Parent indirect block */
+ unsigned par_entry; /* Entry in parent indirect block */
+
+ /* Get parent information */
+ par_iblock = iblock->parent;
+ par_entry = iblock->par_entry;
+
+ /* Update information about indirect block's location */
+ par_iblock->ents[par_entry].addr = addr;
+
+ /* Mark that parent was modified */
+ if(H5HF_iblock_dirty(par_iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty")
+ } /* end if */
+ } /* end if */
+
+ /* Indirect block must be in 'normal' file space now */
+ HDassert(!H5F_IS_TMP_ADDR(f, addr));
+
/* Write the indirect block */
if(H5F_block_write(f, H5FD_MEM_FHEAP_IBLOCK, addr, iblock->size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFLUSH, FAIL, "unable to save fractal heap indirect block to disk")
@@ -1034,9 +1087,8 @@ done:
*
*-------------------------------------------------------------------------
*/
-/* ARGSUSED */
herr_t
-H5HF_cache_iblock_dest(H5F_t UNUSED *f, H5HF_indirect_t *iblock)
+H5HF_cache_iblock_dest(H5F_t *f, H5HF_indirect_t *iblock)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -1047,12 +1099,27 @@ H5HF_cache_iblock_dest(H5F_t UNUSED *f, H5HF_indirect_t *iblock)
*/
HDassert(iblock);
HDassert(iblock->rc == 0);
+ HDassert(iblock->hdr);
+
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!iblock->cache_info.free_file_space_on_destroy || H5F_addr_defined(iblock->cache_info.addr));
+
+ /* Check for freeing file space for indirect block */
+ if(iblock->cache_info.free_file_space_on_destroy) {
+ /* Check if the indirect block is NOT currently allocated in temp. file space */
+ /* (temp. file space does not need to be freed) */
+ if(!H5F_IS_TMP_ADDR(f, iblock->cache_info.addr)) {
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_FHEAP_IBLOCK, H5AC_dxpl_id, iblock->cache_info.addr, (hsize_t)iblock->size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block")
+ } /* end if */
+ } /* end if */
/* Set the shared heap header's file context for this operation */
iblock->hdr->f = f;
/* Decrement reference count on shared info */
- HDassert(iblock->hdr);
if(H5HF_hdr_decr(iblock->hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared heap header")
if(iblock->parent)
@@ -1061,14 +1128,14 @@ H5HF_cache_iblock_dest(H5F_t UNUSED *f, H5HF_indirect_t *iblock)
/* Release entry tables */
if(iblock->ents)
- H5FL_SEQ_FREE(H5HF_indirect_ent_t, iblock->ents);
+ (void)H5FL_SEQ_FREE(H5HF_indirect_ent_t, iblock->ents);
if(iblock->filt_ents)
- H5FL_SEQ_FREE(H5HF_indirect_filt_ent_t, iblock->filt_ents);
+ (void)H5FL_SEQ_FREE(H5HF_indirect_filt_ent_t, iblock->filt_ents);
if(iblock->child_iblocks)
- H5FL_SEQ_FREE(H5HF_indirect_ptr_t, iblock->child_iblocks);
+ (void)H5FL_SEQ_FREE(H5HF_indirect_ptr_t, iblock->child_iblocks);
/* Free fractal heap indirect block info */
- H5FL_FREE(H5HF_indirect_t, iblock);
+ (void)H5FL_FREE(H5HF_indirect_t, iblock);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1194,7 +1261,7 @@ H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size,
/* Set block's internal information */
dblock->size = *size;
- dblock->blk_off_size = H5HF_SIZEOF_OFFSET_LEN(dblock->size);
+ dblock->file_size = 0;
/* Allocate block buffer */
/* XXX: Change to using free-list factories */
@@ -1259,9 +1326,9 @@ H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size,
p = dblock->blk;
/* Magic number */
- if(HDmemcmp(p, H5HF_DBLOCK_MAGIC, (size_t)H5HF_SIZEOF_MAGIC))
+ if(HDmemcmp(p, H5HF_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong fractal heap direct block signature")
- p += H5HF_SIZEOF_MAGIC;
+ p += H5_SIZEOF_MAGIC;
/* Version */
if(*p++ != H5HF_DBLOCK_VERSION)
@@ -1305,7 +1372,7 @@ H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size,
} /* end if */
/* Sanity check */
- HDassert((size_t)(p - dblock->blk) == H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr));
+ HDassert((size_t)(p - dblock->blk) == (size_t)H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr));
/* Set return value */
ret_value = dblock;
@@ -1345,6 +1412,7 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
if(dblock->cache_info.is_dirty) {
H5HF_hdr_t *hdr; /* Shared fractal heap information */
+ hbool_t at_tmp_addr = H5F_IS_TMP_ADDR(f, addr); /* Flag to indicate direct block is at temporary address */
void *write_buf; /* Pointer to buffer to write out */
size_t write_size; /* Size of buffer to write out */
uint8_t *p; /* Pointer into raw data buffer */
@@ -1359,8 +1427,8 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
p = dblock->blk;
/* Magic number */
- HDmemcpy(p, H5HF_DBLOCK_MAGIC, (size_t)H5HF_SIZEOF_MAGIC);
- p += H5HF_SIZEOF_MAGIC;
+ HDmemcpy(p, H5HF_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
/* Version # */
*p++ = H5HF_DBLOCK_VERSION;
@@ -1386,13 +1454,13 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
} /* end if */
/* Sanity check */
- HDassert((size_t)(p - dblock->blk) == H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr));
+ HDassert((size_t)(p - dblock->blk) == (size_t)H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr));
/* Check for I/O filters on this heap */
if(hdr->filter_len > 0) {
H5Z_cb_t filter_cb = {NULL, NULL}; /* Filter callback structure */
size_t nbytes; /* Number of bytes used */
- unsigned filter_mask; /* Filter mask for block */
+ unsigned filter_mask = 0; /* Filter mask for block */
/* Allocate buffer to perform I/O filtering on */
write_size = dblock->size;
@@ -1423,10 +1491,14 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
} /* end if */
/* Check if we need to re-size the block on disk */
- if(hdr->pline_root_direct_size != write_size) {
- /* Release direct block's current disk space */
- if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, addr, (hsize_t)hdr->pline_root_direct_size) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block")
+ if(hdr->pline_root_direct_size != write_size || at_tmp_addr) {
+ /* Check if the direct block is NOT currently allocated in temp. file space */
+ /* (temp. file space does not need to be freed) */
+ if(!at_tmp_addr) {
+ /* Release direct block's current disk space */
+ if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, addr, (hsize_t)hdr->pline_root_direct_size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block")
+ } /* end if */
/* Allocate space for the compressed direct block */
if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)write_size)))
@@ -1470,10 +1542,14 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
} /* end if */
/* Check if we need to re-size the block on disk */
- if(par_iblock->filt_ents[par_entry].size != write_size) {
- /* Release direct block's current disk space */
- if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, addr, (hsize_t)par_iblock->filt_ents[par_entry].size) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block")
+ if(par_iblock->filt_ents[par_entry].size != write_size || at_tmp_addr) {
+ /* Check if the direct block is NOT currently allocated in temp. file space */
+ /* (temp. file space does not need to be freed) */
+ if(!at_tmp_addr) {
+ /* Release direct block's current disk space */
+ if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, addr, (hsize_t)par_iblock->filt_ents[par_entry].size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block")
+ } /* end if */
/* Allocate space for the compressed direct block */
if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)write_size)))
@@ -1501,8 +1577,67 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
else {
write_buf = dblock->blk;
write_size = dblock->size;
+
+ /* Check for needing to re-allocate direct block from 'temp.' to 'normal' file space */
+ if(at_tmp_addr) {
+ /* Check for root direct block */
+ if(NULL == dblock->parent) {
+ /* Sanity check */
+ HDassert(H5F_addr_eq(hdr->man_dtable.table_addr, addr));
+
+ /* Allocate 'normal' space for the direct block */
+ if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)write_size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block")
+
+ /* Sanity check */
+ HDassert(!H5F_addr_eq(hdr->man_dtable.table_addr, addr));
+
+ /* Let the metadata cache know the block moved */
+ if(H5AC_rename(f, H5AC_FHEAP_DBLOCK, hdr->man_dtable.table_addr, addr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRENAME, FAIL, "unable to move direct block")
+
+ /* Update information about direct block's location */
+ hdr->man_dtable.table_addr = addr;
+
+ /* Mark that heap header was modified */
+ if(H5HF_hdr_dirty(hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty")
+ } /* end if */
+ else {
+ H5HF_indirect_t *par_iblock; /* Parent indirect block */
+ unsigned par_entry; /* Entry in parent indirect block */
+
+ /* Get parent information */
+ par_iblock = dblock->parent;
+ par_entry = dblock->par_entry;
+
+ /* Sanity check */
+ HDassert(H5F_addr_eq(par_iblock->ents[par_entry].addr, addr));
+
+ /* Allocate 'normal' space for the direct block */
+ if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)write_size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block")
+
+ /* Sanity check */
+ HDassert(!H5F_addr_eq(par_iblock->ents[par_entry].addr, addr));
+
+ /* Let the metadata cache know the block moved */
+ if(H5AC_rename(f, H5AC_FHEAP_DBLOCK, par_iblock->ents[par_entry].addr, addr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRENAME, FAIL, "unable to move direct block")
+
+ /* Update information about direct block's location */
+ par_iblock->ents[par_entry].addr = addr;
+
+ /* Mark that parent was modified */
+ if(H5HF_iblock_dirty(par_iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty")
+ } /* end else */
+ } /* end if */
} /* end else */
+ /* Direct block must be in 'normal' file space now */
+ HDassert(!H5F_IS_TMP_ADDR(f, addr));
+
/* Write the direct block */
if(H5F_block_write(f, H5FD_MEM_FHEAP_DBLOCK, addr, write_size, dxpl_id, write_buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFLUSH, FAIL, "unable to save fractal heap direct block to disk")
@@ -1536,9 +1671,8 @@ done:
*
*-------------------------------------------------------------------------
*/
-/* ARGSUSED */
herr_t
-H5HF_cache_dblock_dest(H5F_t UNUSED *f, H5HF_direct_t *dblock)
+H5HF_cache_dblock_dest(H5F_t *f, H5HF_direct_t *dblock)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -1549,6 +1683,24 @@ H5HF_cache_dblock_dest(H5F_t UNUSED *f, H5HF_direct_t *dblock)
*/
HDassert(dblock);
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!dblock->cache_info.free_file_space_on_destroy || H5F_addr_defined(dblock->cache_info.addr));
+
+ /* Check for freeing file space for direct block */
+ if(dblock->cache_info.free_file_space_on_destroy) {
+ /* Sanity check */
+ HDassert(dblock->file_size > 0);
+
+ /* Check if the direct block is NOT currently allocated in temp. file space */
+ /* (temp. file space does not need to be freed) */
+ if(!H5F_IS_TMP_ADDR(f, dblock->cache_info.addr)) {
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, H5AC_dxpl_id, dblock->cache_info.addr, dblock->file_size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block")
+ } /* end if */
+ } /* end if */
+
/* Set the shared heap header's file context for this operation */
dblock->hdr->f = f;
@@ -1564,7 +1716,7 @@ H5HF_cache_dblock_dest(H5F_t UNUSED *f, H5HF_direct_t *dblock)
dblock->blk = H5FL_BLK_FREE(direct_block, dblock->blk);
/* Free fractal heap direct block info */
- H5FL_FREE(H5HF_direct_t, dblock);
+ (void)H5FL_FREE(H5HF_direct_t, dblock);
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5HFdbg.c b/src/H5HFdbg.c
index bbbe26f..3931eb0 100644
--- a/src/H5HFdbg.c
+++ b/src/H5HFdbg.c
@@ -204,7 +204,7 @@ H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
/*
* Load the fractal heap header.
*/
- if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (hdr = (H5HF_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header")
/* Print opening message */
@@ -415,7 +415,7 @@ H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
/*
* Load the fractal heap header.
*/
- if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (hdr = (H5HF_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header")
/*
@@ -440,12 +440,9 @@ H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
"Size of block header:",
blk_prefix_size);
- HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
- "Size of block offsets:",
- dblock->blk_off_size);
/* Allocate space for the free space markers */
- if(NULL == (marker = H5MM_calloc(dblock->size)))
+ if(NULL == (marker = (uint8_t *)H5MM_calloc(dblock->size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Initialize the free space information for the heap */
@@ -547,7 +544,7 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
/*
* Load the fractal heap header.
*/
- if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (hdr = (H5HF_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header")
/*
@@ -731,7 +728,7 @@ H5HF_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr,
/*
* Load the fractal heap header.
*/
- if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (hdr = (H5HF_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header")
/* Initialize the free space information for the heap */
diff --git a/src/H5HFdblock.c b/src/H5HFdblock.c
index f173ed0..c16926e 100644
--- a/src/H5HFdblock.c
+++ b/src/H5HFdblock.c
@@ -35,6 +35,7 @@
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
+#include "H5Fprivate.h" /* File access */
#include "H5HFpkg.h" /* Fractal heaps */
#include "H5MFprivate.h" /* File memory management */
#include "H5Vprivate.h" /* Vectors and arrays */
@@ -137,7 +138,7 @@ H5HF_man_dblock_create(hid_t dxpl_id, H5HF_hdr_t *hdr, H5HF_indirect_t *par_iblo
dblock->block_off = 0;
dblock->size = hdr->man_dtable.cparam.start_block_size;
} /* end else */
- dblock->blk_off_size = H5HF_SIZEOF_OFFSET_LEN(dblock->size);
+ dblock->file_size = 0;
free_space = dblock->size - H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr);
/* Allocate buffer for block */
@@ -148,9 +149,15 @@ H5HF_man_dblock_create(hid_t dxpl_id, H5HF_hdr_t *hdr, H5HF_indirect_t *par_iblo
HDmemset(dblock->blk, 0, dblock->size);
#endif /* H5_CLEAR_MEMORY */
- /* Allocate space for the direct block on disk */
- if(HADDR_UNDEF == (dblock_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)dblock->size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block")
+ /* Allocate [temporary] space for the direct block on disk */
+ if(H5F_USE_TMP_SPACE(hdr->f)) {
+ if(HADDR_UNDEF == (dblock_addr = H5MF_alloc_tmp(hdr->f, (hsize_t)dblock->size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block")
+ } /* end if */
+ else {
+ if(HADDR_UNDEF == (dblock_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)dblock->size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block")
+ } /* end else */
/* Attach to parent indirect block, if there is one */
dblock->parent = par_iblock;
@@ -217,6 +224,7 @@ H5HF_man_dblock_destroy(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_direct_t *dblock,
haddr_t dblock_addr)
{
hsize_t dblock_size; /* Size of direct block on disk */
+ unsigned cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting indirect block */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_man_dblock_destroy)
@@ -296,16 +304,15 @@ H5HF_man_dblock_destroy(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_direct_t *dblock,
dblock->par_entry = 0;
} /* end else */
- /* Release direct block's disk space */
- if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, dblock_addr, dblock_size) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block")
-
- /* Remove direct block from metadata cache */
- if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__DIRTIED_FLAG|H5AC__DELETED_FLAG) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block")
- dblock = NULL;
+ /* Indicate that the indirect block should be deleted & file space freed */
+ dblock->file_size = dblock_size;
+ cache_flags |= H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG;
done:
+ /* Unprotect the indirect block, with appropriate flags */
+ if(dblock && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, cache_flags) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_man_dblock_destroy() */
@@ -446,7 +453,7 @@ H5HF_man_dblock_protect(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t dblock_addr,
par_info.entry = par_entry;
/* Protect the direct block */
- if(NULL == (dblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, &par_info, rw)))
+ if(NULL == (dblock = (H5HF_direct_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, &par_info, rw)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap direct block")
/* Set the return value */
@@ -602,13 +609,30 @@ H5HF_man_dblock_delete(H5F_t *f, hid_t dxpl_id, haddr_t dblock_addr,
HDassert(!(dblock_status & H5AC_ES__IS_PROTECTED));
/* Evict the direct block from the metadata cache */
- if(H5AC_expunge_entry(f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr) < 0)
+ if(H5AC_expunge_entry(f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "unable to remove direct block from cache")
} /* end if */
- /* Release direct block's disk space */
- if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, dblock_addr, dblock_size) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block")
+ /* Check if the direct block is NOT currently allocated in temp. file space */
+ /* (temp. file space does not need to be freed) */
+ if(!H5F_IS_TMP_ADDR(f, dblock_addr)) {
+ /* Release direct block's disk space */
+ /* (XXX: Under the best of circumstances, this block's space in the file
+ * would be freed in the H5AC_expunge_entry() call above (and the
+ * H5AC__FREE_FILE_SPACE_FLAG used there), but since the direct
+ * block structure might have a different size on disk than in
+ * the heap's 'abstract' address space, we would need to set the
+ * "file_size" field for the direct block structure. In order to
+ * do that, we'd have to protect/unprotect the direct block and
+ * that would add a bunch of unnecessary overhead to the process,
+ * so we just release the file space here, directly. When the
+ * revised metadata cache is operating, it will "know" the file
+ * size of each entry in the cache and we can the the
+ * H5AC_expunge_entry() method. -QAK)
+ */
+ if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, dblock_addr, dblock_size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block")
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5HFdtable.c b/src/H5HFdtable.c
index b5be676..29af47f 100644
--- a/src/H5HFdtable.c
+++ b/src/H5HFdtable.c
@@ -113,13 +113,13 @@ H5HF_dtable_init(H5HF_dtable_t *dtable)
dtable->max_dir_blk_off_size = H5HF_SIZEOF_OFFSET_LEN(dtable->cparam.max_direct_size);
/* Build table of block sizes for each row */
- if(NULL == (dtable->row_block_size = H5MM_malloc(dtable->max_root_rows * sizeof(hsize_t))))
+ if(NULL == (dtable->row_block_size = (hsize_t *)H5MM_malloc(dtable->max_root_rows * sizeof(hsize_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create doubling table block size table")
- if(NULL == (dtable->row_block_off = H5MM_malloc(dtable->max_root_rows * sizeof(hsize_t))))
+ if(NULL == (dtable->row_block_off = (hsize_t *)H5MM_malloc(dtable->max_root_rows * sizeof(hsize_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create doubling table block offset table")
- if(NULL == (dtable->row_tot_dblock_free = H5MM_malloc(dtable->max_root_rows * sizeof(hsize_t))))
+ if(NULL == (dtable->row_tot_dblock_free = (hsize_t *)H5MM_malloc(dtable->max_root_rows * sizeof(hsize_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create doubling table total direct block free space table")
- if(NULL == (dtable->row_max_dblock_free = H5MM_malloc(dtable->max_root_rows * sizeof(size_t))))
+ if(NULL == (dtable->row_max_dblock_free = (size_t *)H5MM_malloc(dtable->max_root_rows * sizeof(size_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create doubling table max. direct block free space table")
tmp_block_size = dtable->cparam.start_block_size;
acc_block_off = dtable->cparam.start_block_size * dtable->cparam.width;
diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c
index f8a0bb0..db0093e 100644
--- a/src/H5HFhdr.c
+++ b/src/H5HFhdr.c
@@ -43,6 +43,7 @@
/* Local Macros */
/****************/
+#ifndef NDEBUG
/* Limit on the size of the max. direct block size */
/* (This is limited to 32-bits currently, because I think it's unlikely to
* need to be larger, the 32-bit limit for H5V_log2_of2(n), and
@@ -55,6 +56,8 @@
* need to be larger, and its encoded with a maxiumum of 16-bits - QAK)
*/
#define H5HF_WIDTH_LIMIT (64 * 1024)
+#endif /* NDEBUG */
+
/******************/
/* Local Typedefs */
@@ -76,7 +79,7 @@
/*********************/
/* Declare a free list to manage the H5HF_hdr_t struct */
-H5FL_DEFINE(H5HF_hdr_t);
+H5FL_DEFINE_STATIC(H5HF_hdr_t);
/*****************************/
@@ -107,7 +110,7 @@ H5HF_hdr_t *
H5HF_hdr_alloc(H5F_t *f)
{
H5HF_hdr_t *hdr = NULL; /* Shared fractal heap header */
- H5HF_hdr_t *ret_value = NULL; /* Return value */
+ H5HF_hdr_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_alloc)
@@ -118,7 +121,7 @@ H5HF_hdr_alloc(H5F_t *f)
/* Allocate space for the shared information */
if(NULL == (hdr = H5FL_CALLOC(H5HF_hdr_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap shared header")
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "allocation failed for fractal heap shared header")
/* Set the internal parameters for the heap */
hdr->f = f;
@@ -129,9 +132,9 @@ H5HF_hdr_alloc(H5F_t *f)
ret_value = hdr;
done:
- if(!ret_value)
- if(hdr)
- (void)H5HF_cache_hdr_dest(f, hdr);
+ if(!ret_value && hdr)
+ if(H5HF_hdr_free(hdr) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTRELEASE, NULL, "unable to release fractal heap header")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_hdr_alloc() */
@@ -219,7 +222,7 @@ H5HF_hdr_finish_init_phase1(H5HF_hdr_t *hdr)
HDassert(hdr);
/* Compute/cache some values */
- hdr->heap_off_size = H5HF_SIZEOF_OFFSET_BITS(hdr->man_dtable.cparam.max_index);
+ hdr->heap_off_size = (uint8_t)H5HF_SIZEOF_OFFSET_BITS(hdr->man_dtable.cparam.max_index);
if(H5HF_dtable_init(&hdr->man_dtable) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize doubling table info")
@@ -400,20 +403,28 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam)
/* Set "huge" object tracker v2 B-tree address to indicate that there aren't any yet */
hdr->huge_bt2_addr = HADDR_UNDEF;
- /* Note that the shared info is dirty (it's not written to the file yet) */
- hdr->dirty = TRUE;
-
/* First phase of header final initialization */
/* (doesn't need ID length set up) */
if(H5HF_hdr_finish_init_phase1(hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "can't finish phase #1 of header final initialization")
/* Copy any I/O filter pipeline */
- /* (This code is not in the "finish init phase" routines because those
+ /* (This code is not in the "finish init phase" routines because those
* routines are also called from the cache 'load' callback, and the filter
* length is already set in that case (its stored in the header on disk))
*/
if(cparam->pline.nused > 0) {
+ /* Check if the filters in the DCPL can be applied to this dataset */
+ if(H5Z_can_apply_direct(&(cparam->pline)) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "I/O filters can't operate on this heap")
+
+ /* Mark the filters as checked */
+ hdr->checked_filters = TRUE;
+
+ /* Make the "set local" filter callbacks for this dataset */
+ if(H5Z_set_local_direct(&(cparam->pline)) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "unable to set local filter parameters")
+
/* Copy the I/O filter pipeline from the creation parameters to the header */
if(NULL == H5O_msg_copy(H5O_PLINE_ID, &(cparam->pline), &(hdr->pline)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTCOPY, HADDR_UNDEF, "can't copy I/O filter pipeline")
@@ -421,7 +432,7 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam)
/* Pay attention to the latest version flag for the file */
if(H5F_USE_LATEST_FORMAT(hdr->f))
/* Set the latest version for the I/O pipeline message */
- if(H5Z_set_latest_version(&(hdr->pline)) < 0)
+ if(H5O_pline_set_latest_version(&(hdr->pline)) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTSET, HADDR_UNDEF, "can't set latest version of I/O filter pipeline")
/* Compute the I/O filters' encoded size */
@@ -434,18 +445,22 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam)
+ 4 /* Size of filter mask for filtered root direct block */
+ hdr->filter_len; /* Size of encoded I/O filter info */
} /* end if */
- else
+ else {
/* Set size of header on disk */
hdr->heap_size = H5HF_HEADER_SIZE(hdr);
+ /* Mark filters as checked, for performance reasons */
+ hdr->checked_filters = TRUE;
+ } /* end else */
+
/* Set the length of IDs in the heap */
- /* (This code is not in the "finish init phase" routines because those
+ /* (This code is not in the "finish init phase" routines because those
* routines are also called from the cache 'load' callback, and the ID
* length is already set in that case (its stored in the header on disk))
*/
switch(cparam->id_len) {
case 0: /* Set the length of heap IDs to just enough to hold the offset & length of 'normal' objects in the heap */
- hdr->id_len = 1 + hdr->heap_off_size + hdr->heap_len_size;
+ hdr->id_len = (unsigned)1 + hdr->heap_off_size + hdr->heap_len_size;
break;
case 1: /* Set the length of heap IDs to just enough to hold the information needed to directly access 'huge' objects in the heap */
@@ -490,15 +505,15 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam)
/* Cache the new fractal heap header */
if(H5AC_set(f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "can't add fractal heap header to cache")
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, HADDR_UNDEF, "can't add fractal heap header to cache")
/* Set address of heap header to return */
ret_value = hdr->heap_addr;
done:
- if(!H5F_addr_defined(ret_value))
- if(hdr)
- (void)H5HF_cache_hdr_dest(NULL, hdr);
+ if(!H5F_addr_defined(ret_value) && hdr)
+ if(H5HF_hdr_free(hdr) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTRELEASE, HADDR_UNDEF, "unable to release fractal heap header")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_hdr_create() */
@@ -663,9 +678,6 @@ H5HF_hdr_dirty(H5HF_hdr_t *hdr)
if(H5AC_mark_pinned_or_protected_entry_dirty(hdr->f, hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTMARKDIRTY, FAIL, "unable to mark fractal heap header as dirty")
- /* Set the dirty flags for the heap header */
- hdr->dirty = TRUE;
-
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_hdr_dirty() */
@@ -1182,7 +1194,7 @@ H5HF_hdr_reverse_iter(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t dblock_addr)
/* (Skip direct block that will be deleted, if we find it) */
tmp_entry = curr_entry;
while(tmp_entry >= 0 &&
- (H5F_addr_eq(iblock->ents[tmp_entry].addr, dblock_addr) ||
+ (H5F_addr_eq(iblock->ents[tmp_entry].addr, dblock_addr) ||
!H5F_addr_defined(iblock->ents[tmp_entry].addr)))
tmp_entry--;
/* Check for no earlier blocks in this indirect block */
@@ -1320,6 +1332,43 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5HF_hdr_free
+ *
+ * Purpose: Free shared fractal heap header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 27 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_hdr_free(H5HF_hdr_t *hdr)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_hdr_free)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(hdr);
+
+ /* Free the block size lookup table for the doubling table */
+ H5HF_dtable_dest(&hdr->man_dtable);
+
+ /* Release any I/O pipeline filter information */
+ if(hdr->pline.nused)
+ H5O_msg_reset(H5O_PLINE_ID, &(hdr->pline));
+
+ /* Free the shared info itself */
+ hdr = H5FL_FREE(H5HF_hdr_t, hdr);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5HF_hdr_free() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5HF_hdr_delete
*
* Purpose: Delete a fractal heap, starting with the header
@@ -1335,7 +1384,8 @@ done:
herr_t
H5HF_hdr_delete(H5HF_hdr_t *hdr, hid_t dxpl_id)
{
- herr_t ret_value = SUCCEED;
+ unsigned cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting heap header */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HF_hdr_delete, FAIL)
@@ -1403,18 +1453,12 @@ H5HF_hdr_delete(H5HF_hdr_t *hdr, hid_t dxpl_id)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to release fractal heap 'huge' objects and tracker")
} /* end if */
- /* Release header's disk space */
- if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_HDR, dxpl_id, hdr->heap_addr, (hsize_t)hdr->heap_size) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to release fractal heap header")
-
- /* Finished deleting header */
- if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, H5AC__DIRTIED_FLAG|H5AC__DELETED_FLAG) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap header")
- hdr = NULL;
+ /* Indicate that the heap header should be deleted & file space freed */
+ cache_flags |= H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG;
done:
- /* Unprotect the header, if an error occurred */
- if(hdr && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ /* Unprotect the header with appropriate flags */
+ if(hdr && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, cache_flags) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap header")
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5HFhuge.c b/src/H5HFhuge.c
index 198ef62..5490c22 100644
--- a/src/H5HFhuge.c
+++ b/src/H5HFhuge.c
@@ -68,20 +68,12 @@
/* Local v2 B-tree operations */
static herr_t H5HF_huge_bt2_create(H5HF_hdr_t *hdr, hid_t dxpl_id);
-/* v2 B-tree function callbacks (in H5HFbtree2.c) */
-herr_t H5HF_huge_bt2_indir_found(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_indir_remove(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_filt_indir_found(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_filt_indir_remove(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_dir_remove(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_filt_dir_found(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_filt_dir_remove(const void *nrecord, void *op_data);
-
/* Local 'huge' object support routines */
static hsize_t H5HF_huge_new_id(H5HF_hdr_t *hdr);
static herr_t H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id,
const uint8_t *id, hbool_t is_read, H5HF_operator_t op, void *op_data);
+
/*********************/
/* Package Variables */
/*********************/
@@ -113,8 +105,7 @@ static herr_t H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id,
static herr_t
H5HF_huge_bt2_create(H5HF_hdr_t *hdr, hid_t dxpl_id)
{
- const H5B2_class_t *bt2_class; /* v2 B-tree class to use */
- size_t rrec_size; /* Size of 'raw' records on disk */
+ H5B2_create_t bt2_cparam; /* v2 B-tree creation parameters */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_bt2_create)
@@ -133,40 +124,46 @@ H5HF_huge_bt2_create(H5HF_hdr_t *hdr, hid_t dxpl_id)
*/
if(hdr->huge_ids_direct) {
if(hdr->filter_len > 0) {
- rrec_size = hdr->sizeof_addr /* Address of object */
+ bt2_cparam.rrec_size = (size_t)(hdr->sizeof_addr /* Address of object */
+ hdr->sizeof_size /* Length of object */
+ 4 /* Filter mask for filtered object */
- + hdr->sizeof_size; /* Size of de-filtered object in memory */
- bt2_class = H5HF_BT2_FILT_DIR;
+ + hdr->sizeof_size); /* Size of de-filtered object in memory */
+ bt2_cparam.cls = H5HF_HUGE_BT2_FILT_DIR;
} /* end if */
else {
- rrec_size = hdr->sizeof_addr /* Address of object */
- + hdr->sizeof_size; /* Length of object */
- bt2_class = H5HF_BT2_DIR;
+ bt2_cparam.rrec_size = (size_t)(hdr->sizeof_addr /* Address of object */
+ + hdr->sizeof_size); /* Length of object */
+ bt2_cparam.cls = H5HF_HUGE_BT2_DIR;
} /* end else */
} /* end if */
else {
- if (hdr->filter_len > 0) {
- rrec_size = hdr->sizeof_addr /* Address of filtered object */
+ if(hdr->filter_len > 0) {
+ bt2_cparam.rrec_size = (size_t)(hdr->sizeof_addr /* Address of filtered object */
+ hdr->sizeof_size /* Length of filtered object */
+ 4 /* Filter mask for filtered object */
+ hdr->sizeof_size /* Size of de-filtered object in memory */
- + hdr->sizeof_size; /* Unique ID for object */
- bt2_class = H5HF_BT2_FILT_INDIR;
+ + hdr->sizeof_size); /* Unique ID for object */
+ bt2_cparam.cls = H5HF_HUGE_BT2_FILT_INDIR;
} /* end if */
else {
- rrec_size = hdr->sizeof_addr /* Address of object */
+ bt2_cparam.rrec_size = (size_t)(hdr->sizeof_addr /* Address of object */
+ hdr->sizeof_size /* Length of object */
- + hdr->sizeof_size; /* Unique ID for object */
- bt2_class = H5HF_BT2_INDIR;
+ + hdr->sizeof_size); /* Unique ID for object */
+ bt2_cparam.cls = H5HF_HUGE_BT2_INDIR;
} /* end else */
} /* end else */
+ bt2_cparam.node_size = (size_t)H5HF_HUGE_BT2_NODE_SIZE;
+ bt2_cparam.split_percent = H5HF_HUGE_BT2_SPLIT_PERC;
+ bt2_cparam.merge_percent = H5HF_HUGE_BT2_MERGE_PERC;
/* Create v2 B-tree for tracking 'huge' objects */
- if(H5B2_create(hdr->f, dxpl_id, bt2_class, (size_t)H5HF_HUGE_BT2_NODE_SIZE, rrec_size,
- H5HF_HUGE_BT2_SPLIT_PERC, H5HF_HUGE_BT2_MERGE_PERC, &hdr->huge_bt2_addr/*out*/) < 0)
+ if(NULL == (hdr->huge_bt2 = H5B2_create(hdr->f, dxpl_id, &bt2_cparam, hdr->f)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't create v2 B-tree for tracking 'huge' heap objects")
+ /* Retrieve the v2 B-tree's address in the file */
+ if(H5B2_get_addr(hdr->huge_bt2, &hdr->huge_bt2_addr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get v2 B-tree address for tracking 'huge' heap objects")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_huge_bt2_create() */
@@ -206,12 +203,12 @@ HDfprintf(stderr, "%s: hdr->id_len = %u\n", "H5HF_huge_init", (unsigned)hdr->id_
HDfprintf(stderr, "%s: hdr->filter_len = %u\n", "H5HF_huge_init", (unsigned)hdr->filter_len);
#endif /* QAK */
if(hdr->filter_len > 0) {
- if((hdr->id_len - 1) >= (hdr->sizeof_addr + hdr->sizeof_size + 4 + hdr->sizeof_size)) {
+ if((hdr->id_len - 1) >= (unsigned)(hdr->sizeof_addr + hdr->sizeof_size + 4 + hdr->sizeof_size)) {
/* Indicate that v2 B-tree doesn't have to be used to locate object */
hdr->huge_ids_direct = TRUE;
/* Set the size of 'huge' object IDs */
- hdr->huge_id_size = hdr->sizeof_addr + hdr->sizeof_size + hdr->sizeof_size;
+ hdr->huge_id_size = (uint8_t)(hdr->sizeof_addr + hdr->sizeof_size + hdr->sizeof_size);
} /* end if */
else
/* Indicate that v2 B-tree must be used to access object */
@@ -223,7 +220,7 @@ HDfprintf(stderr, "%s: hdr->filter_len = %u\n", "H5HF_huge_init", (unsigned)hdr-
hdr->huge_ids_direct = TRUE;
/* Set the size of 'huge' object IDs */
- hdr->huge_id_size = hdr->sizeof_addr + hdr->sizeof_size;
+ hdr->huge_id_size = (uint8_t)(hdr->sizeof_addr + hdr->sizeof_size);
} /* end if */
else
/* Indicate that v2 B-tree must be used to locate object */
@@ -232,7 +229,7 @@ HDfprintf(stderr, "%s: hdr->filter_len = %u\n", "H5HF_huge_init", (unsigned)hdr-
if(!hdr->huge_ids_direct) {
/* Set the size and maximum value of 'huge' object ID */
if((hdr->id_len - 1) < sizeof(hsize_t)) {
- hdr->huge_id_size = hdr->id_len - 1;
+ hdr->huge_id_size = (uint8_t)(hdr->id_len - 1);
hdr->huge_max_id = ((hsize_t)1 << (hdr->huge_id_size * 8)) - 1;
} /*end if */
else {
@@ -240,6 +237,7 @@ HDfprintf(stderr, "%s: hdr->filter_len = %u\n", "H5HF_huge_init", (unsigned)hdr-
hdr->huge_max_id = HSIZET_MAX;
} /* end else */
} /* end if */
+ hdr->huge_bt2 = NULL;
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5HF_huge_init() */
@@ -332,9 +330,20 @@ HDfprintf(stderr, "%s: obj_size = %Zu\n", FUNC, obj_size);
HDassert(id);
/* Check if the v2 B-tree for tracking 'huge' heap objects has been created yet */
- if(!H5F_addr_defined(hdr->huge_bt2_addr))
+ if(!H5F_addr_defined(hdr->huge_bt2_addr)) {
+ /* Go create (& open) v2 B-tree */
if(H5HF_huge_bt2_create(hdr, dxpl_id) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't create v2 B-tree for tracking 'huge' heap objects")
+ } /* end if */
+ else {
+ /* Check if v2 B-tree is open yet */
+ if(NULL == hdr->huge_bt2) {
+ /* Open existing v2 B-tree */
+ if(NULL == (hdr->huge_bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr, hdr->f)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' heap objects")
+ } /* end if */
+ } /* end else */
+ HDassert(hdr->huge_bt2);
/* Check for I/O pipeline filter on heap */
if(hdr->filter_len > 0) {
@@ -394,7 +403,7 @@ HDfprintf(stderr, "%s: obj_rec = {%a, %Hu, %x, %Hu}\n", FUNC, obj_rec.addr, obj_
#endif /* QAK */
/* Insert record for object in v2 B-tree */
- if(H5B2_insert(hdr->f, dxpl_id, H5HF_BT2_FILT_DIR, hdr->huge_bt2_addr, &obj_rec) < 0)
+ if(H5B2_insert(hdr->huge_bt2, dxpl_id, &obj_rec) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "couldn't insert object tracking record in v2 B-tree")
/* Encode ID for user */
@@ -415,7 +424,7 @@ HDfprintf(stderr, "%s: obj_rec = {%a, %Hu}\n", FUNC, obj_rec.addr, obj_rec.len);
#endif /* QAK */
/* Insert record for object in v2 B-tree */
- if(H5B2_insert(hdr->f, dxpl_id, H5HF_BT2_DIR, hdr->huge_bt2_addr, &obj_rec) < 0)
+ if(H5B2_insert(hdr->huge_bt2, dxpl_id, &obj_rec) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "couldn't insert object tracking record in v2 B-tree")
/* Encode ID for user */
@@ -427,7 +436,6 @@ HDfprintf(stderr, "%s: obj_rec = {%a, %Hu}\n", FUNC, obj_rec.addr, obj_rec.len);
else {
H5HF_huge_bt2_filt_indir_rec_t filt_indir_rec; /* Record for tracking filtered object */
H5HF_huge_bt2_indir_rec_t indir_rec; /* Record for tracking non-filtered object */
- const H5B2_class_t *bt2_class; /* v2 B-tree class to use */
void *ins_rec; /* Pointer to record to insert */
hsize_t new_id; /* New ID for object */
@@ -448,7 +456,6 @@ HDfprintf(stderr, "%s: filt_indir_rec = {%a, %Hu, %x, %Hu, %Hu}\n", FUNC, filt_i
/* Set pointer to record to insert */
ins_rec = &filt_indir_rec;
- bt2_class = H5HF_BT2_FILT_INDIR;
} /* end if */
else {
/* Initialize record for object in v2 B-tree */
@@ -461,11 +468,10 @@ HDfprintf(stderr, "%s: indir_rec = {%a, %Hu, %Hu}\n", FUNC, indir_rec.addr, indi
/* Set pointer to record to insert */
ins_rec = &indir_rec;
- bt2_class = H5HF_BT2_INDIR;
} /* end else */
/* Insert record for tracking object in v2 B-tree */
- if(H5B2_insert(hdr->f, dxpl_id, bt2_class, hdr->huge_bt2_addr, ins_rec) < 0)
+ if(H5B2_insert(hdr->huge_bt2, dxpl_id, ins_rec) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "couldn't insert object tracking record in v2 B-tree")
/* Encode ID for user */
@@ -536,6 +542,13 @@ H5HF_huge_get_obj_len(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
} /* end else */
} /* end if */
else {
+ /* Check if v2 B-tree is open yet */
+ if(NULL == hdr->huge_bt2) {
+ /* Open existing v2 B-tree */
+ if(NULL == (hdr->huge_bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr, hdr->f)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' heap objects")
+ } /* end if */
+
if(hdr->filter_len > 0) {
H5HF_huge_bt2_filt_indir_rec_t found_rec; /* Record found from tracking object */
H5HF_huge_bt2_filt_indir_rec_t search_rec; /* Record for searching for object */
@@ -544,8 +557,7 @@ H5HF_huge_get_obj_len(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
/* Look up object in v2 B-tree */
- if(H5B2_find(hdr->f, dxpl_id, H5HF_BT2_FILT_INDIR, hdr->huge_bt2_addr,
- &search_rec, H5HF_huge_bt2_filt_indir_found, &found_rec) < 0)
+ if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_filt_indir_found, &found_rec) != TRUE)
HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree")
/* Retrieve the object's length */
@@ -559,8 +571,7 @@ H5HF_huge_get_obj_len(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
/* Look up object in v2 B-tree */
- if(H5B2_find(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr,
- &search_rec, H5HF_huge_bt2_indir_found, &found_rec) < 0)
+ if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_indir_found, &found_rec) != TRUE)
HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree")
/* Retrieve the object's length */
@@ -619,6 +630,16 @@ H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
UINT32DECODE(id, filter_mask);
} /* end if */
else {
+ /* Sanity check */
+ HDassert(H5F_addr_defined(hdr->huge_bt2_addr));
+
+ /* Check if v2 B-tree is open yet */
+ if(NULL == hdr->huge_bt2) {
+ /* Open existing v2 B-tree */
+ if(NULL == (hdr->huge_bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr, hdr->f)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' heap objects")
+ } /* end if */
+
if(hdr->filter_len > 0) {
H5HF_huge_bt2_filt_indir_rec_t found_rec; /* Record found from tracking object */
H5HF_huge_bt2_filt_indir_rec_t search_rec; /* Record for searching for object */
@@ -627,8 +648,7 @@ H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
/* Look up object in v2 B-tree */
- if(H5B2_find(hdr->f, dxpl_id, H5HF_BT2_FILT_INDIR, hdr->huge_bt2_addr,
- &search_rec, H5HF_huge_bt2_filt_indir_found, &found_rec) < 0)
+ if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_filt_indir_found, &found_rec) != TRUE)
HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree")
/* Retrieve the object's address & length */
@@ -644,8 +664,7 @@ H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
/* Look up object in v2 B-tree */
- if(H5B2_find(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr,
- &search_rec, H5HF_huge_bt2_indir_found, &found_rec) < 0)
+ if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_indir_found, &found_rec) != TRUE)
HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree")
/* Retrieve the object's address & length */
@@ -759,12 +778,21 @@ H5HF_huge_write(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
H5HF_huge_bt2_indir_rec_t found_rec; /* Record found from tracking object */
H5HF_huge_bt2_indir_rec_t search_rec; /* Record for searching for object */
+ /* Sanity check */
+ HDassert(H5F_addr_defined(hdr->huge_bt2_addr));
+
+ /* Check if v2 B-tree is open yet */
+ if(NULL == hdr->huge_bt2) {
+ /* Open existing v2 B-tree */
+ if(NULL == (hdr->huge_bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr, hdr->f)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' heap objects")
+ } /* end if */
+
/* Get ID for looking up 'huge' object in v2 B-tree */
UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
/* Look up object in v2 B-tree */
- if(H5B2_find(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr,
- &search_rec, H5HF_huge_bt2_indir_found, &found_rec) < 0)
+ if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_indir_found, &found_rec) != TRUE)
HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree")
/* Retrieve the object's address & length */
@@ -880,8 +908,16 @@ H5HF_huge_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id)
* Check arguments.
*/
HDassert(hdr);
+ HDassert(H5F_addr_defined(hdr->huge_bt2_addr));
HDassert(id);
+ /* Check if v2 B-tree is open yet */
+ if(NULL == hdr->huge_bt2) {
+ /* Open existing v2 B-tree */
+ if(NULL == (hdr->huge_bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr, hdr->f)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' heap objects")
+ } /* end if */
+
/* Skip over the flag byte */
id++;
@@ -901,8 +937,7 @@ H5HF_huge_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id)
/* Remove the record for tracking the 'huge' object from the v2 B-tree */
/* (space in the file for the object is freed in the 'remove' callback) */
- if(H5B2_remove(hdr->f, dxpl_id, H5HF_BT2_FILT_DIR, hdr->huge_bt2_addr,
- &search_rec, H5HF_huge_bt2_filt_dir_remove, &udata) < 0)
+ if(H5B2_remove(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_filt_dir_remove, &udata) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree")
} /* end if */
else {
@@ -915,8 +950,7 @@ H5HF_huge_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id)
/* Remove the record for tracking the 'huge' object from the v2 B-tree */
/* (space in the file for the object is freed in the 'remove' callback) */
- if(H5B2_remove(hdr->f, dxpl_id, H5HF_BT2_DIR, hdr->huge_bt2_addr,
- &search_rec, H5HF_huge_bt2_dir_remove, &udata) < 0)
+ if(H5B2_remove(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_dir_remove, &udata) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree")
} /* end else */
} /* end if */
@@ -929,8 +963,7 @@ H5HF_huge_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id)
/* Remove the record for tracking the 'huge' object from the v2 B-tree */
/* (space in the file for the object is freed in the 'remove' callback) */
- if(H5B2_remove(hdr->f, dxpl_id, H5HF_BT2_FILT_INDIR, hdr->huge_bt2_addr,
- &search_rec, H5HF_huge_bt2_filt_indir_remove, &udata) < 0)
+ if(H5B2_remove(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_filt_indir_remove, &udata) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree")
} /* end if */
else {
@@ -941,8 +974,7 @@ H5HF_huge_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id)
/* Remove the record for tracking the 'huge' object from the v2 B-tree */
/* (space in the file for the object is freed in the 'remove' callback) */
- if(H5B2_remove(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr,
- &search_rec, H5HF_huge_bt2_indir_remove, &udata) < 0)
+ if(H5B2_remove(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_indir_remove, &udata) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree")
} /* end else */
} /* end else */
@@ -985,6 +1017,17 @@ H5HF_huge_term(H5HF_hdr_t *hdr, hid_t dxpl_id)
*/
HDassert(hdr);
+ /* Check if v2 B-tree index is open */
+ if(hdr->huge_bt2) {
+ /* Sanity check */
+ HDassert(H5F_addr_defined(hdr->huge_bt2_addr));
+
+ /* Close v2 B-tree index */
+ if(H5B2_close(hdr->huge_bt2, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree")
+ hdr->huge_bt2 = NULL;
+ } /* end if */
+
/* Check if there are no more 'huge' objects in the heap and delete the
* v2 B-tree that tracks them, if so
*/
@@ -994,7 +1037,7 @@ H5HF_huge_term(H5HF_hdr_t *hdr, hid_t dxpl_id)
/* Delete the v2 B-tree */
/* (any v2 B-tree class will work here) */
- if(H5B2_delete(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr, NULL, NULL) < 0)
+ if(H5B2_delete(hdr->f, dxpl_id, hdr->huge_bt2_addr, hdr->f, NULL, NULL) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree")
/* Reset the information about 'huge' objects in the file */
@@ -1030,6 +1073,7 @@ herr_t
H5HF_huge_delete(H5HF_hdr_t *hdr, hid_t dxpl_id)
{
H5HF_huge_remove_ud1_t udata; /* User callback data for v2 B-tree remove call */
+ H5B2_remove_t op; /* Callback for v2 B-tree removal */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_delete)
@@ -1046,28 +1090,24 @@ H5HF_huge_delete(H5HF_hdr_t *hdr, hid_t dxpl_id)
udata.hdr = hdr;
udata.dxpl_id = dxpl_id;
- /* Delete the v2 B-tree */
+ /* Set the v2 B-tree callback operator */
if(hdr->huge_ids_direct) {
- if(hdr->filter_len > 0) {
- if(H5B2_delete(hdr->f, dxpl_id, H5HF_BT2_FILT_DIR, hdr->huge_bt2_addr, H5HF_huge_bt2_filt_dir_remove, &udata) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree")
- } /* end if */
- else {
- if(H5B2_delete(hdr->f, dxpl_id, H5HF_BT2_DIR, hdr->huge_bt2_addr, H5HF_huge_bt2_dir_remove, &udata) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree")
- } /* end else */
+ if(hdr->filter_len > 0)
+ op = H5HF_huge_bt2_filt_dir_remove;
+ else
+ op = H5HF_huge_bt2_dir_remove;
} /* end if */
else {
- if(hdr->filter_len > 0) {
- if(H5B2_delete(hdr->f, dxpl_id, H5HF_BT2_FILT_INDIR, hdr->huge_bt2_addr, H5HF_huge_bt2_filt_indir_remove, &udata) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree")
- } /* end if */
- else {
- if(H5B2_delete(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr, H5HF_huge_bt2_indir_remove, &udata) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree")
- } /* end else */
+ if(hdr->filter_len > 0)
+ op = H5HF_huge_bt2_filt_indir_remove;
+ else
+ op = H5HF_huge_bt2_indir_remove;
} /* end else */
+ /* Delete the v2 B-tree */
+ if(H5B2_delete(hdr->f, dxpl_id, hdr->huge_bt2_addr, hdr->f, op, &udata) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_huge_delete() */
diff --git a/src/H5HFiblock.c b/src/H5HFiblock.c
index 030d1ea..c6e22cc 100644
--- a/src/H5HFiblock.c
+++ b/src/H5HFiblock.c
@@ -35,6 +35,7 @@
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
+#include "H5Fprivate.h" /* File access */
#include "H5HFpkg.h" /* Fractal heaps */
#include "H5MFprivate.h" /* File memory management */
#include "H5Vprivate.h" /* Vectors and arrays */
@@ -125,7 +126,7 @@ H5HF_iblock_pin(H5HF_indirect_t *iblock)
/* Sanity check */
HDassert(par_iblock->child_iblocks);
- HDassert(iblock->par_entry >= (iblock->hdr->man_dtable.max_direct_rows
+ HDassert(iblock->par_entry >= (iblock->hdr->man_dtable.max_direct_rows
* iblock->hdr->man_dtable.cparam.width));
/* Compute index in parent's child iblock pointer array */
@@ -179,7 +180,7 @@ H5HF_iblock_unpin(H5HF_indirect_t *iblock)
/* Sanity check */
HDassert(par_iblock->child_iblocks);
- HDassert(iblock->par_entry >= (iblock->hdr->man_dtable.max_direct_rows
+ HDassert(iblock->par_entry >= (iblock->hdr->man_dtable.max_direct_rows
* iblock->hdr->man_dtable.cparam.width));
/* Compute index in parent's child iblock pointer array */
@@ -296,12 +297,8 @@ H5HF_iblock_decr(H5HF_indirect_t *iblock)
iblock->par_entry = 0;
} /* end if */
- /* Release space for indirect block on disk */
- if(H5MF_xfree(iblock->hdr->f, H5FD_MEM_FHEAP_IBLOCK, H5AC_dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block disk space")
-
/* Evict the indirect block from the metadata cache */
- if(H5AC_expunge_entry(iblock->hdr->f, H5AC_dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr) < 0)
+ if(H5AC_expunge_entry(iblock->hdr->f, H5AC_dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, H5AC__FREE_FILE_SPACE_FLAG) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "unable to remove indirect block from cache")
} /* end if */
} /* end if */
@@ -534,6 +531,9 @@ H5HF_man_iblock_root_double(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t min_dblock_si
/* Compute new # of rows in indirect block */
new_nrows = MAX(min_nrows, MIN(2 * iblock->nrows, iblock->max_rows));
+ /* Check if the indirect block is NOT currently allocated in temp. file space */
+ /* (temp. file space does not need to be freed) */
+ if(!H5F_IS_TMP_ADDR(hdr->f, iblock->addr)) {
/* Currently, the old block data is "thrown away" after the space is reallocated,
* to avoid data copy in H5MF_realloc() call by just free'ing the space and
* allocating new space.
@@ -543,17 +543,24 @@ H5HF_man_iblock_root_double(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t min_dblock_si
*
* QAK - 3/14/2006
*/
- /* Free previous indirect block disk space */
- if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block file space")
+ /* Free previous indirect block disk space */
+ if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block file space")
+ } /* end if */
/* Compute size of buffer needed for new indirect block */
iblock->nrows = new_nrows;
iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock);
- /* Allocate space for the new indirect block on disk */
- if(HADDR_UNDEF == (new_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
- HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
+ /* Allocate [temporary] space for the new indirect block on disk */
+ if(H5F_USE_TMP_SPACE(hdr->f)) {
+ if(HADDR_UNDEF == (new_addr = H5MF_alloc_tmp(hdr->f, (hsize_t)iblock->size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
+ } /* end if */
+ else {
+ if(HADDR_UNDEF == (new_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
+ } /* end else */
/* Move object in cache, if it actually was relocated */
if(H5F_addr_ne(iblock->addr, new_addr)) {
@@ -679,6 +686,9 @@ H5HF_man_iblock_root_halve(H5HF_indirect_t *iblock, hid_t dxpl_id)
/* Compute new # of rows in root indirect block */
new_nrows = 1 << (1 + H5V_log2_gen((uint64_t)max_child_row));
+ /* Check if the indirect block is NOT currently allocated in temp. file space */
+ /* (temp. file space does not need to be freed) */
+ if(!H5F_IS_TMP_ADDR(hdr->f, iblock->addr)) {
/* Currently, the old block data is "thrown away" after the space is reallocated,
* to avoid data copy in H5MF_realloc() call by just free'ing the space and
* allocating new space.
@@ -688,9 +698,10 @@ H5HF_man_iblock_root_halve(H5HF_indirect_t *iblock, hid_t dxpl_id)
*
* QAK - 6/12/2006
*/
- /* Free previous indirect block disk space */
- if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block file space")
+ /* Free previous indirect block disk space */
+ if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block file space")
+ } /* end if */
/* Compute free space in rows to delete */
acc_dblock_free = 0;
@@ -702,9 +713,15 @@ H5HF_man_iblock_root_halve(H5HF_indirect_t *iblock, hid_t dxpl_id)
iblock->nrows = new_nrows;
iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock);
- /* Allocate space for the new indirect block on disk */
- if(HADDR_UNDEF == (new_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
- HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
+ /* Allocate [temporary] space for the new indirect block on disk */
+ if(H5F_USE_TMP_SPACE(hdr->f)) {
+ if(HADDR_UNDEF == (new_addr = H5MF_alloc_tmp(hdr->f, (hsize_t)iblock->size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
+ } /* end if */
+ else {
+ if(HADDR_UNDEF == (new_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
+ } /* end else */
/* Move object in cache, if it actually was relocated */
if(H5F_addr_ne(iblock->addr, new_addr)) {
@@ -738,7 +755,7 @@ H5HF_man_iblock_root_halve(H5HF_indirect_t *iblock, hid_t dxpl_id)
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for filtered direct entries")
} /* end if */
else
- iblock->child_iblocks = H5FL_SEQ_FREE(H5HF_indirect_ptr_t, iblock->child_iblocks);
+ iblock->child_iblocks = (H5HF_indirect_ptr_t *)H5FL_SEQ_FREE(H5HF_indirect_ptr_t, iblock->child_iblocks);
} /* end if */
/* Mark indirect block as dirty */
@@ -990,9 +1007,15 @@ H5HF_man_iblock_create(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_indirect_t *par_iblo
else
iblock->child_iblocks = NULL;
- /* Allocate space for the indirect block on disk */
- if(HADDR_UNDEF == (*addr_p = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
+ /* Allocate [temporary] space for the indirect block on disk */
+ if(H5F_USE_TMP_SPACE(hdr->f)) {
+ if(HADDR_UNDEF == (*addr_p = H5MF_alloc_tmp(hdr->f, (hsize_t)iblock->size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
+ } /* end if */
+ else {
+ if(HADDR_UNDEF == (*addr_p = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
+ } /* end else */
iblock->addr = *addr_p;
/* Attach to parent indirect block, if there is one */
@@ -1062,7 +1085,7 @@ H5HF_man_iblock_protect(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t iblock_addr,
HDassert(iblock_nrows > 0);
HDassert(did_protect);
- /* Check if we are allow to use existing pinned iblock pointer */
+ /* Check if we are allowed to use existing pinned iblock pointer */
if(!must_protect) {
/* Check for this block already being pinned */
if(par_iblock) {
@@ -1070,7 +1093,7 @@ H5HF_man_iblock_protect(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t iblock_addr,
/* Sanity check */
HDassert(par_iblock->child_iblocks);
- HDassert(par_entry >= (hdr->man_dtable.max_direct_rows
+ HDassert(par_entry >= (hdr->man_dtable.max_direct_rows
* hdr->man_dtable.cparam.width));
/* Compute index in parent's child iblock pointer array */
@@ -1105,7 +1128,7 @@ H5HF_man_iblock_protect(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t iblock_addr,
par_info.entry = par_entry;
/* Protect the indirect block */
- if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &iblock_nrows, &par_info, rw)))
+ if(NULL == (iblock = (H5HF_indirect_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &iblock_nrows, &par_info, rw)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block")
*did_protect = TRUE;
} /* end if */
@@ -1382,6 +1405,7 @@ H5HF_man_iblock_delete(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t iblock_addr,
H5HF_indirect_t *iblock; /* Pointer to indirect block */
unsigned row, col; /* Current row & column in indirect block */
unsigned entry; /* Current entry in row */
+ unsigned cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting indirect block */
hbool_t did_protect; /* Whether we protected the indirect block or not */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1415,7 +1439,7 @@ H5HF_man_iblock_delete(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t iblock_addr,
/* Are we in a direct or indirect block row */
if(row < hdr->man_dtable.max_direct_rows) {
hsize_t dblock_size; /* Size of direct block on disk */
-
+
/* Check for I/O filters on this heap */
if(hdr->filter_len > 0)
dblock_size = iblock->filt_ents[entry].size;
@@ -1440,10 +1464,6 @@ H5HF_man_iblock_delete(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t iblock_addr,
} /* end for */
} /* end row */
- /* Release indirect block's disk space */
- if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock_addr, (hsize_t)iblock->size) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block")
-
#ifndef NDEBUG
{
unsigned iblock_status = 0; /* Indirect block's status in the metadata cache */
@@ -1457,12 +1477,14 @@ H5HF_man_iblock_delete(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t iblock_addr,
}
#endif /* NDEBUG */
- /* Finished deleting indirect block in metadata cache */
- if(H5HF_man_iblock_unprotect(iblock, dxpl_id, H5AC__DIRTIED_FLAG|H5AC__DELETED_FLAG, did_protect) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
- iblock = NULL;
+ /* Indicate that the indirect block should be deleted & file space freed */
+ cache_flags |= H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG;
done:
+ /* Unprotect the indirect block, with appropriate flags */
+ if(iblock && H5HF_man_iblock_unprotect(iblock, dxpl_id, cache_flags, did_protect) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_man_iblock_delete() */
@@ -1514,7 +1536,7 @@ H5HF_man_iblock_size(H5F_t *f, hid_t dxpl_id, H5HF_hdr_t *hdr, haddr_t iblock_ad
entry = hdr->man_dtable.max_direct_rows * hdr->man_dtable.cparam.width;
first_row_bits = H5V_log2_of2((uint32_t)hdr->man_dtable.cparam.start_block_size) +
H5V_log2_of2(hdr->man_dtable.cparam.width);
- num_indirect_rows =
+ num_indirect_rows =
(H5V_log2_gen(hdr->man_dtable.row_block_size[hdr->man_dtable.max_direct_rows]) - first_row_bits) + 1;
for(u = hdr->man_dtable.max_direct_rows; u < iblock->nrows; u++, num_indirect_rows++) {
size_t v; /* Local index variable */
diff --git a/src/H5HFiter.c b/src/H5HFiter.c
index 4dbb186..a3c61d7 100644
--- a/src/H5HFiter.c
+++ b/src/H5HFiter.c
@@ -180,7 +180,8 @@ H5HF_man_iter_start_offset(H5HF_hdr_t *hdr, hid_t dxpl_id,
curr_offset = offset - hdr->man_dtable.row_block_off[row];
/* Compute column */
- col = curr_offset / hdr->man_dtable.row_block_size[row];
+ H5_CHECK_OVERFLOW((curr_offset / hdr->man_dtable.row_block_size[row]), hsize_t, unsigned);
+ col = (unsigned)(curr_offset / hdr->man_dtable.row_block_size[row]);
/* Set the current level's context */
biter->curr->row = row;
@@ -396,7 +397,7 @@ H5HF_man_iter_reset(H5HF_block_iter_t *biter)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block")
/* Free the current location context */
- H5FL_FREE(H5HF_block_loc_t, curr_loc);
+ (void)H5FL_FREE(H5HF_block_loc_t, curr_loc);
/* Advance to next location */
curr_loc = next_loc;
@@ -488,7 +489,7 @@ H5HF_man_iter_up(H5HF_block_iter_t *biter)
up_loc = biter->curr->up;
/* Release this location */
- H5FL_FREE(H5HF_block_loc_t, biter->curr);
+ (void)H5FL_FREE(H5HF_block_loc_t, biter->curr);
/* Point location to next location up */
biter->curr = up_loc;
diff --git a/src/H5HFman.c b/src/H5HFman.c
index e92e80c..47478e6 100644
--- a/src/H5HFman.c
+++ b/src/H5HFman.c
@@ -44,6 +44,19 @@
/* Local Macros */
/****************/
+/* Macro to check if we can apply all filters in the pipeline. Use whenever
+ * performing a modification operation */
+ #define H5HF_MAN_WRITE_CHECK_PLINE(HDR) \
+{ \
+ if(!((HDR)->checked_filters)) { \
+ if((HDR)->pline.nused) \
+ if(H5Z_can_apply_direct(&((HDR)->pline)) < 0) \
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "I/O filters can't operate on this heap") \
+ \
+ (HDR)->checked_filters = TRUE; \
+ } /* end if */ \
+}
+
/******************/
/* Local Typedefs */
@@ -113,6 +126,9 @@ H5HF_man_insert(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t obj_size, const void *obj
HDassert(obj);
HDassert(id);
+ /* Check pipeline */
+ H5HF_MAN_WRITE_CHECK_PLINE(hdr)
+
/* Look for free space */
if((node_found = H5HF_space_find(hdr, dxpl_id, (hsize_t)obj_size, &sec_node)) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap")
@@ -151,7 +167,8 @@ H5HF_man_insert(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t obj_size, const void *obj
/* Insert object into block */
/* Get the offset of the object within the block */
- blk_off = sec_node->sect_info.addr - dblock->block_off;
+ H5_CHECK_OVERFLOW((sec_node->sect_info.addr - dblock->block_off), hsize_t, size_t);
+ blk_off = (size_t)(sec_node->sect_info.addr - dblock->block_off);
/* Sanity checks */
HDassert(sec_node->sect_info.size >= obj_size);
@@ -209,7 +226,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_man_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
+H5HF_man_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
H5HF_operator_t op, void *op_data, unsigned op_flags)
{
H5HF_direct_t *dblock = NULL; /* Pointer to direct block to query */
@@ -234,6 +251,9 @@ H5HF_man_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
/* Set the access mode for the direct block */
if(op_flags & H5HF_OP_MODIFY) {
+ /* Check pipeline */
+ H5HF_MAN_WRITE_CHECK_PLINE(hdr)
+
dblock_access = H5AC_WRITE;
dblock_cache_flags = H5AC__DIRTIED_FLAG;
} /* end if */
@@ -280,7 +300,8 @@ H5HF_man_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
/* Set direct block info */
dblock_addr = iblock->ents[entry].addr;
- dblock_size = hdr->man_dtable.row_block_size[entry / hdr->man_dtable.cparam.width];
+ H5_CHECK_OVERFLOW((hdr->man_dtable.row_block_size[entry / hdr->man_dtable.cparam.width]), hsize_t, size_t);
+ dblock_size = (size_t)hdr->man_dtable.row_block_size[entry / hdr->man_dtable.cparam.width];
/* Check for offset of invalid direct block */
if(!H5F_addr_defined(dblock_addr)) {
@@ -480,6 +501,9 @@ H5HF_man_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id)
HDassert(hdr);
HDassert(id);
+ /* Check pipeline */
+ H5HF_MAN_WRITE_CHECK_PLINE(hdr)
+
/* Skip over the flag byte */
id++;
@@ -514,7 +538,8 @@ H5HF_man_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id)
HGOTO_ERROR(H5E_HEAP, H5E_BADRANGE, FAIL, "fractal heap ID not in allocated direct block")
/* Set direct block info */
- dblock_size = hdr->man_dtable.row_block_size[dblock_entry / hdr->man_dtable.cparam.width];
+ H5_CHECK_OVERFLOW((hdr->man_dtable.row_block_size[dblock_entry / hdr->man_dtable.cparam.width]), hsize_t, size_t);
+ dblock_size = (size_t)(hdr->man_dtable.row_block_size[dblock_entry / hdr->man_dtable.cparam.width]);
/* Compute the direct block's offset in the heap's address space */
/* (based on parent indirect block's block offset) */
diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h
index fd332e5..3c5567c 100644
--- a/src/H5HFpkg.h
+++ b/src/H5HFpkg.h
@@ -35,27 +35,19 @@
#include "H5ACprivate.h" /* Metadata cache */
#include "H5B2private.h" /* v2 B-trees */
#include "H5FLprivate.h" /* Free Lists */
-#include "H5FSprivate.h" /* File free space */
+#include "H5FSprivate.h" /* Free space manager */
#include "H5SLprivate.h" /* Skip lists */
/**************************/
/* Package Private Macros */
/**************************/
-/* Size of signature information (on disk) */
-#define H5HF_SIZEOF_MAGIC 4
-
-/* Fractal heap signatures */
-#define H5HF_HDR_MAGIC "FRHP" /* Header */
-#define H5HF_IBLOCK_MAGIC "FHIB" /* Indirect block */
-#define H5HF_DBLOCK_MAGIC "FHDB" /* Direct block */
-
/* Size of checksum information (on disk) */
#define H5HF_SIZEOF_CHKSUM 4
/* "Standard" size of prefix information for fractal heap metadata */
#define H5HF_METADATA_PREFIX_SIZE(c) ( \
- H5HF_SIZEOF_MAGIC /* Signature */ \
+ H5_SIZEOF_MAGIC /* Signature */ \
+ 1 /* Version */ \
+ ((c) ? H5HF_SIZEOF_CHKSUM : 0) /* Metadata checksum */ \
)
@@ -343,25 +335,26 @@ typedef struct H5HF_hdr_t {
/* Cached/computed values (not stored in header) */
size_t rc; /* Reference count of heap's components using heap header */
- hbool_t dirty; /* Shared info is modified */
haddr_t heap_addr; /* Address of heap header in the file */
size_t heap_size; /* Size of heap header in the file */
H5AC_protect_t mode; /* Access mode for heap */
H5F_t *f; /* Pointer to file for heap */
size_t file_rc; /* Reference count of files using heap header */
hbool_t pending_delete; /* Heap is pending deletion */
- size_t sizeof_size; /* Size of file sizes */
- size_t sizeof_addr; /* Size of file addresses */
+ uint8_t sizeof_size; /* Size of file sizes */
+ uint8_t sizeof_addr; /* Size of file addresses */
struct H5HF_indirect_t *root_iblock; /* Pointer to pinned root indirect block */
H5FS_t *fspace; /* Free space list for objects in heap */
H5HF_block_iter_t next_block; /* Block iterator for searching for next block with space */
+ H5B2_t *huge_bt2; /* v2 B-tree handle for huge objects */
hsize_t huge_max_id; /* Max. 'huge' heap ID before rolling 'huge' heap IDs over */
+ uint8_t huge_id_size; /* Size of 'huge' heap IDs (in bytes) */
hbool_t huge_ids_direct; /* Flag to indicate that 'huge' object's offset & length are stored directly in heap ID */
size_t tiny_max_len; /* Max. size of tiny objects for this heap */
hbool_t tiny_len_extended; /* Flag to indicate that 'tiny' object's length is stored in extended form (i.e. w/extra byte) */
- unsigned char huge_id_size; /* Size of 'huge' heap IDs (in bytes) */
- unsigned char heap_off_size; /* Size of heap offsets (in bytes) */
- unsigned char heap_len_size; /* Size of heap ID lengths (in bytes) */
+ uint8_t heap_off_size; /* Size of heap offsets (in bytes) */
+ uint8_t heap_len_size; /* Size of heap ID lengths (in bytes) */
+ hbool_t checked_filters; /* TRUE if pipeline passes can_apply checks */
} H5HF_hdr_t;
/* Common indirect block doubling table entry */
@@ -411,7 +404,7 @@ typedef struct H5HF_direct_t {
H5HF_indirect_t *parent; /* Shared parent indirect block info */
unsigned par_entry; /* Entry in parent's table */
size_t size; /* Size of direct block */
- unsigned blk_off_size; /* Size of offsets in the block */
+ hsize_t file_size; /* Size of direct block in file (only valid when block's space is being freed) */
uint8_t *blk; /* Pointer to buffer containing block data */
/* Stored values */
@@ -488,16 +481,16 @@ H5_DLLVAR const H5AC_class_t H5AC_FHEAP_IBLOCK[1];
H5_DLLVAR const H5AC_class_t H5AC_FHEAP_DBLOCK[1];
/* The v2 B-tree class for tracking indirectly accessed 'huge' objects */
-H5_DLLVAR const H5B2_class_t H5HF_BT2_INDIR[1];
+H5_DLLVAR const H5B2_class_t H5HF_HUGE_BT2_INDIR[1];
/* The v2 B-tree class for tracking indirectly accessed filtered 'huge' objects */
-H5_DLLVAR const H5B2_class_t H5HF_BT2_FILT_INDIR[1];
+H5_DLLVAR const H5B2_class_t H5HF_HUGE_BT2_FILT_INDIR[1];
/* The v2 B-tree class for tracking directly accessed 'huge' objects */
-H5_DLLVAR const H5B2_class_t H5HF_BT2_DIR[1];
+H5_DLLVAR const H5B2_class_t H5HF_HUGE_BT2_DIR[1];
/* The v2 B-tree class for tracking directly accessed filtered 'huge' objects */
-H5_DLLVAR const H5B2_class_t H5HF_BT2_FILT_DIR[1];
+H5_DLLVAR const H5B2_class_t H5HF_HUGE_BT2_FILT_DIR[1];
/* H5HF single section inherits serializable properties from H5FS_section_class_t */
H5_DLLVAR H5FS_section_class_t H5HF_FSPACE_SECT_CLS_SINGLE[1];
@@ -511,9 +504,6 @@ H5_DLLVAR H5FS_section_class_t H5HF_FSPACE_SECT_CLS_NORMAL_ROW[1];
/* H5HF indirect section inherits serializable properties from H5FS_section_class_t */
H5_DLLVAR H5FS_section_class_t H5HF_FSPACE_SECT_CLS_INDIRECT[1];
-/* Declare a free list to manage the H5HF_hdr_t struct */
-H5FL_EXTERN(H5HF_hdr_t);
-
/* Declare a free list to manage the H5HF_indirect_t struct */
H5FL_EXTERN(H5HF_indirect_t);
@@ -571,6 +561,7 @@ H5_DLL herr_t H5HF_hdr_reverse_iter(H5HF_hdr_t *hdr, hid_t dxpl_id,
haddr_t dblock_addr);
H5_DLL herr_t H5HF_hdr_reset_iter(H5HF_hdr_t *hdr, hsize_t curr_off);
H5_DLL herr_t H5HF_hdr_empty(H5HF_hdr_t *hdr);
+H5_DLL herr_t H5HF_hdr_free(H5HF_hdr_t *hdr);
H5_DLL herr_t H5HF_hdr_delete(H5HF_hdr_t *hdr, hid_t dxpl_id);
/* Indirect block routines */
@@ -648,6 +639,15 @@ H5_DLL herr_t H5HF_huge_remove(H5HF_hdr_t *fh, hid_t dxpl_id, const uint8_t *id)
H5_DLL herr_t H5HF_huge_term(H5HF_hdr_t *hdr, hid_t dxpl_id);
H5_DLL herr_t H5HF_huge_delete(H5HF_hdr_t *hdr, hid_t dxpl_id);
+/* 'Huge' object v2 B-tree function callbacks */
+H5_DLL herr_t H5HF_huge_bt2_indir_found(const void *nrecord, void *op_data);
+H5_DLL herr_t H5HF_huge_bt2_indir_remove(const void *nrecord, void *op_data);
+H5_DLL herr_t H5HF_huge_bt2_filt_indir_found(const void *nrecord, void *op_data);
+H5_DLL herr_t H5HF_huge_bt2_filt_indir_remove(const void *nrecord, void *op_data);
+H5_DLL herr_t H5HF_huge_bt2_dir_remove(const void *nrecord, void *op_data);
+H5_DLL herr_t H5HF_huge_bt2_filt_dir_found(const void *nrecord, void *op_data);
+H5_DLL herr_t H5HF_huge_bt2_filt_dir_remove(const void *nrecord, void *op_data);
+
/* 'Tiny' object routines */
H5_DLL herr_t H5HF_tiny_init(H5HF_hdr_t *hdr);
H5_DLL herr_t H5HF_tiny_insert(H5HF_hdr_t *hdr, size_t obj_size, const void *obj,
diff --git a/src/H5HFprivate.h b/src/H5HFprivate.h
index 790f5ea..55daa30 100644
--- a/src/H5HFprivate.h
+++ b/src/H5HFprivate.h
@@ -111,7 +111,7 @@ typedef herr_t (*H5HF_operator_t)(const void *obj/*in*/, size_t obj_len,
H5_DLL H5HF_t *H5HF_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam);
H5_DLL H5HF_t *H5HF_open(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr);
H5_DLL herr_t H5HF_get_id_len(H5HF_t *fh, size_t *id_len_p/*out*/);
-H5_DLL herr_t H5HF_get_heap_addr(H5HF_t *fh, haddr_t *heap_addr/*out*/);
+H5_DLL herr_t H5HF_get_heap_addr(const H5HF_t *fh, haddr_t *heap_addr/*out*/);
H5_DLL herr_t H5HF_insert(H5HF_t *fh, hid_t dxpl_id, size_t size,
const void *obj, void *id/*out*/);
H5_DLL herr_t H5HF_get_obj_len(H5HF_t *fh, hid_t dxpl_id, const void *id,
diff --git a/src/H5HFsection.c b/src/H5HFsection.c
index eca55c8..152f15a 100644
--- a/src/H5HFsection.c
+++ b/src/H5HFsection.c
@@ -206,6 +206,7 @@ H5FS_section_class_t H5HF_FSPACE_SECT_CLS_SINGLE[1] = {{
H5HF_sect_single_shrink, /* Shrink container w/section */
H5HF_sect_single_free, /* Free section */
H5HF_sect_single_valid, /* Check validity of section */
+ NULL, /* Split section node for alignment */
NULL, /* Dump debugging for section */
}};
@@ -234,6 +235,7 @@ H5FS_section_class_t H5HF_FSPACE_SECT_CLS_FIRST_ROW[1] = {{
H5HF_sect_row_shrink, /* Shrink container w/section */
H5HF_sect_row_free, /* Free section */
H5HF_sect_row_valid, /* Check validity of section */
+ NULL, /* Split section node for alignment */
H5HF_sect_row_debug, /* Dump debugging for section */
}};
@@ -259,6 +261,7 @@ H5FS_section_class_t H5HF_FSPACE_SECT_CLS_NORMAL_ROW[1] = {{
NULL, /* Shrink container w/section */
H5HF_sect_row_free, /* Free section */
H5HF_sect_row_valid, /* Check validity of section */
+ NULL, /* Split section node for alignment */
H5HF_sect_row_debug, /* Dump debugging for section */
}};
@@ -287,6 +290,7 @@ H5FS_section_class_t H5HF_FSPACE_SECT_CLS_INDIRECT[1] = {{
NULL, /* Shrink container w/section */
NULL, /* Free section */
NULL, /* Check validity of section */
+ NULL, /* Split section node for alignment */
NULL, /* Dump debugging for section */
}};
@@ -333,7 +337,7 @@ H5HF_sect_init_cls(H5FS_section_class_t *cls, H5HF_hdr_t *hdr)
/* Allocate & initialize the class-private (i.e. private shared) information
* for this type of section
*/
- if(NULL == (cls_prvt = H5MM_malloc(sizeof(H5HF_sect_private_t))))
+ if(NULL == (cls_prvt = (H5HF_sect_private_t *)H5MM_malloc(sizeof(H5HF_sect_private_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
cls_prvt->hdr = hdr;
cls->cls_private = cls_prvt;
@@ -372,7 +376,7 @@ H5HF_sect_term_cls(H5FS_section_class_t *cls)
HDassert(cls);
/* Get pointer to class private info */
- cls_prvt = cls->cls_private;
+ cls_prvt = (H5HF_sect_private_t *)cls->cls_private;
/* Decrement reference count on heap header */
if(H5HF_hdr_decr(cls_prvt->hdr) < 0)
@@ -461,7 +465,7 @@ H5HF_sect_node_free(H5HF_free_section_t *sect, H5HF_indirect_t *iblock)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on section's indirect block")
/* Release the section */
- H5FL_FREE(H5HF_free_section_t, sect);
+ (void)H5FL_FREE(H5HF_free_section_t, sect);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -522,7 +526,7 @@ done:
} /* end if */
/* Release the section */
- H5FL_FREE(H5HF_free_section_t, sect);
+ (void)H5FL_FREE(H5HF_free_section_t, sect);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -1138,7 +1142,7 @@ H5HF_sect_single_shrink(H5FS_section_info_t **_sect, void UNUSED *_udata)
/* Protect the direct block for the section */
/* (should be a root direct block) */
HDassert(dblock_addr == hdr->man_dtable.table_addr);
- if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr,
+ if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr,
dblock_size, (*sect)->u.single.parent, (*sect)->u.single.par_entry, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load fractal heap direct block")
HDassert(H5F_addr_eq(dblock->block_off + dblock_size, (*sect)->sect_info.addr + (*sect)->sect_info.size));
@@ -2051,7 +2055,7 @@ H5HF_sect_row_valid(const H5FS_section_class_t *cls, const H5FS_section_info_t *
HDassert(sect);
/* Retrieve class private information */
- cls_prvt = cls->cls_private;
+ cls_prvt = (H5HF_sect_private_t *)cls->cls_private;
hdr = cls_prvt->hdr;
/* Sanity checking on the row */
@@ -2306,7 +2310,7 @@ H5HF_sect_indirect_new(H5HF_hdr_t *hdr, haddr_t sect_off, hsize_t sect_size,
/* Set the 'indirect' specific fields */
if(iblock) {
sect->u.indirect.u.iblock = iblock;
- sect->u.indirect.iblock_entries = hdr->man_dtable.cparam.width *
+ sect->u.indirect.iblock_entries = hdr->man_dtable.cparam.width *
sect->u.indirect.u.iblock->max_rows;
if(H5HF_iblock_incr(sect->u.indirect.u.iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared indirect block")
@@ -2340,7 +2344,7 @@ done:
HDONE_ERROR(H5E_HEAP, H5E_CANTDEC, NULL, "can't decrement reference count on shared indirect block")
/* Release the section */
- H5FL_FREE(H5HF_free_section_t, sect);
+ (void)H5FL_FREE(H5HF_free_section_t, sect);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -2361,7 +2365,7 @@ done:
*-------------------------------------------------------------------------
*/
static H5HF_free_section_t *
-H5HF_sect_indirect_for_row(H5HF_hdr_t *hdr, H5HF_indirect_t *iblock,
+H5HF_sect_indirect_for_row(H5HF_hdr_t *hdr, H5HF_indirect_t *iblock,
H5HF_free_section_t *row_sect)
{
H5HF_free_section_t *sect = NULL; /* 'Indirect' free space section to add */
@@ -2378,7 +2382,7 @@ H5HF_sect_indirect_for_row(H5HF_hdr_t *hdr, H5HF_indirect_t *iblock,
HDassert(row_sect->u.row.row < hdr->man_dtable.max_direct_rows);
/* Create free space section node */
- if(NULL == (sect = H5HF_sect_indirect_new(hdr, row_sect->sect_info.addr,
+ if(NULL == (sect = H5HF_sect_indirect_new(hdr, row_sect->sect_info.addr,
row_sect->sect_info.size, iblock, iblock->block_off,
row_sect->u.row.row, row_sect->u.row.col, row_sect->u.row.num_entries)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't create indirect section")
@@ -2387,7 +2391,7 @@ H5HF_sect_indirect_for_row(H5HF_hdr_t *hdr, H5HF_indirect_t *iblock,
sect->u.indirect.dir_nrows = 1;
/* Allocate space for the derived row sections */
- if(NULL == (sect->u.indirect.dir_rows = H5MM_malloc(sizeof(H5HF_free_section_t *))))
+ if(NULL == (sect->u.indirect.dir_rows = (H5HF_free_section_t **)H5MM_malloc(sizeof(H5HF_free_section_t *))))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "allocation failed for row section pointer array")
/* Atatch the new row section to indirect section */
@@ -2469,7 +2473,7 @@ H5HF_sect_indirect_init_rows(H5HF_hdr_t *hdr, hid_t dxpl_id,
sect->u.indirect.dir_nrows = 0;
/* Allocate space for the derived row sections */
- if(NULL == (sect->u.indirect.dir_rows = H5MM_malloc(sizeof(H5HF_free_section_t *) * dir_nrows)))
+ if(NULL == (sect->u.indirect.dir_rows = (H5HF_free_section_t **)H5MM_malloc(sizeof(H5HF_free_section_t *) * dir_nrows)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "allocation failed for row section pointer array")
} /* end if */
else {
@@ -2499,14 +2503,13 @@ H5HF_sect_indirect_init_rows(H5HF_hdr_t *hdr, hid_t dxpl_id,
+ indirect_start_col;
/* Compute ending indirect entry */
- indirect_end_entry = (end_row * hdr->man_dtable.cparam.width) +
- end_col;
+ indirect_end_entry = (end_row * hdr->man_dtable.cparam.width) + end_col;
/* Compute # of indirect entries covered */
sect->u.indirect.indir_nents = (indirect_end_entry - indirect_start_entry) + 1;
/* Allocate space for the child indirect sections */
- if(NULL == (sect->u.indirect.indir_ents = H5MM_malloc(sizeof(H5HF_free_section_t *) * sect->u.indirect.indir_nents)))
+ if(NULL == (sect->u.indirect.indir_ents = (H5HF_free_section_t **)H5MM_malloc(sizeof(H5HF_free_section_t *) * sect->u.indirect.indir_nents)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "allocation failed for indirect section pointer array")
} /* end if */
else {
@@ -2647,7 +2650,7 @@ H5HF_sect_indirect_init_rows(H5HF_hdr_t *hdr, hid_t dxpl_id,
sect->u.indirect.dir_nrows = dir_nrows;
/* Make certain we've tracked the section's dependents correctly */
- HDassert(sect->u.indirect.rc ==
+ HDassert(sect->u.indirect.rc ==
(sect->u.indirect.indir_nents + sect->u.indirect.dir_nrows));
done:
@@ -2827,7 +2830,7 @@ H5HF_sect_indirect_revive_row(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_
sect->u.indirect.u.iblock = sec_iblock;
/* Set the number of entries in the indirect block */
- sect->u.indirect.iblock_entries = hdr->man_dtable.cparam.width *
+ sect->u.indirect.iblock_entries = hdr->man_dtable.cparam.width *
sect->u.indirect.u.iblock->max_rows;
/* Unlock indirect block */
@@ -2890,7 +2893,7 @@ H5HF_sect_indirect_revive(H5HF_hdr_t *hdr, hid_t dxpl_id,
sect->u.indirect.u.iblock = sect_iblock;
/* Set the number of entries in the indirect block */
- sect->u.indirect.iblock_entries = hdr->man_dtable.cparam.width *
+ sect->u.indirect.iblock_entries = hdr->man_dtable.cparam.width *
sect->u.indirect.u.iblock->max_rows;
/* Section is "live" now */
@@ -2938,7 +2941,6 @@ H5HF_sect_indirect_reduce_row(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_
unsigned start_col; /* Start column in indirect block */
unsigned end_entry; /* Entry for last block covered */
unsigned end_row; /* End row in indirect block */
- unsigned end_col; /* End column in indirect block */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_indirect_reduce_row)
@@ -2960,7 +2962,6 @@ H5HF_sect_indirect_reduce_row(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_
start_entry = (start_row * hdr->man_dtable.cparam.width) + start_col;
end_entry = (start_entry + sect->u.indirect.num_entries) - 1;
end_row = end_entry / hdr->man_dtable.cparam.width;
- end_col = end_entry % hdr->man_dtable.cparam.width;
/* Additional sanity check */
HDassert(sect->u.indirect.span_size > 0);
@@ -3038,7 +3039,7 @@ H5HF_sect_indirect_reduce_row(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_
HDassert(sect->u.indirect.indir_ents);
/* Eliminate direct rows for this section */
- sect->u.indirect.dir_rows = H5MM_xfree(sect->u.indirect.dir_rows);
+ sect->u.indirect.dir_rows = (H5HF_free_section_t **)H5MM_xfree(sect->u.indirect.dir_rows);
/* Make new "first row" in indirect section */
if(row_sect->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW)
@@ -3107,17 +3108,17 @@ H5HF_sect_indirect_reduce_row(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_
/* Set up direct row & indirect entry information for peer section */
peer_sect->u.indirect.dir_nrows = peer_dir_nrows;
- if(NULL == (peer_sect->u.indirect.dir_rows = H5MM_malloc(sizeof(H5HF_free_section_t *) * peer_dir_nrows)))
+ if(NULL == (peer_sect->u.indirect.dir_rows = (H5HF_free_section_t **)H5MM_malloc(sizeof(H5HF_free_section_t *) * peer_dir_nrows)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "allocation failed for row section pointer array")
peer_sect->u.indirect.indir_nents = 0;
peer_sect->u.indirect.indir_ents = NULL;
/* Transfer row sections between current & peer sections */
HDmemcpy(&peer_sect->u.indirect.dir_rows[0],
- &sect->u.indirect.dir_rows[0],
+ &sect->u.indirect.dir_rows[0],
(sizeof(H5HF_free_section_t *) * peer_dir_nrows));
- HDmemmove(&sect->u.indirect.dir_rows[0],
- &sect->u.indirect.dir_rows[peer_dir_nrows],
+ HDmemmove(&sect->u.indirect.dir_rows[0],
+ &sect->u.indirect.dir_rows[peer_dir_nrows],
(sizeof(H5HF_free_section_t *) * (sect->u.indirect.dir_nrows - peer_dir_nrows)));
sect->u.indirect.dir_nrows -= peer_dir_nrows;
HDassert(row_sect == sect->u.indirect.dir_rows[0]);
@@ -3149,9 +3150,9 @@ H5HF_sect_indirect_reduce_row(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_
sect->u.indirect.num_entries -= (peer_nentries + 1); /* Transferred entries, plus the entry allocated out of the row */
/* Make certain we've tracked the sections' dependents correctly */
- HDassert(sect->u.indirect.rc ==
+ HDassert(sect->u.indirect.rc ==
(sect->u.indirect.indir_nents + sect->u.indirect.dir_nrows));
- HDassert(peer_sect->u.indirect.rc ==
+ HDassert(peer_sect->u.indirect.rc ==
(peer_sect->u.indirect.indir_nents + peer_sect->u.indirect.dir_nrows));
} /* end else */
} /* end if */
@@ -3162,7 +3163,7 @@ H5HF_sect_indirect_reduce_row(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_
HDassert(sect->u.indirect.dir_nrows == 0);
/* Eliminate direct rows for this section */
- sect->u.indirect.dir_rows = H5MM_xfree(sect->u.indirect.dir_rows);
+ sect->u.indirect.dir_rows = (H5HF_free_section_t **)H5MM_xfree(sect->u.indirect.dir_rows);
} /* end else */
done:
@@ -3194,7 +3195,6 @@ H5HF_sect_indirect_reduce(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *s
unsigned start_col; /* Start column in indirect block */
unsigned end_entry; /* Entry for last block covered */
unsigned end_row; /* End row in indirect block */
- unsigned end_col; /* End column in indirect block */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_indirect_reduce)
@@ -3213,7 +3213,6 @@ H5HF_sect_indirect_reduce(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *s
start_entry = (start_row * hdr->man_dtable.cparam.width) + start_col;
end_entry = (start_entry + sect->u.indirect.num_entries) - 1;
end_row = end_entry / hdr->man_dtable.cparam.width;
- end_col = end_entry % hdr->man_dtable.cparam.width;
/* Check how to adjust section for allocated entry */
if(sect->u.indirect.num_entries > 1) {
@@ -3279,7 +3278,7 @@ H5HF_sect_indirect_reduce(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *s
/* Adjust indirect entry information */
sect->u.indirect.indir_nents--;
if(sect->u.indirect.indir_nents == 0)
- sect->u.indirect.indir_ents = H5MM_xfree(sect->u.indirect.indir_ents);
+ sect->u.indirect.indir_ents = (H5HF_free_section_t **)H5MM_xfree(sect->u.indirect.indir_ents);
} /* end if */
else {
H5HF_free_section_t *peer_sect; /* Peer indirect section */
@@ -3337,18 +3336,18 @@ H5HF_sect_indirect_reduce(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *s
peer_sect->u.indirect.dir_nrows = 0;
peer_sect->u.indirect.dir_rows = NULL;
peer_sect->u.indirect.indir_nents = peer_nentries;
- if(NULL == (peer_sect->u.indirect.indir_ents = H5MM_malloc(sizeof(H5HF_free_section_t *) * peer_nentries)))
+ if(NULL == (peer_sect->u.indirect.indir_ents = (H5HF_free_section_t **)H5MM_malloc(sizeof(H5HF_free_section_t *) * peer_nentries)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "allocation failed for indirect section pointer array")
/* Transfer child indirect sections between current & peer sections */
HDmemcpy(&peer_sect->u.indirect.indir_ents[0],
- &sect->u.indirect.indir_ents[sect->u.indirect.indir_nents - peer_nentries],
+ &sect->u.indirect.indir_ents[sect->u.indirect.indir_nents - peer_nentries],
(sizeof(H5HF_free_section_t *) * peer_nentries));
sect->u.indirect.indir_nents -= (peer_nentries + 1); /* Transferred blocks, plus child entry */
/* Eliminate indirect entries for this section, if appropriate */
if(sect->u.indirect.indir_nents == 0)
- sect->u.indirect.indir_ents = H5MM_xfree(sect->u.indirect.indir_ents);
+ sect->u.indirect.indir_ents = (H5HF_free_section_t **)H5MM_xfree(sect->u.indirect.indir_ents);
/* Re-target transferred row sections to point to new underlying indirect section */
for(u = 0; u < peer_nentries; u++)
@@ -3369,9 +3368,9 @@ H5HF_sect_indirect_reduce(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *s
/* (Note modified on current section's ref. count, since we haven't
* detached the child section yet)
*/
- HDassert((sect->u.indirect.rc - 1) ==
+ HDassert((sect->u.indirect.rc - 1) ==
(sect->u.indirect.indir_nents + sect->u.indirect.dir_nrows));
- HDassert(peer_sect->u.indirect.rc ==
+ HDassert(peer_sect->u.indirect.rc ==
(peer_sect->u.indirect.indir_nents + peer_sect->u.indirect.dir_nrows));
} /* end else */
} /* end if */
@@ -3382,7 +3381,7 @@ H5HF_sect_indirect_reduce(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *s
HDassert(sect->u.indirect.indir_nents == 0);
/* Eliminate indirect entries for this section */
- sect->u.indirect.indir_ents = H5MM_xfree(sect->u.indirect.indir_ents);
+ sect->u.indirect.indir_ents = (H5HF_free_section_t **)H5MM_xfree(sect->u.indirect.indir_ents);
} /* end else */
/* Decrement # of sections which depend on this row */
@@ -3535,11 +3534,8 @@ H5HF_sect_indirect_merge_row(H5HF_hdr_t *hdr, hid_t dxpl_id,
unsigned start_entry1; /* Start entry for section #1 */
unsigned start_row1, start_col1; /* Starting row & column for section #1 */
unsigned end_entry1; /* End entry for section #1 */
- unsigned end_row1, end_col1; /* Ending row & column for section #1 */
- unsigned start_entry2; /* Start entry for section #2 */
- unsigned start_row2, start_col2; /* Starting row & column for section #2 */
- unsigned end_row2, end_col2; /* Ending row & column for section #2 */
- unsigned end_entry2; /* End entry for section #2 */
+ unsigned end_row1; /* Ending row for section #1 */
+ unsigned start_row2; /* Starting row for section #2 */
hbool_t merged_rows; /* Flag to indicate that rows was merged together */
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -3577,13 +3573,7 @@ H5HF_sect_indirect_merge_row(H5HF_hdr_t *hdr, hid_t dxpl_id,
start_entry1 = (start_row1 * hdr->man_dtable.cparam.width) + start_col1;
end_entry1 = (start_entry1 + sect1->u.indirect.num_entries) - 1;
end_row1 = end_entry1 / hdr->man_dtable.cparam.width;
- end_col1 = end_entry1 % hdr->man_dtable.cparam.width;
start_row2 = sect2->u.indirect.row;
- start_col2 = sect2->u.indirect.col;
- start_entry2 = (start_row2 * hdr->man_dtable.cparam.width) + start_col2;
- end_entry2 = (start_entry2 + sect2->u.indirect.num_entries) - 1;
- end_row2 = end_entry2 / hdr->man_dtable.cparam.width;
- end_col2 = end_entry2 % hdr->man_dtable.cparam.width;
/* Check for direct sections in second section */
/* (second indirect section can be parent of indirect section for second
@@ -3644,13 +3634,13 @@ H5HF_sect_indirect_merge_row(H5HF_hdr_t *hdr, hid_t dxpl_id,
H5HF_free_section_t **new_dir_rows; /* Pointer to new array of direct row pointers */
/* Extend the first section's row array */
- if(NULL == (new_dir_rows = H5MM_realloc(sect1->u.indirect.dir_rows, sizeof(H5HF_free_section_t *) * new_dir_nrows1)))
+ if(NULL == (new_dir_rows = (H5HF_free_section_t **)H5MM_realloc(sect1->u.indirect.dir_rows, sizeof(H5HF_free_section_t *) * new_dir_nrows1)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "allocation failed for row section pointer array")
sect1->u.indirect.dir_rows = new_dir_rows;
/* Transfer the second section's rows to first section */
- HDmemcpy(&sect1->u.indirect.dir_rows[sect1->u.indirect.dir_nrows],
- &sect2->u.indirect.dir_rows[src_row2],
+ HDmemcpy(&sect1->u.indirect.dir_rows[sect1->u.indirect.dir_nrows],
+ &sect2->u.indirect.dir_rows[src_row2],
(sizeof(H5HF_free_section_t *) * nrows_moved2));
/* Re-target the row sections moved from second section */
@@ -3690,13 +3680,13 @@ H5HF_sect_indirect_merge_row(H5HF_hdr_t *hdr, hid_t dxpl_id,
H5HF_free_section_t **new_indir_ents; /* Pointer to new array of indirect entries */
/* Extend the first section's entry array */
- if(NULL == (new_indir_ents = H5MM_realloc(sect1->u.indirect.indir_ents, sizeof(H5HF_free_section_t *) * new_indir_nents1)))
+ if(NULL == (new_indir_ents = (H5HF_free_section_t **)H5MM_realloc(sect1->u.indirect.indir_ents, sizeof(H5HF_free_section_t *) * new_indir_nents1)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "allocation failed for row section pointer array")
sect1->u.indirect.indir_ents = new_indir_ents;
/* Transfer the second section's entries to first section */
- HDmemcpy(&sect1->u.indirect.indir_ents[sect1->u.indirect.indir_nents],
- &sect2->u.indirect.indir_ents[0],
+ HDmemcpy(&sect1->u.indirect.indir_ents[sect1->u.indirect.indir_nents],
+ &sect2->u.indirect.indir_ents[0],
(sizeof(H5HF_free_section_t *) * sect2->u.indirect.indir_nents));
} /* end else */
@@ -3717,7 +3707,7 @@ H5HF_sect_indirect_merge_row(H5HF_hdr_t *hdr, hid_t dxpl_id,
sect1->u.indirect.span_size += sect2->u.indirect.span_size;
/* Make certain we've tracked the first section's dependents correctly */
- HDassert(sect1->u.indirect.rc ==
+ HDassert(sect1->u.indirect.rc ==
(sect1->u.indirect.indir_nents + sect1->u.indirect.dir_nrows));
/* Wrap up, freeing or re-inserting second row section */
@@ -3807,7 +3797,7 @@ H5HF_sect_indirect_build_parent(H5HF_hdr_t *hdr, H5HF_free_section_t *sect)
HDassert(par_iblock);
/* Create parent indirect section */
- if(NULL == (par_sect = H5HF_sect_indirect_new(hdr, sect->sect_info.addr,
+ if(NULL == (par_sect = H5HF_sect_indirect_new(hdr, sect->sect_info.addr,
sect->sect_info.size, par_iblock, par_iblock->block_off,
par_row, par_col, 1)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't create indirect section")
@@ -3818,7 +3808,7 @@ H5HF_sect_indirect_build_parent(H5HF_hdr_t *hdr, H5HF_free_section_t *sect)
/* Allocate space for the child indirect sections */
par_sect->u.indirect.indir_nents = 1;
- if(NULL == (par_sect->u.indirect.indir_ents = H5MM_malloc(sizeof(H5HF_free_section_t *))))
+ if(NULL == (par_sect->u.indirect.indir_ents = (H5HF_free_section_t **)H5MM_malloc(sizeof(H5HF_free_section_t *))))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "allocation failed for indirect section pointer array")
/* Attach sections together */
@@ -3965,7 +3955,7 @@ H5HF_sect_indirect_deserialize(H5HF_hdr_t *hdr, hid_t dxpl_id,
unsigned *des_flags)
{
H5HF_free_section_t *new_sect; /* New indirect section */
- hsize_t iblock_off; /* Indirect block's offset */
+ hsize_t iblock_off; /* Indirect block's offset */
unsigned start_row; /* Indirect section's start row */
unsigned start_col; /* Indirect section's start column */
unsigned nentries; /* Indirect section's number of entries */
@@ -4050,10 +4040,10 @@ H5HF_sect_indirect_free(H5HF_free_section_t *sect)
HDassert(sect);
/* Release the memory for tracking direct rows */
- sect->u.indirect.dir_rows = H5MM_xfree(sect->u.indirect.dir_rows);
+ sect->u.indirect.dir_rows = (H5HF_free_section_t **)H5MM_xfree(sect->u.indirect.dir_rows);
/* Release the memory for tracking indirect entries */
- sect->u.indirect.indir_ents = H5MM_xfree(sect->u.indirect.indir_ents);
+ sect->u.indirect.indir_ents = (H5HF_free_section_t **)H5MM_xfree(sect->u.indirect.indir_ents);
/* Check for live reference to an indirect block */
if(sect->sect_info.state == H5FS_SECT_LIVE) {
@@ -4091,7 +4081,6 @@ H5HF_sect_indirect_valid(const H5HF_hdr_t *hdr, const H5HF_free_section_t *sect)
unsigned start_col; /* Column for first block covered */
unsigned start_entry; /* Entry for first block covered */
unsigned end_row; /* Row for last block covered */
- unsigned end_col; /* Column for last block covered */
unsigned end_entry; /* Entry for last block covered */
unsigned u; /* Local index variable */
@@ -4109,7 +4098,6 @@ H5HF_sect_indirect_valid(const H5HF_hdr_t *hdr, const H5HF_free_section_t *sect)
/* Compute ending entry, column & row */
end_entry = (start_entry + sect->u.indirect.num_entries) - 1;
end_row = end_entry / hdr->man_dtable.cparam.width;
- end_col = end_entry % hdr->man_dtable.cparam.width;
/* Sanity check any direct rows */
if(sect->u.indirect.dir_nrows > 0) {
diff --git a/src/H5HFspace.c b/src/H5HFspace.c
index 77d8b1b..aa419de 100644
--- a/src/H5HFspace.c
+++ b/src/H5HFspace.c
@@ -44,6 +44,8 @@
#define H5HF_FSPACE_SHRINK 80 /* Percent of "normal" size to shrink serialized free space size */
#define H5HF_FSPACE_EXPAND 120 /* Percent of "normal" size to expand serialized free space size */
+#define H5HF_FSPACE_THRHD_DEF 1 /* Default: no alignment threshold */
+#define H5HF_FSPACE_ALIGN_DEF 1 /* Default: no alignment */
/******************/
/* Local Typedefs */
@@ -91,6 +93,11 @@
* koziol@ncsa.uiuc.edu
* May 2 2006
*
+ * Modifications:
+ * Vailin Choi, July 29th, 2008
+ * Pass values of alignment and threshold to FS_create() and FS_open()
+ * for handling alignment.
+ *
*-------------------------------------------------------------------------
*/
herr_t
@@ -114,7 +121,7 @@ H5HF_space_start(H5HF_hdr_t *hdr, hid_t dxpl_id, hbool_t may_create)
if(H5F_addr_defined(hdr->fs_addr)) {
/* Open an existing free space structure for the heap */
if(NULL == (hdr->fspace = H5FS_open(hdr->f, dxpl_id, hdr->fs_addr,
- NELMTS(classes), classes, hdr)))
+ NELMTS(classes), classes, hdr, (hsize_t)H5HF_FSPACE_THRHD_DEF, (hsize_t)H5HF_FSPACE_ALIGN_DEF)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize free space info")
} /* end if */
else {
@@ -131,8 +138,9 @@ H5HF_space_start(H5HF_hdr_t *hdr, hid_t dxpl_id, hbool_t may_create)
/* Create the free space structure for the heap */
if(NULL == (hdr->fspace = H5FS_create(hdr->f, dxpl_id, &hdr->fs_addr,
- &fs_create, NELMTS(classes), classes, hdr)))
+ &fs_create, NELMTS(classes), classes, hdr, (hsize_t)H5HF_FSPACE_THRHD_DEF, (hsize_t)H5HF_FSPACE_ALIGN_DEF)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize free space info")
+ HDassert(H5F_addr_defined(hdr->fs_addr));
} /* end if */
} /* end else */
@@ -351,7 +359,7 @@ H5HF_space_close(H5HF_hdr_t *hdr, hid_t dxpl_id)
hsize_t nsects; /* Number of sections for this heap */
/* Retrieve the number of sections for this heap */
- if(H5FS_get_sect_count(hdr->fspace, &nsects) < 0)
+ if(H5FS_sect_stats(hdr->fspace, NULL, &nsects) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCOUNT, FAIL, "can't query free space section count")
#ifdef QAK
HDfprintf(stderr, "%s: nsects = %Hu\n", FUNC, nsects);
diff --git a/src/H5HFstat.c b/src/H5HFstat.c
index d151b47..2ab5240 100644
--- a/src/H5HFstat.c
+++ b/src/H5HFstat.c
@@ -112,7 +112,7 @@ H5HF_stat_info(const H5HF_t *fh, H5HF_stat_t *stats)
* Function: H5HF_size
*
* Purpose: Retrieve storage info for:
- * 1. fractal heap
+ * 1. fractal heap
* 2. btree storage used by huge objects in fractal heap
* 3. free space storage info
*
@@ -126,9 +126,10 @@ H5HF_stat_info(const H5HF_t *fh, H5HF_stat_t *stats)
herr_t
H5HF_size(const H5HF_t *fh, hid_t dxpl_id, hsize_t *heap_size)
{
- H5HF_hdr_t *hdr; /* Fractal heap header */
- herr_t ret_value = SUCCEED; /* Return value */
- hsize_t meta_size = 0; /* free space storage size */
+ H5HF_hdr_t *hdr; /* Fractal heap header */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
+ hsize_t meta_size = 0; /* free space storage size */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HF_size, FAIL)
@@ -151,35 +152,29 @@ H5HF_size(const H5HF_t *fh, hid_t dxpl_id, hsize_t *heap_size)
if(H5HF_man_iblock_size(hdr->f, dxpl_id, hdr, hdr->man_dtable.table_addr, hdr->man_dtable.curr_root_rows, NULL, 0, heap_size) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to get fractal heap storage info for indirect block")
- /* Get B-tree storage for huge objects in fractal heap */
+ /* Check for B-tree storage of huge objects in fractal heap */
if(H5F_addr_defined(hdr->huge_bt2_addr)) {
- const H5B2_class_t *huge_bt2_class; /* Class for huge v2 B-tree */
-
- /* Determine the class of the huge v2 B-tree */
- if(hdr->huge_ids_direct)
- if(hdr->filter_len > 0)
- huge_bt2_class = H5HF_BT2_FILT_DIR;
- else
- huge_bt2_class = H5HF_BT2_DIR;
- else
- if(hdr->filter_len > 0)
- huge_bt2_class = H5HF_BT2_FILT_INDIR;
- else
- huge_bt2_class = H5HF_BT2_INDIR;
-
- /* Get the B-tree storage for the appropriate class */
- if(H5B2_iterate_size(hdr->f, dxpl_id, huge_bt2_class, hdr->huge_bt2_addr, heap_size) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info")
+ /* Open the huge object index v2 B-tree */
+ if(NULL == (bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr, hdr->f)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' objects")
+
+ /* Get the B-tree storage */
+ if(H5B2_size(bt2, dxpl_id, heap_size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info")
} /* end if */
/* Get storage for free-space tracking info */
if(H5F_addr_defined(hdr->fs_addr)) {
if(H5HF_space_size(hdr, dxpl_id, &meta_size) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't retrieve FS meta storage info")
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve FS meta storage info")
*heap_size += meta_size;
- }
+ } /* end if */
done:
+ /* Release resources */
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for tracking 'huge' objects")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_size() */
diff --git a/src/H5HFtest.c b/src/H5HFtest.c
index ab42735..30adf96 100644
--- a/src/H5HFtest.c
+++ b/src/H5HFtest.c
@@ -124,7 +124,7 @@ H5HF_get_cparam_test(const H5HF_t *fh, H5HF_create_t *cparam)
int
H5HF_cmp_cparam_test(const H5HF_create_t *cparam1, const H5HF_create_t *cparam2)
{
- int ret_value; /* Return value */
+ int ret_value = 0; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cmp_cparam_test)
@@ -133,8 +133,26 @@ H5HF_cmp_cparam_test(const H5HF_create_t *cparam1, const H5HF_create_t *cparam2)
HDassert(cparam2);
/* Compare doubling table parameters */
- if((ret_value = HDmemcmp(&(cparam1->managed), &(cparam2->managed), sizeof(H5HF_dtable_cparam_t))))
- HGOTO_DONE(ret_value)
+ if(cparam1->managed.width < cparam2->managed.width)
+ HGOTO_DONE(-1)
+ else if(cparam1->managed.width > cparam2->managed.width)
+ HGOTO_DONE(1)
+ if(cparam1->managed.start_block_size < cparam2->managed.start_block_size)
+ HGOTO_DONE(-1)
+ else if(cparam1->managed.start_block_size > cparam2->managed.start_block_size)
+ HGOTO_DONE(1)
+ if(cparam1->managed.max_direct_size < cparam2->managed.max_direct_size)
+ HGOTO_DONE(-1)
+ else if(cparam1->managed.max_direct_size > cparam2->managed.max_direct_size)
+ HGOTO_DONE(1)
+ if(cparam1->managed.max_index < cparam2->managed.max_index)
+ HGOTO_DONE(-1)
+ else if(cparam1->managed.max_index > cparam2->managed.max_index)
+ HGOTO_DONE(1)
+ if(cparam1->managed.start_root_rows < cparam2->managed.start_root_rows)
+ HGOTO_DONE(-1)
+ else if(cparam1->managed.start_root_rows > cparam2->managed.start_root_rows)
+ HGOTO_DONE(1)
/* Compare other general parameters for heap */
if(cparam1->max_man_size < cparam2->max_man_size)
diff --git a/src/H5HFtiny.c b/src/H5HFtiny.c
index 5f5b295..ce91bd1 100644
--- a/src/H5HFtiny.c
+++ b/src/H5HFtiny.c
@@ -291,7 +291,7 @@ H5HF_tiny_op_real(H5HF_hdr_t *hdr, const uint8_t *id, H5HF_operator_t op,
HGOTO_ERROR(H5E_HEAP, H5E_CANTOPERATE, FAIL, "application's callback failed")
done:
- FUNC_LEAVE_NOAPI(SUCCEED)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_tiny_op_real() */
diff --git a/src/H5HG.c b/src/H5HG.c
index 2161592..fe3bf11 100644
--- a/src/H5HG.c
+++ b/src/H5HG.c
@@ -37,33 +37,28 @@
* in the collection, and temporal locality.
*/
+/****************/
+/* Module Setup */
+/****************/
+
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
#define H5HG_PACKAGE /*suppress error about including H5HGpkg */
+/***********/
+/* Headers */
+/***********/
#include "H5private.h" /* Generic Functions */
-#include "H5ACprivate.h" /* Metadata cache */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
-#include "H5FLprivate.h" /* Free lists */
#include "H5HGpkg.h" /* Global heaps */
#include "H5MFprivate.h" /* File memory management */
#include "H5MMprivate.h" /* Memory management */
-/* Private macros */
-
-/*
- * Global heap collection version.
- */
-#define H5HG_VERSION 1
-/*
- * All global heap collections are at least this big. This allows us to read
- * most collections with a single read() since we don't have to read a few
- * bytes of header to figure out the size. If the heap is larger than this
- * then a second read gets the rest after we've decoded the header.
- */
-#define H5HG_MINSIZE 4096
+/****************/
+/* Local Macros */
+/****************/
/*
* Limit global heap collections to the some reasonable size. This is
@@ -73,12 +68,6 @@
#define H5HG_MAXSIZE 65536
/*
- * Maximum length of the CWFS list, the list of remembered collections that
- * have free space.
- */
-#define H5HG_NCWFS 16
-
-/*
* The maximum number of links allowed to a global heap object.
*/
#define H5HG_MAXLINK 65535
@@ -88,70 +77,47 @@
*/
#define H5HG_MAXIDX 65535
-/*
- * The size of the collection header, always a multiple of the alignment so
- * that the stuff that follows the header is aligned.
- */
-#define H5HG_SIZEOF_HDR(f) \
- H5HG_ALIGN(4 + /*magic number */ \
- 1 + /*version number */ \
- 3 + /*reserved */ \
- H5F_SIZEOF_SIZE(f)) /*collection size */
-/*
- * The initial guess for the number of messages in a collection. We assume
- * that all objects in that collection are zero length, giving the maximum
- * possible number of objects in the collection. The collection itself has
- * some overhead and each message has some overhead. The `+2' accounts for
- * rounding and for the free space object.
- */
-#define H5HG_NOBJS(f,z) (int)((((z)-H5HG_SIZEOF_HDR(f))/ \
- H5HG_SIZEOF_OBJHDR(f)+2))
+/******************/
+/* Local Typedefs */
+/******************/
-/*
- * Makes a global heap object pointer undefined, or checks whether one is
- * defined.
- */
-#define H5HG_undef(HGP) ((HGP)->idx=0)
-#define H5HG_defined(HGP) ((HGP)->idx!=0)
-/* Private typedefs */
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
-/* PRIVATE PROTOTYPES */
static haddr_t H5HG_create(H5F_t *f, hid_t dxpl_id, size_t size);
-#ifdef NOT_YET
-static void *H5HG_peek(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj);
-#endif /* NOT_YET */
-
-/* Metadata cache callbacks */
-static H5HG_heap_t *H5HG_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1,
- void *udata2);
-static herr_t H5HG_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr,
- H5HG_heap_t *heap, unsigned UNUSED * flags_ptr);
-static herr_t H5HG_dest(H5F_t *f, H5HG_heap_t *heap);
-static herr_t H5HG_clear(H5F_t *f, H5HG_heap_t *heap, hbool_t destroy);
-static herr_t H5HG_compute_size(const H5F_t *f, const H5HG_heap_t *heap, size_t *size_ptr);
-/*
- * H5HG inherits cache-like properties from H5AC
- */
-const H5AC_class_t H5AC_GHEAP[1] = {{
- H5AC_GHEAP_ID,
- (H5AC_load_func_t)H5HG_load,
- (H5AC_flush_func_t)H5HG_flush,
- (H5AC_dest_func_t)H5HG_dest,
- (H5AC_clear_func_t)H5HG_clear,
- (H5AC_size_func_t)H5HG_compute_size,
-}};
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
/* Declare a free list to manage the H5HG_t struct */
-H5FL_DEFINE_STATIC(H5HG_heap_t);
+H5FL_DEFINE(H5HG_heap_t);
/* Declare a free list to manage sequences of H5HG_obj_t's */
-H5FL_SEQ_DEFINE_STATIC(H5HG_obj_t);
+H5FL_SEQ_DEFINE(H5HG_obj_t);
/* Declare a PQ free list to manage heap chunks */
-H5FL_BLK_DEFINE_STATIC(heap_chunk);
+H5FL_BLK_DEFINE(gheap_chunk);
+
/*-------------------------------------------------------------------------
@@ -220,21 +186,19 @@ H5HG_create (H5F_t *f, hid_t dxpl_id, size_t size)
heap->addr = addr;
heap->size = size;
- if (NULL==(heap->chunk = H5FL_BLK_MALLOC (heap_chunk,size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, \
- "memory allocation failed");
+ if(NULL == (heap->chunk = H5FL_BLK_MALLOC(gheap_chunk, size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "memory allocation failed")
#ifdef H5_CLEAR_MEMORY
HDmemset(heap->chunk, 0, size);
#endif /* H5_CLEAR_MEMORY */
- heap->nalloc = H5HG_NOBJS (f, size);
+ heap->nalloc = H5HG_NOBJS(f, size);
heap->nused = 1; /* account for index 0, which is used for the free object */
- if (NULL==(heap->obj = H5FL_SEQ_MALLOC (H5HG_obj_t,heap->nalloc)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, \
- "memory allocation failed");
+ if(NULL == (heap->obj = H5FL_SEQ_MALLOC(H5HG_obj_t, heap->nalloc)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "memory allocation failed")
/* Initialize the header */
- HDmemcpy (heap->chunk, H5HG_MAGIC, (size_t)H5HG_SIZEOF_MAGIC);
- p = heap->chunk + H5HG_SIZEOF_MAGIC;
+ HDmemcpy(heap->chunk, H5HG_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p = heap->chunk + H5_SIZEOF_MAGIC;
*p++ = H5HG_VERSION;
*p++ = 0; /*reserved*/
*p++ = 0; /*reserved*/
@@ -268,22 +232,22 @@ HDmemset(heap->chunk, 0, size);
#endif /* OLD_WAY */
/* Add this heap to the beginning of the CWFS list */
- if (NULL==f->shared->cwfs) {
- f->shared->cwfs = H5MM_malloc (H5HG_NCWFS * sizeof(H5HG_heap_t*));
- if (NULL==(f->shared->cwfs))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, \
- "memory allocation failed");
+ if(NULL == f->shared->cwfs) {
+ f->shared->cwfs = (H5HG_heap_t **)H5MM_malloc(H5HG_NCWFS * sizeof(H5HG_heap_t *));
+ if(NULL == (f->shared->cwfs))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "memory allocation failed")
f->shared->cwfs[0] = heap;
f->shared->ncwfs = 1;
- } else {
- HDmemmove (f->shared->cwfs+1, f->shared->cwfs,
- MIN (f->shared->ncwfs, H5HG_NCWFS-1)*sizeof(H5HG_heap_t*));
+ } /* end if */
+ else {
+ HDmemmove(f->shared->cwfs + 1, f->shared->cwfs,
+ MIN(f->shared->ncwfs, H5HG_NCWFS - 1) * sizeof(H5HG_heap_t *));
f->shared->cwfs[0] = heap;
- f->shared->ncwfs = MIN (H5HG_NCWFS, f->shared->ncwfs+1);
+ f->shared->ncwfs = MIN(H5HG_NCWFS, f->shared->ncwfs+1);
}
/* Add the heap to the cache */
- if(H5AC_set(f, dxpl_id, H5AC_GHEAP, addr, heap, H5AC__NO_FLAGS_SET)<0)
+ if(H5AC_set(f, dxpl_id, H5AC_GHEAP, addr, heap, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "unable to cache global heap collection")
ret_value = addr;
@@ -298,361 +262,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5HG_load
- *
- * Purpose: Loads a global heap collection from disk.
- *
- * Return: Success: Ptr to a global heap collection.
- *
- * Failure: NULL
- *
- * Programmer: Robb Matzke
- * Friday, March 27, 1998
- *
- * Modifications:
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
- *
- * Quincey Koziol, 2002-7-180
- * Added dxpl parameter to allow more control over I/O from metadata
- * cache.
- *-------------------------------------------------------------------------
- */
-static H5HG_heap_t *
-H5HG_load (H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1,
- void UNUSED * udata2)
-{
- H5HG_heap_t *heap = NULL;
- uint8_t *p = NULL;
- int i;
- size_t nalloc, need;
- size_t max_idx=0; /* The maximum index seen */
- H5HG_heap_t *ret_value = NULL; /* Return value */
-
- FUNC_ENTER_NOAPI(H5HG_load, NULL);
-
- /* check arguments */
- assert (f);
- assert (H5F_addr_defined (addr));
- assert (!udata1);
- assert (!udata2);
-
- /* Read the initial 4k page */
- if(NULL == (heap = H5FL_CALLOC (H5HG_heap_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- heap->addr = addr;
- if(NULL == (heap->chunk = H5FL_BLK_MALLOC(heap_chunk, (size_t)H5HG_MINSIZE)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- if(H5F_block_read(f, H5FD_MEM_GHEAP, addr, (size_t)H5HG_MINSIZE, dxpl_id, heap->chunk)<0)
- HGOTO_ERROR (H5E_HEAP, H5E_READERROR, NULL, "unable to read global heap collection");
-
- /* Magic number */
- if(HDmemcmp(heap->chunk, H5HG_MAGIC, (size_t)H5HG_SIZEOF_MAGIC))
- HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, "bad global heap collection signature");
- p = heap->chunk + H5HG_SIZEOF_MAGIC;
-
- /* Version */
- if (H5HG_VERSION!=*p++)
- HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, "wrong version number in global heap");
-
- /* Reserved */
- p += 3;
-
- /* Size */
- H5F_DECODE_LENGTH (f, p, heap->size);
- assert (heap->size>=H5HG_MINSIZE);
-
- /*
- * If we didn't read enough in the first try, then read the rest of the
- * collection now.
- */
- if (heap->size > H5HG_MINSIZE) {
- haddr_t next_addr = addr + (hsize_t)H5HG_MINSIZE;
- if (NULL==(heap->chunk = H5FL_BLK_REALLOC (heap_chunk, heap->chunk, heap->size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- if (H5F_block_read (f, H5FD_MEM_GHEAP, next_addr, (heap->size-H5HG_MINSIZE), dxpl_id, heap->chunk+H5HG_MINSIZE)<0)
- HGOTO_ERROR (H5E_HEAP, H5E_READERROR, NULL, "unable to read global heap collection");
- }
-
- /* Decode each object */
- p = heap->chunk + H5HG_SIZEOF_HDR (f);
- nalloc = H5HG_NOBJS (f, heap->size);
- if (NULL==(heap->obj = H5FL_SEQ_MALLOC (H5HG_obj_t,nalloc)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- heap->obj[0].size=heap->obj[0].nrefs=0;
- heap->obj[0].begin=NULL;
-
- heap->nalloc = nalloc;
- while (p<heap->chunk+heap->size) {
- if (p+H5HG_SIZEOF_OBJHDR(f)>heap->chunk+heap->size) {
- /*
- * The last bit of space is too tiny for an object header, so we
- * assume that it's free space.
- */
- assert (NULL==heap->obj[0].begin);
- heap->obj[0].size = (heap->chunk+heap->size) - p;
- heap->obj[0].begin = p;
- p += heap->obj[0].size;
- } else {
- unsigned idx;
- uint8_t *begin = p;
-
- UINT16DECODE (p, idx);
-
- /* Check if we need more room to store heap objects */
- if(idx>=heap->nalloc) {
- size_t new_alloc; /* New allocation number */
- H5HG_obj_t *new_obj; /* New array of object descriptions */
-
- /* Determine the new number of objects to index */
- new_alloc=MAX(heap->nalloc*2,(idx+1));
-
- /* Reallocate array of objects */
- if (NULL==(new_obj = H5FL_SEQ_REALLOC (H5HG_obj_t, heap->obj, new_alloc)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
-
- /* Update heap information */
- heap->nalloc=new_alloc;
- heap->obj=new_obj;
- } /* end if */
-
- UINT16DECODE (p, heap->obj[idx].nrefs);
- p += 4; /*reserved*/
- H5F_DECODE_LENGTH (f, p, heap->obj[idx].size);
- heap->obj[idx].begin = begin;
- /*
- * The total storage size includes the size of the object header
- * and is zero padded so the next object header is properly
- * aligned. The last bit of space is the free space object whose
- * size is never padded and already includes the object header.
- */
- if (idx>0) {
- need = H5HG_SIZEOF_OBJHDR(f) + H5HG_ALIGN(heap->obj[idx].size);
-
- /* Check for "gap" in index numbers (caused by deletions) and fill in heap object values */
- if(idx>(max_idx+1))
- HDmemset(&heap->obj[max_idx+1],0,sizeof(H5HG_obj_t)*(idx-(max_idx+1)));
- max_idx=idx;
- } else {
- need = heap->obj[idx].size;
- }
- p = begin + need;
- }
- }
- assert(p==heap->chunk+heap->size);
- assert(H5HG_ISALIGNED(heap->obj[0].size));
-
- /* Set the next index value to use */
- if(max_idx>0)
- heap->nused=max_idx+1;
- else
- heap->nused=1;
-
- /*
- * Add the new heap to the CWFS list, removing some other entry if
- * necessary to make room. We remove the right-most entry that has less
- * free space than this heap.
- */
- if (!f->shared->cwfs) {
- f->shared->cwfs = H5MM_malloc (H5HG_NCWFS*sizeof(H5HG_heap_t*));
- if (NULL==f->shared->cwfs)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- f->shared->ncwfs = 1;
- f->shared->cwfs[0] = heap;
- } else if (H5HG_NCWFS==f->shared->ncwfs) {
- for (i=H5HG_NCWFS-1; i>=0; --i) {
- if (f->shared->cwfs[i]->obj[0].size < heap->obj[0].size) {
- HDmemmove (f->shared->cwfs+1, f->shared->cwfs, i * sizeof(H5HG_heap_t*));
- f->shared->cwfs[0] = heap;
- break;
- }
- }
- } else {
- HDmemmove (f->shared->cwfs+1, f->shared->cwfs, f->shared->ncwfs*sizeof(H5HG_heap_t*));
- f->shared->ncwfs += 1;
- f->shared->cwfs[0] = heap;
- }
-
- ret_value = heap;
-
-done:
- if (!ret_value && heap) {
- if(H5HG_dest(f,heap)<0)
- HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, NULL, "unable to destroy global heap collection");
- }
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5HG_flush
- *
- * Purpose: Flushes a global heap collection from memory to disk if it's
- * dirty. Optionally deletes teh heap from memory.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * Friday, March 27, 1998
- *
- * Modifications:
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
- *
- * Quincey Koziol, 2002-7-180
- * Added dxpl parameter to allow more control over I/O from metadata
- * cache.
- *
- * JRM -- 8/21/06
- * Added the flags_ptr parameter. This parameter exists to
- * allow the flush routine to report to the cache if the
- * entry is resized or renamed as a result of the flush.
- * *flags_ptr is set to H5C_CALLBACK__NO_FLAGS_SET on entry.
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5HG_flush (H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HG_heap_t *heap, unsigned UNUSED * flags_ptr)
-{
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5HG_flush, FAIL);
-
- /* Check arguments */
- assert (f);
- assert (H5F_addr_defined (addr));
- assert (H5F_addr_eq (addr, heap->addr));
- assert (heap);
-
- if (heap->cache_info.is_dirty) {
- if (H5F_block_write (f, H5FD_MEM_GHEAP, addr, heap->size, dxpl_id, heap->chunk)<0)
- HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write global heap collection to file");
- heap->cache_info.is_dirty = FALSE;
- }
-
- if (destroy) {
- if(H5HG_dest(f,heap)<0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy global heap collection");
- }
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5HG_dest
- *
- * Purpose: Destroys a global heap collection in memory
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Wednesday, January 15, 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5HG_dest (H5F_t *f, H5HG_heap_t *heap)
-{
- int i;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HG_dest);
-
- /* Check arguments */
- assert (heap);
-
- /* Verify that node is clean */
- assert (heap->cache_info.is_dirty==FALSE);
-
- for (i=0; i<f->shared->ncwfs; i++) {
- if (f->shared->cwfs[i]==heap) {
- f->shared->ncwfs -= 1;
- HDmemmove (f->shared->cwfs+i, f->shared->cwfs+i+1, (f->shared->ncwfs-i) * sizeof(H5HG_heap_t*));
- break;
- }
- }
-
- if(heap->chunk)
- heap->chunk = H5FL_BLK_FREE(heap_chunk,heap->chunk);
- if(heap->obj)
- heap->obj = H5FL_SEQ_FREE(H5HG_obj_t,heap->obj);
- H5FL_FREE (H5HG_heap_t,heap);
-
- FUNC_LEAVE_NOAPI(SUCCEED);
-} /* H5HG_dest() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5HG_clear
- *
- * Purpose: Mark a global heap in memory as non-dirty.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Thursday, March 20, 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5HG_clear(H5F_t *f, H5HG_heap_t *heap, hbool_t destroy)
-{
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI_NOINIT(H5HG_clear);
-
- /* Check arguments */
- assert (heap);
-
- /* Mark heap as clean */
- heap->cache_info.is_dirty = FALSE;
-
- if (destroy)
- if (H5HG_dest(f, heap) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy global heap collection");
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-} /* H5HG_clear() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5HG_compute_size
- *
- * Purpose: Compute the size in bytes of the specified instance of
- * H5HG_heap_t on disk, and return it in *len_ptr. On failure,
- * the value of *len_ptr is undefined.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: John Mainzer
- * 5/13/04
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5HG_compute_size(const H5F_t UNUSED *f, const H5HG_heap_t *heap, size_t *size_ptr)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HG_compute_size);
-
- /* Check arguments */
- HDassert(heap);
- HDassert(size_ptr);
-
- *size_ptr = heap->size;
-
- FUNC_LEAVE_NOAPI(SUCCEED);
-} /* H5HG_compute_size() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5HG_alloc
*
* Purpose: Given a heap with enough free space, this function will split
@@ -699,7 +308,7 @@ H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, size_t size, unsigned * heap_flags_ptr)
* Find an ID for the new object. ID zero is reserved for the free space
* object.
*/
- if(heap->nused<H5HG_MAXIDX)
+ if(heap->nused<=H5HG_MAXIDX)
idx=heap->nused++;
else {
for (idx=1; idx<heap->nused; idx++)
@@ -707,23 +316,29 @@ H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, size_t size, unsigned * heap_flags_ptr)
break;
} /* end else */
+ HDassert(idx < heap->nused);
+
/* Check if we need more room to store heap objects */
if(idx>=heap->nalloc) {
size_t new_alloc; /* New allocation number */
H5HG_obj_t *new_obj; /* New array of object descriptions */
/* Determine the new number of objects to index */
- new_alloc=MAX(heap->nalloc*2,(idx+1));
- assert(new_alloc<=(H5HG_MAXIDX+1));
+ /* nalloc is *not* guaranteed to be a power of 2! - NAF 10/26/09 */
+ new_alloc = MIN(MAX(heap->nalloc * 2, (idx + 1)), (H5HG_MAXIDX + 1));
+ HDassert(idx < new_alloc);
/* Reallocate array of objects */
if (NULL==(new_obj = H5FL_SEQ_REALLOC (H5HG_obj_t, heap->obj, new_alloc)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed");
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed")
+
+ /* Clear newly allocated space */
+ HDmemset(&new_obj[heap->nalloc], 0, (new_alloc - heap->nalloc) * sizeof(heap->obj[0]));
/* Update heap information */
heap->nalloc=new_alloc;
heap->obj=new_obj;
- assert(heap->nalloc>heap->nused);
+ HDassert(heap->nalloc>heap->nused);
} /* end if */
/* Initialize the new object */
@@ -807,75 +422,60 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5HG_extend (H5F_t *f, H5HG_heap_t *heap, size_t size, unsigned * heap_flags_ptr)
+H5HG_extend(H5F_t *f, H5HG_heap_t *heap, size_t need, unsigned *heap_flags_ptr)
{
- size_t need; /* Actual space needed to store object */
size_t old_size; /* Previous size of the heap's chunk */
- uint8_t *new_chunk=NULL; /* Pointer to new chunk information */
+ uint8_t *new_chunk = NULL; /* Pointer to new chunk information */
uint8_t *p = NULL; /* Pointer to raw heap info */
unsigned u; /* Local index variable */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5HG_extend);
+ FUNC_ENTER_NOAPI_NOINIT(H5HG_extend)
/* Check args */
- assert (f);
- assert (heap);
- assert (heap_flags_ptr);
-
- /* Compute total space need to add to this heap */
- need = H5HG_SIZEOF_OBJHDR(f) + H5HG_ALIGN(size);
-
- /* Decrement the amount needed in the heap by the amount of free space available */
- assert(need>heap->obj[0].size);
- need -= heap->obj[0].size;
-
- /* Don't do anything less than double the size of the heap */
- need = MAX(heap->size,need);
-
- /* Extend the space allocated for this heap on disk */
- if(H5MF_extend(f,H5FD_MEM_GHEAP,heap->addr,(hsize_t)heap->size,(hsize_t)need)<0)
- HGOTO_ERROR (H5E_HEAP, H5E_NOSPACE, FAIL, "can't extend heap on disk");
+ HDassert(f);
+ HDassert(heap);
+ HDassert(heap_flags_ptr);
/* Re-allocate the heap information in memory */
- if (NULL==(new_chunk = H5FL_BLK_REALLOC (heap_chunk, heap->chunk, heap->size+need)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "new heap allocation failed");
+ if(NULL == (new_chunk = H5FL_BLK_REALLOC(gheap_chunk, heap->chunk, (heap->size + need))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "new heap allocation failed")
#ifdef H5_CLEAR_MEMORY
HDmemset(new_chunk + heap->size, 0, need);
#endif /* H5_CLEAR_MEMORY */
/* Adjust the size of the heap */
- old_size=heap->size;
- heap->size+=need;
+ old_size = heap->size;
+ heap->size += need;
/* Encode the new size of the heap */
- p = new_chunk + H5HG_SIZEOF_MAGIC + 1 /* version */ + 3 /* reserved */;
- H5F_ENCODE_LENGTH (f, p, heap->size);
+ p = new_chunk + H5_SIZEOF_MAGIC + 1 /* version */ + 3 /* reserved */;
+ H5F_ENCODE_LENGTH(f, p, heap->size);
/* Move the pointers to the existing objects to their new locations */
- for (u=0; u<heap->nused; u++)
+ for(u = 0; u < heap->nused; u++)
if(heap->obj[u].begin)
heap->obj[u].begin = new_chunk + (heap->obj[u].begin - heap->chunk);
/* Update the heap chunk pointer now */
- heap->chunk=new_chunk;
+ heap->chunk = new_chunk;
/* Update the free space information for the heap */
- heap->obj[0].size+=need;
- if(heap->obj[0].begin==NULL)
- heap->obj[0].begin=heap->chunk+old_size;
+ heap->obj[0].size += need;
+ if(heap->obj[0].begin == NULL)
+ heap->obj[0].begin = heap->chunk+old_size;
p = heap->obj[0].begin;
UINT16ENCODE(p, 0); /*id*/
UINT16ENCODE(p, 0); /*nrefs*/
UINT32ENCODE(p, 0); /*reserved*/
- H5F_ENCODE_LENGTH (f, p, heap->obj[0].size);
+ H5F_ENCODE_LENGTH(f, p, heap->obj[0].size);
assert(H5HG_ISALIGNED(heap->obj[0].size));
/* Mark the heap as dirty */
*heap_flags_ptr |= H5AC__DIRTIED_FLAG;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HG_extend() */
@@ -926,26 +526,26 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5HG_insert (H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*/)
+H5HG_insert(H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*/)
{
size_t need; /*total space needed for object */
- int cwfsno;
+ int cwfsno;
size_t idx;
haddr_t addr = HADDR_UNDEF;
H5HG_heap_t *heap = NULL;
unsigned heap_flags = H5AC__NO_FLAGS_SET;
- hbool_t found=0; /* Flag to indicate a heap with enough space was found */
- herr_t ret_value=SUCCEED; /* Return value */
+ hbool_t found = FALSE; /* Flag to indicate a heap with enough space was found */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5HG_insert, FAIL);
+ FUNC_ENTER_NOAPI(H5HG_insert, FAIL)
/* Check args */
- assert (f);
- assert (0==size || obj);
- assert (hobj);
+ HDassert(f);
+ HDassert(0 == size || obj);
+ HDassert(hobj);
- if (0==(f->intent & H5F_ACC_RDWR))
- HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file");
+ if(0 == (f->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file")
/* Find a large enough collection on the CWFS list */
need = H5HG_SIZEOF_OBJHDR(f) + H5HG_ALIGN(size);
@@ -974,20 +574,18 @@ H5HG_insert (H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*
* take any of it as gospel.
* JRM - 5/24/04
*/
-
- for (cwfsno=0; cwfsno<f->shared->ncwfs; cwfsno++) {
- if (f->shared->cwfs[cwfsno]->obj[0].size>=need) {
+ for(cwfsno = 0; cwfsno < f->shared->ncwfs; cwfsno++)
+ if(f->shared->cwfs[cwfsno]->obj[0].size >= need) {
addr = f->shared->cwfs[cwfsno]->addr;
- found=1;
+ found = TRUE;
break;
} /* end if */
- } /* end for */
/*
* If we didn't find any collection with enough free space the check if
* we can extend any of the collections to make enough room.
*/
- if (!found) {
+ if(!found) {
size_t new_need;
for (cwfsno=0; cwfsno<f->shared->ncwfs; cwfsno++) {
@@ -995,12 +593,19 @@ H5HG_insert (H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*
new_need -= f->shared->cwfs[cwfsno]->obj[0].size;
new_need = MAX(f->shared->cwfs[cwfsno]->size, new_need);
- if((f->shared->cwfs[cwfsno]->size+new_need)<=H5HG_MAXSIZE && H5MF_can_extend(f,H5FD_MEM_GHEAP,f->shared->cwfs[cwfsno]->addr,(hsize_t)f->shared->cwfs[cwfsno]->size,(hsize_t)new_need)) {
- if(H5HG_extend(f,f->shared->cwfs[cwfsno],size, &heap_flags)<0)
- HGOTO_ERROR (H5E_HEAP, H5E_CANTINIT, FAIL, "unable to extend global heap collection");
- addr = f->shared->cwfs[cwfsno]->addr;
- found=1;
- break;
+ if((f->shared->cwfs[cwfsno]->size + new_need) <= H5HG_MAXSIZE) {
+ htri_t extended; /* Whether the heap was extended */
+
+ extended = H5MF_try_extend(f, dxpl_id, H5FD_MEM_GHEAP, f->shared->cwfs[cwfsno]->addr, (hsize_t)f->shared->cwfs[cwfsno]->size, (hsize_t)new_need);
+ if(extended < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTEXTEND, FAIL, "error trying to extend heap")
+ else if(extended == TRUE) {
+ if(H5HG_extend(f, f->shared->cwfs[cwfsno], new_need, &heap_flags) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "unable to extend global heap collection")
+ addr = f->shared->cwfs[cwfsno]->addr;
+ found = TRUE;
+ break;
+ } /* end if */
} /* end if */
} /* end for */
} /* end if */
@@ -1009,43 +614,40 @@ H5HG_insert (H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*
* If we didn't find any collection with enough free space then allocate a
* new collection large enough for the message plus the collection header.
*/
- if (!found) {
-
+ if(!found) {
addr = H5HG_create(f, dxpl_id, need+H5HG_SIZEOF_HDR (f));
- if ( ! H5F_addr_defined(addr) )
- HGOTO_ERROR (H5E_HEAP, H5E_CANTINIT, FAIL, \
- "unable to allocate a global heap collection");
+ if(!H5F_addr_defined(addr))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "unable to allocate a global heap collection")
cwfsno = 0;
} /* end if */
else {
-
/* Move the collection forward in the CWFS list, if it's not
* already at the front
*/
- if (cwfsno>0) {
+ if(cwfsno > 0) {
H5HG_heap_t *tmp = f->shared->cwfs[cwfsno];
- f->shared->cwfs[cwfsno] = f->shared->cwfs[cwfsno-1];
- f->shared->cwfs[cwfsno-1] = tmp;
+
+ f->shared->cwfs[cwfsno] = f->shared->cwfs[cwfsno - 1];
+ f->shared->cwfs[cwfsno - 1] = tmp;
--cwfsno;
} /* end if */
} /* end else */
HDassert(H5F_addr_defined(addr));
-
- if(NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_GHEAP, addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (heap = (H5HG_heap_t *)H5AC_protect(f, dxpl_id, H5AC_GHEAP, addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap")
/* Split the free space to make room for the new object */
- idx = H5HG_alloc (f, heap, size, &heap_flags);
+ idx = H5HG_alloc(f, heap, size, &heap_flags);
/* Copy data into the heap */
- if(size>0) {
- HDmemcpy(heap->obj[idx].begin+H5HG_SIZEOF_OBJHDR(f), obj, size);
+ if(size > 0) {
+ HDmemcpy(heap->obj[idx].begin + H5HG_SIZEOF_OBJHDR(f), obj, size);
#ifdef OLD_WAY
/* Don't bother zeroing out the rest of the info in the heap -QAK */
- HDmemset(heap->obj[idx].begin+H5HG_SIZEOF_OBJHDR(f)+size, 0,
- need-(H5HG_SIZEOF_OBJHDR(f)+size));
+ HDmemset(heap->obj[idx].begin + H5HG_SIZEOF_OBJHDR(f) + size, 0,
+ need - (H5HG_SIZEOF_OBJHDR(f) + size));
#endif /* OLD_WAY */
} /* end if */
heap_flags |= H5AC__DIRTIED_FLAG;
@@ -1058,7 +660,7 @@ done:
if(heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, heap->addr, heap, heap_flags) < 0)
HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to unprotect heap.")
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5HG_insert() */
@@ -1077,13 +679,6 @@ done:
* Programmer: Robb Matzke
* Monday, March 30, 1998
*
- * Modifications:
- *
- * John Mainzer, 6/8/05
- * Modified the function to use the new dirtied parameter of
- * of H5AC_unprotect() instead of modifying the is_dirty
- * field of the cache info.
- *
*-------------------------------------------------------------------------
*/
void *
@@ -1102,7 +697,7 @@ H5HG_read(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object/*out*/,
HDassert(hobj);
/* Load the heap */
- if(NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_GHEAP, hobj->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (heap = (H5HG_heap_t *)H5AC_protect(f, dxpl_id, H5AC_GHEAP, hobj->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap")
HDassert(hobj->idx < heap->nused);
@@ -1184,19 +779,19 @@ H5HG_link (H5F_t *f, hid_t dxpl_id, const H5HG_t *hobj, int adjust)
assert (f);
assert (hobj);
if (0==(f->intent & H5F_ACC_RDWR))
- HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file");
+ HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file")
if(adjust!=0) {
/* Load the heap */
- if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_GHEAP, hobj->addr, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap");
+ if (NULL == (heap = (H5HG_heap_t *)H5AC_protect(f, dxpl_id, H5AC_GHEAP, hobj->addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap")
assert (hobj->idx<heap->nused);
assert (heap->obj[hobj->idx].begin);
if (heap->obj[hobj->idx].nrefs+adjust<0)
- HGOTO_ERROR (H5E_HEAP, H5E_BADRANGE, FAIL, "new link count would be out of range");
+ HGOTO_ERROR (H5E_HEAP, H5E_BADRANGE, FAIL, "new link count would be out of range")
if (heap->obj[hobj->idx].nrefs+adjust>H5HG_MAXLINK)
- HGOTO_ERROR (H5E_HEAP, H5E_BADVALUE, FAIL, "new link count would be out of range");
+ HGOTO_ERROR (H5E_HEAP, H5E_BADVALUE, FAIL, "new link count would be out of range")
heap->obj[hobj->idx].nrefs += adjust;
heap_flags |= H5AC__DIRTIED_FLAG;
} /* end if */
@@ -1206,7 +801,7 @@ H5HG_link (H5F_t *f, hid_t dxpl_id, const H5HG_t *hobj, int adjust)
done:
if(heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, hobj->addr, heap, heap_flags) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release object header");
+ HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release object header")
FUNC_LEAVE_NOAPI(ret_value);
}
@@ -1234,88 +829,88 @@ done:
herr_t
H5HG_remove (H5F_t *f, hid_t dxpl_id, H5HG_t *hobj)
{
- uint8_t *p=NULL, *obj_start=NULL;
H5HG_heap_t *heap = NULL;
+ uint8_t *p = NULL, *obj_start = NULL;
size_t need;
- int i;
unsigned u;
- unsigned flags=H5AC__NO_FLAGS_SET;/* Whether the heap gets deleted */
- herr_t ret_value=SUCCEED; /* Return value */
+ unsigned flags = H5AC__NO_FLAGS_SET;/* Whether the heap gets deleted */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HG_remove, FAIL);
/* Check args */
- assert (f);
- assert (hobj);
- if (0==(f->intent & H5F_ACC_RDWR))
- HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file");
+ HDassert(f);
+ HDassert(hobj);
+ if(0 == (f->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file")
/* Load the heap */
- if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_GHEAP, hobj->addr, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap");
+ if(NULL == (heap = (H5HG_heap_t *)H5AC_protect(f, dxpl_id, H5AC_GHEAP, hobj->addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap")
- assert (hobj->idx<heap->nused);
- assert (heap->obj[hobj->idx].begin);
+ HDassert(hobj->idx < heap->nused);
+ HDassert(heap->obj[hobj->idx].begin);
obj_start = heap->obj[hobj->idx].begin;
/* Include object header size */
- need = H5HG_ALIGN(heap->obj[hobj->idx].size)+H5HG_SIZEOF_OBJHDR(f);
+ need = H5HG_ALIGN(heap->obj[hobj->idx].size) + H5HG_SIZEOF_OBJHDR(f);
/* Move the new free space to the end of the heap */
- for (u=0; u<heap->nused; u++) {
- if (heap->obj[u].begin > heap->obj[hobj->idx].begin)
+ for(u = 0; u < heap->nused; u++)
+ if(heap->obj[u].begin > heap->obj[hobj->idx].begin)
heap->obj[u].begin -= need;
- }
- if (NULL==heap->obj[0].begin) {
- heap->obj[0].begin = heap->chunk + (heap->size-need);
+ if(NULL == heap->obj[0].begin) {
+ heap->obj[0].begin = heap->chunk + (heap->size - need);
heap->obj[0].size = need;
heap->obj[0].nrefs = 0;
- } else {
+ } /* end if */
+ else
heap->obj[0].size += need;
- }
- HDmemmove (obj_start, obj_start+need,
- heap->size-((obj_start+need)-heap->chunk));
- if (heap->obj[0].size>=H5HG_SIZEOF_OBJHDR (f)) {
+ HDmemmove(obj_start, obj_start + need,
+ heap->size - ((obj_start + need) - heap->chunk));
+ if(heap->obj[0].size >= H5HG_SIZEOF_OBJHDR(f)) {
p = heap->obj[0].begin;
UINT16ENCODE(p, 0); /*id*/
UINT16ENCODE(p, 0); /*nrefs*/
UINT32ENCODE(p, 0); /*reserved*/
H5F_ENCODE_LENGTH (f, p, heap->obj[0].size);
- }
- HDmemset (heap->obj+hobj->idx, 0, sizeof(H5HG_obj_t));
+ } /* end if */
+ HDmemset(heap->obj + hobj->idx, 0, sizeof(H5HG_obj_t));
flags |= H5AC__DIRTIED_FLAG;
- if (heap->obj[0].size+H5HG_SIZEOF_HDR(f)==heap->size) {
+ if((heap->obj[0].size + H5HG_SIZEOF_HDR(f)) == heap->size) {
/*
* The collection is empty. Remove it from the CWFS list and return it
* to the file free list.
*/
- H5_CHECK_OVERFLOW(heap->size,size_t,hsize_t);
- H5MF_xfree(f, H5FD_MEM_GHEAP, dxpl_id, heap->addr, (hsize_t)heap->size);
- flags |= H5C__DELETED_FLAG; /* Indicate that the object was deleted, for the unprotect call */
- } else {
+ H5_CHECK_OVERFLOW(heap->size, size_t, hsize_t);
+ flags |= H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG; /* Indicate that the object was deleted, for the unprotect call */
+ } /* end if */
+ else {
+ int i; /* Local index variable */
+
/*
* If the heap is in the CWFS list then advance it one position. The
* H5AC_protect() might have done that too, but that's okay. If the
* heap isn't on the CWFS list then add it to the end.
*/
- for (i=0; i<f->shared->ncwfs; i++) {
- if (f->shared->cwfs[i]==heap) {
- if (i) {
- f->shared->cwfs[i] = f->shared->cwfs[i-1];
- f->shared->cwfs[i-1] = heap;
- }
+ for(i = 0; i < f->shared->ncwfs; i++)
+ if(f->shared->cwfs[i] == heap) {
+ if(i) {
+ f->shared->cwfs[i] = f->shared->cwfs[i - 1];
+ f->shared->cwfs[i - 1] = heap;
+ } /* end if */
break;
- }
- }
- if (i>=f->shared->ncwfs) {
- f->shared->ncwfs = MIN (f->shared->ncwfs+1, H5HG_NCWFS);
- f->shared->cwfs[f->shared->ncwfs-1] = heap;
- }
- }
+ } /* end if */
+ if(i >= f->shared->ncwfs) {
+ f->shared->ncwfs = MIN(f->shared->ncwfs + 1, H5HG_NCWFS);
+ f->shared->cwfs[f->shared->ncwfs - 1] = heap;
+ } /* end if */
+ } /* end else */
done:
- if (heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, hobj->addr, heap, flags) != SUCCEED)
- HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release object header");
+ if(heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, hobj->addr, heap, flags) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release object header")
FUNC_LEAVE_NOAPI(ret_value);
-}
+} /* end H5HG_remove() */
+
diff --git a/src/H5HGcache.c b/src/H5HGcache.c
new file mode 100644
index 0000000..ee318aa
--- /dev/null
+++ b/src/H5HGcache.c
@@ -0,0 +1,452 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5HGcache.c
+ * Feb 5 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Implement global heap metadata cache methods.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+#define H5HG_PACKAGE /*suppress error about including H5HGpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5HGpkg.h" /* Global heaps */
+#include "H5MFprivate.h" /* File memory management */
+#include "H5MMprivate.h" /* Memory management */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* Metadata cache callbacks */
+static H5HG_heap_t *H5HG_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1,
+ void *udata2);
+static herr_t H5HG_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr,
+ H5HG_heap_t *heap, unsigned UNUSED * flags_ptr);
+static herr_t H5HG_clear(H5F_t *f, H5HG_heap_t *heap, hbool_t destroy);
+static herr_t H5HG_size(const H5F_t *f, const H5HG_heap_t *heap, size_t *size_ptr);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* H5HG inherits cache-like properties from H5AC */
+const H5AC_class_t H5AC_GHEAP[1] = {{
+ H5AC_GHEAP_ID,
+ (H5AC_load_func_t)H5HG_load,
+ (H5AC_flush_func_t)H5HG_flush,
+ (H5AC_dest_func_t)H5HG_dest,
+ (H5AC_clear_func_t)H5HG_clear,
+ (H5AC_notify_func_t)NULL,
+ (H5AC_size_func_t)H5HG_size,
+}};
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HG_load
+ *
+ * Purpose: Loads a global heap collection from disk.
+ *
+ * Return: Success: Ptr to a global heap collection.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Friday, March 27, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5HG_heap_t *
+H5HG_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1,
+ void UNUSED * udata2)
+{
+ H5HG_heap_t *heap = NULL;
+ uint8_t *p = NULL;
+ size_t nalloc, need;
+ size_t max_idx = 0; /* The maximum index seen */
+ H5HG_heap_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5HG_load, NULL)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(!udata1);
+ HDassert(!udata2);
+
+ /* Read the initial 4k page */
+ if(NULL == (heap = H5FL_CALLOC(H5HG_heap_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ heap->addr = addr;
+ if(NULL == (heap->chunk = H5FL_BLK_MALLOC(gheap_chunk, (size_t)H5HG_MINSIZE)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ if(H5F_block_read(f, H5FD_MEM_GHEAP, addr, (size_t)H5HG_MINSIZE, dxpl_id, heap->chunk) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "unable to read global heap collection")
+
+ /* Magic number */
+ if(HDmemcmp(heap->chunk, H5HG_MAGIC, (size_t)H5_SIZEOF_MAGIC))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad global heap collection signature")
+ p = heap->chunk + H5_SIZEOF_MAGIC;
+
+ /* Version */
+ if(H5HG_VERSION != *p++)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong version number in global heap")
+
+ /* Reserved */
+ p += 3;
+
+ /* Size */
+ H5F_DECODE_LENGTH(f, p, heap->size);
+ HDassert(heap->size >= H5HG_MINSIZE);
+
+ /*
+ * If we didn't read enough in the first try, then read the rest of the
+ * collection now.
+ */
+ if(heap->size > H5HG_MINSIZE) {
+ haddr_t next_addr = addr + (hsize_t)H5HG_MINSIZE;
+
+ if(NULL == (heap->chunk = H5FL_BLK_REALLOC(gheap_chunk, heap->chunk, heap->size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ if(H5F_block_read(f, H5FD_MEM_GHEAP, next_addr, (heap->size - H5HG_MINSIZE), dxpl_id, heap->chunk + H5HG_MINSIZE) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "unable to read global heap collection")
+ } /* end if */
+
+ /* Decode each object */
+ p = heap->chunk + H5HG_SIZEOF_HDR(f);
+ nalloc = H5HG_NOBJS(f, heap->size);
+
+ /* Calloc the obj array because the file format spec makes no guarantee
+ * about the order of the objects, and unused slots must be set to zero.
+ */
+ if(NULL == (heap->obj = H5FL_SEQ_CALLOC(H5HG_obj_t, nalloc)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ heap->nalloc = nalloc;
+ while(p < (heap->chunk + heap->size)) {
+ if((p + H5HG_SIZEOF_OBJHDR(f)) > (heap->chunk + heap->size)) {
+ /*
+ * The last bit of space is too tiny for an object header, so we
+ * assume that it's free space.
+ */
+ HDassert(NULL == heap->obj[0].begin);
+ heap->obj[0].size = (heap->chunk + heap->size) - p;
+ heap->obj[0].begin = p;
+ p += heap->obj[0].size;
+ } /* end if */
+ else {
+ unsigned idx;
+ uint8_t *begin = p;
+
+ UINT16DECODE(p, idx);
+
+ /* Check if we need more room to store heap objects */
+ if(idx >= heap->nalloc) {
+ size_t new_alloc; /* New allocation number */
+ H5HG_obj_t *new_obj; /* New array of object descriptions */
+
+ /* Determine the new number of objects to index */
+ new_alloc = MAX(heap->nalloc * 2, (idx + 1));
+ HDassert(idx < new_alloc);
+
+ /* Reallocate array of objects */
+ if(NULL == (new_obj = H5FL_SEQ_REALLOC(H5HG_obj_t, heap->obj, new_alloc)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Clear newly allocated space */
+ HDmemset(&new_obj[heap->nalloc], 0, (new_alloc - heap->nalloc) * sizeof(heap->obj[0]));
+
+ /* Update heap information */
+ heap->nalloc = new_alloc;
+ heap->obj = new_obj;
+ HDassert(heap->nalloc>heap->nused);
+ } /* end if */
+
+ UINT16DECODE(p, heap->obj[idx].nrefs);
+ p += 4; /*reserved*/
+ H5F_DECODE_LENGTH(f, p, heap->obj[idx].size);
+ heap->obj[idx].begin = begin;
+
+ /*
+ * The total storage size includes the size of the object header
+ * and is zero padded so the next object header is properly
+ * aligned. The entire obj array was calloc'ed, so no need to zero
+ * the space here. The last bit of space is the free space object
+ * whose size is never padded and already includes the object
+ * header.
+ */
+ if(idx > 0) {
+ need = H5HG_SIZEOF_OBJHDR(f) + H5HG_ALIGN(heap->obj[idx].size);
+
+ if(idx > max_idx)
+ max_idx = idx;
+ } /* end if */
+ else
+ need = heap->obj[idx].size;
+ p = begin + need;
+ } /* end else */
+ } /* end while */
+ HDassert(p == heap->chunk + heap->size);
+ HDassert(H5HG_ISALIGNED(heap->obj[0].size));
+
+ /* Set the next index value to use */
+ if(max_idx > 0)
+ heap->nused = max_idx + 1;
+ else
+ heap->nused = 1;
+
+ HDassert(max_idx < heap->nused);
+
+ /*
+ * Add the new heap to the CWFS list, removing some other entry if
+ * necessary to make room. We remove the right-most entry that has less
+ * free space than this heap.
+ */
+ if(!f->shared->cwfs) {
+ f->shared->cwfs = (H5HG_heap_t **)H5MM_malloc(H5HG_NCWFS * sizeof(H5HG_heap_t *));
+ if(NULL == f->shared->cwfs)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ f->shared->ncwfs = 1;
+ f->shared->cwfs[0] = heap;
+ } else if(H5HG_NCWFS == f->shared->ncwfs) {
+ int i; /* Local index variable */
+
+ for(i = H5HG_NCWFS - 1; i >= 0; --i)
+ if(f->shared->cwfs[i]->obj[0].size < heap->obj[0].size) {
+ HDmemmove(f->shared->cwfs + 1, f->shared->cwfs, i * sizeof(H5HG_heap_t *));
+ f->shared->cwfs[0] = heap;
+ break;
+ } /* end if */
+ } else {
+ HDmemmove(f->shared->cwfs + 1, f->shared->cwfs, f->shared->ncwfs * sizeof(H5HG_heap_t *));
+ f->shared->ncwfs += 1;
+ f->shared->cwfs[0] = heap;
+ } /* end else */
+
+ ret_value = heap;
+
+done:
+ if(!ret_value && heap)
+ if(H5HG_dest(f, heap) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, NULL, "unable to destroy global heap collection")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HG_load() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HG_flush
+ *
+ * Purpose: Flushes a global heap collection from memory to disk if it's
+ * dirty. Optionally deletes teh heap from memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Friday, March 27, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HG_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HG_heap_t *heap, unsigned UNUSED * flags_ptr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5HG_flush, FAIL)
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(H5F_addr_eq(addr, heap->addr));
+ HDassert(heap);
+
+ if(heap->cache_info.is_dirty) {
+ if(H5F_block_write(f, H5FD_MEM_GHEAP, addr, heap->size, dxpl_id, heap->chunk) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write global heap collection to file")
+ heap->cache_info.is_dirty = FALSE;
+ } /* end if */
+
+ if(destroy)
+ if(H5HG_dest(f, heap) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy global heap collection")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HG_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HG_dest
+ *
+ * Purpose: Destroys a global heap collection in memory
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, January 15, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HG_dest(H5F_t *f, H5HG_heap_t *heap)
+{
+ int i; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HG_dest)
+
+ /* Check arguments */
+ HDassert(heap);
+
+ /* Verify that node is clean */
+ HDassert(heap->cache_info.is_dirty == FALSE);
+
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!heap->cache_info.free_file_space_on_destroy || H5F_addr_defined(heap->cache_info.addr));
+
+ /* Check for freeing file space for globalheap */
+ if(heap->cache_info.free_file_space_on_destroy) {
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_GHEAP, H5AC_dxpl_id, heap->cache_info.addr, (hsize_t)heap->size) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free global heap")
+ } /* end if */
+
+ /* Remove heap from NCWFS array, if it's present */
+ for(i = 0; i < f->shared->ncwfs; i++)
+ if(f->shared->cwfs[i] == heap) {
+ f->shared->ncwfs -= 1;
+ HDmemmove(f->shared->cwfs + i, f->shared->cwfs + i + 1, (f->shared->ncwfs - i) * sizeof(H5HG_heap_t *));
+ break;
+ } /* end if */
+
+ /* Release resources */
+ if(heap->chunk)
+ heap->chunk = H5FL_BLK_FREE(gheap_chunk, heap->chunk);
+ if(heap->obj)
+ heap->obj = H5FL_SEQ_FREE(H5HG_obj_t, heap->obj);
+ (void)H5FL_FREE(H5HG_heap_t, heap);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HG_dest() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HG_clear
+ *
+ * Purpose: Mark a global heap in memory as non-dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, March 20, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HG_clear(H5F_t *f, H5HG_heap_t *heap, hbool_t destroy)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HG_clear)
+
+ /* Check arguments */
+ HDassert(heap);
+
+ /* Mark heap as clean */
+ heap->cache_info.is_dirty = FALSE;
+
+ if(destroy)
+ if(H5HG_dest(f, heap) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy global heap collection")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HG_clear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HG_size
+ *
+ * Purpose: Compute the size in bytes of the specified instance of
+ * H5HG_heap_t on disk, and return it in *len_ptr. On failure,
+ * the value of *len_ptr is undefined.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 5/13/04
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HG_size(const H5F_t UNUSED *f, const H5HG_heap_t *heap, size_t *size_ptr)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HG_size)
+
+ /* Check arguments */
+ HDassert(heap);
+ HDassert(size_ptr);
+
+ *size_ptr = heap->size;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5HG_size() */
+
diff --git a/src/H5HGdbg.c b/src/H5HGdbg.c
index 0e5aff8..bda9832 100644
--- a/src/H5HGdbg.c
+++ b/src/H5HGdbg.c
@@ -73,7 +73,7 @@ H5HG_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
assert(indent >= 0);
assert(fwidth >= 0);
- if (NULL == (h = H5AC_protect(f, dxpl_id, H5AC_GHEAP, addr, NULL, NULL, H5AC_READ)))
+ if (NULL == (h = (H5HG_heap_t *)H5AC_protect(f, dxpl_id, H5AC_GHEAP, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load global heap collection");
fprintf(stream, "%*sGlobal Heap Collection...\n", indent, "");
@@ -93,7 +93,10 @@ H5HG_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
fprintf (stream, "%*s%-*s %u/%lu/", indent, "", fwidth,
"Objects defined/allocated/max:",
nused, (unsigned long)h->nalloc);
- fprintf (stream, nused ? "%u\n": "NA\n", maxobj);
+ if(nused)
+ fprintf(stream, "%u\n", maxobj);
+ else
+ fprintf(stream, "NA\n");
fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
"Free space:",
@@ -113,7 +116,7 @@ H5HG_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
(unsigned long)H5HG_ALIGN(h->obj[u].size));
p = h->obj[u].begin + H5HG_SIZEOF_OBJHDR (f);
for (j=0; j<h->obj[u].size; j+=16) {
- fprintf (stream, "%*s%04d: ", indent+6, "", j);
+ fprintf (stream, "%*s%04u: ", indent+6, "", j);
for (k=0; k<16; k++) {
if (8==k) fprintf (stream, " ");
if (j+k<h->obj[u].size) {
diff --git a/src/H5HGpkg.h b/src/H5HGpkg.h
index e814367..96be009 100644
--- a/src/H5HGpkg.h
+++ b/src/H5HGpkg.h
@@ -32,6 +32,9 @@
#include "H5HGprivate.h"
/* Other private headers needed by this file */
+#include "H5ACprivate.h" /* Metadata cache */
+#include "H5FLprivate.h" /* Free lists */
+
/*****************************/
/* Package Private Variables */
@@ -40,11 +43,40 @@
/* The cache subclass */
H5_DLLVAR const H5AC_class_t H5AC_GHEAP[1];
+/* Declare extern the free list to manage the H5HG_t struct */
+H5FL_EXTERN(H5HG_heap_t);
+
+/* Declare extern the free list to manage sequences of H5HG_obj_t's */
+H5FL_SEQ_EXTERN(H5HG_obj_t);
+
+/* Declare extern the PQ free list to manage heap chunks */
+H5FL_BLK_EXTERN(gheap_chunk);
+
+
/**************************/
/* Package Private Macros */
/**************************/
/*
+ * Global heap collection version.
+ */
+#define H5HG_VERSION 1
+
+/*
+ * All global heap collections are at least this big. This allows us to read
+ * most collections with a single read() since we don't have to read a few
+ * bytes of header to figure out the size. If the heap is larger than this
+ * then a second read gets the rest after we've decoded the header.
+ */
+#define H5HG_MINSIZE 4096
+
+/*
+ * Maximum length of the CWFS list, the list of remembered collections that
+ * have free space.
+ */
+#define H5HG_NCWFS 16
+
+/*
* Pad all global heap messages to a multiple of eight bytes so we can load
* the entire collection into memory and operate on it there. Eight should
* be sufficient for machines that have alignment constraints because our
@@ -56,6 +88,16 @@ H5_DLLVAR const H5AC_class_t H5AC_GHEAP[1];
#define H5HG_ISALIGNED(X) ((X)==H5HG_ALIGN(X))
/*
+ * The size of the collection header, always a multiple of the alignment so
+ * that the stuff that follows the header is aligned.
+ */
+#define H5HG_SIZEOF_HDR(f) \
+ H5HG_ALIGN(4 + /*magic number */ \
+ 1 + /*version number */ \
+ 3 + /*reserved */ \
+ H5F_SIZEOF_SIZE(f)) /*collection size */
+
+/*
* The overhead associated with each object in the heap, always a multiple of
* the alignment so that the stuff that follows the header is aligned.
*/
@@ -65,6 +107,17 @@ H5_DLLVAR const H5AC_class_t H5AC_GHEAP[1];
4 + /*reserved */ \
H5F_SIZEOF_SIZE(f)) /*object data size */
+/*
+ * The initial guess for the number of messages in a collection. We assume
+ * that all objects in that collection are zero length, giving the maximum
+ * possible number of objects in the collection. The collection itself has
+ * some overhead and each message has some overhead. The `+2' accounts for
+ * rounding and for the free space object.
+ */
+#define H5HG_NOBJS(f,z) (int)((((z)-H5HG_SIZEOF_HDR(f))/ \
+ H5HG_SIZEOF_OBJHDR(f)+2))
+
+
/****************************/
/* Package Private Typedefs */
/****************************/
@@ -92,6 +145,7 @@ struct H5HG_heap_t {
/******************************/
/* Package Private Prototypes */
/******************************/
+H5_DLL herr_t H5HG_dest(H5F_t *f, H5HG_heap_t *heap);
-#endif
+#endif /* _H5HGpkg_H */
diff --git a/src/H5HGprivate.h b/src/H5HGprivate.h
index 6e2c492..b6cdb4a 100644
--- a/src/H5HGprivate.h
+++ b/src/H5HGprivate.h
@@ -26,12 +26,6 @@
/* Private headers needed by this file. */
#include "H5Fprivate.h" /* File access */
-/*
- * Each collection has a magic number for some redundancy.
- */
-#define H5HG_MAGIC "GCOL"
-#define H5HG_SIZEOF_MAGIC 4
-
/* Information to locate object in global heap */
typedef struct H5HG_t {
haddr_t addr; /*address of collection */
diff --git a/src/H5HL.c b/src/H5HL.c
index 7c8c689..6be0bbc 100644
--- a/src/H5HL.c
+++ b/src/H5HL.c
@@ -22,17 +22,13 @@
* Purpose: Heap functions for the local heaps used by symbol
* tables to store names (among other things).
*
- * Modifications:
- *
- * Robb Matzke, 5 Aug 1997
- * Added calls to H5E.
- *
*-------------------------------------------------------------------------
*/
/****************/
/* Module Setup */
/****************/
+
#define H5F_PACKAGE /* Suppress error about including H5Fpkg */
#define H5HL_PACKAGE /* Suppress error about including H5HLpkg */
@@ -41,10 +37,8 @@
/* Headers */
/***********/
#include "H5private.h" /* Generic Functions */
-#include "H5ACprivate.h" /* Metadata cache */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
-#include "H5FLprivate.h" /* Free lists */
#include "H5HLpkg.h" /* Local Heaps */
#include "H5MFprivate.h" /* File memory management */
@@ -53,13 +47,8 @@
/* Local Macros */
/****************/
-#define H5HL_FREE_NULL 1 /*end of free list on disk */
#define H5HL_MIN_HEAP 128 /* Minimum size to reduce heap buffer to */
-/*
- * Local heap collection version.
- */
-#define H5HL_VERSION 0
/******************/
/* Local Typedefs */
@@ -74,43 +63,15 @@
/********************/
/* Local Prototypes */
/********************/
-static herr_t H5HL_serialize(H5F_t *f, H5HL_t *heap, uint8_t *buf);
+
static H5HL_free_t *H5HL_remove_free(H5HL_t *heap, H5HL_free_t *fl);
static herr_t H5HL_minimize_heap_space(H5F_t *f, hid_t dxpl_id, H5HL_t *heap);
-/* Metadata cache callbacks */
-static H5HL_t *H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1,
- void *udata2);
-static herr_t H5HL_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, H5HL_t *heap, unsigned UNUSED * flags_ptr);
-static herr_t H5HL_dest(H5F_t *f, H5HL_t *heap);
-static herr_t H5HL_clear(H5F_t *f, H5HL_t *heap, hbool_t destroy);
-static herr_t H5HL_size(const H5F_t *f, const H5HL_t *heap, size_t *size_ptr);
-
-/*
- * H5HL inherits cache-like properties from H5AC
- */
-const H5AC_class_t H5AC_LHEAP[1] = {{
- H5AC_LHEAP_ID,
- (H5AC_load_func_t)H5HL_load,
- (H5AC_flush_func_t)H5HL_flush,
- (H5AC_dest_func_t)H5HL_dest,
- (H5AC_clear_func_t)H5HL_clear,
- (H5AC_size_func_t)H5HL_size,
-}};
/*********************/
/* Package Variables */
/*********************/
-/* Declare a free list to manage the H5HL_free_t struct */
-H5FL_DEFINE_STATIC(H5HL_free_t);
-
-/* Declare a free list to manage the H5HL_t struct */
-H5FL_DEFINE_STATIC(H5HL_t);
-
-/* Declare a PQ free list to manage the heap chunk information */
-H5FL_BLK_DEFINE_STATIC(heap_chunk);
-
/*****************************/
/* Library Private Variables */
@@ -121,6 +82,15 @@ H5FL_BLK_DEFINE_STATIC(heap_chunk);
/* Local Variables */
/*******************/
+/* Declare a free list to manage the H5HL_free_t struct */
+H5FL_DEFINE(H5HL_free_t);
+
+/* Declare a free list to manage the H5HL_t struct */
+H5FL_DEFINE(H5HL_t);
+
+/* Declare a PQ free list to manage the heap chunk information */
+H5FL_BLK_DEFINE(lheap_chunk);
+
/*-------------------------------------------------------------------------
@@ -169,14 +139,14 @@ H5HL_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, haddr_t *addr_p/*out*/)
/* Allocate file version */
total_size = sizeof_hdr + size_hint;
if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id, total_size)))
- HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "unable to allocate file memory")
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "unable to allocate file memory")
/* allocate memory version */
if(NULL == (heap = H5FL_CALLOC(H5HL_t)))
- HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed")
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "memory allocation failed")
heap->addr = *addr_p + (hsize_t)sizeof_hdr;
heap->heap_alloc = size_hint;
- if(NULL == (heap->chunk = H5FL_BLK_CALLOC(heap_chunk,(sizeof_hdr + size_hint))))
+ if(NULL == (heap->chunk = H5FL_BLK_CALLOC(lheap_chunk, (sizeof_hdr + size_hint))))
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "memory allocation failed")
/* free list */
@@ -198,10 +168,9 @@ done:
if(ret_value < 0) {
if(H5F_addr_defined(*addr_p))
H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, *addr_p, total_size);
- if(heap) {
+ if(heap)
if(H5HL_dest(f, heap) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy local heap")
- } /* end if */
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -209,120 +178,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5HL_load
- *
- * Purpose: Loads a heap from disk.
- *
- * Return: Success: Ptr to a local heap memory data structure.
- *
- * Failure: NULL
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Jul 17 1997
- *
- *-------------------------------------------------------------------------
- */
-static H5HL_t *
-H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1,
- void UNUSED * udata2)
-{
- uint8_t hdr[52];
- size_t sizeof_hdr; /* Cache H5HL header size for file */
- const uint8_t *p = NULL;
- H5HL_t *heap = NULL;
- H5HL_free_t *fl = NULL, *tail = NULL;
- size_t free_block = H5HL_FREE_NULL;
- H5HL_t *ret_value;
-
- FUNC_ENTER_NOAPI(H5HL_load, NULL)
-
- /* check arguments */
- HDassert(f);
- HDassert(H5F_addr_defined(addr));
- HDassert(!udata1);
- HDassert(!udata2);
-
- /* Cache this for later */
- sizeof_hdr = H5HL_SIZEOF_HDR(f);
- HDassert(sizeof_hdr <= sizeof(hdr));
-
- /* Get the local heap's header */
- if(H5F_block_read(f, H5FD_MEM_LHEAP, addr, sizeof_hdr, dxpl_id, hdr) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "unable to read heap header")
- p = hdr;
-
- /* Check magic number */
- if(HDmemcmp(hdr, H5HL_MAGIC, (size_t)H5HL_SIZEOF_MAGIC))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap signature")
- p += H5HL_SIZEOF_MAGIC;
-
- /* Version */
- if(H5HL_VERSION != *p++)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong version number in global heap")
-
- /* Reserved */
- p += 3;
-
- /* Allocate space in memory for the heap */
- if(NULL == (heap = H5FL_CALLOC(H5HL_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
- /* heap data size */
- H5F_DECODE_LENGTH(f, p, heap->heap_alloc);
-
- /* free list head */
- H5F_DECODE_LENGTH(f, p, free_block);
- if(free_block != H5HL_FREE_NULL && free_block >= heap->heap_alloc)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list")
-
- /* data */
- H5F_addr_decode(f, &p, &(heap->addr));
- if(NULL == (heap->chunk = H5FL_BLK_CALLOC(heap_chunk, (sizeof_hdr + heap->heap_alloc))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- if(heap->heap_alloc &&
- H5F_block_read(f, H5FD_MEM_LHEAP, heap->addr, heap->heap_alloc, dxpl_id, heap->chunk + sizeof_hdr) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to read heap data")
-
- /* Build free list */
- while(H5HL_FREE_NULL != free_block) {
- if(free_block >= heap->heap_alloc)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list")
- if(NULL == (fl = H5FL_MALLOC(H5HL_free_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- fl->offset = free_block;
- fl->prev = tail;
- fl->next = NULL;
- if(tail)
- tail->next = fl;
- tail = fl;
- if(!heap->freelist)
- heap->freelist = fl;
-
- p = heap->chunk + sizeof_hdr + free_block;
-
- H5F_DECODE_LENGTH(f, p, free_block);
- if(free_block == 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "free block size is zero?")
-
- H5F_DECODE_LENGTH(f, p, fl->size);
- if (fl->offset + fl->size > heap->heap_alloc)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list")
- } /* end while */
-
- /* Set return value */
- ret_value = heap;
-
-done:
- if(!ret_value && heap)
- if(H5HL_dest(f,heap) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, NULL, "unable to destroy local heap collection")
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5HL_load() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5HL_minimize_heap_space
*
* Purpose: Go through the heap's freelist and determine if we can
@@ -335,22 +190,6 @@ done:
* wendling@ncsa.uiuc.edu
* Sept. 16, 2003
*
- * Modifications:
- *
- * John Mainzer, 8/10/05
- * Reworked this function for a different role.
- *
- * It used to be called during cache eviction, where it
- * attempted to size the disk space allocation for the
- * actual size of the heap. However, this causes problems
- * in the parallel case, as the reuslting disk allocations
- * may not be synchronized.
- *
- * It is now called from H5HL_remove(), where it is used to
- * reduce heap size in response to an entry deletion. This
- * means that the function should either do nothing, or
- * reduce the size of the disk allocation.
- *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -453,14 +292,14 @@ H5HL_minimize_heap_space(H5F_t *f, hid_t dxpl_id, H5HL_t *heap)
HDassert(new_heap_size < heap->heap_alloc);
/* Resize the memory buffer */
- if(NULL == (heap->chunk = H5FL_BLK_REALLOC(heap_chunk, heap->chunk, (sizeof_hdr + new_heap_size))))
+ if(NULL == (heap->chunk = H5FL_BLK_REALLOC(lheap_chunk, heap->chunk, (sizeof_hdr + new_heap_size))))
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "memory allocation failed")
/* Release old space on disk */
/* (Should be safe to free old heap space first, since it's shrinking -QAK) */
H5_CHECK_OVERFLOW(heap->heap_alloc, size_t, hsize_t);
- H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, old_addr, (hsize_t)heap->heap_alloc);
- H5E_clear_stack(NULL); /* don't really care if the free failed */
+ if(H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, old_addr, (hsize_t)heap->heap_alloc) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free local heap")
/* Allocate new space on disk */
H5_CHECK_OVERFLOW(new_heap_size, size_t, hsize_t);
@@ -478,268 +317,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5HL_serialize
- *
- * Purpose: Serialize the heap. This function will eliminate free
- * blocks at the tail of the heap and also split the block
- * if it needs to be split for the file. This is so that we
- * can serialize it correctly.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Bill Wendling
- * wendling@ncsa.uiuc.edu
- * Sept. 16, 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5HL_serialize(H5F_t *f, H5HL_t *heap, uint8_t *buf)
-{
- H5HL_free_t *fl;
- uint8_t *p;
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_serialize)
-
- /* check args */
- assert(buf);
- assert(heap);
-
- /* serialize the header */
- p = buf;
- fl = heap->freelist;
- HDmemcpy(p, H5HL_MAGIC, (size_t)H5HL_SIZEOF_MAGIC);
- p += H5HL_SIZEOF_MAGIC;
- *p++ = H5HL_VERSION;
- *p++ = 0; /*reserved*/
- *p++ = 0; /*reserved*/
- *p++ = 0; /*reserved*/
- H5F_ENCODE_LENGTH(f, p, heap->heap_alloc);
- H5F_ENCODE_LENGTH(f, p, fl ? fl->offset : H5HL_FREE_NULL);
- H5F_addr_encode(f, &p, heap->addr);
-
- /* serialize the free list */
- for (; fl; fl = fl->next) {
- assert (fl->offset == H5HL_ALIGN (fl->offset));
- p = heap->chunk + H5HL_SIZEOF_HDR(f) + fl->offset;
-
- if (fl->next) {
- H5F_ENCODE_LENGTH(f, p, fl->next->offset);
- } else {
- H5F_ENCODE_LENGTH(f, p, H5HL_FREE_NULL);
- }
-
- H5F_ENCODE_LENGTH(f, p, fl->size);
- }
-
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5HL_flush
- *
- * Purpose: Flushes a heap from memory to disk if it's dirty. Optionally
- * deletes the heap from memory.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Jul 17 1997
- *
- * Modifications:
- * rky, 1998-08-28
- * Only p0 writes metadata to disk.
- *
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
- *
- * Quincey Koziol, 2002-7-180
- * Added dxpl parameter to allow more control over I/O from metadata
- * cache.
- *
- * Bill Wendling, 2003-09-16
- * Separated out the bit that serializes the heap.
- *
- * John Mainzer, 2005-08-10
- * Removed call to H5HL_minimize_heap_space(). It does disk space
- * allocation, which can cause problems if done at flush time.
- * Instead, disk space allocation/deallocation is now done at
- * insert/remove time.
- *
- * John Mainzer, 2006-08-21
- * Added the flags_ptr parameter. This parameter exists to
- * allow the flush routine to report to the cache if the
- * entry is resized or renamed as a result of the flush.
- * *flags_ptr is set to H5C_CALLBACK__NO_FLAGS_SET on entry.
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5HL_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HL_t *heap, unsigned UNUSED * flags_ptr)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5HL_flush, FAIL);
-
- /* check arguments */
- HDassert( f );
- HDassert( H5F_addr_defined(addr) );
- HDassert( heap );
-
- if (heap->cache_info.is_dirty) {
- haddr_t hdr_end_addr;
- size_t sizeof_hdr = H5HL_SIZEOF_HDR(f); /* cache H5HL header size for file */
-
- /* Write the header */
- if (H5HL_serialize(f, heap, heap->chunk) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTSERIALIZE, FAIL, "unable to serialize local heap")
-
- /* Copy buffer to disk */
- hdr_end_addr = addr + (hsize_t)sizeof_hdr;
-
- if (H5F_addr_eq(heap->addr, hdr_end_addr)) {
- /* The header and data are contiguous */
- if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, (sizeof_hdr + heap->heap_alloc),
- dxpl_id, heap->chunk) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header and data to file")
- } else {
- if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, sizeof_hdr, dxpl_id, heap->chunk) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header to file")
-
- if (H5F_block_write(f, H5FD_MEM_LHEAP, heap->addr, heap->heap_alloc,
- dxpl_id, heap->chunk + sizeof_hdr) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap data to file")
- }
-
- heap->cache_info.is_dirty = FALSE;
- }
-
- /* Should we destroy the memory version? */
- if (destroy) {
- if (H5HL_dest(f,heap) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy local heap collection")
- }
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5HL_dest
- *
- * Purpose: Destroys a heap in memory.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Jan 15 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5HL_dest(H5F_t UNUSED *f, H5HL_t *heap)
-{
- H5HL_free_t *fl;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_dest);
-
- /* check arguments */
- assert(heap);
-
- /* Verify that node is clean */
- assert (heap->cache_info.is_dirty==FALSE);
-
- if(heap->chunk)
- heap->chunk = H5FL_BLK_FREE(heap_chunk,heap->chunk);
- while (heap->freelist) {
- fl = heap->freelist;
- heap->freelist = fl->next;
- H5FL_FREE(H5HL_free_t,fl);
- }
- H5FL_FREE(H5HL_t,heap);
-
- FUNC_LEAVE_NOAPI(SUCCEED);
-} /* end H5HL_dest() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5HL_clear
- *
- * Purpose: Mark a local heap in memory as non-dirty.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Mar 20 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5HL_clear(H5F_t *f, H5HL_t *heap, hbool_t destroy)
-{
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI_NOINIT(H5HL_clear);
-
- /* check arguments */
- assert(heap);
-
- /* Mark heap as clean */
- heap->cache_info.is_dirty = FALSE;
-
- if (destroy)
- if (H5HL_dest(f, heap) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy local heap collection");
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5HL_clear() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5HL_size
- *
- * Purpose: Compute the size in bytes of the specified instance of
- * H5HL_t on disk, and return it in *len_ptr. On failure,
- * the value of *len_ptr is undefined.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: John Mainzer
- * 5/13/04
- *
- * Modifications:
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5HL_size(const H5F_t *f, const H5HL_t *heap, size_t *size_ptr)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_size);
-
- /* check arguments */
- HDassert(f);
- HDassert(heap);
- HDassert(size_ptr);
-
- *size_ptr = H5HL_SIZEOF_HDR(f) + heap->heap_alloc;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HL_size() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5HL_protect
*
* Purpose: This function is a wrapper for the H5AC_protect call. The
@@ -781,7 +358,7 @@ H5HL_protect(H5F_t *f, hid_t dxpl_id, haddr_t addr, H5AC_protect_t rw)
HDassert(f);
HDassert(H5F_addr_defined(addr));
- if(NULL == (ret_value = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, rw)))
+ if(NULL == (ret_value = (H5HL_t *)H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, rw)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap")
done:
@@ -816,6 +393,7 @@ H5HL_offset_into(H5F_t *f, const H5HL_t *heap, size_t offset)
HDassert(f);
HDassert(heap);
HDassert(offset < heap->heap_alloc);
+
FUNC_LEAVE_NOAPI(heap->chunk + H5HL_SIZEOF_HDR(f) + offset)
} /* end H5HL_offset_into() */
@@ -881,7 +459,7 @@ H5HL_remove_free(H5HL_t *heap, H5HL_free_t *fl)
if(!fl->prev)
heap->freelist = fl->next;
- FUNC_LEAVE_NOAPI(H5FL_FREE(H5HL_free_t, fl))
+ FUNC_LEAVE_NOAPI((H5HL_free_t *)H5FL_FREE(H5HL_free_t, fl))
} /* end H5HL_remove_free() */
@@ -971,9 +549,9 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t buf_size, const void *
* free chunk. If the heap must expand, we double its size.
*/
if(found == FALSE) {
- size_t need_more; /* How much more space we need */
- size_t new_heap_alloc; /* Final size of space allocated for heap */
- htri_t can_extend; /* Whether the local heap's data segment on disk can be extended */
+ size_t need_more; /* How much more space we need */
+ size_t new_heap_alloc; /* Final size of space allocated for heap */
+ htri_t extended; /* Whether the local heap's data segment on disk was extended */
/* At least double the heap's size, making certain there's enough room
* for the new object */
@@ -994,35 +572,21 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t buf_size, const void *
H5_CHECK_OVERFLOW(heap->heap_alloc, size_t, hsize_t);
H5_CHECK_OVERFLOW(new_heap_alloc, size_t, hsize_t);
- /* Check if current heap is extendible */
- can_extend = H5MF_can_extend(f, H5FD_MEM_LHEAP, heap->addr, (hsize_t)(heap->heap_alloc), (hsize_t)need_more);
- if(can_extend < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "unable to check whether heap can be extended")
+ /* Extend current heap if possible */
+ extended = H5MF_try_extend(f, dxpl_id, H5FD_MEM_LHEAP, heap->addr, (hsize_t)(heap->heap_alloc), (hsize_t)need_more);
+ if(extended < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTEXTEND, UFAIL, "error trying to extend heap")
- /* Check if we can extend heap in file */
- if(can_extend == TRUE) {
- /* Extend file space allocation */
- if(H5MF_extend(f, H5FD_MEM_LHEAP, heap->addr, (hsize_t)(heap->heap_alloc), (hsize_t)need_more) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "can't extend heap on disk")
- } /* end if */
- else { /* ...if we can't, allocate a new chunk & release the old */
- haddr_t new_addr;
-
- /* The new allocation may fail -- to avoid the possiblity of
- * file corruption, allocate the new heap first, and then
- * deallocate the old.
- */
+ /* If we couldn't extend the heap, release old chunk and allocate a new one */
+ if(extended == FALSE) {
+ /* Release old space on disk */
+ if(H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, heap->addr, (hsize_t)heap->heap_alloc) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, UFAIL, "unable to free local heap")
/* allocate new disk space for the heap */
- if((new_addr = H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id, (hsize_t)new_heap_alloc)) == HADDR_UNDEF)
+ if((heap->addr = H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id, (hsize_t)new_heap_alloc)) == HADDR_UNDEF)
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, UFAIL, "unable to allocate file space for heap")
-
- /* Release old space on disk */
- H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, heap->addr, (hsize_t)heap->heap_alloc);
- H5E_clear_stack(NULL); /* don't really care if the free failed */
-
- heap->addr = new_addr;
- } /* end else */
+ } /* end if */
/* If the last free list in the heap is at the end of the heap, extend it */
if(last_fl && last_fl->offset + last_fl->size == heap->heap_alloc) {
@@ -1081,8 +645,8 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t buf_size, const void *
}
#endif
heap->heap_alloc = new_heap_alloc;
- if(NULL == (heap->chunk = H5FL_BLK_REALLOC(heap_chunk, heap->chunk, (sizeof_hdr + heap->heap_alloc))))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, UFAIL, "memory allocation failed")
+ if(NULL == (heap->chunk = H5FL_BLK_REALLOC(lheap_chunk, heap->chunk, (sizeof_hdr + heap->heap_alloc))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
/* Clear new section so junk doesn't appear in the file */
/* (Avoid clearing section which will be overwritten with newly inserted data) */
@@ -1130,7 +694,7 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t offset, size_t size)
H5HL_free_t *fl = NULL;
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5HL_remove, FAIL);
+ FUNC_ENTER_NOAPI(H5HL_remove, FAIL)
/* check arguments */
HDassert(f);
@@ -1274,9 +838,9 @@ done:
herr_t
H5HL_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
{
- H5HL_t *heap = NULL;
- size_t sizeof_hdr; /* Cache H5HL header size for file */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5HL_t *heap = NULL; /* Local heap to delete */
+ unsigned cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting heap */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HL_delete, FAIL)
@@ -1284,43 +848,16 @@ H5HL_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
HDassert(f);
HDassert(H5F_addr_defined(addr));
- /* Cache this for later */
- sizeof_hdr= H5HL_SIZEOF_HDR(f);
-
/* Get heap pointer */
- if(NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap")
+ if(NULL == (heap = (H5HL_t *)H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load heap")
- /* Check if the heap is contiguous on disk */
- assert(!H5F_addr_overflow(addr,sizeof_hdr));
- if(H5F_addr_eq(heap->addr,addr+sizeof_hdr)) {
- /* Free the contiguous local heap in one call */
- H5_CHECK_OVERFLOW(sizeof_hdr+heap->heap_alloc,size_t,hsize_t);
- if(H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, addr, (hsize_t)(sizeof_hdr+heap->heap_alloc)) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free contiguous local heap")
- } /* end if */
- else {
- /* Free the local heap's prefix */
- H5_CHECK_OVERFLOW(sizeof_hdr,size_t,hsize_t);
- if(H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, addr, (hsize_t)sizeof_hdr) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free local heap header")
-
- /* Free the local heap's data */
- H5_CHECK_OVERFLOW(heap->heap_alloc,size_t,hsize_t);
- if(H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, heap->addr, (hsize_t)heap->heap_alloc) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free local heap data")
- } /* end else */
-
- /* Release the local heap metadata from the cache */
- if(H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, heap, H5AC__DIRTIED_FLAG | H5C__DELETED_FLAG) < 0) {
- heap = NULL;
- HGOTO_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release local heap")
- } /* end if */
- heap = NULL;
+ /* Set the cache flags to delete the heap & free its file space */
+ cache_flags |= H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG;
done:
- if(heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, heap, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release local heap")
+ if(heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, heap, cache_flags) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release local heap")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HL_delete() */
@@ -1353,7 +890,7 @@ H5HL_get_size(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t *size)
HDassert(size);
/* Get heap pointer */
- if(NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (heap = (H5HL_t *)H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap")
/* Set the size to return */
@@ -1395,7 +932,7 @@ H5HL_heapsize(H5F_t *f, hid_t dxpl_id, haddr_t addr, hsize_t *heap_size)
HDassert(heap_size);
/* Get heap pointer */
- if(NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (heap = (H5HL_t *)H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap")
/* Get the total size of the local heap */
diff --git a/src/H5HLcache.c b/src/H5HLcache.c
new file mode 100644
index 0000000..fa458ca
--- /dev/null
+++ b/src/H5HLcache.c
@@ -0,0 +1,479 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5HLcache.c
+ * Feb 5 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Implement local heap metadata cache methods.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5HL_PACKAGE /* Suppress error about including H5HLpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5HLpkg.h" /* Local Heaps */
+#include "H5MFprivate.h" /* File memory management */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+#define H5HL_VERSION 0 /* Local heap collection version */
+#define H5HL_FREE_NULL 1 /* End of free list on disk */
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* Local encode/decode routines */
+static herr_t H5HL_serialize(H5F_t *f, H5HL_t *heap, uint8_t *buf);
+
+/* Metadata cache callbacks */
+static H5HL_t *H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1,
+ void *udata2);
+static herr_t H5HL_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, H5HL_t *heap, unsigned UNUSED * flags_ptr);
+static herr_t H5HL_clear(H5F_t *f, H5HL_t *heap, hbool_t destroy);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* H5HL inherits cache-like properties from H5AC */
+const H5AC_class_t H5AC_LHEAP[1] = {{
+ H5AC_LHEAP_ID,
+ (H5AC_load_func_t)H5HL_load,
+ (H5AC_flush_func_t)H5HL_flush,
+ (H5AC_dest_func_t)H5HL_dest,
+ (H5AC_clear_func_t)H5HL_clear,
+ (H5AC_notify_func_t)NULL,
+ (H5AC_size_func_t)H5HL_size,
+}};
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_serialize
+ *
+ * Purpose: Serialize the heap. This function will eliminate free
+ * blocks at the tail of the heap and also split the block
+ * if it needs to be split for the file. This is so that we
+ * can serialize it correctly.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Bill Wendling
+ * wendling@ncsa.uiuc.edu
+ * Sept. 16, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HL_serialize(H5F_t *f, H5HL_t *heap, uint8_t *buf)
+{
+ H5HL_free_t *fl;
+ uint8_t *p;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_serialize)
+
+ /* check args */
+ assert(buf);
+ assert(heap);
+
+ /* serialize the header */
+ p = buf;
+ fl = heap->freelist;
+ HDmemcpy(p, H5HL_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
+ *p++ = H5HL_VERSION;
+ *p++ = 0; /*reserved*/
+ *p++ = 0; /*reserved*/
+ *p++ = 0; /*reserved*/
+ H5F_ENCODE_LENGTH(f, p, heap->heap_alloc);
+ H5F_ENCODE_LENGTH(f, p, fl ? fl->offset : H5HL_FREE_NULL);
+ H5F_addr_encode(f, &p, heap->addr);
+
+ /* serialize the free list */
+ for (; fl; fl = fl->next) {
+ assert (fl->offset == H5HL_ALIGN (fl->offset));
+ p = heap->chunk + H5HL_SIZEOF_HDR(f) + fl->offset;
+
+ if (fl->next) {
+ H5F_ENCODE_LENGTH(f, p, fl->next->offset);
+ } else {
+ H5F_ENCODE_LENGTH(f, p, H5HL_FREE_NULL);
+ }
+
+ H5F_ENCODE_LENGTH(f, p, fl->size);
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HL_serialize() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_load
+ *
+ * Purpose: Loads a heap from disk.
+ *
+ * Return: Success: Ptr to a local heap memory data structure.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Jul 17 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5HL_t *
+H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1,
+ void UNUSED * udata2)
+{
+ uint8_t hdr[52];
+ size_t sizeof_hdr; /* Cache H5HL header size for file */
+ const uint8_t *p = NULL;
+ H5HL_t *heap = NULL;
+ H5HL_free_t *fl = NULL, *tail = NULL;
+ size_t free_block = H5HL_FREE_NULL;
+ H5HL_t *ret_value;
+
+ FUNC_ENTER_NOAPI(H5HL_load, NULL)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(!udata1);
+ HDassert(!udata2);
+
+ /* Cache this for later */
+ sizeof_hdr = H5HL_SIZEOF_HDR(f);
+ HDassert(sizeof_hdr <= sizeof(hdr));
+
+ /* Get the local heap's header */
+ if(H5F_block_read(f, H5FD_MEM_LHEAP, addr, sizeof_hdr, dxpl_id, hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "unable to read heap header")
+ p = hdr;
+
+ /* Check magic number */
+ if(HDmemcmp(hdr, H5HL_MAGIC, (size_t)H5_SIZEOF_MAGIC))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap signature")
+ p += H5_SIZEOF_MAGIC;
+
+ /* Version */
+ if(H5HL_VERSION != *p++)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong version number in global heap")
+
+ /* Reserved */
+ p += 3;
+
+ /* Allocate space in memory for the heap */
+ if(NULL == (heap = H5FL_CALLOC(H5HL_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* heap data size */
+ H5F_DECODE_LENGTH(f, p, heap->heap_alloc);
+
+ /* free list head */
+ H5F_DECODE_LENGTH(f, p, free_block);
+ if(free_block != H5HL_FREE_NULL && free_block >= heap->heap_alloc)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list")
+
+ /* data */
+ H5F_addr_decode(f, &p, &(heap->addr));
+ if(NULL == (heap->chunk = H5FL_BLK_CALLOC(lheap_chunk, (sizeof_hdr + heap->heap_alloc))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ if(heap->heap_alloc &&
+ H5F_block_read(f, H5FD_MEM_LHEAP, heap->addr, heap->heap_alloc, dxpl_id, heap->chunk + sizeof_hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to read heap data")
+
+ /* Build free list */
+ while(H5HL_FREE_NULL != free_block) {
+ if(free_block >= heap->heap_alloc)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list")
+ if(NULL == (fl = H5FL_MALLOC(H5HL_free_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ fl->offset = free_block;
+ fl->prev = tail;
+ fl->next = NULL;
+ if(tail)
+ tail->next = fl;
+ tail = fl;
+ if(!heap->freelist)
+ heap->freelist = fl;
+
+ p = heap->chunk + sizeof_hdr + free_block;
+
+ H5F_DECODE_LENGTH(f, p, free_block);
+ if(free_block == 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "free block size is zero?")
+
+ H5F_DECODE_LENGTH(f, p, fl->size);
+ if(fl->offset + fl->size > heap->heap_alloc)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list")
+ } /* end while */
+
+ /* Set return value */
+ ret_value = heap;
+
+done:
+ if(!ret_value && heap)
+ if(H5HL_dest(f,heap) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, NULL, "unable to destroy local heap collection")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HL_load() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_flush
+ *
+ * Purpose: Flushes a heap from memory to disk if it's dirty. Optionally
+ * deletes the heap from memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Jul 17 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HL_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HL_t *heap, unsigned UNUSED * flags_ptr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5HL_flush, FAIL)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(heap);
+
+ if(heap->cache_info.is_dirty) {
+ haddr_t hdr_end_addr;
+ size_t sizeof_hdr = H5HL_SIZEOF_HDR(f); /* cache H5HL header size for file */
+
+ /* Write the header */
+ if(H5HL_serialize(f, heap, heap->chunk) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTSERIALIZE, FAIL, "unable to serialize local heap")
+
+ /* Copy buffer to disk */
+ hdr_end_addr = addr + (hsize_t)sizeof_hdr;
+
+ if(H5F_addr_eq(heap->addr, hdr_end_addr)) {
+ /* The header and data are contiguous */
+ if(H5F_block_write(f, H5FD_MEM_LHEAP, addr, (sizeof_hdr + heap->heap_alloc), dxpl_id, heap->chunk) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header and data to file")
+ } /* end if */
+ else {
+ if(H5F_block_write(f, H5FD_MEM_LHEAP, addr, sizeof_hdr, dxpl_id, heap->chunk) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header to file")
+
+ if(H5F_block_write(f, H5FD_MEM_LHEAP, heap->addr, heap->heap_alloc, dxpl_id, heap->chunk + sizeof_hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap data to file")
+ } /* end else */
+
+ heap->cache_info.is_dirty = FALSE;
+ } /* end if */
+
+ /* Should we destroy the memory version? */
+ if(destroy)
+ if(H5HL_dest(f, heap) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy local heap collection")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HL_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_dest
+ *
+ * Purpose: Destroys a heap in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jan 15 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HL_dest(H5F_t *f, H5HL_t *heap)
+{
+ H5HL_free_t *fl; /* Heap object free list */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HL_dest)
+
+ /* check arguments */
+ HDassert(heap);
+
+ /* Verify that node is clean */
+ HDassert(heap->cache_info.is_dirty == FALSE);
+
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!heap->cache_info.free_file_space_on_destroy || H5F_addr_defined(heap->cache_info.addr));
+
+ /* Check for freeing file space for local heap */
+ if(heap->cache_info.free_file_space_on_destroy) {
+ size_t sizeof_hdr; /* H5HL header size for file */
+ haddr_t hdr_addr; /* Address of heap header in file */
+
+ /* Compute this for later */
+ sizeof_hdr = H5HL_SIZEOF_HDR(f);
+ hdr_addr = heap->cache_info.addr;
+
+ /* Check if the heap is contiguous on disk */
+ HDassert(!H5F_addr_overflow(hdr_addr, sizeof_hdr));
+ if(H5F_addr_eq(heap->addr, hdr_addr + sizeof_hdr)) {
+ /* Free the contiguous local heap in one call */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ H5_CHECK_OVERFLOW(sizeof_hdr + heap->heap_alloc, size_t, hsize_t);
+ if(H5MF_xfree(f, H5FD_MEM_LHEAP, H5AC_dxpl_id, hdr_addr, (hsize_t)(sizeof_hdr + heap->heap_alloc)) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free contiguous local heap")
+ } /* end if */
+ else {
+ /* Free the local heap's header */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ H5_CHECK_OVERFLOW(sizeof_hdr, size_t, hsize_t);
+ if(H5MF_xfree(f, H5FD_MEM_LHEAP, H5AC_dxpl_id, hdr_addr, (hsize_t)sizeof_hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free local heap header")
+
+ /* Free the local heap's data */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ H5_CHECK_OVERFLOW(heap->heap_alloc, size_t, hsize_t);
+ if(H5MF_xfree(f, H5FD_MEM_LHEAP, H5AC_dxpl_id, heap->addr, (hsize_t)heap->heap_alloc) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free local heap data")
+ } /* end else */
+ } /* end if */
+
+ /* Release resources */
+ if(heap->chunk)
+ heap->chunk = H5FL_BLK_FREE(lheap_chunk, heap->chunk);
+ while(heap->freelist) {
+ fl = heap->freelist;
+ heap->freelist = fl->next;
+ (void)H5FL_FREE(H5HL_free_t, fl);
+ } /* end while */
+ (void)H5FL_FREE(H5HL_t, heap);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HL_dest() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_clear
+ *
+ * Purpose: Mark a local heap in memory as non-dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Mar 20 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HL_clear(H5F_t *f, H5HL_t *heap, hbool_t destroy)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HL_clear)
+
+ /* check arguments */
+ HDassert(heap);
+
+ /* Mark heap as clean */
+ heap->cache_info.is_dirty = FALSE;
+
+ if(destroy)
+ if(H5HL_dest(f, heap) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy local heap collection")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HL_clear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_size
+ *
+ * Purpose: Compute the size in bytes of the specified instance of
+ * H5HL_t on disk, and return it in *len_ptr. On failure,
+ * the value of *len_ptr is undefined.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 5/13/04
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HL_size(const H5F_t *f, const H5HL_t *heap, size_t *size_ptr)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_size)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(heap);
+ HDassert(size_ptr);
+
+ *size_ptr = H5HL_SIZEOF_HDR(f) + heap->heap_alloc;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5HL_size() */
+
diff --git a/src/H5HLdbg.c b/src/H5HLdbg.c
index d33bf0a..ab8d10a 100644
--- a/src/H5HLdbg.c
+++ b/src/H5HLdbg.c
@@ -70,7 +70,7 @@ H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int
HDassert(indent >= 0);
HDassert(fwidth >= 0);
- if (NULL == (h = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_READ)))
+ if (NULL == (h = (H5HL_t *)H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap")
fprintf(stream, "%*sLocal Heap...\n", indent, "");
@@ -92,7 +92,7 @@ H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int
* the heap and that no two free blocks point to the same region of
* the heap. */
if(NULL == (marker = (uint8_t *)H5MM_calloc(h->heap_alloc)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "memory allocation failed")
fprintf(stream, "%*sFree Blocks (offset, size):\n", indent, "");
diff --git a/src/H5HLpkg.h b/src/H5HLpkg.h
index fe6f107..1e34a48 100644
--- a/src/H5HLpkg.h
+++ b/src/H5HLpkg.h
@@ -32,6 +32,9 @@
#include "H5HLprivate.h"
/* Other private headers needed by this file */
+#include "H5ACprivate.h" /* Metadata cache */
+#include "H5FLprivate.h" /* Free lists */
+
/*****************************/
/* Package Private Variables */
@@ -40,17 +43,28 @@
/* The cache subclass */
H5_DLLVAR const H5AC_class_t H5AC_LHEAP[1];
+/* Declare extern the free list to manage the H5HL_free_t struct */
+H5FL_EXTERN(H5HL_free_t);
+
+/* Declare extern the free list to manage the H5HL_t struct */
+H5FL_EXTERN(H5HL_t);
+
+/* Declare extern the PQ free list to manage the heap chunk information */
+H5FL_BLK_EXTERN(lheap_chunk);
+
+
/**************************/
/* Package Private Macros */
/**************************/
#define H5HL_SIZEOF_HDR(F) \
- H5HL_ALIGN(H5HL_SIZEOF_MAGIC + /*heap signature */ \
+ H5HL_ALIGN(H5_SIZEOF_MAGIC + /*heap signature */ \
4 + /*reserved */ \
H5F_SIZEOF_SIZE (F) + /*data size */ \
H5F_SIZEOF_SIZE (F) + /*free list head */ \
H5F_SIZEOF_ADDR (F)) /*data address */
+
/****************************/
/* Package Private Typedefs */
/****************************/
@@ -71,10 +85,13 @@ struct H5HL_t {
H5HL_free_t *freelist; /*the free list */
};
+
/******************************/
/* Package Private Prototypes */
/******************************/
-#endif
+H5_DLL herr_t H5HL_dest(H5F_t *f, H5HL_t *heap);
+H5_DLL herr_t H5HL_size(const H5F_t *f, const H5HL_t *heap, size_t *size_ptr);
+#endif /* _H5HLpkg_H */
diff --git a/src/H5HLprivate.h b/src/H5HLprivate.h
index d8a4b49..2a3e2df 100644
--- a/src/H5HLprivate.h
+++ b/src/H5HLprivate.h
@@ -44,9 +44,6 @@
# undef H5HL_DEBUG
#endif
-#define H5HL_MAGIC "HEAP" /*heap magic number */
-#define H5HL_SIZEOF_MAGIC 4
-
#define H5HL_ALIGN(X) (((X)+7)&(unsigned)(~0x07)) /*align on 8-byte boundary */
#define H5HL_SIZEOF_FREE(F) \
diff --git a/src/H5HP.c b/src/H5HP.c
index e0a94a7..ad76817 100644
--- a/src/H5HP.c
+++ b/src/H5HP.c
@@ -235,11 +235,11 @@ H5HP_sink_max(H5HP_t *heap, size_t loc)
} /* end while */
/* Put object into heap at correct location */
- heap->heap[loc].val=val;
- heap->heap[loc].obj=obj;
+ heap->heap[loc].val = val;
+ heap->heap[loc].obj = (H5HP_info_t *)obj;
/* Update heap location for object */
- heap->heap[loc].obj->heap_loc=loc;
+ heap->heap[loc].obj->heap_loc = loc;
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HP_sink_max() */
@@ -304,11 +304,11 @@ H5HP_sink_min(H5HP_t *heap, size_t loc)
} /* end while */
/* Put object into heap at correct location */
- heap->heap[loc].val=val;
- heap->heap[loc].obj=obj;
+ heap->heap[loc].val = val;
+ heap->heap[loc].obj = (H5HP_info_t *)obj;
/* Update heap location for object */
- heap->heap[loc].obj->heap_loc=loc;
+ heap->heap[loc].obj->heap_loc = loc;
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HP_sink_min() */
@@ -378,11 +378,11 @@ H5HP_create(H5HP_type_t heap_type)
done:
/* Error cleanup */
- if(ret_value==NULL) {
- if(new_heap!=NULL) {
- if(new_heap->heap!=NULL)
- H5FL_SEQ_FREE(H5HP_ent_t,new_heap->heap);
- H5FL_FREE(H5HP_t,new_heap);
+ if(NULL ==ret_value) {
+ if(NULL != new_heap) {
+ if(NULL != new_heap->heap)
+ new_heap->heap = H5FL_SEQ_FREE(H5HP_ent_t, new_heap->heap);
+ new_heap = H5FL_FREE(H5HP_t, new_heap);
} /* end if */
} /* end if */
@@ -489,9 +489,9 @@ H5HP_insert(H5HP_t *heap, int val, void *obj)
} /* end if */
/* Insert new object at end of heap */
- heap->heap[heap->nobjs].val=val;
- heap->heap[heap->nobjs].obj=obj;
- heap->heap[heap->nobjs].obj->heap_loc=heap->nobjs;
+ heap->heap[heap->nobjs].val = val;
+ heap->heap[heap->nobjs].obj = (H5HP_info_t *)obj;
+ heap->heap[heap->nobjs].obj->heap_loc = heap->nobjs;
/* Restore heap condition */
if(heap->type==H5HP_MAX_HEAP) {
@@ -772,20 +772,20 @@ H5HP_incr(H5HP_t *heap, unsigned amt, void *_obj)
assert(heap->heap[0].obj==NULL);
/* Get the location of the object in the heap */
- obj_loc=obj->heap_loc;
- assert(obj_loc>0 && obj_loc<=heap->nobjs);
+ obj_loc = obj->heap_loc;
+ assert(obj_loc > 0 && obj_loc <= heap->nobjs);
/* Change the heap object's priority */
- heap->heap[obj_loc].val+=amt;
+ heap->heap[obj_loc].val += (int)amt;
/* Restore heap condition */
- if(heap->type==H5HP_MAX_HEAP) {
- if(H5HP_swim_max(heap,obj_loc)<0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRESTORE, FAIL, "unable to restore heap condition");
+ if(H5HP_MAX_HEAP == heap->type) {
+ if(H5HP_swim_max(heap, obj_loc) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRESTORE, FAIL, "unable to restore heap condition")
} /* end if */
else {
- if(H5HP_sink_min(heap,obj_loc)<0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRESTORE, FAIL, "unable to restore heap condition");
+ if(H5HP_sink_min(heap, obj_loc) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRESTORE, FAIL, "unable to restore heap condition")
} /* end else */
done:
@@ -896,25 +896,25 @@ done:
herr_t
H5HP_close(H5HP_t *heap)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5HP_close);
+ FUNC_ENTER_NOAPI_NOFUNC(H5HP_close)
/* Check args */
- assert(heap);
+ HDassert(heap);
/* Check internal consistency */
/* (Pre-condition) */
- assert(heap->nobjs<heap->nalloc);
- assert(heap->heap);
- assert((heap->type==H5HP_MAX_HEAP && heap->heap[0].val==INT_MAX) ||
- (heap->type==H5HP_MIN_HEAP && heap->heap[0].val==INT_MIN));
- assert(heap->heap[0].obj==NULL);
+ HDassert(heap->nobjs < heap->nalloc);
+ HDassert(heap->heap);
+ HDassert((heap->type == H5HP_MAX_HEAP && heap->heap[0].val == INT_MAX) ||
+ (heap->type == H5HP_MIN_HEAP && heap->heap[0].val == INT_MIN));
+ HDassert(NULL == heap->heap[0].obj);
/* Free internal structures for heap */
- H5FL_SEQ_FREE(H5HP_ent_t,heap->heap);
+ heap->heap = H5FL_SEQ_FREE(H5HP_ent_t, heap->heap);
/* Free actual heap object */
- H5FL_FREE(H5HP_t,heap);
+ heap = H5FL_FREE(H5HP_t, heap);
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5HP_close() */
diff --git a/src/H5I.c b/src/H5I.c
index 0b8b84e..b116424 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -90,7 +90,8 @@
typedef struct H5I_id_info_t {
hid_t id; /* ID for this info */
unsigned count; /* ref. count for this atom */
- void *obj_ptr; /* pointer associated with the atom */
+ unsigned app_count; /* ref. count of application visible atoms */
+ const void *obj_ptr; /* pointer associated with the atom */
struct H5I_id_info_t *next; /* link to next atom (in case of hash-clash)*/
} H5I_id_info_t;
@@ -145,10 +146,10 @@ DESCRIPTION
static herr_t
H5I_init_interface(void)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5I_init_interface);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5I_init_interface)
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5I_init_interface() */
/*-------------------------------------------------------------------------
@@ -174,31 +175,32 @@ H5I_term_interface(void)
{
H5I_id_type_t *type_ptr;
H5I_type_t type;
- int n=0;
+ int n = 0;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5I_term_interface);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5I_term_interface)
- if (H5_interface_initialize_g) {
+ if(H5_interface_initialize_g) {
/* How many types are still being used? */
- for (type=(H5I_type_t)0; type<H5I_next_type; H5_INC_ENUM(H5I_type_t,type)) {
- if ((type_ptr=H5I_id_type_list_g[type]) && type_ptr->id_list)
+ for(type = (H5I_type_t)0; type < H5I_next_type; H5_INC_ENUM(H5I_type_t, type)) {
+ if((type_ptr = H5I_id_type_list_g[type]) && type_ptr->id_list)
n++;
- }
+ } /* end for */
/* If no types are used then clean up */
- if (0==n) {
- for (type=(H5I_type_t)0; type<H5I_next_type; H5_INC_ENUM(H5I_type_t,type)) {
+ if(0 == n) {
+ for(type = (H5I_type_t)0; type < H5I_next_type; H5_INC_ENUM(H5I_type_t,type)) {
type_ptr = H5I_id_type_list_g[type];
H5MM_xfree(type_ptr);
H5I_id_type_list_g[type] = NULL;
- }
- }
+ } /* end for */
+ } /* end if */
/* Mark interface closed */
H5_interface_initialize_g = 0;
- }
- FUNC_LEAVE_NOAPI(n);
-}
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(n)
+} /* end H5I_term_interface() */
/*-------------------------------------------------------------------------
@@ -225,17 +227,20 @@ H5I_term_interface(void)
*
*-------------------------------------------------------------------------
*/
-H5I_type_t H5Iregister_type(size_t hash_size, unsigned reserved, H5I_free_t free_func)
+H5I_type_t
+H5Iregister_type(size_t hash_size, unsigned reserved, H5I_free_t free_func)
{
- H5I_type_t ret_value;
- FUNC_ENTER_API(H5Iregister_type, H5I_BADID);
+ H5I_type_t ret_value; /* Return value */
- /* Call H5I_register_type with a value of 0 to get a new type */
- ret_value = H5I_register_type((H5I_type_t)0, hash_size, reserved, free_func);
+ FUNC_ENTER_API(H5Iregister_type, H5I_BADID)
+ H5TRACE3("It", "zIux", hash_size, reserved, free_func);
+
+ /* Call H5I_register_type with a value of 0 to get a new type */
+ ret_value = H5I_register_type((H5I_type_t)0, hash_size, reserved, free_func);
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Iregister_type() */
/*-------------------------------------------------------------------------
@@ -275,100 +280,94 @@ done:
*
*-------------------------------------------------------------------------
*/
-
-H5I_type_t H5I_register_type(H5I_type_t type_id, size_t hash_size, unsigned reserved, H5I_free_t free_func)
+H5I_type_t
+H5I_register_type(H5I_type_t type_id, size_t hash_size, unsigned reserved,
+ H5I_free_t free_func)
{
- H5I_type_t ret_value=H5I_BADID; /* type ID to return */
- H5I_id_type_t *type_ptr = NULL; /*ptr to the atomic type*/
- int i;
- int done;
-
- FUNC_ENTER_NOAPI(H5I_register_type, H5I_BADID);
-
- /* Check that type_id is either a library type or zero */
- if(type_id < 0 || type_id >= H5I_NTYPES)
- {
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, H5I_BADID, "invalid type ID");
- }
-
- if(type_id == 0) /* Generate a new H5I_type_t value */
- {
- /* Increment the number of types*/
- if (H5I_next_type < MAX_NUM_TYPES)
- {
- ret_value = H5I_next_type;
- H5_INC_ENUM(H5I_type_t, H5I_next_type);
- }
- else
- {
- done = 0;
- /* Look for a free type to give out */
- for(i = H5I_NTYPES; i < MAX_NUM_TYPES && done==0; i++)
- {
- if(H5I_id_type_list_g[i] == NULL)
- {
- /* Found a free type ID */
- ret_value = (H5I_type_t)i;
- done = 1;
- }
- }
-
- /* Verify that we found a type to give out */
- if(done == 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5I_BADID, "Maximum number of ID types exceeded.");
- }
- }
- else /* type_id is a library type; use this value. */
- {
- ret_value = type_id;
- }
-
- /* Initialize the type */
+ H5I_id_type_t *type_ptr = NULL; /*ptr to the atomic type*/
+ H5I_type_t ret_value = H5I_BADID; /* type ID to return */
+
+ FUNC_ENTER_NOAPI(H5I_register_type, H5I_BADID)
+
+ /* Check that type_id is either a library type or zero */
+ if(type_id < 0 || type_id >= H5I_NTYPES)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, H5I_BADID, "invalid type ID")
+
+ if(type_id == 0) { /* Generate a new H5I_type_t value */
+ /* Increment the number of types*/
+ if(H5I_next_type < MAX_NUM_TYPES) {
+ ret_value = H5I_next_type;
+ H5_INC_ENUM(H5I_type_t, H5I_next_type);
+ }
+ else {
+ hbool_t done; /* Indicate that search was successful */
+ int i; /* Local index variable */
+
+ /* Look for a free type to give out */
+ done = FALSE;
+ for(i = H5I_NTYPES; i < MAX_NUM_TYPES && done == FALSE; i++) {
+ if(NULL == H5I_id_type_list_g[i]) {
+ /* Found a free type ID */
+ ret_value = (H5I_type_t)i;
+ done = TRUE;
+ } /* end if */
+ } /* end for */
+
+ /* Verify that we found a type to give out */
+ if(done == FALSE)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5I_BADID, "Maximum number of ID types exceeded.")
+ } /* end else */
+ } /* end if */
+ else /* type_id is a library type; use this value. */
+ ret_value = type_id;
+
+ /* Initialize the type */
+
/* Check arguments */
#ifdef HASH_SIZE_POWER_2
- if (!POWER_OF_TWO(hash_size) || hash_size == 1)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, H5I_BADID, "invalid hash size");
+ if(!POWER_OF_TWO(hash_size) || hash_size == 1)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, H5I_BADID, "invalid hash size")
#endif /* HASH_SIZE_POWER_2 */
- if (H5I_id_type_list_g[ret_value] == NULL) {
- /* Allocate the type information for new type */
- if (NULL==(type_ptr = H5MM_calloc(sizeof(H5I_id_type_t))))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, H5I_BADID, "memory allocation failed");
- H5I_id_type_list_g[ret_value] = type_ptr;
- } else {
- /* Get the pointer to the existing type */
- type_ptr = H5I_id_type_list_g[ret_value];
- }
-
- if (type_ptr->count == 0) {
- /* Initialize the ID type structure for new types */
- type_ptr->hash_size = hash_size;
- type_ptr->reserved = reserved;
- type_ptr->wrapped = 0;
- type_ptr->ids = 0;
- type_ptr->nextid = reserved;
- type_ptr->free_func = free_func;
- type_ptr->id_list = H5MM_calloc(hash_size*sizeof(H5I_id_info_t *));
- if (NULL==type_ptr->id_list)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, H5I_BADID, "memory allocation failed");
- }
+ if(NULL == H5I_id_type_list_g[ret_value]) {
+ /* Allocate the type information for new type */
+ if(NULL == (type_ptr = (H5I_id_type_t *)H5MM_calloc(sizeof(H5I_id_type_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5I_BADID, "memory allocation failed")
+ H5I_id_type_list_g[ret_value] = type_ptr;
+ } /* end if */
+ else {
+ /* Get the pointer to the existing type */
+ type_ptr = H5I_id_type_list_g[ret_value];
+ } /* end else */
+
+ if(type_ptr->count == 0) {
+ /* Initialize the ID type structure for new types */
+ type_ptr->hash_size = hash_size;
+ type_ptr->reserved = reserved;
+ type_ptr->wrapped = 0;
+ type_ptr->ids = 0;
+ type_ptr->nextid = reserved;
+ type_ptr->free_func = free_func;
+ type_ptr->id_list = (H5I_id_info_t **)H5MM_calloc(hash_size * sizeof(H5I_id_info_t *));
+ if(NULL == type_ptr->id_list)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5I_BADID, "memory allocation failed")
+ } /* end if */
/* Increment the count of the times this type has been initialized */
type_ptr->count++;
- done:
- if(ret_value == H5I_BADID) /* Clean up on error */
- {
- if (type_ptr != NULL)
- {
- H5MM_xfree(type_ptr->id_list);
- H5MM_xfree(type_ptr);
- }
- }
+done:
+ if(ret_value == H5I_BADID) { /* Clean up on error */
+ if(type_ptr != NULL) {
+ H5MM_xfree(type_ptr->id_list);
+ H5MM_xfree(type_ptr);
+ } /* end if */
+ } /* end if */
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_register_type() */
+
/*-------------------------------------------------------------------------
* Function: H5Itype_exists
*
@@ -387,21 +386,23 @@ H5I_type_t H5I_register_type(H5I_type_t type_id, size_t hash_size, unsigned rese
*
*-------------------------------------------------------------------------
*/
-htri_t H5Itype_exists(H5I_type_t type)
+htri_t
+H5Itype_exists(H5I_type_t type)
{
htri_t ret_value = TRUE; /* Return value */
- FUNC_ENTER_API(H5Itype_exists, FAIL);
+ FUNC_ENTER_API(H5Itype_exists, FAIL)
+ H5TRACE1("t", "It", type);
- if (type<=H5I_BADID || type>=H5I_next_type)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ if(type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
- if (H5I_id_type_list_g[type] == NULL)
+ if(NULL == H5I_id_type_list_g[type])
ret_value = FALSE;
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Itype_exists() */
/*-------------------------------------------------------------------------
@@ -428,37 +429,38 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t H5Inmembers(H5I_type_t type, hsize_t *num_members)
+herr_t
+H5Inmembers(H5I_type_t type, hsize_t *num_members)
{
int ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API(H5Inmembers, FAIL);
+ FUNC_ENTER_API(H5Inmembers, FAIL)
+ H5TRACE2("e", "It*h", type, num_members);
- if( H5I_IS_LIB_TYPE( type ) )
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
+ if(H5I_IS_LIB_TYPE(type))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type")
/* Validate parameters. This needs to be done here, instead of letting
* the private interface handle it, because the public interface throws
* an error when the supplied type does not exist.
*/
- if (type<=H5I_BADID || type>=H5I_next_type)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
- if (NULL==H5I_id_type_list_g[type])
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "supplied type does not exist");
+ if(type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
+ if(NULL == H5I_id_type_list_g[type])
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "supplied type does not exist")
- if (num_members)
- {
+ if(num_members) {
int members;
- if ((members = H5I_nmembers(type)) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTCOUNT, FAIL, "can't compute number of members");
+ if((members = H5I_nmembers(type)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTCOUNT, FAIL, "can't compute number of members")
- *num_members=(hsize_t)members;
- }
+ *num_members = (hsize_t)members;
+ } /* end if */
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Inmembers() */
/*-------------------------------------------------------------------------
@@ -484,19 +486,19 @@ H5I_nmembers(H5I_type_t type)
H5I_id_type_t *type_ptr = NULL;
int ret_value;
- FUNC_ENTER_NOAPI(H5I_nmembers, FAIL);
+ FUNC_ENTER_NOAPI(H5I_nmembers, FAIL)
- if (type<=H5I_BADID || type>=H5I_next_type)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
- if (NULL==(type_ptr=H5I_id_type_list_g[type]) || type_ptr->count<=0)
+ if(type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
+ if(NULL == (type_ptr = H5I_id_type_list_g[type]) || type_ptr->count <= 0)
HGOTO_DONE(0);
/* Set return value */
H5_ASSIGN_OVERFLOW(ret_value, type_ptr->ids, unsigned, int);
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_nmembers() */
/*-------------------------------------------------------------------------
@@ -517,22 +519,22 @@ done:
* Modifications:
*-------------------------------------------------------------------------
*/
-herr_t H5Iclear_type(H5I_type_t type, hbool_t force)
+herr_t
+H5Iclear_type(H5I_type_t type, hbool_t force)
{
- herr_t ret_value; /* Return value */
+ herr_t ret_value; /* Return value */
- FUNC_ENTER_API(H5Iclear_type, FAIL);
+ FUNC_ENTER_API(H5Iclear_type, FAIL)
+ H5TRACE2("e", "Itb", type, force);
- if( H5I_IS_LIB_TYPE( type ) )
- {
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
- }
+ if(H5I_IS_LIB_TYPE(type))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type")
- ret_value = H5I_clear_type(type, force);
+ ret_value = H5I_clear_type(type, force, TRUE);
- done:
- FUNC_LEAVE_API(ret_value);
-}
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Iclear_type() */
/*-------------------------------------------------------------------------
@@ -561,50 +563,57 @@ herr_t H5Iclear_type(H5I_type_t type, hbool_t force)
* things like property lists, files, etc. Objects that have a
* reference count larger than one are not affected unless FORCE
* is non-zero.
+ *
+ * Neil Fortner, 2008-08-08
+ * Added app_ref parameter. If app_ref is FALSE, then the
+ * application reference count is ignored (i.e. subtracted from
+ * the total reference count) when determining which id's to
+ * close.
*-------------------------------------------------------------------------
*/
herr_t
-H5I_clear_type(H5I_type_t type, hbool_t force)
+H5I_clear_type(H5I_type_t type, hbool_t force, hbool_t app_ref)
{
- H5I_id_type_t *type_ptr = NULL; /* ptr to the atomic type */
- H5I_id_info_t *cur=NULL; /* Current node being worked with */
- H5I_id_info_t *next=NULL; /* Next node in list */
- H5I_id_info_t *last=NULL; /* Last node seen */
- H5I_id_info_t *tmp=NULL; /* Temporary node ptr */
- int ret_value = SUCCEED;
- unsigned delete_node; /* Flag to indicate node should be removed from linked list */
- unsigned i;
+ H5I_id_type_t *type_ptr; /* ptr to the atomic type */
+ unsigned i; /* Local index variable */
+ int ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5I_clear_type, FAIL);
+ FUNC_ENTER_NOAPI(H5I_clear_type, FAIL)
- if (type <= H5I_BADID || type >= H5I_next_type)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ if(type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if (type_ptr == NULL || type_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
+ if(type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/*
* Call free method for all objects in type regardless of their reference
* counts. Ignore the return value from from the free method and remove
* object from type regardless if FORCE is non-zero.
*/
- for (i=0; i<type_ptr->hash_size; i++) {
- for (cur=type_ptr->id_list[i]; cur; cur=next) {
+ for(i = 0; i < type_ptr->hash_size; i++) {
+ H5I_id_info_t *cur; /* Current node being worked with */
+ H5I_id_info_t *next; /* Next node in list */
+
+ for(cur = type_ptr->id_list[i]; cur; cur = next) {
+ hbool_t delete_node; /* Flag to indicate node should be removed from linked list */
+
/*
* Do nothing to the object if the reference count is larger than
* one and forcing is off.
*/
- if (!force && cur->count>1) {
- next=cur->next;
+ if(!force && (cur->count - (!app_ref * cur->app_count)) > 1) {
+ next = cur->next;
continue;
} /* end if */
/* Check for a 'free' function and call it, if it exists */
- if (type_ptr->free_func && (type_ptr->free_func)(cur->obj_ptr)<0) {
- if (force) {
+ /* (Casting away const OK -QAK) */
+ if(type_ptr->free_func && (type_ptr->free_func)((void *)cur->obj_ptr) < 0) {
+ if(force) {
#ifdef H5I_DEBUG
- if (H5DEBUG(I)) {
+ if(H5DEBUG(I)) {
fprintf(H5DEBUG(I), "H5I: free type=%d obj=0x%08lx "
"failure ignored\n", (int)type,
(unsigned long)(cur->obj_ptr));
@@ -612,20 +621,23 @@ H5I_clear_type(H5I_type_t type, hbool_t force)
#endif /*H5I_DEBUG*/
/* Indicate node should be removed from list */
- delete_node=1;
+ delete_node = TRUE;
} /* end if */
else {
/* Indicate node should _NOT_ be remove from list */
- delete_node=0;
+ delete_node = FALSE;
} /* end else */
} /* end if */
else {
/* Indicate node should be removed from list */
- delete_node=1;
+ delete_node = TRUE;
} /* end else */
/* Check if we should delete this node or not */
if(delete_node) {
+ H5I_id_info_t *last; /* Last node seen */
+ H5I_id_info_t *tmp; /* Temporary node ptr */
+
/* Decrement the number of IDs in the type */
(type_ptr->ids)--;
@@ -637,28 +649,28 @@ H5I_clear_type(H5I_type_t type, hbool_t force)
/* list, because the node's 'free' callback could have */
/* make an H5I call, which could potentially change the */
/* order of the nodes on the list - QAK) */
- last=NULL;
- tmp=type_ptr->id_list[i];
- while(tmp!=cur) {
- assert(tmp!=NULL);
- last=tmp;
- tmp=tmp->next;
+ last = NULL;
+ tmp = type_ptr->id_list[i];
+ while(tmp != cur) {
+ HDassert(tmp != NULL);
+ last = tmp;
+ tmp = tmp->next;
} /* end while */
/* Delete the node from the list */
- if(last==NULL) {
+ if(NULL == last) {
/* Node at head of list, just advance the list head to next node */
- assert(type_ptr->id_list[i]==cur);
+ HDassert(type_ptr->id_list[i] == cur);
type_ptr->id_list[i] = next;
} /* end if */
else {
/* Node in middle of list, jump over it */
- assert(last->next==cur);
- last->next=next;
+ HDassert(last->next == cur);
+ last->next = next;
} /* end else */
/* Free the node */
- H5FL_FREE(H5I_id_info_t,cur);
+ (void)H5FL_FREE(H5I_id_info_t, cur);
} /* end if */
else {
/* Advance to next node */
@@ -668,8 +680,8 @@ H5I_clear_type(H5I_type_t type, hbool_t force)
} /* end for */
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_clear_type() */
/*-------------------------------------------------------------------------
@@ -684,28 +696,28 @@ done:
* Return: Zero on success/Negative on failure
*
* Programmer: Nathaniel Furrer
- * James Laird
+ * James Laird
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-herr_t H5Idestroy_type(H5I_type_t type)
+herr_t
+H5Idestroy_type(H5I_type_t type)
{
- herr_t ret_value;
+ herr_t ret_value; /* Return value */
- FUNC_ENTER_API(H5Idestroy_type, FAIL);
+ FUNC_ENTER_API(H5Idestroy_type, FAIL)
+ H5TRACE1("e", "It", type);
- if( H5I_IS_LIB_TYPE( type ) )
- {
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
- }
+ if(H5I_IS_LIB_TYPE(type))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type")
- ret_value = H5I_destroy_type(type);
+ ret_value = H5I_destroy_type(type);
- done:
- FUNC_LEAVE_API(ret_value);
-}
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Idestroy_type() */
/*-------------------------------------------------------------------------
@@ -719,37 +731,39 @@ herr_t H5Idestroy_type(H5I_type_t type)
* Return: Zero on success/Negative on failure
*
* Programmer: Nathaniel Furrer
- * James Laird
+ * James Laird
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-herr_t H5I_destroy_type(H5I_type_t type)
+herr_t
+H5I_destroy_type(H5I_type_t type)
{
- herr_t ret_value = FAIL;
- H5I_id_type_t *type_ptr = NULL; /* ptr to the atomic type */
+ H5I_id_type_t *type_ptr; /* ptr to the atomic type */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5I_destroy_type, FAIL);
+ FUNC_ENTER_NOAPI(H5I_destroy_type, FAIL)
- if (type <= H5I_BADID || type >= H5I_next_type)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ if(type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if (type_ptr == NULL || type_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
+ if(type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
- H5I_clear_type(type, TRUE);
- H5E_clear_stack(NULL); /*don't care about errors*/
- H5MM_xfree(type_ptr->id_list);
+ /* Close/clear/destroy all IDs for this type */
+ H5I_clear_type(type, TRUE, FALSE);
+ H5E_clear_stack(NULL); /*don't care about errors*/
- H5MM_free(type_ptr);
- H5I_id_type_list_g[type] = NULL;
- ret_value = 0;
+ H5MM_xfree(type_ptr->id_list);
+
+ H5MM_free(type_ptr);
+ H5I_id_type_list_g[type] = NULL;
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_destroy_type() */
/*-------------------------------------------------------------------------
@@ -768,22 +782,22 @@ done:
*
*-------------------------------------------------------------------------
*/
-hid_t H5Iregister(H5I_type_t type, void *object)
+hid_t
+H5Iregister(H5I_type_t type, const void *object)
{
- hid_t ret_value; /* Return value */
+ hid_t ret_value; /* Return value */
- FUNC_ENTER_API(H5Iregister, H5I_INVALID_HID);
+ FUNC_ENTER_API(H5Iregister, H5I_INVALID_HID)
+ H5TRACE2("i", "It*x", type, object);
- if( H5I_IS_LIB_TYPE( type ) )
- {
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
- }
+ if(H5I_IS_LIB_TYPE(type))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type")
- ret_value = H5I_register(type, object);
+ ret_value = H5I_register(type, object, TRUE);
- done:
- FUNC_LEAVE_API(ret_value);
-}
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Iregister() */
/*-------------------------------------------------------------------------
@@ -805,41 +819,47 @@ hid_t H5Iregister(H5I_type_t type, void *object)
*
* Modifications:
*
+ * Neil Fortner, 7 Aug 2008
+ * Added app_ref parameter and support for the app_count field, to
+ * distiguish between reference count from the library and from the
+ * application.
+ *
*-------------------------------------------------------------------------
*/
hid_t
-H5I_register(H5I_type_t type, void *object)
+H5I_register(H5I_type_t type, const void *object, hbool_t app_ref)
{
- H5I_id_type_t *type_ptr=NULL; /*ptr to the type */
- H5I_id_info_t *id_ptr=NULL; /*ptr to the new ID information */
+ H5I_id_type_t *type_ptr; /*ptr to the type */
+ H5I_id_info_t *id_ptr; /*ptr to the new ID information */
hid_t new_id; /*new ID */
unsigned hash_loc; /*new item's hash table location*/
hid_t next_id; /*next ID to check */
- hid_t ret_value=SUCCEED; /*return value */
H5I_id_info_t *curr_id; /*ptr to the current atom */
unsigned i; /*counter */
+ hid_t ret_value = SUCCEED; /*return value */
- FUNC_ENTER_NOAPI(H5I_register, FAIL);
+ FUNC_ENTER_NOAPI(H5I_register, FAIL)
/* Check arguments */
- if (type <= H5I_BADID || type >= H5I_next_type)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ if(type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if (type_ptr == NULL || type_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
- if ((id_ptr = H5FL_MALLOC(H5I_id_info_t)) == NULL)
- HGOTO_ERROR(H5E_ATOM, H5E_NOSPACE, FAIL, "memory allocation failed");
+ if(NULL == type_ptr || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
+ if(NULL == (id_ptr = H5FL_MALLOC(H5I_id_info_t)))
+ HGOTO_ERROR(H5E_ATOM, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Create the struct & it's ID */
new_id = H5I_MAKE(type, type_ptr->nextid);
id_ptr->id = new_id;
id_ptr->count = 1; /*initial reference count*/
+ id_ptr->app_count = !!app_ref;
id_ptr->obj_ptr = object;
id_ptr->next = NULL;
/* hash bucket already full, prepend to front of chain */
- hash_loc = type_ptr->nextid % (unsigned) type_ptr->hash_size;
- if (type_ptr->id_list[hash_loc] != NULL)
+ hash_loc = type_ptr->nextid % (unsigned)type_ptr->hash_size;
+ if(type_ptr->id_list[hash_loc] != NULL)
id_ptr->next = type_ptr->id_list[hash_loc];
/* Insert into the type */
@@ -852,53 +872,55 @@ H5I_register(H5I_type_t type, void *object)
* wrapping around, thus necessitating checking for duplicate IDs being
* handed out.
*/
- if (type_ptr->nextid > (unsigned)ID_MASK) {
+ if(type_ptr->nextid > (unsigned)ID_MASK) {
type_ptr->wrapped = 1;
type_ptr->nextid = type_ptr->reserved;
- }
+ } /* end if */
/*
* If we've wrapped around then we need to check for duplicate id's being
* handed out.
*/
- if (type_ptr->wrapped) {
+ if(type_ptr->wrapped) {
/*
* Make sure we check all available ID's. If we're about at the end
* of the range then wrap around and check the beginning values. If
* we check all possible values and didn't find any free ones *then*
* we can fail.
*/
- for (i=type_ptr->reserved; i<ID_MASK; i++) {
+ for(i = type_ptr->reserved; i < ID_MASK; i++) {
/* Handle end of range by wrapping to beginning */
- if (type_ptr->nextid>(unsigned)ID_MASK)
+ if(type_ptr->nextid > (unsigned)ID_MASK)
type_ptr->nextid = type_ptr->reserved;
/* new ID to check for */
next_id = H5I_MAKE(type, type_ptr->nextid);
- hash_loc = H5I_LOC (type_ptr->nextid, type_ptr->hash_size);
+ hash_loc = H5I_LOC(type_ptr->nextid, type_ptr->hash_size);
curr_id = type_ptr->id_list[hash_loc];
- if (curr_id == NULL)
+ if(curr_id == NULL)
break; /* Ha! this is not likely... */
- while (curr_id) {
- if (curr_id->id == next_id)
+ while(curr_id) {
+ if(curr_id->id == next_id)
break;
curr_id = curr_id->next;
- }
- if (!curr_id)
+ } /* end while */
+ if(!curr_id)
break; /* must not have found a match */
type_ptr->nextid++;
- }
+ } /* end for */
- if (i>=(unsigned)ID_MASK)
+ if(i >= (unsigned)ID_MASK)
/* All the IDs are gone! */
- HGOTO_ERROR(H5E_ATOM, H5E_NOIDS, FAIL, "no IDs available in type");
- }
+ HGOTO_ERROR(H5E_ATOM, H5E_NOIDS, FAIL, "no IDs available in type")
+ } /* end if */
+
+ /* Set return value */
ret_value = new_id;
- done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_register() */
/*-------------------------------------------------------------------------
@@ -920,20 +942,21 @@ H5I_register(H5I_type_t type, void *object)
void *
H5I_object(hid_t id)
{
- H5I_id_info_t *id_ptr = NULL; /*ptr to the new atom */
+ H5I_id_info_t *id_ptr; /*ptr to the new atom */
void *ret_value = NULL; /*return value */
- FUNC_ENTER_NOAPI(H5I_object, NULL);
+ FUNC_ENTER_NOAPI(H5I_object, NULL)
/* General lookup of the ID */
- if (NULL!=(id_ptr = H5I_find_id(id))) {
+ if(NULL != (id_ptr = H5I_find_id(id))) {
/* Get the object pointer to return */
- ret_value = id_ptr->obj_ptr;
+ /* (Casting away const OK -QAK) */
+ ret_value = (void *)id_ptr->obj_ptr;
} /* end if */
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end if */
/*-------------------------------------------------------------------------
@@ -956,23 +979,24 @@ done:
*
*-------------------------------------------------------------------------
*/
-void *H5Iobject_verify(hid_t id, H5I_type_t id_type)
+void *
+H5Iobject_verify(hid_t id, H5I_type_t id_type)
{
- void * ret_value; /* Return value */
+ void * ret_value; /* Return value */
- FUNC_ENTER_API(H5Iobject_verify, NULL);
+ FUNC_ENTER_API(H5Iobject_verify, NULL)
- if( H5I_IS_LIB_TYPE( id_type ) )
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type")
+ if(H5I_IS_LIB_TYPE(id_type))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type")
- if(id_type < 1 || id_type >= H5I_next_type)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "identifier has invalid type")
+ if(id_type < 1 || id_type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "identifier has invalid type")
- ret_value = H5I_object_verify(id, id_type);
+ ret_value = H5I_object_verify(id, id_type);
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Iobject_verify() */
/*-------------------------------------------------------------------------
@@ -999,18 +1023,19 @@ H5I_object_verify(hid_t id, H5I_type_t id_type)
H5I_id_info_t *id_ptr = NULL; /*ptr to the new atom */
void *ret_value = NULL; /*return value */
- FUNC_ENTER_NOAPI(H5I_object_verify, NULL);
+ FUNC_ENTER_NOAPI(H5I_object_verify, NULL)
- assert(id_type>=1 && id_type<H5I_next_type);
+ HDassert(id_type >= 1 && id_type < H5I_next_type);
/* Verify that the type of the ID is correct & lookup the ID */
- if(id_type == H5I_TYPE(id) && NULL!=(id_ptr = H5I_find_id(id))) {
+ if(id_type == H5I_TYPE(id) && NULL != (id_ptr = H5I_find_id(id))) {
/* Get the object pointer to return */
- ret_value = id_ptr->obj_ptr;
+ /* (Casting away const OK -QAK) */
+ ret_value = (void *)id_ptr->obj_ptr;
} /* end if */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5I_object_verify() */
@@ -1038,16 +1063,16 @@ H5I_get_type(hid_t id)
{
H5I_type_t ret_value = H5I_BADID;
- FUNC_ENTER_NOAPI(H5I_get_type, H5I_BADID);
+ FUNC_ENTER_NOAPI(H5I_get_type, H5I_BADID)
- if (id>0)
+ if(id > 0)
ret_value = H5I_TYPE(id);
- assert(ret_value>=H5I_BADID && ret_value<H5I_next_type);
+ HDassert(ret_value >= H5I_BADID && ret_value < H5I_next_type);
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_get_type() */
/*-------------------------------------------------------------------------
@@ -1073,19 +1098,19 @@ done:
H5I_type_t
H5Iget_type(hid_t id)
{
- H5I_type_t ret_value = H5I_BADID;
+ H5I_type_t ret_value = H5I_BADID; /* Return value */
- FUNC_ENTER_API(H5Iget_type, H5I_BADID);
+ FUNC_ENTER_API(H5Iget_type, H5I_BADID)
H5TRACE1("It", "i", id);
ret_value = H5I_get_type(id);
- if (ret_value <= H5I_BADID || ret_value >= H5I_next_type || NULL==H5I_object(id))
+ if(ret_value <= H5I_BADID || ret_value >= H5I_next_type || NULL == H5I_object(id))
HGOTO_DONE(H5I_BADID);
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Iget_type() */
/*-------------------------------------------------------------------------
@@ -1108,21 +1133,22 @@ done:
*
*-------------------------------------------------------------------------
*/
-void *H5Iremove_verify(hid_t id, H5I_type_t id_type)
+void *
+H5Iremove_verify(hid_t id, H5I_type_t id_type)
{
- void * ret_value; /* Return value */
+ void * ret_value; /* Return value */
- FUNC_ENTER_API(H5Iremove_verify, NULL);
+ FUNC_ENTER_API(H5Iremove_verify, NULL)
- if( H5I_IS_LIB_TYPE( id_type ) )
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type")
+ if(H5I_IS_LIB_TYPE(id_type))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type")
- /* Remove the id */
- ret_value = H5I_remove_verify(id, id_type);
+ /* Remove the id */
+ ret_value = H5I_remove_verify(id, id_type);
- done:
- FUNC_LEAVE_API(ret_value);
-}
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Iremove_verify() */
/*-------------------------------------------------------------------------
@@ -1149,19 +1175,17 @@ H5I_remove_verify(hid_t id, H5I_type_t id_type)
{
void * ret_value = NULL; /*return value */
- FUNC_ENTER_NOAPI(H5I_remove_verify, NULL);
+ FUNC_ENTER_NOAPI(H5I_remove_verify, NULL)
- /* Argument checking will be performed by H5I_remove() */
+ /* Argument checking will be performed by H5I_remove() */
/* Verify that the type of the ID is correct */
if(id_type == H5I_TYPE(id))
- {
ret_value = H5I_remove(id);
- }
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_remove_verify() */
@@ -1185,57 +1209,58 @@ done:
void *
H5I_remove(hid_t id)
{
- H5I_id_type_t *type_ptr = NULL;/*ptr to the atomic type */
+ H5I_id_type_t *type_ptr; /*ptr to the atomic type */
H5I_id_info_t *curr_id; /*ptr to the current atom */
H5I_id_info_t *last_id; /*ptr to the last atom */
H5I_type_t type; /*atom's atomic type */
unsigned hash_loc; /*atom's hash table location */
void * ret_value = NULL; /*return value */
- FUNC_ENTER_NOAPI(H5I_remove, NULL);
+ FUNC_ENTER_NOAPI(H5I_remove, NULL)
/* Check arguments */
type = H5I_TYPE(id);
- if (type <= H5I_BADID || type >= H5I_next_type)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid type number");
+ if(type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if (type_ptr == NULL || type_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type");
+ if(type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type")
/* Get the bucket in which the ID is located */
- hash_loc = (unsigned) H5I_LOC(id, type_ptr->hash_size);
+ hash_loc = (unsigned)H5I_LOC(id, type_ptr->hash_size);
curr_id = type_ptr->id_list[hash_loc];
- if (curr_id == NULL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "invalid ID");
+ if(NULL == curr_id)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "invalid ID")
last_id = NULL;
- while (curr_id != NULL) {
- if (curr_id->id == id)
+ while(curr_id != NULL) {
+ if(curr_id->id == id)
break;
last_id = curr_id;
curr_id = curr_id->next;
- }
+ } /* end while */
- if (curr_id != NULL) {
- if (last_id == NULL) {
+ if(curr_id != NULL) {
+ if(last_id == NULL) {
/* ID is the first in the chain */
type_ptr->id_list[hash_loc] = curr_id->next;
} else {
last_id->next = curr_id->next;
}
- ret_value = curr_id->obj_ptr;
- H5FL_FREE(H5I_id_info_t,curr_id);
+ /* (Casting away const OK -QAK) */
+ ret_value = (void *)curr_id->obj_ptr;
+ (void)H5FL_FREE(H5I_id_info_t, curr_id);
} else {
/* couldn't find the ID in the proper place */
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "invalid ID");
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "invalid ID")
}
/* Decrement the number of IDs in the type */
(type_ptr->ids)--;
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_remove() */
/*-------------------------------------------------------------------------
@@ -1260,19 +1285,19 @@ H5Idec_ref(hid_t id)
{
int ret_value; /* Return value */
- FUNC_ENTER_API(H5Idec_ref, FAIL);
+ FUNC_ENTER_API(H5Idec_ref, FAIL)
H5TRACE1("Is", "i", id);
/* Check arguments */
- if (id<0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID");
+ if(id < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID")
/* Do actual decrement operation */
- if((ret_value = H5I_dec_ref(id))<0)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTDEC, FAIL, "can't decrement ID ref count");
+ if((ret_value = H5I_dec_ref(id, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTDEC, FAIL, "can't decrement ID ref count")
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* end H5Idec_ref() */
@@ -1312,32 +1337,37 @@ done:
* count 1. This feature is needed by file close with H5F_CLOSE_SEMI
* value.
*
+ * Neil Fortner, 7 Aug 2008
+ * Added app_ref parameter and support for the app_count field, to
+ * distiguish between reference count from the library and from the
+ * application.
+ *
*-------------------------------------------------------------------------
*/
int
-H5I_dec_ref(hid_t id)
+H5I_dec_ref(hid_t id, hbool_t app_ref)
{
H5I_type_t type; /*type the object is in*/
H5I_id_type_t *type_ptr; /*ptr to the type */
H5I_id_info_t *id_ptr; /*ptr to the new ID */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5I_dec_ref, FAIL);
+ FUNC_ENTER_NOAPI(H5I_dec_ref, FAIL)
/* Sanity check */
- assert(id>=0);
+ HDassert(id >= 0);
/* Check arguments */
type = H5I_TYPE(id);
- if (type <= H5I_BADID || type >= H5I_next_type)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ if(type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if (type_ptr == NULL || type_ptr->count <= 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ if(NULL == type_ptr || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
/* General lookup of the ID */
- if ((id_ptr=H5I_find_id(id))==NULL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID");
+ if(NULL == (id_ptr=H5I_find_id(id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID")
/*
* If this is the last reference to the object then invoke the type's
@@ -1349,20 +1379,25 @@ H5I_dec_ref(hid_t id)
*
* Beware: the free method may call other H5I functions.
*/
- if (1==id_ptr->count) {
- if (!type_ptr->free_func || (type_ptr->free_func)(id_ptr->obj_ptr)>=0) {
+ if(1 == id_ptr->count) {
+ /* (Casting away const OK -QAK) */
+ if(!type_ptr->free_func || (type_ptr->free_func)((void *)id_ptr->obj_ptr) >= 0) {
H5I_remove(id);
ret_value = 0;
} else {
ret_value = FAIL;
}
} else {
- ret_value = --(id_ptr->count);
+ --(id_ptr->count);
+ if (app_ref)
+ --(id_ptr->app_count);
+ HDassert(id_ptr->count >= id_ptr->app_count);
+ ret_value = app_ref ? id_ptr->app_count : id_ptr->count;
}
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_dec_ref() */
/*-------------------------------------------------------------------------
@@ -1385,19 +1420,19 @@ H5Iinc_ref(hid_t id)
{
int ret_value; /* Return value */
- FUNC_ENTER_API(H5Iinc_ref, FAIL);
+ FUNC_ENTER_API(H5Iinc_ref, FAIL)
H5TRACE1("Is", "i", id);
/* Check arguments */
- if (id<0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID");
+ if(id < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID")
/* Do actual increment operation */
- if((ret_value = H5I_inc_ref(id))<0)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count");
+ if((ret_value = H5I_inc_ref(id, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count")
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* end H5Iinc_ref() */
@@ -1415,39 +1450,49 @@ done:
*
* Modifications:
*
+ * Neil Fortner, 7 Aug 2008
+ * Added app_ref parameter and support for the app_count field, to
+ * distiguish between reference count from the library and from the
+ * application.
+ *
*-------------------------------------------------------------------------
*/
int
-H5I_inc_ref(hid_t id)
+H5I_inc_ref(hid_t id, hbool_t app_ref)
{
H5I_type_t type; /*type the object is in*/
H5I_id_type_t *type_ptr; /*ptr to the type */
H5I_id_info_t *id_ptr; /*ptr to the ID */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5I_inc_ref, FAIL);
+ FUNC_ENTER_NOAPI(H5I_inc_ref, FAIL)
/* Sanity check */
- assert(id>=0);
+ HDassert(id >= 0);
/* Check arguments */
type = H5I_TYPE(id);
- if (type <= H5I_BADID || type >= H5I_next_type)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ if(type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if (!type_ptr || type_ptr->count<=0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
+ if(!type_ptr || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/* General lookup of the ID */
- if (NULL==(id_ptr=H5I_find_id(id)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID");
+ if(NULL == (id_ptr = H5I_find_id(id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID")
+
+ /* Adjust reference counts */
+ ++(id_ptr->count);
+ if (app_ref)
+ ++(id_ptr->app_count);
/* Set return value */
- ret_value=++(id_ptr->count);
+ ret_value = app_ref ? id_ptr->app_count : id_ptr->count;
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_inc_ref() */
/*-------------------------------------------------------------------------
@@ -1470,19 +1515,19 @@ H5Iget_ref(hid_t id)
{
int ret_value; /* Return value */
- FUNC_ENTER_API(H5Iget_ref, FAIL);
+ FUNC_ENTER_API(H5Iget_ref, FAIL)
H5TRACE1("Is", "i", id);
/* Check arguments */
- if (id<0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID");
+ if(id < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID")
/* Do actual retrieve operation */
- if((ret_value = H5I_get_ref(id))<0)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID ref count");
+ if((ret_value = H5I_get_ref(id, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID ref count")
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* end H5Iget_ref() */
@@ -1500,38 +1545,43 @@ done:
*
* Modifications:
*
+ * Neil Fortner, 7 Aug 2008
+ * Added app_ref parameter and support for the app_count field, to
+ * distiguish between reference count from the library and from the
+ * application.
+ *
*-------------------------------------------------------------------------
*/
int
-H5I_get_ref(hid_t id)
+H5I_get_ref(hid_t id, hbool_t app_ref)
{
H5I_type_t type; /*type the object is in*/
H5I_id_type_t *type_ptr; /*ptr to the type */
H5I_id_info_t *id_ptr; /*ptr to the ID */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5I_get_ref, FAIL);
+ FUNC_ENTER_NOAPI(H5I_get_ref, FAIL)
/* Sanity check */
- assert(id>=0);
+ HDassert(id >= 0);
/* Check arguments */
type = H5I_TYPE(id);
- if (type <= H5I_BADID || type >= H5I_next_type)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ if(type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if (!type_ptr || type_ptr->count<=0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
+ if(!type_ptr || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/* General lookup of the ID */
- if (NULL==(id_ptr=H5I_find_id(id)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID");
+ if(NULL == (id_ptr = H5I_find_id(id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID")
/* Set return value */
- ret_value=id_ptr->count;
+ ret_value = app_ref ? id_ptr->app_count : id_ptr->count;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5I_get_ref() */
@@ -1556,24 +1606,22 @@ H5Iinc_type_ref(H5I_type_t type)
{
int ret_value; /* Return value */
- FUNC_ENTER_API(H5Iinc_type_ref, FAIL);
+ FUNC_ENTER_API(H5Iinc_type_ref, FAIL)
H5TRACE1("Is", "It", type);
/* Check arguments */
- if (type<=0 || type >= H5I_next_type)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID type");
+ if(type <= 0 || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID type")
- if( H5I_IS_LIB_TYPE( type ) )
- {
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
- }
+ if(H5I_IS_LIB_TYPE(type))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type")
/* Do actual increment operation */
- if((ret_value = H5I_inc_type_ref(type))<0)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID type ref count");
+ if((ret_value = H5I_inc_type_ref(type)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID type ref count")
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* end H5Iinc_ref() */
@@ -1600,22 +1648,22 @@ H5I_inc_type_ref(H5I_type_t type)
H5I_id_type_t *type_ptr; /* ptr to the type */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5I_inc_type_ref, FAIL);
+ FUNC_ENTER_NOAPI(H5I_inc_type_ref, FAIL)
/* Sanity check */
- assert(type>0 && type < H5I_next_type);
+ HDassert(type > 0 && type < H5I_next_type);
/* Check arguments */
type_ptr = H5I_id_type_list_g[type];
- if (!type_ptr )
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
+ if(!type_ptr)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/* Set return value */
- ret_value=++(type_ptr->count);
+ ret_value = ++(type_ptr->count);
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_inc_type_ref() */
/*-------------------------------------------------------------------------
@@ -1642,22 +1690,22 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t H5Idec_type_ref(H5I_type_t type)
+herr_t
+H5Idec_type_ref(H5I_type_t type)
{
- herr_t ret_value;
+ herr_t ret_value; /* Return value */
- FUNC_ENTER_API(H5Idec_type_ref, FAIL);
+ FUNC_ENTER_API(H5Idec_type_ref, FAIL)
+ H5TRACE1("e", "It", type);
- if( H5I_IS_LIB_TYPE( type ) )
- {
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
- }
+ if(H5I_IS_LIB_TYPE(type))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type")
- ret_value = H5I_dec_type_ref(type);
+ ret_value = H5I_dec_type_ref(type);
- done:
- FUNC_LEAVE_API(ret_value);
-}
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Idec_type_ref() */
/*-------------------------------------------------------------------------
@@ -1688,38 +1736,36 @@ herr_t H5Idec_type_ref(H5I_type_t type)
herr_t
H5I_dec_type_ref(H5I_type_t type)
{
- H5I_id_type_t *type_ptr = NULL; /* ptr to the atomic type */
- herr_t ret_value = FAIL;
+ H5I_id_type_t *type_ptr; /* Pointer to the ID type */
+ herr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5I_dec_type_ref, FAIL);
+ FUNC_ENTER_NOAPI(H5I_dec_type_ref, FAIL)
- if (type <= H5I_BADID || type >= H5I_next_type)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ if(type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if (type_ptr == NULL || type_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
+ if(type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/*
* Decrement the number of users of the atomic type. If this is the
* last user of the type then release all atoms from the type and
- * free all memory it used. The free function is invoked for each atom
- * being freed.
+ * free all memory it used. The free function is invoked for each atom
+ * being freed.
*/
- if (1==type_ptr->count)
- {
- H5I_destroy_type(type);
- ret_value = 0;
- }
- else
- {
+ if(1 == type_ptr->count) {
+ H5I_destroy_type(type);
+ ret_value = 0;
+ } /* end if */
+ else {
--(type_ptr->count);
- ret_value = type_ptr->count;
- }
+ ret_value = type_ptr->count;
+ } /* end else */
- done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_dec_type_ref() */
/*-------------------------------------------------------------------------
@@ -1743,24 +1789,22 @@ H5Iget_type_ref(H5I_type_t type)
{
int ret_value; /* Return value */
- FUNC_ENTER_API(H5Iget_type_ref, FAIL);
+ FUNC_ENTER_API(H5Iget_type_ref, FAIL)
H5TRACE1("Is", "It", type);
/* Check arguments */
- if (type<=0 || type >= H5I_next_type)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID type");
+ if(type <= 0 || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID type")
- if( H5I_IS_LIB_TYPE( type ) )
- {
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
- }
+ if(H5I_IS_LIB_TYPE(type))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type")
/* Do actual retrieve operation */
- if((ret_value = H5I_get_type_ref(type))<0)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID type ref count");
+ if((ret_value = H5I_get_type_ref(type)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID type ref count")
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* end H5Iget_ref() */
@@ -1787,22 +1831,65 @@ H5I_get_type_ref(H5I_type_t type)
H5I_id_type_t *type_ptr; /*ptr to the type */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5I_get_type_ref, FAIL);
+ FUNC_ENTER_NOAPI(H5I_get_type_ref, FAIL)
/* Sanity check */
- assert(type>=0);
+ HDassert(type >= 0);
/* Check arguments */
type_ptr = H5I_id_type_list_g[type];
- if (!type_ptr )
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
+ if(!type_ptr)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/* Set return value */
- ret_value=type_ptr->count;
+ ret_value = type_ptr->count;
done:
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5I_get_ref() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_get_type_ref() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Iis_valid
+ *
+ * Purpose: Check if the given id is valid. An id is valid if it is in
+ * use and has an application reference count of at least 1.
+ *
+ * Return: Success: TRUE if the id is valid, FALSE otherwise.
+ *
+ * Failure: Negative (never fails currently)
+ *
+ * Programmer: Neil Fortner
+ * Friday, October 31, 2008 (boo)
+ *
+ * Modifications:
+ * Raymond Lu
+ * 1 April 2009 (Believe it or not!)
+ * Moved the argument check down to H5I_find_id because other
+ * caller functions may pass in some invalid IDs to H5I_find_id.
+ * It used to do assertion check.
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5Iis_valid(hid_t id)
+{
+ H5I_id_info_t *id_ptr; /* ptr to the ID */
+ htri_t ret_value = TRUE; /* Return value */
+
+ FUNC_ENTER_API(H5Iis_valid, FAIL)
+ H5TRACE1("t", "i", id);
+
+ /* Find the ID */
+ if (NULL == (id_ptr = H5I_find_id(id)))
+ ret_value = FALSE;
+
+ /* Check if the found id is an internal id */
+ else if (!id_ptr->app_count)
+ ret_value = FALSE;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Iis_valid() */
/*-------------------------------------------------------------------------
@@ -1829,16 +1916,17 @@ done:
*
*-------------------------------------------------------------------------
*/
-void *H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key)
+void *
+H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key)
{
void * ret_value; /* Return value */
FUNC_ENTER_API(H5Isearch, NULL)
- if( H5I_IS_LIB_TYPE( type ) )
+ if(H5I_IS_LIB_TYPE(type))
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type")
- ret_value = H5I_search(type, func, key);
+ ret_value = H5I_search(type, func, key, TRUE);
done:
FUNC_LEAVE_API(ret_value)
@@ -1866,44 +1954,50 @@ done:
* Programmer: Robb Matzke
* Friday, February 19, 1999
*
- * Modifications:
+ * Modifications: Neil Fortner
+ * Wednesday, October 1, 2008
+ * Added app_ref parameter. When set to TRUE, the function will only
+ * operate on ids that have a nonzero application reference count.
*
*-------------------------------------------------------------------------
*/
void *
-H5I_search(H5I_type_t type, H5I_search_func_t func, void *key)
+H5I_search(H5I_type_t type, H5I_search_func_t func, void *key, hbool_t app_ref)
{
- H5I_id_type_t *type_ptr = NULL; /*ptr to the type */
- H5I_id_info_t *id_ptr = NULL; /*ptr to the new ID */
- H5I_id_info_t *next_id = NULL; /*ptr to the next ID */
- unsigned i; /*counter */
+ H5I_id_type_t *type_ptr; /*ptr to the type */
void *ret_value = NULL; /*return value */
- FUNC_ENTER_NOAPI(H5I_search, NULL);
+ FUNC_ENTER_NOAPI(H5I_search, NULL)
/* Check arguments */
- if (type <= H5I_BADID || type >= H5I_next_type)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid type number");
+ if(type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if (type_ptr == NULL || type_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type");
+ if(type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type")
/* Only iterate through hash table if there are IDs in group */
if(type_ptr->ids > 0) {
+ H5I_id_info_t *id_ptr; /*ptr to the new ID */
+ H5I_id_info_t *next_id; /*ptr to the next ID */
+ unsigned i; /*counter */
+
/* Start at the beginning of the array */
- for (i=0; i<type_ptr->hash_size; i++) {
+ for(i = 0; i < type_ptr->hash_size; i++) {
id_ptr = type_ptr->id_list[i];
- while (id_ptr) {
- next_id= id_ptr->next; /* Protect against ID being deleted in callback */
- if ((*func)(id_ptr->obj_ptr, id_ptr->id, key))
- HGOTO_DONE(id_ptr->obj_ptr); /*found the item*/
+ while(id_ptr) {
+ next_id = id_ptr->next; /* Protect against ID being deleted in callback */
+ /* (Casting away const OK -QAK) */
+ if((!app_ref || id_ptr->app_count) && (*func)((void *)id_ptr->obj_ptr, id_ptr->id, key))
+ /* (Casting away const OK -QAK) */
+ HGOTO_DONE((void *)id_ptr->obj_ptr); /*found the item*/
id_ptr = next_id;
} /* end while */
} /* end for */
} /* end if */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5I_search() */
@@ -1920,7 +2014,9 @@ done:
* Programmer:
*
* Modifications:
- *
+ * Raymond Lu
+ * 1 April 2009 (Believe it or not!)
+ * Added argument check, took away assertion check.
*-------------------------------------------------------------------------
*/
static H5I_id_info_t *
@@ -1931,42 +2027,45 @@ H5I_find_id(hid_t id)
H5I_id_info_t *id_ptr; /*ptr to the new ID */
H5I_type_t type; /*ID's type */
unsigned hash_loc; /*bucket pointer */
- H5I_id_info_t *ret_value = NULL; /*return value */
+ H5I_id_info_t *ret_value; /*return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5I_find_id);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5I_find_id)
/* Check arguments */
type = H5I_TYPE(id);
- assert(type > H5I_BADID && type < H5I_next_type);
- type_ptr = H5I_id_type_list_g[type];
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_DONE(NULL);
- assert(type_ptr && type_ptr->count > 0);
+ type_ptr = H5I_id_type_list_g[type];
+ if (!type_ptr || type_ptr->count <= 0)
+ HGOTO_DONE(NULL);
/* Get the bucket in which the ID is located */
hash_loc = (unsigned)H5I_LOC(id, type_ptr->hash_size);
id_ptr = type_ptr->id_list[hash_loc];
/* Scan the bucket's linked list for a match */
- last_id=NULL;
- while (id_ptr) {
- if (id_ptr->id == id) {
+ last_id = NULL;
+ while(id_ptr) {
+ if(id_ptr->id == id) {
/* If we found an object, move it to the front of the list, if it isn't there already */
- if(last_id!=NULL) {
- last_id->next=id_ptr->next;
- id_ptr->next=type_ptr->id_list[hash_loc];
- type_ptr->id_list[hash_loc]=id_ptr;
+ if(last_id != NULL) {
+ last_id->next = id_ptr->next;
+ id_ptr->next = type_ptr->id_list[hash_loc];
+ type_ptr->id_list[hash_loc] = id_ptr;
} /* end if */
break;
} /* end if */
- last_id=id_ptr;
+ last_id = id_ptr;
id_ptr = id_ptr->next;
} /* end while */
/* Set the return value */
ret_value = id_ptr;
- FUNC_LEAVE_NOAPI(ret_value);
-}
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_find_id() */
/*-------------------------------------------------------------------------
@@ -2031,17 +2130,17 @@ done:
hid_t
H5Iget_file_id(hid_t obj_id)
{
- hid_t ret_value;
+ hid_t ret_value; /* Return value */
- FUNC_ENTER_API(H5Iget_file_id, FAIL);
+ FUNC_ENTER_API(H5Iget_file_id, FAIL)
H5TRACE1("i", "i", obj_id);
- if((ret_value = H5I_get_file_id(obj_id))<0)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve file ID");
+ if((ret_value = H5I_get_file_id(obj_id, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve file ID")
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Iget_file_id() */
/*-------------------------------------------------------------------------
@@ -2060,7 +2159,7 @@ done:
*-------------------------------------------------------------------------
*/
hid_t
-H5I_get_file_id(hid_t obj_id)
+H5I_get_file_id(hid_t obj_id, hbool_t app_ref)
{
H5G_loc_t loc; /* Location of object */
H5I_type_t type; /* ID type */
@@ -2074,13 +2173,13 @@ H5I_get_file_id(hid_t obj_id)
ret_value = obj_id;
/* Increment reference count on atom. */
- if(H5I_inc_ref(ret_value) < 0)
+ if(H5I_inc_ref(ret_value, app_ref) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed")
}
else if(type == H5I_DATATYPE || type == H5I_GROUP || type == H5I_DATASET || type == H5I_ATTR) {
if(H5G_loc(obj_id, &loc) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get object location")
- if((ret_value = H5F_get_id(loc.oloc->file)) < 0)
+ if((ret_value = H5F_get_id(loc.oloc->file, app_ref)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get file ID")
}
else
@@ -2121,7 +2220,7 @@ H5I_debug(H5I_type_t type)
unsigned int iu;
herr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5I_debug, FAIL);
+ FUNC_ENTER_NOAPI(H5I_debug, FAIL)
fprintf(stderr, "Dumping ID type %d\n", (int)type);
type_ptr = H5I_id_type_list_g[type];
@@ -2177,7 +2276,7 @@ H5I_debug(H5I_type_t type)
} /* end for */
done:
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5I_debug() */
#endif /* H5I_DEBUG_OUTPUT */
diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h
index 42575e4..475871b 100644
--- a/src/H5Iprivate.h
+++ b/src/H5Iprivate.h
@@ -52,19 +52,19 @@
/* Private Functions in H5I.c */
H5_DLL H5I_type_t H5I_register_type(H5I_type_t type_id, size_t hash_size, unsigned reserved, H5I_free_t free_func);
H5_DLL int H5I_nmembers(H5I_type_t type);
-H5_DLL herr_t H5I_clear_type(H5I_type_t type, hbool_t force);
+H5_DLL herr_t H5I_clear_type(H5I_type_t type, hbool_t force, hbool_t app_ref);
H5_DLL int H5I_destroy_type(H5I_type_t type);
-H5_DLL hid_t H5I_register(H5I_type_t type, void *object);
+H5_DLL hid_t H5I_register(H5I_type_t type, const void *object, hbool_t app_ref);
H5_DLL void *H5I_object(hid_t id);
H5_DLL void *H5I_object_verify(hid_t id, H5I_type_t id_type);
H5_DLL H5I_type_t H5I_get_type(hid_t id);
-H5_DLL hid_t H5I_get_file_id(hid_t);
+H5_DLL hid_t H5I_get_file_id(hid_t obj_id, hbool_t app_ref);
H5_DLL void *H5I_remove(hid_t id);
H5_DLL void *H5I_remove_verify(hid_t id, H5I_type_t id_type);
-H5_DLL void *H5I_search(H5I_type_t type, H5I_search_func_t func, void *key);
-H5_DLL int H5I_get_ref(hid_t id);
-H5_DLL int H5I_inc_ref(hid_t id);
-H5_DLL int H5I_dec_ref(hid_t id);
+H5_DLL void *H5I_search(H5I_type_t type, H5I_search_func_t func, void *key, hbool_t app_ref);
+H5_DLL int H5I_get_ref(hid_t id, hbool_t app_ref);
+H5_DLL int H5I_inc_ref(hid_t id, hbool_t app_ref);
+H5_DLL int H5I_dec_ref(hid_t id, hbool_t app_ref);
H5_DLL int H5I_inc_type_ref(H5I_type_t type);
H5_DLL herr_t H5I_dec_type_ref(H5I_type_t type);
H5_DLL int H5I_get_type_ref(H5I_type_t type);
diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h
index 108f040..d630556 100644
--- a/src/H5Ipublic.h
+++ b/src/H5Ipublic.h
@@ -77,7 +77,7 @@ extern "C" {
/* Public API functions */
-H5_DLL hid_t H5Iregister(H5I_type_t type, void *object);
+H5_DLL hid_t H5Iregister(H5I_type_t type, const void *object);
H5_DLL void *H5Iobject_verify(hid_t id, H5I_type_t id_type);
H5_DLL void *H5Iremove_verify(hid_t id, H5I_type_t id_type);
H5_DLL H5I_type_t H5Iget_type(hid_t id);
@@ -95,6 +95,7 @@ H5_DLL int H5Iget_type_ref(H5I_type_t type);
H5_DLL void *H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key);
H5_DLL herr_t H5Inmembers(H5I_type_t type, hsize_t *num_members);
H5_DLL htri_t H5Itype_exists(H5I_type_t type);
+H5_DLL htri_t H5Iis_valid(hid_t id);
#ifdef __cplusplus
}
diff --git a/src/H5L.c b/src/H5L.c
index 2a1e096..b217abe 100644
--- a/src/H5L.c
+++ b/src/H5L.c
@@ -82,6 +82,7 @@ typedef struct {
const char *dst_name; /* Destination name for moving object */
H5T_cset_t cset; /* Char set for new name */
H5G_loc_t *dst_loc; /* Destination location for moving object */
+ unsigned dst_target_flags; /* Target flags for destination object */
hbool_t copy; /* TRUE if this is a copy operation */
hid_t lapl_id; /* LAPL to use in callback */
hid_t dxpl_id; /* DXPL to use in callback */
@@ -151,7 +152,7 @@ static herr_t H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name,
const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
H5G_own_loc_t *own_loc/*out*/);
static herr_t H5L_create_real(const H5G_loc_t *link_loc, const char *link_name,
- H5G_name_t *obj_path, H5F_t *obj_file, H5O_link_t *lnk, H5O_obj_create_t *ocrt_info,
+ H5G_name_t *obj_path, H5F_t *obj_file, H5O_link_t *lnk, H5O_obj_create_t *ocrt_info,
hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id);
static herr_t H5L_get_val_real(const H5O_link_t *lnk, void *buf, size_t size);
static herr_t H5L_get_val_cb(H5G_loc_t *grp_loc/*in*/, const char *name,
@@ -285,6 +286,9 @@ H5L_term_interface(void)
H5L_table_g = (H5L_class_t *)H5MM_xfree(H5L_table_g);
H5L_table_used_g = H5L_table_alloc_g = 0;
+ /* Mark the interface as uninitialized */
+ H5_interface_initialize_g = 0;
+
FUNC_LEAVE_NOAPI(n)
} /* H5L_term_interface() */
@@ -345,7 +349,7 @@ H5Lmove(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
lapl_id, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTMOVE, FAIL, "unable to move link")
-done:
+done:
FUNC_LEAVE_API(ret_value)
} /* end H5Lmove() */
@@ -403,7 +407,7 @@ H5Lcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
lapl_id, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTMOVE, FAIL, "unable to move link")
-done:
+done:
FUNC_LEAVE_API(ret_value)
} /* end H5Lcopy() */
@@ -557,6 +561,8 @@ H5Lcreate_ud(hid_t link_loc_id, const char *link_name, H5L_type_t link_type,
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!link_name || !*link_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no link name specified")
+ if(link_type < H5L_TYPE_UD_MIN || link_type > H5L_TYPE_MAX)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid link class")
/* Create external link */
if(H5L_create_ud(&link_loc, link_name, udata, udata_size, link_type, lcpl_id, lapl_id, H5AC_dxpl_id) < 0)
@@ -710,7 +716,7 @@ H5Lget_val(hid_t loc_id, const char *name, void *buf/*out*/, size_t size,
/* Get the link value */
if(H5L_get_val(&loc, name, buf, size, lapl_id, H5AC_ind_dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link value")
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link value for '%s'", name)
done:
FUNC_LEAVE_API(ret_value)
@@ -1586,7 +1592,7 @@ H5L_link(const H5G_loc_t *new_loc, const char *new_name, H5G_loc_t *obj_loc,
lnk.u.hard.addr = obj_loc->oloc->addr;
/* Create the link */
- if(H5L_create_real(new_loc, new_name, obj_loc->path, obj_loc->oloc->file, &lnk, NULL, lcpl_id, lapl_id, dxpl_id) < 0)
+ if(H5L_create_real(new_loc, new_name, obj_loc->path, obj_loc->oloc->file, &lnk, NULL, lcpl_id, lapl_id, dxpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link to object")
done:
@@ -1629,7 +1635,7 @@ H5L_link_object(const H5G_loc_t *new_loc, const char *new_name,
lnk.type = H5L_TYPE_HARD;
/* Create the link */
- if(H5L_create_real(new_loc, new_name, NULL, NULL, &lnk, ocrt_info, lcpl_id, lapl_id, dxpl_id) < 0)
+ if(H5L_create_real(new_loc, new_name, NULL, NULL, &lnk, ocrt_info, lcpl_id, lapl_id, dxpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link to object")
done:
@@ -1743,7 +1749,7 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED
/* Set up location for user-defined callback */
if((grp = H5G_open(&temp_loc, udata->dxpl_id)) == NULL)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
- if((grp_id = H5I_register(H5I_GROUP, grp)) < 0)
+ if((grp_id = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register ID for group")
/* Make callback */
@@ -1755,7 +1761,7 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED
done:
/* Close the location given to the user callback if it was created */
if(grp_id >= 0) {
- if(H5I_dec_ref(grp_id) < 0)
+ if(H5I_dec_ref(grp_id, TRUE) < 0)
HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
} /* end if */
else if(grp != NULL) {
@@ -2048,7 +2054,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5L_get_val_real
*
- * Purpose: Retrieve link value from a link object
+ * Purpose: Retrieve link value from a link object
*
* Return: Non-negative on success/Negative on failure
*
@@ -2071,7 +2077,7 @@ H5L_get_val_real(const H5O_link_t *lnk, void *buf, size_t size)
if(H5L_TYPE_SOFT == lnk->type) {
/* Copy to output buffer */
if(size > 0 && buf) {
- HDstrncpy(buf, lnk->u.soft.name, size);
+ HDstrncpy((char *)buf, lnk->u.soft.name, size);
if(HDstrlen(lnk->u.soft.name) >= size)
((char *)buf)[size - 1] = '\0';
} /* end if */
@@ -2080,7 +2086,7 @@ H5L_get_val_real(const H5O_link_t *lnk, void *buf, size_t size)
else if(lnk->type >= H5L_TYPE_UD_MIN) {
const H5L_class_t *link_class; /* User-defined link class */
- /* Get the link class for this type of link. It's okay if the class
+ /* Get the link class for this type of link. It's okay if the class
* isn't registered, though--we just can't give any more information
* about it
*/
@@ -2114,7 +2120,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5L_get_val_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk,
+H5L_get_val_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char *name, const H5O_link_t *lnk,
H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/)
{
H5L_trav_gv_t *udata = (H5L_trav_gv_t *)_udata; /* User data passed in */
@@ -2124,7 +2130,7 @@ H5L_get_val_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H
/* Check if the name in this group resolved to a valid link */
if(lnk == NULL)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "'%s' doesn't exist", name)
/* Retrieve the value for the link */
if(H5L_get_val_real(lnk, udata->buf, udata->size) < 0)
@@ -2440,7 +2446,7 @@ H5L_move_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name,
/* Set up location for user-defined callback */
if((grp = H5G_open(&temp_loc, udata->dxpl_id)) == NULL)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
- if((grp_id = H5I_register(H5I_GROUP, grp)) < 0)
+ if((grp_id = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group ID")
if(udata->copy) {
@@ -2457,7 +2463,7 @@ H5L_move_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name,
done:
/* Close the location given to the user callback if it was created */
if(grp_id >= 0) {
- if(H5I_dec_ref(grp_id) < 0)
+ if(H5I_dec_ref(grp_id, TRUE) < 0)
HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
} /* end if */
else if(grp != NULL) {
@@ -2528,7 +2534,8 @@ H5L_move_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk,
orig_name = H5MM_xstrdup(name);
/* Insert the link into its new location */
- if(H5G_traverse(udata->dst_loc, udata->dst_name, H5G_TARGET_NORMAL, H5L_move_dest_cb, &udata_out, udata->lapl_id, udata->dxpl_id) < 0)
+ if(H5G_traverse(udata->dst_loc, udata->dst_name, udata->dst_target_flags,
+ H5L_move_dest_cb, &udata_out, udata->lapl_id, udata->dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link")
/* If this is a move and not a copy operation, change the object's name and remove the old link */
@@ -2614,7 +2621,7 @@ H5L_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc,
const char *dst_name, hbool_t copy_flag, hid_t lcpl_id, hid_t lapl_id,
hid_t dxpl_id)
{
- unsigned target_flags = H5G_TARGET_MOUNT|H5G_TARGET_SLINK|H5G_TARGET_UDLINK;
+ unsigned dst_target_flags = H5G_TARGET_NORMAL;
H5T_cset_t char_encoding = H5F_DEFAULT_CSET; /* Character encoding for link */
H5P_genplist_t* lc_plist; /* Link creation property list */
H5P_genplist_t* la_plist; /* Link access property list */
@@ -2641,8 +2648,9 @@ H5L_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc,
if(H5P_get(lc_plist, H5L_CRT_INTERMEDIATE_GROUP_NAME, &crt_intmd_group) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for creating missing groups")
+ /* Set target flags for source and destination */
if(crt_intmd_group > 0)
- target_flags |= H5G_CRT_INTMD_GROUP;
+ dst_target_flags |= H5G_CRT_INTMD_GROUP;
/* Get character encoding property */
if(H5P_get(lc_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &char_encoding) < 0)
@@ -2657,21 +2665,23 @@ H5L_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc,
else {
if(NULL == (la_plist = (H5P_genplist_t *)H5I_object(lapl_id)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a valid access PL")
- if((lapl_copy = H5P_copy_plist(la_plist)) < 0)
+ if((lapl_copy = H5P_copy_plist(la_plist, FALSE)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy access properties")
} /* end else */
/* Set up user data */
udata.dst_loc = dst_loc;
udata.dst_name= dst_name;
+ udata.dst_target_flags = dst_target_flags;
udata.cset = char_encoding;
udata.copy = copy_flag;
udata.lapl_id = lapl_copy;
udata.dxpl_id = dxpl_id;
/* Do the move */
- if(H5G_traverse(src_loc, src_name, target_flags, H5L_move_cb, &udata, lapl_id, dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to find link")
+ if(H5G_traverse(src_loc, src_name, H5G_TARGET_MOUNT | H5G_TARGET_SLINK | H5G_TARGET_UDLINK,
+ H5L_move_cb, &udata, lapl_id, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to find link")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -2700,7 +2710,7 @@ H5L_exists_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name,
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5L_exists_cb)
/* Check if the name in this group resolved to a valid link */
- *udata = (lnk != NULL);
+ *udata = (hbool_t)(lnk != NULL);
/* Indicate that this callback didn't take ownership of the group *
* location for the object */
@@ -2725,8 +2735,8 @@ H5L_exists_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name,
static htri_t
H5L_exists(const H5G_loc_t *loc, const char *name, hid_t lapl_id, hid_t dxpl_id)
{
- hbool_t exists = FALSE; /* Whether the link exists in the group */
- herr_t ret_value = SUCCEED; /* Return value */
+ hbool_t exists = FALSE; /* Whether the link exists in the group */
+ htri_t ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5L_exists)
diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c
index de37ea9..ad8f8e1 100644
--- a/src/H5Lexternal.c
+++ b/src/H5Lexternal.c
@@ -107,9 +107,9 @@ H5L_getenv_prefix_name(char **env_prefix/*in,out*/)
*env_prefix = strret + 1;
*strret = '\0';
}
- return(retptr);
+
FUNC_LEAVE_NOAPI(retptr)
-}
+} /* end H5L_getenv_prefix_name() */
/*--------------------------------------------------------------------------
@@ -121,6 +121,8 @@ H5L_getenv_prefix_name(char **env_prefix/*in,out*/)
*
* Programmer: Vailin Choi, April 2, 2008
*
+ * Modification: Raymond Lu, 14 Jan. 2009
+ * Added support for OpenVMS pathname
--------------------------------------------------------------------------*/
static herr_t
H5L_build_name(char *prefix, char *file_name, char **full_name/*out*/)
@@ -135,13 +137,15 @@ H5L_build_name(char *prefix, char *file_name, char **full_name/*out*/)
fname_len = HDstrlen(file_name);
/* Allocate a buffer to hold the filename + prefix + possibly the delimiter + terminating null byte */
- if(NULL == (*full_name = H5MM_malloc(prefix_len + fname_len + 2)))
+ if(NULL == (*full_name = (char *)H5MM_malloc(prefix_len + fname_len + 2)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate filename buffer")
/* Copy the prefix into the buffer */
HDstrcpy(*full_name, prefix);
+#ifndef H5_VMS
if (!CHECK_DELIMITER(prefix[prefix_len-1]))
HDstrcat(*full_name, DIR_SEPS);
+#endif
/* Add the external link's filename to the prefix supplied */
HDstrcat(*full_name, file_name);
@@ -169,9 +173,17 @@ done:
* Monday, July 10, 2006
* Modifications:
* Vailin Choi, April 2, 2008
- * Add handling to search for the target file
+ * Add handling to search for the target file
* See description in RM: H5Lcreate_external
*
+ * Vailin Choi; Sept. 12th, 2008; bug #1247
+ * Retrieve the file access property list identifer that is set
+ * for link access property via H5Pget_elink_fapl().
+ * If the return value is H5P_DEFAULT, the parent's file access
+ * property is used to H5F_open() the target file;
+ * Otherwise, the file access property retrieved from H5Pget_elink_fapl()
+ * is used to H5F_open() the target file.
+ *
*-------------------------------------------------------------------------
*/
static hid_t
@@ -189,15 +201,16 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group,
const char *obj_name; /* Name external link's object */
size_t fname_len; /* Length of external link file name */
unsigned intent; /* File access permissions */
+ H5L_elink_cb_t cb_info; /* Callback info struct */
hid_t fapl_id = -1; /* File access property list for external link's file */
hid_t ext_obj = -1; /* ID for external link's object */
+ char *temp_group_name = NULL;/* Temporary pointer to group name */
+ char *temp_file_name = NULL; /* Temporary pointer to file name */
+ char *actual_file_name = NULL; /* Parent file's actual name */
+ H5P_genplist_t *fa_plist; /* File access property list pointer */
+ H5F_close_degree_t fc_degree = H5F_CLOSE_WEAK; /* File close degree for target file */
hid_t ret_value; /* Return value */
- char *tempname=NULL, *ptr=NULL, *extpath=NULL;
- char *env_prefix=NULL, *tmp_env_prefix=NULL;
- char *out_prefix_name=NULL, *pp=NULL;
-
-
FUNC_ENTER_NOAPI(H5L_extern_traverse, FAIL)
/* Sanity checks */
@@ -219,118 +232,206 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group,
if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ /* Get the fapl_id set for lapl_id if any */
+ if(H5P_get(plist, H5L_ACS_ELINK_FAPL_NAME, &fapl_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fapl for links")
+
/* Get the location for the group holding the external link */
if(H5G_loc(cur_group, &loc) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get object location")
- /* Whatever access properties and intent the user used on the old file,
- * use the same ones to open the new file. If this is a bad default,
- * users can override this callback using H5Lregister.
- */
- intent = H5F_INTENT(loc.oloc->file);
- if((fapl_id = H5F_get_access_plist(loc.oloc->file)) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get file access property list")
-
- /* Check for non-"weak" file close degree for parent file */
- if(H5F_GET_FC_DEGREE(loc.oloc->file) != H5F_CLOSE_WEAK) {
- H5P_genplist_t *fa_plist; /* Property list pointer */
- H5F_close_degree_t fc_degree = H5F_CLOSE_WEAK; /* File close degree */
-
- /* Get the plist structure */
- if(NULL == (fa_plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
-
- /* Set file close degree for new file to "weak" */
- if(H5P_set(fa_plist, H5F_ACS_CLOSE_DEGREE_NAME, &fc_degree) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree")
+ /* get the access flags set for lapl_id if any */
+ if(H5P_get(plist, H5L_ACS_ELINK_FLAGS_NAME, &intent) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get elink file access flags")
+
+ /* get the file access mode flags for the parent file, if they were not set
+ * on lapl_id */
+ if(intent == H5F_ACC_DEFAULT)
+ intent = H5F_INTENT(loc.oloc->file);
+
+ if((fapl_id == H5P_DEFAULT) && ((fapl_id = H5F_get_access_plist(loc.oloc->file, FALSE)) < 0))
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get parent's file access property list")
+
+ /* Get callback_info */
+ if(H5P_get(plist, H5L_ACS_ELINK_CB_NAME, &cb_info)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get elink callback info")
+
+ /* Get file access property list */
+ if(NULL == (fa_plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Make callback if it exists */
+ if(cb_info.func) {
+ const char *parent_file_name; /* Parent file name */
+ const char *parent_group_name; /* Parent group name */
+
+ /* Get parent file name */
+ parent_file_name = H5F_OPEN_NAME(loc.oloc->file);
+
+ /* Get parent group name */
+ if(loc.path->user_path_r != NULL && loc.path->obj_hidden == 0)
+ /* Use user_path_r if possible */
+ parent_group_name = H5RS_get_str(loc.path->user_path_r);
+ else {
+ /* Otherwise use H5G_get_name */
+ ssize_t group_name_len; /* Length of parent group name */
+
+ /* Get length of parent group name */
+ if((group_name_len = H5G_get_name(cur_group, NULL, (size_t) 0, lapl_id, H5AC_ind_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve length of group name")
+
+ /* account for null terminator */
+ group_name_len++;
+
+ /* Copy parent group name */
+ if(NULL == (temp_group_name = (char *)H5MM_malloc((size_t)group_name_len)))
+ HGOTO_ERROR(H5E_LINK, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(H5G_get_name(cur_group, temp_group_name, (size_t) group_name_len, lapl_id, H5AC_ind_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve group name")
+ parent_group_name = temp_group_name;
+ } /* end else */
+
+ /* Make callback */
+ if((cb_info.func)(parent_file_name, parent_group_name, file_name, obj_name, &intent, fapl_id, cb_info.user_data) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "traversal operator failed")
+
+ /* Free temp_group_name */
+ temp_group_name = (char *)H5MM_xfree(temp_group_name);
+
+ /* Check access flags */
+ if((intent & H5F_ACC_TRUNC) || (intent & H5F_ACC_EXCL))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags")
} /* end if */
+ /* Set file close degree for new file to "weak" */
+ if(H5P_set(fa_plist, H5F_ACS_CLOSE_DEGREE_NAME, &fc_degree) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree")
+
/*
* Start searching for the target file
*/
- if ((tempname=H5MM_strdup(file_name)) == NULL)
+
+ /* Simplify intent flags for open calls */
+ intent = ((intent & H5F_ACC_RDWR) ? H5F_ACC_RDWR : H5F_ACC_RDONLY);
+
+ /* Copy the file name to use */
+ if(NULL == (temp_file_name = H5MM_strdup(file_name)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* target file_name is an absolute pathname: see RM for detailed description */
- if (CHECK_ABSOLUTE(file_name) || CHECK_ABS_PATH(file_name)) {
- if(NULL == (ext_file = H5F_open(file_name, ((intent & H5F_ACC_RDWR) ? H5F_ACC_RDWR : H5F_ACC_RDONLY),
- H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) {
+ if(CHECK_ABSOLUTE(file_name) || CHECK_ABS_PATH(file_name)) {
+ /* Try opening file */
+ if(NULL == (ext_file = H5F_open(file_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) {
+ char *ptr = NULL;
+
H5E_clear_stack(NULL);
+
/* get last component of file_name */
GET_LAST_DELIMITER(file_name, ptr)
HDassert(ptr);
- HDstrcpy(tempname, ++ptr);
- }
- } else if (CHECK_ABS_DRIVE(file_name)) {
- if(NULL == (ext_file = H5F_open(file_name, ((intent & H5F_ACC_RDWR) ? H5F_ACC_RDWR : H5F_ACC_RDONLY),
- H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) {
+ HDstrcpy(temp_file_name, ++ptr);
+ } /* end if */
+ } /* end if */
+ else if(CHECK_ABS_DRIVE(file_name)) {
+ if(NULL == (ext_file = H5F_open(file_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) {
H5E_clear_stack(NULL);
/* strip "<drive-letter>:" */
- HDstrcpy(tempname, &file_name[2]);
- }
- }
-
- /* try searching from paths set in the environment variable */
- if ((ext_file == NULL) && (env_prefix=HDgetenv("HDF5_EXT_PREFIX"))) {
-
- tmp_env_prefix = H5MM_strdup(env_prefix);
- pp = tmp_env_prefix;
-
- while ((tmp_env_prefix) && (*tmp_env_prefix)) {
- out_prefix_name = H5L_getenv_prefix_name(&tmp_env_prefix/*in,out*/);
- if ((out_prefix_name) && (*out_prefix_name)) {
+ HDstrcpy(temp_file_name, &file_name[2]);
+ } /* end if */
+ } /* end if */
- if (H5L_build_name(out_prefix_name, tempname, &full_name/*out*/) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename")
+ /* try searching from paths set in the environment variable */
+ if(ext_file == NULL) {
+ char *env_prefix;
+
+ if(NULL != (env_prefix = HDgetenv("HDF5_EXT_PREFIX"))) {
+ char *tmp_env_prefix;
+
+ if(NULL == (tmp_env_prefix = H5MM_strdup(env_prefix)))
+ HGOTO_ERROR(H5E_LINK, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ while((tmp_env_prefix) && (*tmp_env_prefix)) {
+ char *out_prefix_name;
+
+ out_prefix_name = H5L_getenv_prefix_name(&tmp_env_prefix/*in,out*/);
+ if(out_prefix_name && (*out_prefix_name)) {
+ if(H5L_build_name(out_prefix_name, temp_file_name, &full_name/*out*/) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename")
+
+ ext_file = H5F_open(full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id);
+ full_name = (char *)H5MM_xfree(full_name);
+ if(ext_file != NULL)
+ break;
+ H5E_clear_stack(NULL);
+ } /* end if */
+ } /* end while */
+ } /* end if */
+ } /* end if */
- ext_file = H5F_open(full_name, ((intent & H5F_ACC_RDWR) ? H5F_ACC_RDWR : H5F_ACC_RDONLY),
- H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id);
- if (full_name)
- H5MM_xfree(full_name);
- if (ext_file != NULL)
- break;
- H5E_clear_stack(NULL);
- }
- } /* end while */
- if (pp)
- H5MM_xfree(pp);
- }
-
/* try searching from property list */
- if (ext_file == NULL) {
+ if(ext_file == NULL) {
if(H5P_get(plist, H5L_ACS_ELINK_PREFIX_NAME, &my_prefix) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external link prefix")
- if (my_prefix) {
- if (H5L_build_name(my_prefix, tempname, &full_name/*out*/) < 0)
+ if(my_prefix) {
+ if(H5L_build_name(my_prefix, temp_file_name, &full_name/*out*/) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename")
- if ((ext_file=H5F_open(full_name, ((intent & H5F_ACC_RDWR) ? H5F_ACC_RDWR : H5F_ACC_RDONLY),
- H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id)) == NULL)
+ if(NULL == (ext_file = H5F_open(full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id)))
H5E_clear_stack(NULL);
- if (full_name)
- H5MM_xfree(full_name);
- }
- }
+ full_name = (char *)H5MM_xfree(full_name);
+ } /* end if */
+ } /* end if */
+
+ /* try searching from main file's "extpath": see description in H5F_open() & H5_build_extpath() */
+ if(ext_file == NULL) {
+ char *extpath;
+
+ if(NULL != (extpath = H5F_EXTPATH(loc.oloc->file))) {
+ if(H5L_build_name(extpath, temp_file_name, &full_name/*out*/) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename")
+ if(NULL == (ext_file = H5F_open(full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id)))
+ H5E_clear_stack(NULL);
+ full_name = (char *)H5MM_xfree(full_name);
+ } /* end if */
+ } /* end if */
- /* try searching from main file's "extpath":see description in H5F_open() & H5_build_extpath() */
- if ((ext_file == NULL) && (extpath=H5F_EXTPATH(loc.oloc->file))) {
- if (H5L_build_name(extpath, tempname, &full_name/*out*/) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename")
- if ((ext_file = H5F_open(full_name, ((intent & H5F_ACC_RDWR) ? H5F_ACC_RDWR : H5F_ACC_RDONLY),
- H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id)) == NULL)
+ /* try the relative file_name stored in temp_file_name */
+ if(ext_file == NULL) {
+ if(NULL == (ext_file = H5F_open(temp_file_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id)))
H5E_clear_stack(NULL);
- if (full_name)
- H5MM_xfree(full_name);
- }
+ } /* end if */
- /* try the relative file_name stored in tempname */
- if (ext_file == NULL) {
- if ((ext_file=H5F_open(tempname, ((intent & H5F_ACC_RDWR) ? H5F_ACC_RDWR : H5F_ACC_RDONLY),
- H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id)) == NULL)
- HGOTO_ERROR(H5E_LINK, H5E_CANTOPENFILE, FAIL, "unable to open external file")
- }
+ /* try the 'resolved' name for the parent file (i.e. the name after symlinks
+ * were resolved)
+ */
+ if(ext_file == NULL) {
+ char *ptr = NULL;
+
+ /* Copy resolved file name */
+ if(NULL == (actual_file_name = H5MM_strdup(H5F_ACTUAL_NAME(loc.oloc->file))))
+ HGOTO_ERROR(H5E_LINK, H5E_CANTALLOC, FAIL, "can't duplicate resolved file name string")
+
+ /* get last component of file_name */
+ GET_LAST_DELIMITER(actual_file_name, ptr)
+ if(ptr) {
+ /* Truncate filename portion from actual file name path */
+ *ptr = '\0';
+
+ /* Build new file name for the external file */
+ if(H5L_build_name(actual_file_name, temp_file_name, &full_name/*out*/) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename")
+ } /* end if */
+ else {
+ /* Transfer ownership of actual file name to 'full_name' variable */
+ full_name = actual_file_name;
+ actual_file_name = NULL;
+ } /* end else */
+
+ /* Try opening with the resolved name */
+ if(NULL == (ext_file = H5F_open(full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id)))
+ HGOTO_ERROR(H5E_LINK, H5E_CANTOPENFILE, FAIL, "unable to open external file, external link file name = '%s', temp_file_name = '%s'", file_name, temp_file_name)
+ full_name = (char *)H5MM_xfree(full_name);
+ } /* end if */
- if (tempname)
- H5MM_xfree(tempname);
/* Increment the number of open objects, to hold the file open */
H5F_incr_nopen_objs(ext_file);
@@ -340,7 +441,7 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group,
HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unable to create location for file")
/* Open the object referenced in the external file */
- if((ext_obj = H5O_open_name(&root_loc, obj_name, lapl_id)) < 0) {
+ if((ext_obj = H5O_open_name(&root_loc, obj_name, lapl_id, FALSE)) < 0) {
H5F_decr_nopen_objs(ext_file);
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object")
} /* end if */
@@ -358,14 +459,20 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group,
done:
/* Release resources */
- if(fapl_id > 0 && H5I_dec_ref(fapl_id) < 0)
+ if(fapl_id > 0 && H5I_dec_ref(fapl_id, FALSE) < 0)
HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for file access property list")
if(ext_file && H5F_try_close(ext_file) < 0)
HDONE_ERROR(H5E_LINK, H5E_CANTCLOSEFILE, FAIL, "problem closing external file")
-
- /* Close object if it's open and something failed */
- if(ret_value < 0 && ext_obj >= 0 && H5I_dec_ref(ext_obj) < 0)
- HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for external object")
+ full_name = (char *)H5MM_xfree(full_name);
+ temp_group_name = (char *)H5MM_xfree(temp_group_name);
+ temp_file_name = (char *)H5MM_xfree(temp_file_name);
+ actual_file_name = (char *)H5MM_xfree(actual_file_name);
+
+ if(ret_value < 0) {
+ /* Close object if it's open and something failed */
+ if(ext_obj >= 0 && H5I_dec_ref(ext_obj, FALSE) < 0)
+ HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for external object")
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5L_extern_traverse() */
@@ -414,7 +521,7 @@ H5L_extern_query(const char UNUSED * link_name, const void *_udata, size_t udata
} /* end if */
/* Set return value */
- ret_value = udata_size;
+ ret_value = (ssize_t)udata_size;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -446,6 +553,7 @@ H5Lcreate_external(const char *file_name, const char *obj_name,
hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id)
{
H5G_loc_t link_loc; /* Group location to create link */
+ char *norm_obj_name = NULL; /* Pointer to normalized current name */
void *ext_link_buf = NULL; /* Buffer to contain external link */
size_t buf_size; /* Size of buffer to hold external link */
uint8_t *p; /* Pointer into external link buffer */
@@ -465,24 +573,28 @@ H5Lcreate_external(const char *file_name, const char *obj_name,
if(!link_name || !*link_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no link name specified")
+ /* Get normalized copy of the link target */
+ if(NULL == (norm_obj_name = H5G_normalize(obj_name)))
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize object name")
+
/* Combine the filename and link name into a single buffer to give to the UD link */
- buf_size = 1 + (HDstrlen(file_name) + 1) + (HDstrlen(obj_name) + 1);
+ buf_size = 1 + (HDstrlen(file_name) + 1) + (HDstrlen(norm_obj_name) + 1);
if(NULL == (ext_link_buf = H5MM_malloc(buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate udata buffer")
/* Encode the external link information */
- p = ext_link_buf;
+ p = (uint8_t *)ext_link_buf;
*p++ = (H5L_EXT_VERSION << 4) | H5L_EXT_FLAGS_ALL; /* External link version & flags */
HDstrcpy((char *)p, file_name); /* Name of file containing external link's object */
p += HDstrlen(file_name) + 1;
- HDstrcpy((char *)p, obj_name); /* External link's object */
+ HDstrcpy((char *)p, norm_obj_name); /* External link's object */
/* Create an external link */
if(H5L_create_ud(&link_loc, link_name, ext_link_buf, buf_size, H5L_TYPE_EXTERNAL, lcpl_id, lapl_id, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link")
done:
- if(ext_link_buf != NULL)
+ if(norm_obj_name)
H5MM_free(ext_link_buf);
FUNC_LEAVE_API(ret_value)
diff --git a/src/H5Lprivate.h b/src/H5Lprivate.h
index 6d3811e..f3079bc 100644
--- a/src/H5Lprivate.h
+++ b/src/H5Lprivate.h
@@ -41,12 +41,21 @@
/* ======== Link access property names ======== */
#define H5L_ACS_NLINKS_NAME "max soft links" /* Number of soft links to traverse */
#define H5L_ACS_ELINK_PREFIX_NAME "external link prefix" /* External link prefix */
+#define H5L_ACS_ELINK_FAPL_NAME "external link fapl" /* file access property list for external link access */
+#define H5L_ACS_ELINK_FLAGS_NAME "external link flags" /* file access flags for external link traversal */
+#define H5L_ACS_ELINK_CB_NAME "external link callback" /* callback function for external link traversal */
/****************************/
/* Library Private Typedefs */
/****************************/
+/* Structure for external link traversal callback property */
+typedef struct H5L_elink_cb_t {
+ H5L_elink_traverse_t func;
+ void *user_data;
+} H5L_elink_cb_t;
+
/*****************************/
/* Library Private Variables */
diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h
index 823b046..620d2e9 100644
--- a/src/H5Lpublic.h
+++ b/src/H5Lpublic.h
@@ -29,7 +29,6 @@
/* Public headers needed by this file */
#include "H5public.h" /* Generic Functions */
#include "H5Ipublic.h" /* IDs */
-#include "H5Ppublic.h" /* Property lists */
#include "H5Tpublic.h" /* Datatypes */
/*****************/
@@ -60,7 +59,7 @@ extern "C" {
* defined by HDF5 but their behavior can be overridden by users.
* Users who want to create new classes of links should contact the HDF5
* development team at hdfhelp@ncsa.uiuc.edu .
- * These values can never change because they appear in HDF5 files.
+ * These values can never change because they appear in HDF5 files.
*/
typedef enum {
H5L_TYPE_ERROR = (-1), /* Invalid link type id */
@@ -131,6 +130,12 @@ typedef struct {
typedef herr_t (*H5L_iterate_t)(hid_t group, const char *name, const H5L_info_t *info,
void *op_data);
+/* Callback for external link traversal */
+typedef herr_t (*H5L_elink_traverse_t)(const char *parent_file_name,
+ const char *parent_group_name, const char *child_file_name,
+ const char *child_object_name, unsigned *acc_flags, hid_t fapl_id,
+ void *op_data);
+
/********************/
/* Public Variables */
diff --git a/src/H5MF.c b/src/H5MF.c
index 95d7552..0129c1d 100644
--- a/src/H5MF.c
+++ b/src/H5MF.c
@@ -29,6 +29,7 @@
/****************/
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+#define H5MF_PACKAGE /*suppress error about including H5MFpkg */
/***********/
@@ -37,18 +38,40 @@
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
-#include "H5MFprivate.h" /* File memory management */
+#include "H5MFpkg.h" /* File memory management */
+#include "H5Vprivate.h" /* Vectors and arrays */
/****************/
/* Local Macros */
/****************/
+#define H5MF_FSPACE_SHRINK 80 /* Percent of "normal" size to shrink serialized free space size */
+#define H5MF_FSPACE_EXPAND 120 /* Percent of "normal" size to expand serialized free space size */
+
+/* Map an allocation request type to a free list */
+#define H5MF_ALLOC_TO_FS_TYPE(F, T) ((H5FD_MEM_DEFAULT == (F)->shared->fs_type_map[T]) \
+ ? (T) : (F)->shared->fs_type_map[T])
+
/******************/
/* Local Typedefs */
/******************/
+/* Enum for kind of free space section+aggregator merging allowed for a file */
+typedef enum {
+ H5MF_AGGR_MERGE_SEPARATE, /* Everything in separate free list */
+ H5MF_AGGR_MERGE_DICHOTOMY, /* Metadata in one free list and raw data in another */
+ H5MF_AGGR_MERGE_TOGETHER /* Metadata & raw data in one free list */
+} H5MF_aggr_merge_t;
+
+/* User data for section info iterator callback for iterating over free space sections */
+typedef struct {
+ H5F_sect_info_t *sects; /* section info to be retrieved */
+ size_t sect_count; /* # of sections requested */
+ size_t sect_idx; /* the current count of sections */
+} H5MF_sect_iter_ud_t;
+
/********************/
/* Package Typedefs */
@@ -59,6 +82,10 @@
/* Local Prototypes */
/********************/
+/* Allocator routines */
+static herr_t H5MF_alloc_create(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type);
+static herr_t H5MF_alloc_close(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type);
+
/*********************/
/* Package Variables */
@@ -76,6 +103,291 @@
/*-------------------------------------------------------------------------
+ * Function: H5MF_init_merge_flags
+ *
+ * Purpose: Initialize the free space section+aggregator merge flags
+ * for the file.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, February 1, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5MF_init_merge_flags(H5F_t *f)
+{
+ H5MF_aggr_merge_t mapping_type; /* Type of free list mapping */
+ H5FD_mem_t type; /* Memory type for iteration */
+ hbool_t all_same; /* Whether all the types map to the same value */
+
+ FUNC_ENTER_NOAPI_NOFUNC(H5MF_init_merge_flags)
+
+ /* check args */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->lf);
+
+ /* Iterate over all the free space types to determine if sections of that type
+ * can merge with the metadata or small 'raw' data aggregator
+ */
+ all_same = TRUE;
+ for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type))
+ /* Check for any different type mappings */
+ if(f->shared->fs_type_map[type] != f->shared->fs_type_map[H5FD_MEM_DEFAULT]) {
+ all_same = FALSE;
+ break;
+ } /* end if */
+
+ /* Check for all allocation types mapping to the same free list type */
+ if(all_same) {
+ if(f->shared->fs_type_map[H5FD_MEM_DEFAULT] == H5FD_MEM_DEFAULT)
+ mapping_type = H5MF_AGGR_MERGE_SEPARATE;
+ else
+ mapping_type = H5MF_AGGR_MERGE_TOGETHER;
+ } /* end if */
+ else {
+ /* Check for raw data mapping into same list as metadata */
+ if(f->shared->fs_type_map[H5FD_MEM_DRAW] == f->shared->fs_type_map[H5FD_MEM_SUPER])
+ mapping_type = H5MF_AGGR_MERGE_SEPARATE;
+ else {
+ hbool_t all_metadata_same; /* Whether all metadata go in same free list */
+
+ /* One or more allocation type don't map to the same free list type */
+ /* Check if all the metadata allocation types map to the same type */
+ all_metadata_same = TRUE;
+ for(type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type))
+ /* Skip checking raw data free list mapping */
+ if(type != H5FD_MEM_DRAW) {
+ /* Check for any different type mappings */
+ if(f->shared->fs_type_map[type] != f->shared->fs_type_map[H5FD_MEM_SUPER]) {
+ all_metadata_same = FALSE;
+ break;
+ } /* end if */
+ } /* end if */
+
+ /* Check for all metadata on same free list */
+ if(all_metadata_same)
+ mapping_type = H5MF_AGGR_MERGE_DICHOTOMY;
+ else
+ mapping_type = H5MF_AGGR_MERGE_SEPARATE;
+ } /* end else */
+ } /* end else */
+
+ /* Based on mapping type, initialize merging flags for each free list type */
+ switch(mapping_type) {
+ case H5MF_AGGR_MERGE_SEPARATE:
+ /* Don't merge any metadata together */
+ HDmemset(f->shared->fs_aggr_merge, 0, sizeof(f->shared->fs_aggr_merge));
+
+ /* Check if merging raw data should be allowed */
+ if(H5FD_MEM_DRAW == f->shared->fs_type_map[H5FD_MEM_DRAW] ||
+ H5FD_MEM_DEFAULT == f->shared->fs_type_map[H5FD_MEM_DRAW])
+ f->shared->fs_aggr_merge[H5FD_MEM_DRAW] = H5F_FS_MERGE_RAWDATA;
+ break;
+
+ case H5MF_AGGR_MERGE_DICHOTOMY:
+ /* Merge all metadata together (but not raw data) */
+ HDmemset(f->shared->fs_aggr_merge, H5F_FS_MERGE_METADATA, sizeof(f->shared->fs_aggr_merge));
+
+ /* Allow merging raw data allocations together */
+ f->shared->fs_aggr_merge[H5FD_MEM_DRAW] = H5F_FS_MERGE_RAWDATA;
+ break;
+
+ case H5MF_AGGR_MERGE_TOGETHER:
+ /* Merge all allocation types together */
+ HDmemset(f->shared->fs_aggr_merge, (H5F_FS_MERGE_METADATA | H5F_FS_MERGE_RAWDATA), sizeof(f->shared->fs_aggr_merge));
+ break;
+ } /* end switch */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5MF_init_merge_flags() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_alloc_open
+ *
+ * Purpose: Open an existing free space manager of TYPE for file by
+ * creating a free-space structure
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jan 8 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5MF_alloc_open(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type)
+{
+ const H5FS_section_class_t *classes[] = { /* Free space section classes implemented for file */
+ H5MF_FSPACE_SECT_CLS_SIMPLE};
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5MF_alloc_open)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(H5F_addr_defined(f->shared->fs_addr[type]));
+ HDassert(f->shared->fs_state[type] == H5F_FS_STATE_CLOSED);
+
+ /* Open an existing free space structure for the file */
+ if(NULL == (f->shared->fs_man[type] = H5FS_open(f, dxpl_id, f->shared->fs_addr[type],
+ NELMTS(classes), classes, f, f->shared->alignment, f->shared->threshold)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space info")
+
+ /* Set the state for the free space manager to "open", if it is now */
+ if(f->shared->fs_man[type])
+ f->shared->fs_state[type] = H5F_FS_STATE_OPEN;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_alloc_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_alloc_create
+ *
+ * Purpose: Create free space manager of TYPE for the file by creating
+ * a free-space structure
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jan 8 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5MF_alloc_create(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type)
+{
+ const H5FS_section_class_t *classes[] = { /* Free space section classes implemented for file */
+ H5MF_FSPACE_SECT_CLS_SIMPLE};
+ herr_t ret_value = SUCCEED; /* Return value */
+ H5FS_create_t fs_create; /* Free space creation parameters */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5MF_alloc_create)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(!H5F_addr_defined(f->shared->fs_addr[type]));
+ HDassert(f->shared->fs_state[type] == H5F_FS_STATE_CLOSED);
+
+ /* Set the free space creation parameters */
+ fs_create.client = H5FS_CLIENT_FILE_ID;
+ fs_create.shrink_percent = H5MF_FSPACE_SHRINK;
+ fs_create.expand_percent = H5MF_FSPACE_EXPAND;
+ fs_create.max_sect_addr = 1 + H5V_log2_gen((uint64_t)f->shared->maxaddr);
+ fs_create.max_sect_size = f->shared->maxaddr;
+
+ if(NULL == (f->shared->fs_man[type] = H5FS_create(f, dxpl_id, NULL,
+ &fs_create, NELMTS(classes), classes, f, f->shared->alignment, f->shared->threshold)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space info")
+
+
+ /* Set the state for the free space manager to "open", if it is now */
+ if(f->shared->fs_man[type])
+ f->shared->fs_state[type] = H5F_FS_STATE_OPEN;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_alloc_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_alloc_start
+ *
+ * Purpose: Open or create a free space manager of a given type
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jan 8 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5MF_alloc_start(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5MF_alloc_start)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(f->shared);
+
+ /* Check if the free space manager exists already */
+ if(H5F_addr_defined(f->shared->fs_addr[type])) {
+ /* Open existing free space manager */
+ if(H5MF_alloc_open(f, dxpl_id, type) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTOPENOBJ, FAIL, "can't initialize file free space")
+ } /* end if */
+ else {
+ /* Create new free space manager */
+ if(H5MF_alloc_create(f, dxpl_id, type) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCREATE, FAIL, "can't initialize file free space")
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_alloc_start() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_alloc_close
+ *
+ * Purpose: Close an existing free space manager of TYPE for file
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Vailin Choi; July 1st, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5MF_alloc_close(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5MF_alloc_close)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->fs_man[type]);
+ HDassert(f->shared->fs_state[type] != H5F_FS_STATE_CLOSED);
+
+ /* Close an existing free space structure for the file */
+ if(H5FS_close(f, dxpl_id, f->shared->fs_man[type]) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't release free space info")
+ f->shared->fs_man[type] = NULL;
+ f->shared->fs_state[type] = H5F_FS_STATE_CLOSED;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_alloc_close() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5MF_alloc
*
* Purpose: Allocate SIZE bytes of file memory and return the relative
@@ -93,36 +405,168 @@
*-------------------------------------------------------------------------
*/
haddr_t
-H5MF_alloc(const H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
+H5MF_alloc(H5F_t *f, H5FD_mem_t alloc_type, hid_t dxpl_id, hsize_t size)
{
- haddr_t ret_value; /* Return value */
+ H5FD_mem_t fs_type; /* Free space type (mapped from allocation type) */
+ haddr_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5MF_alloc, HADDR_UNDEF)
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: alloc_type = %u, size = %Hu\n", FUNC, (unsigned)alloc_type, size);
+#endif /* H5MF_ALLOC_DEBUG */
/* check arguments */
HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->lf);
HDassert(size > 0);
- /* Fail if we don't have write access */
- if(0 == (f->intent & H5F_ACC_RDWR))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, HADDR_UNDEF, "file is read-only")
+ /* Get free space type from allocation type */
+ fs_type = H5MF_ALLOC_TO_FS_TYPE(f, alloc_type);
- /* Allocate space from the virtual file layer */
- if(HADDR_UNDEF == (ret_value = H5FD_alloc(f->shared->lf, type, dxpl_id, size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed")
+ /* Check if we are using the free space manager for this file */
+ if(H5F_HAVE_FREE_SPACE_MANAGER(f)) {
+ /* Check if the free space manager for the file has been initialized */
+ if(!f->shared->fs_man[fs_type] && H5F_addr_defined(f->shared->fs_addr[fs_type]))
+ if(H5MF_alloc_open(f, dxpl_id, fs_type) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTOPENOBJ, HADDR_UNDEF, "can't initialize file free space")
- /* Convert absolute file address to relative file address */
- HDassert(ret_value >= f->shared->base_addr);
+ /* Search for large enough space in the free space manager */
+ if(f->shared->fs_man[fs_type]) {
+ H5MF_free_section_t *node; /* Free space section pointer */
+ htri_t node_found = FALSE; /* Whether an existing free list node was found */
- /* Set return value */
- ret_value -= f->shared->base_addr;
+ /* Try to get a section from the free space manager */
+ if((node_found = H5FS_sect_find(f, dxpl_id, f->shared->fs_man[fs_type], size, (H5FS_section_info_t **)&node)) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "error locating free space in file")
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: Check 1.5, node_found = %t\n", FUNC, node_found);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+
+ /* Check for actually finding section */
+ if(node_found) {
+ /* Sanity check */
+ HDassert(node);
+
+ /* Retrieve return value */
+ ret_value = node->sect_info.addr;
+
+ /* Check for eliminating the section */
+ if(node->sect_info.size == size) {
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: Check 1.6, freeing node\n", FUNC);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+ /* Free section node */
+ if(H5MF_sect_simple_free((H5FS_section_info_t *)node) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, HADDR_UNDEF, "can't free simple section node")
+ } /* end if */
+ else {
+ H5MF_sect_ud_t udata; /* User data for callback */
+
+ /* Adjust information for section */
+ node->sect_info.addr += size;
+ node->sect_info.size -= size;
+
+ /* Construct user data for callbacks */
+ udata.f = f;
+ udata.dxpl_id = dxpl_id;
+ udata.alloc_type = alloc_type;
+ udata.allow_sect_absorb = TRUE;
+
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: Check 1.7, re-adding node, node->sect_info.size = %Hu\n", FUNC, node->sect_info.size);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+ /* Re-insert section node into file's free space */
+ if(H5FS_sect_add(f, dxpl_id, f->shared->fs_man[fs_type], (H5FS_section_info_t *)node, H5FS_ADD_RETURNED_SPACE, &udata) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, HADDR_UNDEF, "can't re-add section to file free space")
+ } /* end else */
+
+ /* Leave now */
+ HGOTO_DONE(ret_value)
+ } /* end if */
+ } /* end if */
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: Check 2.0\n", FUNC);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+ } /* end if */
+
+ /* Allocate from the metadata aggregator (or the VFD) */
+ if(HADDR_UNDEF == (ret_value = H5MF_aggr_vfd_alloc(f, alloc_type, dxpl_id, size)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "allocation failed from aggr/vfd")
done:
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Leaving: ret_value = %a, size = %Hu\n", FUNC, ret_value, size);
+#endif /* H5MF_ALLOC_DEBUG */
+#ifdef H5MF_ALLOC_DEBUG_DUMP
+H5MF_sects_dump(f, dxpl_id, stderr);
+#endif /* H5MF_ALLOC_DEBUG_DUMP */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF_alloc() */
/*-------------------------------------------------------------------------
+ * Function: H5MF_alloc_tmp
+ *
+ * Purpose: Allocate temporary space in the file
+ *
+ * Note: The address returned is non-overlapping with any other address
+ * in the file and suitable for insertion into the metadata
+ * cache.
+ *
+ * The address is _not_ suitable for actual file I/O and will
+ * cause an error if it is so used.
+ *
+ * The space allocated with this routine should _not_ be freed,
+ * it should just be abandoned. Calling H5MF_xfree() with space
+ * from this routine will cause an error.
+ *
+ * Return: Success: Temporary file address
+ * Failure: HADDR_UNDEF
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, June 4, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+haddr_t
+H5MF_alloc_tmp(H5F_t *f, hsize_t size)
+{
+ haddr_t eoa; /* End of allocated space in the file */
+ haddr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5MF_alloc_tmp, HADDR_UNDEF)
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: size = %Hu\n", FUNC, size);
+#endif /* H5MF_ALLOC_DEBUG */
+
+ /* check args */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->lf);
+ HDassert(size > 0);
+
+ /* Retrieve the 'eoa' for the file */
+ if(HADDR_UNDEF == (eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_DEFAULT)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, HADDR_UNDEF, "driver get_eoa request failed")
+
+ /* Compute value to return */
+ ret_value = f->shared->tmp_addr - size;
+
+ /* Check for overlap into the actual allocated space in the file */
+ if(H5F_addr_le(ret_value, eoa))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, HADDR_UNDEF, "driver get_eoa request failed")
+
+ /* Adjust temporary address allocator in the file */
+ f->shared->tmp_addr = ret_value;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_alloc_tmp() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5MF_xfree
*
* Purpose: Frees part of a file, making that part of the file
@@ -137,148 +581,696 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5MF_xfree(const H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size)
+H5MF_xfree(H5F_t *f, H5FD_mem_t alloc_type, hid_t dxpl_id, haddr_t addr,
+ hsize_t size)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ H5MF_free_section_t *node = NULL; /* Free space section pointer */
+ H5MF_sect_ud_t udata; /* User data for callback */
+ H5FD_mem_t fs_type; /* Free space type (mapped from allocation type) */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5MF_xfree)
+ FUNC_ENTER_NOAPI(H5MF_xfree, FAIL)
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Entering - alloc_type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)alloc_type, addr, size);
+#endif /* H5MF_ALLOC_DEBUG */
/* check arguments */
HDassert(f);
if(!H5F_addr_defined(addr) || 0 == size)
HGOTO_DONE(SUCCEED);
- HDassert(addr != 0);
+ HDassert(addr != 0); /* Can't deallocate the superblock :-) */
+
+ /* Check for attempting to free space that's a 'temporary' file address */
+ if(H5F_addr_le(f->shared->tmp_addr, addr))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, FAIL, "attempting to free temporary file space")
+
+ /* Check if the space to free intersects with the file's metadata accumulator */
+ if(H5F_accum_free(f, dxpl_id, alloc_type, addr, size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "can't check free space intersection w/metadata accumulator")
+
+ /* Get free space type from allocation type */
+ fs_type = H5MF_ALLOC_TO_FS_TYPE(f, alloc_type);
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: fs_type = %u\n", FUNC, (unsigned)fs_type);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+
+ /* Check if the free space manager for the file has been initialized */
+ if(!f->shared->fs_man[fs_type]) {
+ /* If there's no free space manager for objects of this type,
+ * see if we can avoid creating one by checking if the freed
+ * space is at the end of the file
+ */
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: f->shared->fs_addr[%u] = %a\n", FUNC, (unsigned)fs_type, f->shared->fs_addr[fs_type]);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+ if(!H5F_addr_defined(f->shared->fs_addr[fs_type])) {
+ htri_t status; /* "can absorb" status for section into */
- /* Convert relative address to absolute address */
- addr += f->shared->base_addr;
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: Trying to avoid starting up free space manager\n", FUNC);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+ /* Try to shrink the file or absorb the block into a block aggregator */
+ if((status = H5MF_try_shrink(f, alloc_type, dxpl_id, addr, size)) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMERGE, FAIL, "can't check for absorbing block")
+ else if(status > 0)
+ /* Indicate success */
+ HGOTO_DONE(SUCCEED)
+ else if(size < f->shared->fs_threshold) {
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", FUNC, addr, size);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+ HGOTO_DONE(SUCCEED)
+ }
+ } /* end if */
- /* Allow virtual file layer to free block */
- if(H5FD_free(f->shared->lf, type, dxpl_id, addr, size) < 0) {
-#ifdef H5MF_DEBUG
- if(H5DEBUG(MF))
- fprintf(H5DEBUG(MF), "H5MF_free: lost %lu bytes of file storage\n", (unsigned long)size);
-#endif
+ /* If we are deleting the free space manager, leave now, to avoid
+ * [re-]starting it.
+ * or if file space strategy type is not using a free space manager
+ * (H5F_FILE_SPACE_AGGR_VFD or H5F_FILE_SPACE_VFD), drop free space
+ * section on the floor.
+ *
+ * Note: this drops the space to free on the floor...
+ *
+ */
+ if(f->shared->fs_state[fs_type] == H5F_FS_STATE_DELETING ||
+ !H5F_HAVE_FREE_SPACE_MANAGER(f)) {
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", FUNC, addr, size);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+ HGOTO_DONE(SUCCEED)
+ } /* end if */
+
+ /* There's either already a free space manager, or the freed
+ * space isn't at the end of the file, so start up (or create)
+ * the file space manager
+ */
+ if(H5MF_alloc_start(f, dxpl_id, fs_type) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space")
} /* end if */
+ /* Create free space section for block */
+ if(NULL == (node = H5MF_sect_simple_new(addr, size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space section")
+
+ /* Construct user data for callbacks */
+ udata.f = f;
+ udata.dxpl_id = dxpl_id;
+ udata.alloc_type = alloc_type;
+ udata.allow_sect_absorb = TRUE;
+
+ /* If size of section freed is larger than threshold, add it to the free space manager */
+ if(size >= f->shared->fs_threshold) {
+ HDassert(f->shared->fs_man[fs_type]);
+
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: Before H5FS_sect_add()\n", FUNC);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+ /* Add to the free space for the file */
+ if(H5FS_sect_add(f, dxpl_id, f->shared->fs_man[fs_type], (H5FS_section_info_t *)node, H5FS_ADD_RETURNED_SPACE, &udata) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't add section to file free space")
+ node = NULL;
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: After H5FS_sect_add()\n", FUNC);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+ } /* end if */
+ else {
+ htri_t merged; /* Whether node was merged */
+
+ /* Try to merge the section that is smaller than threshold */
+ if((merged = H5FS_sect_try_merge(f, dxpl_id, f->shared->fs_man[fs_type], (H5FS_section_info_t *)node, H5FS_ADD_RETURNED_SPACE, &udata)) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't merge section to file free space")
+ else if(merged == TRUE) /* successfully merged */
+ /* Indicate that the node was used */
+ node = NULL;
+ } /* end else */
+
done:
+ /* Release section node, if allocated and not added to section list or merged */
+ if(node)
+ if(H5MF_sect_simple_free((H5FS_section_info_t *)node) < 0)
+ HDONE_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free simple section node")
+
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value);
+#endif /* H5MF_ALLOC_DEBUG */
+#ifdef H5MF_ALLOC_DEBUG_DUMP
+H5MF_sects_dump(f, dxpl_id, stderr);
+#endif /* H5MF_ALLOC_DEBUG_DUMP */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF_xfree() */
/*-------------------------------------------------------------------------
- * Function: H5MF_realloc
+ * Function: H5MF_try_extend
*
- * Purpose: Changes the size of an allocated chunk, possibly moving it to
- * a new address. The chunk to change is at address OLD_ADDR
- * and is exactly OLD_SIZE bytes (if these are H5F_ADDR_UNDEF
- * and zero then this function acts like H5MF_alloc). The new
- * size will be NEW_SIZE and its address is the return value (if
- * NEW_SIZE is zero then this function acts like H5MF_free and
- * an undefined address is returned).
+ * Purpose: Extend a block in the file if possible.
*
- * If the new size is less than the old size then the new
- * address will be the same as the old address (except for the
- * special case where the new size is zero).
+ * Return: Success: TRUE(1) - Block was extended
+ * FALSE(0) - Block could not be extended
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, June 11, 2004
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5MF_try_extend(H5F_t *f, hid_t dxpl_id, H5FD_mem_t alloc_type, haddr_t addr,
+ hsize_t size, hsize_t extra_requested)
+{
+ haddr_t end; /* End of block to extend */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5MF_try_extend, FAIL)
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Entering: alloc_type = %u, addr = %a, size = %Hu, extra_requested = %Hu\n", FUNC, (unsigned)alloc_type, addr, size, extra_requested);
+#endif /* H5MF_ALLOC_DEBUG */
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(H5F_INTENT(f) & H5F_ACC_RDWR);
+
+ /* Compute end of block to extend */
+ end = addr + size;
+
+ /* Check if the block is exactly at the end of the file */
+ if((ret_value = H5FD_try_extend(f->shared->lf, alloc_type, f, end, extra_requested)) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTEXTEND, FAIL, "error extending file")
+ else if(ret_value == FALSE) {
+ H5F_blk_aggr_t *aggr; /* Aggregator to use */
+
+ /* Check for test block able to extend aggregation block */
+ aggr = (alloc_type == H5FD_MEM_DRAW) ? &(f->shared->sdata_aggr) : &(f->shared->meta_aggr);
+ if((ret_value = H5MF_aggr_try_extend(f, aggr, alloc_type, end, extra_requested)) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTEXTEND, FAIL, "error extending aggregation block")
+ else if(ret_value == FALSE) {
+ H5FD_mem_t fs_type; /* Free space type (mapped from allocation type) */
+
+ /* Get free space type from allocation type */
+ fs_type = H5MF_ALLOC_TO_FS_TYPE(f, alloc_type);
+
+ /* Check if the free space for the file has been initialized */
+ if(!f->shared->fs_man[fs_type] && H5F_addr_defined(f->shared->fs_addr[fs_type]))
+ if(H5MF_alloc_open(f, dxpl_id, fs_type) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space")
+
+ /* Check for test block able to block in free space manager */
+ if(f->shared->fs_man[fs_type])
+ if((ret_value = H5FS_sect_try_extend(f, dxpl_id, f->shared->fs_man[fs_type], addr, size, extra_requested)) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTEXTEND, FAIL, "error extending block in free space manager")
+ } /* end if */
+ } /* end if */
+
+done:
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Leaving: ret_value = %t\n", FUNC, ret_value);
+#endif /* H5MF_ALLOC_DEBUG */
+#ifdef H5MF_ALLOC_DEBUG_DUMP
+H5MF_sects_dump(f, dxpl_id, stderr);
+#endif /* H5MF_ALLOC_DEBUG_DUMP */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_try_extend() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_get_freespace
*
- * If the new size is more than the old size then most likely a
- * new address will be returned. However, under certain
- * circumstances the library may return the same address.
+ * Purpose: Retrieve the amount of free space in a file.
*
- * Return: Success: The relative file address of the new block.
- * Failure: HADDR_UNDEF
+ * Return: Success: Amount of free space in file
+ * Failure: Negative
*
- * Programmer: Robb Matzke
- * Thursday, April 16, 1998
+ * Programmer: Quincey Koziol
+ * Monday, October 6, 2003
*
*-------------------------------------------------------------------------
*/
-haddr_t
-H5MF_realloc(H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsize_t old_size,
- hsize_t new_size)
+herr_t
+H5MF_get_freespace(H5F_t *f, hid_t dxpl_id, hsize_t *tot_space, hsize_t *meta_size)
{
- haddr_t ret_value;
+ haddr_t eoa; /* End of allocated space in the file */
+ haddr_t ma_addr = HADDR_UNDEF; /* Base "metadata aggregator" address */
+ hsize_t ma_size = 0; /* Size of "metadata aggregator" */
+ haddr_t sda_addr = HADDR_UNDEF; /* Base "small data aggregator" address */
+ hsize_t sda_size = 0; /* Size of "small data aggregator" */
+ hsize_t tot_fs_size = 0; /* Amount of all free space managed */
+ hsize_t tot_meta_size = 0; /* Amount of metadata for free space managers */
+ H5FD_mem_t type; /* Memory type for iteration */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5MF_realloc, HADDR_UNDEF)
+ FUNC_ENTER_NOAPI(H5MF_get_freespace, FAIL)
- /* Convert old relative address to absolute address */
- old_addr += f->shared->base_addr;
+ /* check args */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->lf);
- /* Reallocate memory from the virtual file layer */
- ret_value = H5FD_realloc(f->shared->lf, type, dxpl_id, old_addr, old_size, new_size);
- if(HADDR_UNDEF == ret_value)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "unable to allocate new file memory")
+ /* Retrieve the 'eoa' for the file */
+ if(HADDR_UNDEF == (eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_DEFAULT)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "driver get_eoa request failed")
- /* Convert return value to relative address */
- HDassert(ret_value >= f->shared->base_addr);
+ /* Retrieve metadata aggregator info, if available */
+ if(H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query metadata aggregator stats")
- /* Set return value */
- ret_value -= f->shared->base_addr;
+ /* Retrieve 'small data' aggregator info, if available */
+ if(H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sda_addr, &sda_size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query small data aggregator stats")
+
+ /* Iterate over all the free space types that have managers and get each free list's space */
+ for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) {
+ hbool_t fs_started = FALSE;
+
+ /* Check if the free space for the file has been initialized */
+ if(!f->shared->fs_man[type] && H5F_addr_defined(f->shared->fs_addr[type])) {
+ if(H5MF_alloc_open(f, dxpl_id, type) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space")
+ HDassert(f->shared->fs_man[type]);
+ fs_started = TRUE;
+ } /* end if */
+
+ /* Check if there's free space of this type */
+ if(f->shared->fs_man[type]) {
+ hsize_t type_fs_size = 0; /* Amount of free space managed for each type */
+ hsize_t type_meta_size = 0; /* Amount of free space metadata for each type */
+
+ /* Retrieve free space size from free space manager */
+ if(H5FS_sect_stats(f->shared->fs_man[type], &type_fs_size, NULL) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query free space stats")
+ if(H5FS_size(f, f->shared->fs_man[type], &type_meta_size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query free space metadata stats")
+
+ /* Increment total free space for types */
+ tot_fs_size += type_fs_size;
+ tot_meta_size += type_meta_size;
+ } /* end if */
+
+ /* Close the free space manager, if we opened it here */
+ if(fs_started)
+ if(H5MF_alloc_close(f, dxpl_id, type) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't close file free space")
+ } /* end for */
+
+ /* Check for aggregating metadata allocations */
+ if(ma_size > 0) {
+ /* Add in the reserved space for metadata to the available free space */
+ /* (if it's not at the tail of the file) */
+ if(H5F_addr_ne(ma_addr + ma_size, eoa))
+ tot_fs_size += ma_size;
+ } /* end if */
+
+ /* Check for aggregating small data allocations */
+ if(sda_size > 0) {
+ /* Add in the reserved space for metadata to the available free space */
+ /* (if it's not at the tail of the file) */
+ if(H5F_addr_ne(sda_addr + sda_size, eoa))
+ tot_fs_size += sda_size;
+ } /* end if */
+
+ /* Set the value(s) to return */
+ if(tot_space)
+ *tot_space = tot_fs_size;
+ if(meta_size)
+ *meta_size = tot_meta_size;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5MF_realloc() */
+} /* end H5MF_get_freespace() */
/*-------------------------------------------------------------------------
- * Function: H5MF_can_extend
+ * Function: H5MF_can_shrink
*
- * Purpose: Check if a block in the file can be extended.
+ * Purpose: Try to shrink the size of a file with a block or absorb it
+ * into a block aggregator.
*
- * Return: Success: TRUE(1)/FALSE(0)
- * Failure: FAIL
+ * Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * Friday, June 11, 2004
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Feb 14 2008
*
*-------------------------------------------------------------------------
*/
htri_t
-H5MF_can_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested)
+H5MF_try_shrink(H5F_t *f, H5FD_mem_t alloc_type, hid_t dxpl_id, haddr_t addr,
+ hsize_t size)
{
- htri_t ret_value; /* Return value */
+ H5MF_free_section_t *node = NULL; /* Free space section pointer */
+ H5MF_sect_ud_t udata; /* User data for callback */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5MF_try_shrink, FAIL)
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Entering - alloc_type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)alloc_type, addr, size);
+#endif /* H5MF_ALLOC_DEBUG */
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->lf);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(size > 0);
- FUNC_ENTER_NOAPI(H5MF_can_extend, FAIL)
+ /* Create free space section for block */
+ if(NULL == (node = H5MF_sect_simple_new(addr, size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space section")
- /* Convert old relative address to absolute address */
- addr += H5F_BASE_ADDR(f);
+ /* Construct user data for callbacks */
+ udata.f = f;
+ udata.dxpl_id = dxpl_id;
+ udata.alloc_type = alloc_type;
+ udata.allow_sect_absorb = FALSE; /* Force section to be absorbed into aggregator */
- /* Pass the request down to the virtual file layer */
- if((ret_value = H5FD_can_extend(f->shared->lf, type, addr, size, extra_requested)) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate new file memory");
+ /* Call the "can shrink" callback for the section */
+ if((ret_value = H5MF_sect_simple_can_shrink((const H5FS_section_info_t *)node, &udata)) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTMERGE, FAIL, "can't check if section can shrink container")
+ else if(ret_value > 0) {
+ /* Shrink or absorb the section */
+ if(H5MF_sect_simple_shrink((H5FS_section_info_t **)&node, &udata) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't shrink container")
+ } /* end if */
done:
+ /* Free section node allocated */
+ if(node && H5MF_sect_simple_free((H5FS_section_info_t *)node) < 0)
+ HDONE_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free simple section node")
+
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value);
+#endif /* H5MF_ALLOC_DEBUG */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5MF_can_extend() */
+} /* end H5MF_try_shrink() */
/*-------------------------------------------------------------------------
- * Function: H5MF_extend
+ * Function: H5MF_close
*
- * Purpose: Extend a block in the file.
+ * Purpose: Close the free space tracker(s) for a file
*
- * Return: Success: Non-negative
- * Failure: Negative
+ * Return: SUCCEED/FAIL
*
- * Programmer: Quincey Koziol
- * Saturday, June 12, 2004
+ * Programmer: Quincey Koziol
+ * Tuesday, January 22, 2008
*
*-------------------------------------------------------------------------
*/
herr_t
-H5MF_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested)
+H5MF_close(H5F_t *f, hid_t dxpl_id)
{
- herr_t ret_value; /* Return value */
+ H5FD_mem_t type; /* Memory type for iteration */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5MF_close, FAIL)
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Entering\n", FUNC);
+#endif /* H5MF_ALLOC_DEBUG */
+
+ /* check args */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->lf);
+
+ /* Free the space in aggregators */
+ /* (for space not at EOF, it may be put into free space managers) */
+ if(H5MF_free_aggrs(f, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't free aggregators")
+
+ /* Making free-space managers persistent for superblock version >= 2 */
+ if(f->shared->sblock->super_vers >= HDF5_SUPERBLOCK_VERSION_2
+ && f->shared->fs_strategy == H5F_FILE_SPACE_ALL_PERSIST) {
+ H5O_fsinfo_t fsinfo; /* Free space manager info message */
+ hbool_t update = FALSE; /* To update info for the message */
+
+ /* Check to remove free-space manager info message from superblock extension */
+ if(H5F_addr_defined(f->shared->sblock->ext_addr))
+ if(H5F_super_ext_remove_msg(f, dxpl_id, H5O_FSINFO_ID) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "error in removing message from superblock extension")
+
+ /* Free free-space manager header and/or section info header */
+ for(type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) {
+ H5FS_stat_t fs_stat; /* Information for free-space manager */
+
+ /* Check for free space manager of this type */
+ if(f->shared->fs_man[type]) {
+ /* Switch to "about to be deleted" state */
+ f->shared->fs_state[type] = H5F_FS_STATE_DELETING;
+
+ /* Query the free space manager's information */
+ if(H5FS_stat_info(f, f->shared->fs_man[type], &fs_stat) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't get free-space info")
+
+ /* Check if the free space manager has space in the file */
+ if(H5F_addr_defined(fs_stat.addr) || H5F_addr_defined(fs_stat.sect_addr)) {
+ /* Delete the free space manager in the file */
+ /* (will re-allocate later) */
+ if(H5FS_free(f, f->shared->fs_man[type], dxpl_id) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't release free-space headers")
+ f->shared->fs_addr[type] = HADDR_UNDEF;
+ } /* end if */
+ } /* end iif */
+ fsinfo.fs_addr[type-1] = HADDR_UNDEF;
+ } /* end for */
+
+ fsinfo.strategy = f->shared->fs_strategy;
+ fsinfo.threshold = f->shared->fs_threshold;
+
+ /* Write free-space manager info message to superblock extension object header */
+ /* Create the superblock extension object header in advance if needed */
+ if(H5F_super_ext_write_msg(f, dxpl_id, &fsinfo, H5O_FSINFO_ID, TRUE) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_WRITEERROR, FAIL, "error in writing message to superblock extension")
+
+ /* Re-allocate free-space manager header and/or section info header */
+ for(type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) {
+ H5FS_stat_t fs_stat; /* Information for free-space manager */
+
+ /* Check for active free space manager of this type */
+ if(f->shared->fs_man[type]) {
+ /* Re-query free space manager info for this type */
+ if(H5FS_stat_info(f, f->shared->fs_man[type], &fs_stat) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't get free-space info")
+
+ /* Are there sections to persist? */
+ if(fs_stat.serial_sect_count) {
+ /* Allocate space for free-space manager header */
+ if(H5FS_alloc_hdr(f, f->shared->fs_man[type], &f->shared->fs_addr[type], dxpl_id) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "can't allocated free-space header")
+
+ /* Allocate space for free-space maanger section info header */
+ if(H5FS_alloc_sect(f, f->shared->fs_man[type], dxpl_id) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate free-space section info")
- FUNC_ENTER_NOAPI(H5MF_extend, FAIL)
+ HDassert(f->shared->fs_addr[type]);
+ fsinfo.fs_addr[type-1] = f->shared->fs_addr[type];
+ update = TRUE;
+ } /* end if */
+ } else if(H5F_addr_defined(f->shared->fs_addr[type])) {
+ fsinfo.fs_addr[type-1] = f->shared->fs_addr[type];
+ update = TRUE;
+ } /* end else-if */
+ } /* end for */
- /* Convert relative address to absolute address */
- addr += H5F_BASE_ADDR(f);
+ /* Update the free space manager info message in superblock extension object header */
+ if(update)
+ if(H5F_super_ext_write_msg(f, dxpl_id, &fsinfo, H5O_FSINFO_ID, FALSE) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_WRITEERROR, FAIL, "error in writing message to superblock extension")
- /* Pass the request down to the virtual file layer */
- if((ret_value = H5FD_extend(f->shared->lf, type, addr, size, extra_requested)) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate new file memory")
+ /* Final close of free-space managers */
+ for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) {
+ if(f->shared->fs_man[type]) {
+ if(H5FS_close(f, dxpl_id, f->shared->fs_man[type]) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't close free space manager")
+ f->shared->fs_man[type] = NULL;
+ f->shared->fs_state[type] = H5F_FS_STATE_CLOSED;
+ } /* end if */
+ f->shared->fs_addr[type] = HADDR_UNDEF;
+ } /* end for */
+ } /* end if */
+ else { /* super_vers can be 0, 1, 2 */
+ /* Iterate over all the free space types that have managers and get each free list's space */
+ for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) {
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: Check 1.0 - f->shared->fs_man[%u] = %p, f->shared->fs_addr[%u] = %a\n", FUNC, (unsigned)type, f->shared->fs_man[type], (unsigned)type, f->shared->fs_addr[type]);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+ /* If the free space manager for this type is open, close it */
+ if(f->shared->fs_man[type]) {
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: Before closing free space manager\n", FUNC);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+ if(H5FS_close(f, dxpl_id, f->shared->fs_man[type]) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't release free space info")
+ f->shared->fs_man[type] = NULL;
+ f->shared->fs_state[type] = H5F_FS_STATE_CLOSED;
+ } /* end if */
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: Check 2.0 - f->shared->fs_man[%u] = %p, f->shared->fs_addr[%u] = %a\n", FUNC, (unsigned)type, f->shared->fs_man[type], (unsigned)type, f->shared->fs_addr[type]);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+
+ /* If there is free space manager info for this type, delete it */
+ if(H5F_addr_defined(f->shared->fs_addr[type])) {
+ haddr_t tmp_fs_addr; /* Temporary holder for free space manager address */
+
+ /* Put address into temporary variable and reset it */
+ /* (Avoids loopback in file space freeing routine) */
+ tmp_fs_addr = f->shared->fs_addr[type];
+ f->shared->fs_addr[type] = HADDR_UNDEF;
+
+ /* Shift to "deleting" state, to make certain we don't track any
+ * file space freed as a result of deleting the free space manager.
+ */
+ f->shared->fs_state[type] = H5F_FS_STATE_DELETING;
+
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: Before deleting free space manager\n", FUNC);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+
+ /* Delete free space manager for this type */
+ if(H5FS_delete(f, dxpl_id, tmp_fs_addr) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "can't delete free space manager")
+
+ /* Shift [back] to closed state */
+ HDassert(f->shared->fs_state[type] == H5F_FS_STATE_DELETING);
+ f->shared->fs_state[type] = H5F_FS_STATE_CLOSED;
+
+ /* Sanity check that the free space manager for this type wasn't started up again */
+ HDassert(!H5F_addr_defined(f->shared->fs_addr[type]));
+ } /* end if */
+ } /* end for */
+ } /* end else */
+
+ /* Free the space in aggregators (again) */
+ /* (in case any free space information re-started them) */
+ if(H5MF_free_aggrs(f, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't free aggregators")
+
+done:
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Leaving\n", FUNC);
+#endif /* H5MF_ALLOC_DEBUG */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_sects_cb()
+ *
+ * Purpose: Iterator callback for each free-space section
+ * Retrieve address and size into user data
+ *
+ * Return: Always succeed
+ *
+ * Programmer: Vailin Choi
+ * July 1st, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5MF_sects_cb(const H5FS_section_info_t *_sect, void *_udata)
+{
+ const H5MF_free_section_t *sect = (const H5MF_free_section_t *)_sect;
+ H5MF_sect_iter_ud_t *udata = (H5MF_sect_iter_ud_t *)_udata;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MF_sects_cb)
+
+ if(udata->sect_idx < udata->sect_count) {
+ udata->sects[udata->sect_idx].addr = sect->sect_info.addr;
+ udata->sects[udata->sect_idx].size = sect->sect_info.size;
+ udata->sect_idx++;
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5MF_sects_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_get_free_sections()
+ *
+ * Purpose: To iterate over one or all free-space managers for:
+ * # of sections
+ * section info as defined in H5F_sect_info_t
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Vailin Choi
+ * July 1st, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5MF_get_free_sections(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, size_t nsects, H5F_sect_info_t *sect_info)
+{
+ size_t total_sects = 0; /* total number of sections */
+ H5MF_sect_iter_ud_t sect_udata; /* User data for callback */
+ H5FD_mem_t start_type, end_type; /* Memory types to iterate over */
+ H5FD_mem_t ty; /* Memory type for iteration */
+ ssize_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5MF_get_free_sections, FAIL)
+
+ /* check args */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->lf);
+
+ /* Determine start/end points for loop */
+ if(type == H5FD_MEM_DEFAULT) {
+ start_type = H5FD_MEM_SUPER;
+ end_type = H5FD_MEM_NTYPES;
+ } /* end if */
+ else {
+ start_type = end_type = type;
+ H5_INC_ENUM(H5FD_mem_t, end_type);
+ } /* end else */
+
+ /* Set up user data for section iteration */
+ sect_udata.sects = sect_info;
+ sect_udata.sect_count = nsects;
+ sect_udata.sect_idx = 0;
+
+ /* Iterate over memory types, retrieving the number of sections of each type */
+ for(ty = start_type; ty < end_type; H5_INC_ENUM(H5FD_mem_t, ty)) {
+ hbool_t fs_started = FALSE;
+
+ /* Open free space manager of this type, if it isn't already */
+ if(!f->shared->fs_man[ty] && H5F_addr_defined(f->shared->fs_addr[ty])) {
+ if(H5MF_alloc_open(f, dxpl_id, ty) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTOPENOBJ, FAIL, "can't initialize file free space")
+ HDassert(f->shared->fs_man[ty]);
+ fs_started = TRUE;
+ } /* end if */
+
+ /* Check if f there's free space sections of this type */
+ if(f->shared->fs_man[ty]) {
+ hsize_t hnums = 0; /* Total # of sections */
+ size_t nums; /* Total # of sections, cast to a size_t */
+
+ /* Query how many sections of this type */
+ if(H5FS_sect_stats(f->shared->fs_man[ty], NULL, &hnums) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query free space stats")
+ H5_ASSIGN_OVERFLOW(nums, hnums, hsize_t, size_t);
+
+ /* Increment total # of sections */
+ total_sects += nums;
+
+ /* Check if we should retrieve the section info */
+ if(sect_info && nums > 0) {
+ /* Iterate over all the free space sections of this type, adding them to the user's section info */
+ if(H5FS_sect_iterate(f, dxpl_id, f->shared->fs_man[ty], H5MF_sects_cb, &sect_udata) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_BADITER, FAIL, "can't iterate over sections")
+ } /* end if */
+ } /* end if */
+
+ /* Close the free space manager of this type, if we started it here */
+ if(fs_started)
+ if(H5MF_alloc_close(f, dxpl_id, ty) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCLOSEOBJ, FAIL, "can't close file free space")
+ } /* end for */
+
+ /* Set return value */
+ ret_value = (ssize_t)total_sects;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5MF_extend() */
+} /* H5MF_get_free_sections() */
diff --git a/src/H5MFaggr.c b/src/H5MFaggr.c
new file mode 100644
index 0000000..db13408
--- /dev/null
+++ b/src/H5MFaggr.c
@@ -0,0 +1,727 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Quincey Koziol <koziol@hdfgroup.org>
+ * Tuesday, January 8, 2008
+ *
+ * Purpose: Routines for aggregating free space allocations
+ *
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+#define H5MF_PACKAGE /*suppress error about including H5MFpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5MFpkg.h" /* File memory management */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_aggr_vfd_alloc
+ *
+ * Purpose: Allocate SIZE bytes of file memory via H5MF_aggr_alloc()
+ * and return the relative address where that contiguous chunk
+ * of file memory exists.
+ * The TYPE argument describes the purpose for which the storage
+ * is being requested.
+ *
+ * Return: Success: The file address of new chunk.
+ * Failure: HADDR_UNDEF
+ *
+ * Programmer: Vailin Choi; July 1st, 2009
+ * (The coding is from H5MF_alloc().)
+ *
+ *-------------------------------------------------------------------------
+ */
+haddr_t
+H5MF_aggr_vfd_alloc(H5F_t *f, H5FD_mem_t alloc_type, hid_t dxpl_id, hsize_t size)
+{
+ haddr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5MF_aggr_vfd_alloc, HADDR_UNDEF)
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: alloc_type = %u, size = %Hu\n", FUNC, (unsigned)alloc_type, size);
+#endif /* H5MF_ALLOC_DEBUG */
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->lf);
+ HDassert(size > 0);
+
+ /* Couldn't find anything from the free space manager, go allocate some */
+ if(alloc_type != H5FD_MEM_DRAW) {
+ /* Handle metadata differently from "raw" data */
+ if(HADDR_UNDEF == (ret_value = H5MF_aggr_alloc(f, dxpl_id, &(f->shared->meta_aggr), &(f->shared->sdata_aggr), alloc_type, size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate metadata")
+ } /* end if */
+ else {
+ /* Allocate "raw" data */
+ if(HADDR_UNDEF == (ret_value = H5MF_aggr_alloc(f, dxpl_id, &(f->shared->sdata_aggr), &(f->shared->meta_aggr), alloc_type, size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate raw data")
+ } /* end else */
+
+ /* Sanity check for overlapping into file's temporary allocation space */
+ HDassert(H5F_addr_le((ret_value + size), f->shared->tmp_addr));
+
+done:
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Leaving: ret_value = %a, size = %Hu\n", FUNC, ret_value, size);
+#endif /* H5MF_ALLOC_DEBUG */
+#ifdef H5MF_ALLOC_DEBUG_DUMP
+H5MF_sects_dump(f, dxpl_id, stderr);
+#endif /* H5MF_ALLOC_DEBUG_DUMP */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_aggr_vfd_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_aggr_alloc
+ *
+ * Purpose: Try to allocate SIZE bytes of memory from an aggregator
+ * block if possible.
+ *
+ * Return: Success: The format address of the new file memory.
+ * Failure: The undefined address HADDR_UNDEF
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 13, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+haddr_t
+H5MF_aggr_alloc(H5F_t *f, hid_t dxpl_id, H5F_blk_aggr_t *aggr,
+ H5F_blk_aggr_t *other_aggr, H5FD_mem_t type, hsize_t size)
+{
+ haddr_t eoa_frag_addr = HADDR_UNDEF; /* Address of fragment at EOA */
+ hsize_t eoa_frag_size = 0; /* Size of fragment at EOA */
+ haddr_t eoa = HADDR_UNDEF; /* Initial EOA for the file */
+ haddr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5MF_aggr_alloc, HADDR_UNDEF)
+#ifdef H5MF_AGGR_DEBUG
+HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
+#endif /* H5MF_AGGR_DEBUG */
+
+ /* check args */
+ HDassert(f);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+ HDassert(other_aggr);
+ HDassert(other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+ HDassert(other_aggr->feature_flag != aggr->feature_flag);
+ HDassert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
+ HDassert(size > 0);
+
+ /* Get the EOA for the file */
+ if(HADDR_UNDEF == (eoa = H5F_get_eoa(f, type)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, HADDR_UNDEF, "Unable to get eoa")
+
+ /*
+ * If the aggregation feature is enabled for this file and strategy is not H5F_FILE_SPACE_VFD,
+ * allocate "generic" space and sub-allocate out of that, if possible.
+ * Otherwise just allocate through H5FD_alloc().
+ */
+ if((f->shared->feature_flags & aggr->feature_flag) && f->shared->fs_strategy != H5F_FILE_SPACE_VFD) {
+ haddr_t aggr_frag_addr = HADDR_UNDEF; /* Address of aggregrator fragment */
+ hsize_t aggr_frag_size = 0; /* Size of aggregator fragment */
+ hsize_t alignment; /* Alignment of this section */
+ hsize_t aggr_mis_align = 0; /* Mis-alignment of aggregator */
+ H5FD_mem_t alloc_type, other_alloc_type;/* Current aggregator & 'other' aggregator types */
+
+#ifdef H5MF_AGGR_DEBUG
+HDfprintf(stderr, "%s: aggr = {%a, %Hu, %Hu}\n", FUNC, aggr->addr, aggr->tot_size, aggr->size);
+#endif /* H5MF_AGGR_DEBUG */
+
+ /* Turn off alignment if allocation < threshold */
+ alignment = f->shared->alignment;
+ if(!((alignment > 1) && (size >= f->shared->threshold)))
+ alignment = 0; /* no alignment */
+
+ /* Generate fragment if aggregator is mis-aligned */
+ if(alignment && aggr->addr > 0 && aggr->size > 0 && (aggr_mis_align = (aggr->addr + H5FD_get_base_addr(f->shared->lf)) % alignment)) {
+ aggr_frag_addr = aggr->addr;
+ aggr_frag_size = alignment - aggr_mis_align;
+ } /* end if */
+
+ alloc_type = aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW;
+ other_alloc_type = other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW;
+
+ /* Check if the space requested is larger than the space left in the block */
+ if((size + aggr_frag_size) > aggr->size) {
+ htri_t extended = FALSE; /* Whether the file was extended */
+
+ /* Check if the block asked for is too large for 'normal' aggregator block */
+ if(size >= aggr->alloc_size) {
+ hsize_t ext_size = size + aggr_frag_size;
+
+ /* Check for overlapping into file's temporary allocation space */
+ if(H5F_addr_gt((aggr->addr + aggr->size + ext_size), f->shared->tmp_addr))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, HADDR_UNDEF, "'normal' file space allocation request will overlap into 'temporary' file space")
+
+ if ((aggr->addr > 0) && (extended = H5FD_try_extend(f->shared->lf, alloc_type, f, aggr->addr + aggr->size, ext_size)) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't extending space")
+ else if (extended) {
+ /* aggr->size is unchanged */
+ ret_value = aggr->addr + aggr_frag_size;
+ aggr->addr += ext_size;
+ aggr->tot_size += ext_size;
+ } else {
+ /* Check for overlapping into file's temporary allocation space */
+ if(H5F_addr_gt((eoa + size), f->shared->tmp_addr))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, HADDR_UNDEF, "'normal' file space allocation request will overlap into 'temporary' file space")
+
+ if ((other_aggr->size > 0) && (H5F_addr_eq((other_aggr->addr + other_aggr->size), eoa)) &&
+ ((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size)) {
+
+ if(H5FD_free(f->shared->lf, dxpl_id, other_alloc_type, f, other_aggr->addr, other_aggr->size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block")
+
+ other_aggr->addr = 0;
+ other_aggr->tot_size = 0;
+ other_aggr->size = 0;
+ } /* end if */
+
+ /* Allocate space from the VFD (i.e. at the end of the file) */
+ if(HADDR_UNDEF == (ret_value = H5FD_alloc(f->shared->lf, dxpl_id, type, f, size, &eoa_frag_addr, &eoa_frag_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate aggregation block")
+ } /* end else */
+ } /* end if */
+ else {
+ hsize_t ext_size = aggr->alloc_size;
+
+ /* Allocate another block */
+#ifdef H5MF_AGGR_DEBUG
+HDfprintf(stderr, "%s: Allocating block\n", FUNC);
+#endif /* H5MF_AGGR_DEBUG */
+
+ if(aggr_frag_size > (ext_size - size))
+ ext_size += (aggr_frag_size - (ext_size - size));
+
+ /* Check for overlapping into file's temporary allocation space */
+ if(H5F_addr_gt((aggr->addr + aggr->size + ext_size), f->shared->tmp_addr))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, HADDR_UNDEF, "'normal' file space allocation request will overlap into 'temporary' file space")
+
+ if((aggr->addr > 0) && (extended = H5FD_try_extend(f->shared->lf, alloc_type, f, aggr->addr + aggr->size, ext_size)) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't extending space")
+ else if (extended) {
+ aggr->addr += aggr_frag_size;
+ aggr->size += (ext_size - aggr_frag_size);
+ aggr->tot_size += ext_size;
+ } else {
+ haddr_t new_space; /* Address of new space allocated */
+
+ /* Check for overlapping into file's temporary allocation space */
+ if(H5F_addr_gt((eoa + aggr->alloc_size), f->shared->tmp_addr))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, HADDR_UNDEF, "'normal' file space allocation request will overlap into 'temporary' file space")
+
+ if((other_aggr->size > 0) && (H5F_addr_eq((other_aggr->addr + other_aggr->size), eoa)) &&
+ ((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size)) {
+
+ if(H5FD_free(f->shared->lf, dxpl_id, other_alloc_type, f, other_aggr->addr, other_aggr->size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block")
+ other_aggr->addr = 0;
+ other_aggr->tot_size = 0;
+ other_aggr->size = 0;
+ } /* end if */
+
+ /* Allocate space from the VFD (i.e. at the end of the file) */
+ if(HADDR_UNDEF == (new_space = H5FD_alloc(f->shared->lf, dxpl_id, alloc_type, f, aggr->alloc_size, &eoa_frag_addr, &eoa_frag_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate aggregation block")
+
+ /* Return the unused portion of the block to a free list */
+ if(aggr->size > 0)
+ if(H5MF_xfree(f, alloc_type, dxpl_id, aggr->addr, aggr->size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block")
+
+ /* Point the aggregator at the newly allocated block */
+ aggr->addr = new_space;
+ aggr->size = aggr->alloc_size;
+ aggr->tot_size = aggr->alloc_size;
+ } /* end else */
+
+ /* Allocate space out of the metadata block */
+ ret_value = aggr->addr;
+ aggr->size -= size;
+ aggr->addr += size;
+ } /* end else */
+
+ /* Freeing any possible fragment due to file allocation */
+ if(eoa_frag_size)
+ if(H5MF_xfree(f, type, dxpl_id, eoa_frag_addr, eoa_frag_size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, HADDR_UNDEF, "can't free eoa fragment")
+
+ /* Freeing any possible fragment due to alignment in the block after extension */
+ if(extended && aggr_frag_size)
+ if(H5MF_xfree(f, type, dxpl_id, aggr_frag_addr, aggr_frag_size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation fragment")
+ } /* end if */
+ else {
+ /* Allocate space out of the block */
+ ret_value = aggr->addr + aggr_frag_size;
+ aggr->size -= (size + aggr_frag_size);
+ aggr->addr += (size + aggr_frag_size);
+
+ /* free any possible fragment */
+ if(aggr_frag_size)
+ if(H5MF_xfree(f, type, dxpl_id, aggr_frag_addr, aggr_frag_size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation fragment")
+ } /* end else */
+ } /* end if */
+ else {
+ /* Check for overlapping into file's temporary allocation space */
+ if(H5F_addr_gt((eoa + size), f->shared->tmp_addr))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, HADDR_UNDEF, "'normal' file space allocation request will overlap into 'temporary' file space")
+
+ /* Allocate data from the file */
+ if(HADDR_UNDEF == (ret_value = H5FD_alloc(f->shared->lf, dxpl_id, type, f, size, &eoa_frag_addr, &eoa_frag_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate file space")
+
+ /* Check if fragment was generated */
+ if(eoa_frag_size)
+ /* Put fragment on the free list */
+ if(H5MF_xfree(f, type, dxpl_id, eoa_frag_addr, eoa_frag_size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, HADDR_UNDEF, "can't free eoa fragment")
+ } /* end else */
+
+ /* Sanity check for overlapping into file's temporary allocation space */
+ HDassert(H5F_addr_le((ret_value + size), f->shared->tmp_addr));
+
+ /* Post-condition sanity check */
+ if(f->shared->alignment && size >= f->shared->threshold)
+ HDassert(!((ret_value + H5FD_get_base_addr(f->shared->lf)) % f->shared->alignment));
+
+done:
+#ifdef H5MF_AGGR_DEBUG
+HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
+#endif /* H5MF_AGGR_DEBUG */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_aggr_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_aggr_try_extend
+ *
+ * Purpose: Check if a block is inside an aggregator block and extend it
+ * if possible.
+ *
+ * Return: Success: TRUE(1) - Block was extended
+ * FALSE(0) - Block could not be extended
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 13, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5MF_aggr_try_extend(H5F_t *f, H5F_blk_aggr_t *aggr, H5FD_mem_t type,
+ haddr_t blk_end, hsize_t extra_requested)
+{
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5MF_aggr_try_extend, FAIL)
+
+ /* Check args */
+ HDassert(f);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+
+ /* Check if this aggregator is active */
+ if(f->shared->feature_flags & aggr->feature_flag) {
+ /* If the block being tested adjoins the beginning of the aggregator
+ * block, check if the aggregator can accomodate the extension.
+ */
+ if(H5F_addr_eq(blk_end, aggr->addr)) {
+ /* If the aggregator block is at the end of the file, extend the
+ * file and "bubble" the aggregator up
+ */
+ if((ret_value = H5FD_try_extend(f->shared->lf, type, f, (aggr->addr + aggr->size), extra_requested)) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTEXTEND, FAIL, "error extending file")
+ else if(ret_value == TRUE) {
+ /* Shift the aggregator block by the extra requested */
+ aggr->addr += extra_requested;
+
+ /* Add extra requested to the aggregator block's total amount allocated */
+ aggr->tot_size += extra_requested;
+ } /* end if */
+ else {
+ /* Check if the aggregator block has enough internal space to satisfy
+ * extending the block.
+ */
+ if(aggr->size >= extra_requested) {
+ /* Extend block into aggregator */
+ aggr->size -= extra_requested;
+ aggr->addr += extra_requested;
+
+ /* Indicate success */
+ HGOTO_DONE(TRUE);
+ } /* end if */
+ } /* end else */
+ } /* end if */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_aggr_try_extend() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_aggr_can_absorb
+ *
+ * Purpose: Check if a section adjoins an aggregator block and one can
+ * absorb the other.
+ *
+ * Return: Success: TRUE(1) - Section or aggregator can be absorbed
+ * FALSE(0) - Section and aggregator can not be absorbed
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, February 1, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5MF_aggr_can_absorb(const H5F_t *f, const H5F_blk_aggr_t *aggr,
+ const H5MF_free_section_t *sect, H5MF_shrink_type_t *shrink)
+{
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOFUNC(H5MF_aggr_can_absorb)
+
+ /* Check args */
+ HDassert(f);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+ HDassert(sect);
+ HDassert(shrink);
+
+ /* Check if this aggregator is active */
+ if(f->shared->feature_flags & aggr->feature_flag) {
+ /* Check if the block adjoins the beginning or end of the aggregator */
+ if(H5F_addr_eq((sect->sect_info.addr + sect->sect_info.size), aggr->addr)
+ || H5F_addr_eq((aggr->addr + aggr->size), sect->sect_info.addr)) {
+#ifdef H5MF_AGGR_DEBUG
+HDfprintf(stderr, "%s: section {%a, %Hu} adjoins aggr = {%a, %Hu}\n", "H5MF_aggr_can_absorb", sect->sect_info.addr, sect->sect_info.size, aggr->addr, aggr->size);
+#endif /* H5MF_AGGR_DBEUG */
+ /* Check if aggregator would get too large and should be absorbed into section */
+ if((aggr->size + sect->sect_info.size) >= aggr->alloc_size)
+ *shrink = H5MF_SHRINK_SECT_ABSORB_AGGR;
+ else
+ *shrink = H5MF_SHRINK_AGGR_ABSORB_SECT;
+
+ /* Indicate success */
+ HGOTO_DONE(TRUE)
+ } /* end if */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_aggr_can_absorb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_aggr_absorb
+ *
+ * Purpose: Absorb a free space section into an aggregator block or
+ * vice versa.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, February 1, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5MF_aggr_absorb(const H5F_t UNUSED *f, H5F_blk_aggr_t *aggr, H5MF_free_section_t *sect,
+ hbool_t allow_sect_absorb)
+{
+ FUNC_ENTER_NOAPI_NOFUNC(H5MF_aggr_absorb)
+
+ /* Check args */
+ HDassert(f);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+ HDassert(f->shared->feature_flags & aggr->feature_flag);
+ HDassert(sect);
+
+ /* Check if aggregator would get too large and should be absorbed into section */
+ if((aggr->size + sect->sect_info.size) >= aggr->alloc_size && allow_sect_absorb) {
+ /* Check if the section adjoins the beginning or end of the aggregator */
+ if(H5F_addr_eq((sect->sect_info.addr + sect->sect_info.size), aggr->addr)) {
+#ifdef H5MF_AGGR_DBEUG
+HDfprintf(stderr, "%s: aggr {%a, %Hu} adjoins front of section = {%a, %Hu}\n", "H5MF_aggr_absorb", aggr->addr, aggr->size, sect->sect_info.addr, sect->sect_info.size);
+#endif /* H5MF_AGGR_DBEUG */
+ /* Absorb aggregator onto end of section */
+ sect->sect_info.size += aggr->size;
+ } /* end if */
+ else {
+ /* Sanity check */
+ HDassert(H5F_addr_eq((aggr->addr + aggr->size), sect->sect_info.addr));
+
+#ifdef H5MF_AGGR_DBEUG
+HDfprintf(stderr, "%s: aggr {%a, %Hu} adjoins end of section = {%a, %Hu}\n", "H5MF_aggr_absorb", aggr->addr, aggr->size, sect->sect_info.addr, sect->sect_info.size);
+#endif /* H5MF_AGGR_DBEUG */
+ /* Absorb aggregator onto beginning of section */
+ sect->sect_info.addr -= aggr->size;
+ sect->sect_info.size += aggr->size;
+ } /* end if */
+
+ /* Reset aggregator */
+ aggr->tot_size = 0;
+ aggr->addr = 0;
+ aggr->size = 0;
+ } /* end if */
+ else {
+ /* Check if the section adjoins the beginning or end of the aggregator */
+ if(H5F_addr_eq((sect->sect_info.addr + sect->sect_info.size), aggr->addr)) {
+#ifdef H5MF_AGGR_DBEUG
+HDfprintf(stderr, "%s: section {%a, %Hu} adjoins front of aggr = {%a, %Hu}\n", "H5MF_aggr_absorb", sect->sect_info.addr, sect->sect_info.size, aggr->addr, aggr->size);
+#endif /* H5MF_AGGR_DBEUG */
+ /* Absorb section onto front of aggregator */
+ aggr->addr -= sect->sect_info.size;
+ aggr->size += sect->sect_info.size;
+
+ /* Sections absorbed onto front of aggregator count against the total
+ * amount of space aggregated together.
+ */
+ aggr->tot_size -= MIN(aggr->tot_size, sect->sect_info.size);
+ } /* end if */
+ else {
+ /* Sanity check */
+ HDassert(H5F_addr_eq((aggr->addr + aggr->size), sect->sect_info.addr));
+
+#ifdef H5MF_AGGR_DBEUG
+HDfprintf(stderr, "%s: section {%a, %Hu} adjoins end of aggr = {%a, %Hu}\n", "H5MF_aggr_absorb", sect->sect_info.addr, sect->sect_info.size, aggr->addr, aggr->size);
+#endif /* H5MF_AGGR_DBEUG */
+ /* Absorb section onto end of aggregator */
+ aggr->size += sect->sect_info.size;
+ } /* end if */
+ /* Sanity check */
+ HDassert(!allow_sect_absorb || (aggr->size < aggr->alloc_size));
+ } /* end else */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5MF_aggr_absorb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_aggr_query
+ *
+ * Purpose: Query a block aggregator's current address & size info
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 13, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5MF_aggr_query(const H5F_t *f, const H5F_blk_aggr_t *aggr, haddr_t *addr,
+ hsize_t *size)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MF_aggr_query)
+
+ /* Check args */
+ HDassert(f);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+
+ /* Check if this aggregator is active */
+ if(f->shared->feature_flags & aggr->feature_flag) {
+ *addr = aggr->addr;
+ *size = aggr->size;
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5MF_aggr_query() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_aggr_reset
+ *
+ * Purpose: Reset a block aggregator, returning any space back to file
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 13, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5MF_aggr_reset(H5F_t *f, hid_t dxpl_id, H5F_blk_aggr_t *aggr)
+{
+ H5FD_mem_t alloc_type; /* Type of file memory to work with */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5MF_aggr_reset)
+
+ /* Check args */
+ HDassert(f);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+
+ /* Set the type of memory in the file */
+ alloc_type = (aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW); /* Type of file memory to work with */
+
+ /* Check if this aggregator is active */
+ if(f->shared->feature_flags & aggr->feature_flag) {
+ haddr_t tmp_addr; /* Temporary holder for aggregator address */
+ hsize_t tmp_size; /* Temporary holder for aggregator size */
+
+ /* Retain aggregator info */
+ tmp_addr = aggr->addr;
+ tmp_size = aggr->size;
+#ifdef H5MF_AGGR_DBEUG
+HDfprintf(stderr, "%s: tmp_addr = %a, tmp_size = %Hu\n", FUNC, tmp_addr, tmp_size);
+#endif /* H5MF_AGGR_DBEUG */
+
+ /* Reset aggregator block information */
+ aggr->tot_size = 0;
+ aggr->addr = 0;
+ aggr->size = 0;
+
+ /* Return the unused portion of the metadata block to the file */
+ if(tmp_size > 0 && (H5F_INTENT(f) & H5F_ACC_RDWR))
+ if(H5MF_xfree(f, alloc_type, dxpl_id, tmp_addr, tmp_size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "can't release aggregator's free space")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_aggr_reset() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_free_aggrs
+ *
+ * Purpose: Reset a metadata & small block aggregators, returning any space
+ * back to file
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Vailin Choi
+ * July 1st, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5MF_free_aggrs(H5F_t *f, hid_t dxpl_id)
+{
+ H5F_blk_aggr_t *first_aggr; /* First aggregator to reset */
+ H5F_blk_aggr_t *second_aggr; /* Second aggregator to reset */
+ haddr_t ma_addr = HADDR_UNDEF; /* Base "metadata aggregator" address */
+ hsize_t ma_size = 0; /* Size of "metadata aggregator" */
+ haddr_t sda_addr = HADDR_UNDEF; /* Base "small data aggregator" address */
+ hsize_t sda_size = 0; /* Size of "small data aggregator" */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5MF_free_aggrs, FAIL)
+
+ /* Check args */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->lf);
+
+ /* Retrieve metadata aggregator info, if available */
+ if(H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query metadata aggregator stats")
+
+ /* Retrieve 'small data' aggregator info, if available */
+ if(H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sda_addr, &sda_size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query small data aggregator stats")
+
+ /* Make certain we release the aggregator that's later in the file first */
+ /* (so the file shrinks properly) */
+ if(H5F_addr_defined(ma_addr) && H5F_addr_defined(sda_addr)) {
+ if(H5F_addr_lt(ma_addr, sda_addr)) {
+ first_aggr = &(f->shared->sdata_aggr);
+ second_aggr = &(f->shared->meta_aggr);
+ } /* end if */
+ else {
+ first_aggr = &(f->shared->meta_aggr);
+ second_aggr = &(f->shared->sdata_aggr);
+ } /* end else */
+ } /* end if */
+ else {
+ first_aggr = &(f->shared->meta_aggr);
+ second_aggr = &(f->shared->sdata_aggr);
+ } /* end else */
+
+ /* Release the unused portion of the metadata and "small data" blocks back
+ * to the free lists in the file.
+ */
+ if(H5MF_aggr_reset(f, dxpl_id, first_aggr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't reset metadata block")
+ if(H5MF_aggr_reset(f, dxpl_id, second_aggr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't reset 'small data' block")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_free_aggrs() */
+
diff --git a/src/H5MFdbg.c b/src/H5MFdbg.c
new file mode 100644
index 0000000..31cff15
--- /dev/null
+++ b/src/H5MFdbg.c
@@ -0,0 +1,306 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5MFdbg.c
+ * Jan 31 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: File memory management debugging functions.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+#define H5MF_PACKAGE /*suppress error about including H5MFpkg */
+#define H5MF_DEBUGGING /* Need access to file space debugging routines */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5MFpkg.h" /* File memory management */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/* User data for free space section iterator callback */
+typedef struct {
+ H5FS_t *fspace; /* Free space manager */
+ FILE *stream; /* Stream for output */
+ int indent; /* Indention amount */
+ int fwidth; /* Field width amount */
+} H5MF_debug_iter_ud_t;
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_sects_debug_cb
+ *
+ * Purpose: Prints debugging info about a free space section for a file
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * January 31 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5MF_sects_debug_cb(const H5FS_section_info_t *_sect, void *_udata)
+{
+ const H5MF_free_section_t *sect = (const H5MF_free_section_t *)_sect; /* Section to dump info */
+ H5MF_debug_iter_ud_t *udata = (H5MF_debug_iter_ud_t *)_udata; /* User data for callbacks */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5MF_sects_debug_cb)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(sect);
+ HDassert(udata);
+
+ /* Print generic section information */
+ HDfprintf(udata->stream, "%*s%-*s %s\n", udata->indent, "", udata->fwidth,
+ "Section type:",
+ (sect->sect_info.type == H5MF_FSPACE_SECT_SIMPLE ? "simple" : "unknown"));
+ HDfprintf(udata->stream, "%*s%-*s %a\n", udata->indent, "", udata->fwidth,
+ "Section address:",
+ sect->sect_info.addr);
+ HDfprintf(udata->stream, "%*s%-*s %Hu\n", udata->indent, "", udata->fwidth,
+ "Section size:",
+ sect->sect_info.size);
+ HDfprintf(udata->stream, "%*s%-*s %Hu\n", udata->indent, "", udata->fwidth,
+ "End of section:",
+ (haddr_t)((sect->sect_info.addr + sect->sect_info.size) - 1));
+ HDfprintf(udata->stream, "%*s%-*s %s\n", udata->indent, "", udata->fwidth,
+ "Section state:",
+ (sect->sect_info.state == H5FS_SECT_LIVE ? "live" : "serialized"));
+
+ /* Dump section-specific debugging information */
+ if(H5FS_sect_debug(udata->fspace, _sect, udata->stream, udata->indent + 3, MAX(0, udata->fwidth - 3)) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_BADITER, FAIL, "can't dump section's debugging info")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_sects_debug_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_sects_debug
+ *
+ * Purpose: Iterate over free space sections for a file
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * January 31 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5MF_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr, FILE *stream, int indent, int fwidth)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ H5FD_mem_t type; /* Memory type for iteration */
+
+ FUNC_ENTER_NOAPI(H5MF_sects_debug, FAIL)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+
+ for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type))
+ if(H5F_addr_eq(f->shared->fs_addr[type], fs_addr)) {
+ if(!f->shared->fs_man[type])
+ if(H5MF_alloc_open(f, dxpl_id, type) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space")
+
+ if(f->shared->fs_man[type]) {
+ H5MF_debug_iter_ud_t udata; /* User data for callbacks */
+
+ /* Prepare user data for section iteration callback */
+ udata.fspace = f->shared->fs_man[type];
+ udata.stream = stream;
+ udata.indent = indent;
+ udata.fwidth = fwidth;
+
+ /* Iterate over all the free space sections */
+ if(H5FS_sect_iterate(f, dxpl_id, f->shared->fs_man[type], H5MF_sects_debug_cb, &udata) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_BADITER, FAIL, "can't iterate over heap's free space")
+
+ /* Close the free space information */
+ if(H5FS_close(f, dxpl_id, f->shared->fs_man[type]) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't release free space info")
+ } /* end if */
+ break;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5MF_sects_debug() */
+
+#ifdef H5MF_ALLOC_DEBUG_DUMP
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_sects_dump
+ *
+ * Purpose: Prints debugging info about free space sections for a file.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jan 31 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5MF_sects_dump(H5F_t *f, hid_t dxpl_id, FILE *stream)
+{
+ haddr_t eoa; /* End of allocated space in the file */
+ haddr_t ma_addr = HADDR_UNDEF; /* Base "metadata aggregator" address */
+ hsize_t ma_size = 0; /* Size of "metadata aggregator" */
+ haddr_t sda_addr = HADDR_UNDEF; /* Base "small data aggregator" address */
+ hsize_t sda_size = 0; /* Size of "small data aggregator" */
+ H5FD_mem_t type; /* Memory type for iteration */
+ int indent = 0; /* Amount to indent */
+ int fwidth = 50; /* Field width */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5MF_sects_dump, FAIL)
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Dumping file free space sections\n", FUNC);
+#endif /* H5MF_ALLOC_DEBUG */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(stream);
+
+ /* Retrieve the 'eoa' for the file */
+ if(HADDR_UNDEF == (eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_DEFAULT)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "driver get_eoa request failed")
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: for type = H5FD_MEM_DEFAULT, eoa = %a\n", FUNC, eoa);
+#endif /* H5MF_ALLOC_DEBUG */
+
+ /* Retrieve metadata aggregator info, if available */
+ H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: ma_addr = %a, ma_size = %Hu, end of ma = %a\n", FUNC, ma_addr, ma_size, (haddr_t)((ma_addr + ma_size) - 1));
+#endif /* H5MF_ALLOC_DEBUG */
+
+ /* Retrieve 'small data' aggregator info, if available */
+ H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sda_addr, &sda_size);
+#ifdef H5MF_ALLOC_DEBUG
+HDfprintf(stderr, "%s: sda_addr = %a, sda_size = %Hu, end of sda = %a\n", FUNC, sda_addr, sda_size, (haddr_t)((sda_addr + sda_size) - 1));
+#endif /* H5MF_ALLOC_DEBUG */
+
+ /* Iterate over all the free space types that have managers and dump each free list's space */
+ for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) {
+ /* Print header for type */
+ HDfprintf(stream, "%*sFile Free Space Info for type = %u:\n", indent, "", (unsigned)type);
+
+ /* Check for this type being mapped to another type */
+ if(H5FD_MEM_DEFAULT == f->shared->fs_type_map[type] ||
+ type == f->shared->fs_type_map[type]) {
+ /* Retrieve the 'eoa' for this file memory type */
+ if(HADDR_UNDEF == (eoa = H5FD_get_eoa(f->shared->lf, type)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "driver get_eoa request failed")
+ HDfprintf(stream, "%*s%-*s %a\n", indent + 3, "", MAX(0, fwidth - 3),
+ "eoa:",
+ eoa);
+
+ /* Print header for sections */
+ HDfprintf(stream, "%*sSections:\n", indent + 3, "");
+
+ /* If there is a free space manager for this type, iterate over them */
+ if(f->shared->fs_man[type]) {
+ H5MF_debug_iter_ud_t udata; /* User data for callbacks */
+
+ /* Prepare user data for section iteration callback */
+ udata.fspace = f->shared->fs_man[type];
+ udata.stream = stream;
+ udata.indent = indent + 6;
+ udata.fwidth = MAX(0, fwidth - 6);
+
+ /* Iterate over all the free space sections */
+ if(H5FS_sect_iterate(f, dxpl_id, f->shared->fs_man[type], H5MF_sects_debug_cb, &udata) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_BADITER, FAIL, "can't iterate over heap's free space")
+ } /* end if */
+ else {
+ /* No sections of this type */
+ HDfprintf(stream, "%*s<none>\n", indent + 6, "");
+ } /* end else */
+ } /* end if */
+ else {
+ HDfprintf(stream, "%*sMapped to type = %u\n", indent, "", (unsigned)f->shared->fs_type_map[type]);
+ } /* end else */
+ } /* end for */
+
+done:
+HDfprintf(stderr, "%s: Done dumping file free space sections\n", FUNC);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_sects_dump() */
+#endif /* H5MF_ALLOC_DEBUG_DUMP */
+
diff --git a/src/H5MFpkg.h b/src/H5MFpkg.h
new file mode 100644
index 0000000..25785ae
--- /dev/null
+++ b/src/H5MFpkg.h
@@ -0,0 +1,175 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Quincey Koziol <koziol@hdfgroup.org>
+ * Tuesday, January 8, 2008
+ *
+ * Purpose: This file contains declarations which are visible only within
+ * the H5MF package. Source files outside the H5MF package should
+ * include H5MFprivate.h instead.
+ */
+#ifndef H5MF_PACKAGE
+#error "Do not include this file outside the H5MF package!"
+#endif
+
+#ifndef _H5MFpkg_H
+#define _H5MFpkg_H
+
+/* Get package's private header */
+#include "H5MFprivate.h"
+
+/* Other private headers needed by this file */
+#include "H5FSprivate.h" /* File free space */
+
+
+/**************************/
+/* Package Private Macros */
+/**************************/
+
+/* Define this to display information about file allocations */
+/* #define H5MF_ALLOC_DEBUG */
+
+/* Define this to display more information about file allocations */
+/* #define H5MF_ALLOC_DEBUG_MORE */
+
+/* Define this to display more information about block aggregator actions */
+/* #define H5MF_AGGR_DEBUG */
+
+/* Define this to dump free space tracker contents after they've been modified */
+/* #define H5MF_ALLOC_DEBUG_DUMP */
+
+/* Free space section types for file */
+/* (values stored in free space data structures in file) */
+#define H5MF_FSPACE_SECT_SIMPLE 0 /* Section is a range of actual bytes in file */
+
+
+/****************************/
+/* Package Private Typedefs */
+/****************************/
+
+/* File free space section info */
+typedef struct H5MF_free_section_t {
+ H5FS_section_info_t sect_info; /* Free space section information (must be first in struct) */
+#ifdef NOT_YET
+ union {
+ struct {
+ H5HF_indirect_t *parent; /* Indirect block parent for free section's direct block */
+ unsigned par_entry; /* Entry of free section's direct block in parent indirect block */
+ } single;
+ struct {
+ struct H5HF_free_section_t *under; /* Pointer to indirect block underlying row section */
+ unsigned row; /* Row for range of blocks */
+ unsigned col; /* Column for range of blocks */
+ unsigned num_entries; /* Number of entries covered */
+
+ /* Fields that aren't stored */
+ hbool_t checked_out; /* Flag to indicate that a row section is temporarily out of the free space manager */
+ } row;
+ struct {
+ /* Holds either a pointer to an indirect block (if its "live") or
+ * the block offset of it's indirect block (if its "serialized")
+ * (This allows the indirect block that the section is within to
+ * be compared with other sections, whether it's serialized
+ * or not)
+ */
+ union {
+ H5HF_indirect_t *iblock; /* Indirect block for free section */
+ hsize_t iblock_off; /* Indirect block offset in "heap space" */
+ } u;
+ unsigned row; /* Row for range of blocks */
+ unsigned col; /* Column for range of blocks */
+ unsigned num_entries; /* Number of entries covered */
+
+ /* Fields that aren't stored */
+ struct H5HF_free_section_t *parent; /* Pointer to "parent" indirect section */
+ unsigned par_entry; /* Entry within parent indirect section */
+ hsize_t span_size; /* Size of space tracked, in "heap space" */
+ unsigned iblock_entries; /* Number of entries in indirect block where section is located */
+ unsigned rc; /* Reference count of outstanding row & child indirect sections */
+ unsigned dir_nrows; /* Number of direct rows in section */
+ struct H5HF_free_section_t **dir_rows; /* Array of pointers to outstanding row sections */
+ unsigned indir_nents; /* Number of indirect entries in section */
+ struct H5HF_free_section_t **indir_ents; /* Array of pointers to outstanding child indirect sections */
+ } indirect;
+ } u;
+#endif /* NOT_YET */
+} H5MF_free_section_t;
+
+/* Type of "container shrink" operation to perform */
+typedef enum {
+ H5MF_SHRINK_EOA, /* Section should shrink the EOA value */
+ H5MF_SHRINK_AGGR_ABSORB_SECT, /* Section should merge into the aggregator block */
+ H5MF_SHRINK_SECT_ABSORB_AGGR /* Aggregator block should merge into the section */
+} H5MF_shrink_type_t;
+
+/* User data for free space manager section callbacks */
+typedef struct H5MF_sect_ud_t {
+ /* Down */
+ H5F_t *f; /* Pointer to file to operate on */
+ hid_t dxpl_id; /* DXPL for VFD operations */
+ H5FD_mem_t alloc_type; /* Type of memory being allocated */
+ hbool_t allow_sect_absorb; /* Whether sections are allowed to absorb a block aggregator */
+
+ /* Up */
+ H5MF_shrink_type_t shrink; /* Type of shrink operation to perform */
+ H5F_blk_aggr_t *aggr; /* Aggregator block to operate on */
+} H5MF_sect_ud_t;
+
+
+/*****************************/
+/* Package Private Variables */
+/*****************************/
+
+/* H5MF single section inherits serializable properties from H5FS_section_class_t */
+H5_DLLVAR H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SIMPLE[1];
+
+
+/******************************/
+/* Package Private Prototypes */
+/******************************/
+
+/* Allocator routines */
+H5_DLL herr_t H5MF_alloc_open(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type);
+H5_DLL herr_t H5MF_alloc_start(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type);
+H5_DLL herr_t H5MF_sects_dump(H5F_t *f, hid_t dxpl_id, FILE *stream);
+
+/* 'simple' section routines */
+H5_DLL H5MF_free_section_t *H5MF_sect_simple_new(haddr_t sect_off,
+ hsize_t sect_size);
+H5_DLL htri_t H5MF_sect_simple_can_shrink(const H5FS_section_info_t *_sect,
+ void *udata);
+H5_DLL herr_t H5MF_sect_simple_shrink(H5FS_section_info_t **_sect,
+ void *udata);
+H5_DLL herr_t H5MF_sect_simple_free(H5FS_section_info_t *sect);
+
+/* Block aggregator routines */
+H5_DLL haddr_t H5MF_aggr_alloc(H5F_t *f, hid_t dxpl_id, H5F_blk_aggr_t *aggr,
+ H5F_blk_aggr_t *other_aggr, H5FD_mem_t type, hsize_t size);
+H5_DLL htri_t H5MF_aggr_try_extend(H5F_t *f, H5F_blk_aggr_t *aggr,
+ H5FD_mem_t type, haddr_t abs_blk_end, hsize_t extra_requested);
+H5_DLL htri_t H5MF_aggr_can_absorb(const H5F_t *f, const H5F_blk_aggr_t *aggr,
+ const H5MF_free_section_t *sect, H5MF_shrink_type_t *shrink);
+H5_DLL herr_t H5MF_aggr_absorb(const H5F_t *f, H5F_blk_aggr_t *aggr,
+ H5MF_free_section_t *sect, hbool_t allow_sect_absorb);
+H5_DLL herr_t H5MF_aggr_query(const H5F_t *f, const H5F_blk_aggr_t *aggr,
+ haddr_t *addr, hsize_t *size);
+
+/* Testing routines */
+#ifdef H5MF_TESTING
+#endif /* H5MF_TESTING */
+
+#endif /* _H5MFpkg_H */
+
diff --git a/src/H5MFprivate.h b/src/H5MFprivate.h
index e01a9f6..b471aa3 100644
--- a/src/H5MFprivate.h
+++ b/src/H5MFprivate.h
@@ -32,6 +32,10 @@
#include "H5Fprivate.h" /* File access */
#include "H5FDprivate.h" /* File Drivers */
+/**************************/
+/* Library Private Macros */
+/**************************/
+
/*
* Feature: Define H5MF_DEBUG on the compiler command line if you want to
* see diagnostics from this layer.
@@ -40,18 +44,49 @@
# undef H5MF_DEBUG
#endif
-/*
- * Library prototypes...
- */
-H5_DLL haddr_t H5MF_alloc(const H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
-H5_DLL herr_t H5MF_xfree(const H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr,
+/****************************/
+/* Library Private Typedefs */
+/****************************/
+
+
+/*****************************/
+/* Library-private Variables */
+/*****************************/
+
+
+/***************************************/
+/* Library-private Function Prototypes */
+/***************************************/
+
+/* File space manager routines */
+H5_DLL herr_t H5MF_init_merge_flags(H5F_t *f);
+H5_DLL herr_t H5MF_get_freespace(H5F_t *f, hid_t dxpl_id, hsize_t *tot_space,
+ hsize_t *meta_size);
+H5_DLL herr_t H5MF_close(H5F_t *f, hid_t dxpl_id);
+
+/* File space allocation routines */
+H5_DLL haddr_t H5MF_alloc(H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
+H5_DLL haddr_t H5MF_aggr_vfd_alloc(H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
+H5_DLL herr_t H5MF_xfree(H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr,
hsize_t size);
-H5_DLL haddr_t H5MF_realloc(H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr,
- hsize_t old_size, hsize_t new_size);
-H5_DLL htri_t H5MF_can_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr,
- hsize_t size, hsize_t extra_requested);
-H5_DLL herr_t H5MF_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size,
- hsize_t extra_requested);
+H5_DLL herr_t H5MF_try_extend(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type,
+ haddr_t addr, hsize_t size, hsize_t extra_requested);
+H5_DLL htri_t H5MF_try_shrink(H5F_t *f, H5FD_mem_t alloc_type, hid_t dxpl_id,
+ haddr_t addr, hsize_t size);
+H5_DLL ssize_t H5MF_get_free_sections(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type,
+ size_t nsects, H5F_sect_info_t *sect_info);
+
+/* File 'temporary' space allocation routines */
+H5_DLL haddr_t H5MF_alloc_tmp(H5F_t *f, hsize_t size);
+
+/* 'block aggregator' routines */
+H5_DLL herr_t H5MF_free_aggrs(H5F_t *f, hid_t dxpl_id);
+
+/* Debugging routines */
+#ifdef H5MF_DEBUGGING
+H5_DLL herr_t H5MF_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ FILE *stream, int indent, int fwidth);
+#endif /* H5MF_DEBUGGING */
#endif /* end _H5MFprivate_H */
diff --git a/src/H5MFsection.c b/src/H5MFsection.c
new file mode 100644
index 0000000..d10b6b1
--- /dev/null
+++ b/src/H5MFsection.c
@@ -0,0 +1,533 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Quincey Koziol <koziol@hdfgroup.org>
+ * Tuesday, January 8, 2008
+ *
+ * Purpose: Free space section callbacks for file.
+ *
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+#define H5MF_PACKAGE /*suppress error about including H5MFpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5MFpkg.h" /* File memory management */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* 'simple' section callbacks */
+static H5FS_section_info_t *H5MF_sect_simple_deserialize(const H5FS_section_class_t *cls,
+ hid_t dxpl_id, const uint8_t *buf, haddr_t sect_addr, hsize_t sect_size,
+ unsigned *des_flags);
+static htri_t H5MF_sect_simple_can_merge(const H5FS_section_info_t *sect1,
+ const H5FS_section_info_t *sect2, void *udata);
+static herr_t H5MF_sect_simple_merge(H5FS_section_info_t *sect1,
+ H5FS_section_info_t *sect2, void *udata);
+static herr_t H5MF_sect_simple_valid(const H5FS_section_class_t *cls,
+ const H5FS_section_info_t *sect);
+static H5FS_section_info_t *H5MF_sect_simple_split(H5FS_section_info_t *sect,
+ hsize_t frag_size);
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Class info for "simple" free space sections */
+H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SIMPLE[1] = {{
+ /* Class variables */
+ H5MF_FSPACE_SECT_SIMPLE, /* Section type */
+ 0, /* Extra serialized size */
+ H5FS_CLS_MERGE_SYM | H5FS_CLS_ADJUST_OK, /* Class flags */
+ NULL, /* Class private info */
+
+ /* Class methods */
+ NULL, /* Initialize section class */
+ NULL, /* Terminate section class */
+
+ /* Object methods */
+ NULL, /* Add section */
+ NULL, /* Serialize section */
+ H5MF_sect_simple_deserialize, /* Deserialize section */
+ H5MF_sect_simple_can_merge, /* Can sections merge? */
+ H5MF_sect_simple_merge, /* Merge sections */
+ H5MF_sect_simple_can_shrink, /* Can section shrink container?*/
+ H5MF_sect_simple_shrink, /* Shrink container w/section */
+ H5MF_sect_simple_free, /* Free section */
+ H5MF_sect_simple_valid, /* Check validity of section */
+ H5MF_sect_simple_split, /* Split section node for alignment */
+ NULL, /* Dump debugging for section */
+}};
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5MF_free_section_t struct */
+H5FL_DEFINE(H5MF_free_section_t);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_sect_simple_new
+ *
+ * Purpose: Create a new 'simple' section and return it to the caller
+ *
+ * Return: Pointer to new section on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * January 8 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+H5MF_free_section_t *
+H5MF_sect_simple_new(haddr_t sect_off, hsize_t sect_size)
+{
+ H5MF_free_section_t *sect = NULL; /* 'Simple' free space section to add */
+ H5MF_free_section_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5MF_sect_simple_new)
+
+ /* Check arguments. */
+ HDassert(sect_size);
+
+ /* Create free space section node */
+ if(NULL == (sect = H5FL_MALLOC(H5MF_free_section_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for direct block free list section")
+
+ /* Set the information passed in */
+ sect->sect_info.addr = sect_off;
+ sect->sect_info.size = sect_size;
+
+ /* Set the section's class & state */
+ sect->sect_info.type = H5MF_FSPACE_SECT_SIMPLE;
+ sect->sect_info.state = H5FS_SECT_LIVE;
+
+ /* Set return value */
+ ret_value = sect;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_sect_simple_new() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_sect_simple_deserialize
+ *
+ * Purpose: Deserialize a buffer into a "live" single section
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, January 8, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5FS_section_info_t *
+H5MF_sect_simple_deserialize(const H5FS_section_class_t UNUSED *cls,
+ hid_t UNUSED dxpl_id, const uint8_t UNUSED *buf, haddr_t sect_addr,
+ hsize_t sect_size, unsigned UNUSED *des_flags)
+{
+ H5MF_free_section_t *sect; /* New section */
+ H5FS_section_info_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5MF_sect_simple_deserialize)
+
+ /* Check arguments. */
+ HDassert(H5F_addr_defined(sect_addr));
+ HDassert(sect_size);
+
+ /* Create free space section for block */
+ if(NULL == (sect = H5MF_sect_simple_new(sect_addr, sect_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't initialize free space section")
+
+ /* Set return value */
+ ret_value = (H5FS_section_info_t *)sect;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5MF_sect_simple_deserialize() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_sect_simple_can_merge
+ *
+ * Purpose: Can two sections of this type merge?
+ *
+ * Note: Second section must be "after" first section
+ *
+ * Return: Success: non-negative (TRUE/FALSE)
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, January 8, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5MF_sect_simple_can_merge(const H5FS_section_info_t *_sect1,
+ const H5FS_section_info_t *_sect2, void UNUSED *_udata)
+{
+ const H5MF_free_section_t *sect1 = (const H5MF_free_section_t *)_sect1; /* File free section */
+ const H5MF_free_section_t *sect2 = (const H5MF_free_section_t *)_sect2; /* File free section */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MF_sect_simple_can_merge)
+
+ /* Check arguments. */
+ HDassert(sect1);
+ HDassert(sect2);
+ HDassert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */
+ HDassert(H5F_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr));
+
+ /* Check if second section adjoins first section */
+ ret_value = H5F_addr_eq(sect1->sect_info.addr + sect1->sect_info.size, sect2->sect_info.addr);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5MF_sect_simple_can_merge() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_sect_simple_merge
+ *
+ * Purpose: Merge two sections of this type
+ *
+ * Note: Second section always merges into first node
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, January 8, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5MF_sect_simple_merge(H5FS_section_info_t *_sect1, H5FS_section_info_t *_sect2,
+ void UNUSED *_udata)
+{
+ H5MF_free_section_t *sect1 = (H5MF_free_section_t *)_sect1; /* File free section */
+ H5MF_free_section_t *sect2 = (H5MF_free_section_t *)_sect2; /* File free section */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5MF_sect_simple_merge)
+
+ /* Check arguments. */
+ HDassert(sect1);
+ HDassert(sect1->sect_info.type == H5MF_FSPACE_SECT_SIMPLE);
+ HDassert(sect2);
+ HDassert(sect2->sect_info.type == H5MF_FSPACE_SECT_SIMPLE);
+ HDassert(H5F_addr_eq(sect1->sect_info.addr + sect1->sect_info.size, sect2->sect_info.addr));
+
+ /* Add second section's size to first section */
+ sect1->sect_info.size += sect2->sect_info.size;
+
+ /* Get rid of second section */
+ if(H5MF_sect_simple_free((H5FS_section_info_t *)sect2) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free section node")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5MF_sect_simple_merge() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_sect_simple_can_shrink
+ *
+ * Purpose: Can this section shrink the container?
+ *
+ * Return: Success: non-negative (TRUE/FALSE)
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, January 8, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5MF_sect_simple_can_shrink(const H5FS_section_info_t *_sect, void *_udata)
+{
+ const H5MF_free_section_t *sect = (const H5MF_free_section_t *)_sect; /* File free section */
+ H5MF_sect_ud_t *udata = (H5MF_sect_ud_t *)_udata; /* User data for callback */
+ haddr_t eoa; /* End of address space in the file */
+ haddr_t end; /* End of section to extend */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5MF_sect_simple_can_shrink)
+
+ /* Check arguments. */
+ HDassert(sect);
+ HDassert(udata);
+ HDassert(udata->f);
+
+ /* Retrieve the end of the file's address space */
+ if(HADDR_UNDEF == (eoa = H5FD_get_eoa(udata->f->shared->lf, udata->alloc_type)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "driver get_eoa request failed")
+
+ /* Compute address of end of section to check */
+ end = sect->sect_info.addr + sect->sect_info.size;
+
+ /* Check if the section is exactly at the end of the allocated space in the file */
+ if(H5F_addr_eq(end, eoa)) {
+ /* Set the shrinking type */
+ udata->shrink = H5MF_SHRINK_EOA;
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: section {%a, %Hu}, shrinks file, eoa = %a\n", FUNC, sect->sect_info.addr, sect->sect_info.size, eoa);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+
+ /* Indicate shrinking can occur */
+ HGOTO_DONE(TRUE)
+ } /* end if */
+ else {
+ /* Check if this section is allowed to merge with metadata aggregation block */
+ if(udata->f->shared->fs_aggr_merge[udata->alloc_type] & H5F_FS_MERGE_METADATA) {
+ htri_t status; /* Status from aggregator adjoin */
+
+ /* See if section can absorb the aggregator & vice versa */
+ if((status = H5MF_aggr_can_absorb(udata->f, &(udata->f->shared->meta_aggr), sect, &(udata->shrink))) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTMERGE, FAIL, "error merging section with aggregation block")
+ else if(status > 0) {
+ /* Set the aggregator to operate on */
+ udata->aggr = &(udata->f->shared->meta_aggr);
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: section {%a, %Hu}, adjoins metadata aggregator\n", FUNC, sect->sect_info.addr, sect->sect_info.size);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+
+ /* Indicate shrinking can occur */
+ HGOTO_DONE(TRUE)
+ } /* end if */
+ } /* end if */
+
+ /* Check if this section is allowed to merge with small 'raw' aggregation block */
+ if(udata->f->shared->fs_aggr_merge[udata->alloc_type] & H5F_FS_MERGE_RAWDATA) {
+ htri_t status; /* Status from aggregator adjoin */
+
+ /* See if section can absorb the aggregator & vice versa */
+ if((status = H5MF_aggr_can_absorb(udata->f, &(udata->f->shared->sdata_aggr), sect, &(udata->shrink))) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTMERGE, FAIL, "error merging section with aggregation block")
+ else if(status > 0) {
+ /* Set the aggregator to operate on */
+ udata->aggr = &(udata->f->shared->sdata_aggr);
+#ifdef H5MF_ALLOC_DEBUG_MORE
+HDfprintf(stderr, "%s: section {%a, %Hu}, adjoins small data aggregator\n", FUNC, sect->sect_info.addr, sect->sect_info.size);
+#endif /* H5MF_ALLOC_DEBUG_MORE */
+
+ /* Indicate shrinking can occur */
+ HGOTO_DONE(TRUE)
+ } /* end if */
+ } /* end if */
+ } /* end else */
+
+ /* Set return value */
+ ret_value = FALSE;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5MF_sect_simple_can_shrink() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_sect_simple_shrink
+ *
+ * Purpose: Shrink container with section
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, January 8, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5MF_sect_simple_shrink(H5FS_section_info_t **_sect, void *_udata)
+{
+ H5MF_free_section_t **sect = (H5MF_free_section_t **)_sect; /* File free section */
+ H5MF_sect_ud_t *udata = (H5MF_sect_ud_t *)_udata; /* User data for callback */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5MF_sect_simple_shrink)
+
+ /* Check arguments. */
+ HDassert(sect);
+ HDassert(udata);
+ HDassert(udata->f);
+
+ /* Check for shrinking file */
+ if(H5MF_SHRINK_EOA == udata->shrink) {
+ /* Sanity check */
+ HDassert(H5F_INTENT(udata->f) & H5F_ACC_RDWR);
+
+ /* Release section's space at EOA with file driver */
+ if(H5FD_free(udata->f->shared->lf, udata->dxpl_id, udata->alloc_type, udata->f, (*sect)->sect_info.addr, (*sect)->sect_info.size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "driver free request failed")
+ } /* end if */
+ else {
+ /* Sanity check */
+ HDassert(udata->aggr);
+
+ /* Absorb the section into the aggregator or vice versa */
+ if(H5MF_aggr_absorb(udata->f, udata->aggr, *sect, udata->allow_sect_absorb) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTMERGE, FAIL, "can't absorb section into aggregator or vice versa")
+ } /* end else */
+
+ /* Check for freeing section */
+ if(udata->shrink != H5MF_SHRINK_SECT_ABSORB_AGGR) {
+ /* Free section */
+ if(H5MF_sect_simple_free((H5FS_section_info_t *)*sect) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free simple section node")
+
+ /* Mark section as freed, for free space manager */
+ *sect = NULL;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5MF_sect_simple_shrink() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_sect_simple_free
+ *
+ * Purpose: Free a 'single' section node
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, January 8, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5MF_sect_simple_free(H5FS_section_info_t *_sect)
+{
+ H5MF_free_section_t *sect = (H5MF_free_section_t *)_sect; /* File free section */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MF_sect_simple_free)
+
+ /* Check arguments. */
+ HDassert(sect);
+
+ /* Release the section */
+ (void)H5FL_FREE(H5MF_free_section_t, sect);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5MF_sect_simple_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_sect_simple_valid
+ *
+ * Purpose: Check the validity of a section
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, January 8, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5MF_sect_simple_valid(const H5FS_section_class_t UNUSED *cls,
+ const H5FS_section_info_t
+#ifdef NDEBUG
+ UNUSED
+#endif /* NDEBUG */
+ *_sect)
+{
+#ifndef NDEBUG
+ const H5MF_free_section_t *sect = (const H5MF_free_section_t *)_sect; /* File free section */
+#endif /* NDEBUG */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MF_sect_simple_valid)
+
+ /* Check arguments. */
+ HDassert(sect);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5MF_sect_simple_valid() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_sect_simple_split
+ *
+ * Purpose: Split SECT into 2 sections: fragment for alignment & the aligned section
+ * SECT's addr and size are updated to point to the aligned section
+ *
+ * Return: Success: the fragment for aligning sect
+ * Failure: null
+ *
+ * Programmer: Vailin Choi, July 29, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5FS_section_info_t *
+H5MF_sect_simple_split(H5FS_section_info_t *sect, hsize_t frag_size)
+{
+ H5MF_free_section_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5MF_sect_simple_split)
+
+ /* Allocate space for new section */
+ if(NULL == (ret_value = H5MF_sect_simple_new(sect->addr, frag_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't initialize free space section")
+
+ /* Set new section's info */
+ sect->addr += frag_size;
+ sect->size -= frag_size;
+
+done:
+ FUNC_LEAVE_NOAPI((H5FS_section_info_t *)ret_value)
+} /* end H5MF_sect_simple_split() */
+
diff --git a/src/H5MM.c b/src/H5MM.c
index cd246e5..14e847b 100644
--- a/src/H5MM.c
+++ b/src/H5MM.c
@@ -177,7 +177,7 @@ H5MM_xstrdup(const char *s)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MM_xstrdup)
if(s) {
- ret_value = H5MM_malloc(HDstrlen(s) + 1);
+ ret_value = (char *)H5MM_malloc(HDstrlen(s) + 1);
HDassert(ret_value);
HDstrcpy(ret_value, s);
} /* end if */
@@ -210,17 +210,17 @@ H5MM_strdup(const char *s)
{
char *ret_value;
- FUNC_ENTER_NOAPI(H5MM_strdup, NULL);
+ FUNC_ENTER_NOAPI(H5MM_strdup, NULL)
- if (!s)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, NULL, "null string");
- if (NULL==(ret_value = H5MM_malloc(HDstrlen(s) + 1)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ if(!s)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "null string")
+ if(NULL == (ret_value = (char *)H5MM_malloc(HDstrlen(s) + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
HDstrcpy(ret_value, s);
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MM_strdup() */
/*-------------------------------------------------------------------------
diff --git a/src/H5MP.c b/src/H5MP.c
index e7be06f..63a65ae 100644
--- a/src/H5MP.c
+++ b/src/H5MP.c
@@ -147,14 +147,14 @@ H5MP_new_page(H5MP_pool_t *mp, size_t page_size)
/* Allocate page */
if(page_size > mp->page_size) {
- if(NULL == (new_page = H5MM_malloc(page_size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for page")
+ if(NULL == (new_page = (H5MP_page_t *)H5MM_malloc(page_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for page")
new_page->free_size = page_size - H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t));
new_page->fac_alloc = FALSE;
} /* end if */
else {
- if((new_page = H5FL_FAC_MALLOC(mp->page_fac)) == NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for page")
+ if(NULL == (new_page = (H5MP_page_t *)H5FL_FAC_MALLOC(mp->page_fac)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for page")
new_page->free_size = mp->max_size;
new_page->fac_alloc = TRUE;
} /* end else */
@@ -461,7 +461,7 @@ H5MP_close (H5MP_pool_t *mp)
HGOTO_ERROR (H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy page factory")
/* Free the memory pool itself */
- H5FL_FREE(H5MP_pool_t, mp);
+ (void)H5FL_FREE(H5MP_pool_t, mp);
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5O.c b/src/H5O.c
index 6a9b81e..6f743a4 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -84,6 +84,7 @@ static herr_t H5O_obj_type_real(H5O_t *oh, H5O_type_t *obj_type);
static herr_t H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id,
hid_t dxpl_id);
+static herr_t H5O_get_hdr_info_real(const H5O_t *oh, H5O_hdr_info_t *hdr);
/*********************/
@@ -124,21 +125,10 @@ const H5O_msg_class_t *const H5O_msg_class_g[] = {
H5O_MSG_DRVINFO, /*0x0014 Driver info settings */
H5O_MSG_AINFO, /*0x0015 Attribute information */
H5O_MSG_REFCOUNT, /*0x0016 Object's ref. count */
+ H5O_MSG_FSINFO, /*0x0018 Free-space manager info message */
H5O_MSG_UNKNOWN, /*0x0017 Placeholder for unknown message */
};
-/* Header object ID to class mapping */
-/*
- * Initialize the object class info table. Begin with the most general types
- * and end with the most specific. For instance, any object that has a
- * datatype message is a datatype but only some of them are datasets.
- */
-const H5O_obj_class_t *const H5O_obj_class_g[] = {
- H5O_OBJ_DATATYPE, /* Datatype object (H5O_TYPE_NAMED_DATATYPE - 2) */
- H5O_OBJ_DATASET, /* Dataset object (H5O_TYPE_DATASET - 1) */
- H5O_OBJ_GROUP, /* Group object (H5O_TYPE_GROUP - 0) */
-};
-
/* Declare a free list to manage the H5O_t struct */
H5FL_DEFINE(H5O_t);
@@ -167,6 +157,18 @@ H5FL_EXTERN(H5_obj_t);
/* Local Variables */
/*******************/
+/* Header object ID to class mapping */
+/*
+ * Initialize the object class info table. Begin with the most general types
+ * and end with the most specific. For instance, any object that has a
+ * datatype message is a datatype but only some of them are datasets.
+ */
+static const H5O_obj_class_t *const H5O_obj_class_g[] = {
+ H5O_OBJ_DATATYPE, /* Datatype object (H5O_TYPE_NAMED_DATATYPE - 2) */
+ H5O_OBJ_DATASET, /* Dataset object (H5O_TYPE_DATASET - 1) */
+ H5O_OBJ_GROUP, /* Group object (H5O_TYPE_GROUP - 0) */
+};
+
/*-------------------------------------------------------------------------
@@ -238,7 +240,7 @@ H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
/* Open the object */
- if((ret_value = H5O_open_name(&loc, name, lapl_id)) < 0)
+ if((ret_value = H5O_open_name(&loc, name, lapl_id, TRUE)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object")
done:
@@ -309,7 +311,7 @@ H5Oopen_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type,
loc_found = TRUE;
/* Open the object */
- if((ret_value = H5O_open_by_loc(&obj_loc, H5AC_dxpl_id)) < 0)
+ if((ret_value = H5O_open_by_loc(&obj_loc, lapl_id, H5AC_dxpl_id, TRUE)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object")
done:
@@ -342,7 +344,7 @@ done:
* H5Odecr_refcount() should be used when the object is
* no longer being referenced by address (e.g. when the UD link
* is deleted).
- *
+ *
* The address of the HDF5 file on disk has no effect on
* H5Oopen_by_addr(), nor does the use of any unusual file
* drivers. The "address" is really the offset within the
@@ -365,6 +367,7 @@ H5Oopen_by_addr(hid_t loc_id, haddr_t addr)
H5G_name_t obj_path; /* Opened object group hier. path */
H5O_loc_t obj_oloc; /* Opened object object location */
hbool_t loc_found = FALSE; /* Location at 'name' found */
+ hid_t lapl_id = H5P_LINK_ACCESS_DEFAULT; /* lapl to use to open this object */
hid_t ret_value = FAIL;
FUNC_ENTER_API(H5Oopen_by_addr, FAIL)
@@ -385,7 +388,7 @@ H5Oopen_by_addr(hid_t loc_id, haddr_t addr)
H5G_name_reset(obj_loc.path); /* objects opened through this routine don't have a path name */
/* Open the object */
- if((ret_value = H5O_open_by_loc(&obj_loc, H5AC_dxpl_id)) < 0)
+ if((ret_value = H5O_open_by_loc(&obj_loc, lapl_id, H5AC_dxpl_id, TRUE)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object")
done:
@@ -438,8 +441,11 @@ H5Olink(hid_t obj_id, hid_t new_loc_id, const char *new_name, hid_t lcpl_id,
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!new_name || !*new_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
+/* Avoid compiler warning on 32-bit machines */
+#if H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T
if(HDstrlen(new_name) > H5L_MAX_LINK_NAME_LEN)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "name too long")
+#endif /* H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T */
if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list")
@@ -1012,7 +1018,7 @@ H5Oclose(hid_t object_id)
case(H5I_DATASET):
if(H5I_object(object_id) == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object")
- if(H5I_dec_ref(object_id) < 0)
+ if(H5I_dec_ref(object_id, TRUE) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object")
break;
@@ -1062,14 +1068,16 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id,
/* check args */
HDassert(f);
+ HDassert(f->intent & H5F_ACC_RDWR);
HDassert(loc);
HDassert(TRUE == H5P_isa_class(ocpl_id, H5P_OBJECT_CREATE));
+
/* Make certain we allocate at least a reasonable size for the object header */
size_hint = H5O_ALIGN_F(f, MAX(H5O_MIN_SIZE, size_hint));
/* Get the property list */
- if(NULL == (oc_plist = H5I_object(ocpl_id)))
+ if(NULL == (oc_plist = (H5P_genplist_t *)H5I_object(ocpl_id)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a property list")
/* Get any object header status flags set by properties */
@@ -1125,9 +1133,13 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id,
oh->flags |= H5O_HDR_ATTR_STORE_PHASE_CHANGE;
/* Determine correct value for chunk #0 size bits */
+/* Avoid compiler warning on 32-bit machines */
+#if H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T
if(size_hint > 4294967295)
oh->flags |= H5O_HDR_CHUNK0_8;
- else if(size_hint > 65535)
+ else
+#endif /* H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T */
+ if(size_hint > 65535)
oh->flags |= H5O_HDR_CHUNK0_4;
else if(size_hint > 255)
oh->flags |= H5O_HDR_CHUNK0_2;
@@ -1163,7 +1175,7 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id,
/* Put magic # for object header in first chunk */
if(oh->version > H5O_VERSION_1)
- HDmemcpy(oh->chunk[0].image, H5O_HDR_MAGIC, (size_t)H5O_SIZEOF_MAGIC);
+ HDmemcpy(oh->chunk[0].image, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC);
/* Create the message list */
oh->nmesgs = 1;
@@ -1214,7 +1226,7 @@ done:
* Modification:
* Raymond Lu
* 5 November 2007
- * Turn off the holding file variable if it's on. When it's
+ * Turn off the holding file variable if it's on. When it's
* needed, the caller will turn it on again.
*-------------------------------------------------------------------------
*/
@@ -1259,7 +1271,7 @@ done:
*-------------------------------------------------------------------------
*/
hid_t
-H5O_open_name(H5G_loc_t *loc, const char *name, hid_t lapl_id)
+H5O_open_name(H5G_loc_t *loc, const char *name, hid_t lapl_id, hbool_t app_ref)
{
H5G_loc_t obj_loc; /* Location used to open group */
H5G_name_t obj_path; /* Opened object group hier. path */
@@ -1284,7 +1296,7 @@ H5O_open_name(H5G_loc_t *loc, const char *name, hid_t lapl_id)
loc_found = TRUE;
/* Open the object */
- if((ret_value = H5O_open_by_loc(&obj_loc, H5AC_ind_dxpl_id)) < 0)
+ if((ret_value = H5O_open_by_loc(&obj_loc, lapl_id, H5AC_ind_dxpl_id, app_ref)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object")
done:
@@ -1310,7 +1322,7 @@ done:
*-------------------------------------------------------------------------
*/
hid_t
-H5O_open_by_loc(const H5G_loc_t *obj_loc, hid_t dxpl_id)
+H5O_open_by_loc(const H5G_loc_t *obj_loc, hid_t lapl_id, hid_t dxpl_id, hbool_t app_ref)
{
const H5O_obj_class_t *obj_class; /* Class of object for location */
hid_t ret_value; /* Return value */
@@ -1325,7 +1337,7 @@ H5O_open_by_loc(const H5G_loc_t *obj_loc, hid_t dxpl_id)
/* Call the object class's 'open' routine */
HDassert(obj_class->open);
- if((ret_value = obj_class->open(obj_loc, dxpl_id)) < 0)
+ if((ret_value = obj_class->open(obj_loc, lapl_id, dxpl_id, app_ref)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object")
done:
@@ -1390,9 +1402,9 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5O_link
+ * Function: H5O_link_oh
*
- * Purpose: Adjust the link count for an object header by adding
+ * Purpose: Adjust the link count for an open object header by adding
* ADJUST to the link count.
*
* Return: Success: New link count
@@ -1406,24 +1418,12 @@ done:
*-------------------------------------------------------------------------
*/
int
-H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
+H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, unsigned *oh_flags)
{
- H5O_t *oh = NULL;
- H5AC_protect_t oh_acc; /* Access mode for protecting object header */
- unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Whether the object was deleted */
+ haddr_t addr = H5O_OH_GET_ADDR(oh); /* Object header address */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_link, FAIL)
-
- /* check args */
- HDassert(loc);
- HDassert(loc->file);
- HDassert(H5F_addr_defined(loc->addr));
-
- /* Get header */
- oh_acc = adjust ? H5AC_WRITE : H5AC_READ;
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, oh_acc)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
+ FUNC_ENTER_NOAPI(H5O_link_oh, FAIL)
/* Check for adjusting link count */
if(adjust) {
@@ -1432,40 +1432,42 @@ H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
if((unsigned)(-adjust) > oh->nlink)
HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "link count would be negative")
oh->nlink += adjust;
- oh_flags |= H5AC__DIRTIED_FLAG;
+ *oh_flags |= H5AC__DIRTIED_FLAG;
/* Check if the object should be deleted */
if(oh->nlink == 0) {
/* Check if the object is still open by the user */
- if(H5FO_opened(loc->file, loc->addr) != NULL) {
+ if(H5FO_opened(f, addr) != NULL) {
/* Flag the object to be deleted when it's closed */
- if(H5FO_mark(loc->file, loc->addr, TRUE) < 0)
+ if(H5FO_mark(f, addr, TRUE) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion")
} /* end if */
else {
/* Delete object right now */
- if(H5O_delete_oh(loc->file, dxpl_id, oh) < 0)
+ if(H5O_delete_oh(f, dxpl_id, oh) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file")
/* Mark the object header for deletion */
- oh_flags = H5C__DELETED_FLAG;
+ *oh_flags = H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG;
} /* end else */
} /* end if */
- } else {
+ } /* end if */
+ else {
/* A new object, or one that will be deleted */
- if(oh->nlink == 0) {
- /* Check if the object is current open, but marked for deletion */
- if(H5FO_marked(loc->file, loc->addr) > 0) {
+ if(0 == oh->nlink) {
+ /* Check if the object is currently open, but marked for deletion */
+ if(H5FO_marked(f, addr)) {
/* Remove "delete me" flag on the object */
- if(H5FO_mark(loc->file, loc->addr, FALSE) < 0)
+ if(H5FO_mark(f, addr, FALSE) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion")
} /* end if */
} /* end if */
/* Adjust the link count for the object header */
oh->nlink += adjust;
+
/* Mark the object header for deletion */
- oh_flags |= H5AC__DIRTIED_FLAG;
+ *oh_flags |= H5AC__DIRTIED_FLAG;
} /* end if */
/* Check for operations on refcount message */
@@ -1474,7 +1476,7 @@ H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
if(oh->has_refcount_msg) {
/* Check for removing refcount message */
if(oh->nlink <= 1) {
- if(H5O_msg_remove_real(loc->file, oh, H5O_MSG_REFCOUNT, H5O_ALL, NULL, NULL, TRUE, dxpl_id) < 0)
+ if(H5O_msg_remove_real(f, oh, H5O_MSG_REFCOUNT, H5O_ALL, NULL, NULL, TRUE, dxpl_id) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete refcount message")
oh->has_refcount_msg = FALSE;
} /* end if */
@@ -1482,7 +1484,7 @@ H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
else {
H5O_refcount_t refcount = oh->nlink;
- if(H5O_msg_write_real(loc->file, dxpl_id, oh, H5O_MSG_REFCOUNT, H5O_MSG_FLAG_DONTSHARE, 0, &refcount) < 0)
+ if(H5O_msg_write_real(f, dxpl_id, oh, H5O_MSG_REFCOUNT, H5O_MSG_FLAG_DONTSHARE, 0, &refcount) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update refcount message")
} /* end else */
} /* end if */
@@ -1491,7 +1493,7 @@ H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
if(oh->nlink > 1) {
H5O_refcount_t refcount = oh->nlink;
- if(H5O_msg_append_real(loc->file, dxpl_id, oh, H5O_MSG_REFCOUNT, H5O_MSG_FLAG_DONTSHARE, 0, &refcount) < 0)
+ if(H5O_msg_append_real(f, dxpl_id, oh, H5O_MSG_REFCOUNT, H5O_MSG_FLAG_DONTSHARE, 0, &refcount) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to create new refcount message")
oh->has_refcount_msg = TRUE;
} /* end if */
@@ -1500,7 +1502,52 @@ H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
} /* end if */
/* Set return value */
- ret_value = oh->nlink;
+ ret_value = (int)oh->nlink;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_link_oh() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link
+ *
+ * Purpose: Adjust the link count for an object header by adding
+ * ADJUST to the link count.
+ *
+ * Return: Success: New link count
+ *
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 5 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
+{
+ H5O_t *oh = NULL;
+ H5AC_protect_t oh_acc; /* Access mode for protecting object header */
+ unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Whether the object was deleted */
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_link, FAIL)
+
+ /* check args */
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+
+ /* Get header */
+ oh_acc = adjust ? H5AC_WRITE : H5AC_READ;
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, oh_acc)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
+
+ /* Call the "real" link routine */
+ if((ret_value = H5O_link_oh(loc->file, adjust, dxpl_id, oh, &oh_flags)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust object link count")
done:
if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0)
@@ -1511,15 +1558,14 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5O_protect
+ * Function: H5O_pin
*
- * Purpose: Wrapper around H5AC_protect for use during a H5O_protect->
- * H5O_msg_append->...->H5O_msg_append->H5O_unprotect sequence of calls
- * during an object's creation.
+ * Purpose: Pin an object header down for use during a sequence of message
+ * operations, which prevents the object header from being
+ * evicted from the cache.
*
* Return: Success: Pointer to the object header structure for the
* object.
- *
* Failure: NULL
*
* Programmer: Quincey Koziol
@@ -1529,11 +1575,12 @@ done:
*-------------------------------------------------------------------------
*/
H5O_t *
-H5O_protect(H5O_loc_t *loc, hid_t dxpl_id)
+H5O_pin(H5O_loc_t *loc, hid_t dxpl_id)
{
- H5O_t *ret_value; /* Return value */
+ H5O_t *oh = NULL; /* Object header */
+ H5O_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_protect, NULL)
+ FUNC_ENTER_NOAPI(H5O_pin, NULL)
/* check args */
HDassert(loc);
@@ -1545,31 +1592,36 @@ H5O_protect(H5O_loc_t *loc, hid_t dxpl_id)
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "no write intent on file")
/* Lock the object header into the cache */
- if(NULL == (ret_value = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, NULL, "unable to load object header")
- /* Mark object header as un-evictable */
- if(H5AC_pin_protected_entry(loc->file, ret_value) < 0) {
- if(H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, ret_value, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, NULL, "unable to release object header")
-
- HGOTO_ERROR(H5E_OHDR, H5E_CANTPIN, NULL, "unable to pin object header")
+ /* Check if the object header needs to be pinned */
+ if(0 == oh->npins) {
+ /* Mark object header as un-evictable */
+ if(H5AC_pin_protected_entry(loc->file, oh) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPIN, NULL, "unable to pin object header")
} /* end if */
- /* Release the object header from the cache */
- if(H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, ret_value, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_PROTECT, NULL, "unable to release object header")
+ /* Increment the pin count */
+ oh->npins++;
+
+ /* Set the return value */
+ ret_value = oh;
+
done:
+ /* Release the object header from the cache */
+ if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, ret_value, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, NULL, "unable to release object header")
+
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_protect() */
+} /* end H5O_pin() */
/*-------------------------------------------------------------------------
- * Function: H5O_unprotect
+ * Function: H5O_unpin
*
- * Purpose: Wrapper around H5AC_unprotect for use during a H5O_protect->
- * H5O_msg_append->...->H5O_msg_append->H5O_unprotect sequence of calls
- * during an object's creation.
+ * Purpose: Unpin an object header, allowing it to be evicted from the
+ * metadata cache.
*
* Return: Success: Non-negative
* Failure: Negative
@@ -1581,11 +1633,11 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_unprotect(H5O_loc_t *loc, H5O_t *oh)
+H5O_unpin(H5O_loc_t *loc, H5O_t *oh)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5O_unprotect, FAIL)
+ FUNC_ENTER_NOAPI(H5O_unpin, FAIL)
/* check args */
HDassert(loc);
@@ -1593,13 +1645,19 @@ H5O_unprotect(H5O_loc_t *loc, H5O_t *oh)
HDassert(H5F_addr_defined(loc->addr));
HDassert(oh);
- /* Mark object header as evictable again */
- if(H5AC_unpin_entry(loc->file, oh) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPIN, FAIL, "unable to unpin object header")
+ /* Check if this is the last unpin operation */
+ if(1 == oh->npins) {
+ /* Mark object header as evictable again */
+ if(H5AC_unpin_entry(loc->file, oh) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPIN, FAIL, "unable to unpin object header")
+ } /* end if */
+
+ /* Decrement the pin count */
+ oh->npins--;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_unprotect() */
+} /* end H5O_unpin() */
/*-------------------------------------------------------------------------
@@ -1650,11 +1708,11 @@ H5O_touch_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hbool_t force)
HGOTO_DONE(SUCCEED); /*nothing to do*/
/* Allocate space for the modification time message */
- if((idx = H5O_msg_alloc(f, dxpl_id, oh, H5O_MSG_MTIME_NEW, &mesg_flags, &now)) == UFAIL)
+ if(UFAIL == (idx = H5O_msg_alloc(f, dxpl_id, oh, H5O_MSG_MTIME_NEW, &mesg_flags, &now)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for modification time message")
/* Set the message's flags if appropriate */
- oh->mesg[idx].flags = mesg_flags;
+ oh->mesg[idx].flags = (uint8_t)mesg_flags;
} /* end if */
/* Allocate 'native' space, if necessary */
@@ -1717,7 +1775,7 @@ H5O_touch(H5O_loc_t *loc, hbool_t force, hid_t dxpl_id)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file")
/* Get the object header */
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Create/Update the modification time message */
@@ -1826,7 +1884,7 @@ H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
HDassert(H5F_addr_defined(addr));
/* Get the object header information */
- if(NULL == (oh = H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Delete object */
@@ -1834,7 +1892,7 @@ H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file")
done:
- if(oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, H5AC__DIRTIED_FLAG | H5C__DELETED_FLAG) < 0)
+ if(oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0)
HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
FUNC_LEAVE_NOAPI(ret_value)
@@ -1880,10 +1938,6 @@ H5O_delete_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message")
} /* end for */
- /* Free main (first) object header "chunk" */
- if(H5MF_xfree(f, H5FD_MEM_OHDR, dxpl_id, oh->chunk[0].addr, (hsize_t)oh->chunk[0].size) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free object header")
-
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_delete_oh() */
@@ -1894,8 +1948,8 @@ done:
*
* Purpose: Retrieves the type of object pointed to by `loc'.
*
- * Return: Success: An object type defined in H5Gpublic.h
- * Failure: H5G_UNKNOWN
+ * Return: Success: Non-negative
+ * Failure: Negative
*
* Programmer: Robb Matzke
* Wednesday, November 4, 1998
@@ -1911,7 +1965,7 @@ H5O_obj_type(const H5O_loc_t *loc, H5O_type_t *obj_type, hid_t dxpl_id)
FUNC_ENTER_NOAPI(H5O_obj_type, FAIL)
/* Load the object header */
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Retrieve the type of the object */
@@ -1931,8 +1985,8 @@ done:
*
* Purpose: Returns the type of object pointed to by `oh'.
*
- * Return: Success: An object type defined in H5Opublic.h
- * Failure: H5G_UNKNOWN
+ * Return: Success: Non-negative
+ * Failure: Negative
*
* Programmer: Quincey Koziol
* Monday, November 21, 2005
@@ -1989,7 +2043,7 @@ H5O_obj_class(const H5O_loc_t *loc, hid_t dxpl_id)
FUNC_ENTER_NOAPI_NOINIT(H5O_obj_class)
/* Load the object header */
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, NULL, "unable to load object header")
/* Test whether entry qualifies as a particular type of object */
@@ -2247,6 +2301,131 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_get_hdr_info
+ *
+ * Purpose: Retrieve the object header information for an object
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * September 22 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_get_hdr_info(const H5O_loc_t *oloc, hid_t dxpl_id, H5O_hdr_info_t *hdr)
+{
+ H5O_t *oh = NULL; /* Object header */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_get_hdr_info, FAIL)
+
+ /* Check args */
+ HDassert(oloc);
+ HDassert(hdr);
+
+ /* Reset the object header info structure */
+ HDmemset(hdr, 0, sizeof(*hdr));
+
+ /* Get the object header */
+ if(NULL == (oh = (H5O_t *)H5AC_protect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
+
+ /* Get the information for the object header */
+ if(H5O_get_hdr_info_real(oh, hdr) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object header info")
+
+done:
+ if(oh && H5AC_unprotect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_get_hdr_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_get_hdr_info_real
+ *
+ * Purpose: Internal routine to retrieve the object header information for an object
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * September 22 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_get_hdr_info_real(const H5O_t *oh, H5O_hdr_info_t *hdr)
+{
+ const H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
+ const H5O_chunk_t *curr_chunk; /* Pointer to current message being operated on */
+ unsigned u; /* Local index variable */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_get_hdr_info_real)
+
+ /* Check args */
+ HDassert(oh);
+ HDassert(hdr);
+
+ /* Set the version for the object header */
+ hdr->version = oh->version;
+
+ /* Set the number of messages & chunks */
+ hdr->nmesgs = oh->nmesgs;
+ hdr->nchunks = oh->nchunks;
+
+ /* Set the status flags */
+ hdr->flags = oh->flags;
+
+ /* Iterate over all the messages, accumulating message size & type information */
+ hdr->space.meta = H5O_SIZEOF_HDR(oh) + (H5O_SIZEOF_CHKHDR_OH(oh) * (oh->nchunks - 1));
+ hdr->space.mesg = 0;
+ hdr->space.free = 0;
+ hdr->mesg.present = 0;
+ hdr->mesg.shared = 0;
+ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
+ uint64_t type_flag; /* Flag for message type */
+
+ /* Accumulate space usage information, based on the type of message */
+ if(H5O_NULL_ID == curr_msg->type->id)
+ hdr->space.free += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size;
+ else if(H5O_CONT_ID == curr_msg->type->id)
+ hdr->space.meta += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size;
+ else {
+ hdr->space.meta += H5O_SIZEOF_MSGHDR_OH(oh);
+ hdr->space.mesg += curr_msg->raw_size;
+ } /* end else */
+
+ /* Set flag to indicate presence of message type */
+ type_flag = ((uint64_t)1) << curr_msg->type->id;
+ hdr->mesg.present |= type_flag;
+
+ /* Set flag if the message is shared in some way */
+ if(curr_msg->flags & H5O_MSG_FLAG_SHARED) \
+ hdr->mesg.shared |= type_flag;
+ } /* end for */
+
+ /* Iterate over all the chunks, adding any gaps to the free space */
+ hdr->space.total = 0;
+ for(u = 0, curr_chunk = &oh->chunk[0]; u < oh->nchunks; u++, curr_chunk++) {
+ /* Accumulate the size of the header on disk */
+ hdr->space.total += curr_chunk->size;
+
+ /* If the chunk has a gap, add it to the free space */
+ hdr->space.free += curr_chunk->gap;
+ } /* end for */
+
+ /* Sanity check that all the bytes are accounted for */
+ HDassert(hdr->space.total == (hdr->space.free + hdr->space.meta + hdr->space.mesg));
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_get_hdr_info_real() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_get_info
*
* Purpose: Retrieve the information for an object
@@ -2260,12 +2439,11 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_get_info(const H5O_loc_t *loc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info_t *oinfo)
+H5O_get_info(const H5O_loc_t *loc, hid_t dxpl_id, hbool_t want_ih_info,
+ H5O_info_t *oinfo)
{
+ const H5O_obj_class_t *obj_class; /* Class of object for header */
H5O_t *oh = NULL; /* Object header */
- H5O_chunk_t *curr_chunk; /* Pointer to current message being operated on */
- H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
- unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5O_get_info, FAIL)
@@ -2275,7 +2453,7 @@ H5O_get_info(const H5O_loc_t *loc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info
HDassert(oinfo);
/* Get the object header */
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Reset the object info structure */
@@ -2287,20 +2465,12 @@ H5O_get_info(const H5O_loc_t *loc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info
/* Set the object's address */
oinfo->addr = loc->addr;
- /* Retrieve the type of the object */
- if(H5O_obj_type_real(oh, &oinfo->type) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object type")
+ /* Get class for object */
+ if(NULL == (obj_class = H5O_obj_class_real(oh)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine object class")
- /* Retrieve btree and heap storage info, if requested */
- if(want_ih_info) {
- if(oinfo->type == H5O_TYPE_GROUP) {
- if(H5O_group_bh_info(loc->file, dxpl_id, oh, &(oinfo->meta_size.obj)/*out*/) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve group btree & heap info")
- } else if(oinfo->type == H5O_TYPE_DATASET) {
- if(H5O_dset_bh_info(loc->file, dxpl_id, oh, &(oinfo->meta_size.obj)/*out*/) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve chunked dataset btree info")
- }
- } /* end if */
+ /* Retrieve the type of the object */
+ oinfo->type = obj_class->type;
/* Set the object's reference count */
oinfo->rc = oh->nlink;
@@ -2313,6 +2483,8 @@ H5O_get_info(const H5O_loc_t *loc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info
oinfo->btime = oh->btime;
} /* end if */
else {
+ htri_t exists; /* Flag if header message of interest exists */
+
/* No information for access & modification fields */
/* (we stopped updating the "modification time" header message for
* raw data changes, so the "modification time" header message
@@ -2323,74 +2495,50 @@ H5O_get_info(const H5O_loc_t *loc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info
oinfo->btime = 0;
/* Might be information for modification time */
- if(NULL == H5O_msg_read_real(loc->file, dxpl_id, oh, H5O_MTIME_ID, &oinfo->ctime)) {
- H5E_clear_stack(NULL);
- if(NULL == H5O_msg_read_real(loc->file, dxpl_id, oh, H5O_MTIME_NEW_ID, &oinfo->ctime)) {
- H5E_clear_stack(NULL);
- oinfo->ctime = 0;
- } /* end if */
+ if((exists = H5O_msg_exists_oh(oh, H5O_MTIME_ID)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "unable to check for MTIME message")
+ if(exists > 0) {
+ /* Get "old style" modification time info */
+ if(NULL == H5O_msg_read_oh(loc->file, dxpl_id, oh, H5O_MTIME_ID, &oinfo->ctime))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't read MTIME message")
} /* end if */
- } /* end else */
-
- /* Set the version for the object header */
- oinfo->hdr.version = oh->version;
-
- /* Set the number of messages & chunks */
- oinfo->hdr.nmesgs = oh->nmesgs;
- oinfo->hdr.nchunks = oh->nchunks;
-
- /* Set the status flags */
- oinfo->hdr.flags = oh->flags;
-
- /* Iterate over all the messages, accumulating message size & type information */
- oinfo->hdr.space.meta = H5O_SIZEOF_HDR(oh) + (H5O_SIZEOF_CHKHDR_OH(oh) * (oh->nchunks - 1));
- oinfo->hdr.space.mesg = 0;
- oinfo->hdr.space.free = 0;
- oinfo->hdr.mesg.present = 0;
- oinfo->hdr.mesg.shared = 0;
- for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
- uint64_t type_flag; /* Flag for message type */
-
- /* Accumulate space usage information, based on the type of message */
- if(H5O_NULL_ID == curr_msg->type->id)
- oinfo->hdr.space.free += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size;
- else if(H5O_CONT_ID == curr_msg->type->id)
- oinfo->hdr.space.meta += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size;
else {
- oinfo->hdr.space.meta += H5O_SIZEOF_MSGHDR_OH(oh);
- oinfo->hdr.space.mesg += curr_msg->raw_size;
+ /* Check for "new style" modification time info */
+ if((exists = H5O_msg_exists_oh(oh, H5O_MTIME_NEW_ID)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "unable to check for MTIME_NEW message")
+ if(exists > 0) {
+ /* Get "new style" modification time info */
+ if(NULL == H5O_msg_read_oh(loc->file, dxpl_id, oh, H5O_MTIME_NEW_ID, &oinfo->ctime))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't read MTIME_NEW message")
+ } /* end if */
+ else
+ oinfo->ctime = 0;
} /* end else */
+ } /* end else */
- /* Set flag to indicate presence of message type */
- type_flag = ((uint64_t)1) << curr_msg->type->id;
- oinfo->hdr.mesg.present |= type_flag;
-
- /* Set flag if the message is shared in some way */
- if(curr_msg->flags & H5O_MSG_FLAG_SHARED) \
- oinfo->hdr.mesg.shared |= type_flag;
- } /* end for */
+ /* Get the information for the object header */
+ if(H5O_get_hdr_info_real(oh, &oinfo->hdr) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object header info")
/* Retrieve # of attributes */
- oinfo->num_attrs = H5O_attr_count_real(loc->file, dxpl_id, oh);
+ if(H5O_attr_count_real(loc->file, dxpl_id, oh, &oinfo->num_attrs) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve attribute count")
/* Get B-tree & heap metadata storage size, if requested */
if(want_ih_info) {
- if((oinfo->num_attrs > 0) && (H5O_attr_bh_info(loc->file, dxpl_id, oh, &oinfo->meta_size.attr/*out*/) < 0))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve attribute btree & heap info")
- } /* end if */
-
- /* Iterate over all the chunks, adding any gaps to the free space */
- oinfo->hdr.space.total = 0;
- for(u = 0, curr_chunk = &oh->chunk[0]; u < oh->nchunks; u++, curr_chunk++) {
- /* Accumulate the size of the header on disk */
- oinfo->hdr.space.total += curr_chunk->size;
-
- /* If the chunk has a gap, add it to the free space */
- oinfo->hdr.space.free += curr_chunk->gap;
- } /* end for */
+ /* Check for 'bh_info' callback for this type of object */
+ if(obj_class->bh_info) {
+ /* Call the object's class 'bh_info' routine */
+ if((obj_class->bh_info)(loc->file, dxpl_id, oh, &oinfo->meta_size.obj) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object's btree & heap info")
+ } /* end if */
- /* Sanity check that all the bytes are accounted for */
- HDassert(oinfo->hdr.space.total == (oinfo->hdr.space.free + oinfo->hdr.space.meta + oinfo->hdr.space.mesg));
+ /* Get B-tree & heap info for any attributes */
+ if(oinfo->num_attrs > 0) {
+ if(H5O_attr_bh_info(loc->file, dxpl_id, oh, &oinfo->meta_size.attr) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve attribute btree & heap info")
+ } /* end if */
+ } /* end if */
done:
if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
@@ -2426,7 +2574,7 @@ H5O_get_create_plist(const H5O_loc_t *loc, hid_t dxpl_id, H5P_genplist_t *oc_pli
HDassert(oc_plist);
/* Get the object header */
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Set property values, if they were used for the object */
@@ -2481,8 +2629,8 @@ H5O_get_nlinks(const H5O_loc_t *loc, hid_t dxpl_id, hsize_t *nlinks)
HDassert(nlinks);
/* Get the object header */
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Retrieve the # of link messages seen when the object header was loaded */
*nlinks = oh->link_msgs_seen;
@@ -2600,7 +2748,7 @@ H5O_get_rc_and_type(const H5O_loc_t *loc, hid_t dxpl_id, unsigned *rc, H5O_type_
HDassert(otype);
/* Get the object header */
- if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Set the object's reference count */
@@ -2635,7 +2783,7 @@ H5O_free_visit_visited(void *item, void UNUSED *key, void UNUSED *operator_data/
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_free_visit_visited)
- H5FL_FREE(H5_obj_t, item);
+ (void)H5FL_FREE(H5_obj_t, item);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_free_visit_visited() */
@@ -2805,13 +2953,17 @@ H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
/* Open the object */
/* (Takes ownership of the obj_loc information) */
- if((obj_id = H5O_open_by_loc(&obj_loc, dxpl_id)) < 0)
+ if((obj_id = H5O_open_by_loc(&obj_loc, lapl_id, dxpl_id, TRUE)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object")
/* Make callback for starting object */
if((ret_value = op(obj_id, ".", &oinfo, op_data)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "can't visit objects")
+ /* Check return value of first callback */
+ if(ret_value != H5_ITER_CONT)
+ HGOTO_DONE(ret_value);
+
/* Check for object being a group */
if(oinfo.type == H5O_TYPE_GROUP) {
H5G_loc_t start_loc; /* Location of starting group */
@@ -2827,9 +2979,9 @@ H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
udata.dxpl_id = dxpl_id;
udata.op = op;
udata.op_data = op_data;
-
+
/* Create skip list to store visited object information */
- if((udata.visited = H5SL_create(H5SL_TYPE_OBJ, 0.5, (size_t)16)) == NULL)
+ if((udata.visited = H5SL_create(H5SL_TYPE_OBJ)) == NULL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "can't create skip list for visited objects")
/* If its ref count is > 1, we add it to the list of visited objects */
@@ -2857,7 +3009,7 @@ H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
done:
if(obj_id > 0) {
- if(H5I_dec_ref(obj_id) < 0)
+ if(H5I_dec_ref(obj_id, TRUE) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object")
} /* end if */
else if(loc_found && H5G_loc_free(&obj_loc) < 0)
@@ -2867,5 +3019,3 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_visit() */
-
-
diff --git a/src/H5Oainfo.c b/src/H5Oainfo.c
index 968b165..e61d899 100644
--- a/src/H5Oainfo.c
+++ b/src/H5Oainfo.c
@@ -35,7 +35,8 @@
/* PRIVATE PROTOTYPES */
-static void *H5O_ainfo_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_ainfo_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_ainfo_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
static void *H5O_ainfo_copy(const void *_mesg, void *_dest);
static size_t H5O_ainfo_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
@@ -47,6 +48,9 @@ static herr_t H5O_ainfo_pre_copy_file(H5F_t *file_src, const void *mesg_src,
static void *H5O_ainfo_copy_file(H5F_t *file_src, void *mesg_src,
H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, void *udata,
hid_t dxpl_id);
+static herr_t H5O_ainfo_post_copy_file(const H5O_loc_t *src_oloc,
+ const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id,
+ H5O_copy_t *cpy_info);
static herr_t H5O_ainfo_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -68,7 +72,7 @@ const H5O_msg_class_t H5O_MSG_AINFO[1] = {{
NULL, /*can share method */
H5O_ainfo_pre_copy_file, /* pre copy native value to file */
H5O_ainfo_copy_file, /* copy native value to file */
- NULL, /* post copy native value to file */
+ H5O_ainfo_post_copy_file, /* post copy native value to file */
NULL, /* get creation index */
NULL, /* set creation index */
H5O_ainfo_debug /*debug the message */
@@ -101,8 +105,8 @@ H5FL_DEFINE_STATIC(H5O_ainfo_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_ainfo_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_ainfo_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_ainfo_t *ainfo = NULL; /* Attribute info */
unsigned char flags; /* Flags for encoding attribute info */
@@ -155,7 +159,7 @@ H5O_ainfo_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
done:
if(ret_value == NULL && ainfo != NULL)
- H5FL_FREE(H5O_ainfo_t, ainfo);
+ (void)H5FL_FREE(H5O_ainfo_t, ainfo);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_ainfo_decode() */
@@ -310,7 +314,7 @@ H5O_ainfo_free(void *mesg)
HDassert(mesg);
- H5FL_FREE(H5O_ainfo_t, mesg);
+ (void)H5FL_FREE(H5O_ainfo_t, mesg);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_ainfo_free() */
@@ -392,15 +396,14 @@ H5O_ainfo_pre_copy_file(H5F_t UNUSED *file_src, const void UNUSED *native_src,
* Return: Success: Ptr to _DEST
* Failure: NULL
*
- * Programmer: Quincey Koziol
- * March 9, 2007
+ * Programmer: Peter Cao
+ * July 18, 2007
*
*-------------------------------------------------------------------------
*/
static void *
-H5O_ainfo_copy_file(H5F_t UNUSED *file_src, void *mesg_src,
- H5F_t UNUSED *file_dst, hbool_t UNUSED *recompute_size,
- H5O_copy_t UNUSED *cpy_info, void UNUSED *udata, hid_t UNUSED dxpl_id)
+H5O_ainfo_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
+ hbool_t *recompute_size, H5O_copy_t *cpy_info, void UNUSED *udata, hid_t dxpl_id)
{
H5O_ainfo_t *ainfo_src = (H5O_ainfo_t *)mesg_src;
H5O_ainfo_t *ainfo_dst = NULL;
@@ -415,10 +418,6 @@ H5O_ainfo_copy_file(H5F_t UNUSED *file_src, void *mesg_src,
HDassert(cpy_info);
HDassert(!cpy_info->copy_without_attr);
-/* XXX: Bail out for now, if the source object has densely stored attributes */
- if(H5F_addr_defined(ainfo_src->fheap_addr))
- HGOTO_ERROR(H5E_OHDR, H5E_UNSUPPORTED, NULL, "densely stored attributes not supported yet")
-
/* Allocate space for the destination message */
if(NULL == (ainfo_dst = H5FL_MALLOC(H5O_ainfo_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
@@ -426,19 +425,67 @@ H5O_ainfo_copy_file(H5F_t UNUSED *file_src, void *mesg_src,
/* Copy the top level of the information */
*ainfo_dst = *ainfo_src;
+ if(H5F_addr_defined(ainfo_src->fheap_addr)) {
+ /* copy dense attribute */
+
+ if(H5A_dense_create(file_dst, dxpl_id, ainfo_dst) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to create dense storage for attributes")
+
+ if ( (H5A_dense_copy_file_all(file_src, ainfo_src, file_dst, ainfo_dst, recompute_size, cpy_info, dxpl_id)) <0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to create dense storage for attributes")
+ }
+
/* Set return value */
ret_value = ainfo_dst;
done:
/* Release destination attribute information on failure */
if(ret_value == NULL && ainfo_dst != NULL)
- H5FL_FREE(H5O_ainfo_t, ainfo_dst);
+ (void)H5FL_FREE(H5O_ainfo_t, ainfo_dst);
FUNC_LEAVE_NOAPI(ret_value)
} /* H5O_ainfo_copy_file() */
/*-------------------------------------------------------------------------
+ * Function: H5O_ainfo_post_copy_file
+ *
+ * Purpose: Finish copying a message from between files.
+ * We have to copy the values of a reference attribute in the
+ * post copy because H5O_post_copy_file() fails at the case that
+ * an object may have a reference attribute that points to the
+ * object itself.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Peter Cao
+ * July 25, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_ainfo_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
+ H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
+{
+ const H5O_ainfo_t *ainfo_src = (const H5O_ainfo_t *)mesg_src;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_ainfo_post_copy_file)
+
+ HDassert(ainfo_src);
+
+ if(H5F_addr_defined(ainfo_src->fheap_addr)) {
+ if ( H5A_dense_post_copy_file_all(src_oloc, ainfo_src, dst_oloc,
+ (H5O_ainfo_t *)mesg_dst, dxpl_id, cpy_info) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "can't copy attribute")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_ainfo_post_copy_file() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_ainfo_debug
*
* Purpose: Prints debugging info for a message.
diff --git a/src/H5Oalloc.c b/src/H5Oalloc.c
index 29c057d..9cf50ad 100644
--- a/src/H5Oalloc.c
+++ b/src/H5Oalloc.c
@@ -64,13 +64,15 @@ static herr_t H5O_eliminate_gap(H5O_t *oh, H5O_mesg_t *mesg,
uint8_t *new_gap_loc, size_t new_gap_size);
static herr_t H5O_alloc_null(H5O_t *oh, unsigned null_idx,
const H5O_msg_class_t *new_type, void *new_native, size_t new_size);
-static htri_t H5O_alloc_extend_chunk(H5F_t *f, H5O_t *oh, unsigned chunkno,
- size_t size, unsigned * msg_idx);
+static htri_t H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
+ unsigned chunkno, size_t size, unsigned * msg_idx);
static unsigned H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
size_t size);
-static htri_t H5O_move_msgs_forward(H5O_t *oh);
-static htri_t H5O_merge_null(H5O_t *oh);
+static htri_t H5O_move_cont(H5F_t *f, H5O_t *oh, unsigned cont_u, hid_t dxpl_id);
+static htri_t H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id);
+static htri_t H5O_merge_null(H5F_t *f, H5O_t *oh, hid_t dxpl_id);
static htri_t H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id);
+static herr_t H5O_alloc_shrink_chunk(H5F_t *f, H5O_t *oh, hid_t dxpl_id, unsigned chunkno);
/*********************/
@@ -148,7 +150,7 @@ H5O_add_gap(H5O_t *oh, unsigned chunkno, unsigned idx,
oh->mesg[u].raw -= new_gap_size;
/* Slide raw message info forward in chunk image */
- HDmemmove(new_gap_loc, new_gap_loc + new_gap_size,
+ HDmemmove(new_gap_loc, new_gap_loc + new_gap_size,
(size_t)((oh->chunk[chunkno].image + (oh->chunk[chunkno].size - H5O_SIZEOF_CHKSUM_OH(oh))) - (new_gap_loc + new_gap_size)));
/* Add existing gap size to new gap size */
@@ -161,7 +163,7 @@ H5O_add_gap(H5O_t *oh, unsigned chunkno, unsigned idx,
/* Check if we need to extend message table to hold the new null message */
if(oh->nmesgs >= oh->alloc_nmesgs)
if(H5O_alloc_msgs(oh, (size_t)1) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "can't allocate more space for messages")
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate more space for messages")
/* Increment new gap size */
oh->chunk[chunkno].gap += new_gap_size;
@@ -329,7 +331,7 @@ H5O_alloc_null(H5O_t *oh, unsigned null_idx, const H5O_msg_class_t *new_type,
/* Add the gap to the chunk */
if(H5O_add_gap(oh, alloc_msg->chunkno, null_idx, alloc_msg->raw + alloc_msg->raw_size, gap_size) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, UFAIL, "can't insert gap in chunk")
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert gap in chunk")
} /* end if */
else {
size_t new_mesg_size = new_size + H5O_SIZEOF_MSGHDR_OH(oh); /* Total size of newly allocated message */
@@ -338,7 +340,7 @@ H5O_alloc_null(H5O_t *oh, unsigned null_idx, const H5O_msg_class_t *new_type,
/* Check if we need to extend message table to hold the new null message */
if(oh->nmesgs >= oh->alloc_nmesgs) {
if(H5O_alloc_msgs(oh, (size_t)1) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "can't allocate more space for messages")
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate more space for messages")
/* "Retarget" 'alloc_msg' pointer into newly re-allocated array of messages */
alloc_msg = &oh->mesg[null_idx];
@@ -363,7 +365,7 @@ H5O_alloc_null(H5O_t *oh, unsigned null_idx, const H5O_msg_class_t *new_type,
if(H5O_eliminate_gap(oh, null_msg,
((oh->chunk[null_chunkno].image + oh->chunk[null_chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[null_chunkno].gap)),
oh->chunk[null_chunkno].gap) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTREMOVE, UFAIL, "can't eliminate gap in chunk")
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTREMOVE, FAIL, "can't eliminate gap in chunk")
/* Set the gap size to zero for the chunk */
oh->chunk[null_chunkno].gap = 0;
@@ -462,14 +464,14 @@ done:
*-------------------------------------------------------------------------
*/
static htri_t
-H5O_alloc_extend_chunk(H5F_t *f, H5O_t *oh, unsigned chunkno,
+H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned chunkno,
size_t size, unsigned * msg_idx)
{
size_t delta; /* Change in chunk's size */
size_t aligned_size = H5O_ALIGN_OH(oh, size);
uint8_t *old_image; /* Old address of chunk's image in memory */
size_t old_size; /* Old size of chunk */
- htri_t tri_result; /* Result from checking if chunk can be extended */
+ htri_t extended; /* If chunk can be extended */
int extend_msg = -1;/* Index of null message to extend */
uint8_t new_size_flags = 0; /* New chunk #0 size flags */
hbool_t adjust_size_flags = FALSE; /* Whether to adjust the chunk #0 size flags */
@@ -537,16 +539,12 @@ H5O_alloc_extend_chunk(H5F_t *f, H5O_t *oh, unsigned chunkno,
} /* end if */
/* Determine whether the chunk can be extended */
- tri_result = H5MF_can_extend(f, H5FD_MEM_OHDR, oh->chunk[chunkno].addr,
+ extended = H5MF_try_extend(f, dxpl_id, H5FD_MEM_OHDR, oh->chunk[chunkno].addr,
(hsize_t)(oh->chunk[chunkno].size), (hsize_t)(delta + extra_prfx_size));
- if(tri_result == FALSE) /* can't extend -- we are done */
+ if(extended < 0) /* error */
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTEXTEND, FAIL, "can't tell if we can extend chunk")
+ else if(extended == FALSE) /* can't extend -- we are done */
HGOTO_DONE(FALSE)
- else if(tri_result < 0) /* error */
- HGOTO_ERROR(H5E_RESOURCE, H5E_SYSTEM, FAIL, "can't tell if we can extend chunk")
-
- /* If we get this far, we should be able to extend the chunk */
- if(H5MF_extend(f, H5FD_MEM_OHDR, oh->chunk[chunkno].addr, (hsize_t)(oh->chunk[chunkno].size), (hsize_t)(delta + extra_prfx_size)) < 0 )
- HGOTO_ERROR(H5E_RESOURCE, H5E_SYSTEM, FAIL, "can't extend chunk")
/* Adjust object header prefix flags */
if(adjust_size_flags) {
@@ -675,6 +673,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
H5O_mesg_t *curr_msg; /* Pointer to current message to operate on */
size_t cont_size; /*continuation message size */
+ size_t multi_size = 0; /* Size of all the messages in the last chunk */
int found_null = (-1); /* Best fit null message */
alloc_info found_attr = {-1, 0, 0, 0, 0}; /* Best fit attribute message */
alloc_info found_other = {-1, 0, 0, 0, 0}; /* Best fit other message */
@@ -770,11 +769,15 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
found_other.null_msgno = null_msgno;
} /* end if */
} /* end else */
- } /* end if */
+ } else if(found_null < 0 && found_attr.msgno < 0 && found_other.msgno < 0 && msg_chunkno == oh->nchunks - 1)
+ /* Keep track of the total size of smaller messages in the last
+ * chunk, in case we need to move more than 1 message.
+ */
+ multi_size += curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh);
} /* end else */
} /* end for */
- if(found_null < 0 && found_attr.msgno < 0 && found_other.msgno < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "unable to locate message to move")
+ if(found_null >= 0 || found_attr.msgno >= 0 || found_other.msgno >= 0)
+ multi_size = 0;
/*
* If we must move some other message to make room for the null
@@ -783,14 +786,20 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
*
* Move other messages first, and attributes only as a last resort.
*
+ * If all else fails, move every message in the last chunk.
+ *
*/
- if(found_null < 0) {
- if(found_other.msgno < 0)
- found_other = found_attr;
+ if(multi_size == 0) {
+ if(found_null < 0) {
+ if(found_other.msgno < 0)
+ found_other = found_attr;
- HDassert(found_other.msgno >= 0);
- size += H5O_SIZEOF_MSGHDR_OH(oh) + oh->mesg[found_other.msgno].raw_size;
+ HDassert(found_other.msgno >= 0);
+ size += H5O_SIZEOF_MSGHDR_OH(oh) + oh->mesg[found_other.msgno].raw_size;
+ } /* end if */
} /* end if */
+ else
+ size += multi_size;
/*
* The total chunk size must include the requested space plus enough
@@ -837,8 +846,8 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
* # at the beginning of the chunk image.
*/
if(oh->version > H5O_VERSION_1) {
- HDmemcpy(p, H5O_CHK_MAGIC, (size_t)H5O_SIZEOF_MAGIC);
- p += H5O_SIZEOF_MAGIC;
+ HDmemcpy(p, H5O_CHK_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
} /* end if */
/*
@@ -849,10 +858,58 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
if(H5O_alloc_msgs(oh, (size_t)3) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "can't allocate more space for messages")
- /* Move message (that will be replaced with continuation message)
- * to new chunk, if necessary.
- */
- if(found_null < 0) {
+ if(multi_size > 0) {
+ /* Move all non-null messages in the last chunk to the new chunk. This
+ * should be extremely rare so we don't care too much about minimizing
+ * the space used */
+ H5O_mesg_t *null_msg; /* Pointer to new null message */
+
+ /* Copy each message to the new location */
+ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++)
+ if(curr_msg->chunkno == chunkno - 1) {
+ if(curr_msg->type->id == H5O_NULL_ID) {
+ /* Delete the null message */
+ if(u < oh->nmesgs - 1)
+ HDmemmove(curr_msg, curr_msg + 1, ((oh->nmesgs - 1) - u) * sizeof(H5O_mesg_t));
+ oh->nmesgs--;
+ } else {
+ /* Copy the raw data */
+ HDmemcpy(p, curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh),
+ curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh));
+
+ /* Update the message info */
+ curr_msg->chunkno = chunkno;
+ curr_msg->raw = p + H5O_SIZEOF_MSGHDR_OH(oh);
+
+ /* Account for copied message in new chunk */
+ p += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size;
+ size -= H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size;
+ } /* end else */
+ } /* end if */
+
+ /* Create a null message spanning the entire last chunk */
+ found_null = oh->nmesgs++;
+ null_msg = &(oh->mesg[found_null]);
+ null_msg->type = H5O_MSG_NULL;
+ null_msg->dirty = TRUE;
+ null_msg->native = NULL;
+ null_msg->raw = oh->chunk[chunkno-1].image
+ + ((chunkno == 1) ? H5O_SIZEOF_HDR(oh) : H5O_SIZEOF_CHKHDR_OH(oh))
+ - H5O_SIZEOF_CHKSUM_OH(oh) + H5O_SIZEOF_MSGHDR_OH(oh);
+ null_msg->raw_size = oh->chunk[chunkno-1].size
+ - ((chunkno == 1) ? H5O_SIZEOF_HDR(oh) : H5O_SIZEOF_CHKHDR_OH(oh))
+ - H5O_SIZEOF_MSGHDR_OH(oh);
+ null_msg->chunkno = chunkno - 1;
+
+ HDassert(null_msg->raw_size >= cont_size);
+
+ /* Remove any gap in the chunk */
+ oh->chunk[chunkno-1].gap = 0;
+
+ } else if(found_null < 0) {
+ /* Move message (that will be replaced with continuation message)
+ * to new chunk, if necessary.
+ */
H5O_mesg_t *null_msg; /* Pointer to new null message */
/* Create null message for space that message to copy currently occupies */
@@ -996,13 +1053,13 @@ H5O_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *type,
HDassert(H5F_addr_defined(oh->chunk[chunkno].addr));
- tri_result = H5O_alloc_extend_chunk(f, oh, chunkno, raw_size, &idx);
+ tri_result = H5O_alloc_extend_chunk(f, dxpl_id, oh, chunkno, raw_size, &idx);
if(tri_result == TRUE)
break;
else if(tri_result == FALSE)
idx = UFAIL;
else
- HGOTO_ERROR(H5E_OHDR, H5E_SYSTEM, UFAIL, "H5O_alloc_extend_chunk failed unexpectedly")
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTEXTEND, UFAIL, "H5O_alloc_extend_chunk failed unexpectedly")
} /* end for */
/* If idx is still UFAIL, we were not able to extend a chunk,
@@ -1080,7 +1137,7 @@ H5O_release_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_mesg_t *mesg,
/* Check if chunk has a gap currently */
if(oh->chunk[mesg->chunkno].gap) {
/* Eliminate the gap in the chunk */
- if(H5O_eliminate_gap(oh, mesg,
+ if(H5O_eliminate_gap(oh, mesg,
((oh->chunk[mesg->chunkno].image + oh->chunk[mesg->chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[mesg->chunkno].gap)),
oh->chunk[mesg->chunkno].gap) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTREMOVE, FAIL, "can't eliminate gap in chunk")
@@ -1095,6 +1152,118 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_move_cont
+ *
+ * Purpose: Check and move message(s) forward into a continuation message
+ *
+ * Return: Success: non-negative (TRUE/FALSE)
+ * Failure: negative
+ *
+ * Programmer: Vailin Choi
+ * Feb. 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5O_move_cont(H5F_t *f, H5O_t *oh, unsigned cont_u, hid_t dxpl_id)
+{
+ unsigned v; /* local index variable */
+ H5O_mesg_t *cont_msg; /* pointer to the continuation message */
+ H5O_mesg_t *nonnull_msg; /* pointer to the current message to operate on */
+ H5O_mesg_t *null_msg; /* pointer to the current message to operate on */
+ size_t total_size=0; /* total size of nonnull messages in the chunk pointed to by cont message */
+ size_t move_size=0; /* size of the message to be moved */
+ uint8_t *move_start, *move_end; /* pointers to area of messages to move */
+ size_t gap_size; /* size of gap produced */
+ unsigned deleted_chunkno; /* Chunk # to delete */
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_move_cont)
+
+ /* Check arguments. */
+ HDassert(f);
+ HDassert(oh);
+
+ cont_msg = &oh->mesg[cont_u];
+ H5O_LOAD_NATIVE(f, dxpl_id, 0, oh, cont_msg, FAIL)
+ deleted_chunkno = ((H5O_cont_t *)(cont_msg->native))->chunkno;
+
+ /* proceed further only if continuation message is pointing to the last chunk */
+ if(deleted_chunkno != (oh->nchunks - 1))
+ HGOTO_DONE(FALSE)
+
+ /* find size of all nonnull messages in the chunk pointed to by the continuation message */
+ for(v = 0, nonnull_msg = &oh->mesg[0]; v < oh->nmesgs; v++, nonnull_msg++)
+ if(nonnull_msg->chunkno == deleted_chunkno && nonnull_msg->type->id != H5O_NULL_ID) {
+ HDassert(nonnull_msg->type->id != H5O_CONT_ID);
+ total_size += nonnull_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh);
+ }
+
+ /* check if messages can fit into the continuation message */
+ if(total_size && total_size <= (cont_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh))) {
+
+ /* convert continuation message into a null message */
+ if(H5O_release_mesg(f, dxpl_id, oh, cont_msg, TRUE) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to convert into null message")
+
+ move_start = cont_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh);
+ move_end = cont_msg->raw + cont_msg->raw_size;
+
+ /* move message(s) forward into continuation message */
+ for(v = 0, nonnull_msg = &oh->mesg[0]; v < oh->nmesgs; v++, nonnull_msg++)
+ if(nonnull_msg->chunkno == deleted_chunkno && nonnull_msg->type->id != H5O_NULL_ID) {
+ move_size = nonnull_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh);
+ HDmemcpy(move_start, nonnull_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), move_size);
+ nonnull_msg->raw = move_start + H5O_SIZEOF_MSGHDR_OH(oh);
+ nonnull_msg->chunkno = cont_msg->chunkno;
+ nonnull_msg->dirty = TRUE;
+ move_start += move_size;
+ }
+
+ HDassert(move_start <= move_end);
+
+ /* check if there is space remaining in the continuation message */
+ /* the remaining space can be gap or a null message */
+ gap_size = move_end - move_start;
+ if(gap_size >= (size_t)H5O_SIZEOF_MSGHDR_OH(oh)) {
+ cont_msg->raw_size = gap_size - H5O_SIZEOF_MSGHDR_OH(oh);
+ cont_msg->raw = move_start + H5O_SIZEOF_MSGHDR_OH(oh);
+ cont_msg->dirty = TRUE;
+ } else {
+ if(gap_size && (H5O_add_gap(oh, cont_msg->chunkno, cont_u, move_start, gap_size) < 0))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert gap in chunk")
+ /* Release any information/memory for continuation message */
+ H5O_msg_free_mesg(cont_msg);
+ if(cont_u < (oh->nmesgs - 1))
+ HDmemmove(&oh->mesg[cont_u], &oh->mesg[cont_u + 1], ((oh->nmesgs - 1) - cont_u) * sizeof(H5O_mesg_t));
+ oh->nmesgs--;
+ }
+
+ /* remove all null messages in deleted chunk from list of messages */
+ /* Note: unsigned v wrapping around at the end */
+ for (v = oh->nmesgs - 1, null_msg = &oh->mesg[v]; v < oh->nmesgs; v--, null_msg--)
+ if(null_msg->type->id == H5O_NULL_ID && null_msg->chunkno == deleted_chunkno) {
+
+ /* Release any information/memory for message */
+ H5O_msg_free_mesg(null_msg);
+
+ if(v < (oh->nmesgs - 1))
+ HDmemmove(&oh->mesg[v], &oh->mesg[v + 1], ((oh->nmesgs - 1) - v) * sizeof(H5O_mesg_t));
+ oh->nmesgs--;
+ } /* end if */
+
+ (void)H5FL_BLK_FREE(chunk_image, oh->chunk[deleted_chunkno].image);
+
+ oh->nchunks--;
+ ret_value = TRUE;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_move_cont() */
+
+
+/*-------------------------------------------------------------------------
*
* Function: H5O_move_msgs_forward
*
@@ -1105,11 +1274,14 @@ done:
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
* Oct 17 2005
+ * Modifications:
+ * Feb. 2009: Vailin Choi
+ * Add changes to move messages forward into "continuation" message
*
*-------------------------------------------------------------------------
*/
static htri_t
-H5O_move_msgs_forward(H5O_t *oh)
+H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
{
hbool_t packed_msg; /* Flag to indicate that messages were packed */
hbool_t did_packing = FALSE; /* Whether any messages were packed */
@@ -1138,7 +1310,7 @@ H5O_move_msgs_forward(H5O_t *oh)
/* Check if null message is not last in chunk */
chunk = &(oh->chunk[curr_msg->chunkno]);
- if((curr_msg->raw + curr_msg->raw_size)
+ if((curr_msg->raw + curr_msg->raw_size)
!= ((chunk->image + chunk->size) - (H5O_SIZEOF_CHKSUM_OH(oh) + chunk->gap))) {
H5O_mesg_t *nonnull_msg; /* Pointer to current message to operate on */
unsigned v; /* Local index variable */
@@ -1186,7 +1358,17 @@ H5O_move_msgs_forward(H5O_t *oh)
} /* end if */
else {
H5O_mesg_t *null_msg; /* Pointer to current message to operate on */
- unsigned v; /* Local index variable */
+ unsigned v; /* Local index variable */
+ htri_t status;
+
+ if(H5O_CONT_ID == curr_msg->type->id) {
+ if((status = H5O_move_cont(f, oh, u, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "Error in moving messages into cont message")
+ else if(status > 0) { /* message(s) got moved into "continuation" message */
+ packed_msg = TRUE;
+ break;
+ }
+ }
/* Loop over messages again, looking for large enough null message in earlier chunk */
for(v = 0, null_msg = &oh->mesg[0]; v < oh->nmesgs; v++, null_msg++) {
@@ -1222,7 +1404,7 @@ H5O_move_msgs_forward(H5O_t *oh)
/* Check for gap in null message's chunk */
if(oh->chunk[old_chunkno].gap > 0) {
/* Eliminate the gap in the chunk */
- if(H5O_eliminate_gap(oh, null_msg,
+ if(H5O_eliminate_gap(oh, null_msg,
((oh->chunk[old_chunkno].image + oh->chunk[old_chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[old_chunkno].gap)),
oh->chunk[old_chunkno].gap) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTREMOVE, FAIL, "can't eliminate gap in chunk")
@@ -1282,7 +1464,7 @@ H5O_move_msgs_forward(H5O_t *oh)
/* Check for gap in new null message's chunk */
if(oh->chunk[old_chunkno].gap > 0) {
/* Eliminate the gap in the chunk */
- if(H5O_eliminate_gap(oh, &oh->mesg[new_null_msg],
+ if(H5O_eliminate_gap(oh, &oh->mesg[new_null_msg],
((oh->chunk[old_chunkno].image + oh->chunk[old_chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[old_chunkno].gap)),
oh->chunk[old_chunkno].gap) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTREMOVE, FAIL, "can't eliminate gap in chunk")
@@ -1316,7 +1498,7 @@ H5O_move_msgs_forward(H5O_t *oh)
} while(packed_msg);
/* Set return value */
- ret_value = did_packing;
+ ret_value = (htri_t)did_packing;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1338,13 +1520,13 @@ done:
*-------------------------------------------------------------------------
*/
static htri_t
-H5O_merge_null(H5O_t *oh)
+H5O_merge_null(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
{
hbool_t merged_msg; /* Flag to indicate that messages were merged */
hbool_t did_merging = FALSE; /* Whether any messages were merged */
htri_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_merge_null)
+ FUNC_ENTER_NOAPI_NOINIT(H5O_merge_null)
/* check args */
HDassert(oh != NULL);
@@ -1407,6 +1589,11 @@ H5O_merge_null(H5O_t *oh)
/* (Don't bother reducing size of message array for now -QAK) */
oh->nmesgs--;
+ /* If the merged message is too large, shrink the chunk */
+ if(curr_msg->raw_size >= H5O_MESG_MAX_SIZE)
+ if(H5O_alloc_shrink_chunk(f, oh, dxpl_id, curr_msg->chunkno) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "unable to shrink chunk")
+
/* Get out of loop */
break;
} /* end if */
@@ -1425,8 +1612,9 @@ H5O_merge_null(H5O_t *oh)
} while(merged_msg);
/* Set return value */
- ret_value = did_merging;
+ ret_value = (htri_t)did_merging;
+done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5O_merge_null() */
@@ -1486,12 +1674,7 @@ H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
for(v = 0, cont_msg = &oh->mesg[0]; v < oh->nmesgs; v++, cont_msg++) {
if(H5O_CONT_ID == cont_msg->type->id) {
/* Decode current continuation message if necessary */
- if(NULL == cont_msg->native) {
- HDassert(H5O_MSG_CONT->decode);
- cont_msg->native = (H5O_MSG_CONT->decode)(f, dxpl_id, 0, cont_msg->raw);
- if(NULL == cont_msg->native)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message")
- } /* end if */
+ H5O_LOAD_NATIVE(f, dxpl_id, 0, oh, cont_msg, FAIL)
/* Check for correct chunk to delete */
if(oh->chunk[null_msg->chunkno].addr == ((H5O_cont_t *)(cont_msg->native))->addr)
@@ -1515,7 +1698,7 @@ H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
*/
/* Free memory for chunk image */
- H5FL_BLK_FREE(chunk_image, oh->chunk[null_msg->chunkno].image);
+ (void)H5FL_BLK_FREE(chunk_image, oh->chunk[null_msg->chunkno].image);
/* Remove chunk from list of chunks */
if(null_msg->chunkno < (oh->nchunks - 1))
@@ -1552,12 +1735,7 @@ H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
/* Check for continuation message */
if(H5O_CONT_ID == curr_msg->type->id) {
/* Decode current continuation message if necessary */
- if(NULL == curr_msg->native) {
- HDassert(H5O_MSG_CONT->decode);
- curr_msg->native = (H5O_MSG_CONT->decode)(f, dxpl_id, 0, curr_msg->raw);
- if(NULL == curr_msg->native)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message")
- } /* end if */
+ H5O_LOAD_NATIVE(f, dxpl_id, 0, oh, curr_msg, FAIL)
/* Check for pointer to chunk after deleted chunk */
if(((H5O_cont_t *)(curr_msg->native))->chunkno > deleted_chunkno)
@@ -1577,7 +1755,7 @@ H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
} while(deleted_chunk);
/* Set return value */
- ret_value = did_deleting;
+ ret_value = (htri_t)did_deleting;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1596,6 +1774,11 @@ done:
* koziol@ncsa.uiuc.edu
* Oct 4 2005
*
+ * Modifications:
+ * Feb. 2009: Vailin Choi
+ * Add 2 more parameters to H5O_move_msgs_forward() for moving
+ * messages forward into "continuation" message
+ *
*-------------------------------------------------------------------------
*/
herr_t
@@ -1616,14 +1799,14 @@ H5O_condense_header(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
rescan_header = FALSE;
/* Scan for messages that can be moved earlier in chunks */
- result = H5O_move_msgs_forward(oh);
+ result = H5O_move_msgs_forward(f, oh, dxpl_id);
if(result < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "can't move header messages forward")
if(result > 0)
rescan_header = TRUE;
/* Scan for adjacent null messages & merge them */
- result = H5O_merge_null(oh);
+ result = H5O_merge_null(f, oh, dxpl_id);
if(result < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "can't pack null header messages")
if(result > 0)
@@ -1644,3 +1827,184 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5O_condense_header() */
+
+/*-------------------------------------------------------------------------
+ *
+ * Function: H5O_alloc_shrink_chunk
+ *
+ * Purpose: Shrinks a chunk, removing all null messages and any gap.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * nfortne2@hdfgroup.org
+ * Oct 20 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_alloc_shrink_chunk(H5F_t *f,
+ H5O_t *oh,
+ hid_t dxpl_id,
+ unsigned chunkno)
+{
+ H5O_chunk_t *chunk = &oh->chunk[chunkno]; /* Chunk to shrink */
+ H5O_mesg_t *curr_msg;
+ uint8_t *old_image = chunk->image; /* Old address of chunk's image in memory */
+ size_t old_size = chunk->size; /* Old size of chunk */
+ size_t new_size = chunk->size - chunk->gap; /* Size of shrunk chunk */
+ size_t total_msg_size; /* Size of the messages in this chunk */
+ size_t min_chunk_size = H5O_ALIGN_OH(oh, H5O_MIN_SIZE); /* Minimum chunk size */
+ size_t sizeof_chksum = H5O_SIZEOF_CHKSUM_OH(oh); /* Size of chunk checksum */
+ size_t sizeof_msghdr = H5O_SIZEOF_MSGHDR_OH(oh); /* Size of message header */
+ uint8_t new_size_flags = 0; /* New chunk #0 size flags */
+ hbool_t adjust_size_flags = FALSE; /* Whether to adjust the chunk #0 size flags */
+ size_t less_prfx_size = 0; /* Bytes removed from object header prefix */
+ herr_t ret_value = SUCCEED; /* Return value */
+ unsigned u; /* Index */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_alloc_shrink_chunk)
+
+ /* check args */
+ HDassert(f != NULL);
+
+ /* Loop backwards to increase the chance of seeing more null messages at the
+ * end of the chunk. Note that we rely on unsigned u wrapping around at the
+ * end.
+ */
+ for (u = oh->nmesgs - 1, curr_msg = &oh->mesg[u]; u < oh->nmesgs; u--, curr_msg--) {
+ if ((H5O_NULL_ID == curr_msg->type->id) && (chunkno == curr_msg->chunkno)) {
+ size_t shrink_size = curr_msg->raw_size + sizeof_msghdr; /* Amount to shrink the chunk by */
+
+ /* If the current message is not at the end of the chunk, copy the
+ * data after it (except the checksum).
+ */
+ if (curr_msg->raw + curr_msg->raw_size
+ < old_image + new_size - sizeof_chksum) {
+ unsigned v; /* Index */
+ H5O_mesg_t *curr_msg2;
+ uint8_t *src = curr_msg->raw + curr_msg->raw_size; /* Source location */
+
+ /* Slide down the raw data */
+ HDmemmove(curr_msg->raw - sizeof_msghdr, src,
+ (size_t)(old_image + new_size - sizeof_chksum - src));
+
+ /* Update the raw data pointers for messages after this one */
+ for (v = 0, curr_msg2 = &oh->mesg[0]; v < oh->nmesgs; v++, curr_msg2++)
+ if ((chunkno == curr_msg2->chunkno) && (curr_msg2->raw > curr_msg->raw))
+ curr_msg2->raw -= shrink_size;
+ } /* end if */
+
+ /* Adjust the new chunk size */
+ new_size -= shrink_size;
+
+ /* Release any information/memory for the message */
+ H5O_msg_free_mesg(curr_msg);
+
+ /* Remove the deleted null message from list of messages */
+ if (u < (oh->nmesgs - 1))
+ HDmemmove(&oh->mesg[u], &oh->mesg[u+1], ((oh->nmesgs - 1) - u) * sizeof(H5O_mesg_t));
+
+ /* Decrement # of messages */
+ /* (Don't bother reducing size of message array for now) */
+ oh->nmesgs--;
+ } /* end if */
+ } /* end for */
+
+ /* Check if the chunk is too small, extend if necessary */
+ total_msg_size = new_size - (chunkno == 0 ? H5O_SIZEOF_HDR(oh) : H5O_SIZEOF_CHKHDR_OH(oh));
+ if(total_msg_size < min_chunk_size) {
+ HDassert(oh->alloc_nmesgs > oh->nmesgs);
+ oh->nmesgs++;
+
+ /* Initialize new null message to make the chunk large enough */
+ oh->mesg[oh->nmesgs].type = H5O_MSG_NULL;
+ oh->mesg[oh->nmesgs].dirty = TRUE;
+ oh->mesg[oh->nmesgs].native = NULL;
+ oh->mesg[oh->nmesgs].raw = old_image + new_size + sizeof_msghdr - sizeof_chksum;
+ oh->mesg[oh->nmesgs].raw_size = MAX(H5O_ALIGN_OH(oh, min_chunk_size - total_msg_size),
+ sizeof_msghdr) - sizeof_msghdr;
+ oh->mesg[oh->nmesgs].chunkno = chunkno;
+
+ /* update the new chunk size */
+ new_size += oh->mesg[oh->nmesgs].raw_size + sizeof_msghdr;
+ }
+
+ /* Check for changing the chunk #0 data size enough to need adjusting the flags */
+ if(oh->version > H5O_VERSION_1 && chunkno == 0) {
+ uint64_t chunk0_newsize = new_size - H5O_SIZEOF_HDR(oh); /* New size of chunk 0's data */
+ size_t orig_prfx_size = 1 << (oh->flags & H5O_HDR_CHUNK0_SIZE); /* Original prefix size */
+
+ /* Check for moving to a 1-byte size encoding */
+ if (orig_prfx_size > 1 && chunk0_newsize <= 255) {
+ less_prfx_size = orig_prfx_size - 1;
+ new_size_flags = H5O_HDR_CHUNK0_1;
+ adjust_size_flags = TRUE;
+ } /* end if */
+ /* Check for moving to a 2-byte size encoding */
+ else if (orig_prfx_size > 2 && chunk0_newsize <= 65535) {
+ less_prfx_size = orig_prfx_size - 2;
+ new_size_flags = H5O_HDR_CHUNK0_2;
+ adjust_size_flags = TRUE;
+ } /* end if */
+ /* Check for moving to a 4-byte size encoding */
+ else if (orig_prfx_size > 4 && chunk0_newsize <= 4294967295) {
+ less_prfx_size = orig_prfx_size - 4;
+ new_size_flags = H5O_HDR_CHUNK0_4;
+ adjust_size_flags = TRUE;
+ } /* end if */
+ } /* end if */
+
+ if(adjust_size_flags) {
+ /* Adjust object header prefix flags */
+ oh->flags &= ~H5O_HDR_CHUNK0_SIZE;
+ oh->flags |= new_size_flags;
+
+ /* Slide chunk 0 data down */
+ HDmemmove(chunk->image + H5O_SIZEOF_HDR(oh) - sizeof_chksum,
+ chunk->image + H5O_SIZEOF_HDR(oh) - sizeof_chksum + less_prfx_size,
+ new_size - H5O_SIZEOF_HDR(oh));
+
+ /* Adjust chunk size */
+ new_size -= less_prfx_size;
+ } /* end if */
+
+ /* Allocate less memory space for chunk's image */
+ chunk->size = new_size;
+ chunk->image = H5FL_BLK_REALLOC(chunk_image, old_image, chunk->size);
+ chunk->gap = 0;
+ chunk->dirty = TRUE;
+ if (NULL == oh->chunk[chunkno].image)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Spin through existing messages, adjusting them */
+ for (u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
+ if (adjust_size_flags || (chunk->image != old_image))
+ /* Adjust raw addresses for messages in this chunk to reflect new 'image' address */
+ if (curr_msg->chunkno == chunkno)
+ curr_msg->raw = chunk->image - less_prfx_size + (curr_msg->raw - old_image);
+
+ /* Find continuation message which points to this chunk and adjust chunk's size */
+ /* (Chunk 0 doesn't have a continuation message that points to it and
+ * its size is directly encoded in the object header) */
+ if (chunkno > 0 && (H5O_CONT_ID == curr_msg->type->id) &&
+ (((H5O_cont_t *)(curr_msg->native))->chunkno == chunkno)) {
+ /* Adjust size of continuation message */
+ HDassert(((H5O_cont_t *)(curr_msg->native))->size == old_size);
+ ((H5O_cont_t *)(curr_msg->native))->size = chunk->size;
+
+ /* Flag continuation message as dirty */
+ curr_msg->dirty = TRUE;
+ } /* end if */
+ } /* end for */
+
+ HDassert(new_size <= old_size);
+
+ /* Free the unused space in the file */
+ if (H5MF_xfree(f, H5FD_MEM_OHDR, dxpl_id, chunk->addr + new_size, (hsize_t)(old_size - new_size)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to shrink object header chunk")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_alloc_shrink_chunk() */
+
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index 4bfeb3d..ad068ad 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -20,17 +20,15 @@
#include "H5private.h" /* Generic Functions */
#include "H5Apkg.h" /* Attributes */
-#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
-#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
#include "H5Spkg.h" /* Dataspaces */
-#include "H5SMprivate.h" /* Shared Object Header Messages */
/* PRIVATE PROTOTYPES */
static herr_t H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg);
-static void *H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_attr_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static void *H5O_attr_copy(const void *_mesg, void *_dest);
static size_t H5O_attr_size(const H5F_t *f, const void *_mesg);
static herr_t H5O_attr_free(void *mesg);
@@ -123,8 +121,8 @@ H5FL_EXTERN(H5S_extent_t);
function using malloc() and is returned to the caller.
--------------------------------------------------------------------------*/
static void *
-H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_attr_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned UNUSED mesg_flags,
+ unsigned *ioflags, const uint8_t *p)
{
H5A_t *attr = NULL;
H5S_extent_t *extent; /*extent dimensionality information */
@@ -173,7 +171,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
* as well as some reserved bytes.
*/
if(attr->shared->version >= H5O_ATTR_VERSION_3)
- attr->shared->encoding = *p++;
+ attr->shared->encoding = (H5T_cset_t)*p++;
/* Decode and store the name */
if(NULL == (attr->shared->name = H5MM_strdup((const char *)p)))
@@ -184,7 +182,8 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
p += name_len; /* advance the memory pointer */
/* Decode the attribute's datatype */
- if((attr->shared->dt = (H5T_t *)(H5O_MSG_DTYPE->decode)(f, dxpl_id, ((flags & H5O_ATTR_FLAG_TYPE_SHARED) ? H5O_MSG_FLAG_SHARED : 0), p)) == NULL)
+ if(NULL == (attr->shared->dt = (H5T_t *)(H5O_MSG_DTYPE->decode)(f, dxpl_id, open_oh,
+ ((flags & H5O_ATTR_FLAG_TYPE_SHARED) ? H5O_MSG_FLAG_SHARED : 0), ioflags, p)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype")
if(attr->shared->version < H5O_ATTR_VERSION_2)
p += H5O_ALIGN_OLD(attr->shared->dt_size);
@@ -198,14 +197,15 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Decode attribute's dataspace extent */
- if((extent = (H5S_extent_t *)(H5O_MSG_SDSPACE->decode)(f, dxpl_id, ((flags & H5O_ATTR_FLAG_SPACE_SHARED) ? H5O_MSG_FLAG_SHARED : 0), p)) == NULL)
+ if((extent = (H5S_extent_t *)(H5O_MSG_SDSPACE->decode)(f, dxpl_id, open_oh,
+ ((flags & H5O_ATTR_FLAG_SPACE_SHARED) ? H5O_MSG_FLAG_SHARED : 0), ioflags, p)) == NULL)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute dataspace")
/* Copy the extent information to the dataspace */
HDmemcpy(&(attr->shared->ds->extent), extent, sizeof(H5S_extent_t));
/* Release temporary extent information */
- H5FL_FREE(H5S_extent_t, extent);
+ (void)H5FL_FREE(H5S_extent_t, extent);
/* Default to entire dataspace being selected */
if(H5S_select_all(attr->shared->ds, FALSE) < 0)
@@ -226,10 +226,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
HDmemcpy(attr->shared->data, p, attr->shared->data_size);
} /* end if */
- /* Indicate that the fill values aren't to be written out */
- attr->shared->initialized = 1;
-
- /* Increment the reference count for this object header message in cache(compact
+ /* Increment the reference count for this object header message in cache(compact
storage) or for the object from dense storage. */
attr->shared->nrefs++;
@@ -237,6 +234,21 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
ret_value = attr;
done:
+ if(NULL == ret_value) {
+ if(attr) {
+ if(attr->shared) {
+ /* Free any dynamicly allocated items */
+ if(H5A_free(attr) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't release attribute info")
+
+ /* Destroy shared attribute struct */
+ attr->shared = H5FL_FREE(H5A_shared_t, attr->shared);
+ } /* end if */
+ } /* end if */
+
+ attr = H5FL_FREE(H5A_t, attr);
+ } /* end if */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_attr_decode() */
@@ -459,14 +471,14 @@ H5O_attr_size(const H5F_t UNUSED *f, const void *_mesg)
* Modification:Raymond Lu
* 25 June 2008
* Made this function empty. The freeing action is actually
- * done in H5O_attr_free (see H5O_msg_free_real). But this
- * empty reset function needs to be here. Otherwise, the
- * caller function H5O_msg_reset_real will zero-set the whole
+ * done in H5O_attr_free (see H5O_msg_free_real). But this
+ * empty reset function needs to be here. Otherwise, the
+ * caller function H5O_msg_reset_real will zero-set the whole
* message.
*-------------------------------------------------------------------------
*/
herr_t
-H5O_attr_reset(void *_mesg)
+H5O_attr_reset(void UNUSED *_mesg)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_attr_reset)
@@ -636,261 +648,30 @@ H5O_attr_pre_copy_file(H5F_t UNUSED *file_src, const void UNUSED *native_src,
*-------------------------------------------------------------------------
*/
static void *
-H5O_attr_copy_file(H5F_t UNUSED *file_src, const H5O_msg_class_t UNUSED *mesg_type,
+H5O_attr_copy_file(H5F_t *file_src, const H5O_msg_class_t UNUSED *mesg_type,
void *native_src, H5F_t *file_dst, hbool_t *recompute_size,
H5O_copy_t *cpy_info, void UNUSED *udata, hid_t dxpl_id)
{
- H5A_t *attr_src = (H5A_t *)native_src;
- H5A_t *attr_dst = NULL;
-
- /* for dataype conversion */
- hid_t tid_src = -1; /* Datatype ID for source datatype */
- hid_t tid_dst = -1; /* Datatype ID for destination datatype */
- hid_t tid_mem = -1; /* Datatype ID for memory datatype */
- void *buf = NULL; /* Buffer for copying data */
- void *reclaim_buf = NULL; /* Buffer for reclaiming data */
- hid_t buf_sid = -1; /* ID for buffer dataspace */
-
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_attr_copy_file)
/* check args */
- HDassert(attr_src);
+ HDassert(native_src);
HDassert(file_dst);
HDassert(cpy_info);
HDassert(!cpy_info->copy_without_attr);
- /* Allocate space for the destination message */
- if(NULL == (attr_dst = H5FL_CALLOC(H5A_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
- /* Copy the top level of the attribute */
- *attr_dst = *attr_src;
-
- if(NULL == (attr_dst->shared = H5FL_CALLOC(H5A_shared_t)))
- HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared attr structure")
-
- /* Don't have an opened group location for copy */
- H5O_loc_reset(&(attr_dst->shared->oloc));
- H5G_name_reset(&(attr_dst->path));
- attr_dst->obj_opened = FALSE;
-
- /* Reference count for the header message in the cache */
- attr_dst->shared->nrefs = 1;
-
- /* Copy attribute's name */
- attr_dst->shared->name = H5MM_strdup(attr_src->shared->name);
- HDassert(attr_dst->shared->name);
-
- /* Copy attribute's datatype */
- /* (Start destination datatype as transient, even if source is named) */
- attr_dst->shared->dt = H5T_copy(attr_src->shared->dt, H5T_COPY_ALL);
- HDassert(attr_dst->shared->dt);
-
- /* Set the location of the destination datatype */
- if(H5T_set_loc(attr_dst->shared->dt, file_dst, H5T_LOC_DISK) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "cannot mark datatype on disk")
-
- /* Check for named datatype being copied */
- if(H5T_committed(attr_src->shared->dt)) {
- H5O_loc_t *src_oloc; /* Pointer to source datatype's object location */
- H5O_loc_t *dst_oloc; /* Pointer to dest. datatype's object location */
-
- /* Get group entries for source & destination */
- src_oloc = H5T_oloc(attr_src->shared->dt);
- HDassert(src_oloc);
- dst_oloc = H5T_oloc(attr_dst->shared->dt);
- HDassert(dst_oloc);
-
- /* Reset object location for new object */
- H5O_loc_reset(dst_oloc);
- dst_oloc->file = file_dst;
-
- /* Copy the shared object from source to destination */
- if(H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, cpy_info, FALSE) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object")
-
- /* Update shared message info from named datatype info */
- H5T_update_shared(attr_dst->shared->dt);
- } /* end if */
- else {
- /* If the datatype is not named, it may have been shared in the
- * source file's heap. Un-share it for now. We'll try to shared
- * it in the destination file below.
- */
- if(H5O_msg_reset_share(H5O_DTYPE_ID, attr_dst->shared->dt) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to reset datatype sharing")
- } /* end else */
-
- /* Copy the dataspace for the attribute */
- attr_dst->shared->ds = H5S_copy(attr_src->shared->ds, FALSE, FALSE);
- HDassert(attr_dst->shared->ds);
-
- /* Reset the dataspace's sharing in the source file before trying to share
- * it in the destination.
- */
- if(H5O_msg_reset_share(H5O_SDSPACE_ID, attr_dst->shared->ds) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to reset dataspace sharing")
-
-
- /* Try to share both the datatype and dataset. This does nothing if the
- * datatype is committed or sharing is disabled.
- */
- if(H5SM_try_share(file_dst, dxpl_id, NULL, H5O_DTYPE_ID, attr_dst->shared->dt, NULL) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "can't share attribute datatype")
- if(H5SM_try_share(file_dst, dxpl_id, NULL, H5O_SDSPACE_ID, attr_dst->shared->ds, NULL) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "can't share attribute dataspace")
-
- /* Compute the sizes of the datatype and dataspace. This is their raw
- * size unless they're shared.
- */
- attr_dst->shared->dt_size = H5O_msg_raw_size(file_dst, H5O_DTYPE_ID, FALSE, attr_dst->shared->dt);
- HDassert(attr_dst->shared->dt_size > 0);
- attr_dst->shared->ds_size = H5O_msg_raw_size(file_dst, H5O_SDSPACE_ID, FALSE, attr_dst->shared->ds);
- HDassert(attr_dst->shared->ds_size > 0);
-
- /* Check whether to recompute the size of the attribute */
- /* (happens when the datatype or dataspace changes sharing status) */
- if(attr_dst->shared->dt_size != attr_src->shared->dt_size || attr_dst->shared->ds_size != attr_src->shared->ds_size)
- *recompute_size = TRUE;
-
- /* Compute the size of the data */
- H5_ASSIGN_OVERFLOW(attr_dst->shared->data_size, H5S_GET_EXTENT_NPOINTS(attr_dst->shared->ds) * H5T_get_size(attr_dst->shared->dt), hsize_t, size_t);
-
- /* Copy (& convert) the data, if necessary */
- if(attr_src->shared->data) {
- if(NULL == (attr_dst->shared->data = H5FL_BLK_MALLOC(attr_buf, attr_dst->shared->data_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
- /* Check if we need to convert data */
- if(H5T_detect_class(attr_src->shared->dt, H5T_VLEN) > 0) {
- H5T_path_t *tpath_src_mem, *tpath_mem_dst; /* Datatype conversion paths */
- H5T_t *dt_mem; /* Memory datatype */
- size_t src_dt_size; /* Source datatype size */
- size_t tmp_dt_size; /* Temp. datatype size */
- size_t max_dt_size; /* Max atatype size */
- H5S_t *buf_space; /* Dataspace describing buffer */
- hsize_t buf_dim; /* Dimension for buffer */
- size_t nelmts; /* Number of elements in buffer */
- size_t buf_size; /* Size of copy buffer */
-
- /* Create datatype ID for src datatype */
- if((tid_src = H5I_register(H5I_DATATYPE, attr_src->shared->dt)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register source file datatype")
-
- /* create a memory copy of the variable-length datatype */
- if(NULL == (dt_mem = H5T_copy(attr_src->shared->dt, H5T_COPY_TRANSIENT)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy")
- if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register memory datatype")
-
- /* create variable-length datatype at the destinaton file */
- if((tid_dst = H5I_register(H5I_DATATYPE, attr_dst->shared->dt)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register destination file datatype")
-
- /* Set up the conversion functions */
- if(NULL == (tpath_src_mem = H5T_path_find(attr_src->shared->dt, dt_mem, NULL, NULL, dxpl_id, FALSE)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to convert between src and mem datatypes")
- if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, attr_dst->shared->dt, NULL, NULL, dxpl_id, FALSE)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to convert between mem and dst datatypes")
-
- /* Determine largest datatype size */
- if(0 == (src_dt_size = H5T_get_size(attr_src->shared->dt)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to determine datatype size")
- if(0 == (tmp_dt_size = H5T_get_size(dt_mem)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to determine datatype size")
- max_dt_size = MAX(src_dt_size, tmp_dt_size);
- if(0 == (tmp_dt_size = H5T_get_size(attr_dst->shared->dt)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to determine datatype size")
- max_dt_size = MAX(max_dt_size, tmp_dt_size);
-
- /* Set number of whole elements that fit in buffer */
- if(0 == (nelmts = attr_src->shared->data_size / src_dt_size))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "element size too large")
-
- /* Set up number of bytes to copy, and initial buffer size */
- buf_size = nelmts * max_dt_size;
-
- /* Create dataspace for number of elements in buffer */
- buf_dim = nelmts;
-
- /* Create the space and set the initial extent */
- if(NULL == (buf_space = H5S_create_simple((unsigned)1, &buf_dim, NULL)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, NULL, "can't create simple dataspace")
-
- /* Atomize */
- if((buf_sid = H5I_register(H5I_DATASPACE, buf_space)) < 0) {
- H5S_close(buf_space);
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, NULL, "unable to register dataspace ID")
- } /* end if */
-
- /* Allocate memory for recclaim buf */
- if(NULL == (reclaim_buf = H5FL_BLK_MALLOC(attr_buf, buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation NULLed for raw data chunk")
-
- /* Allocate memory for copying the chunk */
- if(NULL == (buf = H5FL_BLK_MALLOC(attr_buf, buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation NULLed for raw data chunk")
-
- HDmemcpy(buf, attr_src->shared->data, attr_src->shared->data_size);
-
- /* Convert from source file to memory */
- if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "datatype conversion NULLed")
-
- HDmemcpy(reclaim_buf, buf, buf_size);
-
- /* Convert from memory to destination file */
- if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "datatype conversion NULLed")
+ /* Mark datatype as being on disk now. This step used to be done in a lower level
+ * by H5O_dtype_decode. But it has been moved up. Not an ideal place, but no better
+ * place than here. */
+ if(H5T_set_loc(((H5A_t *)native_src)->shared->dt, file_src, H5T_LOC_DISK) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "invalid datatype location")
- HDmemcpy(attr_dst->shared->data, buf, attr_dst->shared->data_size);
-
- if(H5D_vlen_reclaim(tid_mem, buf_space, H5P_DATASET_XFER_DEFAULT, reclaim_buf) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_BADITER, NULL, "unable to reclaim variable-length data")
- } /* end if */
- else {
- HDassert(attr_dst->shared->data_size == attr_src->shared->data_size);
- HDmemcpy(attr_dst->shared->data, attr_src->shared->data, attr_src->shared->data_size);
- } /* end else */
- } /* end if(attr_src->shared->data) */
-
- /* Recompute the version to encode the destination attribute */
- if(H5A_set_version(file_dst, attr_dst) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, NULL, "unable to update attribute version")
-
- /* Indicate that the fill values aren't to be written out */
- attr_dst->shared->initialized = TRUE;
-
- /* Set return value */
- ret_value = attr_dst;
+ if ( NULL == (ret_value=H5A_attr_copy_file((H5A_t *)native_src, file_dst, recompute_size, cpy_info, dxpl_id)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "can't copy attribute")
done:
- if(buf_sid > 0)
- if(H5I_dec_ref(buf_sid) < 0)
- HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary dataspace ID")
- if(tid_src > 0)
- /* Don't decrement ID, we want to keep underlying datatype */
- if(H5I_remove(tid_src) == NULL)
- HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
- if(tid_dst > 0)
- /* Don't decrement ID, we want to keep underlying datatype */
- if(H5I_remove(tid_dst) == NULL)
- HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
- if(tid_mem > 0)
- /* Decrement the memory datatype ID, it's transient */
- if(H5I_dec_ref(tid_mem) < 0)
- HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
- if(buf)
- buf = H5FL_BLK_FREE(attr_buf, buf);
- if(reclaim_buf)
- reclaim_buf = H5FL_BLK_FREE(attr_buf, reclaim_buf);
-
- /* Release destination attribute information on failure */
- if(!ret_value && attr_dst && H5A_close(attr_dst) < 0)
- HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute")
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5O_attr_copy_file() */
@@ -915,49 +696,14 @@ static herr_t
H5O_attr_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
{
- const H5A_t *attr_src = (const H5A_t *)mesg_src;
- H5A_t *attr_dst = (H5A_t *)mesg_dst;
- H5F_t *file_src = src_oloc->file;
- H5F_t *file_dst = dst_oloc->file;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_attr_post_copy_file)
- /* check args */
- HDassert(attr_src);
- HDassert(file_src);
- HDassert(attr_dst);
- HDassert(file_dst);
-
-
- /* Only need to fix reference attribute with real data being copied to
- * another file.
- */
- if((NULL != attr_src->shared->data) &&
- (H5T_get_class(attr_src->shared->dt, FALSE) == H5T_REFERENCE) &&
- (file_src != file_dst)) {
-
- /* copy object pointed by reference. The current implementation does not
- * deal with nested reference such as reference in a compound structure
- */
-
- /* Check for expanding references */
- if(cpy_info->expand_ref) {
- size_t ref_count;
-
- /* Determine # of reference elements to copy */
- ref_count = attr_dst->shared->data_size / H5T_get_size(attr_dst->shared->dt);
-
- /* Copy objects referenced in source buffer to destination file and set destination elements */
- if(H5O_copy_expand_ref(file_src, attr_src->shared->data, dxpl_id,
- file_dst, attr_dst->shared->data, ref_count, H5T_get_ref_type(attr_src->shared->dt), cpy_info) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy reference attribute")
- } /* end if */
- else
- /* Reset value to zero */
- HDmemset(attr_dst->shared->data, 0, attr_dst->shared->data_size);
- } /* end if */
+ if ( H5A_attr_post_copy_file(src_oloc, (const H5A_t *)mesg_src,
+ dst_oloc, (H5A_t *)mesg_dst, dxpl_id, cpy_info) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "can't copy attribute")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1077,14 +823,11 @@ H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int in
"Character Set of Name:",
s);
HDfprintf(stream, "%*s%-*s %t\n", indent, "", fwidth,
- "Initialized:",
- mesg->shared->initialized);
- HDfprintf(stream, "%*s%-*s %t\n", indent, "", fwidth,
"Object opened:",
mesg->obj_opened);
HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
"Object:",
- mesg->shared->oloc.addr);
+ mesg->oloc.addr);
/* Check for attribute creation order index on the attribute */
if(mesg->shared->crt_idx != H5O_MAX_CRT_ORDER_IDX)
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index 982948f..72f02df 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -138,7 +138,7 @@ typedef struct {
static herr_t H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc,
hid_t dxpl_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t skip,
hsize_t *last_attr, const H5A_attr_iter_op_t *attr_op, void *op_data);
-static htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr,
+static htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr,
const char* name_to_open);
/*********************/
@@ -239,15 +239,16 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr)
/* Check if this object already has attribute information */
if(oh->version > H5O_VERSION_1) {
- hbool_t new_ainfo = FALSE; /* Flag to indicate that the attribute information is new */
-
- if(NULL == H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo)) {
- /* Clear error stack from not finding attribute info */
- H5E_clear_stack(NULL);
+ hbool_t new_ainfo = FALSE; /* Flag to indicate that the attribute information is new */
+ htri_t ainfo_exists; /* Whether the attribute info was retrieved */
+ /* Check for (& retrieve if available) attribute info */
+ if((ainfo_exists = H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
+ if(!ainfo_exists) {
/* Initialize attribute information */
- ainfo.track_corder = (oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) ? TRUE : FALSE;
- ainfo.index_corder = (oh->flags & H5O_HDR_ATTR_CRT_ORDER_INDEXED) ? TRUE : FALSE;
+ ainfo.track_corder = (hbool_t)((oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) ? TRUE : FALSE);
+ ainfo.index_corder = (hbool_t)((oh->flags & H5O_HDR_ATTR_CRT_ORDER_INDEXED) ? TRUE : FALSE);
ainfo.max_crt_idx = 0;
ainfo.corder_bt2_addr = HADDR_UNDEF;
ainfo.nattrs = 0;
@@ -346,10 +347,10 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to create new attribute in header")
} /* end else */
- /* Increment reference count for shared attribute object for the
+ /* Increment reference count for shared attribute object for the
* object handle created by the caller function H5A_create. The count
* for the cached object header has been incremented in the step above
- * (in H5O_msg_append_real). The dense storage doesn't need a count. */
+ * (in H5O_msg_append_real). The dense storage doesn't need a count. */
attr->shared->nrefs += 1;
/* Was new attribute shared? */
@@ -465,7 +466,7 @@ done:
*
* Modification:Raymond Lu
* 23 June 2008
- * If the attribute is in dense storage and has already been
+ * If the attribute is in dense storage and has already been
* opened, make a copy of already opened object to share some
* object information.
*-------------------------------------------------------------------------
@@ -491,22 +492,29 @@ H5O_attr_open_by_name(const H5O_loc_t *loc, const char *name, hid_t dxpl_id)
/* Check for attribute info stored */
ainfo.fheap_addr = HADDR_UNDEF;
- if(oh->version > H5O_VERSION_1 && NULL == H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo))
- /* Clear error stack from not finding attribute info */
- H5E_clear_stack(NULL);
+ if(oh->version > H5O_VERSION_1) {
+ /* Check for (& retrieve if available) attribute info */
+ if(H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "can't check for attribute info message")
+ } /* end if */
/* If found the attribute is already opened, make a copy of it to share the
- object information. If not, open attribute as a new object */
+ * object information. If not, open attribute as a new object
+ */
if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr, name)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "failed in finding opened attribute")
else if(found_open_attr == TRUE) {
if(NULL == (ret_value = H5A_copy(NULL, exist_attr)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "can't copy existing attribute")
- } else {
- if(H5F_addr_defined(ainfo.fheap_addr)) { /* open attribute with dense storage */
+ } /* end else if */
+ else {
+ /* Check for attributes in dense storage */
+ if(H5F_addr_defined(ainfo.fheap_addr)) {
+ /* Open attribute with dense storage */
if(NULL == (ret_value = H5A_dense_open(loc->file, dxpl_id, &ainfo, name)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "can't open attribute")
- } else {
+ } /* end if */
+ else {
H5O_iter_opn_t udata; /* User data for callback */
H5O_mesg_operator_t op; /* Wrapper for operator */
@@ -528,7 +536,12 @@ H5O_attr_open_by_name(const H5O_loc_t *loc, const char *name, hid_t dxpl_id)
HDassert(udata.attr);
ret_value = udata.attr;
} /* end else */
- }
+
+ /* Mark datatype as being on disk now */
+ if(H5T_set_loc(ret_value->shared->dt, loc->file, H5T_LOC_DISK) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "invalid datatype location")
+
+ } /* end else */
done:
if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
@@ -595,12 +608,11 @@ H5A_t *
H5O_attr_open_by_idx(const H5O_loc_t *loc, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, hid_t dxpl_id)
{
+ H5O_t *oh = NULL; /* Object header */
H5A_attr_iter_op_t attr_op; /* Attribute operator */
H5A_t *exist_attr = NULL; /* Opened attribute object */
htri_t found_open_attr = FALSE; /* Whether opened object is found */
H5A_t *ret_value = NULL; /* Return value */
- H5O_t *oh = NULL; /* Object header */
- H5O_ainfo_t ainfo; /* Attribute information for object */
FUNC_ENTER_NOAPI_NOINIT(H5O_attr_open_by_idx)
@@ -615,38 +627,35 @@ H5O_attr_open_by_idx(const H5O_loc_t *loc, H5_index_t idx_type,
if(H5O_attr_iterate_real((hid_t)-1, loc, dxpl_id, idx_type, order, n, NULL, &attr_op, &ret_value) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_BADITER, NULL, "can't locate attribute")
-
/* Protect the object header to iterate over */
if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, NULL, "unable to load object header")
- /* Check for attribute info stored */
- ainfo.fheap_addr = HADDR_UNDEF;
- if(oh->version > H5O_VERSION_1 && NULL == H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo))
- /* Clear error stack from not finding attribute info */
- H5E_clear_stack(NULL);
-
/* Find out whether it has already been opened. If it has, close the object
- * and make a copy of the already opened object to share the object info. */
+ * and make a copy of the already opened object to share the object info.
+ */
if(ret_value) {
- if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr,
- ret_value->shared->name)) < 0)
+ if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr, ret_value->shared->name)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "failed in finding opened attribute")
- /* If found that the attribute is already opened, make a copy of it
- and close the object just opened. */
+ /* If found that the attribute is already opened, make a copy of it
+ * and close the object just opened.
+ */
if(found_open_attr && exist_attr) {
if(H5A_close(ret_value) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, NULL, "can't close attribute")
-
if(NULL == (ret_value = H5A_copy(NULL, exist_attr)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "can't copy existing attribute")
- }
- }
+ } else {
+ /* Mark datatype as being on disk now */
+ if(H5T_set_loc(ret_value->shared->dt, loc->file, H5T_LOC_DISK) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "invalid datatype location")
+ } /* end if */
+ } /* end if */
done:
if(oh && H5AC_unprotect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, NULL, "unable to release object header")
+ HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, NULL, "unable to release object header")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_attr_open_by_idx() */
@@ -659,7 +668,7 @@ done:
* the name. Return the pointer to the object if found.
*
* Return: TRUE: found the already opened object
- * FALSE: didn't find the opened object
+ * FALSE: didn't find the opened object
* FAIL: function failed.
*
* Programmer: Raymond Lu
@@ -667,14 +676,13 @@ done:
*
*-------------------------------------------------------------------------
*/
-static
-htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char* name_to_open)
+static htri_t
+H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char* name_to_open)
{
- htri_t ret_value = FALSE;
- int num_open_attr = 0;
- hid_t *attr_id_list = NULL;
- unsigned long loc_fnum, attr_fnum;
- int i;
+ hid_t *attr_id_list = NULL; /* List of IDs for opened attributes */
+ unsigned long loc_fnum; /* File serial # for object */
+ size_t num_open_attr; /* Number of opened attributes */
+ htri_t ret_value = FALSE; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_attr_find_opened_attr)
@@ -683,39 +691,48 @@ htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char*
HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "can't get file serial number")
/* Count all opened attributes */
- if((num_open_attr = H5F_get_obj_count(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL)) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "can't get number of opened attributes")
+ num_open_attr = H5F_get_obj_count(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, FALSE);
/* Find out whether the attribute has been opened */
- if(num_open_attr) {
- attr_id_list = (hid_t*)H5MM_malloc(num_open_attr*sizeof(hid_t));
+ if(num_open_attr) {
+ size_t u; /* Local index variable */
+
+ /* Allocate space for the attribute ID list */
+ if(NULL == (attr_id_list = (hid_t *)H5MM_malloc(num_open_attr * sizeof(hid_t))))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "unable to allocate memory for attribute ID list")
/* Retrieve the IDs of all opened attributes */
- if(H5F_get_obj_ids(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, num_open_attr, attr_id_list) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't IDs of opened attributes")
+ H5F_get_obj_ids(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, num_open_attr, attr_id_list, FALSE);
- for(i=0; i<num_open_attr; i++) {
- if(NULL == (*attr = (H5A_t *)H5I_object_verify(attr_id_list[i], H5I_ATTR)))
+ /* Iterate over the attributes */
+ for(u = 0; u < num_open_attr; u++) {
+ unsigned long attr_fnum; /* Attributes file serial number */
+
+ /* Get pointer to attribute */
+ if(NULL == (*attr = (H5A_t *)H5I_object_verify(attr_id_list[u], H5I_ATTR)))
HGOTO_ERROR(H5E_ATTR, H5E_BADTYPE, FAIL, "not an attribute")
/* Get file serial number for attribute */
- if(H5F_get_fileno((*attr)->shared->oloc.file, &attr_fnum) < 0)
+ if(H5F_get_fileno((*attr)->oloc.file, &attr_fnum) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "can't get file serial number")
- /* Verify whether it's the right object. The attribute name, object address
- * to which the attribute is attached, and file serial number should all
- * match. */
- if(!strcmp(name_to_open, (*attr)->shared->name) &&
- loc->addr == (*attr)->shared->oloc.addr &&
- loc_fnum == attr_fnum) {
+ /* Verify whether it's the right object. The attribute name, object
+ * address to which the attribute is attached, and file serial
+ * number should all match.
+ */
+ if(!HDstrcmp(name_to_open, (*attr)->shared->name) &&
+ loc->addr == (*attr)->oloc.addr &&
+ loc_fnum == attr_fnum) {
ret_value = TRUE;
break;
- }
- }
- H5MM_free(attr_id_list);
- }
+ } /* end if */
+ } /* end for */
+ } /* end if */
done:
+ if(attr_id_list)
+ H5MM_free(attr_id_list);
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_attr_find_opened_attr */
@@ -811,7 +828,7 @@ done:
* Modification:Raymond Lu
* 4 June 2008
* Took out the data copying part because the attribute data
- * is shared between attribute handle and object header.
+ * is shared between attribute handle and object header.
*-------------------------------------------------------------------------
*/
static herr_t
@@ -885,9 +902,11 @@ H5O_attr_write(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr)
/* Check for attribute info stored */
ainfo.fheap_addr = HADDR_UNDEF;
- if(oh->version > H5O_VERSION_1 && NULL == H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo))
- /* Clear error stack from not finding attribute info */
- H5E_clear_stack(NULL);
+ if(oh->version > H5O_VERSION_1) {
+ /* Check for (& retrieve if available) attribute info */
+ if(H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
+ } /* end if */
/* Check for attributes stored densely */
if(H5F_addr_defined(ainfo.fheap_addr)) {
@@ -1023,7 +1042,7 @@ H5O_attr_rename_mod_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
/* Check for shared message */
if(mesg->flags & H5O_MSG_FLAG_SHARED) {
/* Update the shared attribute in the SOHM storage */
- if(H5O_attr_update_shared(udata->f, udata->dxpl_id, oh, mesg->native, NULL) < 0)
+ if(H5O_attr_update_shared(udata->f, udata->dxpl_id, oh, (H5A_t *)mesg->native, NULL) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, H5_ITER_ERROR, "unable to update attribute in shared storage")
} /* end if */
else {
@@ -1035,7 +1054,7 @@ H5O_attr_rename_mod_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
old_version != ((H5A_t *)mesg->native)->shared->version) {
H5A_t *attr; /* Attribute to re-add */
- /* Take ownership of the message's native info (the attribute)
+ /* Take ownership of the message's native info (the attribute)
* so any shared objects in the file aren't adjusted (and
* possibly deleted) when the message is released.
*/
@@ -1117,9 +1136,11 @@ H5O_attr_rename(const H5O_loc_t *loc, hid_t dxpl_id, const char *old_name,
/* Check for attribute info stored */
ainfo.fheap_addr = HADDR_UNDEF;
- if(oh->version > H5O_VERSION_1 && NULL == H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo))
- /* Clear error stack from not finding attribute info */
- H5E_clear_stack(NULL);
+ if(oh->version > H5O_VERSION_1) {
+ /* Check for (& retrieve if available) attribute info */
+ if(H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
+ } /* end if */
/* Check for attributes stored densely */
if(H5F_addr_defined(ainfo.fheap_addr)) {
@@ -1210,9 +1231,11 @@ H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id,
/* Check for attribute info stored */
ainfo.fheap_addr = HADDR_UNDEF;
- if(oh->version > H5O_VERSION_1 && NULL == H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo))
- /* Clear error stack from not finding attribute info */
- H5E_clear_stack(NULL);
+ if(oh->version > H5O_VERSION_1) {
+ /* Check for (& retrieve if available) attribute info */
+ if(H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
+ } /* end if */
/* Check for attributes stored densely */
if(H5F_addr_defined(ainfo.fheap_addr)) {
@@ -1226,8 +1249,7 @@ H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id,
oh = NULL;
/* Iterate over attributes in dense storage */
- if((ret_value = H5A_dense_iterate(loc->file, dxpl_id, loc_id, &ainfo,
- idx_type, order, skip, last_attr, attr_op, op_data)) < 0)
+ if((ret_value = H5A_dense_iterate(loc->file, dxpl_id, loc_id, &ainfo, idx_type, order, skip, last_attr, attr_op, op_data)) < 0)
HERROR(H5E_ATTR, H5E_BADITER, "error iterating over attributes");
} /* end if */
else {
@@ -1310,9 +1332,9 @@ done:
*
* Modification:Raymond Lu
* 24 June 2008
- * When converting storage from dense to compact, if found
- * the attribute is already opened, use the opened message
- * to insert. If not, still use the message in the attribute
+ * When converting storage from dense to compact, if found
+ * the attribute is already opened, use the opened message
+ * to insert. If not, still use the message in the attribute
* table. This will guarantee that the attribute message is
* shared between the object in metadata cache and the opened
* object.
@@ -1377,14 +1399,14 @@ H5O_attr_remove_update(const H5O_loc_t *loc, H5O_t *oh, H5O_ainfo_t *ainfo,
(atable.attrs[u])->sh_loc.type = H5O_SHARE_TYPE_UNSHARED;
} /* end else */
- /* Insert attribute message into object header (Will increment
+ /* Insert attribute message into object header (Will increment
reference count on shared attributes) */
/* Find out whether the attribute has been opened */
if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr, (atable.attrs[u])->shared->name)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "failed in finding opened attribute")
/* If found the attribute is already opened, use the opened message to insert.
- If not, still use the message in the attribute table. */
+ If not, still use the message in the attribute table. */
if(found_open_attr && exist_attr) {
if(H5O_msg_append_real(loc->file, dxpl_id, oh, H5O_MSG_ATTR, 0, 0, exist_attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't create message")
@@ -1488,7 +1510,7 @@ H5O_attr_remove(const H5O_loc_t *loc, const char *name, hid_t dxpl_id)
{
H5O_t *oh = NULL; /* Pointer to actual object header */
H5O_ainfo_t ainfo; /* Attribute information for object */
- H5O_ainfo_t *ainfo_ptr = NULL; /* Pointer to attribute information for object */
+ htri_t ainfo_exists = FALSE; /* Whether the attribute info exists in the file */
unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for object header */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1504,9 +1526,11 @@ H5O_attr_remove(const H5O_loc_t *loc, const char *name, hid_t dxpl_id)
/* Check for attribute info stored */
ainfo.fheap_addr = HADDR_UNDEF;
- if(oh->version > H5O_VERSION_1 && NULL == (ainfo_ptr = H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo)))
- /* Clear error stack from not finding attribute info */
- H5E_clear_stack(NULL);
+ if(oh->version > H5O_VERSION_1) {
+ /* Check for (& retrieve if available) attribute info */
+ if((ainfo_exists = H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
+ } /* end if */
/* Check for attributes stored densely */
if(H5F_addr_defined(ainfo.fheap_addr)) {
@@ -1536,7 +1560,7 @@ H5O_attr_remove(const H5O_loc_t *loc, const char *name, hid_t dxpl_id)
} /* end else */
/* Update the attribute information after removing an attribute */
- if(ainfo_ptr)
+ if(ainfo_exists)
if(H5O_attr_remove_update(loc, oh, &ainfo, dxpl_id) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update attribute info")
@@ -1574,7 +1598,7 @@ H5O_attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type,
{
H5O_t *oh = NULL; /* Pointer to actual object header */
H5O_ainfo_t ainfo; /* Attribute information for object */
- H5O_ainfo_t *ainfo_ptr = NULL; /* Pointer to attribute information for object */
+ htri_t ainfo_exists = FALSE; /* Whether the attribute info exists in the file */
unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for object header */
H5A_attr_table_t atable = {0, NULL}; /* Table of attributes */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1590,9 +1614,11 @@ H5O_attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type,
/* Check for attribute info stored */
ainfo.fheap_addr = HADDR_UNDEF;
- if(oh->version > H5O_VERSION_1 && NULL == (ainfo_ptr = H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo)))
- /* Clear error stack from not finding attribute info */
- H5E_clear_stack(NULL);
+ if(oh->version > H5O_VERSION_1) {
+ /* Check for (& retrieve if available) attribute info */
+ if((ainfo_exists = H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
+ } /* end if */
/* Check for attributes stored densely */
if(H5F_addr_defined(ainfo.fheap_addr)) {
@@ -1630,7 +1656,7 @@ H5O_attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type,
} /* end else */
/* Update the attribute information after removing an attribute */
- if(ainfo_ptr)
+ if(ainfo_exists)
if(H5O_attr_remove_update(loc, oh, &ainfo, dxpl_id) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update attribute info")
@@ -1663,40 +1689,44 @@ done:
*
*-------------------------------------------------------------------------
*/
-hsize_t
-H5O_attr_count_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
+herr_t
+H5O_attr_count_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hsize_t *nattrs)
{
- hsize_t ret_value; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_attr_count_real)
+ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_count_real)
/* Check arguments */
HDassert(f);
HDassert(oh);
+ HDassert(nattrs);
/* Check for attributes stored densely */
if(oh->version > H5O_VERSION_1) {
+ htri_t ainfo_exists = FALSE; /* Whether the attribute info exists in the file */
H5O_ainfo_t ainfo; /* Attribute information for object */
/* Attempt to get the attribute information from the object header */
- if(H5A_get_ainfo(f, dxpl_id, oh, &ainfo))
- ret_value = ainfo.nattrs;
- else {
- /* Clear error stack from not finding attribute info */
- H5E_clear_stack(NULL);
-
- ret_value = 0;
- } /* end else */
+ if((ainfo_exists = H5A_get_ainfo(f, dxpl_id, oh, &ainfo)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
+ else if(ainfo_exists > 0)
+ *nattrs = ainfo.nattrs;
+ else
+ *nattrs = 0;
} /* end if */
else {
+ hsize_t attr_count; /* Number of attributes found */
unsigned u; /* Local index variable */
/* Loop over all messages, counting the attributes */
- for(u = ret_value = 0; u < oh->nmesgs; u++)
+ attr_count = 0;
+ for(u = 0; u < oh->nmesgs; u++)
if(oh->mesg[u].type == H5O_MSG_ATTR)
- ret_value++;
+ attr_count++;
+ *nattrs = attr_count;
} /* end else */
+done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_attr_count_real */
@@ -1772,9 +1802,11 @@ H5O_attr_exists(const H5O_loc_t *loc, const char *name, hid_t dxpl_id)
/* Check for attribute info stored */
ainfo.fheap_addr = HADDR_UNDEF;
- if(oh->version > H5O_VERSION_1 && NULL == H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo))
- /* Clear error stack from not finding attribute info */
- H5E_clear_stack(NULL);
+ if(oh->version > H5O_VERSION_1) {
+ /* Check for (& retrieve if available) attribute info */
+ if(H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
+ } /* end if */
/* Check for attributes stored densely */
if(H5F_addr_defined(ainfo.fheap_addr)) {
@@ -1799,7 +1831,7 @@ H5O_attr_exists(const H5O_loc_t *loc, const char *name, hid_t dxpl_id)
HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "error checking for existence of attribute")
/* Check that we found the attribute */
- ret_value = udata.found;
+ ret_value = (htri_t)udata.found;
} /* end else */
done:
@@ -1826,6 +1858,8 @@ herr_t
H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info)
{
H5HF_t *fheap = NULL; /* Fractal heap handle */
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
+ H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5O_attr_bh_info, FAIL)
@@ -1837,36 +1871,43 @@ H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info)
/* Attributes are only stored in fractal heap & indexed w/v2 B-tree in later versions */
if(oh->version > H5O_VERSION_1) {
H5O_ainfo_t ainfo; /* Attribute information for object */
+ htri_t ainfo_exists = FALSE; /* Whether the attribute info exists in the file */
+
+ /* Check for (& retrieve if available) attribute info */
+ if((ainfo_exists = H5A_get_ainfo(f, dxpl_id, oh, &ainfo)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
+ else if(ainfo_exists > 0) {
+ /* Check if name index available */
+ if(H5F_addr_defined(ainfo.name_bt2_addr)) {
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo.name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
+ /* Get name index B-tree size */
+ if(H5B2_size(bt2_name, dxpl_id, &(bh_info->index_size)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info")
+ } /* end if */
- /* Check for attribute info stored */
- if(NULL == H5A_get_ainfo(f, dxpl_id, oh, &ainfo))
- /* Clear error stack from not finding attribute info */
- H5E_clear_stack(NULL);
- else {
- /* Get storage size of creation order index, if it's used */
- if(H5F_addr_defined(ainfo.corder_bt2_addr))
- if(H5B2_iterate_size(f, dxpl_id, H5A_BT2_CORDER, ainfo.corder_bt2_addr, &(bh_info->index_size)) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info")
+ /* Check if creation order index available */
+ if(H5F_addr_defined(ainfo.corder_bt2_addr)) {
+ /* Open the creation order index v2 B-tree */
+ if(NULL == (bt2_corder = H5B2_open(f, dxpl_id, ainfo.corder_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index")
- /* Get storage size of name index, if it's used */
- if(H5F_addr_defined(ainfo.name_bt2_addr))
- if(H5B2_iterate_size(f, dxpl_id, H5A_BT2_NAME, ainfo.name_bt2_addr, &(bh_info->index_size)) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info")
+ /* Get creation order index B-tree size */
+ if(H5B2_size(bt2_corder, dxpl_id, &(bh_info->index_size)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info")
+ } /* end if */
/* Get storage size of fractal heap, if it's used */
if(H5F_addr_defined(ainfo.fheap_addr)) {
/* Open the fractal heap for attributes */
if(NULL == (fheap = H5HF_open(f, dxpl_id, ainfo.fheap_addr)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
/* Get heap storage size */
if(H5HF_size(fheap, dxpl_id, &(bh_info->heap_size)) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info")
-
- /* Release the fractal heap */
- if(H5HF_close(fheap, dxpl_id) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
- fheap = NULL;
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info")
} /* end if */
} /* end else */
} /* end if */
@@ -1874,7 +1915,11 @@ H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info)
done:
/* Release resources */
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ HDONE_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap")
+ if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index")
+ if(bt2_corder && H5B2_close(bt2_corder, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for creation order index")
FUNC_LEAVE_NOAPI(ret_value)
} /* H5O_attr_bh_info() */
@@ -1896,8 +1941,9 @@ done:
int
H5O_attr_count(const H5O_loc_t *loc, hid_t dxpl_id)
{
- H5O_t *oh = NULL; /* Pointer to actual object header */
- int ret_value; /* Return value */
+ H5O_t *oh = NULL; /* Pointer to actual object header */
+ hsize_t nattrs; /* Number of attributes */
+ int ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_attr_count)
@@ -1909,7 +1955,11 @@ H5O_attr_count(const H5O_loc_t *loc, hid_t dxpl_id)
HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Retrieve # of attributes on object */
- ret_value = (int)H5O_attr_count_real(loc->file, dxpl_id, oh);
+ if(H5O_attr_count_real(loc->file, dxpl_id, oh, &nattrs) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve attribute count")
+
+ /* Set return value */
+ ret_value = (int)nattrs;
done:
if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
diff --git a/src/H5Obogus.c b/src/H5Obogus.c
index 1233ec0..cee3199 100644
--- a/src/H5Obogus.c
+++ b/src/H5Obogus.c
@@ -38,7 +38,8 @@
#ifdef H5O_ENABLE_BOGUS
/* PRIVATE PROTOTYPES */
-static void *H5O_bogus_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_bogus_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_bogus_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
static size_t H5O_bogus_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
static herr_t H5O_bogus_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream,
@@ -86,8 +87,8 @@ const H5O_msg_class_t H5O_MSG_BOGUS[1] = {{
*-------------------------------------------------------------------------
*/
static void *
-H5O_bogus_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_bogus_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_bogus_t *mesg = NULL;
void *ret_value; /* Return value */
diff --git a/src/H5Obtreek.c b/src/H5Obtreek.c
index e116ff2..99e6bdd 100644
--- a/src/H5Obtreek.c
+++ b/src/H5Obtreek.c
@@ -28,7 +28,8 @@
#include "H5Opkg.h" /* Object headers */
#include "H5MMprivate.h" /* Memory management */
-static void *H5O_btreek_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_btreek_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_btreek_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
static void *H5O_btreek_copy(const void *_mesg, void *_dest);
static size_t H5O_btreek_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
@@ -78,8 +79,8 @@ const H5O_msg_class_t H5O_MSG_BTREEK[1] = {{
*-------------------------------------------------------------------------
*/
static void *
-H5O_btreek_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_btreek_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_btreek_t *mesg; /* Native message */
void *ret_value; /* Return value */
@@ -95,11 +96,11 @@ H5O_btreek_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_fl
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message")
/* Allocate space for message */
- if(NULL == (mesg = H5MM_calloc(sizeof(H5O_btreek_t))))
+ if(NULL == (mesg = (H5O_btreek_t *)H5MM_calloc(sizeof(H5O_btreek_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for v1 B-tree 'K' message")
/* Retrieve non-default B-tree 'K' values */
- UINT16DECODE(p, mesg->btree_k[H5B_ISTORE_ID]);
+ UINT16DECODE(p, mesg->btree_k[H5B_CHUNK_ID]);
UINT16DECODE(p, mesg->btree_k[H5B_SNODE_ID]);
UINT16DECODE(p, mesg->sym_leaf_k);
@@ -137,7 +138,7 @@ H5O_btreek_encode(H5F_t UNUSED *f, hbool_t UNUSED disable_shared, uint8_t *p, co
/* Store version and non-default v1 B-tree 'K' values */
*p++ = H5O_BTREEK_VERSION;
- UINT16ENCODE(p, mesg->btree_k[H5B_ISTORE_ID]);
+ UINT16ENCODE(p, mesg->btree_k[H5B_CHUNK_ID]);
UINT16ENCODE(p, mesg->btree_k[H5B_SNODE_ID]);
UINT16ENCODE(p, mesg->sym_leaf_k);
@@ -171,7 +172,7 @@ H5O_btreek_copy(const void *_mesg, void *_dest)
/* Sanity check */
HDassert(mesg);
- if(!dest && NULL == (dest = H5MM_malloc(sizeof(H5O_btreek_t))))
+ if(!dest && NULL == (dest = (H5O_btreek_t *)H5MM_malloc(sizeof(H5O_btreek_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for shared message table message")
/* All this message requires is a shallow copy */
@@ -210,7 +211,7 @@ H5O_btreek_size(const H5F_t UNUSED *f, hbool_t UNUSED disable_shared, const void
HDassert(f);
ret_value = 1 + /* Version number */
- 2 + /* Indexed storage internal B-tree 'K' value */
+ 2 + /* Chunked storage internal B-tree 'K' value */
2 + /* Symbol table node internal B-tree 'K' value */
2; /* Symbol table node leaf 'K' value */
@@ -246,7 +247,7 @@ H5O_btreek_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE
HDassert(fwidth >= 0);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Indexed storage internal B-tree 'K' value:", mesg->btree_k[H5B_ISTORE_ID]);
+ "Chunked storage internal B-tree 'K' value:", mesg->btree_k[H5B_CHUNK_ID]);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Symbol table node internal B-tree 'K' value:", mesg->btree_k[H5B_SNODE_ID]);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
diff --git a/src/H5Ocache.c b/src/H5Ocache.c
index a2b9a57..0709e60 100644
--- a/src/H5Ocache.c
+++ b/src/H5Ocache.c
@@ -37,6 +37,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5FLprivate.h" /* Free lists */
+#include "H5MFprivate.h" /* File memory management */
#include "H5Opkg.h" /* Object headers */
@@ -97,6 +98,7 @@ const H5AC_class_t H5AC_OHDR[1] = {{
(H5AC_flush_func_t)H5O_flush,
(H5AC_dest_func_t)H5O_dest,
(H5AC_clear_func_t)H5O_clear,
+ (H5AC_notify_func_t)NULL,
(H5AC_size_func_t)H5O_size,
}};
@@ -130,8 +132,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
unsigned merged_null_msgs = 0; /* Number of null messages merged together */
haddr_t chunk_addr; /* Address of first chunk */
size_t chunk_size; /* Size of first chunk */
- haddr_t abs_eoa; /* Absolute end of file address */
- haddr_t rel_eoa; /* Relative end of file address */
+ haddr_t eoa; /* Relative end of file address */
H5O_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_load)
@@ -143,14 +144,11 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
HDassert(!_udata2);
/* Make certain we don't speculatively read off the end of the file */
- if(HADDR_UNDEF == (abs_eoa = H5F_get_eoa(f)))
+ if(HADDR_UNDEF == (eoa = H5F_get_eoa(f, H5FD_MEM_OHDR)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "unable to determine file size")
- /* Adjust absolute EOA address to relative EOA address */
- rel_eoa = abs_eoa - H5F_get_base_addr(f);
-
/* Compute the size of the speculative object header buffer */
- H5_ASSIGN_OVERFLOW(spec_read_size, MIN(rel_eoa - addr, H5O_SPEC_READ_SIZE), /* From: */ hsize_t, /* To: */ size_t);
+ H5_ASSIGN_OVERFLOW(spec_read_size, MIN(eoa - addr, H5O_SPEC_READ_SIZE), /* From: */ hsize_t, /* To: */ size_t);
/* Attempt to speculatively read both object header prefix and first chunk */
if(H5F_block_read(f, H5FD_MEM_OHDR, addr, spec_read_size, dxpl_id, read_buf) < 0)
@@ -167,9 +165,9 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
/* Check for presence of magic number */
/* (indicates version 2 or later) */
- if(!HDmemcmp(p, H5O_HDR_MAGIC, (size_t)H5O_SIZEOF_MAGIC)) {
+ if(!HDmemcmp(p, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
/* Magic number */
- p += H5O_SIZEOF_MAGIC;
+ p += H5_SIZEOF_MAGIC;
/* Version */
oh->version = *p++;
@@ -189,10 +187,16 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
/* Time fields */
if(oh->flags & H5O_HDR_STORE_TIMES) {
- UINT32DECODE(p, oh->atime);
- UINT32DECODE(p, oh->mtime);
- UINT32DECODE(p, oh->ctime);
- UINT32DECODE(p, oh->btime);
+ uint32_t tmp; /* Temporary value */
+
+ UINT32DECODE(p, tmp);
+ oh->atime = (time_t)tmp;
+ UINT32DECODE(p, tmp);
+ oh->mtime = (time_t)tmp;
+ UINT32DECODE(p, tmp);
+ oh->ctime = (time_t)tmp;
+ UINT32DECODE(p, tmp);
+ oh->btime = (time_t)tmp;
} /* end if */
else
oh->atime = oh->mtime = oh->ctime = oh->btime = 0;
@@ -349,9 +353,9 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
/* Check for magic # on chunks > 0 in later versions of the format */
if(chunkno > 0 && oh->version > H5O_VERSION_1) {
/* Magic number */
- if(HDmemcmp(p, H5O_CHK_MAGIC, (size_t)H5O_SIZEOF_MAGIC))
+ if(HDmemcmp(p, H5O_CHK_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "wrong object header chunk signature")
- p += H5O_SIZEOF_MAGIC;
+ p += H5_SIZEOF_MAGIC;
} /* end if */
/* Decode messages from this chunk */
@@ -415,7 +419,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
#endif /* NDEBUG */
/* Check for combining two adjacent 'null' messages */
- if((H5F_get_intent(f) & H5F_ACC_RDWR) &&
+ if((H5F_INTENT(f) & H5F_ACC_RDWR) &&
H5O_NULL_ID == id && oh->nmesgs > 0 &&
H5O_NULL_ID == oh->mesg[oh->nmesgs - 1].type->id &&
oh->mesg[oh->nmesgs - 1].chunkno == chunkno) {
@@ -468,7 +472,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
/* Check for "mark if unknown" message flag, etc. */
else if((flags & H5O_MSG_FLAG_MARK_IF_UNKNOWN) &&
!(flags & H5O_MSG_FLAG_WAS_UNKNOWN) &&
- (H5F_get_intent(f) & H5F_ACC_RDWR)) {
+ (H5F_INTENT(f) & H5F_ACC_RDWR)) {
/* Mark the message as "unknown" */
/* This is a bit aggressive, since the application may
@@ -505,7 +509,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
HDassert(nullcnt == 0);
/* Set gap information for chunk */
- oh->chunk[chunkno].gap = (eom_ptr - p);
+ oh->chunk[chunkno].gap = (size_t)(eom_ptr - p);
/* Increment location in chunk */
p += oh->chunk[chunkno].gap;
@@ -536,9 +540,10 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
/* Check if next message to examine is a continuation message */
if(H5O_CONT_ID == oh->mesg[curmesg].type->id) {
H5O_cont_t *cont;
+ unsigned ioflags = 0; /* Flags for decode routine */
/* Decode continuation message */
- cont = (H5O_cont_t *)(H5O_MSG_CONT->decode)(f, dxpl_id, 0, oh->mesg[curmesg].raw);
+ cont = (H5O_cont_t *)(H5O_MSG_CONT->decode)(f, dxpl_id, NULL, 0, &ioflags, oh->mesg[curmesg].raw);
cont->chunkno = oh->nchunks; /*the next chunk to allocate */
/* Save 'native' form of continuation message */
@@ -547,14 +552,21 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
/* Set up to read in next chunk */
chunk_addr = cont->addr;
chunk_size = cont->size;
+
+ /* Mark the object header as dirty if the message was changed by decoding */
+ if((ioflags & H5O_DECODEIO_DIRTY) && (H5F_get_intent(f) & H5F_ACC_RDWR)) {
+ oh->mesg[curmesg].dirty = TRUE;
+ oh->cache_info.is_dirty = TRUE;
+ }
} /* end if */
/* Check if next message to examine is a ref. count message */
else if(H5O_REFCOUNT_ID == oh->mesg[curmesg].type->id) {
H5O_refcount_t *refcount;
+ unsigned ioflags = 0; /* Flags for decode routine */
/* Decode ref. count message */
HDassert(oh->version > H5O_VERSION_1);
- refcount = (H5O_refcount_t *)(H5O_MSG_REFCOUNT->decode)(f, dxpl_id, 0, oh->mesg[curmesg].raw);
+ refcount = (H5O_refcount_t *)(H5O_MSG_REFCOUNT->decode)(f, dxpl_id, NULL, 0, &ioflags, oh->mesg[curmesg].raw);
/* Save 'native' form of ref. count message */
oh->mesg[curmesg].native = refcount;
@@ -562,6 +574,12 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
/* Set object header values */
oh->has_refcount_msg = TRUE;
oh->nlink = *refcount;
+
+ /* Mark the object header as dirty if the message was changed by decoding */
+ if((ioflags & H5O_DECODEIO_DIRTY) && (H5F_get_intent(f) & H5F_ACC_RDWR)) {
+ oh->mesg[curmesg].dirty = TRUE;
+ oh->cache_info.is_dirty = TRUE;
+ }
} /* end if */
/* Check if next message to examine is a link message */
else if(H5O_LINK_ID == oh->mesg[curmesg].type->id) {
@@ -592,7 +610,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "corrupt object header - too few messages")
#else /* H5_STRICT_FORMAT_CHECKS */
/* Check for incorrect # of messages in object header and if we have write
- * access on the file, flag the object header as dirty, so it gets fixed.
+ * access on the file, flag the object header as dirty, so it gets fixed.
*/
if(oh->version == H5O_VERSION_1)
if((oh->nmesgs + merged_null_msgs) != nmesgs &&
@@ -662,8 +680,8 @@ H5O_assert(oh);
uint64_t chunk0_size = oh->chunk[0].size - H5O_SIZEOF_HDR(oh); /* Size of chunk 0's data */
/* Verify magic number */
- HDassert(!HDmemcmp(p, H5O_HDR_MAGIC, H5O_SIZEOF_MAGIC));
- p += H5O_SIZEOF_MAGIC;
+ HDassert(!HDmemcmp(p, H5O_HDR_MAGIC, H5_SIZEOF_MAGIC));
+ p += H5_SIZEOF_MAGIC;
/* Version */
*p++ = oh->version;
@@ -689,7 +707,7 @@ H5O_assert(oh);
switch(oh->flags & H5O_HDR_CHUNK0_SIZE) {
case 0: /* 1 byte size */
HDassert(chunk0_size < 256);
- *p++ = chunk0_size;
+ *p++ = (uint8_t)chunk0_size;
break;
case 1: /* 2 byte size */
@@ -740,7 +758,7 @@ H5O_assert(oh);
/* Mark chunk 0 as dirty, since the object header prefix has been updated */
/* (this could be more sophisticated and track whether any prefix fields
- * have been changed, which could save I/O accesses if the
+ * have been changed, which could save I/O accesses if the
* messages in chunk 0 haven't changed - QAK)
*/
HDassert(H5F_addr_eq(addr, oh->chunk[0].addr));
@@ -755,7 +773,7 @@ H5O_assert(oh);
/* Sanity checks */
if(oh->version > H5O_VERSION_1)
/* Make certain the magic # is present */
- HDassert(!HDmemcmp(oh->chunk[u].image, (u == 0 ? H5O_HDR_MAGIC : H5O_CHK_MAGIC), H5O_SIZEOF_MAGIC));
+ HDassert(!HDmemcmp(oh->chunk[u].image, (u == 0 ? H5O_HDR_MAGIC : H5O_CHK_MAGIC), H5_SIZEOF_MAGIC));
else
/* Gaps should never occur in version 1 of the format */
HDassert(oh->chunk[u].gap == 0);
@@ -818,20 +836,37 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_dest(H5F_t UNUSED *f, H5O_t *oh)
+H5O_dest(H5F_t *f, H5O_t *oh)
{
unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_dest)
+ FUNC_ENTER_NOAPI_NOINIT(H5O_dest)
+#ifdef QAK
+HDfprintf(stderr, "%s: oh->cache_info.addr = %a\n", FUNC, oh->cache_info.addr);
+HDfprintf(stderr, "%s: oh->cache_info.free_file_space_on_destroy = %t\n", FUNC, oh->cache_info.free_file_space_on_destroy);
+#endif /* QAK */
/* check args */
HDassert(oh);
/* Verify that node is clean */
- HDassert(oh->cache_info.is_dirty == FALSE);
+ HDassert(!oh->cache_info.is_dirty);
+
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!oh->cache_info.free_file_space_on_destroy || H5F_addr_defined(oh->cache_info.addr));
/* destroy chunks */
if(oh->chunk) {
+ /* Check for releasing file space for object header */
+ if(oh->cache_info.free_file_space_on_destroy) {
+ /* Free main (first) object header "chunk" */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_OHDR, H5AC_dxpl_id, oh->chunk[0].addr, (hsize_t)oh->chunk[0].size) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free object header")
+ } /* end if */
+
+ /* Release buffer for each chunk */
for(u = 0; u < oh->nchunks; u++) {
/* Verify that chunk is clean */
HDassert(oh->chunk[u].dirty == 0);
@@ -839,25 +874,36 @@ H5O_dest(H5F_t UNUSED *f, H5O_t *oh)
oh->chunk[u].image = H5FL_BLK_FREE(chunk_image, oh->chunk[u].image);
} /* end for */
+ /* Release array of chunk info */
oh->chunk = (H5O_chunk_t *)H5FL_SEQ_FREE(H5O_chunk_t, oh->chunk);
} /* end if */
/* destroy messages */
if(oh->mesg) {
for(u = 0; u < oh->nmesgs; u++) {
- /* Verify that message is clean */
- HDassert(oh->mesg[u].dirty == 0);
+ /* Verify that message is clean, unless it could have been marked
+ * dirty by decoding */
+#ifndef NDEBUG
+ if(oh->ndecode_dirtied && oh->mesg[u].dirty)
+ oh->ndecode_dirtied--;
+ else
+ HDassert(oh->mesg[u].dirty == 0);
+#endif /* NDEBUG */
H5O_msg_free_mesg(&oh->mesg[u]);
} /* end for */
+ /* Make sure we accounted for all the messages dirtied by decoding */
+ HDassert(!oh->ndecode_dirtied);
+
oh->mesg = (H5O_mesg_t *)H5FL_SEQ_FREE(H5O_mesg_t, oh->mesg);
} /* end if */
/* destroy object header */
- H5FL_FREE(H5O_t, oh);
+ (void)H5FL_FREE(H5O_t, oh);
- FUNC_LEAVE_NOAPI(SUCCEED)
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_dest() */
@@ -893,6 +939,11 @@ H5O_clear(H5F_t *f, H5O_t *oh, hbool_t destroy)
for(u = 0; u < oh->nmesgs; u++)
oh->mesg[u].dirty = FALSE;
+#ifndef NDEBUG
+ /* Reset the number of messages dirtied by decoding */
+ oh->ndecode_dirtied = 0;
+#endif /* NDEBUG */
+
/* Mark whole header as clean */
oh->cache_info.is_dirty = FALSE;
diff --git a/src/H5Ocont.c b/src/H5Ocont.c
index 92c4a3c..df336dd 100644
--- a/src/H5Ocont.c
+++ b/src/H5Ocont.c
@@ -37,7 +37,8 @@
/* PRIVATE PROTOTYPES */
-static void *H5O_cont_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_cont_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_cont_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
static size_t H5O_cont_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
static herr_t H5O_cont_free(void *mesg);
@@ -89,8 +90,8 @@ H5FL_DEFINE(H5O_cont_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_cont_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_cont_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_cont_t *cont = NULL;
void *ret_value;
@@ -204,7 +205,7 @@ H5O_cont_free(void *mesg)
HDassert(mesg);
- H5FL_FREE(H5O_cont_t, mesg);
+ (void)H5FL_FREE(H5O_cont_t, mesg);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_cont_free() */
diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c
index 14280b3..e0bc7d5 100644
--- a/src/H5Ocopy.c
+++ b/src/H5Ocopy.c
@@ -99,11 +99,11 @@ H5FL_DEFINE(H5O_addr_map_t);
* Purpose: Copy an object (group or dataset) to destination location
* within a file or cross files. PLIST_ID is a property list
* which is used to pass user options and properties to the
- * copy. The name, dst_name, must not already be taken by some
+ * copy. The name, dst_name, must not already be taken by some
* other object in the destination group.
*
* H5Ocopy() will fail if the name of the destination object
- * exists in the destination group. For example,
+ * exists in the destination group. For example,
* H5Ocopy(fid_src, "/dset", fid_dst, "/dset", ...)
* will fail if "/dset" exists in the destination file
*
@@ -113,21 +113,21 @@ H5FL_DEFINE(H5O_addr_map_t);
* the group are copied. Otherwise (default), it will
* recursively copy all objects below the group
* H5O_COPY_EXPAND_SOFT_LINK_FLAG
- * If this flag is specified, it will copy the objects
- * pointed by the soft links. Otherwise (default), it
+ * If this flag is specified, it will copy the objects
+ * pointed by the soft links. Otherwise (default), it
* will copy the soft link as they are
* H5O_COPY_WITHOUT_ATTR_FLAG
- * If this flag is specified, it will copy object without
+ * If this flag is specified, it will copy object without
* copying attributes. Otherwise (default), it will
* copy object along with all its attributes
* H5O_COPY_EXPAND_REFERENCE_FLAG
* 1) Copy object between two different files:
- * When this flag is specified, it will copy objects that
+ * When this flag is specified, it will copy objects that
* are pointed by the references and update the values of
* references in the destination file. Otherwise (default)
* the values of references in the destination will set to
* zero
- * The current implementation does not handle references
+ * The current implementation does not handle references
* inside of other datatype structure. For example, if
* a member of compound datatype is reference, H5Ocopy()
* will copy that field as it is. It will not set the
@@ -138,11 +138,11 @@ H5FL_DEFINE(H5O_addr_map_t);
* Datasets or attributes of references are copied as they
* are, i.e. values of references of the destination object
* are the same as the values of the source object
- *
+ *
* OPTIONS THAT MAY APPLY TO COPY IN THE FUTURE.
* H5O_COPY_EXPAND_EXT_LINK_FLAG
* If this flag is specified, it will expand the external links
- * into new objects, Otherwise (default), it will keep external
+ * into new objects, Otherwise (default), it will keep external
* links as they are (default)
*
* PROPERTIES THAT MAY APPLY TO COPY IN FUTURE
@@ -397,7 +397,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
if(copy_type->pre_copy_file) {
/* Decode the message if necessary. */
- H5O_LOAD_NATIVE(oloc_src->file, dxpl_id, oh_src, mesg_src, FAIL)
+ H5O_LOAD_NATIVE(oloc_src->file, dxpl_id, 0, oh_src, mesg_src, FAIL)
/* Perform "pre copy" operation on message */
if((copy_type->pre_copy_file)(oloc_src->file, mesg_src->native, &(deleted[mesgno]), cpy_info, udata) < 0)
@@ -468,11 +468,11 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
hbool_t recompute_size; /* Whether copy_file callback created a shared message */
/* Decode the message if necessary. */
- H5O_LOAD_NATIVE(oloc_src->file, dxpl_id, oh_src, mesg_src, FAIL)
+ H5O_LOAD_NATIVE(oloc_src->file, dxpl_id, 0, oh_src, mesg_src, FAIL)
/* Copy the source message */
recompute_size = FALSE;
- if((mesg_dst->native = H5O_msg_copy_file(copy_type,
+ if((mesg_dst->native = H5O_msg_copy_file(copy_type,
oloc_src->file, mesg_src->native, oloc_dst->file,
&recompute_size, cpy_info, udata, dxpl_id)) == NULL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
@@ -544,7 +544,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
/* Check if the chunk's data portion is too small */
dst_oh_gap = dst_oh_null = 0;
if(dst_oh_size < H5O_MIN_SIZE) {
- size_t delta = (H5O_MIN_SIZE - dst_oh_size); /* Delta in chunk size needed */
+ size_t delta = (size_t)(H5O_MIN_SIZE - dst_oh_size); /* Delta in chunk size needed */
/* Sanity check */
HDassert((oh_dst->flags & H5O_HDR_CHUNK0_SIZE) == H5O_HDR_CHUNK0_1);
@@ -592,7 +592,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
* header. This will be written when the header is flushed to disk.
*/
if(oh_dst->version > H5O_VERSION_1)
- HDmemcpy(current_pos, H5O_HDR_MAGIC, (size_t)H5O_SIZEOF_MAGIC);
+ HDmemcpy(current_pos, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC);
current_pos += H5O_SIZEOF_HDR(oh_dst) - H5O_SIZEOF_CHKSUM_OH(oh_dst);
/* Loop through destination messages, updating their "raw" info */
@@ -720,7 +720,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
} /* end if */
/* Insert destination object header in cache */
- if(H5AC_set(oloc_dst->file, dxpl_id, H5AC_OHDR, oloc_dst->addr, oh_dst, H5AC__DIRTIED_FLAG) < 0)
+ if(H5AC_set(oloc_dst->file, dxpl_id, H5AC_OHDR, oloc_dst->addr, oh_dst, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header")
oh_dst = NULL;
@@ -862,7 +862,7 @@ H5O_copy_free_addrmap_cb(void *item, void UNUSED *key, void UNUSED *op_data)
HDassert(item);
/* Release the item */
- H5FL_FREE(H5O_addr_map_t, item);
+ (void)H5FL_FREE(H5O_addr_map_t, item);
FUNC_LEAVE_NOAPI(0)
} /* H5O_copy_free_addrmap_cb() */
@@ -915,7 +915,7 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
cpy_info.preserve_null = TRUE;
/* Create a skip list to keep track of which objects are copied */
- if((cpy_info.map_list = H5SL_create(H5SL_TYPE_HADDR, 0.5, (size_t)16)) == NULL)
+ if((cpy_info.map_list = H5SL_create(H5SL_TYPE_HADDR)) == NULL)
HGOTO_ERROR(H5E_SLIST, H5E_CANTCREATE, FAIL, "cannot make skip list")
/* copy the object from the source file to the destination file */
@@ -1002,8 +1002,8 @@ done:
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Peter Cao
- * Aug 7 2006
+ * Programmer: Peter Cao
+ * Aug 7 2006
*
*-------------------------------------------------------------------------
*/
@@ -1037,7 +1037,7 @@ H5O_copy_obj_by_ref(H5O_loc_t *src_oloc, hid_t dxpl_id, H5O_loc_t *dst_oloc,
new_oloc.addr = dst_oloc->addr;
/* Pick a default name for the new object */
- sprintf(tmp_obj_name, "~obj_pointed_by_%llu", (unsigned long_long)dst_oloc->addr);
+ sprintf(tmp_obj_name, "~obj_pointed_by_%llu", (unsigned long long)dst_oloc->addr);
/* Create a link to the newly copied object */
if(H5L_link(dst_root_loc, tmp_obj_name, &new_loc, H5P_DEFAULT, H5P_DEFAULT, dxpl_id) < 0)
@@ -1058,8 +1058,8 @@ done:
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Peter Cao
- * Aug 7 2006
+ * Programmer: Peter Cao
+ * Aug 7 2006
*
*-------------------------------------------------------------------------
*/
@@ -1125,7 +1125,7 @@ H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, hid_t dxpl_id,
uint8_t *buf; /* Buffer to store serialized selection in */
H5HG_t hobjid; /* Heap object ID */
size_t buf_size; /* Length of object in heap */
-
+
/* Making equivalent references in the destination file */
for(i = 0; i < ref_count; i++) {
/* Get the heap ID for the dataset region */
diff --git a/src/H5Odbg.c b/src/H5Odbg.c
index 2fc0b12..b731ce9 100644
--- a/src/H5Odbg.c
+++ b/src/H5Odbg.c
@@ -37,6 +37,7 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
+#include "H5Ppublic.h" /* Property Lists */
/****************/
/* Local Macros */
@@ -127,7 +128,7 @@ H5O_assert(const H5O_t *oh)
/* Version specific checks */
if(oh->version > H5O_VERSION_1) {
/* Make certain that the magic number is correct for each chunk */
- HDassert(!HDmemcmp(oh->chunk[u].image, (u == 0 ? H5O_HDR_MAGIC : H5O_CHK_MAGIC), H5O_SIZEOF_MAGIC));
+ HDassert(!HDmemcmp(oh->chunk[u].image, (u == 0 ? H5O_HDR_MAGIC : H5O_CHK_MAGIC), H5_SIZEOF_MAGIC));
/* Check for valid gap size */
HDassert(oh->chunk[u].gap < (size_t)H5O_SIZEOF_MSGHDR_OH(oh));
@@ -269,12 +270,16 @@ done:
* matzke@llnl.gov
* Aug 6 1997
*
+ * Modifications:
+ * Feb. 2009: Vailin Choi
+ * Fixed bug in the accumulation of chunk_total
+ * Used the appropriate flag when printing creation order tracked/indexed
*-------------------------------------------------------------------------
*/
herr_t
H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, int indent, int fwidth)
{
- size_t mesg_total = 0, chunk_total = 0;
+ size_t mesg_total = 0, chunk_total = 0, gap_total = 0;
unsigned *sequence;
unsigned i; /* Local index variable */
herr_t ret_value = SUCCEED;
@@ -310,10 +315,10 @@ H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, i
/* Display object's status flags */
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
"Attribute creation order tracked:",
- (oh->flags & H5P_CRT_ORDER_TRACKED) ? "Yes" : "No");
+ (oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) ? "Yes" : "No");
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
"Attribute creation order indexed:",
- (oh->flags & H5P_CRT_ORDER_INDEXED) ? "Yes" : "No");
+ (oh->flags & H5O_HDR_ATTR_CRT_ORDER_INDEXED) ? "Yes" : "No");
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
"Attribute storage phase change values:",
(oh->flags & H5O_HDR_ATTR_STORE_PHASE_CHANGE) ? "Non-default" : "Default");
@@ -391,6 +396,7 @@ H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, i
/* Accumulate chunk's size to total */
chunk_total += chunk_size;
+ gap_total += oh->chunk[i].gap;
HDfprintf(stream, "%*s%-*s %Zu\n", indent + 3, "", MAX(0, fwidth - 3),
"Size in bytes:",
@@ -402,7 +408,7 @@ H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, i
} /* end for */
/* debug each message */
- if(NULL == (sequence = H5MM_calloc(NELMTS(H5O_msg_class_g) * sizeof(unsigned))))
+ if(NULL == (sequence = (unsigned *)H5MM_calloc(NELMTS(H5O_msg_class_g) * sizeof(unsigned))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
for(i = 0, mesg_total = 0; i < oh->nmesgs; i++) {
const H5O_msg_class_t *debug_type; /* Type of message to use for callbacks */
@@ -411,6 +417,10 @@ H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, i
/* Accumulate message's size to total */
mesg_total += H5O_SIZEOF_MSGHDR_OH(oh) + oh->mesg[i].raw_size;
+ /* For version 2 object header, add size of "OCHK" for continuation chunk */
+ if (oh->mesg[i].type->id == H5O_CONT_ID)
+ mesg_total += H5O_SIZEOF_CHKHDR_OH(oh);
+
HDfprintf(stream, "%*sMessage %d...\n", indent, "", i);
/* check for bad message id */
@@ -488,7 +498,7 @@ H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, i
/* decode the message */
debug_type = oh->mesg[i].type;
if(NULL == oh->mesg[i].native && debug_type->decode)
- H5O_LOAD_NATIVE(f, dxpl_id, oh, &oh->mesg[i], FAIL)
+ H5O_LOAD_NATIVE(f, dxpl_id, H5O_DECODEIO_NOCHANGE, oh, &oh->mesg[i], FAIL)
/* print the message */
HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
@@ -498,9 +508,9 @@ H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, i
else
HDfprintf(stream, "%*s<No info for this message>\n", indent + 6, "");
} /* end for */
- sequence = H5MM_xfree(sequence);
+ sequence = (unsigned *)H5MM_xfree(sequence);
- if(mesg_total != chunk_total)
+ if((mesg_total + gap_total) != chunk_total)
HDfprintf(stream, "*** TOTAL SIZE DOES NOT MATCH ALLOCATED SIZE!\n");
done:
@@ -536,7 +546,7 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
HDassert(indent >= 0);
HDassert(fwidth >= 0);
- if(NULL == (oh = H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* debug */
diff --git a/src/H5Odrvinfo.c b/src/H5Odrvinfo.c
index fd2d049..864fe9e 100644
--- a/src/H5Odrvinfo.c
+++ b/src/H5Odrvinfo.c
@@ -28,7 +28,8 @@
#include "H5Opkg.h" /* Object headers */
#include "H5MMprivate.h" /* Memory management */
-static void *H5O_drvinfo_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_drvinfo_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_drvinfo_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
static void *H5O_drvinfo_copy(const void *_mesg, void *_dest);
static size_t H5O_drvinfo_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
@@ -79,8 +80,8 @@ const H5O_msg_class_t H5O_MSG_DRVINFO[1] = {{
*-------------------------------------------------------------------------
*/
static void *
-H5O_drvinfo_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_drvinfo_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_drvinfo_t *mesg; /* Native message */
void *ret_value; /* Return value */
@@ -96,7 +97,7 @@ H5O_drvinfo_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_f
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message")
/* Allocate space for message */
- if(NULL == (mesg = H5MM_calloc(sizeof(H5O_drvinfo_t))))
+ if(NULL == (mesg = (H5O_drvinfo_t *)H5MM_calloc(sizeof(H5O_drvinfo_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for driver info message")
/* Retrieve driver name */
@@ -109,8 +110,8 @@ H5O_drvinfo_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_f
HDassert(mesg->len);
/* Allocate space for buffer */
- if(NULL == (mesg->buf = H5MM_malloc(mesg->len))) {
- mesg = H5MM_xfree(mesg);
+ if(NULL == (mesg->buf = (uint8_t *)H5MM_malloc(mesg->len))) {
+ mesg = (H5O_drvinfo_t *)H5MM_xfree(mesg);
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for driver info buffer")
} /* end if */
@@ -187,16 +188,16 @@ H5O_drvinfo_copy(const void *_mesg, void *_dest)
/* Sanity check */
HDassert(mesg);
- if(!dest && NULL == (dest = H5MM_malloc(sizeof(H5O_drvinfo_t))))
+ if(!dest && NULL == (dest = (H5O_drvinfo_t *)H5MM_malloc(sizeof(H5O_drvinfo_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for shared message table message")
/* Shallow copy the fields */
*dest = *mesg;
/* Copy the buffer */
- if(NULL == (dest->buf = H5MM_malloc(mesg->len))) {
+ if(NULL == (dest->buf = (uint8_t *)H5MM_malloc(mesg->len))) {
if(dest != _dest)
- dest = H5MM_xfree(dest);
+ dest = (H5O_drvinfo_t *)H5MM_xfree(dest);
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
} /* end if */
HDmemcpy(dest->buf, mesg->buf, mesg->len);
@@ -269,7 +270,7 @@ H5O_drvinfo_reset(void *_mesg)
HDassert(mesg);
/* reset */
- mesg->buf = H5MM_xfree(mesg->buf);
+ mesg->buf = (uint8_t *)H5MM_xfree(mesg->buf);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_drvinfo_reset() */
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index ba343bc..fc71d65 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -17,6 +17,7 @@
#define H5T_PACKAGE /*prevent warning from including H5Tpkg */
#include "H5private.h" /* Generic Functions */
+#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fprivate.h" /* Files */
#include "H5FLprivate.h" /* Free Lists */
@@ -29,7 +30,8 @@
/* PRIVATE PROTOTYPES */
static herr_t H5O_dtype_encode(H5F_t *f, uint8_t *p, const void *mesg);
-static void *H5O_dtype_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_dtype_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static void *H5O_dtype_copy(const void *_mesg, void *_dest);
static size_t H5O_dtype_size(const H5F_t *f, const void *_mesg);
static herr_t H5O_dtype_reset(void *_mesg);
@@ -60,11 +62,30 @@ static herr_t H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
#define H5O_SHARED_COPY_FILE H5O_dtype_shared_copy_file
#define H5O_SHARED_COPY_FILE_REAL H5O_dtype_copy_file
#define H5O_SHARED_POST_COPY_FILE H5O_dtype_shared_post_copy_file
-#undef H5O_SHARED_POST_COPY_FILE_REAL
+#undef H5O_SHARED_POST_COPY_FILE_REAL
#define H5O_SHARED_DEBUG H5O_dtype_shared_debug
#define H5O_SHARED_DEBUG_REAL H5O_dtype_debug
#include "H5Oshared.h" /* Shared Object Header Message Callbacks */
+/* Macros to check for the proper version of a datatype */
+#ifdef H5_STRICT_FORMAT_CHECKS
+/* If the version is too low, give an error. No error if nochange is set
+ * because in that case we are either debugging or deleting the object header */
+#define H5O_DTYPE_CHECK_VERSION(DT, VERS, MIN_VERS, IOF, CLASS, ERR) \
+ if(((VERS) < (MIN_VERS)) && !(*(IOF) & H5O_DECODEIO_NOCHANGE)) \
+ HGOTO_ERROR(H5E_DATATYPE, H5E_VERSION, ERR, "incorrect " CLASS " datatype version")
+#else /* H5_STRICT_FORMAT_CHECKS */
+/* If the version is too low and we are allowed to change the message, upgrade
+ * it and mark the object header as dirty */
+#define H5O_DTYPE_CHECK_VERSION(DT, VERS, MIN_VERS, IOF, CLASS, ERR) \
+ if(((VERS) < (MIN_VERS)) && !(*(IOF) & H5O_DECODEIO_NOCHANGE)) { \
+ (VERS) = (MIN_VERS); \
+ if(H5T_upgrade_version((DT), (VERS)) < 0) \
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't upgrade " CLASS " encoding version") \
+ *(IOF) |= H5O_DECODEIO_DIRTY; \
+ } /* end if */
+#endif /* H5_STRICT_FORMAT_CHECKS */
+
/* This message derives from H5O message class */
const H5O_msg_class_t H5O_MSG_DTYPE[1] = {{
H5O_DTYPE_ID, /* message id number */
@@ -95,20 +116,23 @@ const H5O_msg_class_t H5O_MSG_DTYPE[1] = {{
*
* Purpose: Decodes a datatype
*
- * Return: Non-negative on success/Negative on failure
+ * Return: TRUE if we can upgrade the parent type's version even
+ * with strict format checks
+ * FALSE if we cannot
+ * Negative on failure
*
* Programmer: Robb Matzke
* Monday, December 8, 1997
*
*-------------------------------------------------------------------------
*/
-static herr_t
-H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
+static htri_t
+H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **pp, H5T_t *dt)
{
unsigned flags, version;
unsigned i;
size_t z;
- herr_t ret_value = SUCCEED; /* Return value */
+ htri_t ret_value = FALSE; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_dtype_decode_helper)
@@ -233,6 +257,8 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
{
unsigned offset_nbytes; /* Size needed to encode member offsets */
size_t max_memb_pos = 0; /* Maximum member covered, so far */
+ unsigned max_version = 0; /* Maximum member version */
+ hbool_t upgrade_to = 0; /* Version number we can "soft" upgrade to */
unsigned j;
/* Compute the # of bytes required to store a member offset */
@@ -243,13 +269,14 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
*/
dt->shared->u.compnd.nmembs = flags & 0xffff;
HDassert(dt->shared->u.compnd.nmembs > 0);
- dt->shared->u.compnd.packed = TRUE; /* Start off packed */
dt->shared->u.compnd.nalloc = dt->shared->u.compnd.nmembs;
dt->shared->u.compnd.memb = (H5T_cmemb_t *)H5MM_calloc(dt->shared->u.compnd.nalloc * sizeof(H5T_cmemb_t));
+ dt->shared->u.compnd.memb_size = 0;
if(NULL == dt->shared->u.compnd.memb)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
unsigned ndims = 0; /* Number of dimensions of the array field */
+ htri_t can_upgrade; /* Whether we can upgrade this type's version */
hsize_t dim[H5O_LAYOUT_NDIMS]; /* Dimensions of the array */
H5T_t *array_dt; /* Temporary pointer to the array datatype */
H5T_t *temp_type; /* Temporary pointer to the field's datatype */
@@ -297,13 +324,21 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Decode the field's datatype information */
- if(H5O_dtype_decode_helper(f, pp, temp_type) < 0) {
+ if((can_upgrade = H5O_dtype_decode_helper(f, ioflags, pp, temp_type)) < 0) {
for(j = 0; j <= i; j++)
H5MM_xfree(dt->shared->u.compnd.memb[j].name);
H5MM_xfree(dt->shared->u.compnd.memb);
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode member type")
} /* end if */
+ /* Upgrade the version if we can and it is necessary */
+ if(can_upgrade && temp_type->shared->version > version) {
+ upgrade_to = temp_type->shared->version;
+
+ /* Pass "can_upgrade" flag down to parent type */
+ ret_value = TRUE;
+ } /* end if */
+
/* Go create the array datatype now, for older versions of the datatype message */
if(version == H5O_DTYPE_VERSION_1) {
/* Check if this member is an array field */
@@ -321,9 +356,26 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
/* Make the array type the type that is set for the field */
temp_type = array_dt;
+
+ /* Reset array version if NOCHANGE is specified (i.e. h5debug) */
+ if(*ioflags & H5O_DECODEIO_NOCHANGE)
+ temp_type->shared->version = H5O_DTYPE_VERSION_1;
+ else {
+ /* Otherwise upgrade the compound version */
+ if(upgrade_to < temp_type->shared->version)
+ upgrade_to = temp_type->shared->version;
+
+ /* Set the return value to indicate that we should freely
+ * upgrade parent types */
+ ret_value = TRUE;
+ } /* end else */
} /* end if */
} /* end if */
+ /* Keep track of the maximum member version found */
+ if(temp_type->shared->version > max_version)
+ max_version = temp_type->shared->version;
+
/*
* Set the "force conversion" flag if VL datatype fields exist in this
* type or any component types
@@ -333,6 +385,7 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
/* Member size */
dt->shared->u.compnd.memb[i].size = temp_type->shared->size;
+ dt->shared->u.compnd.memb_size += temp_type->shared->size;
/* Set the field datatype (finally :-) */
dt->shared->u.compnd.memb[i].type = temp_type;
@@ -348,30 +401,24 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
/* Update the maximum member position covered */
max_memb_pos = MAX(max_memb_pos, (dt->shared->u.compnd.memb[i].offset + dt->shared->u.compnd.memb[i].size));
-
- /* Check if the datatype stayed packed */
- if(dt->shared->u.compnd.packed) {
- /* Check if the member type is packed */
- if(H5T_is_packed(temp_type) > 0) {
- if(i == 0) {
- /* If the is the first member, the datatype is not packed
- * if the first member isn't at offset 0
- */
- if(dt->shared->u.compnd.memb[i].offset > 0)
- dt->shared->u.compnd.packed = FALSE;
- } /* end if */
- else {
- /* If the is not the first member, the datatype is not
- * packed if the new member isn't adjoining the previous member
- */
- if(dt->shared->u.compnd.memb[i].offset != (dt->shared->u.compnd.memb[i - 1].offset + dt->shared->u.compnd.memb[i - 1].size))
- dt->shared->u.compnd.packed = FALSE;
- } /* end else */
- } /* end if */
- else
- dt->shared->u.compnd.packed = FALSE;
- } /* end if */
} /* end for */
+
+ /* Check if the compound type is packed */
+ H5T_update_packed(dt);
+
+ /* Upgrade the compound if requested */
+ if(version < upgrade_to) {
+ version = upgrade_to;
+ if(H5T_upgrade_version(dt, upgrade_to) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't upgrade compound encoding version")
+ /* We won't mark the message dirty since there were no
+ * errors in the file, simply type versions that we will no
+ * longer encode. */
+ } /* end if */
+
+ /* Check that no member of this compound has a version greater
+ * than the compound itself. */
+ H5O_DTYPE_CHECK_VERSION(dt, version, max_version, ioflags, "compound", FAIL)
}
break;
@@ -387,8 +434,9 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
/* Set extra information for object references, so the hobj_ref_t gets swizzled correctly */
if(dt->shared->u.atomic.u.r.rtype == H5R_OBJECT) {
- /* This type is on disk */
- dt->shared->u.atomic.u.r.loc = H5T_LOC_DISK;
+ /* Mark location this type as undefined for now. The caller function should
+ * decide the location. */
+ dt->shared->u.atomic.u.r.loc = H5T_LOC_BADLOC;
/* This type needs conversion */
dt->shared->force_conv = TRUE;
@@ -402,8 +450,14 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
dt->shared->u.enumer.nmembs = dt->shared->u.enumer.nalloc = flags & 0xffff;
if(NULL == (dt->shared->parent = H5T_alloc()))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- if(H5O_dtype_decode_helper(f, pp, dt->shared->parent) < 0)
+ if(H5O_dtype_decode_helper(f, ioflags, pp, dt->shared->parent) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode parent datatype")
+
+ /* Check if the parent of this enum has a version greater than the
+ * enum itself. */
+ H5O_DTYPE_CHECK_VERSION(dt, version, dt->shared->parent->shared->version,
+ ioflags, "enum", FAIL)
+
if(NULL == (dt->shared->u.enumer.name = (char **)H5MM_calloc(dt->shared->u.enumer.nalloc * sizeof(char*))) ||
NULL == (dt->shared->u.enumer.value = (uint8_t *)H5MM_calloc(dt->shared->u.enumer.nalloc * dt->shared->parent->shared->size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
@@ -438,12 +492,19 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
/* Decode base type of VL information */
if(NULL == (dt->shared->parent = H5T_alloc()))
HGOTO_ERROR(H5E_DATATYPE, H5E_NOSPACE, FAIL, "memory allocation failed")
- if(H5O_dtype_decode_helper(f, pp, dt->shared->parent) < 0)
+ if(H5O_dtype_decode_helper(f, ioflags, pp, dt->shared->parent) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode VL parent type")
+ /* Check if the parent of this vlen has a version greater than the
+ * vlen itself. */
+ H5O_DTYPE_CHECK_VERSION(dt, version, dt->shared->parent->shared->version,
+ ioflags, "vlen", FAIL)
+
dt->shared->force_conv=TRUE;
- /* Mark this type as on disk */
- if(H5T_set_loc(dt, f, H5T_LOC_DISK) < 0)
+
+ /* Mark location this type as undefined for now. The caller function should
+ * decide the location. */
+ if(H5T_set_loc(dt, f, H5T_LOC_BADLOC) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
break;
@@ -471,8 +532,17 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
/* Decode base type of array */
if(NULL == (dt->shared->parent = H5T_alloc()))
HGOTO_ERROR(H5E_DATATYPE, H5E_NOSPACE, FAIL, "memory allocation failed")
- if(H5O_dtype_decode_helper(f, pp, dt->shared->parent) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode VL parent type")
+ if(H5O_dtype_decode_helper(f, ioflags, pp, dt->shared->parent) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode array parent type")
+
+ /* Check if the parent of this array has a version greater than the
+ * array itself. */
+ H5O_DTYPE_CHECK_VERSION(dt, version, dt->shared->parent->shared->version,
+ ioflags, "array", FAIL)
+
+ /* There should be no array datatypes with version < 2. */
+ H5O_DTYPE_CHECK_VERSION(dt, version, H5O_DTYPE_VERSION_2, ioflags,
+ "array", FAIL)
/*
* Set the "force conversion" flag if a VL base datatype is used or
@@ -490,8 +560,8 @@ done:
if(ret_value < 0) {
if(dt != NULL) {
if(dt->shared != NULL)
- H5FL_FREE(H5T_shared_t, dt->shared);
- H5FL_FREE(H5T_t, dt);
+ dt->shared = H5FL_FREE(H5T_shared_t, dt->shared);
+ dt = H5FL_FREE(H5T_t, dt);
} /* end if */
} /* end if */
@@ -758,6 +828,9 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
/* (compound datatypes w/array members must be encoded w/version >= 2) */
HDassert(dt->shared->u.compnd.memb[i].type->shared->type != H5T_ARRAY || dt->shared->version >= H5O_DTYPE_VERSION_2);
+ /* Check that the version is at least as great as the member */
+ HDassert(dt->shared->version >= dt->shared->u.compnd.memb[i].type->shared->version);
+
/* Name */
HDstrcpy((char*)(*pp), dt->shared->u.compnd.memb[i].name);
@@ -817,6 +890,9 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
break;
case H5T_ENUM:
+ /* Check that the version is at least as great as the parent */
+ HDassert(dt->shared->version >= dt->shared->parent->shared->version);
+
/*
* Enumeration datatypes...
*/
@@ -849,6 +925,9 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
break;
case H5T_VLEN: /* Variable length datatypes... */
+ /* Check that the version is at least as great as the parent */
+ HDassert(dt->shared->version >= dt->shared->parent->shared->version);
+
flags |= (dt->shared->u.vlen.type & 0x0f);
if(dt->shared->u.vlen.type == H5T_VLEN_STRING) {
flags |= (dt->shared->u.vlen.pad & 0x0f) << 4;
@@ -864,6 +943,12 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
/* Double-check the number of dimensions */
HDassert(dt->shared->u.array.ndims <= H5S_MAX_RANK);
+ /* Check that the version is valid */
+ HDassert(dt->shared->version >= H5O_DTYPE_VERSION_2);
+
+ /* Check that the version is at least as great as the parent */
+ HDassert(dt->shared->version >= dt->shared->parent->shared->version);
+
/* Encode the number of dimensions */
*(*pp)++ = dt->shared->u.array.ndims;
@@ -927,7 +1012,8 @@ done:
function using malloc() and is returned to the caller.
--------------------------------------------------------------------------*/
static void *
-H5O_dtype_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, const uint8_t *p)
+H5O_dtype_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh, unsigned UNUSED mesg_flags,
+ unsigned *ioflags/*in,out*/, const uint8_t *p)
{
H5T_t *dt = NULL;
void *ret_value; /* Return value */
@@ -942,21 +1028,13 @@ H5O_dtype_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, con
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Perform actual decode of message */
- if(H5O_dtype_decode_helper(f, &p, dt) < 0)
+ if(H5O_dtype_decode_helper(f, ioflags, &p, dt) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL, "can't decode type")
/* Set return value */
ret_value = dt;
done:
- if(ret_value == NULL) {
- if(dt != NULL) {
- if(dt->shared != NULL)
- H5FL_FREE(H5T_shared_t, dt->shared);
- H5FL_FREE(H5T_t, dt);
- } /* end if */
- } /* end if */
-
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_dtype_decode() */
@@ -1036,7 +1114,7 @@ H5O_dtype_copy(const void *_src, void *_dst)
/* Was result already allocated? */
if(_dst) {
*((H5T_t *) _dst) = *dst;
- H5FL_FREE(H5T_t, dst);
+ (void)H5FL_FREE(H5T_t, dst);
dst = (H5T_t *) _dst;
} /* end if */
@@ -1063,9 +1141,6 @@ done:
This function returns the size of the raw simple datatype message on
success. (Not counting the message type or size fields, only the data
portion of the message). It doesn't take into account alignment.
- NOTES
- All datatype messages have a common 8 byte header, plus a variable-
- sized "properties" field.
--------------------------------------------------------------------------*/
static size_t
H5O_dtype_size(const H5F_t *f, const void *_mesg)
@@ -1131,7 +1206,7 @@ H5O_dtype_size(const H5F_t *f, const void *_mesg)
ret_value += offset_nbytes; /*member offset*/
if(dt->shared->version >= H5O_DTYPE_VERSION_2)
ret_value += 4; /*member offset*/
- else
+ else
ret_value += 4 + /*member offset*/
1 + /*dimensionality*/
3 + /*reserved*/
@@ -1233,8 +1308,8 @@ H5O_dtype_free(void *mesg)
HDassert(mesg);
- H5FL_FREE(H5T_shared_t, ((H5T_t *) mesg)->shared);
- H5FL_FREE(H5T_t,mesg);
+ (void)H5FL_FREE(H5T_shared_t, ((H5T_t *) mesg)->shared);
+ (void)H5FL_FREE(H5T_t, mesg);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_dtype_free() */
@@ -1255,8 +1330,8 @@ H5O_dtype_free(void *mesg)
static herr_t
H5O_dtype_set_share(void *_mesg/*in,out*/, const H5O_shared_t *sh)
{
- H5T_t *dt = (H5T_t *)_mesg;
- herr_t ret_value = SUCCEED;
+ H5T_t *dt = (H5T_t *)_mesg;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5O_dtype_set_share)
@@ -1295,7 +1370,7 @@ done:
* Function: H5O_dtype_can_share
*
* Purpose: Determines if this datatype is allowed to be shared or
- * not. Immutable datatypes or datatypes that are already
+ * not. Immutable datatypes or datatypes that are already
* shared cannot be shared (again).
*
* Return: TRUE if datatype can be shared
@@ -1355,9 +1430,9 @@ H5O_dtype_pre_copy_file(H5F_t *file_src, const void *mesg_src,
hbool_t UNUSED *deleted, const H5O_copy_t UNUSED *cpy_info,
void *_udata)
{
- const H5T_t *dt_src = (const H5T_t *)mesg_src; /* Source datatype */
+ const H5T_t *dt_src = (const H5T_t *)mesg_src; /* Source datatype */
H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; /* Dataset copying user data */
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_dtype_pre_copy_file)
@@ -1389,12 +1464,12 @@ done:
/*-------------------------------------------------------------------------
* Function: H5O_dtype_copy_file
- *
+ *
* Purpose: Copy a native datatype message from one file to another.
*
* Return: Success: Native copy of message
* Failure: NULL
- *
+ *
* Programmer: James Laird
* December 12, 2006
*
@@ -1405,8 +1480,8 @@ H5O_dtype_copy_file(H5F_t UNUSED *file_src, const H5O_msg_class_t *mesg_type,
void *native_src, H5F_t *file_dst, hbool_t UNUSED *recompute_size,
H5O_copy_t UNUSED *cpy_info, void UNUSED *udata, hid_t UNUSED dxpl_id)
{
- H5T_t *dst_mesg = NULL; /* Destination datatype */
- void *ret_value = NULL; /* Return value */
+ H5T_t *dst_mesg; /* Destination datatype */
+ void *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_dtype_copy_file)
@@ -1523,12 +1598,15 @@ H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream,
"Size:",
(unsigned long)(dt->shared->size), 1 == dt->shared->size ? "" : "s");
+ fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Version:", dt->shared->version);
+
if (H5T_COMPOUND == dt->shared->type) {
- fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth,
+ fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Number of members:",
dt->shared->u.compnd.nmembs);
for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
- sprintf(buf, "Member %d:", i);
+ sprintf(buf, "Member %u:", i);
fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
buf,
dt->shared->u.compnd.memb[i].name);
@@ -1541,11 +1619,11 @@ H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream,
} else if(H5T_ENUM == dt->shared->type) {
fprintf(stream, "%*s%s\n", indent, "", "Base type:");
H5O_dtype_debug(f, dxpl_id, dt->shared->parent, stream, indent+3, MAX(0, fwidth-3));
- fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth,
+ fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Number of members:",
dt->shared->u.enumer.nmembs);
for(i = 0; i < dt->shared->u.enumer.nmembs; i++) {
- sprintf(buf, "Member %d:", i);
+ sprintf(buf, "Member %u:", i);
fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
buf,
dt->shared->u.enumer.name[i]);
@@ -1622,7 +1700,7 @@ H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream,
s = "disk";
break;
default:
- sprintf(buf, "H5T_LOC_%d", dt->shared->u.vlen.loc);
+ sprintf(buf, "H5T_LOC_%d", (int)dt->shared->u.vlen.loc);
s = buf;
break;
} /* end switch */
@@ -1667,7 +1745,7 @@ H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream,
s);
} /* end if */
} else if(H5T_ARRAY == dt->shared->type) {
- fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth,
+ fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Rank:",
dt->shared->u.array.ndims);
fprintf(stream, "%*s%-*s {", indent, "", fwidth, "Dim Size:");
diff --git a/src/H5Oefl.c b/src/H5Oefl.c
index 5fa9d6a..5702b34 100644
--- a/src/H5Oefl.c
+++ b/src/H5Oefl.c
@@ -29,7 +29,8 @@
#include "H5Opkg.h" /* Object headers */
/* PRIVATE PROTOTYPES */
-static void *H5O_efl_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_efl_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_efl_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
static void *H5O_efl_copy(const void *_mesg, void *_dest);
static size_t H5O_efl_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
@@ -83,8 +84,8 @@ const H5O_msg_class_t H5O_MSG_EFL[1] = {{
*-------------------------------------------------------------------------
*/
static void *
-H5O_efl_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_efl_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_efl_t *mesg = NULL;
int version;
@@ -99,7 +100,7 @@ H5O_efl_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
HDassert(f);
HDassert(p);
- if(NULL == (mesg = H5MM_calloc(sizeof(H5O_efl_t))))
+ if(NULL == (mesg = (H5O_efl_t *)H5MM_calloc(sizeof(H5O_efl_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Version */
@@ -125,7 +126,7 @@ H5O_efl_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
if(NULL == (heap = H5HL_protect(f, dxpl_id, mesg->heap_addr, H5AC_READ)))
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read protect link value")
- s = H5HL_offset_into(f, heap, 0);
+ s = (const char *)H5HL_offset_into(f, heap, 0);
HDassert(s && !*s);
@@ -135,7 +136,7 @@ H5O_efl_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
#endif
/* Decode the file list */
- mesg->slot = H5MM_calloc(mesg->nalloc * sizeof(H5O_efl_entry_t));
+ mesg->slot = (H5O_efl_entry_t *)H5MM_calloc(mesg->nalloc * sizeof(H5O_efl_entry_t));
if(NULL == mesg->slot)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
@@ -145,7 +146,7 @@ H5O_efl_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags,
/* Name */
H5F_DECODE_LENGTH (f, p, mesg->slot[u].name_offset);
- s = H5HL_offset_into(f, heap, mesg->slot[u].name_offset);
+ s = (const char *)H5HL_offset_into(f, heap, mesg->slot[u].name_offset);
HDassert(s && *s);
mesg->slot[u].name = H5MM_xstrdup (s);
HDassert(mesg->slot[u].name);
@@ -261,12 +262,12 @@ H5O_efl_copy(const void *_mesg, void *_dest)
/* check args */
HDassert(mesg);
if(!dest) {
- if(NULL == (dest = H5MM_calloc(sizeof(H5O_efl_t))) ||
- NULL == (dest->slot = H5MM_malloc(mesg->nalloc * sizeof(H5O_efl_entry_t))))
+ if(NULL == (dest = (H5O_efl_t *)H5MM_calloc(sizeof(H5O_efl_t))) ||
+ NULL == (dest->slot = (H5O_efl_entry_t *)H5MM_malloc(mesg->nalloc * sizeof(H5O_efl_entry_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
} else if(dest->nalloc < mesg->nalloc) {
H5MM_xfree(dest->slot);
- if(NULL == (dest->slot = H5MM_malloc(mesg->nalloc * sizeof(H5O_efl_entry_t))))
+ if(NULL == (dest->slot = (H5O_efl_entry_t *)H5MM_malloc(mesg->nalloc * sizeof(H5O_efl_entry_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
}
dest->heap_addr = mesg->heap_addr;
@@ -353,11 +354,11 @@ H5O_efl_reset(void *_mesg)
/* reset */
for(u = 0; u < mesg->nused; u++)
- mesg->slot[u].name = H5MM_xfree(mesg->slot[u].name);
+ mesg->slot[u].name = (char *)H5MM_xfree(mesg->slot[u].name);
mesg->heap_addr = HADDR_UNDEF;
mesg->nused = mesg->nalloc = 0;
if(mesg->slot)
- mesg->slot = H5MM_xfree(mesg->slot);
+ mesg->slot = (H5O_efl_entry_t *)H5MM_xfree(mesg->slot);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_efl_reset() */
@@ -434,7 +435,7 @@ H5O_efl_copy_file(H5F_t UNUSED *file_src, void *mesg_src, H5F_t *file_dst,
HDassert(file_dst);
/* Allocate space for the destination efl */
- if(NULL == (efl_dst = H5MM_calloc(sizeof(H5O_efl_t))))
+ if(NULL == (efl_dst = (H5O_efl_t *)H5MM_calloc(sizeof(H5O_efl_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Copy the "top level" information */
@@ -461,7 +462,7 @@ H5O_efl_copy_file(H5F_t UNUSED *file_src, void *mesg_src, H5F_t *file_dst,
/* allocate array of external file entries */
if(efl_src->nalloc > 0) {
size = efl_src->nalloc * sizeof(H5O_efl_entry_t);
- if((efl_dst->slot = H5MM_calloc(size)) == NULL)
+ if((efl_dst->slot = (H5O_efl_entry_t *)H5MM_calloc(size)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* copy content from the source. Need to update later */
diff --git a/src/H5Ofill.c b/src/H5Ofill.c
index a67f6aa..f403b81 100644
--- a/src/H5Ofill.c
+++ b/src/H5Ofill.c
@@ -33,10 +33,12 @@
#include "H5Sprivate.h" /* Dataspaces */
-static void *H5O_fill_old_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_fill_old_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_fill_old_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static size_t H5O_fill_old_size(const H5F_t *f, const void *_mesg);
-static void *H5O_fill_new_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_fill_new_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_fill_new_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static size_t H5O_fill_new_size(const H5F_t *f, const void *_mesg);
static void *H5O_fill_copy(const void *_mesg, void *_dest);
@@ -180,8 +182,8 @@ H5FL_BLK_EXTERN(type_conv);
*-------------------------------------------------------------------------
*/
static void *
-H5O_fill_new_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_fill_new_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_fill_t *fill = NULL;
void *ret_value;
@@ -234,10 +236,10 @@ H5O_fill_new_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unknown flag for fill value message")
/* Space allocation time */
- fill->alloc_time = (flags >> H5O_FILL_SHIFT_ALLOC_TIME) & H5O_FILL_MASK_ALLOC_TIME;
+ fill->alloc_time = (H5D_alloc_time_t)((flags >> H5O_FILL_SHIFT_ALLOC_TIME) & H5O_FILL_MASK_ALLOC_TIME);
/* Fill value write time */
- fill->fill_time = (flags >> H5O_FILL_SHIFT_FILL_TIME) & H5O_FILL_MASK_FILL_TIME;
+ fill->fill_time = (H5D_fill_time_t)((flags >> H5O_FILL_SHIFT_FILL_TIME) & H5O_FILL_MASK_FILL_TIME);
/* Check for undefined fill value */
if(flags & H5O_FILL_FLAG_UNDEFINED_VALUE) {
@@ -273,7 +275,7 @@ done:
if(!ret_value && fill) {
if(fill->buf)
H5MM_xfree(fill->buf);
- H5FL_FREE(H5O_fill_t, fill);
+ (void)H5FL_FREE(H5O_fill_t, fill);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -294,8 +296,8 @@ done:
*-------------------------------------------------------------------------
*/
static void *
-H5O_fill_old_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_fill_old_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_fill_t *fill = NULL; /* Decoded fill value message */
void *ret_value; /* Return value */
@@ -333,7 +335,7 @@ done:
if(!ret_value && fill) {
if(fill->buf)
H5MM_xfree(fill->buf);
- H5FL_FREE(H5O_fill_t, fill);
+ (void)H5FL_FREE(H5O_fill_t, fill);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -376,7 +378,7 @@ H5O_fill_new_encode(H5F_t UNUSED *f, uint8_t *p, const void *_fill)
*p++ = fill->fill_time;
/* Whether fill value is defined */
- *p++ = fill->fill_defined;
+ *p++ = (uint8_t)fill->fill_defined;
/* Only write out the size and fill value if it is defined */
if(fill->fill_defined) {
@@ -505,7 +507,7 @@ H5O_fill_copy(const void *_src, void *_dst)
/* Copy data type of fill value */
if(src->type) {
if(NULL == (dst->type = H5T_copy(src->type, H5T_COPY_TRANSIENT)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy fill value data type")
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "can't copy datatype")
} /* end if */
else
dst->type = NULL;
@@ -532,35 +534,35 @@ H5O_fill_copy(const void *_src, void *_dst)
size_t bkg_size; /* Size of background buffer */
/* Wrap copies of types to convert */
- dst_id = H5I_register(H5I_DATATYPE, H5T_copy(dst->type, H5T_COPY_TRANSIENT));
+ dst_id = H5I_register(H5I_DATATYPE, H5T_copy(dst->type, H5T_COPY_TRANSIENT), FALSE);
if(dst_id < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy/register datatype")
- src_id = H5I_register(H5I_DATATYPE, H5T_copy(src->type, H5T_COPY_ALL));
+ src_id = H5I_register(H5I_DATATYPE, H5T_copy(src->type, H5T_COPY_ALL), FALSE);
if(src_id < 0) {
- H5I_dec_ref(dst_id);
+ H5I_dec_ref(dst_id, FALSE);
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy/register datatype")
} /* end if */
/* Allocate a background buffer */
bkg_size = MAX(H5T_get_size(dst->type), H5T_get_size(src->type));
if(H5T_path_bkg(tpath) && NULL == (bkg_buf = H5FL_BLK_CALLOC(type_conv, bkg_size))) {
- H5I_dec_ref(src_id);
- H5I_dec_ref(dst_id);
+ H5I_dec_ref(src_id, FALSE);
+ H5I_dec_ref(dst_id, FALSE);
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
} /* end if */
/* Convert fill value */
if(H5T_convert(tpath, src_id, dst_id, (size_t)1, (size_t)0, (size_t)0, dst->buf, bkg_buf, H5AC_ind_dxpl_id) < 0) {
- H5I_dec_ref(src_id);
- H5I_dec_ref(dst_id);
+ H5I_dec_ref(src_id, FALSE);
+ H5I_dec_ref(dst_id, FALSE);
if(bkg_buf)
bkg_buf = H5FL_BLK_FREE(type_conv, bkg_buf);
HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, NULL, "datatype conversion failed")
} /* end if */
/* Release the background buffer */
- H5I_dec_ref(src_id);
- H5I_dec_ref(dst_id);
+ H5I_dec_ref(src_id, FALSE);
+ H5I_dec_ref(dst_id, FALSE);
if(bkg_buf)
bkg_buf = H5FL_BLK_FREE(type_conv, bkg_buf);
} /* end if */
@@ -579,7 +581,7 @@ done:
if(dst->type)
H5T_close(dst->type);
if(!_dst)
- H5FL_FREE(H5O_fill_t, dst);
+ (void)H5FL_FREE(H5O_fill_t, dst);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -622,14 +624,14 @@ H5O_fill_new_size(const H5F_t UNUSED *f, const void *_fill)
1; /* Fill value defined */
if(fill->fill_defined)
ret_value += 4 + /* Fill value size */
- (fill->size > 0 ? fill->size : 0); /* Size of fill value */
+ (fill->size > 0 ? (size_t)fill->size : 0); /* Size of fill value */
} /* end if */
else {
ret_value = 1 + /* Version number */
1; /* Status flags */
if(fill->size > 0)
ret_value += 4 + /* Fill value size */
- fill->size; /* Size of fill value */
+ (size_t)fill->size; /* Size of fill value */
} /* end else */
FUNC_LEAVE_NOAPI(ret_value)
@@ -660,7 +662,7 @@ H5O_fill_old_size(const H5F_t UNUSED *f, const void *_fill)
HDassert(fill);
- FUNC_LEAVE_NOAPI(4 + fill->size)
+ FUNC_LEAVE_NOAPI(4 + (size_t)fill->size)
} /* end H5O_fill_old_size() */
@@ -687,14 +689,14 @@ H5O_fill_reset_dyn(H5O_fill_t *fill)
HDassert(fill);
if(fill->buf) {
- if(fill->type && H5T_detect_class(fill->type, H5T_VLEN) > 0) {
+ if(fill->type && H5T_detect_class(fill->type, H5T_VLEN, FALSE) > 0) {
H5T_t *fill_type; /* Copy of fill value datatype */
H5S_t *fill_space; /* Scalar dataspace for fill value element */
/* Copy the fill value datatype and get an ID for it */
if(NULL == (fill_type = H5T_copy(fill->type, H5T_COPY_TRANSIENT)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy fill value datatype")
- if((fill_type_id = H5I_register(H5I_DATATYPE, fill_type)) < 0) {
+ if((fill_type_id = H5I_register(H5I_DATATYPE, fill_type, FALSE)) < 0) {
H5T_close(fill_type);
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register fill value datatype")
} /* end if */
@@ -724,7 +726,7 @@ H5O_fill_reset_dyn(H5O_fill_t *fill)
done:
if(fill_type_id > 0)
- H5I_dec_ref(fill_type_id);
+ H5I_dec_ref(fill_type_id, FALSE);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_fill_reset_dyn() */
@@ -781,7 +783,7 @@ H5O_fill_free(void *fill)
HDassert(fill);
- H5FL_FREE(H5O_fill_t, fill);
+ (void)H5FL_FREE(H5O_fill_t, fill);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_fill_free() */
@@ -936,8 +938,8 @@ H5O_fill_convert(H5O_fill_t *fill, H5T_t *dset_type, hbool_t *fill_changed, hid_
/* Don't bother doing anything if there will be no actual conversion */
if(!H5T_path_noop(tpath)) {
- if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(fill->type, H5T_COPY_ALL))) < 0 ||
- (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(dset_type, H5T_COPY_ALL))) < 0)
+ if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(fill->type, H5T_COPY_ALL), FALSE)) < 0 ||
+ (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(dset_type, H5T_COPY_ALL), FALSE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register data type")
/*
@@ -976,9 +978,9 @@ H5O_fill_convert(H5O_fill_t *fill, H5T_t *dset_type, hbool_t *fill_changed, hid_
done:
if(src_id >= 0)
- H5I_dec_ref(src_id);
+ H5I_dec_ref(src_id, FALSE);
if(dst_id >= 0)
- H5I_dec_ref(dst_id);
+ H5I_dec_ref(dst_id, FALSE);
if(buf != fill->buf)
H5MM_xfree(buf);
if(bkg)
diff --git a/src/H5Ofsinfo.c b/src/H5Ofsinfo.c
new file mode 100644
index 0000000..fb0151f
--- /dev/null
+++ b/src/H5Ofsinfo.c
@@ -0,0 +1,309 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Ofsinfo.c
+ * Feb 2009
+ * Vailin Choi
+ *
+ * Purpose: Free space manager info message.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#define H5O_PACKAGE /* suppress error about including H5Opkg */
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free lists */
+#include "H5Opkg.h" /* Object headers */
+
+/* PRIVATE PROTOTYPES */
+static void *H5O_fsinfo_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
+static herr_t H5O_fsinfo_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
+static void *H5O_fsinfo_copy(const void *_mesg, void *_dest);
+static size_t H5O_fsinfo_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
+static herr_t H5O_fsinfo_free(void *mesg);
+static herr_t H5O_fsinfo_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
+ FILE * stream, int indent, int fwidth);
+
+/* This message derives from H5O message class */
+const H5O_msg_class_t H5O_MSG_FSINFO[1] = {{
+ H5O_FSINFO_ID, /* message id number */
+ "fsinfo", /* message name for debugging */
+ sizeof(H5O_fsinfo_t), /* native message size */
+ 0, /* messages are sharable? */
+ H5O_fsinfo_decode, /* decode message */
+ H5O_fsinfo_encode, /* encode message */
+ H5O_fsinfo_copy, /* copy the native value */
+ H5O_fsinfo_size, /* size of free-space manager info message */
+ NULL, /* default reset method */
+ H5O_fsinfo_free, /* free method */
+ NULL, /* file delete method */
+ NULL, /* link method */
+ NULL, /* set share method */
+ NULL, /* can share method */
+ NULL, /* pre copy native value to file */
+ NULL, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ NULL, /* get creation index */
+ NULL, /* set creation index */
+ H5O_fsinfo_debug /* debug the message */
+}};
+
+/* Current version of free-space manager info information */
+#define H5O_FSINFO_VERSION 0
+
+/* Declare a free list to manage the H5O_fsinfo_t struct */
+H5FL_DEFINE_STATIC(H5O_fsinfo_t);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_fsinfo_decode
+ *
+ * Purpose: Decode a message and return a pointer to a newly allocated one.
+ *
+ * Return: Success: Ptr to new message in native form.
+ * Failure: NULL
+ *
+ * Programmer: Vailin Choi; Feb 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_fsinfo_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
+{
+ H5O_fsinfo_t *fsinfo = NULL; /* free-space manager info */
+ H5FD_mem_t type; /* Memory type for iteration */
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_fsinfo_decode)
+
+ /* check args */
+ HDassert(f);
+ HDassert(p);
+
+ /* Version of message */
+ if(*p++ != H5O_FSINFO_VERSION)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message")
+
+ /* Allocate space for message */
+ if(NULL == (fsinfo = H5FL_CALLOC(H5O_fsinfo_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ fsinfo->strategy = *p++; /* file space strategy */
+ H5F_DECODE_LENGTH(f, p, fsinfo->threshold); /* free space section size threshold */
+
+ /* Addresses of free space managers: only exist for H5F_FILE_SPACE_ALL_PERSIST */
+ if(fsinfo->strategy == H5F_FILE_SPACE_ALL_PERSIST) {
+ for(type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type))
+ H5F_addr_decode(f, &p, &(fsinfo->fs_addr[type-1]));
+ } /* end if */
+ else {
+ for(type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type))
+ fsinfo->fs_addr[type-1] = HADDR_UNDEF;
+ } /* end else */
+
+ /* Set return value */
+ ret_value = fsinfo;
+
+done:
+ if(ret_value == NULL && fsinfo != NULL)
+ fsinfo = H5FL_FREE(H5O_fsinfo_t, fsinfo);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_fsinfo_decode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_fsinfo_encode
+ *
+ * Purpose: Encodes a message.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Feb 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_fsinfo_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const void *_mesg)
+{
+ const H5O_fsinfo_t *fsinfo = (const H5O_fsinfo_t *)_mesg;
+ H5FD_mem_t type; /* Memory type for iteration */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_fsinfo_encode)
+
+ /* check args */
+ HDassert(f);
+ HDassert(p);
+ HDassert(fsinfo);
+
+ *p++ = H5O_FSINFO_VERSION; /* message version */
+ *p++ = fsinfo->strategy; /* file space strategy */
+ H5F_ENCODE_LENGTH(f, p, fsinfo->threshold); /* free-space section size threshold */
+
+ /* Addresses of free space managers: only exist for H5F_FILE_SPACE_ALL_PERSIST */
+ if(fsinfo->strategy == H5F_FILE_SPACE_ALL_PERSIST) {
+ for(type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type))
+ H5F_addr_encode(f, &p, fsinfo->fs_addr[type-1]);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_fsinfo_encode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_fsinfo_copy
+ *
+ * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if
+ * necessary.
+ *
+ * Return: Success: Ptr to _DEST
+ * Failure: NULL
+ *
+ * Programmer: Vailin Choi; Feb 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_fsinfo_copy(const void *_mesg, void *_dest)
+{
+ const H5O_fsinfo_t *fsinfo = (const H5O_fsinfo_t *)_mesg;
+ H5O_fsinfo_t *dest = (H5O_fsinfo_t *) _dest;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_fsinfo_copy)
+
+ /* check args */
+ HDassert(fsinfo);
+ if(!dest && NULL == (dest = H5FL_CALLOC(H5O_fsinfo_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* copy */
+ *dest = *fsinfo;
+
+ /* Set return value */
+ ret_value = dest;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_fsinfo_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_fsinfo_size
+ *
+ * Purpose: Returns the size of the raw message in bytes not counting
+ * the message type or size fields, but only the data fields.
+ * This function doesn't take into account alignment.
+ *
+ * Return: Success: Message data size in bytes without alignment.
+ * Failure: zero
+ *
+ * Programmer: Vailin Choi; Feb 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5O_fsinfo_size(const H5F_t *f, hbool_t UNUSED disable_shared, const void *_mesg)
+{
+ const H5O_fsinfo_t *fsinfo = (const H5O_fsinfo_t *)_mesg;
+ size_t fs_addr_size = 0;
+ size_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_fsinfo_size)
+
+
+ /* Addresses of free-space managers exist only for H5F_FILE_SPACE_ALL_PERSIST type */
+ if(H5F_FILE_SPACE_ALL_PERSIST == fsinfo->strategy)
+ fs_addr_size = (H5FD_MEM_NTYPES - 1) * H5F_SIZEOF_ADDR(f);
+
+ ret_value = 2 /* Version & strategy */
+ + H5F_SIZEOF_SIZE(f) /* Threshold */
+ + fs_addr_size; /* Addresses of free-space managers */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_fsinfo_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_fsinfo_free
+ *
+ * Purpose: Free's the message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Feb 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_fsinfo_free(void *mesg)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_fsinfo_free)
+
+ HDassert(mesg);
+
+ (void)H5FL_FREE(H5O_fsinfo_t, mesg);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_fsinfo_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_fsinfo_debug
+ *
+ * Purpose: Prints debugging info for a message.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Feb 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_fsinfo_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * stream,
+ int indent, int fwidth)
+{
+ const H5O_fsinfo_t *fsinfo = (const H5O_fsinfo_t *) _mesg;
+ H5FD_mem_t type; /* Memory type for iteration */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_fsinfo_debug)
+
+ /* check args */
+ HDassert(f);
+ HDassert(fsinfo);
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "File space strategy:", fsinfo->strategy);
+
+ HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
+ "Free space section threshold:", fsinfo->threshold);
+
+ if(fsinfo->strategy == H5F_FILE_SPACE_ALL_PERSIST) {
+ for(type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type))
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
+ "Free space manager address:", fsinfo->fs_addr[type-1]);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_fsinfo_debug() */
+
diff --git a/src/H5Oginfo.c b/src/H5Oginfo.c
index 5888f58..83a6085 100644
--- a/src/H5Oginfo.c
+++ b/src/H5Oginfo.c
@@ -33,7 +33,8 @@
/* PRIVATE PROTOTYPES */
-static void *H5O_ginfo_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_ginfo_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_ginfo_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
static void *H5O_ginfo_copy(const void *_mesg, void *_dest);
static size_t H5O_ginfo_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
@@ -94,8 +95,8 @@ H5FL_DEFINE_STATIC(H5O_ginfo_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_ginfo_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_ginfo_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_ginfo_t *ginfo = NULL; /* Pointer to group information message */
unsigned char flags; /* Flags for encoding group info */
@@ -147,7 +148,7 @@ H5O_ginfo_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_fla
done:
if(ret_value == NULL)
if(ginfo != NULL)
- H5FL_FREE(H5O_ginfo_t, ginfo);
+ (void)H5FL_FREE(H5O_ginfo_t, ginfo);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_ginfo_decode() */
@@ -303,7 +304,7 @@ H5O_ginfo_free(void *mesg)
HDassert(mesg);
- H5FL_FREE(H5O_ginfo_t, mesg);
+ (void)H5FL_FREE(H5O_ginfo_t, mesg);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_ginfo_free() */
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index 1f371f3..ebae1fb 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -33,7 +33,8 @@
/* PRIVATE PROTOTYPES */
-static void *H5O_layout_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_layout_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_layout_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
static void *H5O_layout_copy(const void *_mesg, void *_dest);
static size_t H5O_layout_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
@@ -71,12 +72,6 @@ const H5O_msg_class_t H5O_MSG_LAYOUT[1] = {{
H5O_layout_debug /*debug the message */
}};
-/* For forward and backward compatibility. Version is 1 when space is
- * allocated; 2 when space is delayed for allocation; 3 is default now and
- * is revised to just store information needed for each storage type. */
-#define H5O_LAYOUT_VERSION_1 1
-#define H5O_LAYOUT_VERSION_2 2
-#define H5O_LAYOUT_VERSION_3 3
/* Declare a free list to manage the H5O_layout_t struct */
H5FL_DEFINE(H5O_layout_t);
@@ -98,8 +93,8 @@ H5FL_DEFINE(H5O_layout_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_layout_t *mesg = NULL;
unsigned u;
@@ -115,7 +110,6 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
if(NULL == (mesg = H5FL_CALLOC(H5O_layout_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- /* Version. 1 when space allocated; 2 when space allocation is delayed */
mesg->version = *p++;
if(mesg->version < H5O_LAYOUT_VERSION_1 || mesg->version > H5O_LAYOUT_VERSION_3)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for layout message")
@@ -137,20 +131,21 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
/* Address */
if(mesg->type == H5D_CONTIGUOUS) {
- H5F_addr_decode(f, &p, &(mesg->u.contig.addr));
+ H5F_addr_decode(f, &p, &(mesg->storage.u.contig.addr));
/* Set the layout operations */
mesg->ops = H5D_LOPS_CONTIG;
} /* end if */
else if(mesg->type == H5D_CHUNKED) {
- H5F_addr_decode(f, &p, &(mesg->u.chunk.addr));
+ H5F_addr_decode(f, &p, &(mesg->storage.u.chunk.idx_addr));
/* Set the layout operations */
mesg->ops = H5D_LOPS_CHUNK;
/* Set the chunk operations */
- /* (Only "istore" indexing type currently supported */
- mesg->u.chunk.ops = H5D_COPS_ISTORE;
+ /* (Only "btree" indexing type currently supported in this version) */
+ mesg->storage.u.chunk.idx_type = H5D_CHUNK_BTREE;
+ mesg->storage.u.chunk.ops = H5D_COPS_BTREE;
} /* end if */
else {
/* Sanity check */
@@ -181,12 +176,12 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
} /* end if */
if(mesg->type == H5D_COMPACT) {
- UINT32DECODE(p, mesg->u.compact.size);
- if(mesg->u.compact.size > 0) {
- if(NULL == (mesg->u.compact.buf = H5MM_malloc(mesg->u.compact.size)))
+ UINT32DECODE(p, mesg->storage.u.compact.size);
+ if(mesg->storage.u.compact.size > 0) {
+ if(NULL == (mesg->storage.u.compact.buf = H5MM_malloc(mesg->storage.u.compact.size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer")
- HDmemcpy(mesg->u.compact.buf, p, mesg->u.compact.size);
- p += mesg->u.compact.size;
+ HDmemcpy(mesg->storage.u.compact.buf, p, mesg->storage.u.compact.size);
+ p += mesg->storage.u.compact.size;
} /* end if */
} /* end if */
} /* end if */
@@ -197,12 +192,12 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
/* Interpret the rest of the message according to the layout class */
switch(mesg->type) {
case H5D_COMPACT:
- UINT16DECODE(p, mesg->u.compact.size);
- if(mesg->u.compact.size > 0) {
- if(NULL == (mesg->u.compact.buf = H5MM_malloc(mesg->u.compact.size)))
+ UINT16DECODE(p, mesg->storage.u.compact.size);
+ if(mesg->storage.u.compact.size > 0) {
+ if(NULL == (mesg->storage.u.compact.buf = H5MM_malloc(mesg->storage.u.compact.size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer")
- HDmemcpy(mesg->u.compact.buf, p, mesg->u.compact.size);
- p += mesg->u.compact.size;
+ HDmemcpy(mesg->storage.u.compact.buf, p, mesg->storage.u.compact.size);
+ p += mesg->storage.u.compact.size;
} /* end if */
/* Set the layout operations */
@@ -210,8 +205,8 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
break;
case H5D_CONTIGUOUS:
- H5F_addr_decode(f, &p, &(mesg->u.contig.addr));
- H5F_DECODE_LENGTH(f, p, mesg->u.contig.size);
+ H5F_addr_decode(f, &p, &(mesg->storage.u.contig.addr));
+ H5F_DECODE_LENGTH(f, p, mesg->storage.u.contig.size);
/* Set the layout operations */
mesg->ops = H5D_LOPS_CONTIG;
@@ -224,7 +219,7 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large")
/* B-tree address */
- H5F_addr_decode(f, &p, &(mesg->u.chunk.addr));
+ H5F_addr_decode(f, &p, &(mesg->storage.u.chunk.idx_addr));
/* Chunk dimensions */
for(u = 0; u < mesg->u.chunk.ndims; u++)
@@ -234,12 +229,13 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
for(u = 1, mesg->u.chunk.size = mesg->u.chunk.dim[0]; u < mesg->u.chunk.ndims; u++)
mesg->u.chunk.size *= mesg->u.chunk.dim[u];
+ /* Set the chunk operations */
+ /* (Only "btree" indexing type supported with v3 of message format) */
+ mesg->storage.u.chunk.idx_type = H5D_CHUNK_BTREE;
+ mesg->storage.u.chunk.ops = H5D_COPS_BTREE;
+
/* Set the layout operations */
mesg->ops = H5D_LOPS_CHUNK;
-
- /* Set the chunk operations */
- /* (Only "istore" indexing type currently supported */
- mesg->u.chunk.ops = H5D_COPS_ISTORE;
break;
default:
@@ -253,7 +249,7 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
done:
if(ret_value == NULL)
if(mesg)
- H5FL_FREE(H5O_layout_t, mesg);
+ (void)H5FL_FREE(H5O_layout_t, mesg);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_layout_decode() */
@@ -303,8 +299,8 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi
HDassert(mesg);
HDassert(p);
- /* Version 3 by default now. */
- *p++ = H5O_LAYOUT_VERSION_3;
+ /* Message version */
+ *p++ = (uint8_t)H5O_LAYOUT_VERSION_3;
/* Layout class */
*p++ = mesg->type;
@@ -313,30 +309,30 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi
switch(mesg->type) {
case H5D_COMPACT:
/* Size of raw data */
- UINT16ENCODE(p, mesg->u.compact.size);
+ UINT16ENCODE(p, mesg->storage.u.compact.size);
/* Raw data */
- if(mesg->u.compact.size > 0) {
- if(mesg->u.compact.buf)
- HDmemcpy(p, mesg->u.compact.buf, mesg->u.compact.size);
+ if(mesg->storage.u.compact.size > 0) {
+ if(mesg->storage.u.compact.buf)
+ HDmemcpy(p, mesg->storage.u.compact.buf, mesg->storage.u.compact.size);
else
- HDmemset(p, 0, mesg->u.compact.size);
- p += mesg->u.compact.size;
+ HDmemset(p, 0, mesg->storage.u.compact.size);
+ p += mesg->storage.u.compact.size;
} /* end if */
break;
case H5D_CONTIGUOUS:
- H5F_addr_encode(f, &p, mesg->u.contig.addr);
- H5F_ENCODE_LENGTH(f, p, mesg->u.contig.size);
+ H5F_addr_encode(f, &p, mesg->storage.u.contig.addr);
+ H5F_ENCODE_LENGTH(f, p, mesg->storage.u.contig.size);
break;
case H5D_CHUNKED:
/* Number of dimensions */
HDassert(mesg->u.chunk.ndims > 0 && mesg->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
- *p++ = mesg->u.chunk.ndims;
+ *p++ = (uint8_t)mesg->u.chunk.ndims;
/* B-tree address */
- H5F_addr_encode(f, &p, mesg->u.chunk.addr);
+ H5F_addr_encode(f, &p, mesg->storage.u.chunk.idx_addr);
/* Dimension sizes */
for(u = 0; u < mesg->u.chunk.ndims; u++)
@@ -378,91 +374,38 @@ H5O_layout_copy(const void *_mesg, void *_dest)
/* check args */
HDassert(mesg);
+
+ /* Allocate destination message, if necessary */
if(!dest && NULL == (dest = H5FL_MALLOC(H5O_layout_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "layout message allocation failed")
/* copy */
*dest = *mesg;
/* Deep copy the buffer for compact datasets also */
- if(mesg->type == H5D_COMPACT) {
+ if(mesg->type == H5D_COMPACT && mesg->storage.u.compact.size > 0) {
/* Allocate memory for the raw data */
- if(NULL == (dest->u.compact.buf = H5MM_malloc(dest->u.compact.size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for compact dataset")
+ if(NULL == (dest->storage.u.compact.buf = H5MM_malloc(dest->storage.u.compact.size)))
+ HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "unable to allocate memory for compact dataset")
/* Copy over the raw data */
- HDmemcpy(dest->u.compact.buf, mesg->u.compact.buf, dest->u.compact.size);
+ HDmemcpy(dest->storage.u.compact.buf, mesg->storage.u.compact.buf, dest->storage.u.compact.size);
} /* end if */
+ /* Reset the pointer of the chunked storage index but not the address */
+ if(dest->type == H5D_CHUNKED && dest->storage.u.chunk.ops)
+ H5D_chunk_idx_reset(&dest->storage.u.chunk, FALSE);
+
/* Set return value */
ret_value = dest;
done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_layout_copy() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_layout_meta_size
- *
- * Purpose: Returns the size of the raw message in bytes except raw data
- * part for compact dataset. This function doesn't take into
- * account message alignment.
- *
- * Return: Success: Message data size in bytes(except raw data
- * for compact dataset)
- * Failure: 0
- *
- * Programmer: Raymond Lu
- * August 14, 2002
- *
- *-------------------------------------------------------------------------
- */
-size_t
-H5O_layout_meta_size(const H5F_t *f, const void *_mesg)
-{
- const H5O_layout_t *mesg = (const H5O_layout_t *) _mesg;
- size_t ret_value;
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_layout_meta_size)
-
- /* check args */
- HDassert(f);
- HDassert(mesg);
-
- ret_value = 1 + /* Version number */
- 1; /* layout class type */
-
- switch(mesg->type) {
- case H5D_COMPACT:
- /* Size of raw data */
- ret_value += 2;
- break;
-
- case H5D_CONTIGUOUS:
- ret_value += H5F_SIZEOF_ADDR(f); /* Address of data */
- ret_value += H5F_SIZEOF_SIZE(f); /* Length of data */
- break;
-
- case H5D_CHUNKED:
- /* Number of dimensions (1 byte) */
- assert(mesg->u.chunk.ndims > 0 && mesg->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
- ret_value++;
-
- /* B-tree address */
- ret_value += H5F_SIZEOF_ADDR(f); /* Address of data */
-
- /* Dimension sizes */
- ret_value += mesg->u.chunk.ndims * 4;
- break;
-
- default:
- HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, 0, "Invalid layout class")
- } /* end switch */
+ if(ret_value == NULL)
+ if(NULL == _dest)
+ dest = H5FL_FREE(H5O_layout_t, dest);
-done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_layout_meta_size() */
+} /* end H5O_layout_copy() */
/*-------------------------------------------------------------------------
@@ -493,9 +436,9 @@ H5O_layout_size(const H5F_t *f, hbool_t UNUSED disable_shared, const void *_mesg
HDassert(f);
HDassert(mesg);
- ret_value = H5O_layout_meta_size(f, mesg);
- if(mesg->type == H5D_COMPACT)
- ret_value += mesg->u.compact.size;/* data for compact dataset */
+ /* Compute serialized size */
+ /* (including possibly compact data) */
+ ret_value = H5D_layout_meta_size(f, mesg, TRUE);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_layout_size() */
@@ -512,28 +455,26 @@ H5O_layout_size(const H5F_t *f, hbool_t UNUSED disable_shared, const void *_mesg
* Programmer: Quincey Koziol
* Friday, September 13, 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_layout_reset (void *_mesg)
+H5O_layout_reset(void *_mesg)
{
- H5O_layout_t *mesg = (H5O_layout_t *) _mesg;
+ H5O_layout_t *mesg = (H5O_layout_t *)_mesg;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_layout_reset);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_layout_reset)
if(mesg) {
/* Free the compact storage buffer */
- if(mesg->type==H5D_COMPACT)
- mesg->u.compact.buf=H5MM_xfree(mesg->u.compact.buf);
+ if(H5D_COMPACT == mesg->type)
+ mesg->storage.u.compact.buf = H5MM_xfree(mesg->storage.u.compact.buf);
/* Reset the message */
- mesg->type=H5D_CONTIGUOUS;
+ mesg->type = H5D_CONTIGUOUS;
} /* end if */
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_layout_reset() */
/*-------------------------------------------------------------------------
@@ -546,27 +487,27 @@ H5O_layout_reset (void *_mesg)
* Programmer: Quincey Koziol
* Saturday, March 11, 2000
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_layout_free (void *_mesg)
+H5O_layout_free(void *_mesg)
{
H5O_layout_t *mesg = (H5O_layout_t *) _mesg;
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_layout_free);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_layout_free)
- assert (mesg);
+ HDassert(mesg);
- /* Free the compact storage buffer */
- if(mesg->type==H5D_COMPACT)
- mesg->u.compact.buf=H5MM_xfree(mesg->u.compact.buf);
+ /* Free resources within the message */
+ if(H5O_layout_reset(mesg) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free message resources")
- H5FL_FREE(H5O_layout_t,mesg);
+ (void)H5FL_FREE(H5O_layout_t, mesg);
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_layout_free() */
/*-------------------------------------------------------------------------
@@ -579,12 +520,10 @@ H5O_layout_free (void *_mesg)
* Programmer: Quincey Koziol
* Wednesday, March 19, 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_layout_delete(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, void *_mesg)
+H5O_layout_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg)
{
H5O_layout_t *mesg = (H5O_layout_t *) _mesg;
herr_t ret_value = SUCCEED; /* Return value */
@@ -593,6 +532,7 @@ H5O_layout_delete(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, void *_mesg)
/* check args */
HDassert(f);
+ HDassert(open_oh);
HDassert(mesg);
/* Perform different actions, depending on the type of storage */
@@ -603,13 +543,13 @@ H5O_layout_delete(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, void *_mesg)
case H5D_CONTIGUOUS: /* Contiguous block on disk */
/* Free the file space for the raw data */
- if(H5D_contig_delete(f, dxpl_id, mesg) < 0)
+ if(H5D_contig_delete(f, dxpl_id, &mesg->storage) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free raw data")
break;
case H5D_CHUNKED: /* Chunked blocks on disk */
/* Free the file space for the index & chunk raw data */
- if(H5D_chunk_delete(f, dxpl_id, mesg) < 0)
+ if(H5D_chunk_delete(f, dxpl_id, open_oh, &mesg->storage) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free raw data")
break;
@@ -654,26 +594,18 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
/* Allocate space for the destination layout */
if(NULL == (layout_dst = H5FL_MALLOC(H5O_layout_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "memory allocation failed")
/* Copy the "top level" information */
- HDmemcpy(layout_dst, layout_src, sizeof(H5O_layout_t));
+ *layout_dst = *layout_src;
/* Copy the layout type specific information */
switch(layout_src->type) {
case H5D_COMPACT:
- if(layout_src->u.compact.buf) {
- if(NULL == (layout_dst->u.compact.buf = H5MM_malloc(layout_src->u.compact.size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for compact dataset")
-
+ if(layout_src->storage.u.compact.buf) {
/* copy compact raw data */
- if(H5D_compact_copy(file_src, layout_src, file_dst, layout_dst, udata->src_dtype, cpy_info, dxpl_id) < 0)
- HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to copy chunked storage")
-
- layout_dst->u.compact.dirty = TRUE;
-
- /* Freed by copy routine */
- udata->src_dtype = NULL;
+ if(H5D_compact_copy(file_src, &layout_src->storage.u.compact, file_dst, &layout_dst->storage.u.compact, udata->src_dtype, cpy_info, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy chunked storage")
} /* end if */
break;
@@ -683,44 +615,38 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
* truncate the dimension sizes to 32-bits of information. - QAK 5/26/04
*/
if(layout_src->version < 3)
- layout_dst->u.contig.size = H5S_extent_nelem(udata->src_space_extent) *
+ layout_dst->storage.u.contig.size = H5S_extent_nelem(udata->src_space_extent) *
H5T_get_size(udata->src_dtype);
- if(H5F_addr_defined(layout_src->u.contig.addr)) {
- /* create contig layout */
- if(H5D_contig_copy(file_src, layout_src, file_dst, layout_dst, udata->src_dtype, cpy_info, dxpl_id) < 0)
- HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to copy contiguous storage")
-
- /* Freed by copy routine */
- udata->src_dtype = NULL;
- } /* if ( H5F_addr_defined(layout_src->u.contig.addr)) */
+ if(H5D_contig_is_space_alloc(&layout_src->storage)) {
+ /* copy contiguous raw data */
+ if(H5D_contig_copy(file_src, &layout_src->storage.u.contig, file_dst, &layout_dst->storage.u.contig, udata->src_dtype, cpy_info, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy contiguous storage")
+ } /* end if */
break;
case H5D_CHUNKED:
- if(H5F_addr_defined(layout_src->u.chunk.addr)) {
- /* layout is not created in the destination file, undef btree address */
- layout_dst->u.chunk.addr = HADDR_UNDEF;
-
- /* create chunked layout */
- if(H5D_chunk_copy(file_src, layout_src, file_dst, layout_dst, udata->src_dtype, cpy_info, udata->src_pline, dxpl_id) < 0)
- HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to copy chunked storage")
-
- /* Freed by copy routine */
- udata->src_dtype = NULL;
- } /* if ( H5F_addr_defined(layout_srct->u.chunk.addr)) */
+ if(H5D_chunk_is_space_alloc(&layout_src->storage)) {
+ /* Create chunked layout */
+ if(H5D_chunk_copy(file_src, &layout_src->storage.u.chunk, &layout_src->u.chunk, file_dst, &layout_dst->storage.u.chunk, udata->src_space_extent, udata->src_dtype, udata->common.src_pline, cpy_info, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy chunked storage")
+ } /* end if */
break;
default:
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "Invalid layout class")
} /* end switch */
+ /* Freed by copy routine */
+ udata->src_dtype = NULL;
+
/* Set return value */
ret_value = layout_dst;
done:
if(!ret_value)
if(layout_dst)
- H5FL_FREE(H5O_layout_t, layout_dst);
+ (void)H5FL_FREE(H5O_layout_t, layout_dst);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_layout_copy_file() */
@@ -741,13 +667,13 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_layout_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * stream,
- int indent, int fwidth)
+H5O_layout_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg,
+ FILE * stream, int indent, int fwidth)
{
const H5O_layout_t *mesg = (const H5O_layout_t *) _mesg;
unsigned u;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_layout_debug);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_layout_debug)
/* check args */
HDassert(f);
@@ -758,37 +684,58 @@ H5O_layout_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Version:", mesg->version);
- if(mesg->type==H5D_CHUNKED) {
- HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
- "Type:", "Chunked");
- HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
- "B-tree address:", mesg->u.chunk.addr);
- HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
- "Number of dimensions:",
- (unsigned long) (mesg->u.chunk.ndims));
- /* Size */
- HDfprintf(stream, "%*s%-*s {", indent, "", fwidth, "Size:");
- for (u = 0; u < mesg->u.chunk.ndims; u++) {
- HDfprintf(stream, "%s%lu", u ? ", " : "",
- (unsigned long) (mesg->u.chunk.dim[u]));
- }
- HDfprintf(stream, "}\n");
- } /* end if */
- else if(mesg->type==H5D_CONTIGUOUS) {
- HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
- "Type:", "Contiguous");
- HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
- "Data address:", mesg->u.contig.addr);
- HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
- "Data Size:", mesg->u.contig.size);
- } /* end if */
- else {
- HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
- "Type:", "Compact");
- HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
- "Data Size:", mesg->u.compact.size);
- } /* end else */
+ switch(mesg->type) {
+ case H5D_CHUNKED:
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Type:", "Chunked");
+
+ /* Chunk # of dims & size */
+ HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Number of dimensions:",
+ (unsigned long)(mesg->u.chunk.ndims));
+ HDfprintf(stream, "%*s%-*s {", indent, "", fwidth, "Size:");
+ for(u = 0; u < mesg->u.chunk.ndims; u++)
+ HDfprintf(stream, "%s%lu", u ? ", " : "", (unsigned long)(mesg->u.chunk.dim[u]));
+ HDfprintf(stream, "}\n");
+
+ /* Index information */
+ switch(mesg->storage.u.chunk.idx_type) {
+ case H5D_CHUNK_BTREE:
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Index Type:", "v1 B-tree");
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
+ "B-tree address:", mesg->storage.u.chunk.idx_addr);
+ break;
+
+ default:
+ HDfprintf(stream, "%*s%-*s %s (%u)\n", indent, "", fwidth,
+ "Index Type:", "Unknown", (unsigned)mesg->storage.u.chunk.idx_type);
+ break;
+ } /* end switch */
+ break;
+
+ case H5D_CONTIGUOUS:
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Type:", "Contiguous");
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
+ "Data address:", mesg->storage.u.contig.addr);
+ HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
+ "Data Size:", mesg->storage.u.contig.size);
+ break;
+
+ case H5D_COMPACT:
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Type:", "Compact");
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "Data Size:", mesg->storage.u.compact.size);
+ break;
+
+ default:
+ HDfprintf(stream, "%*s%-*s %s (%u)\n", indent, "", fwidth,
+ "Type:", "Unknown", (unsigned)mesg->type);
+ break;
+ } /* end switch */
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_layout_debug() */
diff --git a/src/H5Olinfo.c b/src/H5Olinfo.c
index 384353c..ba5ec56 100644
--- a/src/H5Olinfo.c
+++ b/src/H5Olinfo.c
@@ -35,7 +35,8 @@
/* PRIVATE PROTOTYPES */
-static void *H5O_linfo_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_linfo_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_linfo_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
static void *H5O_linfo_copy(const void *_mesg, void *_dest);
static size_t H5O_linfo_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
@@ -110,8 +111,8 @@ H5FL_DEFINE_STATIC(H5O_linfo_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_linfo_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_linfo_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_linfo_t *linfo = NULL; /* Link info */
unsigned char index_flags; /* Flags for encoding link index info */
@@ -165,7 +166,7 @@ H5O_linfo_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
done:
if(ret_value == NULL)
if(linfo != NULL)
- H5FL_FREE(H5O_linfo_t, linfo);
+ (void)H5FL_FREE(H5O_linfo_t, linfo);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_linfo_decode() */
@@ -320,7 +321,7 @@ H5O_linfo_free(void *mesg)
HDassert(mesg);
- H5FL_FREE(H5O_linfo_t, mesg);
+ (void)H5FL_FREE(H5O_linfo_t, mesg);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_linfo_free() */
@@ -376,11 +377,12 @@ done:
*/
static void *
H5O_linfo_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst,
- hbool_t UNUSED *recompute_size, H5O_copy_t *cpy_info, void UNUSED *udata,
+ hbool_t UNUSED *recompute_size, H5O_copy_t *cpy_info, void *_udata,
hid_t dxpl_id)
{
H5O_linfo_t *linfo_src = (H5O_linfo_t *) native_src;
H5O_linfo_t *linfo_dst = NULL;
+ H5G_copy_file_ud_t *udata = (H5G_copy_file_ud_t *) _udata;
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_linfo_copy_file)
@@ -390,7 +392,7 @@ H5O_linfo_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst,
HDassert(cpy_info);
/* Copy the source message */
- if(NULL == (linfo_dst = H5O_linfo_copy(linfo_src, NULL)))
+ if(NULL == (linfo_dst = (H5O_linfo_t *)H5O_linfo_copy(linfo_src, NULL)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "memory allocation failed")
/* If we are performing a 'shallow hierarchy' copy, and the links in this
@@ -410,7 +412,8 @@ H5O_linfo_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst,
* dense link storage components and use those - QAK)
*/
if(H5F_addr_defined(linfo_src->fheap_addr)) {
- if(H5G_dense_create(file_dst, dxpl_id, linfo_dst) < 0)
+ /* Create the dense link storage */
+ if(H5G_dense_create(file_dst, dxpl_id, linfo_dst, udata->common.src_pline) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create 'dense' form of new format group")
} /* end if */
} /* end else */
@@ -421,7 +424,7 @@ H5O_linfo_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst,
done:
if(!ret_value)
if(linfo_dst)
- H5FL_FREE(H5O_linfo_t, linfo_dst);
+ (void)H5FL_FREE(H5O_linfo_t, linfo_dst);
FUNC_LEAVE_NOAPI(ret_value)
} /* H5O_linfo_copy_file() */
diff --git a/src/H5Olink.c b/src/H5Olink.c
index 175c937..ffe80e7 100644
--- a/src/H5Olink.c
+++ b/src/H5Olink.c
@@ -38,7 +38,8 @@
/* PRIVATE PROTOTYPES */
-static void *H5O_link_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_link_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_link_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
static void *H5O_link_copy(const void *_mesg, void *_dest);
static size_t H5O_link_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
@@ -115,8 +116,8 @@ H5FL_DEFINE_STATIC(H5O_link_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_link_t *lnk = NULL; /* Pointer to link message */
size_t len = 0; /* Length of a string in the message */
@@ -145,7 +146,7 @@ H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
/* Check for non-default link type */
if(link_flags & H5O_LINK_STORE_LINK_TYPE) {
/* Get the type of the link */
- lnk->type = *p++;
+ lnk->type = (H5L_type_t)*p++;
if(lnk->type < H5L_TYPE_HARD || lnk->type > H5L_TYPE_MAX)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad link type")
} /* end if */
@@ -197,7 +198,7 @@ H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "invalid name length")
/* Get the link's name */
- if(NULL == (lnk->name = H5MM_malloc(len + 1)))
+ if(NULL == (lnk->name = (char *)H5MM_malloc(len + 1)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
HDmemcpy(lnk->name, p, len);
lnk->name[len] = '\0';
@@ -215,7 +216,7 @@ H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
UINT16DECODE(p, len)
if(len == 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "invalid link length")
- if(NULL == (lnk->u.soft.name = H5MM_malloc((size_t)len + 1)))
+ if(NULL == (lnk->u.soft.name = (char *)H5MM_malloc((size_t)len + 1)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
HDmemcpy(lnk->u.soft.name, p, len);
lnk->u.soft.name[len] = '\0';
@@ -253,7 +254,7 @@ done:
H5MM_xfree(lnk->u.soft.name);
if(lnk->type >= H5L_TYPE_UD_MIN && lnk->u.ud.size > 0 && lnk->u.ud.udata != NULL)
H5MM_xfree(lnk->u.ud.udata);
- H5FL_FREE(H5O_link_t, lnk);
+ (void)H5FL_FREE(H5O_link_t, lnk);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -323,7 +324,7 @@ H5O_link_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const void
/* Store the link name's length */
switch(link_flags & H5O_LINK_NAME_SIZE) {
case 0: /* 1 byte size */
- *p++ = len;
+ *p++ = (uint8_t)len;
break;
case 1: /* 2 byte size */
@@ -534,12 +535,12 @@ H5O_link_reset(void *_mesg)
if(lnk) {
/* Free information for link (but don't free link pointer) */
if(lnk->type == H5L_TYPE_SOFT)
- lnk->u.soft.name = H5MM_xfree(lnk->u.soft.name);
+ lnk->u.soft.name = (char *)H5MM_xfree(lnk->u.soft.name);
else if (lnk->type >= H5L_TYPE_UD_MIN) {
if(lnk->u.ud.size > 0)
lnk->u.ud.udata = H5MM_xfree(lnk->u.ud.udata);
} /* end if */
- lnk->name = H5MM_xfree(lnk->name);
+ lnk->name = (char *)H5MM_xfree(lnk->name);
} /* end if */
FUNC_LEAVE_NOAPI(SUCCEED)
@@ -569,7 +570,7 @@ H5O_link_free(void *_mesg)
/* Free information for link */
H5O_link_reset(lnk);
- H5FL_FREE(H5O_link_t, lnk);
+ (void)H5FL_FREE(H5O_link_t, lnk);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_link_free() */
@@ -627,17 +628,17 @@ H5O_link_delete(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, void *_mesg)
hid_t file_id; /* ID for the file the link is located in (passed to user callback) */
/* Get a file ID for the file the link is in */
- if((file_id = H5F_get_id(f)) < 0)
+ if((file_id = H5F_get_id(f, FALSE)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get file ID")
/* Call user-defined link's 'delete' callback */
if((link_class->del_func)(lnk->name, file_id, lnk->u.ud.udata, lnk->u.ud.size) < 0) {
- H5I_dec_ref(file_id);
+ H5I_dec_ref(file_id, FALSE);
HGOTO_ERROR(H5E_OHDR, H5E_CALLBACK, FAIL, "link deletion callback returned failure")
} /* end if */
/* Release the file ID */
- if(H5I_dec_ref(file_id) < 0)
+ if(H5I_dec_ref(file_id, FALSE) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCLOSEFILE, FAIL, "can't close file")
} /* end if */
} /* end if */
@@ -836,7 +837,7 @@ H5O_link_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE *
default:
if(lnk->type >= H5L_TYPE_UD_MIN) {
if(lnk->type == H5L_TYPE_EXTERNAL) {
- const char * objname = (const char *)lnk->u.ud.udata + (HDstrlen(lnk->u.ud.udata) + 1);
+ const char *objname = (const char *)lnk->u.ud.udata + (HDstrlen((const char *)lnk->u.ud.udata) + 1);
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
"External File Name:", lnk->u.ud.udata);
diff --git a/src/H5Omessage.c b/src/H5Omessage.c
index 3e3a87a..02379e4 100644
--- a/src/H5Omessage.c
+++ b/src/H5Omessage.c
@@ -74,7 +74,7 @@ typedef struct {
/********************/
static herr_t H5O_msg_reset_real(const H5O_msg_class_t *type, void *native);
-static herr_t H5O_msg_remove_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
+static herr_t H5O_msg_remove_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
unsigned sequence, hbool_t *oh_modified, void *_udata/*in,out*/);
static herr_t H5O_copy_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx,
const H5O_msg_class_t *type, const void *mesg, unsigned mesg_flags,
@@ -393,7 +393,7 @@ H5O_msg_write_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *ty
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message type not found")
/* Check for modifying a constant message */
- if(idx_msg->flags & H5O_MSG_FLAG_CONSTANT)
+ if(!(update_flags & H5O_UPDATE_FORCE) && (idx_msg->flags & H5O_MSG_FLAG_CONSTANT))
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify constant message")
/* This message is shared, but it's being modified. */
else if((idx_msg->flags & H5O_MSG_FLAG_SHARED) || (idx_msg->flags & H5O_MSG_FLAG_SHAREABLE)) {
@@ -488,7 +488,7 @@ H5O_msg_read(const H5O_loc_t *loc, unsigned type_id, void *mesg,
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, NULL, "unable to load object header")
/* Call the "real" read routine */
- if(NULL == (ret_value = H5O_msg_read_real(loc->file, dxpl_id, oh, type_id, mesg)))
+ if(NULL == (ret_value = H5O_msg_read_oh(loc->file, dxpl_id, oh, type_id, mesg)))
HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to load object header")
done:
@@ -500,7 +500,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5O_msg_read_real
+ * Function: H5O_msg_read_oh
*
* Purpose: Reads a message from an object header and returns a pointer
* to it. The caller will usually supply the memory through
@@ -523,14 +523,14 @@ done:
*-------------------------------------------------------------------------
*/
void *
-H5O_msg_read_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id,
+H5O_msg_read_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id,
void *mesg)
{
const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
unsigned idx; /* Message's index in object header */
void *ret_value = NULL;
- FUNC_ENTER_NOAPI_NOINIT(H5O_msg_read_real)
+ FUNC_ENTER_NOAPI_NOINIT(H5O_msg_read_oh)
/* check args */
HDassert(f);
@@ -550,7 +550,7 @@ H5O_msg_read_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id,
* Decode the message if necessary. If the message is shared then retrieve
* native message through the shared interface.
*/
- H5O_LOAD_NATIVE(f, dxpl_id, oh, &(oh->mesg[idx]), NULL)
+ H5O_LOAD_NATIVE(f, dxpl_id, 0, oh, &(oh->mesg[idx]), NULL)
/*
* The object header caches the native message (along with
@@ -562,7 +562,7 @@ H5O_msg_read_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id,
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_msg_read_real() */
+} /* end H5O_msg_read_oh() */
/*-------------------------------------------------------------------------
@@ -1299,7 +1299,7 @@ H5O_msg_iterate_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type,
for(sequence = 0, idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs && !ret_value; idx++, idx_msg++) {
if(type == idx_msg->type) {
/* Decode the message if necessary. */
- H5O_LOAD_NATIVE(f, dxpl_id, oh, idx_msg, FAIL)
+ H5O_LOAD_NATIVE(f, dxpl_id, 0, oh, idx_msg, FAIL)
/* Check for making an "internal" (i.e. within the H5O package) callback */
if(op->op_type == H5O_MESG_OP_LIB)
@@ -1421,7 +1421,7 @@ H5O_msg_size_f(const H5F_t *f, hid_t ocpl_id, unsigned type_id,
HDassert(mesg);
/* Get the property list */
- if(NULL == (ocpl = H5I_object(ocpl_id)))
+ if(NULL == (ocpl = (H5P_genplist_t *)H5I_object(ocpl_id)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, 0, "not a property list")
/* Get any object header status flags set by properties */
@@ -1653,7 +1653,7 @@ H5O_msg_set_share(unsigned type_id, const H5O_shared_t *share, void *mesg)
HDassert(share);
HDassert(share->type != H5O_SHARE_TYPE_UNSHARED);
- /* If there's a special action for this class that needs to be performed
+ /* If there's a special action for this class that needs to be performed
* when setting the shared component, do that
*/
if(type->set_share) {
@@ -1804,13 +1804,20 @@ done:
* slu@ncsa.uiuc.edu
* July 14, 2004
*
+ * Modifications: Neil Fortner
+ * Feb 4 2009
+ * Added open_oh parameter. This parameter is optional and
+ * contains this message's protected object header
+ *
*-------------------------------------------------------------------------
*/
void *
-H5O_msg_decode(H5F_t *f, hid_t dxpl_id, unsigned type_id, const unsigned char *buf)
+H5O_msg_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned type_id,
+ const unsigned char *buf)
{
const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
void *ret_value; /* Return value */
+ unsigned ioflags = 0; /* Flags for decode routine */
FUNC_ENTER_NOAPI(H5O_msg_decode, NULL)
@@ -1821,7 +1828,7 @@ H5O_msg_decode(H5F_t *f, hid_t dxpl_id, unsigned type_id, const unsigned char *b
HDassert(type);
/* decode */
- if((ret_value = (type->decode)(f, dxpl_id, 0, buf)) == NULL)
+ if((ret_value = (type->decode)(f, dxpl_id, open_oh, 0, &ioflags, buf)) == NULL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode message")
done:
@@ -2078,7 +2085,7 @@ H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_mesg_t *mesg)
/* Check if there is a file space deletion callback for this type of message */
if(type->del) {
/* Decode the message if necessary. */
- H5O_LOAD_NATIVE(f, dxpl_id, oh, mesg, FAIL)
+ H5O_LOAD_NATIVE(f, dxpl_id, H5O_DECODEIO_NOCHANGE, oh, mesg, FAIL)
if((type->del)(f, dxpl_id, oh, mesg->native) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message")
@@ -2228,6 +2235,12 @@ H5O_flush_msgs(H5F_t *f, H5O_t *oh)
if(oh->nmesgs != u)
HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "corrupt object header - too few messages")
+#ifndef NDEBUG
+ /* Reset the number of messages dirtied by decoding, as they have all
+ * been flushed */
+ oh->ndecode_dirtied = 0;
+#endif /* NDEBUG */
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_flush_msgs() */
diff --git a/src/H5Omtime.c b/src/H5Omtime.c
index df4bdd4..1bbcfe3 100644
--- a/src/H5Omtime.c
+++ b/src/H5Omtime.c
@@ -28,11 +28,13 @@
#include "H5Opkg.h" /* Object headers */
-static void *H5O_mtime_new_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_mtime_new_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_mtime_new_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
static size_t H5O_mtime_new_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
-static void *H5O_mtime_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_mtime_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_mtime_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
static void *H5O_mtime_copy(const void *_mesg, void *_dest);
static size_t H5O_mtime_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
@@ -117,8 +119,8 @@ H5FL_DEFINE(time_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_mtime_new_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_mtime_new_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
time_t *mesg;
uint32_t tmp_time; /* Temporary copy of the time */
@@ -170,8 +172,8 @@ done:
*-------------------------------------------------------------------------
*/
static void *
-H5O_mtime_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_mtime_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
time_t *mesg, the_time;
int i;
@@ -242,7 +244,7 @@ H5O_mtime_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_fla
the_time -= tz.tz_minuteswest * 60 - (tm.tm_isdst ? 3600 : 0);
}
-#else
+#else
/*
* The catch-all. If we can't convert a character string universal
* coordinated time to a time_t value reliably then we can't decode the
@@ -494,16 +496,16 @@ H5O_mtime_reset(void UNUSED *_mesg)
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_mtime_free (void *mesg)
+H5O_mtime_free(void *mesg)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_mtime_free);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_mtime_free)
- assert (mesg);
+ HDassert(mesg);
- H5FL_FREE(time_t,mesg);
+ (void)H5FL_FREE(time_t, mesg);
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_mtime_free() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Oname.c b/src/H5Oname.c
index 44ab432..5ffa870 100644
--- a/src/H5Oname.c
+++ b/src/H5Oname.c
@@ -33,7 +33,8 @@
/* PRIVATE PROTOTYPES */
-static void *H5O_name_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_name_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_name_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
static void *H5O_name_copy(const void *_mesg, void *_dest);
static size_t H5O_name_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
@@ -83,35 +84,35 @@ const H5O_msg_class_t H5O_MSG_NAME[1] = {{
*-------------------------------------------------------------------------
*/
static void *
-H5O_name_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_name_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_name_t *mesg;
void *ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_name_decode);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_name_decode)
/* check args */
- assert(f);
- assert(p);
+ HDassert(f);
+ HDassert(p);
/* decode */
- if (NULL==(mesg = H5MM_calloc(sizeof(H5O_name_t))) ||
- NULL==(mesg->s = H5MM_malloc (HDstrlen((const char*)p)+1)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- HDstrcpy(mesg->s, (const char*)p);
+ if(NULL == (mesg = (H5O_name_t *)H5MM_calloc(sizeof(H5O_name_t))) ||
+ NULL == (mesg->s = (char *)H5MM_malloc(HDstrlen((const char *)p) + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HDstrcpy(mesg->s, (const char *)p);
/* Set return value */
- ret_value=mesg;
+ ret_value = mesg;
done:
- if(ret_value==NULL) {
+ if(NULL == ret_value) {
if(mesg)
- H5MM_xfree (mesg);
+ H5MM_xfree(mesg);
} /* end if */
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_name_decode() */
/*-------------------------------------------------------------------------
@@ -173,24 +174,25 @@ H5O_name_copy(const void *_mesg, void *_dest)
H5O_name_t *dest = (H5O_name_t *) _dest;
void *ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_name_copy);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_name_copy)
/* check args */
- assert(mesg);
- if (!dest && NULL==(dest = H5MM_calloc(sizeof(H5O_name_t))))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ HDassert(mesg);
+
+ if(!dest && NULL == (dest = (H5O_name_t *)H5MM_calloc(sizeof(H5O_name_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* copy */
*dest = *mesg;
- if((dest->s = H5MM_xstrdup(mesg->s))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ if(NULL == (dest->s = H5MM_xstrdup(mesg->s)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Set return value */
- ret_value=dest;
+ ret_value = dest;
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_name_copy() */
/*-------------------------------------------------------------------------
@@ -252,16 +254,16 @@ H5O_name_reset(void *_mesg)
{
H5O_name_t *mesg = (H5O_name_t *) _mesg;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_name_reset);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_name_reset)
/* check args */
- assert(mesg);
+ HDassert(mesg);
/* reset */
- mesg->s = H5MM_xfree(mesg->s);
+ mesg->s = (char *)H5MM_xfree(mesg->s);
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_name_reset() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index a55ea1e..262386a 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -30,7 +30,7 @@
#define H5O_NMESGS 8 /*initial number of messages */
#define H5O_NCHUNKS 2 /*initial number of chunks */
#define H5O_MIN_SIZE 22 /* Min. obj header data size (must be big enough for a message prefix and a continuation message) */
-#define H5O_MSG_TYPES 24 /* # of types of messages */
+#define H5O_MSG_TYPES 25 /* # of types of messages */
#define H5O_MAX_CRT_ORDER_IDX 65535 /* Max. creation order index value */
/* Versions of object header structure */
@@ -43,7 +43,7 @@
*/
#define H5O_VERSION_2 2
-/* The latest version of the format. Look through the 'flush'
+/* The latest version of the format. Look through the 'flush'
* and 'size' callback for places to change when updating this. */
#define H5O_VERSION_LATEST H5O_VERSION_2
@@ -67,13 +67,6 @@
#define H5O_ALIGN_F(F, X) \
H5O_ALIGN_VERS((H5F_USE_LATEST_FORMAT(F) ? H5O_VERSION_LATEST : H5O_VERSION_1), X)
-/* Size of signature information (on disk) */
-#define H5O_SIZEOF_MAGIC 4
-
-/* Object header signatures */
-#define H5O_HDR_MAGIC "OHDR" /* Header */
-#define H5O_CHK_MAGIC "OCHK" /* Continuation chunk */
-
/* Size of checksum (on disk) */
#define H5O_SIZEOF_CHKSUM 4
@@ -106,7 +99,7 @@
4 + /*reference count */ \
4) /*chunk data size */ \
: \
- (H5O_SIZEOF_MAGIC + /*magic number */ \
+ (H5_SIZEOF_MAGIC + /*magic number */ \
1 + /*version number */ \
1 + /*flags */ \
(((O)->flags & H5O_HDR_STORE_TIMES) ? ( \
@@ -155,7 +148,7 @@
0 + /*no magic # */ \
0 /*no checksum */ \
: \
- H5O_SIZEOF_MAGIC + /*magic # */ \
+ H5_SIZEOF_MAGIC + /*magic # */ \
H5O_SIZEOF_CHKSUM /*checksum */ \
)
#define H5O_SIZEOF_CHKHDR_OH(O) \
@@ -174,17 +167,37 @@
#define H5O_SIZEOF_CHKSUM_OH(O) \
H5O_SIZEOF_CHKSUM_VERS((O)->version)
+/* Input/output flags for decode functions */
+#define H5O_DECODEIO_NOCHANGE 0x01u /* IN: do not modify values */
+#define H5O_DECODEIO_DIRTY 0x02u /* OUT: message has been changed */
+
+/* Macro to incremend ndecode_dirtied (only if we are debugging) */
+#ifndef NDEBUG
+#define INCR_NDECODE_DIRTIED(OH) (OH)->ndecode_dirtied++;
+#else /* NDEBUG */
+#define INCR_NDECODE_DIRTIED(OH) ;
+#endif /* NDEBUG */
+
/* Load native information for a message, if it's not already present */
/* (Only works for messages with decode callback) */
-#define H5O_LOAD_NATIVE(F, DXPL, OH, MSG, ERR) \
+#define H5O_LOAD_NATIVE(F, DXPL, IOF, OH, MSG, ERR) \
if(NULL == (MSG)->native) { \
const H5O_msg_class_t *msg_type = (MSG)->type; \
+ unsigned ioflags = (IOF); \
\
/* Decode the message */ \
HDassert(msg_type->decode); \
- if(NULL == ((MSG)->native = (msg_type->decode)((F), (DXPL), (MSG)->flags, (MSG)->raw))) \
+ if(NULL == ((MSG)->native = (msg_type->decode)((F), (DXPL), (OH), (MSG)->flags, &ioflags, (MSG)->raw))) \
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, ERR, "unable to decode message") \
\
+ /* Mark the message dirty if it was changed by decoding */ \
+ if((ioflags & H5O_DECODEIO_DIRTY) && (H5F_get_intent((F)) & H5F_ACC_RDWR)) { \
+ (MSG)->dirty = TRUE; \
+ /* Increment the count of messages dirtied by decoding, but */ \
+ /* only ifndef NDEBUG */ \
+ INCR_NDECODE_DIRTIED(OH) \
+ } \
+ \
/* Set the message's "shared info", if it's shareable */ \
if((MSG)->flags & H5O_MSG_FLAG_SHAREABLE) { \
H5O_UPDATE_SHARED((H5O_shared_t *)(MSG)->native, H5O_SHARE_TYPE_HERE, (F), msg_type->id, (MSG)->crt_idx, (OH)->chunk[0].addr) \
@@ -209,7 +222,7 @@ struct H5O_msg_class_t {
const char *name; /*for debugging */
size_t native_size; /*size of native message */
unsigned share_flags; /* Message sharing settings */
- void *(*decode)(H5F_t *, hid_t, unsigned, const uint8_t *);
+ void *(*decode)(H5F_t *, hid_t, H5O_t *, unsigned, unsigned *, const uint8_t *);
herr_t (*encode)(H5F_t *, hbool_t, uint8_t *, const void *);
void *(*copy)(const void *, void *); /*copy native value */
size_t (*raw_size)(const H5F_t *, hbool_t, const void *);/*sizeof encoded message */
@@ -253,12 +266,20 @@ struct H5O_t {
/* File-specific information (not stored) */
size_t sizeof_size; /* Size of file sizes */
size_t sizeof_addr; /* Size of file addresses */
+
+ /* Misc. information (not stored) */
+ unsigned npins; /* Number of times the header is pinned */
+
+ /* Debugging information (not stored) */
#ifdef H5O_ENABLE_BAD_MESG_COUNT
hbool_t store_bad_mesg_count; /* Flag to indicate that a bad message count should be stored */
/* (This is to simulate a bug in earlier
* versions of the library)
*/
#endif /* H5O_ENABLE_BAD_MESG_COUNT */
+#ifndef NDEBUG
+ size_t ndecode_dirtied; /* Number of messages dirtied by decoding */
+#endif /* NDEBUG */
/* Object information (stored) */
hbool_t has_refcount_msg; /* Whether the object has a ref. count message */
@@ -289,13 +310,6 @@ struct H5O_t {
H5O_chunk_t *chunk; /*array of chunks */
};
-/* Callback information for copying dataset */
-typedef struct {
- struct H5S_extent_t *src_space_extent; /* Copy of dataspace extent for dataset */
- H5T_t *src_dtype; /* Copy of datatype for dataset */
- H5O_pline_t *src_pline; /* Copy of filter pipeline for dataet */
-} H5D_copy_file_ud_t;
-
/* Class for types of objects in file */
typedef struct H5O_obj_class_t {
H5O_type_t type; /*object type on disk */
@@ -303,9 +317,10 @@ typedef struct H5O_obj_class_t {
void *(*get_copy_file_udata)(void); /*retrieve user data for 'copy file' operation */
void (*free_copy_file_udata)(void *); /*free user data for 'copy file' operation */
htri_t (*isa)(H5O_t *); /*if a header matches an object class */
- hid_t (*open)(const H5G_loc_t *, hid_t ); /*open an object of this class */
+ hid_t (*open)(const H5G_loc_t *, hid_t, hid_t, hbool_t ); /*open an object of this class */
void *(*create)(H5F_t *, void *, H5G_loc_t *, hid_t ); /*create an object of this class */
H5O_loc_t *(*get_oloc)(hid_t ); /*get the object header location for an object */
+ herr_t (*bh_info)(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info); /*get the index & heap info for an object */
} H5O_obj_class_t;
/* Node in skip list to map addresses from one file to another during object header copy */
@@ -323,9 +338,6 @@ H5_DLLVAR const H5AC_class_t H5AC_OHDR[1];
/* Header message ID to class mapping */
H5_DLLVAR const H5O_msg_class_t *const H5O_msg_class_g[H5O_MSG_TYPES];
-/* Header object ID to class mapping */
-H5_DLLVAR const H5O_obj_class_t *const H5O_obj_class_g[3];
-
/* Declare external the free list for H5O_t's */
H5FL_EXTERN(H5O_t);
@@ -401,7 +413,7 @@ H5_DLLVAR const H5O_msg_class_t H5O_MSG_NAME[1];
*/
H5_DLLVAR const H5O_msg_class_t H5O_MSG_MTIME[1];
-/* Shared Message information message (0x000f)
+/* Shared Message information message (0x000f)
* A message for the superblock extension, holding information about
* the file-wide shared message "SOHM" table
*/
@@ -419,13 +431,13 @@ H5_DLLVAR const H5O_msg_class_t H5O_MSG_STAB[1];
*/
H5_DLLVAR const H5O_msg_class_t H5O_MSG_MTIME_NEW[1];
-/* v1 B-tree 'K' value message (0x0013)
+/* v1 B-tree 'K' value message (0x0013)
* A message for the superblock extension, holding information about
* the file-wide v1 B-tree 'K' values.
*/
H5_DLLVAR const H5O_msg_class_t H5O_MSG_BTREEK[1];
-/* Driver info message (0x0014)
+/* Driver info message (0x0014)
* A message for the superblock extension, holding information about
* the file driver settings
*/
@@ -437,9 +449,11 @@ H5_DLLVAR const H5O_msg_class_t H5O_MSG_AINFO[1];
/* Reference Count Message. (0x0016) */
H5_DLLVAR const H5O_msg_class_t H5O_MSG_REFCOUNT[1];
-/* Placeholder for unknown message. (0x0017) */
-H5_DLLVAR const H5O_msg_class_t H5O_MSG_UNKNOWN[1];
+/* Free-space Manager Info message. (0x0017) */
+H5_DLLVAR const H5O_msg_class_t H5O_MSG_FSINFO[1];
+/* Placeholder for unknown message. (0x0018) */
+H5_DLLVAR const H5O_msg_class_t H5O_MSG_UNKNOWN[1];
/*
* Object header "object" types
@@ -458,7 +472,7 @@ H5_DLLVAR const H5O_obj_class_t H5O_OBJ_DATATYPE[1];
/* Package-local function prototypes */
H5_DLL herr_t H5O_msg_flush(H5F_t *f, H5O_t *oh, H5O_mesg_t *mesg);
H5_DLL herr_t H5O_flush_msgs(H5F_t *f, H5O_t *oh);
-H5_DLL hid_t H5O_open_by_loc(const H5G_loc_t *obj_loc, hid_t dxpl_id);
+H5_DLL hid_t H5O_open_by_loc(const H5G_loc_t *obj_loc, hid_t lapl_id, hid_t dxpl_id, hbool_t app_ref);
H5_DLL herr_t H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_mesg_t *mesg);
H5_DLL const H5O_obj_class_t *H5O_obj_class_real(H5O_t *oh);
@@ -471,12 +485,9 @@ H5_DLL herr_t H5O_msg_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
H5_DLL herr_t H5O_msg_write_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
const H5O_msg_class_t *type, unsigned mesg_flags, unsigned update_flags,
void *mesg);
-H5_DLL void *H5O_msg_read_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
- unsigned type_id, void *mesg);
H5_DLL void *H5O_msg_free_real(const H5O_msg_class_t *type, void *mesg);
H5_DLL herr_t H5O_msg_free_mesg(H5O_mesg_t *mesg);
H5_DLL unsigned H5O_msg_count_real(const H5O_t *oh, const H5O_msg_class_t *type);
-H5_DLL htri_t H5O_msg_exists_oh(const H5O_t *oh, unsigned type_id);
H5_DLL herr_t H5O_msg_remove_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type,
int sequence, H5O_operator_t op, void *op_data, hbool_t adj_link, hid_t dxpl_id);
H5_DLL void *H5O_msg_copy_file(const H5O_msg_class_t *type, H5F_t *file_src,
@@ -486,10 +497,6 @@ H5_DLL herr_t H5O_msg_iterate_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *t
const H5O_mesg_operator_t *op, void *op_data, hid_t dxpl_id);
/* Collect storage info for btree and heap */
-H5_DLL herr_t H5O_group_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
- H5_ih_info_t *bh_info);
-H5_DLL herr_t H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
- H5_ih_info_t *bh_info);
H5_DLL herr_t H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
H5_ih_info_t *bh_info);
@@ -502,14 +509,15 @@ H5_DLL herr_t H5O_release_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
H5O_mesg_t *mesg, hbool_t adj_link);
/* Shared object operators */
-H5_DLL void * H5O_shared_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *buf, const H5O_msg_class_t *type);
+H5_DLL void * H5O_shared_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned *ioflags, const uint8_t *buf, const H5O_msg_class_t *type);
H5_DLL herr_t H5O_shared_encode(const H5F_t *f, uint8_t *buf/*out*/, const H5O_shared_t *sh_mesg);
H5_DLL size_t H5O_shared_size(const H5F_t *f, const H5O_shared_t *sh_mesg);
H5_DLL herr_t H5O_shared_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
const H5O_msg_class_t *mesg_type, H5O_shared_t *sh_mesg);
H5_DLL herr_t H5O_shared_link(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
const H5O_msg_class_t *mesg_type, H5O_shared_t *sh_mesg);
-H5_DLL herr_t H5O_shared_copy_file(H5F_t *file_src, H5F_t *file_dst,
+H5_DLL herr_t H5O_shared_copy_file(H5F_t *file_src, H5F_t *file_dst,
const H5O_msg_class_t *mesg_type, const void *_native_src, void *_native_dst,
hbool_t *recompute_size, H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
H5_DLL herr_t H5O_shared_post_copy_file (H5F_t *f, hid_t dxpl_id, H5O_t *oh, void *mesg);
@@ -520,6 +528,9 @@ H5_DLL herr_t H5O_shared_debug(const H5O_shared_t *mesg, FILE *stream,
H5_DLL herr_t H5O_attr_reset(void *_mesg);
H5_DLL herr_t H5O_attr_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg);
H5_DLL herr_t H5O_attr_link(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg);
+H5_DLL herr_t H5O_attr_count_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
+ hsize_t *nattrs);
+
/* These functions operate on object locations */
H5_DLL H5O_loc_t *H5O_get_loc(hid_t id);
diff --git a/src/H5Opline.c b/src/H5Opline.c
index 9a926c1..0a50963 100644
--- a/src/H5Opline.c
+++ b/src/H5Opline.c
@@ -24,6 +24,7 @@
#define H5Z_PACKAGE /*suppress error about including H5Zpkg */
#include "H5private.h" /* Generic Functions */
+#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
#include "H5FLprivate.h" /* Free Lists */
#include "H5MMprivate.h" /* Memory management */
@@ -33,12 +34,13 @@
/* PRIVATE PROTOTYPES */
static herr_t H5O_pline_encode(H5F_t *f, uint8_t *p, const void *mesg);
-static void *H5O_pline_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_pline_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static void *H5O_pline_copy(const void *_mesg, void *_dest);
static size_t H5O_pline_size(const H5F_t *f, const void *_mesg);
static herr_t H5O_pline_reset(void *_mesg);
static herr_t H5O_pline_free(void *_mesg);
-static herr_t H5O_pline_pre_copy_file(H5F_t *file_src,
+static herr_t H5O_pline_pre_copy_file(H5F_t *file_src,
const void *mesg_src, hbool_t *deleted, const H5O_copy_t *cpy_info, void *_udata);
static herr_t H5O_pline_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -106,8 +108,8 @@ H5FL_DEFINE(H5O_pline_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_pline_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_pline_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_pline_t *pline = NULL; /* Pipeline message */
H5Z_filter_info_t *filter; /* Filter to decode */
@@ -272,7 +274,7 @@ H5O_pline_encode(H5F_t UNUSED *f, uint8_t *p/*out*/, const void *mesg)
name = NULL;
} /* end if */
else {
- H5Z_class_t *cls; /* Filter class */
+ H5Z_class2_t *cls; /* Filter class */
/*
* Get the filter name. If the pipeline message has a name in it then
@@ -452,7 +454,7 @@ H5O_pline_size(const H5F_t UNUSED *f, const void *mesg)
if(pline->version > H5O_PLINE_VERSION_1 && pline->filter[i].id < H5Z_FILTER_RESERVED)
name_len = 0;
else {
- H5Z_class_t *cls; /* Filter class */
+ H5Z_class2_t *cls; /* Filter class */
/* Get the name of the filter, same as done with H5O_pline_encode() */
if(NULL == (name = pline->filter[i].name) && (cls = H5Z_find(pline->filter[i].id)))
@@ -542,9 +544,9 @@ H5O_pline_free(void *mesg)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_pline_free)
- HDassert (mesg);
+ HDassert(mesg);
- H5FL_FREE(H5O_pline_t, mesg);
+ (void)H5FL_FREE(H5O_pline_t, mesg);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_pline_free() */
@@ -570,7 +572,7 @@ H5O_pline_pre_copy_file(H5F_t UNUSED *file_src, const void *mesg_src,
hbool_t UNUSED *deleted, const H5O_copy_t UNUSED *cpy_info, void *_udata)
{
const H5O_pline_t *pline_src = (const H5O_pline_t *)mesg_src; /* Source datatype */
- H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; /* Dataset copying user data */
+ H5O_copy_file_ud_common_t *udata = (H5O_copy_file_ud_common_t *)_udata; /* Object copying user data */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_pline_pre_copy_file)
@@ -578,7 +580,7 @@ H5O_pline_pre_copy_file(H5F_t UNUSED *file_src, const void *mesg_src,
/* check args */
HDassert(pline_src);
- /* If the user data is non-NULL, assume we are copying a dataset
+ /* If the user data is non-NULL, assume we are copying a dataset or group
* and make a copy of the filter pipeline for later in
* the object copying process.
*/
@@ -663,3 +665,30 @@ H5O_pline_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *mesg, FILE *s
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_pline_debug() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_pline_set_latest_version
+ *
+ * Purpose: Set the encoding for a I/O filter pipeline to the latest version.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, July 24, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_pline_set_latest_version(H5O_pline_t *pline)
+{
+ FUNC_ENTER_NOAPI_NOFUNC(H5O_pline_set_latest_version)
+
+ /* Sanity check */
+ HDassert(pline);
+
+ /* Set encoding of I/O pipeline to latest version */
+ pline->version = H5O_PLINE_VERSION_LATEST;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_pline_set_latest_version() */
+
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index a6e81f8..df772cc 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -79,6 +79,7 @@ typedef struct H5O_t H5O_t;
/* Flags for updating messages */
#define H5O_UPDATE_TIME 0x01u
+#define H5O_UPDATE_FORCE 0x02u /* Force updating the message */
/* Hash value constants */
#define H5O_HASH_SIZE 32
@@ -87,6 +88,8 @@ typedef struct H5O_t H5O_t;
#define H5O_CRT_ATTR_MAX_COMPACT_NAME "max compact attr" /* Max. # of attributes to store compactly */
#define H5O_CRT_ATTR_MIN_DENSE_NAME "min dense attr" /* Min. # of attributes to store densely */
#define H5O_CRT_OHDR_FLAGS_NAME "object header flags" /* Object header flags */
+#define H5O_CRT_PIPELINE_NAME "pline" /* Filter pipeline */
+#define H5O_CRT_PIPELINE_DEF {{0, NULL, H5O_NULL_ID, {{0, HADDR_UNDEF}}}, H5O_PLINE_VERSION_1, 0, 0, NULL}
#ifdef H5O_ENABLE_BOGUS
#define H5O_BOGUS_MSG_FLAGS_NAME "bogus msg flags" /* Flags for 'bogus' message */
#define H5O_BOGUS_MSG_FLAGS_SIZE sizeof(uint8_t)
@@ -164,7 +167,8 @@ typedef struct H5O_copy_t {
#define H5O_DRVINFO_ID 0x0014 /* Driver info message. */
#define H5O_AINFO_ID 0x0015 /* Attribute info message. */
#define H5O_REFCOUNT_ID 0x0016 /* Reference count message. */
-#define H5O_UNKNOWN_ID 0x0017 /* Placeholder message ID for unknown message. */
+#define H5O_FSINFO_ID 0x0017 /* Free-space manager info message. */
+#define H5O_UNKNOWN_ID 0x0018 /* Placeholder message ID for unknown message. */
/* (this should never exist in a file) */
@@ -320,45 +324,88 @@ typedef struct H5O_efl_t {
H5O_efl_entry_t *slot; /*array of external file entries */
} H5O_efl_t;
+
/*
* Data Layout Message.
- * (Data structure in memory)
+ * (Data structure in file)
*/
#define H5O_LAYOUT_NDIMS (H5S_MAX_RANK+1)
+/* Initial version of the layout information. Used when space is allocated */
+#define H5O_LAYOUT_VERSION_1 1
+
+/* This version added support for delaying allocation */
+#define H5O_LAYOUT_VERSION_2 2
+
+/* This version is revised to store just the information needed for each
+ * storage type, and to straighten out problems with contiguous layout's
+ * sizes (was encoding them as 4-byte values when they were really n-byte
+ * values (where n usually is 8)).
+ */
+#define H5O_LAYOUT_VERSION_3 3
+
+/* This version adds different types of indices to chunked datasets */
+#define H5O_LAYOUT_VERSION_4 4
+
+/* The latest version of the format. Look through the 'encode'
+ * and 'size' callbacks for places to change when updating this. */
+#define H5O_LAYOUT_VERSION_LATEST H5O_LAYOUT_VERSION_4
+
+
/* Forward declaration of structs used below */
struct H5D_layout_ops_t; /* Defined in H5Dpkg.h */
struct H5D_chunk_ops_t; /* Defined in H5Dpkg.h */
-typedef struct H5O_layout_contig_t {
+typedef struct H5O_storage_contig_t {
haddr_t addr; /* File address of data */
hsize_t size; /* Size of data in bytes */
-} H5O_layout_contig_t;
+} H5O_storage_contig_t;
+
+typedef struct H5O_storage_chunk_btree_t {
+ H5RC_t *shared; /* Ref-counted shared info for B-tree nodes */
+} H5O_storage_chunk_btree_t;
+
+typedef struct H5O_storage_chunk_t {
+ H5D_chunk_index_t idx_type; /* Type of chunk index */
+ haddr_t idx_addr; /* File address of chunk index */
+ const struct H5D_chunk_ops_t *ops; /* Pointer to chunked storage operations */
+ union {
+ H5O_storage_chunk_btree_t btree; /* Information for v1 B-tree index */
+ } u;
+} H5O_storage_chunk_t;
+
+typedef struct H5O_storage_compact_t {
+ hbool_t dirty; /* Dirty flag for compact dataset */
+ size_t size; /* Size of buffer in bytes */
+ void *buf; /* Buffer for compact dataset */
+} H5O_storage_compact_t;
+
+typedef struct H5O_storage_t {
+ H5D_layout_t type; /* Type of layout */
+ union {
+ H5O_storage_contig_t contig; /* Information for contiguous storage */
+ H5O_storage_chunk_t chunk; /* Information for chunked storage */
+ H5O_storage_compact_t compact; /* Information for compact storage */
+ } u;
+} H5O_storage_t;
typedef struct H5O_layout_chunk_t {
- haddr_t addr; /* File address of B-tree */
unsigned ndims; /* Num dimensions in chunk */
uint32_t dim[H5O_LAYOUT_NDIMS]; /* Size of chunk in elements */
uint32_t size; /* Size of chunk in bytes */
- H5RC_t *btree_shared; /* Ref-counted info for B-tree nodes */
- const struct H5D_chunk_ops_t *ops; /* Pointer to chunked layout operations */
+ hsize_t nchunks; /* Number of chunks in dataset */
+ hsize_t chunks[H5O_LAYOUT_NDIMS]; /* # of chunks in dataset dimensions */
+ hsize_t down_chunks[H5O_LAYOUT_NDIMS]; /* "down" size of number of chunks in each dimension */
} H5O_layout_chunk_t;
-typedef struct H5O_layout_compact_t {
- hbool_t dirty; /* Dirty flag for compact dataset */
- size_t size; /* Size of buffer in bytes */
- void *buf; /* Buffer for compact dataset */
-} H5O_layout_compact_t;
-
typedef struct H5O_layout_t {
H5D_layout_t type; /* Type of layout */
unsigned version; /* Version of message */
const struct H5D_layout_ops_t *ops; /* Pointer to data layout I/O operations */
union {
- H5O_layout_contig_t contig; /* Information for contiguous layout */
H5O_layout_chunk_t chunk; /* Information for chunked layout */
- H5O_layout_compact_t compact; /* Information for compact layout */
} u;
+ H5O_storage_t storage; /* Information for storing dataset elements */
} H5O_layout_t;
/* Enable reading/writing "bogus" messages */
@@ -403,6 +450,20 @@ typedef struct H5O_ginfo_t {
* Filter pipeline message.
* (Data structure in memory)
*/
+
+/* The initial version of the format */
+#define H5O_PLINE_VERSION_1 1
+
+/* This version encodes the message fields more efficiently */
+/* (Drops the reserved bytes, doesn't align the name and doesn't encode the
+ * filter name at all if it's a filter provided by the library)
+ */
+#define H5O_PLINE_VERSION_2 2
+
+/* The latest version of the format. Look through the 'encode' and 'size'
+ * callbacks for places to change when updating this. */
+#define H5O_PLINE_VERSION_LATEST H5O_PLINE_VERSION_2
+
typedef struct H5O_pline_t {
H5O_shared_t sh_loc; /* Shared message info (must be first) */
@@ -507,6 +568,17 @@ typedef uint32_t H5O_refcount_t; /* Contains # of links to object, if >1
*/
typedef unsigned H5O_unknown_t; /* Original message type ID */
+/*
+ * Free space manager info Message.
+ * Contains file space management info and
+ * addresses of free space managers for file memory
+ * (Data structure in memory)
+ */
+typedef struct H5O_fsinfo_t {
+ H5F_file_space_type_t strategy; /* File space strategy */
+ hsize_t threshold; /* Free space section threshold */
+ haddr_t fs_addr[H5FD_MEM_NTYPES-1]; /* Addresses of free space managers */
+} H5O_fsinfo_t;
/* Typedef for "application" iteration operations */
typedef herr_t (*H5O_operator_t)(const void *mesg/*in*/, unsigned idx,
@@ -517,11 +589,13 @@ typedef herr_t (*H5O_lib_operator_t)(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
unsigned sequence, hbool_t *oh_modified/*out*/, void *operator_data/*in,out*/);
/* Some syntactic sugar to make the compiler happy with two different kinds of iterator callbacks */
+typedef enum H5O_mesg_operator_type_t {
+ H5O_MESG_OP_APP, /* Application callback */
+ H5O_MESG_OP_LIB /* Library internal callback */
+} H5O_mesg_operator_type_t;
+
typedef struct {
- enum {
- H5O_MESG_OP_APP, /* Application callback */
- H5O_MESG_OP_LIB /* Library internal callback */
- } op_type;
+ H5O_mesg_operator_type_t op_type;
union {
H5O_operator_t app_op; /* Application callback for each message */
H5O_lib_operator_t lib_op; /* Library internal callback for each message */
@@ -546,8 +620,9 @@ H5_DLL herr_t H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint,
H5_DLL herr_t H5O_open(H5O_loc_t *loc);
H5_DLL herr_t H5O_close(H5O_loc_t *loc);
H5_DLL int H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id);
-H5_DLL H5O_t *H5O_protect(H5O_loc_t *loc, hid_t dxpl_id);
-H5_DLL herr_t H5O_unprotect(H5O_loc_t *loc, H5O_t *oh);
+H5_DLL int H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, unsigned *oh_flags);
+H5_DLL H5O_t *H5O_pin(H5O_loc_t *loc, hid_t dxpl_id);
+H5_DLL herr_t H5O_unpin(H5O_loc_t *loc, H5O_t *oh);
H5_DLL herr_t H5O_touch(H5O_loc_t *loc, hbool_t force, hid_t dxpl_id);
H5_DLL herr_t H5O_touch_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
hbool_t force);
@@ -555,11 +630,12 @@ H5_DLL herr_t H5O_touch_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
H5_DLL herr_t H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned mesg_flags);
#endif /* H5O_ENABLE_BOGUS */
H5_DLL herr_t H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr);
+H5_DLL herr_t H5O_get_hdr_info(const H5O_loc_t *oloc, hid_t dxpl_id, H5O_hdr_info_t *hdr);
H5_DLL herr_t H5O_get_info(const H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info,
H5O_info_t *oinfo);
H5_DLL herr_t H5O_obj_type(const H5O_loc_t *loc, H5O_type_t *obj_type, hid_t dxpl_id);
H5_DLL herr_t H5O_get_create_plist(const H5O_loc_t *loc, hid_t dxpl_id, struct H5P_genplist_t *oc_plist);
-H5_DLL hid_t H5O_open_name(H5G_loc_t *loc, const char *name, hid_t lapl_id);
+H5_DLL hid_t H5O_open_name(H5G_loc_t *loc, const char *name, hid_t lapl_id, hbool_t app_ref);
H5_DLL herr_t H5O_get_nlinks(const H5O_loc_t *loc, hid_t dxpl_id, hsize_t *nlinks);
H5_DLL void *H5O_obj_create(H5F_t *f, H5O_type_t obj_type, void *crt_info, H5G_loc_t *obj_loc, hid_t dxpl_id);
H5_DLL haddr_t H5O_get_oh_addr(const H5O_t *oh);
@@ -576,11 +652,14 @@ H5_DLL herr_t H5O_msg_write_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
unsigned type_id, unsigned mesg_flags, unsigned update_flags, void *mesg);
H5_DLL void *H5O_msg_read(const H5O_loc_t *loc, unsigned type_id, void *mesg,
hid_t dxpl_id);
+H5_DLL void *H5O_msg_read_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id,
+ void *mesg);
H5_DLL herr_t H5O_msg_reset(unsigned type_id, void *native);
H5_DLL void *H5O_msg_free(unsigned type_id, void *mesg);
H5_DLL void *H5O_msg_copy(unsigned type_id, const void *mesg, void *dst);
H5_DLL int H5O_msg_count(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id);
H5_DLL htri_t H5O_msg_exists(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id);
+H5_DLL htri_t H5O_msg_exists_oh(const H5O_t *oh, unsigned type_id);
H5_DLL herr_t H5O_msg_remove(const H5O_loc_t *loc, unsigned type_id, int sequence,
hbool_t adj_link, hid_t dxpl_id);
H5_DLL herr_t H5O_msg_remove_op(const H5O_loc_t *loc, unsigned type_id, int sequence,
@@ -603,8 +682,8 @@ H5_DLL herr_t H5O_msg_get_crt_index(unsigned type_id, const void *mesg,
H5O_msg_crt_idx_t *crt_idx);
H5_DLL herr_t H5O_msg_encode(H5F_t *f, unsigned type_id, hbool_t disable_shared,
unsigned char *buf, const void *obj);
-H5_DLL void* H5O_msg_decode(H5F_t *f, hid_t dxpl_id, unsigned type_id,
- const unsigned char *buf);
+H5_DLL void* H5O_msg_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned type_id, const unsigned char *buf);
H5_DLL herr_t H5O_msg_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
unsigned type_id, void *mesg);
@@ -626,9 +705,6 @@ H5_DLL herr_t H5O_loc_copy(H5O_loc_t *dst, const H5O_loc_t *src, H5_copy_depth_t
H5_DLL herr_t H5O_loc_hold_file(H5O_loc_t *loc);
H5_DLL herr_t H5O_loc_free(H5O_loc_t *loc);
-/* Layout operators */
-H5_DLL size_t H5O_layout_meta_size(const H5F_t *f, const void *_mesg);
-
/* EFL operators */
H5_DLL hsize_t H5O_efl_total_size(H5O_efl_t *efl);
@@ -641,11 +717,11 @@ H5_DLL herr_t H5O_fill_set_latest_version(H5O_fill_t *fill);
H5_DLL herr_t H5O_link_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
void *_mesg);
+/* Filter pipeline operators */
+H5_DLL herr_t H5O_pline_set_latest_version(H5O_pline_t *pline);
+
/* Shared message operators */
H5_DLL herr_t H5O_set_shared(H5O_shared_t *dst, const H5O_shared_t *src);
-/* Attribute operators */
-H5_DLL hsize_t H5O_attr_count_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh);
-
#endif /* _H5Oprivate_H */
diff --git a/src/H5Opublic.h b/src/H5Opublic.h
index acce42c..84fdecc 100644
--- a/src/H5Opublic.h
+++ b/src/H5Opublic.h
@@ -87,6 +87,24 @@ typedef enum H5O_type_t {
H5O_TYPE_NTYPES /* Number of different object types (must be last!) */
} H5O_type_t;
+/* Information struct for object header metadata (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) */
+typedef struct H5O_hdr_info_t {
+ unsigned version; /* Version number of header format in file */
+ unsigned nmesgs; /* Number of object header messages */
+ unsigned nchunks; /* Number of object header chunks */
+ unsigned flags; /* Object header status flags */
+ struct {
+ hsize_t total; /* Total space for storing object header in file */
+ hsize_t meta; /* Space within header for object header metadata information */
+ hsize_t mesg; /* Space within header for actual message information */
+ hsize_t free; /* Free space within object header */
+ } space;
+ struct {
+ uint64_t present; /* Flags to indicate presence of message type in header */
+ uint64_t shared; /* Flags to indicate message type is shared in header */
+ } mesg;
+} H5O_hdr_info_t;
+
/* Information struct for object (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) */
typedef struct H5O_info_t {
unsigned long fileno; /* File number that object is located in */
@@ -98,22 +116,7 @@ typedef struct H5O_info_t {
time_t ctime; /* Change time */
time_t btime; /* Birth time */
hsize_t num_attrs; /* # of attributes attached to object */
- struct {
- unsigned version; /* Version number of header format in file */
- unsigned nmesgs; /* Number of object header messages */
- unsigned nchunks; /* Number of object header chunks */
- unsigned flags; /* Object header status flags */
- struct {
- hsize_t total; /* Total space for storing object header in file */
- hsize_t meta; /* Space within header for object header metadata information */
- hsize_t mesg; /* Space within header for actual message information */
- hsize_t free; /* Free space within object header */
- } space;
- struct {
- uint64_t present; /* Flags to indicate presence of message type in header */
- uint64_t shared; /* Flags to indicate message type is shared in header */
- } mesg;
- } hdr;
+ H5O_hdr_info_t hdr; /* Object header information */
/* Extra metadata storage for obj & attributes */
struct {
H5_ih_info_t obj; /* v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets */
@@ -171,7 +174,7 @@ H5_DLL herr_t H5Ovisit_by_name(hid_t loc_id, const char *obj_name,
H5_DLL herr_t H5Oclose(hid_t object_id);
/* Symbols defined for compatibility with previous versions of the HDF5 API.
- *
+ *
* Use of these symbols is deprecated.
*/
#ifndef H5_NO_DEPRECATED_SYMBOLS
diff --git a/src/H5Orefcount.c b/src/H5Orefcount.c
index 0a06d11..2f00e86 100644
--- a/src/H5Orefcount.c
+++ b/src/H5Orefcount.c
@@ -33,7 +33,8 @@
/* PRIVATE PROTOTYPES */
-static void *H5O_refcount_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_refcount_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_refcount_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
static void *H5O_refcount_copy(const void *_mesg, void *_dest);
static size_t H5O_refcount_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
@@ -89,8 +90,8 @@ H5FL_DEFINE_STATIC(H5O_refcount_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_refcount_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_refcount_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_refcount_t *refcount = NULL; /* Reference count */
void *ret_value; /* Return value */
@@ -117,7 +118,7 @@ H5O_refcount_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_
done:
if(ret_value == NULL && refcount != NULL)
- H5FL_FREE(H5O_refcount_t, refcount);
+ (void)H5FL_FREE(H5O_refcount_t, refcount);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_refcount_decode() */
@@ -249,7 +250,7 @@ H5O_refcount_free(void *mesg)
HDassert(mesg);
- H5FL_FREE(H5O_refcount_t, mesg);
+ (void)H5FL_FREE(H5O_refcount_t, mesg);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_refcount_free() */
diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c
index 414aa98..d7dccbd 100644
--- a/src/H5Osdspace.c
+++ b/src/H5Osdspace.c
@@ -17,6 +17,7 @@
#define H5S_PACKAGE /*prevent warning from including H5Spkg.h */
#include "H5private.h" /* Generic Functions */
+#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
#include "H5FLprivate.h" /* Free lists */
#include "H5Gprivate.h" /* Groups */
@@ -26,7 +27,8 @@
/* PRIVATE PROTOTYPES */
-static void *H5O_sdspace_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_sdspace_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_sdspace_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_sdspace_copy(const void *_mesg, void *_dest);
static size_t H5O_sdspace_size(const H5F_t *f, const void *_mesg);
@@ -108,8 +110,8 @@ H5FL_ARR_EXTERN(hsize_t);
within this function using malloc() and is returned to the caller.
--------------------------------------------------------------------------*/
static void *
-H5O_sdspace_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_sdspace_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5S_extent_t *sdim = NULL;/* New extent dimensionality structure */
void *ret_value;
@@ -189,7 +191,7 @@ H5O_sdspace_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
done:
if(!ret_value && sdim) {
H5S_extent_release(sdim);
- H5FL_FREE(H5S_extent_t, sdim);
+ (void)H5FL_FREE(H5S_extent_t, sdim);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -413,7 +415,7 @@ H5O_sdspace_free(void *mesg)
HDassert(mesg);
- H5FL_FREE(H5S_extent_t, mesg);
+ (void)H5FL_FREE(H5S_extent_t, mesg);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_sdspace_free() */
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index e406065..fd7cc8b 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -107,8 +107,8 @@
*-------------------------------------------------------------------------
*/
static void *
-H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared,
- const H5O_msg_class_t *type)
+H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned *ioflags,
+ const H5O_shared_t *shared, const H5O_msg_class_t *type)
{
H5HF_t *fheap = NULL;
H5WB_t *wb = NULL; /* Wrapped buffer for attribute data */
@@ -151,7 +151,7 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared,
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't wrap buffer")
/* Get a pointer to a buffer that's large enough for message */
- if(NULL == (mesg_ptr = H5WB_actual(wb, mesg_size)))
+ if(NULL == (mesg_ptr = (uint8_t *)H5WB_actual(wb, mesg_size)))
HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Retrieve the message from the heap */
@@ -159,7 +159,7 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared,
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "can't read message from fractal heap.")
/* Decode the message */
- if(NULL == (ret_value = (type->decode)(f, dxpl_id, 0, mesg_ptr)))
+ if(NULL == (ret_value = (type->decode)(f, dxpl_id, open_oh, 0, ioflags, mesg_ptr)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "can't decode shared message.")
} /* end if */
else {
@@ -167,12 +167,22 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared,
HDassert(shared->type == H5O_SHARE_TYPE_COMMITTED);
- /* Get the shared message from an object header */
+ /* Build the object location for the shared message's object header */
oloc.file = f;
oloc.addr = shared->u.loc.oh_addr;
oloc.holding_file = FALSE;
- if(NULL == (ret_value = H5O_msg_read(&oloc, type->id, NULL, dxpl_id)))
- HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read message")
+
+ if(open_oh && oloc.addr == H5O_OH_GET_ADDR(open_oh)) {
+ /* The shared message is in the already opened object header. This
+ * is possible, for example, if an attribute's datatype is shared in
+ * the same object header the attribute is in. Read the message
+ * directly. */
+ if(NULL == (ret_value = H5O_msg_read_oh(f, dxpl_id, open_oh, type->id, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read message")
+ } else
+ /* The shared message is in another object header */
+ if(NULL == (ret_value = H5O_msg_read(&oloc, type->id, NULL, dxpl_id)))
+ HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read message")
} /* end else */
/* Mark the message as shared */
@@ -228,7 +238,7 @@ H5O_shared_link_adj(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
H5O_loc_t oloc; /* Location for object header where message is stored */
/*
- * The shared message is stored in some other object header.
+ * The shared message is stored in some object header.
* The other object header must be in the same file as the
* new object header. Adjust the reference count on that
* object header.
@@ -236,13 +246,26 @@ H5O_shared_link_adj(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
if(shared->file->shared != f->shared)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "interfile hard links are not allowed")
- /* Get the shared message from an object header */
+ /* Build the object location for the shared message's object header */
oloc.file = f;
oloc.addr = shared->u.loc.oh_addr;
oloc.holding_file = FALSE;
- if(H5O_link(&oloc, adjust, dxpl_id) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared object link count")
+ if(open_oh && oloc.addr == H5O_OH_GET_ADDR(open_oh)) {
+ /* The shared message is in the already opened object header. This
+ * is possible, for example, if an attribute's datatype is shared in
+ * the same object header the attribute is in. Adjust the link
+ * count directly. */
+ unsigned oh_flags = H5AC__NO_FLAGS_SET; /* This is used only to satisfy H5O_link_oh */
+
+ if(H5O_link_oh(f, adjust, dxpl_id, open_oh, &oh_flags) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared object link count")
+
+ HDassert(!(oh_flags & H5AC__DELETED_FLAG));
+ } else
+ /* The shared message is in another object header */
+ if(H5O_link(&oloc, adjust, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared object link count")
} /* end if */
else {
HDassert(shared->type == H5O_SHARE_TYPE_SOHM || shared->type == H5O_SHARE_TYPE_HERE);
@@ -277,7 +300,8 @@ done:
*-------------------------------------------------------------------------
*/
void *
-H5O_shared_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *buf, const H5O_msg_class_t *type)
+H5O_shared_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned *ioflags,
+ const uint8_t *buf, const H5O_msg_class_t *type)
{
H5O_shared_t sh_mesg; /* Shared message info */
unsigned version; /* Shared message version */
@@ -343,7 +367,7 @@ H5O_shared_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *buf, const H5O_msg_cla
sh_mesg.msg_type_id = type->id;
/* Retrieve actual message, through decoded shared message info */
- if(NULL == (ret_value = H5O_shared_read(f, dxpl_id, &sh_mesg, type)))
+ if(NULL == (ret_value = H5O_shared_read(f, dxpl_id, open_oh, ioflags, &sh_mesg, type)))
HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to retrieve native message")
done:
@@ -489,7 +513,7 @@ H5O_shared_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
HDassert(f);
HDassert(sh_mesg);
- /*
+ /*
* Committed datatypes increment the OH of the original message when they
* are written (in H5O_shared_link) and decrement it here.
* SOHMs in the heap behave differently; their refcount is incremented
@@ -555,7 +579,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_shared_copy_file(H5F_t UNUSED *file_src, H5F_t *file_dst,
+H5O_shared_copy_file(H5F_t UNUSED *file_src, H5F_t *file_dst,
const H5O_msg_class_t *mesg_type, const void *_native_src, void *_native_dst,
hbool_t UNUSED *recompute_size, H5O_copy_t *cpy_info, void UNUSED *udata,
hid_t dxpl_id)
@@ -614,7 +638,7 @@ done:
* Purpose: Delate a shared message and replace with a new one.
* The function is needed at cases such as coping a shared reg_ref attribute.
* When a shared reg_ref attribute is copied from one file to
- * another, the values in file need to be replaced. The only way
+ * another, the values in file need to be replaced. The only way
* to complish that is to delete the old message and write the
* new message with the correct values.
*
@@ -707,7 +731,7 @@ H5O_shared_debug(const H5O_shared_t *mesg, FILE *stream, int indent, int fwidth)
"SOHM");
HDfprintf(stream, "%*s%-*s %016llx\n", indent, "", fwidth,
"Heap ID:",
- (unsigned long_long)mesg->u.heap_id);
+ (unsigned long long)mesg->u.heap_id);
break;
case H5O_SHARE_TYPE_HERE:
diff --git a/src/H5Oshared.h b/src/H5Oshared.h
index 582d29b..c0f5cd6 100644
--- a/src/H5Oshared.h
+++ b/src/H5Oshared.h
@@ -48,7 +48,8 @@
*-------------------------------------------------------------------------
*/
static H5_inline void *
-H5O_SHARED_DECODE(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p)
+H5O_SHARED_DECODE(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned mesg_flags,
+ unsigned *ioflags, const uint8_t *p)
{
void *ret_value; /* Return value */
@@ -67,12 +68,20 @@ H5O_SHARED_DECODE(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p
/* Check for shared message */
if(mesg_flags & H5O_MSG_FLAG_SHARED) {
/* Retrieve native message info indirectly through shared message */
- if(NULL == (ret_value = H5O_shared_decode(f, dxpl_id, p, H5O_SHARED_TYPE)))
+ if(NULL == (ret_value = H5O_shared_decode(f, dxpl_id, open_oh, ioflags, p, H5O_SHARED_TYPE)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode shared message")
+
+ /* We currently do not support automatically fixing shared messages */
+#ifdef H5_STRICT_FORMAT_CHECKS
+ if(*ioflags & H5O_DECODEIO_DIRTY)
+ HGOTO_ERROR(H5E_OHDR, H5E_UNSUPPORTED, NULL, "unable to mark shared message dirty")
+#else /* H5_STRICT_FORMAT_CHECKS */
+ *ioflags &= ~H5O_DECODEIO_DIRTY;
+#endif /* H5_STRICT_FORMAT_CHECKS */
} /* end if */
else {
/* Decode native message directly */
- if(NULL == (ret_value = H5O_SHARED_DECODE_REAL(f, dxpl_id, mesg_flags, p)))
+ if(NULL == (ret_value = H5O_SHARED_DECODE_REAL(f, dxpl_id, open_oh, mesg_flags, ioflags, p)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode native message")
} /* end else */
@@ -350,7 +359,7 @@ done:
if(!ret_value)
if(dst_mesg)
H5O_msg_free(H5O_SHARED_TYPE->id, dst_mesg);
-
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_SHARED_COPY_FILE() */
@@ -395,7 +404,7 @@ H5O_SHARED_POST_COPY_FILE(const H5O_loc_t *oloc_src, const void *mesg_src,
#ifdef H5O_SHARED_POST_COPY_FILE_REAL
/* Call native message's copy file callback to copy the message */
- if(H5O_SHARED_POST_COPY_FILE_REAL(oloc_src, mesg_src, oloc_dst, mesg_dst, dxpl_id, cpy_info) <0 )
+ if(H5O_SHARED_POST_COPY_FILE_REAL(oloc_src, mesg_src, oloc_dst, mesg_dst, dxpl_id, cpy_info) <0 )
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy native message to another file")
#endif /* H5O_SHARED_POST_COPY_FILE_REAL */
diff --git a/src/H5Oshmesg.c b/src/H5Oshmesg.c
index e66bdec..51c1c55 100644
--- a/src/H5Oshmesg.c
+++ b/src/H5Oshmesg.c
@@ -28,7 +28,8 @@
#include "H5Opkg.h" /* Object headers */
#include "H5MMprivate.h" /* Memory management */
-static void *H5O_shmesg_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_shmesg_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_shmesg_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
static void *H5O_shmesg_copy(const void *_mesg, void *_dest);
static size_t H5O_shmesg_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
@@ -75,8 +76,8 @@ const H5O_msg_class_t H5O_MSG_SHMESG[1] = {{
*-------------------------------------------------------------------------
*/
static void *
-H5O_shmesg_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_shmesg_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_shmesg_table_t *mesg; /* Native message */
void *ret_value; /* Return value */
@@ -87,7 +88,7 @@ H5O_shmesg_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
HDassert(f);
HDassert(p);
- if(NULL == (mesg = H5MM_calloc(sizeof(H5O_shmesg_table_t))))
+ if(NULL == (mesg = (H5O_shmesg_table_t *)H5MM_calloc(sizeof(H5O_shmesg_table_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for shared message table message")
/* Retrieve version, table address, and number of indexes */
@@ -162,7 +163,7 @@ H5O_shmesg_copy(const void *_mesg, void *_dest)
/* Sanity check */
HDassert(mesg);
- if(!dest && NULL == (dest = H5MM_malloc(sizeof(H5O_shmesg_table_t))))
+ if(!dest && NULL == (dest = (H5O_shmesg_table_t *)H5MM_malloc(sizeof(H5O_shmesg_table_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for shared message table message")
/* All this message requires is a shallow copy */
diff --git a/src/H5Ostab.c b/src/H5Ostab.c
index 231f2ce..a93a46d 100644
--- a/src/H5Ostab.c
+++ b/src/H5Ostab.c
@@ -36,7 +36,8 @@
/* PRIVATE PROTOTYPES */
-static void *H5O_stab_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
+static void *H5O_stab_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
+ unsigned mesg_flags, unsigned *ioflags, const uint8_t *p);
static herr_t H5O_stab_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
static void *H5O_stab_copy(const void *_mesg, void *_dest);
static size_t H5O_stab_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
@@ -95,35 +96,35 @@ H5FL_DEFINE_STATIC(H5O_stab_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_stab_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
- const uint8_t *p)
+H5O_stab_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+ unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
- H5O_stab_t *stab=NULL;
+ H5O_stab_t *stab = NULL;
void *ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_stab_decode);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_stab_decode)
/* check args */
- assert(f);
- assert(p);
+ HDassert(f);
+ HDassert(p);
/* decode */
- if (NULL==(stab = H5FL_CALLOC(H5O_stab_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ if(NULL == (stab = H5FL_CALLOC(H5O_stab_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
H5F_addr_decode(f, &p, &(stab->btree_addr));
H5F_addr_decode(f, &p, &(stab->heap_addr));
/* Set return value */
- ret_value=stab;
+ ret_value = stab;
done:
- if(ret_value==NULL) {
- if(stab!=NULL)
- H5FL_FREE(H5O_stab_t,stab);
+ if(ret_value == NULL) {
+ if(stab != NULL)
+ (void)H5FL_FREE(H5O_stab_t,stab);
} /* end if */
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_stab_decode() */
/*-------------------------------------------------------------------------
@@ -246,16 +247,16 @@ H5O_stab_size(const H5F_t *f, hbool_t UNUSED disable_shared, const void UNUSED *
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_stab_free (void *mesg)
+H5O_stab_free(void *mesg)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_stab_free);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_stab_free)
- assert (mesg);
+ HDassert(mesg);
- H5FL_FREE(H5O_stab_t,mesg);
+ (void)H5FL_FREE(H5O_stab_t, mesg);
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_stab_free() */
/*-------------------------------------------------------------------------
@@ -282,7 +283,7 @@ H5O_stab_delete(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, void *mesg)
HDassert(mesg);
/* Free the file space for the symbol table */
- if(H5G_stab_delete(f, dxpl_id, mesg) < 0)
+ if(H5G_stab_delete(f, dxpl_id, (const H5O_stab_t *)mesg) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free symbol table")
done:
@@ -338,7 +339,7 @@ H5O_stab_copy_file(H5F_t *file_src, void *native_src, H5F_t *file_dst,
done:
if(!ret_value)
if(stab_dst)
- H5FL_FREE(H5O_stab_t, stab_dst);
+ (void)H5FL_FREE(H5O_stab_t, stab_dst);
FUNC_LEAVE_NOAPI(ret_value)
} /* H5O_stab_copy_file() */
diff --git a/src/H5Otest.c b/src/H5Otest.c
index f6e4ba6..5282538 100644
--- a/src/H5Otest.c
+++ b/src/H5Otest.c
@@ -107,14 +107,16 @@ H5O_is_attr_dense_test(hid_t oid)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
/* Get the object header */
- if(NULL == (oh = H5AC_protect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Check for attribute info stored */
ainfo.fheap_addr = HADDR_UNDEF;
- if(oh->version > H5O_VERSION_1 && NULL == H5A_get_ainfo(loc->file, H5AC_ind_dxpl_id, oh, &ainfo))
- /* Clear error stack from not finding attribute info */
- H5E_clear_stack(NULL);
+ if(oh->version > H5O_VERSION_1) {
+ /* Check for (& retrieve if available) attribute info */
+ if(H5A_get_ainfo(loc->file, H5AC_ind_dxpl_id, oh, &ainfo) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
+ } /* end if */
/* Check if dense storage is being used */
if(H5F_addr_defined(ainfo.fheap_addr)) {
@@ -156,8 +158,9 @@ htri_t
H5O_is_attr_empty_test(hid_t oid)
{
H5O_t *oh = NULL; /* Object header */
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
H5O_ainfo_t ainfo; /* Attribute information for object */
- H5O_ainfo_t *ainfo_ptr = NULL; /* Pointer to attribute information for object */
+ htri_t ainfo_exists = FALSE; /* Whether the attribute info exists in the file */
H5O_loc_t *loc; /* Pointer to object's location */
hsize_t nattrs; /* Number of attributes */
htri_t ret_value; /* Return value */
@@ -169,29 +172,34 @@ H5O_is_attr_empty_test(hid_t oid)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
/* Get the object header */
- if(NULL == (oh = H5AC_protect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Check for attribute info stored */
- ainfo.fheap_addr = HADDR_UNDEF;
- if(oh->version > H5O_VERSION_1 && NULL == (ainfo_ptr = H5A_get_ainfo(loc->file, H5AC_ind_dxpl_id, oh, &ainfo)))
- /* Clear error stack from not finding attribute info */
- H5E_clear_stack(NULL);
+ if(oh->version > H5O_VERSION_1) {
+ /* Check for (& retrieve if available) attribute info */
+ if((ainfo_exists = H5A_get_ainfo(loc->file, H5AC_ind_dxpl_id, oh, &ainfo)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
+ } /* end if */
/* Retrieve the number of attribute messages in header */
nattrs = H5O_msg_count_real(oh, H5O_MSG_ATTR);
/* Check for later version of object header format & attribute info available */
if(oh->version > H5O_VERSION_1) {
- if(ainfo_ptr) {
+ if(ainfo_exists) {
/* Check for using dense storage */
if(H5F_addr_defined(ainfo.fheap_addr)) {
/* Check for any messages in object header */
HDassert(nattrs == 0);
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(loc->file, H5AC_ind_dxpl_id, ainfo.name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
/* Retrieve # of records in name index */
- if(H5B2_get_nrec(loc->file, H5AC_ind_dxpl_id, H5A_BT2_NAME, ainfo.name_bt2_addr, &nattrs) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index")
+ if(H5B2_get_nrec(bt2_name, &nattrs) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index")
} /* end if */
/* Verify that attribute count in object header is correct */
@@ -205,6 +213,9 @@ H5O_is_attr_empty_test(hid_t oid)
ret_value = (nattrs == 0) ? TRUE : FALSE;
done:
+ /* Release resources */
+ if(bt2_name && H5B2_close(bt2_name, H5AC_ind_dxpl_id) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index")
if(oh && H5AC_unprotect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
@@ -235,6 +246,7 @@ herr_t
H5O_num_attrs_test(hid_t oid, hsize_t *nattrs)
{
H5O_t *oh = NULL; /* Object header */
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
H5O_ainfo_t ainfo; /* Attribute information for object */
H5O_loc_t *loc; /* Pointer to object's location */
hsize_t obj_nattrs; /* Number of attributes */
@@ -247,14 +259,16 @@ H5O_num_attrs_test(hid_t oid, hsize_t *nattrs)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
/* Get the object header */
- if(NULL == (oh = H5AC_protect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Check for attribute info stored */
ainfo.fheap_addr = HADDR_UNDEF;
- if(oh->version > H5O_VERSION_1 && NULL == H5A_get_ainfo(loc->file, H5AC_ind_dxpl_id, oh, &ainfo))
- /* Clear error stack from not finding attribute info */
- H5E_clear_stack(NULL);
+ if(oh->version > H5O_VERSION_1) {
+ /* Check for (& retrieve if available) attribute info */
+ if(H5A_get_ainfo(loc->file, H5AC_ind_dxpl_id, oh, &ainfo) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
+ } /* end if */
/* Retrieve the number of attribute messages in header */
obj_nattrs = H5O_msg_count_real(oh, H5O_MSG_ATTR);
@@ -266,9 +280,13 @@ H5O_num_attrs_test(hid_t oid, hsize_t *nattrs)
/* Check for any messages in object header */
HDassert(obj_nattrs == 0);
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(loc->file, H5AC_ind_dxpl_id, ainfo.name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
/* Retrieve # of records in name index */
- if(H5B2_get_nrec(loc->file, H5AC_ind_dxpl_id, H5A_BT2_NAME, ainfo.name_bt2_addr, &obj_nattrs) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index")
+ if(H5B2_get_nrec(bt2_name, &obj_nattrs) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index")
} /* end if */
/* Verify that attribute count in object header is correct */
@@ -279,6 +297,9 @@ H5O_num_attrs_test(hid_t oid, hsize_t *nattrs)
*nattrs = obj_nattrs;
done:
+ /* Release resources */
+ if(bt2_name && H5B2_close(bt2_name, H5AC_ind_dxpl_id) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index")
if(oh && H5AC_unprotect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
@@ -311,6 +332,8 @@ herr_t
H5O_attr_dense_info_test(hid_t oid, hsize_t *name_count, hsize_t *corder_count)
{
H5O_t *oh = NULL; /* Object header */
+ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
+ H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */
H5O_ainfo_t ainfo; /* Attribute information for object */
H5O_loc_t *loc; /* Pointer to object's location */
herr_t ret_value = SUCCEED; /* Return value */
@@ -322,14 +345,16 @@ H5O_attr_dense_info_test(hid_t oid, hsize_t *name_count, hsize_t *corder_count)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
/* Get the object header */
- if(NULL == (oh = H5AC_protect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Check for attribute info stored */
ainfo.fheap_addr = HADDR_UNDEF;
- if(oh->version > H5O_VERSION_1 && NULL == H5A_get_ainfo(loc->file, H5AC_ind_dxpl_id, oh, &ainfo))
- /* Clear error stack from not finding attribute info */
- H5E_clear_stack(NULL);
+ if(oh->version > H5O_VERSION_1) {
+ /* Check for (& retrieve if available) attribute info */
+ if(H5A_get_ainfo(loc->file, H5AC_ind_dxpl_id, oh, &ainfo) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
+ } /* end if */
/* Check for 'dense' attribute storage file addresses being defined */
if(!H5F_addr_defined(ainfo.fheap_addr))
@@ -337,20 +362,33 @@ H5O_attr_dense_info_test(hid_t oid, hsize_t *name_count, hsize_t *corder_count)
if(!H5F_addr_defined(ainfo.name_bt2_addr))
HGOTO_DONE(FAIL)
+ /* Open the name index v2 B-tree */
+ if(NULL == (bt2_name = H5B2_open(loc->file, H5AC_ind_dxpl_id, ainfo.name_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+
/* Retrieve # of records in name index */
- if(H5B2_get_nrec(loc->file, H5AC_ind_dxpl_id, H5A_BT2_NAME, ainfo.name_bt2_addr, name_count) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index")
+ if(H5B2_get_nrec(bt2_name, name_count) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index")
/* Check if there is a creation order index */
if(H5F_addr_defined(ainfo.corder_bt2_addr)) {
+ /* Open the creation order index v2 B-tree */
+ if(NULL == (bt2_corder = H5B2_open(loc->file, H5AC_ind_dxpl_id, ainfo.corder_bt2_addr, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index")
+
/* Retrieve # of records in creation order index */
- if(H5B2_get_nrec(loc->file, H5AC_ind_dxpl_id, H5A_BT2_CORDER, ainfo.corder_bt2_addr, corder_count) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from creation order index")
+ if(H5B2_get_nrec(bt2_corder, corder_count) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from creation order index")
} /* end if */
else
*corder_count = 0;
done:
+ /* Release resources */
+ if(bt2_name && H5B2_close(bt2_name, H5AC_ind_dxpl_id) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index")
+ if(bt2_corder && H5B2_close(bt2_corder, H5AC_ind_dxpl_id) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for creation order index")
if(oh && H5AC_unprotect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
@@ -395,7 +433,7 @@ H5O_check_msg_marked_test(hid_t oid, hbool_t flag_val)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
/* Get the object header */
- if(NULL == (oh = H5AC_protect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Locate "unknown" message */
diff --git a/src/H5Ounknown.c b/src/H5Ounknown.c
index 5b0a38a..fe31a6d 100644
--- a/src/H5Ounknown.c
+++ b/src/H5Ounknown.c
@@ -82,7 +82,7 @@ H5O_unknown_free(void *mesg)
HDassert(mesg);
- H5FL_FREE(H5O_unknown_t, mesg);
+ (void)H5FL_FREE(H5O_unknown_t, mesg);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_unknown_free() */
diff --git a/src/H5P.c b/src/H5P.c
index c6a762c..212b308 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -128,7 +128,7 @@ H5Pcopy(hid_t id)
/* Compare property lists */
if(H5I_GENPROP_LST == H5I_get_type(id)) {
- if((ret_value = H5P_copy_plist(obj)) < 0)
+ if((ret_value = H5P_copy_plist((H5P_genplist_t *)obj, TRUE)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property list");
} /* end if */
/* Must be property classes */
@@ -136,11 +136,11 @@ H5Pcopy(hid_t id)
H5P_genclass_t *copy_class; /* Copy of class */
/* Copy the class */
- if((copy_class = H5P_copy_pclass(obj)) == NULL)
+ if((copy_class = H5P_copy_pclass((H5P_genclass_t *)obj)) == NULL)
HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property class");
/* Get an atom for the copied class */
- if((ret_value = H5I_register(H5I_GENPROP_CLS, copy_class)) < 0) {
+ if((ret_value = H5I_register(H5I_GENPROP_CLS, copy_class, TRUE)) < 0) {
H5P_close_class(copy_class);
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class");
} /* end if */
@@ -196,39 +196,39 @@ H5Pcreate_class(hid_t parent, const char *name,
H5P_genclass_t *pclass = NULL; /* Property list class created */
hid_t ret_value; /* Return value */
- FUNC_ENTER_API(H5Pcreate_class, FAIL);
+ FUNC_ENTER_API(H5Pcreate_class, FAIL)
H5TRACE8("i", "i*sx*xx*xx*x", parent, name, cls_create, create_data, cls_copy,
copy_data, cls_close, close_data);
/* Check arguments. */
if(H5P_DEFAULT!=parent && (H5I_GENPROP_CLS!=H5I_get_type(parent)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class")
if(!name || !*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name");
- if((create_data!=NULL && cls_create==NULL)
- || (copy_data!=NULL && cls_copy==NULL)
- || (close_data!=NULL && cls_close==NULL))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "data specified, but no callback provided");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name")
+ if((create_data != NULL && cls_create == NULL)
+ || (copy_data != NULL && cls_copy == NULL)
+ || (close_data != NULL && cls_close == NULL))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "data specified, but no callback provided")
/* Get the pointer to the parent class */
- if(parent==H5P_DEFAULT)
- par_class=NULL;
- else if(NULL == (par_class = H5I_object(parent)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't retrieve parent class");
+ if(parent == H5P_DEFAULT)
+ par_class = NULL;
+ else if(NULL == (par_class = (H5P_genclass_t *)H5I_object(parent)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't retrieve parent class")
/* Create the new property list class */
- if(NULL==(pclass=H5P_create_class(par_class, name, 0, cls_create, create_data, cls_copy, copy_data, cls_close, close_data)))
- HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list class");
+ if(NULL == (pclass = H5P_create_class(par_class, name, 0, cls_create, create_data, cls_copy, copy_data, cls_close, close_data)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list class")
/* Get an atom for the class */
- if((ret_value = H5I_register(H5I_GENPROP_CLS, pclass)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class");
+ if((ret_value = H5I_register(H5I_GENPROP_CLS, pclass, TRUE)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class")
done:
- if(ret_value<0 && pclass)
+ if(ret_value < 0 && pclass)
H5P_close_class(pclass);
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* H5Pcreate_class() */
@@ -264,11 +264,11 @@ H5Pcreate(hid_t cls_id)
H5TRACE1("i", "i", cls_id);
/* Check arguments. */
- if(NULL == (pclass = H5I_object_verify(cls_id, H5I_GENPROP_CLS)))
+ if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(cls_id, H5I_GENPROP_CLS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
/* Create the new property list */
- if((ret_value = H5P_create_id(pclass)) < 0)
+ if((ret_value = H5P_create_id(pclass, TRUE)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list");
done:
@@ -445,7 +445,7 @@ H5Pregister2(hid_t cls_id, const char *name, size_t size, void *def_value,
prp_set, prp_get, prp_delete, prp_copy, prp_cmp, prp_close);
/* Check arguments. */
- if(NULL == (pclass = H5I_object_verify(cls_id, H5I_GENPROP_CLS)))
+ if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(cls_id, H5I_GENPROP_CLS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name");
@@ -614,7 +614,7 @@ H5Pinsert2(hid_t plist_id, const char *name, size_t size, void *value,
prp_delete, prp_copy, prp_cmp, prp_close);
/* Check arguments. */
- if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name")
@@ -671,7 +671,7 @@ H5Pset(hid_t plist_id, const char *name, void *value)
H5TRACE3("e", "i*s*x", plist_id, name, value);
/* Check arguments. */
- if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
@@ -727,14 +727,14 @@ H5Pexist(hid_t id, const char *name)
/* Check for the existance of the property in the list or class */
if(H5I_GENPROP_LST == H5I_get_type(id)) {
- if(NULL == (plist = H5I_object(id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
if((ret_value = H5P_exist_plist(plist, name)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property does not exist in list");
} /* end if */
else
if(H5I_GENPROP_CLS == H5I_get_type(id)) {
- if(NULL == (pclass = H5I_object(id)))
+ if(NULL == (pclass = (H5P_genclass_t *)H5I_object(id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class");
if((ret_value = H5P_exist_pclass(pclass, name)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property does not exist in class");
@@ -789,7 +789,7 @@ H5Pget_size(hid_t id, const char *name, size_t *size)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property size");
if(H5I_GENPROP_LST == H5I_get_type(id)) {
- if(NULL == (plist = H5I_object(id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
/* Check the property size */
@@ -798,7 +798,7 @@ H5Pget_size(hid_t id, const char *name, size_t *size)
} /* end if */
else
if(H5I_GENPROP_CLS == H5I_get_type(id)) {
- if(NULL == (pclass = H5I_object(id)))
+ if(NULL == (pclass = (H5P_genclass_t *)H5I_object(id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
/* Check the property size */
@@ -844,7 +844,7 @@ H5Pget_class(hid_t plist_id)
H5TRACE1("i", "i", plist_id);
/* Check arguments. */
- if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
/* Retrieve the property list class */
@@ -856,7 +856,7 @@ H5Pget_class(hid_t plist_id)
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't increment class ID ref count");
/* Get an atom for the class */
- if((ret_value = H5I_register(H5I_GENPROP_CLS, pclass)) < 0)
+ if((ret_value = H5I_register(H5I_GENPROP_CLS, pclass, TRUE)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class");
done:
@@ -907,14 +907,14 @@ H5Pget_nprops(hid_t id, size_t *nprops)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property nprops pointer");
if(H5I_GENPROP_LST == H5I_get_type(id)) {
- if(NULL == (plist = H5I_object(id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
if(H5P_get_nprops_plist(plist, nprops) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query # of properties in plist");
} /* end if */
else
if(H5I_GENPROP_CLS == H5I_get_type(id)) {
- if(NULL == (pclass = H5I_object(id)))
+ if(NULL == (pclass = (H5P_genclass_t *)H5I_object(id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class");
if(H5P_get_nprops_pclass(pclass, nprops, FALSE) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query # of properties in pclass");
@@ -967,12 +967,12 @@ H5Pequal(hid_t id1, hid_t id2)
/* Compare property lists */
if(H5I_GENPROP_LST == H5I_get_type(id1)) {
- if(H5P_cmp_plist(obj1, obj2) == 0)
+ if(H5P_cmp_plist((const H5P_genplist_t *)obj1, (const H5P_genplist_t *)obj2) == 0)
ret_value = TRUE;
} /* end if */
/* Must be property classes */
else {
- if(H5P_cmp_class(obj1, obj2) == 0)
+ if(H5P_cmp_class((const H5P_genclass_t *)obj1, (const H5P_genclass_t *)obj2) == 0)
ret_value = TRUE;
} /* end else */
@@ -1152,7 +1152,7 @@ H5Pget(hid_t plist_id, const char *name, void *value)
H5TRACE3("e", "i*s*x", plist_id, name, value);
/* Check arguments. */
- if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
@@ -1204,7 +1204,7 @@ H5Premove(hid_t plist_id, const char *name)
H5TRACE2("e", "i*s", plist_id, name);
/* Check arguments. */
- if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
@@ -1283,7 +1283,7 @@ H5Pcopy_prop(hid_t dst_id, hid_t src_id, const char *name)
} /* end if */
/* Must be property classes */
else {
- if(H5P_copy_prop_pclass(dst_obj, src_obj, name) < 0)
+ if(H5P_copy_prop_pclass((H5P_genclass_t *)dst_obj, (H5P_genclass_t *)src_obj, name) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property between classes");
} /* end else */
@@ -1323,7 +1323,7 @@ H5Punregister(hid_t pclass_id, const char *name)
H5TRACE2("e", "i*s", pclass_id, name);
/* Check arguments. */
- if(NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
+ if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
@@ -1374,7 +1374,7 @@ H5Pclose(hid_t plist_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
/* Close the property list */
- if(H5I_dec_ref(plist_id) < 0)
+ if(H5I_dec_ref(plist_id, TRUE) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close");
done:
@@ -1411,7 +1411,7 @@ H5Pget_class_name(hid_t pclass_id)
FUNC_ENTER_API(H5Pget_class_name, NULL);
/* Check arguments. */
- if(NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
+ if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property class");
/* Get the property list class name */
@@ -1446,33 +1446,33 @@ hid_t
H5Pget_class_parent(hid_t pclass_id)
{
H5P_genclass_t *pclass; /* Property class to query */
- H5P_genclass_t *parent=NULL; /* Parent's property class */
+ H5P_genclass_t *parent = NULL; /* Parent's property class */
hid_t ret_value; /* return value */
- FUNC_ENTER_API(H5Pget_class_parent, FAIL);
+ FUNC_ENTER_API(H5Pget_class_parent, FAIL)
H5TRACE1("i", "i", pclass_id);
/* Check arguments. */
- if(NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class");
+ if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class")
/* Retrieve the property class's parent */
- if((parent = H5P_get_class_parent(pclass)) == NULL)
- HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to query class of property list");
+ if(NULL == (parent = H5P_get_class_parent(pclass)))
+ HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to query class of property list")
/* Increment the outstanding references to the class object */
if(H5P_access_class(parent, H5P_MOD_INC_REF) < 0)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't increment class ID ref count");
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL,"Can't increment class ID ref count")
/* Get an atom for the class */
- if((ret_value = H5I_register(H5I_GENPROP_CLS, parent)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class");
+ if((ret_value = H5I_register(H5I_GENPROP_CLS, parent, TRUE)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class")
done:
- if(ret_value<0 && parent)
+ if(ret_value < 0 && parent)
H5P_close_class(parent);
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* H5Pget_class_parent() */
@@ -1507,7 +1507,7 @@ H5Pclose_class(hid_t cls_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
/* Close the property list class */
- if(H5I_dec_ref(cls_id) < 0)
+ if(H5I_dec_ref(cls_id, TRUE) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close");
done:
diff --git a/src/H5Pdapl.c b/src/H5Pdapl.c
new file mode 100644
index 0000000..db66366
--- /dev/null
+++ b/src/H5Pdapl.c
@@ -0,0 +1,273 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Pdapl.c
+ * October 27, 2008
+ * Neil Fortner <nfortne2@hdfgroup.org>
+ *
+ * Purpose: Dataset access property list class routines
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+#define H5P_PACKAGE /*suppress error about including H5Ppkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Dprivate.h" /* Datasets */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fprivate.h" /* Files */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Ppkg.h" /* Property lists */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* ========= Dataset Access properties ============ */
+/* Definitions for size of raw data chunk cache(slots) */
+#define H5D_ACS_DATA_CACHE_NUM_SLOTS_SIZE sizeof(size_t)
+#define H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF H5D_CHUNK_CACHE_NSLOTS_DEFAULT
+/* Definition for size of raw data chunk cache(bytes) */
+#define H5D_ACS_DATA_CACHE_BYTE_SIZE_SIZE sizeof(size_t)
+#define H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF H5D_CHUNK_CACHE_NBYTES_DEFAULT
+/* Definition for preemption read chunks first */
+#define H5D_ACS_PREEMPT_READ_CHUNKS_SIZE sizeof(double)
+#define H5D_ACS_PREEMPT_READ_CHUNKS_DEF H5D_CHUNK_CACHE_W0_DEFAULT
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* Property class callbacks */
+static herr_t H5P_dacc_reg_prop(H5P_genclass_t *pclass);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Dataset access property list class library initialization object */
+const H5P_libclass_t H5P_CLS_DACC[1] = {{
+ "dataset access", /* Class name for debugging */
+ &H5P_CLS_LINK_ACCESS_g, /* Parent class ID */
+ &H5P_CLS_DATASET_ACCESS_g, /* Pointer to class ID */
+ &H5P_LST_DATASET_ACCESS_g, /* Pointer to default property list ID */
+ H5P_dacc_reg_prop, /* Default property registration routine */
+ NULL, /* Class creation callback */
+ NULL, /* Class creation callback info */
+ NULL, /* Class copy callback */
+ NULL, /* Class copy callback info */
+ NULL, /* Class close callback */
+ NULL /* Class close callback info */
+}};
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_dacc_reg_prop
+ *
+ * Purpose: Register the dataset access property list class's
+ * properties
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * October 27, 2008
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P_dacc_reg_prop(H5P_genclass_t *pclass)
+{
+ size_t rdcc_nslots = H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF; /* Default raw data chunk cache # of slots */
+ size_t rdcc_nbytes = H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF; /* Default raw data chunk cache # of bytes */
+ double rdcc_w0 = H5D_ACS_PREEMPT_READ_CHUNKS_DEF; /* Default raw data chunk cache dirty ratio */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5P_dacc_reg_prop)
+
+ /* Register the size of raw data chunk cache (elements) */
+ if(H5P_register(pclass, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, H5D_ACS_DATA_CACHE_NUM_SLOTS_SIZE, &rdcc_nslots, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+ /* Register the size of raw data chunk cache(bytes) */
+ if(H5P_register(pclass, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, H5D_ACS_DATA_CACHE_BYTE_SIZE_SIZE, &rdcc_nbytes, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+ /* Register the preemption for reading chunks */
+ if(H5P_register(pclass, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, H5D_ACS_PREEMPT_READ_CHUNKS_SIZE, &rdcc_w0, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_dacc_reg_prop() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_chunk_cache
+ *
+ * Purpose: Set the number of objects in the meta data cache and the
+ * maximum number of chunks and bytes in the raw data chunk cache.
+ * Once set, these values will override the values in the file access
+ * property list. Each of thhese values can be individually unset
+ * (or not set at all) by passing the macros:
+ * H5D_CHUNK_CACHE_NCHUNKS_DEFAULT,
+ * H5D_CHUNK_CACHE_NSLOTS_DEFAULT, and/or
+ * H5D_CHUNK_CACHE_W0_DEFAULT
+ * as appropriate.
+ *
+ * The RDCC_W0 value should be between 0 and 1 inclusive and
+ * indicates how much chunks that have been fully read or fully
+ * written are favored for preemption. A value of zero means
+ * fully read or written chunks are treated no differently than
+ * other chunks (the preemption is strictly LRU) while a value
+ * of one means fully read chunks are always preempted before
+ * other chunks.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Monday, October 27, 2008
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_chunk_cache(hid_t dapl_id, size_t rdcc_nslots, size_t rdcc_nbytes, double rdcc_w0)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(H5Pset_chunk_cache, FAIL);
+ H5TRACE4("e", "izzd", dapl_id, rdcc_nslots, rdcc_nbytes, rdcc_w0);
+
+ /* Check arguments. Note that we allow negative values - they are
+ * considered to "unset" the property. */
+ if (rdcc_w0 > 1.0)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "raw data cache w0 value must be between 0.0 and 1.0 inclusive, or H5D_CHUNK_CACHE_W0_DEFAULT");
+
+ /* Get the plist structure */
+ if (NULL == (plist = H5P_object_verify(dapl_id,H5P_DATASET_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+ /* Set sizes */
+ if (H5P_set(plist, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, &rdcc_nslots) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET,FAIL, "can't set data cache number of chunks");
+ if (H5P_set(plist, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, &rdcc_nbytes) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET,FAIL, "can't set data cache byte size");
+ if (H5P_set(plist, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, &rdcc_w0) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET,FAIL, "can't set preempt read chunks");
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_chunk_cache
+ *
+ * Purpose: Retrieves the maximum possible number of elements in the meta
+ * data cache and the maximum possible number of elements and
+ * bytes and the RDCC_W0 value in the raw data chunk cache. Any
+ * (or all) arguments may be null pointers in which case the
+ * corresponding datum is not returned. If these properties have
+ * not been set on this property list, the default values for a
+ * file access property list are returned.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Monday, October 27, 2008
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_chunk_cache(hid_t dapl_id, size_t *rdcc_nslots, size_t *rdcc_nbytes, double *rdcc_w0)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5P_genplist_t *def_plist; /* Default file access property list */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(H5Pget_chunk_cache, FAIL);
+ H5TRACE4("e", "i*z*z*d", dapl_id, rdcc_nslots, rdcc_nbytes, rdcc_w0);
+
+ /* Get the plist structure */
+ if (NULL == (plist = H5P_object_verify(dapl_id, H5P_DATASET_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+ /* Get default file access plist */
+ if (NULL == (def_plist = (H5P_genplist_t *)H5I_object(H5P_FILE_ACCESS_DEFAULT)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for default fapl ID");
+
+ /* Get the properties. If a property is set to the default value, the value
+ * from the default fapl is used. */
+ if (rdcc_nslots) {
+ if (H5P_get(plist, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, rdcc_nslots) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get data cache number of slots");
+ if (*rdcc_nslots == H5D_CHUNK_CACHE_NSLOTS_DEFAULT)
+ if (H5P_get(def_plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, rdcc_nslots) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get default data cache number of slots");
+ } /* end if */
+ if (rdcc_nbytes) {
+ if (H5P_get(plist, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, rdcc_nbytes) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get data cache byte size");
+ if (*rdcc_nbytes == H5D_CHUNK_CACHE_NBYTES_DEFAULT)
+ if (H5P_get(def_plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, rdcc_nbytes) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get default data cache byte size");
+ } /* end if */
+ if (rdcc_w0) {
+ if (H5P_get(plist, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, rdcc_w0) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get preempt read chunks");
+ if (*rdcc_w0 < 0)
+ if (H5P_get(def_plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, rdcc_w0) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get default preempt read chunks");
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c
index 913d200..82053e4 100644
--- a/src/H5Pdcpl.c
+++ b/src/H5Pdcpl.c
@@ -47,17 +47,34 @@
/* Local Macros */
/****************/
+/* Define default layout information */
+#define H5D_DEF_STORAGE_COMPACT_INIT {(hbool_t)FALSE, (size_t)0, NULL}
+#define H5D_DEF_STORAGE_CONTIG_INIT {HADDR_UNDEF, (hsize_t)0}
+#define H5D_DEF_STORAGE_CHUNK_INIT {H5D_CHUNK_BTREE, HADDR_UNDEF, NULL, {{NULL}}}
+#define H5D_DEF_LAYOUT_CHUNK_INIT {(unsigned)1, {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, (uint32_t)0, (hsize_t)0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
+#ifdef H5_HAVE_C99_DESIGNATED_INITIALIZER
+#define H5D_DEF_STORAGE_COMPACT {H5D_COMPACT, { .compact = H5D_DEF_STORAGE_COMPACT_INIT }}
+#define H5D_DEF_STORAGE_CONTIG {H5D_CONTIGUOUS, { .contig = H5D_DEF_STORAGE_CONTIG_INIT }}
+#define H5D_DEF_STORAGE_CHUNK {H5D_CHUNKED, { .chunk = H5D_DEF_STORAGE_CHUNK_INIT }}
+#define H5D_DEF_LAYOUT_COMPACT {H5D_COMPACT, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_COMPACT}
+#define H5D_DEF_LAYOUT_CONTIG {H5D_CONTIGUOUS, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_CONTIG}
+#define H5D_DEF_LAYOUT_CHUNK {H5D_CHUNKED, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_CHUNK}
+#else /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
+/* Note that the compact & chunked layout initialization values are using the
+ * contiguous layout initialization in the union, because the contiguous
+ * layout is first in the union. These values are overridden in the
+ * H5P_init_def_layout() routine. -QAK
+ */
+#define H5D_DEF_LAYOUT_COMPACT {H5D_COMPACT, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}}
+#define H5D_DEF_LAYOUT_CONTIG {H5D_CONTIGUOUS, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}}
+#define H5D_DEF_LAYOUT_CHUNK {H5D_CHUNKED, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}}
+#endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
+
/* ======== Dataset creation properties ======== */
/* Definitions for storage layout property */
-#define H5D_CRT_LAYOUT_SIZE sizeof(H5D_layout_t)
-#define H5D_CRT_LAYOUT_DEF H5D_CONTIGUOUS
-/* Definitions for chunk dimensionality property */
-#define H5D_CRT_CHUNK_DIM_SIZE sizeof(unsigned)
-#define H5D_CRT_CHUNK_DIM_DEF 1
-/* Definitions for chunk size */
-#define H5D_CRT_CHUNK_SIZE_SIZE sizeof(uint32_t[H5O_LAYOUT_NDIMS])
-#define H5D_CRT_CHUNK_SIZE_DEF {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
+#define H5D_CRT_LAYOUT_SIZE sizeof(H5O_layout_t)
+#define H5D_CRT_LAYOUT_DEF H5D_DEF_LAYOUT_CONTIG
+#define H5D_CRT_LAYOUT_CMP H5P_dcrt_layout_cmp
/* Definitions for fill value. size=0 means fill value will be 0 as
* library default; size=-1 means fill value is undefined. */
#define H5D_CRT_FILL_VALUE_SIZE sizeof(H5O_fill_t)
@@ -70,10 +87,6 @@
#define H5D_CRT_EXT_FILE_LIST_SIZE sizeof(H5O_efl_t)
#define H5D_CRT_EXT_FILE_LIST_DEF {HADDR_UNDEF, 0, 0, NULL}
#define H5D_CRT_EXT_FILE_LIST_CMP H5P_dcrt_ext_file_list_cmp
-/* Definitions for data filter pipeline */
-#define H5D_CRT_DATA_PIPELINE_SIZE sizeof(H5O_pline_t)
-#define H5D_CRT_DATA_PIPELINE_DEF {{0, NULL, H5O_NULL_ID, {{0, HADDR_UNDEF}}}, H5O_PLINE_VERSION_1, 0, 0, NULL}
-#define H5D_CRT_DATA_PIPELINE_CMP H5P_dcrt_data_pipeline_cmp
/******************/
@@ -91,7 +104,10 @@
/********************/
/* General routines */
-static herr_t H5P_set_layout(H5P_genplist_t *plist, H5D_layout_t layout);
+static herr_t H5P_set_layout(H5P_genplist_t *plist, const H5O_layout_t *layout);
+#ifndef H5_HAVE_C99_DESIGNATED_INITIALIZER
+static herr_t H5P_init_def_layout(void);
+#endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
/* Property class callbacks */
static herr_t H5P_dcrt_reg_prop(H5P_genclass_t *pclass);
@@ -99,8 +115,8 @@ static herr_t H5P_dcrt_copy(hid_t new_plist_t, hid_t old_plist_t, void *copy_dat
static herr_t H5P_dcrt_close(hid_t dxpl_id, void *close_data);
/* Property callbacks */
+static int H5P_dcrt_layout_cmp(const void *value1, const void *value2, size_t size);
static int H5P_dcrt_ext_file_list_cmp(const void *value1, const void *value2, size_t size);
-static int H5P_dcrt_data_pipeline_cmp(const void *value1, const void *value2, size_t size);
/*********************/
@@ -130,6 +146,18 @@ const H5P_libclass_t H5P_CLS_DCRT[1] = {{
/* Declare extern the free list to manage blocks of type conversion data */
H5FL_BLK_EXTERN(type_conv);
+/* Defaults for each type of layout */
+#ifdef H5_HAVE_C99_DESIGNATED_INITIALIZER
+static const H5O_layout_t H5D_def_layout_compact_g = H5D_DEF_LAYOUT_COMPACT;
+static const H5O_layout_t H5D_def_layout_contig_g = H5D_DEF_LAYOUT_CONTIG;
+static const H5O_layout_t H5D_def_layout_chunk_g = H5D_DEF_LAYOUT_CHUNK;
+#else /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
+static H5O_layout_t H5D_def_layout_compact_g = H5D_DEF_LAYOUT_COMPACT;
+static H5O_layout_t H5D_def_layout_contig_g = H5D_DEF_LAYOUT_CONTIG;
+static H5O_layout_t H5D_def_layout_chunk_g = H5D_DEF_LAYOUT_CHUNK;
+static hbool_t H5P_dcrt_def_layout_init_g = FALSE;
+#endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
+
/*-------------------------------------------------------------------------
@@ -146,27 +174,16 @@ H5FL_BLK_EXTERN(type_conv);
static herr_t
H5P_dcrt_reg_prop(H5P_genclass_t *pclass)
{
- H5D_layout_t layout = H5D_CRT_LAYOUT_DEF; /* Default storage layout */
- unsigned chunk_ndims = H5D_CRT_CHUNK_DIM_DEF; /* Default rank for chunks */
- uint32_t chunk_size[H5O_LAYOUT_NDIMS] = H5D_CRT_CHUNK_SIZE_DEF; /* Default chunk size */
+ H5O_layout_t layout = H5D_CRT_LAYOUT_DEF; /* Default storage layout */
H5O_fill_t fill = H5D_CRT_FILL_VALUE_DEF; /* Default fill value */
unsigned alloc_time_state = H5D_CRT_ALLOC_TIME_STATE_DEF; /* Default allocation time state */
H5O_efl_t efl = H5D_CRT_EXT_FILE_LIST_DEF; /* Default external file list */
- H5O_pline_t pline = H5D_CRT_DATA_PIPELINE_DEF; /* Default I/O pipeline setting */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5P_dcrt_reg_prop)
/* Register the storage layout property */
- if(H5P_register(pclass, H5D_CRT_LAYOUT_NAME, H5D_CRT_LAYOUT_SIZE, &layout, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
-
- /* Register the chunking dimensionality property */
- if(H5P_register(pclass, H5D_CRT_CHUNK_DIM_NAME, H5D_CRT_CHUNK_DIM_SIZE, &chunk_ndims, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
-
- /* Register the chunking size property */
- if(H5P_register(pclass, H5D_CRT_CHUNK_SIZE_NAME, H5D_CRT_CHUNK_SIZE_SIZE, chunk_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ if(H5P_register(pclass, H5D_CRT_LAYOUT_NAME, H5D_CRT_LAYOUT_SIZE, &layout, NULL, NULL, NULL, NULL, NULL, H5D_CRT_LAYOUT_CMP, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
/* Register the fill value property */
@@ -181,10 +198,6 @@ H5P_dcrt_reg_prop(H5P_genclass_t *pclass)
if(H5P_register(pclass, H5D_CRT_EXT_FILE_LIST_NAME, H5D_CRT_EXT_FILE_LIST_SIZE, &efl, NULL, NULL, NULL, NULL, NULL, H5D_CRT_EXT_FILE_LIST_CMP, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
- /* Register the data pipeline property */
- if(H5P_register(pclass, H5D_CRT_DATA_PIPELINE_NAME, H5D_CRT_DATA_PIPELINE_SIZE, &pline, NULL, NULL, NULL, NULL, NULL, H5D_CRT_DATA_PIPELINE_CMP, NULL) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
-
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P_dcrt_reg_prop() */
@@ -203,9 +216,6 @@ done:
* Programmer: Raymond Lu
* Tuesday, October 2, 2001
*
- * Modifications: pvn, April 02, 2007
- * Reset external file list slots name_offset to a state when created
- *
*-------------------------------------------------------------------------
*/
/* ARGSUSED */
@@ -214,7 +224,7 @@ H5P_dcrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data)
{
H5O_fill_t src_fill, dst_fill; /* Source & destination fill values */
H5O_efl_t src_efl, dst_efl; /* Source & destination external file lists */
- H5O_pline_t src_pline, dst_pline; /* Source & destination I/O pipelines */
+ H5O_layout_t src_layout, dst_layout; /* Source & destination layout */
H5P_genplist_t *src_plist; /* Pointer to source property list */
H5P_genplist_t *dst_plist; /* Pointer to destination property list */
herr_t ret_value = SUCCEED; /* Return value */
@@ -222,52 +232,83 @@ H5P_dcrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data)
FUNC_ENTER_NOAPI_NOINIT(H5P_dcrt_copy)
/* Verify property list IDs */
- if(NULL == (dst_plist = H5I_object(dst_plist_id)))
+ if(NULL == (dst_plist = (H5P_genplist_t *)H5I_object(dst_plist_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list")
- if(NULL == (src_plist = H5I_object(src_plist_id)))
+ if(NULL == (src_plist = (H5P_genplist_t *)H5I_object(src_plist_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list")
- /* Get the fill value, external file list, and data pipeline properties
- * from the old property list */
+ /* Get the layout, fill value, external file list, and data pipeline
+ * properties from the old property list
+ */
+ if(H5P_get(src_plist, H5D_CRT_LAYOUT_NAME, &src_layout) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get layout")
if(H5P_get(src_plist, H5D_CRT_FILL_VALUE_NAME, &src_fill) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value")
if(H5P_get(src_plist, H5D_CRT_EXT_FILE_LIST_NAME, &src_efl) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list")
- if(H5P_get(src_plist, H5D_CRT_DATA_PIPELINE_NAME, &src_pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
- /* Make copies of fill value, external file list, and data pipeline */
+ /* Make copy of layout */
+ if(NULL == H5O_msg_copy(H5O_LAYOUT_ID, &src_layout, &dst_layout))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't copy layout")
+
+ /* Reset layout values set when dataset is created */
+ dst_layout.ops = NULL;
+ switch(dst_layout.type) {
+ case H5D_COMPACT:
+ dst_layout.storage.u.compact.buf = H5MM_xfree(dst_layout.storage.u.compact.buf);
+ HDmemset(&dst_layout.storage.u.compact, 0, sizeof(dst_layout.storage.u.compact));
+ break;
+
+ case H5D_CONTIGUOUS:
+ dst_layout.storage.u.contig.addr = HADDR_UNDEF;
+ dst_layout.storage.u.contig.size = 0;
+ break;
+
+ case H5D_CHUNKED:
+ /* Reset chunk size */
+ dst_layout.u.chunk.size = 0;
+
+ /* Reset index info, if the chunk ops are set */
+ if(dst_layout.storage.u.chunk.ops)
+ /* Reset address and pointer of the array struct for the chunked storage index */
+ if(H5D_chunk_idx_reset(&dst_layout.storage.u.chunk, TRUE) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to reset chunked storage index in dest")
+
+ /* Reset chunk index ops */
+ dst_layout.storage.u.chunk.ops = NULL;
+ break;
+
+ default:
+ HDassert(0 && "Unknown layout type!");
+ } /* end switch */
+
+ /* Make copy of fill value */
if(NULL == H5O_msg_copy(H5O_FILL_ID, &src_fill, &dst_fill))
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't copy fill value")
+
+ /* Make copy of external file list */
HDmemset(&dst_efl, 0, sizeof(H5O_efl_t));
if(NULL == H5O_msg_copy(H5O_EFL_ID, &src_efl, &dst_efl))
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't copy external file list")
- /* reset efl name_offset and heap_addr, these are the values when the dataset is created */
- if (dst_efl.slot)
- {
+ /* Reset efl name_offset and heap_addr, these are the values when the dataset is created */
+ if(dst_efl.slot) {
unsigned int i;
dst_efl.heap_addr = HADDR_UNDEF;
- for ( i = 0; i < dst_efl.nused; i++)
- {
+ for(i = 0; i < dst_efl.nused; i++)
dst_efl.slot[i].name_offset = 0;
- }
-
- }
-
-
- if(NULL == H5O_msg_copy(H5O_PLINE_ID, &src_pline, &dst_pline))
- HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't copy data pipeline")
+ } /* end if */
- /* Set the fill value, external file list, and data pipeline property
- * for the destination property list */
+ /* Set the layout, fill value, external file list, and data pipeline
+ * properties for the destination property list
+ */
+ if(H5P_set(dst_plist, H5D_CRT_LAYOUT_NAME, &dst_layout) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set layout")
if(H5P_set(dst_plist, H5D_CRT_FILL_VALUE_NAME, &dst_fill) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set fill value")
if(H5P_set(dst_plist, H5D_CRT_EXT_FILE_LIST_NAME, &dst_efl) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set external file list")
- if(H5P_set(dst_plist, H5D_CRT_DATA_PIPELINE_NAME, &dst_pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -295,14 +336,13 @@ H5P_dcrt_close(hid_t dcpl_id, void UNUSED *close_data)
{
H5O_fill_t fill; /* Fill value */
H5O_efl_t efl; /* External file list */
- H5O_pline_t pline; /* I/O pipeline */
H5P_genplist_t *plist; /* Property list */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5P_dcrt_close)
/* Check arguments */
- if(NULL == (plist = H5I_object(dcpl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list")
/* Get the fill value, external file list, and data pipeline properties
@@ -311,17 +351,12 @@ H5P_dcrt_close(hid_t dcpl_id, void UNUSED *close_data)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value")
if(H5P_get(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list")
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
- /* Clean up any values set for the fill-value, external file-list and
- * data pipeline */
+ /* Clean up any values set for the fill-value and external file-list */
if(H5O_msg_reset(H5O_FILL_ID, &fill) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't release fill info")
if(H5O_msg_reset(H5O_EFL_ID, &efl) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't release external file list info")
- if(H5O_msg_reset(H5O_PLINE_ID, &pline) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't release pipeline info")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -329,6 +364,75 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5P_dcrt_layout_cmp
+ *
+ * Purpose: Callback routine which is called whenever the layout
+ * property in the dataset creation property list is
+ * compared.
+ *
+ * Return: positive if VALUE1 is greater than VALUE2, negative if
+ * VALUE2 is greater than VALUE1 and zero if VALUE1 and
+ * VALUE2 are equal.
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, December 23, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5P_dcrt_layout_cmp(const void *_layout1, const void *_layout2, size_t UNUSED size)
+{
+ const H5O_layout_t *layout1 = (const H5O_layout_t *)_layout1, /* Create local aliases for values */
+ *layout2 = (const H5O_layout_t *)_layout2;
+ herr_t ret_value = 0; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_dcrt_layout_cmp)
+
+ /* Sanity check */
+ HDassert(layout1);
+ HDassert(layout1);
+ HDassert(size == sizeof(H5O_layout_t));
+
+ /* Check for different layout type */
+ if(layout1->type < layout2->type) HGOTO_DONE(-1)
+ if(layout1->type > layout2->type) HGOTO_DONE(1)
+
+ /* Check for different layout version */
+ if(layout1->version < layout2->version) HGOTO_DONE(-1)
+ if(layout1->version > layout2->version) HGOTO_DONE(1)
+
+ /* Compare non-dataset-specific fields in layout info */
+ switch(layout1->type) {
+ case H5D_COMPACT:
+ case H5D_CONTIGUOUS:
+ break;
+
+ case H5D_CHUNKED:
+ {
+ unsigned u; /* Local index variable */
+
+ /* Check the number of dimensions */
+ if(layout1->u.chunk.ndims < layout2->u.chunk.ndims) HGOTO_DONE(-1)
+ if(layout1->u.chunk.ndims > layout2->u.chunk.ndims) HGOTO_DONE(1)
+
+ /* Compare the chunk dims */
+ for(u = 0; u < layout1->u.chunk.ndims - 1; u++) {
+ if(layout1->u.chunk.dim[u] < layout2->u.chunk.dim[u]) HGOTO_DONE(-1)
+ if(layout1->u.chunk.dim[u] > layout2->u.chunk.dim[u]) HGOTO_DONE(1)
+ } /* end for */
+ } /* end case */
+ break;
+
+ default:
+ HDassert(0 && "Unknown layout type!");
+ } /* end switch */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_dcrt_layout_cmp() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5P_fill_value_cmp
*
* Purpose: Callback routine which is called whenever the fill value
@@ -471,107 +575,19 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5P_dcrt_data_pipeline_cmp
- *
- * Purpose: Callback routine which is called whenever the filter pipeline
- * property in the dataset creation property list is compared.
- *
- * Return: positive if VALUE1 is greater than VALUE2, negative if
- * VALUE2 is greater than VALUE1 and zero if VALUE1 and
- * VALUE2 are equal.
- *
- * Programmer: Quincey Koziol
- * Wednesday, January 7, 2004
- *
- *-------------------------------------------------------------------------
- */
-static int
-H5P_dcrt_data_pipeline_cmp(const void *_pline1, const void *_pline2, size_t UNUSED size)
-{
- const H5O_pline_t *pline1 = (const H5O_pline_t *)_pline1, /* Create local aliases for values */
- *pline2 = (const H5O_pline_t *)_pline2;
- int cmp_value; /* Value from comparison */
- herr_t ret_value = 0; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_dcrt_data_pipeline_cmp)
-
- /* Sanity check */
- HDassert(pline1);
- HDassert(pline2);
- HDassert(size == sizeof(H5O_pline_t));
-
- /* Check the number of allocated pipeline entries */
- if(pline1->nalloc < pline2->nalloc) HGOTO_DONE(-1);
- if(pline1->nalloc > pline2->nalloc) HGOTO_DONE(1);
-
- /* Check the number of used pipeline entries */
- if(pline1->nused < pline2->nused) HGOTO_DONE(-1);
- if(pline1->nused > pline2->nused) HGOTO_DONE(1);
-
- /* Check the filter entry information */
- if(pline1->filter == NULL && pline2->filter != NULL) HGOTO_DONE(-1);
- if(pline1->filter != NULL && pline2->filter == NULL) HGOTO_DONE(1);
- if(pline1->filter != NULL && pline1->nused > 0) {
- size_t u; /* Local index variable */
-
- /* Loop through all filters, comparing them */
- for(u = 0; u < pline1->nused; u++) {
- /* Check the ID of the filter */
- if(pline1->filter[u].id < pline2->filter[u].id) HGOTO_DONE(-1);
- if(pline1->filter[u].id > pline2->filter[u].id) HGOTO_DONE(1);
-
- /* Check the flags for the filter */
- if(pline1->filter[u].flags < pline2->filter[u].flags) HGOTO_DONE(-1);
- if(pline1->filter[u].flags > pline2->filter[u].flags) HGOTO_DONE(1);
-
- /* Check the name of the filter */
- if(pline1->filter[u].name == NULL && pline2->filter[u].name != NULL) HGOTO_DONE(-1);
- if(pline1->filter[u].name != NULL && pline2->filter[u].name == NULL) HGOTO_DONE(1);
- if(pline1->filter[u].name != NULL)
- if((cmp_value = HDstrcmp(pline1->filter[u].name, pline2->filter[u].name)) != 0)
- HGOTO_DONE(cmp_value);
-
- /* Check the number of parameters for the filter */
- if(pline1->filter[u].cd_nelmts < pline2->filter[u].cd_nelmts) HGOTO_DONE(-1);
- if(pline1->filter[u].cd_nelmts > pline2->filter[u].cd_nelmts) HGOTO_DONE(1);
-
- /* Check the filter parameter information */
- if(pline1->filter[u].cd_values == NULL && pline2->filter[u].cd_values != NULL) HGOTO_DONE(-1);
- if(pline1->filter[u].cd_values != NULL && pline2->filter[u].cd_values == NULL) HGOTO_DONE(1);
- if(pline1->filter[u].cd_values != NULL && pline1->filter[u].cd_nelmts > 0) {
- size_t v; /* Local index variable */
-
- /* Loop through all parameters, comparing them */
- for(v = 0; v < pline1->filter[u].cd_nelmts; v++) {
- /* Check each parameter for the filter */
- if(pline1->filter[u].cd_values[v] < pline2->filter[u].cd_values[v]) HGOTO_DONE(-1);
- if(pline1->filter[u].cd_values[v] > pline2->filter[u].cd_values[v]) HGOTO_DONE(1);
- } /* end for */
- } /* end if */
- } /* end for */
- } /* end if */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5P_dcrt_data_pipeline_cmp() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5P_set_layout
*
* Purpose: Sets the layout of raw data in the file.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * Tuesday, November 23, 2004
- *
- * Modifications:
+ * Programmer: Quincey Koziol
+ * Tuesday, November 23, 2004
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5P_set_layout(H5P_genplist_t *plist, H5D_layout_t layout)
+H5P_set_layout(H5P_genplist_t *plist, const H5O_layout_t *layout)
{
unsigned alloc_time_state; /* State of allocation time property */
herr_t ret_value = SUCCEED; /* return value */
@@ -591,7 +607,7 @@ H5P_set_layout(H5P_genplist_t *plist, H5D_layout_t layout)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value")
/* Set the default based on layout */
- switch(layout) {
+ switch(layout->type) {
case H5D_COMPACT:
fill.alloc_time = H5D_ALLOC_TIME_EARLY;
break;
@@ -605,22 +621,58 @@ H5P_set_layout(H5P_genplist_t *plist, H5D_layout_t layout)
break;
default:
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unknown layou t type")
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unknown layout type")
} /* end switch */
/* Set updated fill value info */
if(H5P_set(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set space allocat ion time")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set space allocation time")
} /* end if */
/* Set layout value */
- if(H5P_set(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
+ if(H5P_set(plist, H5D_CRT_LAYOUT_NAME, layout) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set layout")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P_set_layout() */
+#ifndef H5_HAVE_C99_DESIGNATED_INITIALIZER
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_init_def_layout
+ *
+ * Purpose: Set the default layout information for the various types of
+ * dataset layouts
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, January 13, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P_init_def_layout(void)
+{
+ const H5O_layout_chunk_t def_layout_chunk = H5D_DEF_LAYOUT_CHUNK_INIT;
+ const H5O_storage_compact_t def_store_compact = H5D_DEF_STORAGE_COMPACT_INIT;
+ const H5O_storage_chunk_t def_store_chunk = H5D_DEF_STORAGE_CHUNK_INIT;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_init_def_layout)
+
+ /* Initialize the default layout info for non-contigous layouts */
+ H5D_def_layout_compact_g.storage.u.compact = def_store_compact;
+ H5D_def_layout_chunk_g.u.chunk = def_layout_chunk;
+ H5D_def_layout_chunk_g.storage.u.chunk = def_store_chunk;
+
+ /* Note that we've initialized the default values */
+ H5P_dcrt_def_layout_init_g = TRUE;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5P_init_def_layout() */
+#endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
+
/*-------------------------------------------------------------------------
* Function: H5Pset_layout
@@ -642,29 +694,57 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Pset_layout(hid_t plist_id, H5D_layout_t layout)
+H5Pset_layout(hid_t plist_id, H5D_layout_t layout_type)
{
- H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value=SUCCEED; /* return value */
+ H5P_genplist_t *plist; /* Property list pointer */
+ const H5O_layout_t *layout; /* Pointer to default layout information for type specified */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Pset_layout, FAIL)
- H5TRACE2("e", "iDl", plist_id, layout);
+ H5TRACE2("e", "iDl", plist_id, layout_type);
/* Check arguments */
- if (layout < 0 || layout >= H5D_NLAYOUTS)
+ if(layout_type < 0 || layout_type >= H5D_NLAYOUTS)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "raw data layout method is not valid")
/* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE)))
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+#ifndef H5_HAVE_C99_DESIGNATED_INITIALIZER
+ /* If the compiler doesn't support C99 designated initializers, check if
+ * the default layout structs have been initialized yet or not. *ick* -QAK
+ */
+ if(!H5P_dcrt_def_layout_init_g)
+ if(H5P_init_def_layout() < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't initialize default layout info")
+#endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
+
+ /* Get pointer to correct default layout */
+ switch(layout_type) {
+ case H5D_COMPACT:
+ layout = &H5D_def_layout_compact_g;
+ break;
+
+ case H5D_CONTIGUOUS:
+ layout = &H5D_def_layout_contig_g;
+ break;
+
+ case H5D_CHUNKED:
+ layout = &H5D_def_layout_chunk_g;
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unknown layout type")
+ } /* end switch */
+
/* Set value */
- if(H5P_set_layout (plist, layout) < 0)
+ if(H5P_set_layout(plist, layout) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set layout")
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Pset_layout() */
/*-------------------------------------------------------------------------
@@ -692,22 +772,26 @@ H5D_layout_t
H5Pget_layout(hid_t plist_id)
{
H5P_genplist_t *plist; /* Property list pointer */
- H5D_layout_t ret_value=H5D_LAYOUT_ERROR;
+ H5O_layout_t layout; /* Layout property */
+ H5D_layout_t ret_value; /* Return value */
FUNC_ENTER_API(H5Pget_layout, H5D_LAYOUT_ERROR)
H5TRACE1("Dl", "i", plist_id);
/* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE)))
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5D_LAYOUT_ERROR, "can't find object for ID")
- /* Get value */
- if(H5P_get(plist, H5D_CRT_LAYOUT_NAME, &ret_value) < 0)
+ /* Get layout property */
+ if(H5P_get(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5D_LAYOUT_ERROR, "can't get layout")
+ /* Set return value */
+ ret_value = layout.type;
+
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* ed H5Pget_layout() */
/*-------------------------------------------------------------------------
@@ -715,7 +799,7 @@ done:
*
* Purpose: Sets the number of dimensions and the size of each chunk to
* the values specified. The dimensionality of the chunk should
- * match the dimensionality of the data space.
+ * match the dimensionality of the dataspace.
*
* As a side effect, the layout method is changed to
* H5D_CHUNKED.
@@ -738,7 +822,7 @@ herr_t
H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[/*ndims*/])
{
H5P_genplist_t *plist; /* Property list pointer */
- uint32_t real_dims[H5O_LAYOUT_NDIMS]; /* Full-sized array to hold chunk dims */
+ H5O_layout_t chunk_layout; /* Layout information for setting chunk info */
uint64_t chunk_nelmts; /* Number of elements in chunk */
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -754,8 +838,18 @@ H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[/*ndims*/])
if(!dim)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no chunk dimensions specified")
- /* Verify & initialize internal chunk dims */
- HDmemset(real_dims, 0, sizeof(real_dims));
+#ifndef H5_HAVE_C99_DESIGNATED_INITIALIZER
+ /* If the compiler doesn't support C99 designated initializers, check if
+ * the default layout structs have been initialized yet or not. *ick* -QAK
+ */
+ if(!H5P_dcrt_def_layout_init_g)
+ if(H5P_init_def_layout() < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't initialize default layout info")
+#endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
+
+ /* Verify & initialize property's chunk dims */
+ HDmemcpy(&chunk_layout, &H5D_def_layout_chunk_g, sizeof(H5D_def_layout_chunk_g));
+ HDmemset(&chunk_layout.u.chunk.dim, 0, sizeof(chunk_layout.u.chunk.dim));
chunk_nelmts = 1;
for(u = 0; u < (unsigned)ndims; u++) {
if(dim[u] == 0)
@@ -765,7 +859,7 @@ H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[/*ndims*/])
chunk_nelmts *= dim[u];
if(chunk_nelmts > (uint64_t)0xffffffff)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "number of elements in chunk must be < 4GB")
- real_dims[u] = (uint32_t)dim[u]; /* Store user's chunk dimensions */
+ chunk_layout.u.chunk.dim[u] = (uint32_t)dim[u]; /* Store user's chunk dimensions */
} /* end for */
/* Get the plist structure */
@@ -773,12 +867,9 @@ H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[/*ndims*/])
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Set chunk information in property list */
- if(H5P_set_layout(plist, H5D_CHUNKED) < 0)
+ chunk_layout.u.chunk.ndims = (unsigned)ndims;
+ if(H5P_set_layout(plist, &chunk_layout) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set layout")
- if(H5P_set(plist, H5D_CRT_CHUNK_DIM_NAME, &ndims) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set chunk dimensionanlity")
- if(H5P_set(plist, H5D_CRT_CHUNK_SIZE_NAME, real_dims) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set chunk size")
done:
FUNC_LEAVE_API(ret_value)
@@ -812,40 +903,33 @@ done:
int
H5Pget_chunk(hid_t plist_id, int max_ndims, hsize_t dim[]/*out*/)
{
- int ndims;
- H5D_layout_t layout;
H5P_genplist_t *plist; /* Property list pointer */
- int ret_value;
+ H5O_layout_t layout; /* Layout information */
+ int ret_value; /* Return value */
FUNC_ENTER_API(H5Pget_chunk, FAIL)
H5TRACE3("Is", "iIsx", plist_id, max_ndims, dim);
/* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE)))
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ /* Retrieve the layout property */
if(H5P_get(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout")
- if(H5D_CHUNKED != layout)
+ if(H5D_CHUNKED != layout.type)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a chunked storage layout")
- if(H5P_get(plist, H5D_CRT_CHUNK_DIM_NAME, &ndims) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get chunk dimensionality")
-
if(dim) {
- int i;
- uint32_t chunk_size[H5O_LAYOUT_NDIMS];
-
- if(H5P_get(plist, H5D_CRT_CHUNK_SIZE_NAME, chunk_size) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get chunk size")
+ unsigned u; /* Local index variable */
/* Get the dimension sizes */
- for(i = 0; i < ndims && i < max_ndims; i++)
- dim[i] = chunk_size[i];
+ for(u = 0; u < layout.u.chunk.ndims && u < (unsigned)max_ndims; u++)
+ dim[u] = layout.u.chunk.dim[u];
} /* end if */
/* Set the return value */
- ret_value = ndims;
+ ret_value = (int)layout.u.chunk.ndims;
done:
FUNC_LEAVE_API(ret_value)
@@ -865,7 +949,7 @@ done:
* should be defined in order. The total size of the dataset is
* the sum of the SIZE arguments for all the external files. If
* the total size is larger than the size of a dataset then the
- * dataset can be extended (provided the data space also allows
+ * dataset can be extended (provided the dataspace also allows
* the extending).
*
* Return: Non-negative on success/Negative on failure
@@ -889,7 +973,7 @@ H5Pset_external(hid_t plist_id, const char *name, off_t offset, hsize_t size)
hsize_t total, tmp;
H5O_efl_t efl;
H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Pset_external, FAIL)
H5TRACE4("e", "i*soh", plist_id, name, offset, size);
@@ -903,7 +987,7 @@ H5Pset_external(hid_t plist_id, const char *name, off_t offset, hsize_t size)
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "zero size")
/* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE)))
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
if(H5P_get(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
@@ -921,15 +1005,15 @@ H5Pset_external(hid_t plist_id, const char *name, off_t offset, hsize_t size)
/* Add to the list */
- if (efl.nused >= efl.nalloc) {
+ if(efl.nused >= efl.nalloc) {
size_t na = efl.nalloc + H5O_EFL_ALLOC;
- H5O_efl_entry_t *x = H5MM_realloc (efl.slot, na*sizeof(H5O_efl_entry_t));
+ H5O_efl_entry_t *x = (H5O_efl_entry_t *)H5MM_realloc(efl.slot, na * sizeof(H5O_efl_entry_t));
- if (!x)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(!x)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
efl.nalloc = na;
efl.slot = x;
- }
+ } /* end if */
idx = efl.nused;
efl.slot[idx].name_offset = 0; /*not entered into heap yet*/
efl.slot[idx].name = H5MM_xstrdup (name);
@@ -977,7 +1061,7 @@ H5Pget_external_count(hid_t plist_id)
H5TRACE1("Is", "i", plist_id);
/* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE)))
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Get value */
@@ -985,11 +1069,11 @@ H5Pget_external_count(hid_t plist_id)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list")
/* Set return value */
- ret_value=(int)efl.nused;
+ ret_value = (int)efl.nused;
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Pget_external_count() */
/*-------------------------------------------------------------------------
@@ -1029,727 +1113,33 @@ H5Pget_external(hid_t plist_id, unsigned idx, size_t name_size, char *name/*out*
{
H5O_efl_t efl;
H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value=SUCCEED; /* return value */
+ herr_t ret_value = SUCCEED; /* return value */
FUNC_ENTER_API(H5Pget_external, FAIL)
H5TRACE6("e", "iIuzxxx", plist_id, idx, name_size, name, offset, size);
/* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE)))
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Get value */
if(H5P_get(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list")
- if (idx>=efl.nused)
- HGOTO_ERROR (H5E_ARGS, H5E_BADRANGE, FAIL, "external file index is out of range")
+ if(idx >= efl.nused)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "external file index is out of range")
/* Return values */
- if (name_size>0 && name)
- HDstrncpy (name, efl.slot[idx].name, name_size);
- if (offset)
+ if(name_size>0 && name)
+ HDstrncpy(name, efl.slot[idx].name, name_size);
+ if(offset)
*offset = efl.slot[idx].offset;
- if (size)
+ if(size)
*size = efl.slot[idx].size;
done:
FUNC_LEAVE_API(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5P_modify_filter
- *
- * Purpose: Modifies the specified FILTER in the
- * transient or permanent output filter pipeline
- * depending on whether PLIST is a dataset creation or dataset
- * transfer property list. The FLAGS argument specifies certain
- * general properties of the filter and is documented below.
- * The CD_VALUES is an array of CD_NELMTS integers which are
- * auxiliary data for the filter. The integer vlues will be
- * stored in the dataset object header as part of the filter
- * information.
- *
- * The FLAGS argument is a bit vector of the following fields:
- *
- * H5Z_FLAG_OPTIONAL(0x0001)
- * If this bit is set then the filter is optional. If the
- * filter fails during an H5Dwrite() operation then the filter
- * is just excluded from the pipeline for the chunk for which it
- * failed; the filter will not participate in the pipeline
- * during an H5Dread() of the chunk. If this bit is clear and
- * the filter fails then the entire I/O operation fails.
- * If this bit is set but encoding is disabled for a filter,
- * attempting to write will generate an error.
- *
- * Note: This function currently supports only the permanent filter
- * pipeline. That is, PLIST_ID must be a dataset creation
- * property list.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Wednesday, October 17, 2007
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5P_modify_filter(H5P_genplist_t *plist, H5Z_filter_t filter, unsigned flags,
- size_t cd_nelmts, const unsigned cd_values[/*cd_nelmts*/])
-{
- H5O_pline_t pline;
- herr_t ret_value = SUCCEED; /* return value */
-
- FUNC_ENTER_NOAPI(H5P_modify_filter, FAIL)
-
- /* Get the pipeline property to append to */
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
-
- /* Modify the filter parameters of the I/O pipeline */
- if(H5Z_modify(&pline, filter, flags, cd_nelmts, cd_values) < 0)
- HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add filter to pipeline")
-
- /* Put the I/O pipeline information back into the property list */
- if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5P_modify_filter() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5Pmodify_filter
- *
- * Purpose: Modifies the specified FILTER in the
- * transient or permanent output filter pipeline
- * depending on whether PLIST is a dataset creation or dataset
- * transfer property list. The FLAGS argument specifies certain
- * general properties of the filter and is documented below.
- * The CD_VALUES is an array of CD_NELMTS integers which are
- * auxiliary data for the filter. The integer vlues will be
- * stored in the dataset object header as part of the filter
- * information.
- *
- * The FLAGS argument is a bit vector of the following fields:
- *
- * H5Z_FLAG_OPTIONAL(0x0001)
- * If this bit is set then the filter is optional. If the
- * filter fails during an H5Dwrite() operation then the filter
- * is just excluded from the pipeline for the chunk for which it
- * failed; the filter will not participate in the pipeline
- * during an H5Dread() of the chunk. If this bit is clear and
- * the filter fails then the entire I/O operation fails.
- * If this bit is set but encoding is disabled for a filter,
- * attempting to write will generate an error.
- *
- * Note: This function currently supports only the permanent filter
- * pipeline. That is, PLIST_ID must be a dataset creation
- * property list.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Friday, April 5, 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags,
- size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/])
-{
- H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value = SUCCEED; /* return value */
-
- FUNC_ENTER_API(H5Pmodify_filter, FAIL)
- H5TRACE5("e", "iZfIuz*[a3]Iu", plist_id, filter, flags, cd_nelmts, cd_values);
-
- /* Check args */
- if (filter<0 || filter>H5Z_FILTER_MAX)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identifier")
- if (flags & ~((unsigned)H5Z_FLAG_DEFMASK))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags")
- if (cd_nelmts>0 && !cd_values)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no client data values supplied")
-
- /* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
-
- /* Modify the filter parameters of the I/O pipeline */
- if(H5P_modify_filter(plist, filter, flags, cd_nelmts, cd_values) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't modify filter")
-
-done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Pmodify_filter() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5Pset_filter
- *
- * Purpose: Adds the specified FILTER and corresponding properties to the
- * end of the transient or permanent output filter pipeline
- * depending on whether PLIST is a dataset creation or dataset
- * transfer property list. The FLAGS argument specifies certain
- * general properties of the filter and is documented below.
- * The CD_VALUES is an array of CD_NELMTS integers which are
- * auxiliary data for the filter. The integer vlues will be
- * stored in the dataset object header as part of the filter
- * information.
- *
- * The FLAGS argument is a bit vector of the following fields:
- *
- * H5Z_FLAG_OPTIONAL(0x0001)
- * If this bit is set then the filter is optional. If the
- * filter fails during an H5Dwrite() operation then the filter
- * is just excluded from the pipeline for the chunk for which it
- * failed; the filter will not participate in the pipeline
- * during an H5Dread() of the chunk. If this bit is clear and
- * the filter fails then the entire I/O operation fails.
- * If this bit is set but encoding is disabled for a filter,
- * attempting to write will generate an error.
- *
- * Note: This function currently supports only the permanent filter
- * pipeline. That is, PLIST_ID must be a dataset creation
- * property list.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * Wednesday, April 15, 1998
- *
- * Modifications:
- *
- * Raymond Lu
- * Tuesday, October 2, 2001
- * Changed the way to check parameter and set property for
- * generic property list.
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags,
- size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/])
-{
- H5O_pline_t pline;
- H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value=SUCCEED; /* return value */
-
- FUNC_ENTER_API(H5Pset_filter, FAIL)
- H5TRACE5("e", "iZfIuz*[a3]Iu", plist_id, filter, flags, cd_nelmts, cd_values);
-
- /* Check args */
- if (filter<0 || filter>H5Z_FILTER_MAX)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identifier")
- if (flags & ~((unsigned)H5Z_FLAG_DEFMASK))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags")
- if (cd_nelmts>0 && !cd_values)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no client data values supplied")
-
- /* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
-
- /* Get the pipeline property to append to */
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
-
- /* Add the filter to the I/O pipeline */
- if(H5Z_append(&pline, filter, flags, cd_nelmts, cd_values) < 0)
- HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add filter to pipeline")
-
- /* Put the I/O pipeline information back into the property list */
- if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline")
-
-done:
- FUNC_LEAVE_API(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5Pget_nfilters
- *
- * Purpose: Returns the number of filters in the permanent or transient
- * pipeline depending on whether PLIST_ID is a dataset creation
- * or dataset transfer property list. In each pipeline the
- * filters are numbered from zero through N-1 where N is the
- * value returned by this function. During output to the file
- * the filters of a pipeline are applied in increasing order
- * (the inverse is true for input).
- *
- * Note: Only permanent filters are supported at this time.
- *
- * Return: Success: Number of filters or zero if there are none.
- *
- * Failure: Negative
- *
- * Programmer: Robb Matzke
- * Tuesday, August 4, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-int
-H5Pget_nfilters(hid_t plist_id)
-{
- H5O_pline_t pline;
- H5P_genplist_t *plist; /* Property list pointer */
- int ret_value; /* return value */
-
- FUNC_ENTER_API(H5Pget_nfilters, FAIL)
- H5TRACE1("Is", "i", plist_id);
-
- /* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
-
- /* Get value */
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
-
- /* Set return value */
- ret_value=(int)(pline.nused);
-
-done:
- FUNC_LEAVE_API(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5P_get_filter
- *
- * Purpose: Internal component of H5Pget_filter & H5Pget_filter_id
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Monday, October 23, 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5P_get_filter(const H5Z_filter_info_t *filter, unsigned int *flags/*out*/,
- size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/,
- size_t namelen, char name[]/*out*/,
- unsigned *filter_config /*out*/)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_filter)
-
- /* Check arguments */
- HDassert(filter);
-
- /* Filter flags */
- if(flags)
- *flags = filter->flags;
-
- /* Filter parameters */
- if(cd_values) {
- size_t i; /* Local index variable */
-
- for(i = 0; i < filter->cd_nelmts && i < *cd_nelmts; i++)
- cd_values[i] = filter->cd_values[i];
- } /* end if */
-
- /* Number of filter parameters */
- if(cd_nelmts)
- *cd_nelmts = filter->cd_nelmts;
-
- /* Filter name */
- if(namelen > 0 && name) {
- const char *s = filter->name;
-
- /* If there's no name on the filter, use the class's filter name */
- if(!s) {
- H5Z_class_t *cls = H5Z_find(filter->id);
-
- if(cls)
- s = cls->name;
- } /* end if */
-
- /* Check for actual name */
- if(s) {
- HDstrncpy(name, s, namelen);
- name[namelen - 1] = '\0';
- } /* end if */
- else {
- /* Check for unknown library filter */
- /* (probably from a future version of the library) */
- if(filter->id < 256) {
- HDstrncpy(name, "Unknown library filter", namelen);
- name[namelen - 1] = '\0';
- } /* end if */
- else
- name[0] = '\0';
- } /* end if */
- } /* end if */
-
- /* Filter configuration (assume filter ID has already been checked) */
- if(filter_config)
- H5Zget_filter_info(filter->id, filter_config);
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5P_get_filter() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5Pget_filter2
- *
- * Purpose: This is the query counterpart of H5Pset_filter() and returns
- * information about a particular filter number in a permanent
- * or transient pipeline depending on whether PLIST_ID is a
- * dataset creation or transfer property list. On input,
- * CD_NELMTS indicates the number of entries in the CD_VALUES
- * array allocated by the caller while on exit it contains the
- * number of values defined by the filter. FILTER_CONFIG is a bit
- * field contaning encode/decode flags from H5Zpublic.h. The IDX
- * should be a value between zero and N-1 as described for
- * H5Pget_nfilters() and the function will return failure if the
- * filter number is out of range.
- *
- * Return: Success: Filter identification number.
- *
- * Failure: H5Z_FILTER_ERROR (Negative)
- *
- * Programmer: Robb Matzke
- * Wednesday, April 15, 1998
- *
- *-------------------------------------------------------------------------
- */
-H5Z_filter_t
-H5Pget_filter2(hid_t plist_id, unsigned idx, unsigned int *flags/*out*/,
- size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/,
- size_t namelen, char name[]/*out*/,
- unsigned *filter_config /*out*/)
-{
- H5O_pline_t pline; /* Filter pipeline */
- const H5Z_filter_info_t *filter; /* Pointer to filter information */
- H5P_genplist_t *plist; /* Property list pointer */
- H5Z_filter_t ret_value; /* return value */
-
- FUNC_ENTER_API(H5Pget_filter2, H5Z_FILTER_ERROR)
- H5TRACE8("Zf", "iIux*zxzxx", plist_id, idx, flags, cd_nelmts, cd_values,
- namelen, name, filter_config);
-
- /* Check args */
- if(cd_nelmts || cd_values) {
- /*
- * It's likely that users forget to initialize this on input, so
- * we'll check that it has a reasonable value. The actual number
- * is unimportant because the H5O layer will detect when a message
- * is too large.
- */
- if(cd_nelmts && *cd_nelmts > 256)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "probable uninitialized *cd_nelmts argument")
- if(cd_nelmts && *cd_nelmts > 0 && !cd_values)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "client data values not supplied")
-
- /*
- * If cd_nelmts is null but cd_values is non-null then just ignore
- * cd_values
- */
- if(!cd_nelmts)
- cd_values = NULL;
- } /* end if */
-
- /* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5Z_FILTER_ERROR, "can't find object for ID")
-
- /* Get pipeline info */
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline")
-
- /* Check more args */
- if(idx >= pline.nused)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "filter number is invalid")
-
- /* Set pointer to particular filter to query */
- filter = &pline.filter[idx];
-
- /* Get filter information */
- if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info")
-
- /* Set return value */
- ret_value = filter->id;
-
-done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Pget_filter2() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5P_get_filter_by_id
- *
- * Purpose: This is an additional query counterpart of H5Pset_filter() and
- * returns information about a particular filter in a permanent
- * or transient pipeline depending on whether PLIST_ID is a
- * dataset creation or transfer property list. On input,
- * CD_NELMTS indicates the number of entries in the CD_VALUES
- * array allocated by the caller while on exit it contains the
- * number of values defined by the filter. FILTER_CONFIG is a bit
- * field contaning encode/decode flags from H5Zpublic.h. The ID
- * should be the filter ID to retrieve the parameters for. If the
- * filter is not set for the property list, an error will be returned.
- *
- * Return: Success: Non-negative
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * Wednesday, October 17, 2007
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id, unsigned int *flags/*out*/,
- size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/,
- size_t namelen, char name[]/*out*/, unsigned *filter_config)
-{
- H5O_pline_t pline; /* Filter pipeline */
- H5Z_filter_info_t *filter; /* Pointer to filter information */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5P_get_filter_by_id, FAIL)
-
- /* Get pipeline info */
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
-
- /* Get pointer to filter in pipeline */
- if(NULL == (filter = H5Z_filter_info(&pline, id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filter ID is invalid")
-
- /* Get filter information */
- if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5P_get_filter_by_id() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5Pget_filter_by_id2
- *
- * Purpose: This is an additional query counterpart of H5Pset_filter() and
- * returns information about a particular filter in a permanent
- * or transient pipeline depending on whether PLIST_ID is a
- * dataset creation or transfer property list. On input,
- * CD_NELMTS indicates the number of entries in the CD_VALUES
- * array allocated by the caller while on exit it contains the
- * number of values defined by the filter. FILTER_CONFIG is a bit
- * field contaning encode/decode flags from H5Zpublic.h. The ID
- * should be the filter ID to retrieve the parameters for. If the
- * filter is not set for the property list, an error will be returned.
- *
- * Return: Success: Non-negative
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * Friday, April 5, 2003
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/,
- size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/,
- size_t namelen, char name[]/*out*/, unsigned *filter_config)
-{
- H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_API(H5Pget_filter_by_id2, FAIL)
- H5TRACE8("e", "iZfx*zxzx*Iu", plist_id, id, flags, cd_nelmts, cd_values,
- namelen, name, filter_config);
-
- /* Check args */
- if(cd_nelmts || cd_values) {
- /*
- * It's likely that users forget to initialize this on input, so
- * we'll check that it has a reasonable value. The actual number
- * is unimportant because the H5O layer will detect when a message
- * is too large.
- */
- if(cd_nelmts && *cd_nelmts > 256)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "probable uninitialized *cd_nelmts argument")
- if(cd_nelmts && *cd_nelmts > 0 && !cd_values)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "client data values not supplied")
-
- /*
- * If cd_nelmts is null but cd_values is non-null then just ignore
- * cd_values
- */
- if(!cd_nelmts)
- cd_values = NULL;
- } /* end if */
-
- /* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
-
- /* Get filter info */
- if(H5P_get_filter_by_id(plist, id, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info")
-
-done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Pget_filter_by_id2() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5Pall_filters_avail
- *
- * Purpose: This is a query routine to verify that all the filters set
- * in the dataset creation property list are available currently.
- *
- * Return: Success: TRUE if all filters available, FALSE if one or
- * more filters not currently available.
- * Failure: FAIL on error
- *
- * Programmer: Quincey Koziol
- * Tuesday, April 8, 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-htri_t
-H5Pall_filters_avail(hid_t plist_id)
-{
- H5O_pline_t pline; /* Filter pipeline */
- H5P_genplist_t *plist; /* Property list pointer */
- hbool_t ret_value = TRUE; /* return value */
-
- FUNC_ENTER_API(H5Pall_filters_avail, UFAIL)
- H5TRACE1("t", "i", plist_id);
-
- /* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, UFAIL, "can't find object for ID")
-
- /* Get pipeline info */
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, UFAIL, "can't get pipeline")
-
- /* Set return value */
- if(UFAIL == (ret_value = H5Z_all_filters_avail(&pline)))
- HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, UFAIL, "can't check pipeline information")
-
-done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Pall_filters_avail() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5Premove_filter
- *
- * Purpose: Deletes a filter from the dataset creation property list;
- * deletes all filters if FILTER is H5Z_FILTER_NONE
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Pedro Vicente
- * January 26, 2004
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5Premove_filter(hid_t plist_id, H5Z_filter_t filter)
-{
- H5P_genplist_t *plist; /* Property list pointer */
- H5O_pline_t pline; /* Filter pipeline */
- herr_t ret_value = SUCCEED; /* return value */
-
- FUNC_ENTER_API(H5Premove_filter, FAIL)
- H5TRACE2("e", "iZf", plist_id, filter);
-
- /* Get the property list structure */
- if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
-
- /* Get pipeline info */
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline")
-
- /* Check if there are any filters */
- if (pline.filter) {
- /* Delete filter */
- if(H5Z_delete(&pline, filter) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't delete filter")
-
- /* Put the I/O pipeline information back into the property list */
- if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline")
- } /* end if */
-
-done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Premove_filter() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5Pset_deflate
- *
- * Purpose: Sets the compression method for a permanent or transient
- * filter pipeline (depending on whether PLIST_ID is a dataset
- * creation or transfer property list) to H5Z_FILTER_DEFLATE
- * and the compression level to LEVEL which should be a value
- * between zero and nine, inclusive. Lower compression levels
- * are faster but result in less compression. This is the same
- * algorithm as used by the GNU gzip program.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * Wednesday, April 15, 1998
- *
- * Modifications:
- *
- * Raymond Lu
- * Tuesday, October 2, 2001
- * Changed the way to check parameter and set property for
- * generic property list.
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5Pset_deflate(hid_t plist_id, unsigned level)
-{
- H5O_pline_t pline;
- H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value=SUCCEED; /* return value */
-
- FUNC_ENTER_API(H5Pset_deflate, FAIL)
- H5TRACE2("e", "iIu", plist_id, level);
-
- /* Check arguments */
- if(level>9)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid deflate level")
-
- /* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
-
- /* Add the filter */
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
- if(H5Z_append(&pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &level) < 0)
- HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add deflate filter to pipeline")
- if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline")
-
-done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Pset_deflate() */
+} /* end H5Pget_external() */
/*-------------------------------------------------------------------------
@@ -1819,11 +1209,11 @@ H5Pset_szip(hid_t plist_id, unsigned options_mask, unsigned pixels_per_block)
cd_values[1]=pixels_per_block;
/* Add the filter */
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
if(H5Z_append(&pline, H5Z_FILTER_SZIP, H5Z_FLAG_OPTIONAL, (size_t)2, cd_values) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add szip filter to pipeline")
- if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
+ if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline")
done:
@@ -1862,15 +1252,15 @@ H5Pset_shuffle(hid_t plist_id)
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list")
/* Get the plist structure */
- if(NULL == (plist = H5I_object(plist_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(plist_id)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Add the filter */
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
if(H5Z_append(&pline, H5Z_FILTER_SHUFFLE, H5Z_FLAG_OPTIONAL, (size_t)0, NULL) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to shuffle the data")
- if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
+ if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline")
done:
@@ -1908,15 +1298,15 @@ H5Pset_nbit(hid_t plist_id)
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list")
/* Get the plist structure */
- if(NULL == (plist = H5I_object(plist_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(plist_id)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Add the nbit filter */
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
if(H5Z_append(&pline, H5Z_FILTER_NBIT, H5Z_FLAG_OPTIONAL, (size_t)0, NULL) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add nbit filter to pipeline")
- if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
+ if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline")
done:
@@ -1970,11 +1360,13 @@ H5Pset_scaleoffset(hid_t plist_id, H5Z_SO_scale_type_t scale_type, int scale_fac
if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_CREATE))
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list")
+ if(scale_factor < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "scale factor must be > 0")
if(scale_type!=H5Z_SO_FLOAT_DSCALE && scale_type!=H5Z_SO_FLOAT_ESCALE && scale_type!=H5Z_SO_INT)
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "invalid scale type")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid scale type")
/* Get the plist structure */
- if(NULL == (plist = H5I_object(plist_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(plist_id)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Set parameters for the filter
@@ -1986,14 +1378,14 @@ H5Pset_scaleoffset(hid_t plist_id, H5Z_SO_scale_type_t scale_type, int scale_fac
* if scale_factor = 0, then filter calculates minimum number of bits
*/
cd_values[0] = scale_type;
- cd_values[1] = scale_factor;
+ cd_values[1] = (unsigned)scale_factor;
/* Add the scaleoffset filter */
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
if(H5Z_append(&pline, H5Z_FILTER_SCALEOFFSET, H5Z_FLAG_OPTIONAL, (size_t)2, cd_values) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add scaleoffset filter to pipeline")
- if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
+ if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline")
done:
@@ -2002,48 +1394,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5Pset_fletcher32
- *
- * Purpose: Sets Fletcher32 checksum of EDC for a dataset creation
- * property list.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Raymond Lu
- * Dec 19, 2002
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5Pset_fletcher32(hid_t plist_id)
-{
- H5O_pline_t pline;
- H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value=SUCCEED; /* return value */
-
- FUNC_ENTER_API(H5Pset_fletcher32, FAIL)
- H5TRACE1("e", "i", plist_id);
-
- /* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
-
- /* Add the Fletcher32 checksum as a filter */
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
- if(H5Z_append(&pline, H5Z_FILTER_FLETCHER32, H5Z_FLAG_MANDATORY, (size_t)0, NULL) < 0)
- HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add fletcher32 filter to pipeline")
- if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline")
-
-done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Pset_fletcher32() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5Pset_fill_value
*
* Purpose: Set the fill value for a dataset creation property list. The
@@ -2093,13 +1443,13 @@ H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value)
H5T_path_t *tpath; /* Conversion information */
/* Retrieve pointer to datatype */
- if(NULL == (type = H5I_object_verify(type_id, H5I_DATATYPE)))
+ if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
/* Set the fill value */
if(NULL == (fill.type = H5T_copy(type, H5T_COPY_TRANSIENT)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy datatype")
- fill.size = H5T_get_size(type);
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy datatype")
+ fill.size = (ssize_t)H5T_get_size(type);
if(NULL == (fill.buf = H5MM_malloc((size_t)fill.size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "memory allocation failed for fill value")
HDmemcpy(fill.buf, value, (size_t)fill.size);
@@ -2192,7 +1542,7 @@ H5P_get_fill_value(H5P_genplist_t *plist, const H5T_t *type, void *value/*out*/,
*/
if(NULL == (tpath = H5T_path_find(fill.type, type, NULL, NULL, dxpl_id, FALSE)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and dst datatypes")
- if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(fill.type, H5T_COPY_TRANSIENT))) < 0)
+ if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(fill.type, H5T_COPY_TRANSIENT), FALSE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register datatype")
/*
@@ -2214,7 +1564,7 @@ H5P_get_fill_value(H5P_genplist_t *plist, const H5T_t *type, void *value/*out*/,
HDmemcpy(buf, fill.buf, H5T_get_size(fill.type));
/* Do the conversion */
- if((dst_id = H5I_register(H5I_DATATYPE, H5T_copy(type, H5T_COPY_TRANSIENT))) < 0)
+ if((dst_id = H5I_register(H5I_DATATYPE, H5T_copy(type, H5T_COPY_TRANSIENT), FALSE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register datatype")
if(H5T_convert(tpath, src_id, dst_id, (size_t)1, (size_t)0, (size_t)0, buf, bkg, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed")
@@ -2227,9 +1577,9 @@ done:
if(bkg != value)
H5MM_xfree(bkg);
if(src_id >= 0)
- H5I_dec_ref(src_id);
+ H5I_dec_ref(src_id, FALSE);
if(dst_id >= 0)
- H5I_dec_ref(dst_id);
+ H5I_dec_ref(dst_id, FALSE);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P_get_fill_value() */
@@ -2262,7 +1612,7 @@ H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/)
H5TRACE3("e", "iix", plist_id, type_id, value);
/* Check arguments */
- if(NULL == (type = H5I_object_verify(type_id, H5I_DATATYPE)))
+ if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
if(!value)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,"no fill value output buffer")
@@ -2430,14 +1780,14 @@ H5Pset_alloc_time(hid_t plist_id, H5D_alloc_time_t alloc_time)
/* Check for resetting to default for layout type */
if(alloc_time == H5D_ALLOC_TIME_DEFAULT) {
- H5D_layout_t layout; /* Type of storage layout */
+ H5O_layout_t layout; /* Type of storage layout */
/* Retrieve the storage layout */
if(H5P_get(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get layout")
/* Set the default based on layout */
- switch(layout) {
+ switch(layout.type) {
case H5D_COMPACT:
alloc_time = H5D_ALLOC_TIME_EARLY;
break;
@@ -2615,158 +1965,3 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_fill_time() */
-#ifndef H5_NO_DEPRECATED_SYMBOLS
-
-/*-------------------------------------------------------------------------
- * Function: H5Pget_filter1
- *
- * Purpose: This is the query counterpart of H5Pset_filter() and returns
- * information about a particular filter number in a permanent
- * or transient pipeline depending on whether PLIST_ID is a
- * dataset creation or transfer property list. On input,
- * CD_NELMTS indicates the number of entries in the CD_VALUES
- * array allocated by the caller while on exit it contains the
- * number of values defined by the filter. The IDX
- * should be a value between zero and N-1 as described for
- * H5Pget_nfilters() and the function will return failure if the
- * filter number is out of range.
- *
- * Return: Success: Filter identification number.
- *
- * Failure: H5Z_FILTER_ERROR (Negative)
- *
- * Programmer: Robb Matzke
- * Wednesday, April 15, 1998
- *
- *-------------------------------------------------------------------------
- */
-H5Z_filter_t
-H5Pget_filter1(hid_t plist_id, unsigned idx, unsigned int *flags/*out*/,
- size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/,
- size_t namelen, char name[]/*out*/)
-{
- H5O_pline_t pline; /* Filter pipeline */
- const H5Z_filter_info_t *filter; /* Pointer to filter information */
- H5P_genplist_t *plist; /* Property list pointer */
- H5Z_filter_t ret_value; /* return value */
-
- FUNC_ENTER_API(H5Pget_filter1, H5Z_FILTER_ERROR)
- H5TRACE7("Zf", "iIux*zxzx", plist_id, idx, flags, cd_nelmts, cd_values, namelen,
- name);
-
- /* Check args */
- if(cd_nelmts || cd_values) {
- /*
- * It's likely that users forget to initialize this on input, so
- * we'll check that it has a reasonable value. The actual number
- * is unimportant because the H5O layer will detect when a message
- * is too large.
- */
- if(cd_nelmts && *cd_nelmts > 256)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "probable uninitialized *cd_nelmts argument")
- if(cd_nelmts && *cd_nelmts > 0 && !cd_values)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "client data values not supplied")
-
- /*
- * If cd_nelmts is null but cd_values is non-null then just ignore
- * cd_values
- */
- if(!cd_nelmts)
- cd_values = NULL;
- } /* end if */
-
- /* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5Z_FILTER_ERROR, "can't find object for ID")
-
- /* Get pipeline info */
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline")
-
- /* Check more args */
- if(idx >= pline.nused)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "filter number is invalid")
-
- /* Set pointer to particular filter to query */
- filter = &pline.filter[idx];
-
- /* Get filter information */
- if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, NULL) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info")
-
- /* Set return value */
- ret_value = filter->id;
-
-done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Pget_filter1() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5Pget_filter_by_id1
- *
- * Purpose: This is an additional query counterpart of H5Pset_filter() and
- * returns information about a particular filter in a permanent
- * or transient pipeline depending on whether PLIST_ID is a
- * dataset creation or transfer property list. On input,
- * CD_NELMTS indicates the number of entries in the CD_VALUES
- * array allocated by the caller while on exit it contains the
- * number of values defined by the filter. The ID
- * should be the filter ID to retrieve the parameters for. If the
- * filter is not set for the property list, an error will be returned.
- *
- * Return: Success: Non-negative
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * Friday, April 5, 2003
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5Pget_filter_by_id1(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/,
- size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/,
- size_t namelen, char name[]/*out*/)
-{
- H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_API(H5Pget_filter_by_id1, FAIL)
- H5TRACE7("e", "iZfx*zxzx", plist_id, id, flags, cd_nelmts, cd_values, namelen,
- name);
-
- /* Check args */
- if(cd_nelmts || cd_values) {
- /*
- * It's likely that users forget to initialize this on input, so
- * we'll check that it has a reasonable value. The actual number
- * is unimportant because the H5O layer will detect when a message
- * is too large.
- */
- if(cd_nelmts && *cd_nelmts > 256)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "probable uninitialized *cd_nelmts argument")
- if(cd_nelmts && *cd_nelmts > 0 && !cd_values)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "client data values not supplied")
-
- /*
- * If cd_nelmts is null but cd_values is non-null then just ignore
- * cd_values
- */
- if(!cd_nelmts)
- cd_values = NULL;
- } /* end if */
-
- /* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
-
- /* Get filter info */
- if(H5P_get_filter_by_id(plist, id, flags, cd_nelmts, cd_values, namelen, name, NULL) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info")
-
-done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Pget_filter_by_id1() */
-
-#endif /* H5_NO_DEPRECATED_SYMBOLS */
-
diff --git a/src/H5Pdeprec.c b/src/H5Pdeprec.c
index 1234735..5c72247 100644
--- a/src/H5Pdeprec.c
+++ b/src/H5Pdeprec.c
@@ -257,7 +257,7 @@ H5Pregister1(hid_t cls_id, const char *name, size_t size, void *def_value,
prp_set, prp_get, prp_delete, prp_copy, prp_close);
/* Check arguments. */
- if(NULL == (pclass = H5I_object_verify(cls_id, H5I_GENPROP_CLS)))
+ if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(cls_id, H5I_GENPROP_CLS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name");
@@ -426,7 +426,7 @@ H5Pinsert1(hid_t plist_id, const char *name, size_t size, void *value,
prp_delete, prp_copy, prp_close);
/* Check arguments. */
- if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name")
@@ -440,5 +440,59 @@ H5Pinsert1(hid_t plist_id, const char *name, size_t size, void *value,
done:
FUNC_LEAVE_API(ret_value);
} /* H5Pinsert1() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_version
+ *
+ * Purpose: Retrieves version information for various parts of a file.
+ *
+ * SUPER: The file super block.
+ * FREELIST: The global free list.
+ * STAB: The root symbol table entry.
+ * SHHDR: Shared object headers.
+ *
+ * Any (or even all) of the output arguments can be null
+ * pointers.
+ *
+ * Return: Success: Non-negative, version information is returned
+ * through the arguments.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, January 7, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_version(hid_t plist_id, unsigned *super/*out*/, unsigned *freelist/*out*/,
+ unsigned *stab/*out*/, unsigned *shhdr/*out*/)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Pget_version, FAIL)
+ H5TRACE5("e", "ixxxx", plist_id, super, freelist, stab, shhdr);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id,H5P_FILE_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get values */
+ if(super)
+ if(H5P_get(plist, H5F_CRT_SUPER_VERS_NAME, super) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get superblock version")
+ if(freelist)
+ *freelist = HDF5_FREESPACE_VERSION; /* (hard-wired) */
+ if(stab)
+ *stab = HDF5_OBJECTDIR_VERSION; /* (hard-wired) */
+ if(shhdr)
+ *shhdr = HDF5_SHAREDHEADER_VERSION; /* (hard-wired) */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_version() */
+
#endif /* H5_NO_DEPRECATED_SYMBOLS */
diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c
index 8bc263a..aab8b57 100644
--- a/src/H5Pdxpl.c
+++ b/src/H5Pdxpl.c
@@ -323,7 +323,7 @@ H5P_dxfr_create(hid_t dxpl_id, void UNUSED *create_data)
FUNC_ENTER_NOAPI_NOINIT(H5P_dxfr_create)
/* Check arguments */
- if(NULL == (plist = H5I_object(dxpl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list")
/* Get the driver information */
@@ -372,9 +372,9 @@ H5P_dxfr_copy(hid_t dst_dxpl_id, hid_t src_dxpl_id, void UNUSED *copy_data)
FUNC_ENTER_NOAPI_NOINIT(H5P_dxfr_copy)
- if(NULL == (dst_plist = H5I_object(dst_dxpl_id)))
+ if(NULL == (dst_plist = (H5P_genplist_t *)H5I_object(dst_dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
- if(NULL == (src_plist = H5I_object(src_dxpl_id)))
+ if(NULL == (src_plist = (H5P_genplist_t *)H5I_object(src_dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
/* Get values from old property list */
@@ -424,7 +424,7 @@ H5P_dxfr_close(hid_t dxpl_id, void UNUSED *close_data)
FUNC_ENTER_NOAPI_NOINIT(H5P_dxfr_close)
/* Check arguments */
- if(NULL == (plist = H5I_object(dxpl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list")
if(H5P_get(plist, H5D_XFER_VFL_ID_NAME, &driver_id) < 0)
@@ -572,7 +572,7 @@ H5Pset_data_transform(hid_t plist_id, const char *expression)
/* See if a data transform is already set, and free it if it is */
if(H5P_get(plist, H5D_XFER_XFORM_NAME, &data_xform_prop) >= 0)
H5Z_xform_destroy(data_xform_prop);
-
+
/* Create data transform info from expression */
if(NULL == (data_xform_prop = H5Z_xform_create(expression)))
HGOTO_ERROR(H5E_PLINE, H5E_NOSPACE, FAIL, "unable to create data transform info")
@@ -839,7 +839,7 @@ H5Pget_preserve(hid_t plist_id)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Get value */
- if (H5P_get(plist,H5D_XFER_BKGR_BUF_NAME,&need_bkg)<0)
+ if (H5P_get(plist,H5D_XFER_BKGR_BUF_TYPE_NAME,&need_bkg)<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value")
/* Set return value */
diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c
index a988658..5d73afe 100644
--- a/src/H5Pfapl.c
+++ b/src/H5Pfapl.c
@@ -57,9 +57,9 @@
/* Definitions for the initial metadata cache resize configuration */
#define H5F_ACS_META_CACHE_INIT_CONFIG_SIZE sizeof(H5AC_cache_config_t)
#define H5F_ACS_META_CACHE_INIT_CONFIG_DEF H5AC__DEFAULT_CACHE_CONFIG
-/* Definitions for size of raw data chunk cache(elements) */
-#define H5F_ACS_DATA_CACHE_ELMT_SIZE_SIZE sizeof(size_t)
-#define H5F_ACS_DATA_CACHE_ELMT_SIZE_DEF 521
+/* Definitions for size of raw data chunk cache(slots) */
+#define H5F_ACS_DATA_CACHE_NUM_SLOTS_SIZE sizeof(size_t)
+#define H5F_ACS_DATA_CACHE_NUM_SLOTS_DEF 521
/* Definition for size of raw data chunk cache(bytes) */
#define H5F_ACS_DATA_CACHE_BYTE_SIZE_SIZE sizeof(size_t)
#define H5F_ACS_DATA_CACHE_BYTE_SIZE_DEF (1024*1024)
@@ -101,18 +101,23 @@
#define H5F_ACS_FAMILY_OFFSET_DEF 0
/* Definition for new member size of family driver. It's private
* property only used by h5repart */
-#define H5F_ACS_FAMILY_NEWSIZE_SIZE sizeof(hsize_t)
-#define H5F_ACS_FAMILY_NEWSIZE_DEF 0
+#define H5F_ACS_FAMILY_NEWSIZE_SIZE sizeof(hsize_t)
+#define H5F_ACS_FAMILY_NEWSIZE_DEF 0
/* Definition for whether to convert family to sec2 driver. It's private
* property only used by h5repart */
-#define H5F_ACS_FAMILY_TO_SEC2_SIZE sizeof(hbool_t)
-#define H5F_ACS_FAMILY_TO_SEC2_DEF FALSE
+#define H5F_ACS_FAMILY_TO_SEC2_SIZE sizeof(hbool_t)
+#define H5F_ACS_FAMILY_TO_SEC2_DEF FALSE
/* Definition for data type in multi file driver */
#define H5F_ACS_MULTI_TYPE_SIZE sizeof(H5FD_mem_t)
#define H5F_ACS_MULTI_TYPE_DEF H5FD_MEM_DEFAULT
/* Definition for 'use latest format version' flag */
#define H5F_ACS_LATEST_FORMAT_SIZE sizeof(hbool_t)
#define H5F_ACS_LATEST_FORMAT_DEF FALSE
+/* Definition for whether to query the file descriptor from the core VFD
+ * instead of the memory address. (Private to library)
+ */
+#define H5F_ACS_WANT_POSIX_FD_SIZE sizeof(hbool_t)
+#define H5F_ACS_WANT_POSIX_FD_DEF FALSE
/******************/
@@ -187,7 +192,7 @@ static herr_t
H5P_facc_reg_prop(H5P_genclass_t *pclass)
{
H5AC_cache_config_t mdc_initCacheCfg = H5F_ACS_META_CACHE_INIT_CONFIG_DEF; /* Default metadata cache settings */
- size_t rdcc_nelmts = H5F_ACS_DATA_CACHE_ELMT_SIZE_DEF; /* Default raw data chunk cache # of elements */
+ size_t rdcc_nslots = H5F_ACS_DATA_CACHE_NUM_SLOTS_DEF; /* Default raw data chunk cache # of slots */
size_t rdcc_nbytes = H5F_ACS_DATA_CACHE_BYTE_SIZE_DEF; /* Default raw data chunk cache # of bytes */
double rdcc_w0 = H5F_ACS_PREEMPT_READ_CHUNKS_DEF; /* Default raw data chunk cache dirty ratio */
hsize_t threshold = H5F_ACS_ALIGN_THRHD_DEF; /* Default allocation alignment threshold */
@@ -204,6 +209,7 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass)
hbool_t family_to_sec2 = H5F_ACS_FAMILY_TO_SEC2_DEF; /* Default ?? for family VFD */
H5FD_mem_t mem_type = H5F_ACS_MULTI_TYPE_DEF; /* Default file space type for multi VFD */
hbool_t latest_format = H5F_ACS_LATEST_FORMAT_DEF; /* Default setting for "use the latest version of the format" flag */
+ hbool_t want_posix_fd = H5F_ACS_WANT_POSIX_FD_DEF; /* Default setting for retrieving 'handle' from core VFD */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5P_facc_reg_prop)
@@ -213,7 +219,7 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
/* Register the size of raw data chunk cache (elements) */
- if(H5P_register(pclass, H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME, H5F_ACS_DATA_CACHE_ELMT_SIZE_SIZE, &rdcc_nelmts, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ if(H5P_register(pclass, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, H5F_ACS_DATA_CACHE_NUM_SLOTS_SIZE, &rdcc_nslots, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
/* Register the size of raw data chunk cache(bytes) */
@@ -280,6 +286,11 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass)
if(H5P_register(pclass, H5F_ACS_LATEST_FORMAT_NAME, H5F_ACS_LATEST_FORMAT_SIZE, &latest_format, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ /* Register the private property of whether to retrieve the file descriptor from the core VFD */
+ /* (used internally to the library only) */
+ if(H5P_register(pclass, H5F_ACS_WANT_POSIX_FD_NAME, H5F_ACS_WANT_POSIX_FD_SIZE, &want_posix_fd, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P_facc_reg_prop() */
@@ -312,7 +323,7 @@ H5P_facc_create(hid_t fapl_id, void UNUSED *copy_data)
FUNC_ENTER_NOAPI_NOINIT(H5P_facc_create)
/* Check argument */
- if(NULL == (plist = H5I_object(fapl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
/* Retrieve driver ID property */
@@ -362,7 +373,7 @@ H5P_facc_copy(hid_t dst_fapl_id, hid_t src_fapl_id, void UNUSED *copy_data)
FUNC_ENTER_NOAPI_NOINIT(H5P_facc_copy)
/* Get driver ID from source property list */
- if(NULL == (src_plist = H5I_object(src_fapl_id)))
+ if(NULL == (src_plist = (H5P_genplist_t *)H5I_object(src_fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
if(H5P_get(src_plist, H5F_ACS_FILE_DRV_ID_NAME, &driver_id) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get driver ID")
@@ -376,7 +387,7 @@ H5P_facc_copy(hid_t dst_fapl_id, hid_t src_fapl_id, void UNUSED *copy_data)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get driver info")
/* Set the driver for the destination property list */
- if(NULL == (dst_plist = H5I_object(dst_fapl_id)))
+ if(NULL == (dst_plist = (H5P_genplist_t *)H5I_object(dst_fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
if(H5FD_fapl_open(dst_plist, driver_id, driver_info) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver")
@@ -413,7 +424,7 @@ H5P_facc_close(hid_t fapl_id, void UNUSED *close_data)
FUNC_ENTER_NOAPI(H5P_facc_close, FAIL)
/* Check argument */
- if(NULL == (plist = H5I_object(fapl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
/* Get driver ID property */
@@ -577,17 +588,17 @@ H5P_set_driver(H5P_genplist_t *plist, hid_t new_driver_id, const void *new_drive
void *driver_info; /* VFL driver info */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5P_set_driver, FAIL);
+ FUNC_ENTER_NOAPI(H5P_set_driver, FAIL)
- if (NULL==H5I_object_verify(new_driver_id, H5I_VFL))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file driver ID");
+ if(NULL == H5I_object_verify(new_driver_id, H5I_VFL))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file driver ID")
- if( TRUE == H5P_isa_class(plist->plist_id, H5P_FILE_ACCESS) ) {
+ if(TRUE == H5P_isa_class(plist->plist_id, H5P_FILE_ACCESS)) {
/* Get the current driver information */
if(H5P_get(plist, H5F_ACS_FILE_DRV_ID_NAME, &driver_id) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get driver ID");
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get driver ID")
if(H5P_get(plist, H5F_ACS_FILE_DRV_INFO_NAME, &driver_info) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL,"can't get driver info");
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL,"can't get driver info")
/* Close the driver for the property list */
if(H5FD_fapl_close(driver_id, driver_info)<0)
@@ -596,26 +607,26 @@ H5P_set_driver(H5P_genplist_t *plist, hid_t new_driver_id, const void *new_drive
/* Set the driver for the property list */
if(H5FD_fapl_open(plist, new_driver_id, new_driver_info)<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver")
- } else if( TRUE == H5P_isa_class(plist->plist_id, H5P_DATASET_XFER) ) {
+ } else if(TRUE == H5P_isa_class(plist->plist_id, H5P_DATASET_XFER)) {
/* Get the current driver information */
- if(H5P_get(plist, H5D_XFER_VFL_ID_NAME, &driver_id)<0)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve VFL driver ID");
- if(H5P_get(plist, H5D_XFER_VFL_INFO_NAME, &driver_info)<0)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve VFL driver info");
+ if(H5P_get(plist, H5D_XFER_VFL_ID_NAME, &driver_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve VFL driver ID")
+ if(H5P_get(plist, H5D_XFER_VFL_INFO_NAME, &driver_info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve VFL driver info")
/* Close the driver for the property list */
- if(H5FD_dxpl_close(driver_id, driver_info)<0)
+ if(H5FD_dxpl_close(driver_id, driver_info) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't reset driver")
/* Set the driver for the property list */
- if(H5FD_dxpl_open(plist, new_driver_id, new_driver_info)<0)
+ if(H5FD_dxpl_open(plist, new_driver_id, new_driver_info) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver")
} else {
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access or data transfer property list");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access or data transfer property list")
}
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P_set_driver() */
@@ -650,23 +661,23 @@ herr_t
H5Pset_driver(hid_t plist_id, hid_t new_driver_id, const void *new_driver_info)
{
H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API(H5Pset_driver, FAIL);
+ FUNC_ENTER_API(H5Pset_driver, FAIL)
H5TRACE3("e", "ii*x", plist_id, new_driver_id, new_driver_info);
/* Check arguments */
- if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
- if (NULL==H5I_object_verify(new_driver_id, H5I_VFL))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file driver ID");
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
+ if(NULL == H5I_object_verify(new_driver_id, H5I_VFL))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file driver ID")
/* Set the driver */
- if(H5P_set_driver(plist,new_driver_id,new_driver_info)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver info");
+ if(H5P_set_driver(plist, new_driver_id, new_driver_info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver info")
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* end H5Pset_driver() */
@@ -763,17 +774,17 @@ H5Pget_driver(hid_t plist_id)
H5P_genplist_t *plist; /* Property list pointer */
hid_t ret_value; /* Return value */
- FUNC_ENTER_API(H5Pget_driver, FAIL);
+ FUNC_ENTER_API(H5Pget_driver, FAIL)
H5TRACE1("i", "i", plist_id);
- if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
ret_value = H5P_get_driver(plist);
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_driver() */
/*-------------------------------------------------------------------------
@@ -859,14 +870,14 @@ H5Pget_driver_info(hid_t plist_id)
FUNC_ENTER_API(H5Pget_driver_info, NULL);
- if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list");
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list")
- if((ret_value=H5P_get_driver_info(plist))==NULL)
- HGOTO_ERROR(H5E_PLIST,H5E_CANTGET,NULL,"can't get driver info");
+ if(NULL == (ret_value = H5P_get_driver_info(plist)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver info")
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* end H5Pget_driver_info() */
@@ -1213,13 +1224,13 @@ done:
*/
herr_t
H5Pset_cache(hid_t plist_id, int UNUSED mdc_nelmts,
- size_t rdcc_nelmts, size_t rdcc_nbytes, double rdcc_w0)
+ size_t rdcc_nslots, size_t rdcc_nbytes, double rdcc_w0)
{
H5P_genplist_t *plist; /* Property list pointer */
herr_t ret_value=SUCCEED; /* return value */
FUNC_ENTER_API(H5Pset_cache, FAIL);
- H5TRACE5("e", "iIszzd", plist_id, mdc_nelmts, rdcc_nelmts, rdcc_nbytes,
+ H5TRACE5("e", "iIszzd", plist_id, mdc_nelmts, rdcc_nslots, rdcc_nbytes,
rdcc_w0);
/* Check arguments */
@@ -1231,8 +1242,8 @@ H5Pset_cache(hid_t plist_id, int UNUSED mdc_nelmts,
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
/* Set sizes */
- if(H5P_set(plist, H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME, &rdcc_nelmts) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET,FAIL, "can't set data cache element size");
+ if(H5P_set(plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, &rdcc_nslots) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET,FAIL, "can't set data cache number of slots");
if(H5P_set(plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &rdcc_nbytes) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET,FAIL, "can't set data cache byte size");
if(H5P_set(plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, &rdcc_w0) < 0)
@@ -1273,13 +1284,13 @@ done:
*/
herr_t
H5Pget_cache(hid_t plist_id, int *mdc_nelmts,
- size_t *rdcc_nelmts, size_t *rdcc_nbytes, double *rdcc_w0)
+ size_t *rdcc_nslots, size_t *rdcc_nbytes, double *rdcc_w0)
{
H5P_genplist_t *plist; /* Property list pointer */
herr_t ret_value=SUCCEED; /* return value */
FUNC_ENTER_API(H5Pget_cache, FAIL);
- H5TRACE5("e", "i*Is*z*z*d", plist_id, mdc_nelmts, rdcc_nelmts, rdcc_nbytes,
+ H5TRACE5("e", "i*Is*z*z*d", plist_id, mdc_nelmts, rdcc_nslots, rdcc_nbytes,
rdcc_w0);
/* Get the plist structure */
@@ -1292,9 +1303,9 @@ H5Pget_cache(hid_t plist_id, int *mdc_nelmts,
if (mdc_nelmts)
*mdc_nelmts = 0;
- if (rdcc_nelmts)
- if(H5P_get(plist, H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME, rdcc_nelmts) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get data cache element size");
+ if (rdcc_nslots)
+ if(H5P_get(plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, rdcc_nslots) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get data cache number of slots");
if (rdcc_nbytes)
if(H5P_get(plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, rdcc_nbytes) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get data cache byte size");
@@ -1960,7 +1971,7 @@ H5Pset_libver_bounds(hid_t plist_id, H5F_libver_t low,
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Set values */
- latest = (low == H5F_LIBVER_LATEST) ? TRUE : FALSE;
+ latest = (hbool_t)((low == H5F_LIBVER_LATEST) ? TRUE : FALSE);
if(H5P_set(plist, H5F_ACS_LATEST_FORMAT_NAME, &latest) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set library version bounds")
diff --git a/src/H5Pfcpl.c b/src/H5Pfcpl.c
index 8fd4909..cb3bccd 100644
--- a/src/H5Pfcpl.c
+++ b/src/H5Pfcpl.c
@@ -53,12 +53,12 @@
#define H5F_CRT_SYM_LEAF_SIZE sizeof(unsigned)
/* Definitions for the 1/2 rank for btree internal nodes */
#define H5F_CRT_BTREE_RANK_SIZE sizeof(unsigned[H5B_NUM_BTREE_ID])
-#define H5F_CRT_BTREE_RANK_DEF {HDF5_BTREE_SNODE_IK_DEF,HDF5_BTREE_ISTORE_IK_DEF}
+#define H5F_CRT_BTREE_RANK_DEF {HDF5_BTREE_SNODE_IK_DEF,HDF5_BTREE_CHUNK_IK_DEF}
/* Definitions for byte number in an address */
-#define H5F_CRT_ADDR_BYTE_NUM_SIZE sizeof(size_t)
+#define H5F_CRT_ADDR_BYTE_NUM_SIZE sizeof(uint8_t)
#define H5F_CRT_ADDR_BYTE_NUM_DEF H5F_OBJ_ADDR_SIZE
/* Definitions for byte number for object size */
-#define H5F_CRT_OBJ_BYTE_NUM_SIZE sizeof(size_t)
+#define H5F_CRT_OBJ_BYTE_NUM_SIZE sizeof(uint8_t)
#define H5F_CRT_OBJ_BYTE_NUM_DEF H5F_OBJ_SIZE_SIZE
/* Definitions for version number of the superblock */
#define H5F_CRT_SUPER_VERS_SIZE sizeof(unsigned)
@@ -75,6 +75,11 @@
#define H5F_CRT_SHMSG_LIST_MAX_DEF (50)
#define H5F_CRT_SHMSG_BTREE_MIN_SIZE sizeof(unsigned)
#define H5F_CRT_SHMSG_BTREE_MIN_DEF (40)
+/* Definitions for file space handling strategy */
+#define H5F_CRT_FILE_SPACE_STRATEGY_SIZE sizeof(unsigned)
+#define H5F_CRT_FILE_SPACE_STRATEGY_DEF H5F_FILE_SPACE_STRATEGY_DEF
+#define H5F_CRT_FREE_SPACE_THRESHOLD_SIZE sizeof(hsize_t)
+#define H5F_CRT_FREE_SPACE_THRESHOLD_DEF H5F_FREE_SPACE_THRESHOLD_DEF
/******************/
@@ -100,7 +105,7 @@ static herr_t H5P_fcrt_reg_prop(H5P_genclass_t *pclass);
/* File creation property list class library initialization object */
const H5P_libclass_t H5P_CLS_FCRT[1] = {{
- "file create", /* Class name for debugging */
+ "file create", /* Class name for debugging */
&H5P_CLS_GROUP_CREATE_g, /* Parent class ID */
&H5P_CLS_FILE_CREATE_g, /* Pointer to class ID */
&H5P_LST_FILE_CREATE_g, /* Pointer to default property list ID */
@@ -142,14 +147,16 @@ H5P_fcrt_reg_prop(H5P_genclass_t *pclass)
hsize_t userblock_size = H5F_CRT_USER_BLOCK_DEF; /* Default userblock size */
unsigned sym_leaf_k = H5F_CRT_SYM_LEAF_DEF; /* Default size for symbol table leaf nodes */
unsigned btree_k[H5B_NUM_BTREE_ID] = H5F_CRT_BTREE_RANK_DEF; /* Default 'K' values for B-trees in file */
- size_t sizeof_addr = H5F_CRT_ADDR_BYTE_NUM_DEF; /* Default size of addresses in the file */
- size_t sizeof_size = H5F_CRT_OBJ_BYTE_NUM_DEF; /* Default size of sizes in the file */
+ uint8_t sizeof_addr = H5F_CRT_ADDR_BYTE_NUM_DEF; /* Default size of addresses in the file */
+ uint8_t sizeof_size = H5F_CRT_OBJ_BYTE_NUM_DEF; /* Default size of sizes in the file */
unsigned superblock_ver = H5F_CRT_SUPER_VERS_DEF; /* Default superblock version # */
unsigned num_sohm_indexes = H5F_CRT_SHMSG_NINDEXES_DEF;
unsigned sohm_index_flags[H5O_SHMESG_MAX_NINDEXES] = H5F_CRT_SHMSG_INDEX_TYPES_DEF;
unsigned sohm_index_minsizes[H5O_SHMESG_MAX_NINDEXES] = H5F_CRT_SHMSG_INDEX_MINSIZE_DEF;
unsigned sohm_list_max = H5F_CRT_SHMSG_LIST_MAX_DEF;
unsigned sohm_btree_min = H5F_CRT_SHMSG_BTREE_MIN_DEF;
+ unsigned file_space_strategy = H5F_CRT_FILE_SPACE_STRATEGY_DEF;
+ hsize_t free_space_threshold = H5F_CRT_FREE_SPACE_THRESHOLD_DEF;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5P_fcrt_reg_prop)
@@ -192,65 +199,19 @@ H5P_fcrt_reg_prop(H5P_genclass_t *pclass)
if(H5P_register(pclass,H5F_CRT_SHMSG_BTREE_MIN_NAME, H5F_CRT_SHMSG_BTREE_MIN_SIZE, &sohm_btree_min,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ /* Register the file space handling strategy */
+ if(H5P_register(pclass, H5F_CRT_FILE_SPACE_STRATEGY_NAME, H5F_CRT_FILE_SPACE_STRATEGY_SIZE, &file_space_strategy, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+ /* Register the free space section threshold */
+ if(H5P_register(pclass, H5F_CRT_FREE_SPACE_THRESHOLD_NAME, H5F_CRT_FREE_SPACE_THRESHOLD_SIZE, &free_space_threshold, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P_fcrt_reg_prop() */
/*-------------------------------------------------------------------------
- * Function: H5Pget_version
- *
- * Purpose: Retrieves version information for various parts of a file.
- *
- * SUPER: The file super block.
- * FREELIST: The global free list.
- * STAB: The root symbol table entry.
- * SHHDR: Shared object headers.
- *
- * Any (or even all) of the output arguments can be null
- * pointers.
- *
- * Return: Success: Non-negative, version information is returned
- * through the arguments.
- *
- * Failure: Negative
- *
- * Programmer: Robb Matzke
- * Wednesday, January 7, 1998
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5Pget_version(hid_t plist_id, unsigned *super/*out*/, unsigned *freelist/*out*/,
- unsigned *stab/*out*/, unsigned *shhdr/*out*/)
-{
- H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_API(H5Pget_version, FAIL)
- H5TRACE5("e", "ixxxx", plist_id, super, freelist, stab, shhdr);
-
- /* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id,H5P_FILE_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
-
- /* Get values */
- if(super)
- if(H5P_get(plist, H5F_CRT_SUPER_VERS_NAME, super) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get superblock version")
- if(freelist)
- *freelist = HDF5_FREESPACE_VERSION; /* (hard-wired) */
- if(stab)
- *stab = HDF5_OBJECTDIR_VERSION; /* (hard-wired) */
- if(shhdr)
- *shhdr = HDF5_SHAREDHEADER_VERSION; /* (hard-wired) */
-
-done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Pget_version() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5Pset_userblock
*
* Purpose: Sets the userblock size field of a file creation property
@@ -261,44 +222,39 @@ done:
* Programmer: Robb Matzke
* Tuesday, January 6, 1998
*
- * Modifications:
- *
- * Raymond Lu, Oct 14, 2001
- * Changed to the new generic property list.
- *
*-------------------------------------------------------------------------
*/
herr_t
H5Pset_userblock(hid_t plist_id, hsize_t size)
{
- unsigned i;
H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value=SUCCEED; /* return value */
+ herr_t ret_value = SUCCEED; /* return value */
- FUNC_ENTER_API(H5Pset_userblock, FAIL);
+ FUNC_ENTER_API(H5Pset_userblock, FAIL)
H5TRACE2("e", "ih", plist_id, size);
- /* Check that the userblock size is a power of two */
- for (i=8; i<8*sizeof(hsize_t); i++) {
- hsize_t p2 = 8==i ? 0 : ((hsize_t)1<<i);
+ /* Sanity check non-zero userblock sizes */
+ if(size > 0) {
+ /* Check that the userblock size is >=512 */
+ if(size < 512)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "userblock size is non-zero and less than 512")
- if (size == p2)
- break;
- }
- if (i>=8*sizeof(hsize_t))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "userblock size is not valid");
+ /* Check that the userblock size is a power of two */
+ if(!POWER_OF_TWO(size))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "userblock size is non-zero and not a power of two")
+ } /* end if */
/* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id,H5P_FILE_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_FILE_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Set value */
if(H5P_set(plist, H5F_CRT_USER_BLOCK_NAME, &size) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set user block");
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set user block")
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_userblock() */
/*-------------------------------------------------------------------------
@@ -356,46 +312,48 @@ done:
* Programmer: Robb Matzke
* Tuesday, January 6, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5Pset_sizes(hid_t plist_id, size_t sizeof_addr, size_t sizeof_size)
{
H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value=SUCCEED; /* return value */
+ herr_t ret_value = SUCCEED; /* return value */
- FUNC_ENTER_API(H5Pset_sizes, FAIL);
+ FUNC_ENTER_API(H5Pset_sizes, FAIL)
H5TRACE3("e", "izz", plist_id, sizeof_addr, sizeof_size);
/* Check arguments */
- if (sizeof_addr) {
- if (sizeof_addr != 2 && sizeof_addr != 4 &&
- sizeof_addr != 8 && sizeof_addr != 16)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file haddr_t size is not valid");
- }
- if (sizeof_size) {
- if (sizeof_size != 2 && sizeof_size != 4 &&
- sizeof_size != 8 && sizeof_size != 16)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file size_t size is not valid");
- }
+ if(sizeof_addr) {
+ if(sizeof_addr != 2 && sizeof_addr != 4 && sizeof_addr != 8 && sizeof_addr != 16)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file haddr_t size is not valid")
+ } /* end if */
+ if(sizeof_size) {
+ if(sizeof_size != 2 && sizeof_size != 4 && sizeof_size != 8 && sizeof_size != 16)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file size_t size is not valid")
+ } /* end if */
/* Get the plist structure */
if(NULL == (plist = H5P_object_verify(plist_id,H5P_FILE_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Set value */
- if (sizeof_addr)
- if(H5P_set(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &sizeof_addr) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set byte number for an address");
- if (sizeof_size)
- if(H5P_set(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set byte number for object ");
+ if(sizeof_addr) {
+ uint8_t tmp_sizeof_addr = (uint8_t)sizeof_addr;
+
+ if(H5P_set(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &tmp_sizeof_addr) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set byte number for an address")
+ } /* end if */
+ if(sizeof_size) {
+ uint8_t tmp_sizeof_size = (uint8_t)sizeof_size;
+
+ if(H5P_set(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &tmp_sizeof_size) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set byte number for object ")
+ } /* end if */
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_sizes() */
/*-------------------------------------------------------------------------
@@ -406,41 +364,45 @@ done:
* even both) SIZEOF_ADDR and SIZEOF_SIZE may be null pointers.
*
* Return: Success: Non-negative, sizes returned through arguments.
- *
* Failure: Negative
*
* Programmer: Robb Matzke
* Wednesday, January 7, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5Pget_sizes(hid_t plist_id,
- size_t *sizeof_addr /*out */ , size_t *sizeof_size /*out */ )
+H5Pget_sizes(hid_t plist_id, size_t *sizeof_addr, size_t *sizeof_size)
{
H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value=SUCCEED; /* return value */
+ herr_t ret_value = SUCCEED; /* return value */
- FUNC_ENTER_API(H5Pget_sizes, FAIL);
- H5TRACE3("e", "ixx", plist_id, sizeof_addr, sizeof_size);
+ FUNC_ENTER_API(H5Pget_sizes, FAIL)
+ H5TRACE3("e", "i*z*z", plist_id, sizeof_addr, sizeof_size);
/* Get the plist structure */
if(NULL == (plist = H5P_object_verify(plist_id,H5P_FILE_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Get values */
- if (sizeof_addr)
- if(H5P_get(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, sizeof_addr) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get byte number for an address");
- if (sizeof_size)
- if(H5P_get(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, sizeof_size) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get byte number for object ");
+ if(sizeof_addr) {
+ uint8_t tmp_sizeof_addr;
+
+ if(H5P_get(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &tmp_sizeof_addr) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get byte number for an address")
+ *sizeof_addr = tmp_sizeof_addr;
+ } /* end if */
+ if(sizeof_size) {
+ uint8_t tmp_sizeof_size;
+
+ if(H5P_get(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &tmp_sizeof_size) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get byte number for object ")
+ *sizeof_size = tmp_sizeof_size;
+ } /* end if */
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_sizes() */
/*-------------------------------------------------------------------------
@@ -593,7 +555,7 @@ H5Pset_istore_k(hid_t plist_id, unsigned ik)
/* Set value */
if(H5P_get(plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get rank for btree interanl nodes");
- btree_k[H5B_ISTORE_ID] = ik;
+ btree_k[H5B_CHUNK_ID] = ik;
if(H5P_set(plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set rank for btree interanl nodes");
@@ -641,7 +603,7 @@ H5Pget_istore_k(hid_t plist_id, unsigned *ik /*out */ )
if(ik) {
if(H5P_get(plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get rank for btree interanl nodes");
- *ik = btree_k[H5B_ISTORE_ID];
+ *ik = btree_k[H5B_CHUNK_ID];
} /* end if */
done:
@@ -758,15 +720,15 @@ H5Pset_shared_mesg_index(hid_t plist_id, unsigned index_num, unsigned mesg_type_
/* Check arguments */
if(mesg_type_flags > H5O_SHMESG_ALL_FLAG)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "unrecognized flags in mesg_type_flags");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "unrecognized flags in mesg_type_flags")
/* Get the plist structure */
if(NULL == (plist = H5P_object_verify(plist_id,H5P_FILE_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Read the current number of indexes */
if(H5P_get(plist, H5F_CRT_SHMSG_NINDEXES_NAME, &nindexes) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get number of indexes");
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get number of indexes")
/* Range check */
if(index_num >= nindexes)
@@ -784,9 +746,9 @@ H5Pset_shared_mesg_index(hid_t plist_id, unsigned index_num, unsigned mesg_type_
/* Write arrays back to plist */
if(H5P_set(plist, H5F_CRT_SHMSG_INDEX_TYPES_NAME, type_flags) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set index type flags");
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set index type flags")
if(H5P_set(plist, H5F_CRT_SHMSG_INDEX_MINSIZE_NAME, minsizes) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set min mesg sizes");
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set min mesg sizes")
done:
FUNC_LEAVE_API(ret_value)
@@ -845,7 +807,7 @@ H5Pget_shared_mesg_index(hid_t plist_id, unsigned index_num, unsigned *mesg_type
done:
FUNC_LEAVE_API(ret_value);
-}
+} /* end H5Pset_shared_mesg_index() */
/*-------------------------------------------------------------------------
@@ -878,7 +840,7 @@ H5Pset_shared_mesg_phase_change(hid_t plist_id, unsigned max_list, unsigned min_
/* Check that values are sensible. The min_btree value must be no greater
* than the max list plus one.
- *
+ *
* Range check to make certain they will fit into encoded form.
*/
if(max_list + 1 < min_btree)
@@ -905,7 +867,7 @@ H5Pset_shared_mesg_phase_change(hid_t plist_id, unsigned max_list, unsigned min_
done:
FUNC_LEAVE_API(ret_value);
-}
+} /* end H5Pset_shared_mesg_phase_change() */
/*-------------------------------------------------------------------------
@@ -946,5 +908,90 @@ H5Pget_shared_mesg_phase_change(hid_t plist_id, unsigned *max_list, unsigned *mi
done:
FUNC_LEAVE_API(ret_value);
-}
+} /* end H5Pget_shared_mesg_phase_change() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_file_space
+ *
+ * Purpose: Sets the strategy that the library employs in managing file space.
+ * If strategy is zero, the property is not changed; the existing
+ * strategy is retained.
+ * Sets the threshold value that the file's free space
+ * manager(s) will use to track free space sections.
+ * If threshold is zero, the property is not changed; the existing
+ * threshold is retained.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; June 10, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_file_space(hid_t plist_id, H5F_file_space_type_t strategy, hsize_t threshold)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Pset_file_space, FAIL)
+ H5TRACE3("e", "iFfh", plist_id, strategy, threshold);
+
+ if((unsigned)strategy >= H5F_FILE_SPACE_NTYPES)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid strategy")
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id,H5P_FILE_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Set value(s), if non-zero */
+ if(strategy)
+ if(H5P_set(plist, H5F_CRT_FILE_SPACE_STRATEGY_NAME, &strategy) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set file space strategy")
+ if(threshold)
+ if(H5P_set(plist, H5F_CRT_FREE_SPACE_THRESHOLD_NAME, &threshold) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set free-space threshold")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Pset_file_space() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_file_space
+ *
+ * Purpose: Retrieves the strategy that the library uses in managing file space.
+ * Retrieves the threshold value that the file's free space
+ * managers use to track free space sections.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; June 10, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_file_space(hid_t plist_id, H5F_file_space_type_t *strategy, hsize_t *threshold)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Pget_file_space, FAIL)
+ H5TRACE3("e", "i*Ff*h", plist_id, strategy, threshold);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id,H5P_FILE_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get value(s) */
+ if(strategy)
+ if(H5P_get(plist, H5F_CRT_FILE_SPACE_STRATEGY_NAME, strategy) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file space strategy")
+ if(threshold)
+ if(H5P_get(plist, H5F_CRT_FREE_SPACE_THRESHOLD_NAME, threshold) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get free-space threshold")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Pget_file_space() */
diff --git a/src/H5Pgcpl.c b/src/H5Pgcpl.c
index a4aff51..913c5f1 100644
--- a/src/H5Pgcpl.c
+++ b/src/H5Pgcpl.c
@@ -257,8 +257,8 @@ H5Pset_link_phase_change(hid_t plist_id, unsigned max_compact, unsigned min_dens
ginfo.store_link_phase_change = TRUE;
else
ginfo.store_link_phase_change = FALSE;
- ginfo.max_compact = max_compact;
- ginfo.min_dense = min_dense;
+ ginfo.max_compact = (uint16_t)max_compact;
+ ginfo.min_dense = (uint16_t)min_dense;
/* Set group info */
if(H5P_set(plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
@@ -361,8 +361,8 @@ H5Pset_est_link_info(hid_t plist_id, unsigned est_num_entries, unsigned est_name
ginfo.store_est_entry_info = TRUE;
else
ginfo.store_est_entry_info = FALSE;
- ginfo.est_num_entries = est_num_entries;
- ginfo.est_name_len = est_name_len;
+ ginfo.est_num_entries = (uint16_t)est_num_entries;
+ ginfo.est_name_len = (uint16_t)est_name_len;
/* Set group info */
if(H5P_set(plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
@@ -451,8 +451,8 @@ H5Pset_link_creation_order(hid_t plist_id, unsigned crt_order_flags)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get link info")
/* Update fields */
- linfo.track_corder = (crt_order_flags & H5P_CRT_ORDER_TRACKED) ? TRUE : FALSE;
- linfo.index_corder = (crt_order_flags & H5P_CRT_ORDER_INDEXED) ? TRUE : FALSE;
+ linfo.track_corder = (hbool_t)((crt_order_flags & H5P_CRT_ORDER_TRACKED) ? TRUE : FALSE);
+ linfo.index_corder = (hbool_t)((crt_order_flags & H5P_CRT_ORDER_INDEXED) ? TRUE : FALSE);
/* Set link info */
if(H5P_set(plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0)
diff --git a/src/H5Pint.c b/src/H5Pint.c
index 233e187..7111cba 100644
--- a/src/H5Pint.c
+++ b/src/H5Pint.c
@@ -42,8 +42,6 @@
/* Local Macros */
/****************/
-#define H5P_DEFAULT_SKIPLIST_HEIGHT 8
-
/******************/
/* Local Typedefs */
@@ -142,22 +140,6 @@ const H5P_libclass_t H5P_CLS_GACC[1] = {{
NULL /* Class close callback info */
}};
-/* Dataset access property list class library initialization object */
-/* (move to proper source code file when used for real) */
-const H5P_libclass_t H5P_CLS_DACC[1] = {{
- "dataset access", /* Class name for debugging */
- &H5P_CLS_LINK_ACCESS_g, /* Parent class ID */
- &H5P_CLS_DATASET_ACCESS_g, /* Pointer to class ID */
- &H5P_LST_DATASET_ACCESS_g, /* Pointer to default property list ID */
- NULL, /* Default property registration routine */
- NULL, /* Class creation callback */
- NULL, /* Class creation callback info */
- NULL, /* Class copy callback */
- NULL, /* Class copy callback info */
- NULL, /* Class close callback */
- NULL /* Class close callback info */
-}};
-
/* Datatype creation property list class library initialization object */
/* (move to proper source code file when used for real) */
const H5P_libclass_t H5P_CLS_TCRT[1] = {{
@@ -200,6 +182,7 @@ H5_DLLVAR const H5P_libclass_t H5P_CLS_OCPY[1]; /* Object copy */
H5_DLLVAR const H5P_libclass_t H5P_CLS_FCRT[1]; /* File creation */
H5_DLLVAR const H5P_libclass_t H5P_CLS_FACC[1]; /* File access */
H5_DLLVAR const H5P_libclass_t H5P_CLS_DCRT[1]; /* Dataset creation */
+H5_DLLVAR const H5P_libclass_t H5P_CLS_DACC[1]; /* Dataset access */
H5_DLLVAR const H5P_libclass_t H5P_CLS_DXFR[1]; /* Data transfer */
H5_DLLVAR const H5P_libclass_t H5P_CLS_FMNT[1]; /* File mount */
H5_DLLVAR const H5P_libclass_t H5P_CLS_ACRT[1]; /* Attribute creation */
@@ -294,7 +277,7 @@ H5P_do_prop_cb1(H5SL_t *slist, H5P_genprop_t *prop, H5P_prp_cb1_t cb)
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Property callback failed");
/* Check if the property value changed */
- if(HDmemcmp(tmp_value,prop->value,prop->size)) {
+ if((prop->cmp)(tmp_value,prop->value,prop->size)) {
/* Make a copy of the class's property */
if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL)
HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property");
@@ -406,7 +389,7 @@ H5P_init_interface(void)
/* Check for parent class */
if(lib_class->par_class_id) {
/* Get the pointer to the parent class */
- if(NULL == (par_pclass = H5I_object(*lib_class->par_class_id)))
+ if(NULL == (par_pclass = (H5P_genclass_t *)H5I_object(*lib_class->par_class_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class")
} /* end if */
@@ -419,13 +402,13 @@ H5P_init_interface(void)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register properties")
/* Register the new class */
- if((*lib_class->class_id = H5I_register(H5I_GENPROP_CLS, new_pclass)) < 0)
+ if((*lib_class->class_id = H5I_register(H5I_GENPROP_CLS, new_pclass, FALSE)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class")
/* Only register the default property list if it hasn't been created yet */
if(lib_class->def_plist_id && *lib_class->def_plist_id == (-1)) {
/* Register the default property list for the new class*/
- if((*lib_class->def_plist_id = H5P_create_id(new_pclass)) < 0)
+ if((*lib_class->def_plist_id = H5P_create_id(new_pclass, FALSE)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register default property list for class")
} /* end if */
@@ -482,7 +465,7 @@ H5P_term_interface(void)
if(n) {
/* Clear the lists */
if(nlist>0) {
- H5I_clear_type(H5I_GENPROP_LST, FALSE);
+ H5I_clear_type(H5I_GENPROP_LST, FALSE, FALSE);
/* Reset the default property lists, if they've been closed */
if(H5I_nmembers(H5I_GENPROP_LST)==0) {
@@ -505,7 +488,7 @@ H5P_term_interface(void)
/* Only attempt to close the classes after all the lists are closed */
if(nlist==0 && nclass>0) {
- H5I_clear_type(H5I_GENPROP_CLS, FALSE);
+ H5I_clear_type(H5I_GENPROP_CLS, FALSE, FALSE);
/* Reset the default property lists, if they've been closed */
if(H5I_nmembers(H5I_GENPROP_CLS)==0) {
@@ -588,7 +571,7 @@ H5P_copy_pclass(H5P_genclass_t *pclass)
curr_node=H5SL_first(pclass->props);
while(curr_node!=NULL) {
/* Make a copy of the class's property */
- if((pcopy=H5P_dup_prop(H5SL_item(curr_node),H5P_PROP_WITHIN_CLASS)) == NULL)
+ if(NULL == (pcopy = H5P_dup_prop((H5P_genprop_t *)H5SL_item(curr_node), H5P_PROP_WITHIN_CLASS)))
HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't copy property");
/* Insert the initialized property into the property list */
@@ -636,7 +619,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
hid_t
-H5P_copy_plist(H5P_genplist_t *old_plist)
+H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref)
{
H5P_genclass_t *tclass; /* Temporary class pointer */
H5P_genplist_t *new_plist=NULL; /* New property list generated from copy */
@@ -667,11 +650,11 @@ H5P_copy_plist(H5P_genplist_t *old_plist)
new_plist->class_init = 0; /* Initially, wait until the class callback finishes to set */
/* Initialize the skip list to hold the changed properties */
- if((new_plist->props = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL)
+ if((new_plist->props = H5SL_create(H5SL_TYPE_STR)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for changed properties");
/* Create the skip list for deleted properties */
- if((new_plist->del = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL)
+ if((new_plist->del = H5SL_create(H5SL_TYPE_STR)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for deleted properties");
/* Create the skip list to hold names of properties already seen
@@ -679,7 +662,7 @@ H5P_copy_plist(H5P_genplist_t *old_plist)
* 'create' callback called, if a property in the class hierarchy has
* already been seen)
*/
- if((seen = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT))== NULL)
+ if((seen = H5SL_create(H5SL_TYPE_STR))== NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties");
nseen = 0;
@@ -712,11 +695,11 @@ H5P_copy_plist(H5P_genplist_t *old_plist)
curr_node=H5SL_first(old_plist->props);
while(curr_node) {
/* Get a pointer to the node's property */
- tmp=H5SL_item(curr_node);
+ tmp = (H5P_genprop_t *)H5SL_item(curr_node);
/* Make a copy of the list's property */
- if((new_prop=H5P_dup_prop(tmp,H5P_PROP_WITHIN_LIST)) == NULL)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property");
+ if(NULL == (new_prop = H5P_dup_prop(tmp, H5P_PROP_WITHIN_LIST)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property")
/* Call property copy callback, if it exists */
if(new_prop->copy) {
@@ -750,14 +733,14 @@ H5P_copy_plist(H5P_genplist_t *old_plist)
* initialize each with default value & make property 'copy' callback.
*/
tclass=old_plist->pclass;
- has_parent_class=(tclass!=NULL && tclass->parent!=NULL && tclass->parent->nprops>0);
+ has_parent_class = (hbool_t)(tclass != NULL && tclass->parent != NULL && tclass->parent->nprops > 0);
while(tclass!=NULL) {
if(tclass->nprops>0) {
/* Walk through the properties in the old class */
curr_node=H5SL_first(tclass->props);
while(curr_node!=NULL) {
/* Get pointer to property from node */
- tmp=H5SL_item(curr_node);
+ tmp = (H5P_genprop_t *)H5SL_item(curr_node);
/* Only "copy" properties we haven't seen before */
if(nseen==0 || H5SL_search(seen,tmp->name) == NULL) {
@@ -793,20 +776,28 @@ H5P_copy_plist(H5P_genplist_t *old_plist)
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't increment class ref count");
/* Get an atom for the property list */
- if((new_plist_id = H5I_register(H5I_GENPROP_LST, new_plist)) < 0)
+ if((new_plist_id = H5I_register(H5I_GENPROP_LST, new_plist, app_ref)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list");
/* Save the property list ID in the property list struct, for use in the property class's 'close' callback */
new_plist->plist_id=new_plist_id;
- /* Call the class callback (if it exists) now that we have the property list ID */
- if(new_plist->pclass->copy_func!=NULL) {
- if((new_plist->pclass->copy_func)(new_plist_id,old_plist->plist_id,old_plist->pclass->copy_data) < 0) {
- /* Delete ID, ignore return value */
- H5I_remove(new_plist_id);
- HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property");
+ /* Call the class callback (if it exists) now that we have the property list ID
+ * (up through chain of parent classes also)
+ */
+ tclass = new_plist->pclass;
+ while(NULL != tclass) {
+ if(NULL != tclass->copy_func) {
+ if((tclass->copy_func)(new_plist_id, old_plist->plist_id, old_plist->pclass->copy_data) < 0) {
+ /* Delete ID, ignore return value */
+ H5I_remove(new_plist_id);
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property")
+ } /* end if */
} /* end if */
- } /* end if */
+
+ /* Go up to parent class */
+ tclass = tclass->parent;
+ } /* end while */
/* Set the class initialization flag */
new_plist->class_init=1;
@@ -848,27 +839,27 @@ done:
static H5P_genprop_t *
H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type)
{
- H5P_genprop_t *prop=NULL; /* Pointer to new property copied */
+ H5P_genprop_t *prop = NULL; /* Pointer to new property copied */
H5P_genprop_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5P_dup_prop);
+ FUNC_ENTER_NOAPI_NOINIT(H5P_dup_prop)
- assert(oprop);
- assert(type!=H5P_PROP_WITHIN_UNKNOWN);
+ HDassert(oprop);
+ HDassert(type != H5P_PROP_WITHIN_UNKNOWN);
/* Allocate the new property */
- if(NULL==(prop = H5FL_MALLOC (H5P_genprop_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ if(NULL == (prop = H5FL_MALLOC(H5P_genprop_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Copy basic property information */
- HDmemcpy(prop,oprop,sizeof(H5P_genprop_t));
+ HDmemcpy(prop, oprop, sizeof(H5P_genprop_t));
/* Check if we should duplicate the name or share it */
/* Duplicating property for a class */
- if(type==H5P_PROP_WITHIN_CLASS) {
- assert(oprop->type==H5P_PROP_WITHIN_CLASS);
- assert(oprop->shared_name==0);
+ if(type == H5P_PROP_WITHIN_CLASS) {
+ HDassert(oprop->type == H5P_PROP_WITHIN_CLASS);
+ HDassert(oprop->shared_name == 0);
/* Duplicate name */
prop->name = H5MM_xstrdup(oprop->name);
@@ -878,48 +869,48 @@ H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type)
/* Check if we are duplicating a property from a list or a class */
/* Duplicating a property from a list */
- if(oprop->type==H5P_PROP_WITHIN_LIST) {
+ if(oprop->type == H5P_PROP_WITHIN_LIST) {
/* If the old property's name wasn't shared, we have to copy it here also */
if(!oprop->shared_name)
prop->name = H5MM_xstrdup(oprop->name);
} /* end if */
/* Duplicating a property from a class */
else {
- assert(oprop->type==H5P_PROP_WITHIN_CLASS);
- assert(oprop->shared_name==0);
+ HDassert(oprop->type == H5P_PROP_WITHIN_CLASS);
+ HDassert(oprop->shared_name == 0);
/* Share the name */
- prop->shared_name=1;
+ prop->shared_name = 1;
/* Set the type */
- prop->type=type;
+ prop->type = type;
} /* end else */
} /* end else */
/* Duplicate current value, if it exists */
- if(oprop->value!=NULL) {
- assert(prop->size>0);
- if(NULL==(prop->value = H5MM_malloc (prop->size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- HDmemcpy(prop->value,oprop->value,prop->size);
+ if(oprop->value != NULL) {
+ HDassert(prop->size > 0);
+ if(NULL == (prop->value = H5MM_malloc(prop->size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HDmemcpy(prop->value, oprop->value, prop->size);
} /* end if */
/* Set return value */
- ret_value=prop;
+ ret_value = prop;
done:
/* Free any resources allocated */
- if(ret_value==NULL) {
- if(prop!=NULL) {
- if(prop->name!=NULL)
+ if(ret_value == NULL) {
+ if(prop != NULL) {
+ if(prop->name != NULL)
H5MM_xfree(prop->name);
- if(prop->value!=NULL)
+ if(prop->value != NULL)
H5MM_xfree(prop->value);
- H5FL_FREE(H5P_genprop_t,prop);
+ (void)H5FL_FREE(H5P_genprop_t, prop);
} /* end if */
} /* end if */
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5P_dup_prop() */
@@ -1014,7 +1005,7 @@ done:
H5MM_xfree(prop->name);
if(prop->value!=NULL)
H5MM_xfree(prop->value);
- H5FL_FREE(H5P_genprop_t,prop);
+ (void)H5FL_FREE(H5P_genprop_t, prop);
} /* end if */
} /* end if */
@@ -1083,40 +1074,40 @@ H5P_find_prop_plist(H5P_genplist_t *plist, const char *name)
{
H5P_genprop_t *ret_value; /* Property pointer return value */
- FUNC_ENTER_NOAPI_NOINIT(H5P_find_prop_plist);
+ FUNC_ENTER_NOAPI_NOINIT(H5P_find_prop_plist)
- assert(plist);
- assert(name);
+ HDassert(plist);
+ HDassert(name);
/* Check if the property has been deleted from list */
- if(H5SL_search(plist->del,name)!=NULL) {
- HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list");
+ if(H5SL_search(plist->del,name) != NULL) {
+ HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "can't find property in skip list")
} /* end if */
else {
/* Get the property data from the skip list */
- if((ret_value=H5SL_search(plist->props,name)) == NULL) {
+ if(NULL == (ret_value = (H5P_genprop_t *)H5SL_search(plist->props, name))) {
H5P_genclass_t *tclass; /* Temporary class pointer */
/* Couldn't find property in list itself, start searching through class info */
- tclass=plist->pclass;
- while(tclass!=NULL) {
+ tclass = plist->pclass;
+ while(tclass != NULL) {
/* Find the property in the class */
- if((ret_value=H5SL_search(tclass->props,name))!=NULL)
+ if(NULL != (ret_value = (H5P_genprop_t *)H5SL_search(tclass->props, name)))
/* Got pointer to property - leave now */
break;
/* Go up to parent class */
- tclass=tclass->parent;
+ tclass = tclass->parent;
} /* end while */
/* Check if we haven't found the property */
- if(ret_value==NULL)
- HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list");
+ if(ret_value == NULL)
+ HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list")
} /* end else */
} /* end else */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5P_find_prop_plist() */
@@ -1143,17 +1134,17 @@ H5P_find_prop_pclass(H5P_genclass_t *pclass, const char *name)
{
H5P_genprop_t *ret_value; /* Property pointer return value */
- FUNC_ENTER_NOAPI_NOINIT(H5P_find_prop_pclass);
+ FUNC_ENTER_NOAPI_NOINIT(H5P_find_prop_pclass)
- assert(pclass);
- assert(name);
+ HDassert(pclass);
+ HDassert(name);
/* Get the property from the skip list */
- if((ret_value=H5SL_search(pclass->props,name)) == NULL)
- HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list");
+ if(NULL == (ret_value = (H5P_genprop_t *)H5SL_search(pclass->props, name)))
+ HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5P_find_prop_pclass() */
@@ -1190,7 +1181,7 @@ H5P_free_prop(H5P_genprop_t *prop)
if(prop->shared_name==0)
H5MM_xfree(prop->name);
- H5FL_FREE(H5P_genprop_t,prop);
+ (void)H5FL_FREE(H5P_genprop_t, prop);
FUNC_LEAVE_NOAPI(SUCCEED);
} /* H5P_free_prop() */
@@ -1336,7 +1327,8 @@ H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod)
case H5P_MOD_ERR:
case H5P_MOD_MAX:
- assert(0 && "Invalid H5P class modification");
+ default:
+ HDassert(0 && "Invalid H5P class modification");
} /* end switch */
/* Check if we can release the class information now */
@@ -1353,7 +1345,7 @@ H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod)
H5SL_destroy(pclass->props,H5P_free_prop_cb,&make_cb);
} /* end if */
- H5FL_FREE(H5P_genclass_t,pclass);
+ (void)H5FL_FREE(H5P_genclass_t, pclass);
/* Reduce the number of dependent classes on parent class also */
if(par_class!=NULL)
@@ -1476,7 +1468,7 @@ H5P_create_class(H5P_genclass_t *par_class, const char *name, unsigned internal,
pclass->revision = H5P_GET_NEXT_REV; /* Get a revision number for the class */
/* Create the skip list for properties */
- if((pclass->props = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL)
+ if((pclass->props = H5SL_create(H5SL_TYPE_STR)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for properties");
/* Set callback functions and pass-along data */
@@ -1500,7 +1492,7 @@ done:
/* Free any resources allocated */
if(ret_value==NULL)
if(pclass!=NULL)
- H5FL_FREE(H5P_genclass_t,pclass);
+ (void)H5FL_FREE(H5P_genclass_t, pclass);
FUNC_LEAVE_NOAPI(ret_value)
} /* H5P_create_class() */
@@ -1558,11 +1550,11 @@ H5P_create(H5P_genclass_t *pclass)
plist->class_init = 0; /* Initially, wait until the class callback finishes to set */
/* Create the skip list for changed properties */
- if((plist->props = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL)
+ if((plist->props = H5SL_create(H5SL_TYPE_STR)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for changed properties");
/* Create the skip list for deleted properties */
- if((plist->del = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL)
+ if((plist->del = H5SL_create(H5SL_TYPE_STR)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for deleted properties");
/* Create the skip list to hold names of properties already seen
@@ -1570,7 +1562,7 @@ H5P_create(H5P_genclass_t *pclass)
* 'create' callback called, if a property in the class hierarchy has
* already been seen)
*/
- if((seen = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL)
+ if((seen = H5SL_create(H5SL_TYPE_STR)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for seen properties");
/*
@@ -1586,7 +1578,7 @@ H5P_create(H5P_genclass_t *pclass)
curr_node=H5SL_first(tclass->props);
while(curr_node!=NULL) {
/* Get pointer to property from node */
- tmp=H5SL_item(curr_node);
+ tmp = (H5P_genprop_t *)H5SL_item(curr_node);
/* Only "create" properties we haven't seen before */
if(H5SL_search(seen,tmp->name) == NULL) {
@@ -1641,7 +1633,7 @@ done:
H5SL_close(plist->del);
/* Release the property list itself */
- H5FL_FREE(H5P_genplist_t,plist);
+ (void)H5FL_FREE(H5P_genplist_t, plist);
} /* end if */
} /* end if */
@@ -1672,10 +1664,11 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
hid_t
-H5P_create_id(H5P_genclass_t *pclass)
+H5P_create_id(H5P_genclass_t *pclass, hbool_t app_ref)
{
- H5P_genplist_t *plist=NULL; /* Property list created */
- hid_t plist_id=FAIL; /* Property list ID */
+ H5P_genclass_t *tclass; /* Temporary class pointer */
+ H5P_genplist_t *plist = NULL; /* Property list created */
+ hid_t plist_id = FAIL; /* Property list ID */
hid_t ret_value; /* return value */
FUNC_ENTER_NOAPI(H5P_create_id, FAIL);
@@ -1687,20 +1680,28 @@ H5P_create_id(H5P_genclass_t *pclass)
HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list");
/* Get an atom for the property list */
- if((plist_id = H5I_register(H5I_GENPROP_LST, plist)) < 0)
+ if((plist_id = H5I_register(H5I_GENPROP_LST, plist, app_ref)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list");
/* Save the property list ID in the property list struct, for use in the property class's 'close' callback */
plist->plist_id=plist_id;
- /* Call the class callback (if it exists) now that we have the property list ID */
- if(plist->pclass->create_func!=NULL) {
- if((plist->pclass->create_func)(plist_id,plist->pclass->create_data) < 0) {
- /* Delete ID, ignore return value */
- H5I_remove(plist_id);
- HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property");
+ /* Call the class callback (if it exists) now that we have the property list ID
+ * (up through chain of parent classes also)
+ */
+ tclass = plist->pclass;
+ while(NULL != tclass) {
+ if(NULL != tclass->create_func) {
+ if((tclass->create_func)(plist_id, tclass->create_data) < 0) {
+ /* Delete ID, ignore return value */
+ H5I_remove(plist_id);
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property")
+ } /* end if */
} /* end if */
- } /* end if */
+
+ /* Go up to parent class */
+ tclass = tclass->parent;
+ } /* end while */
/* Set the class initialization flag */
plist->class_init=1;
@@ -1908,10 +1909,10 @@ H5P_register(H5P_genclass_t *pclass, const char *name, size_t size,
/* Walk through the properties in the old class */
curr_node=H5SL_first(pclass->props);
- while(curr_node!=NULL) {
+ while(curr_node != NULL) {
/* Make a copy of the class's property */
- if((pcopy=H5P_dup_prop(H5SL_item(curr_node),H5P_PROP_WITHIN_CLASS)) == NULL)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property");
+ if(NULL == (pcopy = H5P_dup_prop((H5P_genprop_t *)H5SL_item(curr_node), H5P_PROP_WITHIN_CLASS)))
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL, "Can't copy property")
/* Insert the initialized property into the property list */
if(H5P_add_prop(new_class->props,pcopy) < 0)
@@ -1950,7 +1951,7 @@ done:
H5MM_xfree(new_prop->name);
if(new_prop->value!=NULL)
H5MM_xfree(new_prop->value);
- H5FL_FREE(H5P_genprop_t,new_prop);
+ (void)H5FL_FREE(H5P_genprop_t, new_prop);
} /* end if */
} /* end if */
FUNC_LEAVE_NOAPI(ret_value);
@@ -2162,7 +2163,7 @@ done:
H5MM_xfree(new_prop->name);
if(new_prop->value!=NULL)
H5MM_xfree(new_prop->value);
- H5FL_FREE(H5P_genprop_t,new_prop);
+ (void)H5FL_FREE(H5P_genprop_t, new_prop);
} /* end if */
} /* end if */
@@ -2219,7 +2220,7 @@ H5P_set(H5P_genplist_t *plist, const char *name, const void *value)
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist");
/* Find property in changed list */
- if((prop=H5SL_search(plist->props,name))!=NULL) {
+ if(NULL != (prop = (H5P_genprop_t *)H5SL_search(plist->props, name))) {
/* Check for property size >0 */
if(prop->size==0)
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size");
@@ -2258,7 +2259,7 @@ H5P_set(H5P_genplist_t *plist, const char *name, const void *value)
while(tclass!=NULL) {
if(tclass->nprops>0) {
/* Find the property in the class */
- if((prop=H5SL_search(tclass->props,name))!=NULL) {
+ if((prop = (H5P_genprop_t *)H5SL_search(tclass->props,name))!=NULL) {
H5P_genprop_t *pcopy; /* Copy of property to insert into skip list */
/* Check for property size >0 */
@@ -2280,7 +2281,7 @@ H5P_set(H5P_genplist_t *plist, const char *name, const void *value)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value");
} /* end if */
- if(HDmemcmp(tmp_value,prop->value,prop->size)) {
+ if((prop->cmp)(tmp_value,prop->value,prop->size)) {
/* Make a copy of the class's property */
if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property");
@@ -2298,7 +2299,7 @@ H5P_set(H5P_genplist_t *plist, const char *name, const void *value)
} /* end if */
/* No 'set' callback, just copy value */
else {
- if(HDmemcmp(value,prop->value,prop->size)) {
+ if((prop->cmp)(value,prop->value,prop->size)) {
/* Make a copy of the class's property */
if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property");
@@ -2821,8 +2822,8 @@ H5P_cmp_class(const H5P_genclass_t *pclass1, const H5P_genclass_t *pclass2)
if(tnode1 != NULL && tnode2 == NULL) HGOTO_DONE(1);
/* Compare the two properties */
- prop1 = H5SL_item(tnode1);
- prop2 = H5SL_item(tnode2);
+ prop1 = (H5P_genprop_t *)H5SL_item(tnode1);
+ prop2 = (H5P_genprop_t *)H5SL_item(tnode2);
if((cmp_value = H5P_cmp_prop(prop1, prop2)) != 0)
HGOTO_DONE(cmp_value);
@@ -2893,8 +2894,8 @@ H5P_cmp_plist(const H5P_genplist_t *plist1, const H5P_genplist_t *plist2)
if(tnode1 != NULL && tnode2 == NULL) HGOTO_DONE(1);
/* Compare the two deleted properties */
- name1 = H5SL_item(tnode1);
- name2 = H5SL_item(tnode2);
+ name1 = (const char *)H5SL_item(tnode1);
+ name2 = (const char *)H5SL_item(tnode2);
if((cmp_value = HDstrcmp(name1, name2)) != 0)
HGOTO_DONE(cmp_value);
@@ -2921,8 +2922,8 @@ H5P_cmp_plist(const H5P_genplist_t *plist1, const H5P_genplist_t *plist2)
if(tnode1 != NULL && tnode2 == NULL) HGOTO_DONE(1);
/* Compare the two properties */
- prop1 = H5SL_item(tnode1);
- prop2 = H5SL_item(tnode2);
+ prop1 = (H5P_genprop_t *)H5SL_item(tnode1);
+ prop2 = (H5P_genprop_t *)H5SL_item(tnode2);
if((cmp_value = H5P_cmp_prop(prop1, prop2)) != 0)
HGOTO_DONE(cmp_value);
@@ -3027,9 +3028,9 @@ H5P_isa_class(hid_t plist_id, hid_t pclass_id)
FUNC_ENTER_NOAPI(H5P_isa_class, FAIL);
/* Check arguments. */
- if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
- if(NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
+ if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class");
/* Compare the property list's class against the other class */
@@ -3069,23 +3070,23 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-void *
+H5P_genplist_t *
H5P_object_verify(hid_t plist_id, hid_t pclass_id)
{
- void *ret_value; /* return value */
+ H5P_genplist_t *ret_value; /* return value */
- FUNC_ENTER_NOAPI(H5P_object_verify, NULL);
+ FUNC_ENTER_NOAPI(H5P_object_verify, NULL)
/* Compare the property list's class against the other class */
if(H5P_isa_class(plist_id, pclass_id) != TRUE)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, NULL, "property list is not a member of the class");
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, NULL, "property list is not a member of the class")
/* Get the plist structure */
- if(NULL == (ret_value = H5I_object(plist_id)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+ if(NULL == (ret_value = (H5P_genplist_t *)H5I_object(plist_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5P_object_verify() */
@@ -3157,11 +3158,11 @@ H5P_iterate_plist(hid_t plist_id, int *idx, H5P_iterate_t iter_func, void *iter_
HDassert(iter_func);
/* Get the property list object */
- if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
/* Create the skip list to hold names of properties already seen */
- if((seen = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL)
+ if((seen = H5SL_create(H5SL_TYPE_STR)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties");
/* Walk through the changed properties in the list */
@@ -3169,7 +3170,7 @@ H5P_iterate_plist(hid_t plist_id, int *idx, H5P_iterate_t iter_func, void *iter_
curr_node = H5SL_first(plist->props);
while(curr_node != NULL) {
/* Get pointer to property from node */
- tmp = H5SL_item(curr_node);
+ tmp = (H5P_genprop_t *)H5SL_item(curr_node);
/* Check if we've found the correctly indexed property */
if(curr_idx>=*idx) {
@@ -3200,7 +3201,7 @@ H5P_iterate_plist(hid_t plist_id, int *idx, H5P_iterate_t iter_func, void *iter_
curr_node=H5SL_first(tclass->props);
while(curr_node!=NULL) {
/* Get pointer to property from node */
- tmp=H5SL_item(curr_node);
+ tmp = (H5P_genprop_t *)H5SL_item(curr_node);
/* Only call iterator callback for properties we haven't seen
* before and that haven't been deleted
@@ -3313,7 +3314,7 @@ H5P_iterate_pclass(hid_t pclass_id, int *idx, H5P_iterate_t iter_func, void *ite
assert(iter_func);
/* Get the property list object */
- if(NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
+ if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class");
/* Cycle through the properties and call the callback */
@@ -3322,7 +3323,7 @@ H5P_iterate_pclass(hid_t pclass_id, int *idx, H5P_iterate_t iter_func, void *ite
while(curr_node!=NULL) {
if(curr_idx>=*idx) {
/* Get the property for the node */
- prop=H5SL_item(curr_node);
+ prop = (H5P_genprop_t *)H5SL_item(curr_node);
/* Call the callback function */
ret_value=(*iter_func)(pclass_id,prop->name,iter_data);
@@ -3573,7 +3574,7 @@ H5P_get(const H5P_genplist_t *plist, const char *name, void *value)
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist");
/* Find property */
- if((prop=H5SL_search(plist->props,name))!=NULL) {
+ if((prop = (H5P_genprop_t *)H5SL_search(plist->props,name))!=NULL) {
/* Check for property size >0 */
if(prop->size==0)
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size");
@@ -3610,7 +3611,7 @@ H5P_get(const H5P_genplist_t *plist, const char *name, void *value)
while(tclass!=NULL) {
if(tclass->nprops>0) {
/* Find the property in the class */
- if((prop=H5SL_search(tclass->props,name))!=NULL) {
+ if((prop = (H5P_genprop_t *)H5SL_search(tclass->props,name))!=NULL) {
/* Check for property size >0 */
if(prop->size==0)
HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size");
@@ -3630,7 +3631,7 @@ H5P_get(const H5P_genplist_t *plist, const char *name, void *value)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value");
} /* end if */
- if(HDmemcmp(tmp_value,prop->value,prop->size)) {
+ if((prop->cmp)(tmp_value,prop->value,prop->size)) {
H5P_genprop_t *pcopy; /* Copy of property to insert into skip list */
/* Make a copy of the class's property */
@@ -3719,7 +3720,7 @@ H5P_remove(hid_t plist_id, H5P_genplist_t *plist, const char *name)
HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list");
/* Get the property node from the changed property skip list */
- if((prop=H5SL_search(plist->props,name))!=NULL) {
+ if((prop = (H5P_genprop_t *)H5SL_search(plist->props,name))!=NULL) {
/* Pass value to 'close' callback, if it exists */
if(prop->del!=NULL) {
/* Call user's callback */
@@ -3851,7 +3852,7 @@ H5P_copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name)
assert(name);
/* Get the objects to operate on */
- if(NULL == (src_plist = H5I_object(src_id)) || NULL == (dst_plist = H5I_object(dst_id)))
+ if(NULL == (src_plist = (H5P_genplist_t *)H5I_object(src_id)) || NULL == (dst_plist = (H5P_genplist_t *)H5I_object(dst_id)))
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist");
/* If the property exists in the destination alread */
@@ -4011,7 +4012,7 @@ H5P_unregister(H5P_genclass_t *pclass, const char *name)
assert(name);
/* Get the property node from the skip list */
- if((prop=H5SL_search(pclass->props,name)) == NULL)
+ if((prop = (H5P_genprop_t *)H5SL_search(pclass->props,name)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list");
/* Remove the property from the skip list */
@@ -4074,10 +4075,20 @@ H5P_close(void *_plist)
assert(plist);
- /* Make call to property list class close callback, if needed */
- if(plist->class_init!=0 && plist->pclass->close_func!=NULL) {
- /* Call user's "close" callback function, ignoring return value */
- (plist->pclass->close_func)(plist->plist_id,plist->pclass->close_data);
+ /* Make call to property list class close callback, if needed
+ * (up through chain of parent classes also)
+ */
+ if(plist->class_init !=0) {
+ tclass = plist->pclass;
+ while(NULL != tclass) {
+ if(NULL != tclass->close_func) {
+ /* Call user's "close" callback function, ignoring return value */
+ (tclass->close_func)(plist->plist_id, tclass->close_data);
+ } /* end if */
+
+ /* Go up to parent class */
+ tclass = tclass->parent;
+ } /* end while */
} /* end if */
/* Create the skip list to hold names of properties already seen
@@ -4085,7 +4096,7 @@ H5P_close(void *_plist)
* 'close' callback called, if a property in the class hierarchy has
* already been seen)
*/
- if((seen = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL)
+ if((seen = H5SL_create(H5SL_TYPE_STR)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties");
nseen = 0;
@@ -4094,7 +4105,7 @@ H5P_close(void *_plist)
curr_node=H5SL_first(plist->props);
while(curr_node!=NULL) {
/* Get pointer to property from node */
- tmp=H5SL_item(curr_node);
+ tmp = (H5P_genprop_t *)H5SL_item(curr_node);
/* Call property close callback, if it exists */
if(tmp->close) {
@@ -4120,14 +4131,14 @@ H5P_close(void *_plist)
* initialize each with default value & make property 'remove' callback.
*/
tclass=plist->pclass;
- has_parent_class=(tclass!=NULL && tclass->parent!=NULL && tclass->parent->nprops>0);
+ has_parent_class = (hbool_t)(tclass != NULL && tclass->parent != NULL && tclass->parent->nprops > 0);
while(tclass!=NULL) {
if(tclass->nprops>0) {
/* Walk through the properties in the class */
curr_node=H5SL_first(tclass->props);
while(curr_node!=NULL) {
/* Get pointer to property from node */
- tmp=H5SL_item(curr_node);
+ tmp = (H5P_genprop_t *)H5SL_item(curr_node);
/* Only "delete" properties we haven't seen before
* and that haven't already been deleted
@@ -4183,11 +4194,11 @@ H5P_close(void *_plist)
H5SL_destroy(plist->props,H5P_free_prop_cb,&make_cb);
/* Destroy property list object */
- H5FL_FREE(H5P_genplist_t,plist);
+ (void)H5FL_FREE(H5P_genplist_t, plist);
done:
/* Release the skip list of 'seen' properties */
- if(seen!=NULL)
+ if(seen != NULL)
H5SL_close(seen);
FUNC_LEAVE_NOAPI(ret_value);
@@ -4276,7 +4287,7 @@ H5P_get_class_path(H5P_genclass_t *pclass)
/* Allocate enough space for the parent class's path, plus the '/'
* separator, this class's name and the string terminator
*/
- if(NULL==(ret_value=H5MM_malloc(par_path_len+1+my_path_len+1)))
+ if(NULL == (ret_value = (char *)H5MM_malloc(par_path_len + 1 + my_path_len + 1)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for class name");
/* Build the full path for this class */
@@ -4320,24 +4331,24 @@ done:
H5P_genclass_t *
H5P_open_class_path(const char *path)
{
- char *tmp_path=NULL; /* Temporary copy of the path */
+ char *tmp_path = NULL; /* Temporary copy of the path */
char *curr_name; /* Pointer to current component of path name */
char *delimit; /* Pointer to path delimiter during traversal */
H5P_genclass_t *curr_class; /* Pointer to class during path traversal */
H5P_genclass_t *ret_value; /* Return value */
H5P_check_class_t check_info; /* Structure to hold the information for checking duplicate names */
- FUNC_ENTER_NOAPI_NOINIT(H5P_open_class_path);
+ FUNC_ENTER_NOAPI_NOINIT(H5P_open_class_path)
- assert(path);
+ HDassert(path);
/* Duplicate the path to use */
- tmp_path=H5MM_xstrdup(path);
- assert(tmp_path);
+ tmp_path = H5MM_xstrdup(path);
+ HDassert(tmp_path);
/* Find the generic property class with this full path */
- curr_name=tmp_path;
- curr_class=NULL;
+ curr_name = tmp_path;
+ curr_class = NULL;
while((delimit=HDstrchr(curr_name,'/'))!=NULL) {
/* Change the delimiter to terminate the string */
*delimit='\0';
@@ -4347,7 +4358,7 @@ H5P_open_class_path(const char *path)
check_info.name=curr_name;
/* Find the class with this name & parent by iterating over the open classes */
- if((curr_class=H5I_search(H5I_GENPROP_CLS,H5P_check_class,&check_info)) == NULL)
+ if(NULL == (curr_class = (H5P_genclass_t *)H5I_search(H5I_GENPROP_CLS, H5P_check_class, &check_info, FALSE)))
HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class");
/* Advance the pointer in the path to the start of the next component */
@@ -4357,22 +4368,22 @@ H5P_open_class_path(const char *path)
/* Should be pointing to the last component in the path name now... */
/* Set up the search structure */
- check_info.parent=curr_class;
- check_info.name=curr_name;
+ check_info.parent = curr_class;
+ check_info.name = curr_name;
/* Find the class with this name & parent by iterating over the open classes */
- if((curr_class=H5I_search(H5I_GENPROP_CLS,H5P_check_class,&check_info)) == NULL)
- HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class");
+ if(NULL == (curr_class = (H5P_genclass_t *)H5I_search(H5I_GENPROP_CLS, H5P_check_class, &check_info, FALSE)))
+ HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class")
/* Copy it */
- if((ret_value=H5P_copy_pclass(curr_class)) == NULL)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, NULL, "can't copy property class");
+ if(NULL == (ret_value = H5P_copy_pclass(curr_class)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, NULL, "can't copy property class")
done:
/* Free the duplicated path */
H5MM_xfree(tmp_path);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5P_open_class_path() */
diff --git a/src/H5Plapl.c b/src/H5Plapl.c
index 8987c49..608240f 100644
--- a/src/H5Plapl.c
+++ b/src/H5Plapl.c
@@ -55,6 +55,21 @@
#define H5L_ACS_ELINK_PREFIX_COPY H5P_lacc_elink_pref_copy
#define H5L_ACS_ELINK_PREFIX_CLOSE H5P_lacc_elink_pref_close
+/* Definitions for setting fapl of external link access */
+#define H5L_ACS_ELINK_FAPL_SIZE sizeof(hid_t)
+#define H5L_ACS_ELINK_FAPL_DEF H5P_DEFAULT
+#define H5L_ACS_ELINK_FAPL_DEL H5P_lacc_elink_fapl_del
+#define H5L_ACS_ELINK_FAPL_COPY H5P_lacc_elink_fapl_copy
+#define H5L_ACS_ELINK_FAPL_CLOSE H5P_lacc_elink_fapl_close
+
+/* Definitions for file access flags for external link traversal */
+#define H5L_ACS_ELINK_FLAGS_SIZE sizeof(unsigned)
+#define H5L_ACS_ELINK_FLAGS_DEF H5F_ACC_DEFAULT
+
+/* Definitions for callback function for external link traversal */
+#define H5L_ACS_ELINK_CB_SIZE sizeof(H5L_elink_cb_t)
+#define H5L_ACS_ELINK_CB_DEF {NULL,NULL}
+
/******************/
/* Local Typedefs */
/******************/
@@ -77,6 +92,10 @@ static herr_t H5P_lacc_elink_pref_del(hid_t prop_id, const char* name, size_t si
static herr_t H5P_lacc_elink_pref_copy(const char* name, size_t size, void* value);
static herr_t H5P_lacc_elink_pref_close(const char* name, size_t size, void* value);
+static herr_t H5P_lacc_elink_fapl_del(hid_t prop_id, const char* name, size_t size, void* value);
+static herr_t H5P_lacc_elink_fapl_copy(const char* name, size_t size, void* value);
+static herr_t H5P_lacc_elink_fapl_close(const char* name, size_t size, void* value);
+
/*********************/
/* Package Variables */
@@ -118,14 +137,23 @@ const H5P_libclass_t H5P_CLS_LACC[1] = {{
*
* Programmer: Quincey Koziol
* October 31, 2006
+ *
+ * Modifications:
+ * Vailin Choi, Sept. 12th 2008
+ * Register the setting of file access property list for link access
+ *
*-------------------------------------------------------------------------
*/
static herr_t
H5P_lacc_reg_prop(H5P_genclass_t *pclass)
{
- size_t nlinks = H5L_ACS_NLINKS_DEF; /* Default number of soft links to traverse */
+ size_t nlinks = H5L_ACS_NLINKS_DEF; /* Default number of soft links to traverse */
char *elink_prefix = H5L_ACS_ELINK_PREFIX_DEF; /* Default external link prefix string */
- herr_t ret_value = SUCCEED; /* Return value */
+ hid_t def_fapl_id = H5L_ACS_ELINK_FAPL_DEF; /* Default fapl for external link access */
+ unsigned elink_flags = H5L_ACS_ELINK_FLAGS_DEF; /* Default file access flags for external link traversal */
+ H5L_elink_cb_t elink_cb = H5L_ACS_ELINK_CB_DEF; /* Default external link traversal callback */
+
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5P_lacc_reg_prop)
@@ -139,11 +167,133 @@ H5P_lacc_reg_prop(H5P_genclass_t *pclass)
&elink_prefix, NULL, NULL, NULL, H5L_ACS_ELINK_PREFIX_DEL, H5L_ACS_ELINK_PREFIX_COPY, NULL, H5L_ACS_ELINK_PREFIX_CLOSE) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ /* Register fapl for link access */
+ if(H5P_register(pclass, H5L_ACS_ELINK_FAPL_NAME, H5L_ACS_ELINK_FAPL_SIZE, &def_fapl_id, NULL, NULL, NULL, H5L_ACS_ELINK_FAPL_DEL, H5L_ACS_ELINK_FAPL_COPY, NULL, H5L_ACS_ELINK_FAPL_CLOSE) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+ /* Register property for external link file access flags */
+ if(H5P_register(pclass, H5L_ACS_ELINK_FLAGS_NAME, H5L_ACS_ELINK_FLAGS_SIZE,
+ &elink_flags, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+ /* Register property for external link file traversal callback */
+ if(H5P_register(pclass, H5L_ACS_ELINK_CB_NAME, H5L_ACS_ELINK_CB_SIZE,
+ &elink_cb, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P_lacc_reg_prop() */
+/*--------------------------------------------------------------------------
+ * Function: H5P_lacc_elink_fapl_del
+ *
+ * Purpose: Close the FAPL for link access
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Vailin Choi
+ * Tuesday, Sept 23, 2008
+ *
+ *--------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static herr_t
+H5P_lacc_elink_fapl_del(hid_t UNUSED prop_id, const char UNUSED *name, size_t UNUSED size, void *value)
+{
+ hid_t l_fapl_id;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5P_lacc_elink_fapl_del, FAIL)
+
+ HDassert(value);
+
+ l_fapl_id = (*(const hid_t *)value);
+
+ if((l_fapl_id > H5P_DEFAULT) && (H5I_dec_ref(l_fapl_id, FALSE) < 0))
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for file access property list")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_lacc_elink_fapl_del() */
+
+
+/*--------------------------------------------------------------------------
+ * Function: H5P_lacc_elink_fapl_copy
+ *
+ * Purpose: Copy the FAPL for link access
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Vailin Choi
+ * Tuesday, Sept 23, 2008
+ *
+ *--------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static herr_t
+H5P_lacc_elink_fapl_copy(const char UNUSED *name, size_t UNUSED size, void *value)
+{
+ hid_t l_fapl_id;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5P_lacc_elink_fapl_copy, FAIL)
+
+ HDassert(value);
+
+ l_fapl_id = (*(const hid_t *)value);
+
+ if(l_fapl_id > H5P_DEFAULT) {
+ H5P_genplist_t *l_fapl_plist;
+
+ if(NULL == (l_fapl_plist = (H5P_genplist_t *)H5P_object_verify(l_fapl_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
+
+ if(((*(hid_t *)value) = H5P_copy_plist(l_fapl_plist, FALSE)) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to copy file access properties")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_lacc_elink_fapl_copy() */
+
+
+/*--------------------------------------------------------------------------
+ * Function: H5P_lacc_elink_fapl_close
+ *
+ * Purpose: Close the FAPL for link access
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Vailin Choi
+ * Tuesday, Sept 23, 2008
+ *
+ *---------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static herr_t
+H5P_lacc_elink_fapl_close(const char UNUSED *name, size_t UNUSED size, void *value)
+{
+ hid_t l_fapl_id;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5P_lacc_elink_fapl_close)
+
+ HDassert(value);
+
+ l_fapl_id = (*(const hid_t *)value);
+ if((l_fapl_id > H5P_DEFAULT) && (H5I_dec_ref(l_fapl_id, FALSE) < 0))
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for file access property list")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_lacc_elink_fapl_close() */
+
+
/*-------------------------------------------------------------------------
* Function: H5P_lacc_elink_pref_del
*
@@ -315,7 +465,7 @@ done:
* Purpose: Set a prefix to be applied to the path of any external links
* traversed. The prefix is appended to the filename stored
* in the external link.
- *
+ *
* Return: Non-negative on success/Negative on failure
*
* Programmer: James Laird
@@ -412,3 +562,260 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_elink_prefix() */
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_elink_fapl
+ *
+ * Purpose: Sets the file access property list for link access
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer:
+ * Vailin Choi; Tuesday, September 12th, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_elink_fapl(hid_t lapl_id, hid_t fapl_id)
+{
+ H5P_genplist_t *plist, *fapl_plist; /* Property list pointer */
+ hid_t l_fapl_id, new_fapl_id;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Pset_elink_fapl, FAIL)
+ H5TRACE2("e", "ii", lapl_id, fapl_id);
+
+ /* Check arguments */
+ if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link access property list");
+
+ /* Get the current file access property list for the link access */
+ if(H5P_get(plist, H5L_ACS_ELINK_FAPL_NAME, &l_fapl_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fapl")
+
+ /* Close the current file access property list if set */
+ if((l_fapl_id > H5P_DEFAULT) && (H5I_dec_ref(l_fapl_id, FALSE) < 0))
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for file access property list")
+
+ if(NULL == (fapl_plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list");
+
+ /* Make a copy of the property list for FAPL_ID */
+ if((new_fapl_id = H5P_copy_plist(fapl_plist, FALSE)) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to copy file access properties")
+
+ /* Set the file access property list for the link access */
+ if(H5P_set(plist, H5L_ACS_ELINK_FAPL_NAME, &new_fapl_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set fapl for link")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_elink_fapl() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_elink_fapl
+ *
+ * Purpose: Gets the file access property list identifier that is
+ * set for link access property.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer:
+ * Vailin Choi; Tuesday, September 12th, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Pget_elink_fapl(hid_t lapl_id)
+{
+ H5P_genplist_t *plist, *fapl_plist; /* Property list pointer */
+ hid_t l_fapl_id;
+ hid_t ret_value=FAIL; /* Return value */
+
+ FUNC_ENTER_API(H5Pget_elink_fapl, FAIL)
+ H5TRACE1("i", "i", lapl_id);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ if(H5P_get(plist, H5L_ACS_ELINK_FAPL_NAME, &l_fapl_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fapl for links")
+
+ if(l_fapl_id > H5P_DEFAULT) {
+ if(NULL==(fapl_plist = H5P_object_verify(l_fapl_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list");
+
+ if((ret_value = H5P_copy_plist(fapl_plist, TRUE)) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to copy file access properties")
+ } else
+ ret_value = l_fapl_id;
+
+done:
+ FUNC_LEAVE_API(ret_value);
+} /* end H5Pget_elink_fapl() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_elink_acc_flags
+ *
+ * Purpose: Sets the file access flags to be used when traversing an
+ * external link. This should be either H5F_ACC_RDONLY or
+ * H5F_ACC_RDWR, or H5F_ACC_DEFAULT to unset the value.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, December 9, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_elink_acc_flags(hid_t lapl_id, unsigned flags)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Pset_elink_acc_flags, FAIL)
+ H5TRACE2("e", "iIu", lapl_id, flags);
+
+ /* Check that flags are valid */
+ if((flags != H5F_ACC_RDWR) && (flags != H5F_ACC_RDONLY) && (flags != H5F_ACC_DEFAULT))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags")
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Set flags */
+ if(H5P_set(plist, H5L_ACS_ELINK_FLAGS_NAME, &flags) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set access flags")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_elink_acc_flags() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_elink_acc_flags
+ *
+ * Purpose: Gets the file access flags to be used when traversing an
+ * external link.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, December 9, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_elink_acc_flags(hid_t lapl_id, unsigned *flags)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Pget_elink_acc_flags, FAIL)
+ H5TRACE2("e", "i*Iu", lapl_id, flags);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get flags */
+ if (flags)
+ if(H5P_get(plist, H5L_ACS_ELINK_FLAGS_NAME, flags)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, 0, "can't get access flags")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_elink_acc_flags() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_elink_cb
+ *
+ * Purpose: Sets the file access flags to be used when traversing an
+ * external link. This should be either H5F_ACC_RDONLY or
+ * H5F_ACC_RDWR.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, December 15, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_elink_cb(hid_t lapl_id, H5L_elink_traverse_t func, void *op_data)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5L_elink_cb_t cb_info; /* Callback info struct */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Pset_elink_cb, FAIL)
+ H5TRACE3("e", "ix*x", lapl_id, func, op_data);
+
+ /* Check if the callback function is NULL and the user data is non-NULL.
+ * This is almost certainly an error as the user data will not be used. */
+ if(!func && op_data)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback is NULL while user data is not")
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Populate the callback info struct */
+ cb_info.func = func;
+ cb_info.user_data = op_data;
+
+ /* Set callback info */
+ if(H5P_set(plist, H5L_ACS_ELINK_CB_NAME, &cb_info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set callback info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_elink_acc_flags() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_elink_cb
+ *
+ * Purpose: Gets the file access flags to be used when traversing an
+ * external link.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, December 15, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_elink_cb(hid_t lapl_id, H5L_elink_traverse_t *func, void **op_data)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5L_elink_cb_t cb_info; /* Callback info struct */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Pget_elink_cb, FAIL)
+ H5TRACE3("e", "i*x**x", lapl_id, func, op_data);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get callback_info */
+ if(H5P_get(plist, H5L_ACS_ELINK_CB_NAME, &cb_info)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get callback info")
+
+ if(func)
+ *func = cb_info.func;
+
+ if(op_data)
+ *op_data = cb_info.user_data;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_elink_cb() */
+
diff --git a/src/H5Plcpl.c b/src/H5Plcpl.c
index 4006f0e..1e4355e 100644
--- a/src/H5Plcpl.c
+++ b/src/H5Plcpl.c
@@ -156,7 +156,7 @@ H5Pset_create_intermediate_group(hid_t plist_id, unsigned crt_intmd_group)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Set value */
- crt_intmd_group = crt_intmd_group > 0 ? 1 : 0;
+ crt_intmd_group = (unsigned)(crt_intmd_group > 0 ? 1 : 0);
if(H5P_set(plist, H5L_CRT_INTERMEDIATE_GROUP_NAME, &crt_intmd_group) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set intermediate group creation flag")
diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c
index b947bef..9f144f1 100755
--- a/src/H5Pocpl.c
+++ b/src/H5Pocpl.c
@@ -52,6 +52,9 @@
#define H5O_CRT_ATTR_MIN_DENSE_SIZE sizeof(unsigned)
/* Definitions for object header flags */
#define H5O_CRT_OHDR_FLAGS_SIZE sizeof(uint8_t)
+/* Definitions for filter pipeline */
+#define H5O_CRT_PIPELINE_SIZE sizeof(H5O_pline_t)
+#define H5O_CRT_PIPELINE_CMP H5P_ocrt_pipeline_cmp
/******************/
@@ -70,6 +73,11 @@
/* Property class callbacks */
static herr_t H5P_ocrt_reg_prop(H5P_genclass_t *pclass);
+static herr_t H5P_ocrt_copy(hid_t new_plist_t, hid_t old_plist_t, void *copy_data);
+static herr_t H5P_ocrt_close(hid_t dxpl_id, void *close_data);
+
+/* Property callbacks */
+static int H5P_ocrt_pipeline_cmp(const void *value1, const void *value2, size_t size);
/*********************/
@@ -85,9 +93,9 @@ const H5P_libclass_t H5P_CLS_OCRT[1] = {{
H5P_ocrt_reg_prop, /* Default property registration routine */
NULL, /* Class creation callback */
NULL, /* Class creation callback info */
- NULL, /* Class copy callback */
+ H5P_ocrt_copy, /* Class copy callback */
NULL, /* Class copy callback info */
- NULL, /* Class close callback */
+ H5P_ocrt_close, /* Class close callback */
NULL /* Class close callback info */
}};
@@ -121,7 +129,8 @@ H5P_ocrt_reg_prop(H5P_genclass_t *pclass)
{
unsigned attr_max_compact = H5O_CRT_ATTR_MAX_COMPACT_DEF; /* Default max. compact attribute storage settings */
unsigned attr_min_dense = H5O_CRT_ATTR_MIN_DENSE_DEF; /* Default min. dense attribute storage settings */
- uint8_t ohdr_flags = H5O_CRT_OHDR_FLAGS_DEF; /* Default object header flag settings */
+ uint8_t ohdr_flags = H5O_CRT_OHDR_FLAGS_DEF; /* Default object header flag settings */
+ H5O_pline_t pline = H5O_CRT_PIPELINE_DEF; /* Default I/O pipeline setting */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5P_ocrt_reg_prop)
@@ -141,12 +150,108 @@ H5P_ocrt_reg_prop(H5P_genclass_t *pclass)
&ohdr_flags, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ /* Register the pipeline property */
+ if(H5P_register(pclass, H5O_CRT_PIPELINE_NAME, H5O_CRT_PIPELINE_SIZE,
+ &pline, NULL, NULL, NULL, NULL, NULL, H5O_CRT_PIPELINE_CMP, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P_ocrt_reg_prop() */
/*-------------------------------------------------------------------------
+ * Function: H5P_ocrt_copy
+ *
+ * Purpose: Callback routine which is called whenever any object
+ * creation property list is copied. This routine copies
+ * the properties from the old list to the new list.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Neil Fortner
+ * Monday, September 21, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static herr_t
+H5P_ocrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data)
+{
+ H5O_pline_t src_pline, dst_pline; /* Source & destination pipelines */
+ H5P_genplist_t *src_plist; /* Pointer to source property list */
+ H5P_genplist_t *dst_plist; /* Pointer to destination property list */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5P_ocrt_copy)
+
+ /* Verify property list IDs */
+ if(NULL == (dst_plist = (H5P_genplist_t *)H5I_object(dst_plist_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object creation property list")
+ if(NULL == (src_plist = (H5P_genplist_t *)H5I_object(src_plist_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object creation property list")
+
+ /* Get the link pipeline property from the old property list */
+ if(H5P_get(src_plist, H5O_CRT_PIPELINE_NAME, &src_pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
+
+ /* Make copy of link pipeline */
+ if(NULL == H5O_msg_copy(H5O_PLINE_ID, &src_pline, &dst_pline))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't copy link pipeline")
+
+ /* Set the link pipeline property for the destination property list */
+ if(H5P_set(dst_plist, H5O_CRT_PIPELINE_NAME, &dst_pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_ocrt_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_ocrt_close
+ *
+ * Purpose: Callback routine which is called whenever any object create
+ * property list is closed. This routine performs any generic
+ * cleanup needed on the properties the library put into the list.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Neil Fortner
+ * Monday, September 21, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static herr_t
+H5P_ocrt_close(hid_t dcpl_id, void UNUSED *close_data)
+{
+ H5O_pline_t pline; /* I/O pipeline */
+ H5P_genplist_t *plist; /* Property list */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5P_ocrt_close)
+
+ /* Check arguments */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object creation property list")
+
+ /* Get the link pipeline property from the old property list */
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
+
+ /* Clean up any values set for the link pipeline */
+ if(H5O_msg_reset(H5O_PLINE_ID, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't release pipeline info")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_ocrt_close() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Pset_attr_phase_change
*
* Purpose: Sets the cutoff values for indexes storing attributes
@@ -275,11 +380,11 @@ H5Pset_attr_creation_order(hid_t plist_id, unsigned crt_order_flags)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object header flags")
/* Mask off previous attribute creation order flag settings */
- ohdr_flags &= ~(H5O_HDR_ATTR_CRT_ORDER_TRACKED | H5O_HDR_ATTR_CRT_ORDER_INDEXED);
+ ohdr_flags &= (uint8_t)~(H5O_HDR_ATTR_CRT_ORDER_TRACKED | H5O_HDR_ATTR_CRT_ORDER_INDEXED);
/* Update with new attribute creation order flags */
- ohdr_flags |= (crt_order_flags & H5P_CRT_ORDER_TRACKED) ? H5O_HDR_ATTR_CRT_ORDER_TRACKED : 0;
- ohdr_flags |= (crt_order_flags & H5P_CRT_ORDER_INDEXED) ? H5O_HDR_ATTR_CRT_ORDER_INDEXED : 0;
+ ohdr_flags |= (uint8_t)((crt_order_flags & H5P_CRT_ORDER_TRACKED) ? H5O_HDR_ATTR_CRT_ORDER_TRACKED : 0);
+ ohdr_flags |= (uint8_t)((crt_order_flags & H5P_CRT_ORDER_INDEXED) ? H5O_HDR_ATTR_CRT_ORDER_INDEXED : 0);
/* Set object header flags */
if(H5P_set(plist, H5O_CRT_OHDR_FLAGS_NAME, &ohdr_flags) < 0)
@@ -382,10 +487,10 @@ H5Pset_obj_track_times(hid_t plist_id, hbool_t track_times)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object header flags")
/* Mask off previous time tracking flag settings */
- ohdr_flags &= ~H5O_HDR_STORE_TIMES;
+ ohdr_flags &= (uint8_t)~H5O_HDR_STORE_TIMES;
/* Update with new time tracking flag */
- ohdr_flags |= track_times ? H5O_HDR_STORE_TIMES : 0;
+ ohdr_flags |= (uint8_t)(track_times ? H5O_HDR_STORE_TIMES : 0);
/* Set object header flags */
if(H5P_set(plist, H5O_CRT_OHDR_FLAGS_NAME, &ohdr_flags) < 0)
@@ -430,10 +535,1050 @@ H5Pget_obj_track_times(hid_t plist_id, hbool_t *track_times)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object header flags")
/* Set track times flag to return */
- *track_times = (ohdr_flags & H5O_HDR_STORE_TIMES) ? TRUE : FALSE;
+ *track_times = (hbool_t)((ohdr_flags & H5O_HDR_STORE_TIMES) ? TRUE : FALSE);
} /* end if */
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_obj_track_times() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_modify_filter
+ *
+ * Purpose: Modifies the specified FILTER in the
+ * transient or permanent output filter pipeline
+ * depending on whether PLIST is a dataset creation or dataset
+ * transfer property list. The FLAGS argument specifies certain
+ * general properties of the filter and is documented below.
+ * The CD_VALUES is an array of CD_NELMTS integers which are
+ * auxiliary data for the filter. The integer vlues will be
+ * stored in the dataset object header as part of the filter
+ * information.
+ *
+ * The FLAGS argument is a bit vector of the following fields:
+ *
+ * H5Z_FLAG_OPTIONAL(0x0001)
+ * If this bit is set then the filter is optional. If the
+ * filter fails during an H5Dwrite() operation then the filter
+ * is just excluded from the pipeline for the chunk for which it
+ * failed; the filter will not participate in the pipeline
+ * during an H5Dread() of the chunk. If this bit is clear and
+ * the filter fails then the entire I/O operation fails.
+ * If this bit is set but encoding is disabled for a filter,
+ * attempting to write will generate an error.
+ *
+ * Note: This function currently supports only the permanent filter
+ * pipeline. That is, PLIST_ID must be a dataset creation
+ * property list.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, October 17, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P_modify_filter(H5P_genplist_t *plist, H5Z_filter_t filter, unsigned flags,
+ size_t cd_nelmts, const unsigned cd_values[/*cd_nelmts*/])
+{
+ H5O_pline_t pline;
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_NOAPI(H5P_modify_filter, FAIL)
+
+ /* Get the pipeline property to modify */
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
+
+ /* Modify the filter parameters of the I/O pipeline */
+ if(H5Z_modify(&pline, filter, flags, cd_nelmts, cd_values) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add filter to pipeline")
+
+ /* Put the I/O pipeline information back into the property list */
+ if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_modify_filter() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pmodify_filter
+ *
+ * Purpose: Modifies the specified FILTER in the
+ * transient or permanent output filter pipeline
+ * depending on whether PLIST is a dataset creation or dataset
+ * transfer property list. The FLAGS argument specifies certain
+ * general properties of the filter and is documented below.
+ * The CD_VALUES is an array of CD_NELMTS integers which are
+ * auxiliary data for the filter. The integer vlues will be
+ * stored in the dataset object header as part of the filter
+ * information.
+ *
+ * The FLAGS argument is a bit vector of the following fields:
+ *
+ * H5Z_FLAG_OPTIONAL(0x0001)
+ * If this bit is set then the filter is optional. If the
+ * filter fails during an H5Dwrite() operation then the filter
+ * is just excluded from the pipeline for the chunk for which it
+ * failed; the filter will not participate in the pipeline
+ * during an H5Dread() of the chunk. If this bit is clear and
+ * the filter fails then the entire I/O operation fails.
+ * If this bit is set but encoding is disabled for a filter,
+ * attempting to write will generate an error.
+ *
+ * Note: This function currently supports only the permanent filter
+ * pipeline. That is, PLIST_ID must be a dataset creation
+ * property list.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, April 5, 2003
+ *
+ * Modifications:
+ *
+ * Neil Fortner
+ * Thursday, March 26, 2009
+ * Overloaded to accept gcpl's as well as dcpl's and moved to
+ * H5Pocpl.c
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags,
+ size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/])
+{
+ H5P_genplist_t *plist; /* Property list */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(H5Pmodify_filter, FAIL)
+ H5TRACE5("e", "iZfIuz*[a3]Iu", plist_id, filter, flags, cd_nelmts, cd_values);
+
+ /* Check args */
+ if (filter<0 || filter>H5Z_FILTER_MAX)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identifier")
+ if (flags & ~((unsigned)H5Z_FLAG_DEFMASK))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags")
+ if (cd_nelmts>0 && !cd_values)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no client data values supplied")
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+
+ /* Modify the filter parameters of the I/O pipeline */
+ if(H5P_modify_filter(plist, filter, flags, cd_nelmts, cd_values) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't modify filter")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pmodify_filter() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_filter
+ *
+ * Purpose: Adds the specified FILTER and corresponding properties to the
+ * end of the data or link output filter pipeline
+ * depending on whether PLIST is a dataset creation or group
+ * creation property list. The FLAGS argument specifies certain
+ * general properties of the filter and is documented below.
+ * The CD_VALUES is an array of CD_NELMTS integers which are
+ * auxiliary data for the filter. The integer vlues will be
+ * stored in the dataset object header as part of the filter
+ * information.
+ *
+ * The FLAGS argument is a bit vector of the following fields:
+ *
+ * H5Z_FLAG_OPTIONAL(0x0001)
+ * If this bit is set then the filter is optional. If the
+ * filter fails during an H5Dwrite() operation then the filter
+ * is just excluded from the pipeline for the chunk for which it
+ * failed; the filter will not participate in the pipeline
+ * during an H5Dread() of the chunk. If this bit is clear and
+ * the filter fails then the entire I/O operation fails.
+ * If this bit is set but encoding is disabled for a filter,
+ * attempting to write will generate an error.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, April 15, 1998
+ *
+ * Modifications:
+ *
+ * Raymond Lu
+ * Tuesday, October 2, 2001
+ * Changed the way to check parameter and set property for
+ * generic property list.
+ *
+ * Neil Fortner
+ * Wednesday, May 20, 2009
+ * Overloaded to accept gcpl's as well as dcpl's and moved to
+ * H5Pocpl.c
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags,
+ size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/])
+{
+ H5P_genplist_t *plist; /* Property list */
+ H5O_pline_t pline; /* Filter pipeline */
+ herr_t ret_value=SUCCEED; /* return value */
+
+ FUNC_ENTER_API(H5Pset_filter, FAIL)
+ H5TRACE5("e", "iZfIuz*[a3]Iu", plist_id, filter, flags, cd_nelmts, cd_values);
+
+ /* Check args */
+ if (filter<0 || filter>H5Z_FILTER_MAX)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identifier")
+ if (flags & ~((unsigned)H5Z_FLAG_DEFMASK))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags")
+ if (cd_nelmts>0 && !cd_values)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no client data values supplied")
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get the pipeline property to append to */
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
+
+ /* Add the filter to the I/O pipeline */
+ if(H5Z_append(&pline, filter, flags, cd_nelmts, cd_values) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add filter to pipeline")
+
+ /* Put the I/O pipeline information back into the property list */
+ if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_filter() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_nfilters
+ *
+ * Purpose: Returns the number of filters in the data or link
+ * pipeline depending on whether PLIST_ID is a dataset creation
+ * or group creation property list. In each pipeline the
+ * filters are numbered from zero through N-1 where N is the
+ * value returned by this function. During output to the file
+ * the filters of a pipeline are applied in increasing order
+ * (the inverse is true for input).
+ *
+ * Return: Success: Number of filters or zero if there are none.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, August 4, 1998
+ *
+ * Modifications:
+ *
+ * Neil Fortner
+ * Wednesday, May 20, 2009
+ * Overloaded to accept gcpl's as well as dcpl's and moved to
+ * H5Pocpl.c
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5Pget_nfilters(hid_t plist_id)
+{
+ H5P_genplist_t *plist; /* Property list */
+ H5O_pline_t pline; /* Filter pipeline */
+ int ret_value; /* return value */
+
+ FUNC_ENTER_API(H5Pget_nfilters, FAIL)
+ H5TRACE1("Is", "i", plist_id);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get the pipeline property to query */
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
+
+ /* Set return value */
+ ret_value=(int)(pline.nused);
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_nfilters */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_filter2
+ *
+ * Purpose: This is the query counterpart of H5Pset_filter() and returns
+ * information about a particular filter number in a permanent
+ * or transient pipeline depending on whether PLIST_ID is a
+ * dataset creation or transfer property list. On input,
+ * CD_NELMTS indicates the number of entries in the CD_VALUES
+ * array allocated by the caller while on exit it contains the
+ * number of values defined by the filter. FILTER_CONFIG is a bit
+ * field contaning encode/decode flags from H5Zpublic.h. The IDX
+ * should be a value between zero and N-1 as described for
+ * H5Pget_nfilters() and the function will return failure if the
+ * filter number is out of range.
+ *
+ * Return: Success: Filter identification number.
+ *
+ * Failure: H5Z_FILTER_ERROR (Negative)
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, April 15, 1998
+ *
+ * Modifications:
+ *
+ * Neil Fortner
+ * Wednesday, May 20, 2009
+ * Overloaded to accept gcpl's as well as dcpl's and moved to
+ * H5Pocpl.c
+ *
+ *-------------------------------------------------------------------------
+ */
+H5Z_filter_t
+H5Pget_filter2(hid_t plist_id, unsigned idx, unsigned int *flags/*out*/,
+ size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/,
+ size_t namelen, char name[]/*out*/,
+ unsigned *filter_config /*out*/)
+{
+ H5P_genplist_t *plist; /* Property list */
+ H5O_pline_t pline; /* Filter pipeline */
+ const H5Z_filter_info_t *filter; /* Pointer to filter information */
+ H5Z_filter_t ret_value; /* return value */
+
+ FUNC_ENTER_API(H5Pget_filter2, H5Z_FILTER_ERROR)
+ H5TRACE8("Zf", "iIux*zxzxx", plist_id, idx, flags, cd_nelmts, cd_values,
+ namelen, name, filter_config);
+
+ /* Check args */
+ if(cd_nelmts || cd_values) {
+ /*
+ * It's likely that users forget to initialize this on input, so
+ * we'll check that it has a reasonable value. The actual number
+ * is unimportant because the H5O layer will detect when a message
+ * is too large.
+ */
+ if(cd_nelmts && *cd_nelmts > 256)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "probable uninitialized *cd_nelmts argument")
+ if(cd_nelmts && *cd_nelmts > 0 && !cd_values)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "client data values not supplied")
+
+ /*
+ * If cd_nelmts is null but cd_values is non-null then just ignore
+ * cd_values
+ */
+ if(!cd_nelmts)
+ cd_values = NULL;
+ } /* end if */
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5Z_FILTER_ERROR, "can't find object for ID")
+
+ /* Get the pipeline property to query */
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline")
+
+ /* Check index */
+ if(idx >= pline.nused)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "filter number is invalid")
+
+ /* Set pointer to particular filter to query */
+ filter = &pline.filter[idx];
+
+ /* Get filter information */
+ if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info")
+
+ /* Set return value */
+ ret_value = filter->id;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_filter2() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_get_filter_by_id
+ *
+ * Purpose: This is an additional query counterpart of H5Pset_filter() and
+ * returns information about a particular filter in a permanent
+ * or transient pipeline depending on whether PLIST_ID is a
+ * dataset creation or transfer property list. On input,
+ * CD_NELMTS indicates the number of entries in the CD_VALUES
+ * array allocated by the caller while on exit it contains the
+ * number of values defined by the filter. FILTER_CONFIG is a bit
+ * field contaning encode/decode flags from H5Zpublic.h. The ID
+ * should be the filter ID to retrieve the parameters for. If the
+ * filter is not set for the property list, an error will be returned.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, October 17, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id, unsigned int *flags/*out*/,
+ size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/,
+ size_t namelen, char name[]/*out*/, unsigned *filter_config)
+{
+ H5O_pline_t pline; /* Filter pipeline */
+ H5Z_filter_info_t *filter; /* Pointer to filter information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5P_get_filter_by_id, FAIL)
+
+ /* Get pipeline info */
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
+
+ /* Get pointer to filter in pipeline */
+ if(NULL == (filter = H5Z_filter_info(&pline, id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filter ID is invalid")
+
+ /* Get filter information */
+ if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_get_filter_by_id() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_filter_by_id2
+ *
+ * Purpose: This is an additional query counterpart of H5Pset_filter() and
+ * returns information about a particular filter in a permanent
+ * or transient pipeline depending on whether PLIST_ID is a
+ * dataset creation or transfer property list. On input,
+ * CD_NELMTS indicates the number of entries in the CD_VALUES
+ * array allocated by the caller while on exit it contains the
+ * number of values defined by the filter. FILTER_CONFIG is a bit
+ * field contaning encode/decode flags from H5Zpublic.h. The ID
+ * should be the filter ID to retrieve the parameters for. If the
+ * filter is not set for the property list, an error will be returned.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, April 5, 2003
+ *
+ * Modifications:
+ *
+ * Neil Fortner
+ * Thursday, May 21, 2009
+ * Overloaded to accept gcpl's as well as dcpl's and moved to
+ * H5Pocpl.c
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/,
+ size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/,
+ size_t namelen, char name[]/*out*/, unsigned *filter_config)
+{
+ H5P_genplist_t *plist; /* Property list */
+ H5O_pline_t pline; /* Filter pipeline */
+ const H5Z_filter_info_t *filter; /* Pointer to filter information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Pget_filter_by_id2, FAIL)
+ H5TRACE8("e", "iZfx*zxzx*Iu", plist_id, id, flags, cd_nelmts, cd_values,
+ namelen, name, filter_config);
+
+ /* Check args */
+ if(cd_nelmts || cd_values) {
+ /*
+ * It's likely that users forget to initialize this on input, so
+ * we'll check that it has a reasonable value. The actual number
+ * is unimportant because the H5O layer will detect when a message
+ * is too large.
+ */
+ if(cd_nelmts && *cd_nelmts > 256)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "probable uninitialized *cd_nelmts argument")
+ if(cd_nelmts && *cd_nelmts > 0 && !cd_values)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "client data values not supplied")
+
+ /*
+ * If cd_nelmts is null but cd_values is non-null then just ignore
+ * cd_values
+ */
+ if(!cd_nelmts)
+ cd_values = NULL;
+ } /* end if */
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get the pipeline property to query */
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
+
+ /* Get pointer to filter in pipeline */
+ if(NULL == (filter = H5Z_filter_info(&pline, id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filter ID is invalid")
+
+ /* Get filter information */
+ if(H5P_get_filter_by_id(plist, id, flags, cd_nelmts, cd_values, namelen,
+ name, filter_config) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_filter_by_id2() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pall_filters_avail
+ *
+ * Purpose: This is a query routine to verify that all the filters set
+ * in the dataset creation property list are available currently.
+ *
+ * Return: Success: TRUE if all filters available, FALSE if one or
+ * more filters not currently available.
+ * Failure: FAIL on error
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, April 8, 2003
+ *
+ * Modifications:
+ *
+ * Neil Fortner
+ * Thursday, May 21, 2009
+ * Overloaded to accept gcpl's as well as dcpl's and moved to
+ * H5Pocpl.c
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5Pall_filters_avail(hid_t plist_id)
+{
+ H5P_genplist_t *plist; /* Property list */
+ H5O_pline_t pline; /* Filter pipeline */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Pall_filters_avail, FAIL)
+ H5TRACE1("t", "i", plist_id);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get the pipeline property to query */
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
+
+ /* Check if all filters are available */
+ if((ret_value = H5Z_all_filters_avail(&pline)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "can't check pipeline information")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pall_filters_avail() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Premove_filter
+ *
+ * Purpose: Deletes a filter from the dataset creation property list;
+ * deletes all filters if FILTER is H5Z_FILTER_NONE
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Pedro Vicente
+ * January 26, 2004
+ *
+ * Modifications:
+ *
+ * Neil Fortner
+ * Thursday, May 21, 2009
+ * Overloaded to accept gcpl's as well as dcpl's and moved to
+ * H5Pocpl.c
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Premove_filter(hid_t plist_id, H5Z_filter_t filter)
+{
+ H5P_genplist_t *plist; /* Property list */
+ H5O_pline_t pline; /* Filter pipeline */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(H5Premove_filter, FAIL)
+ H5TRACE2("e", "iZf", plist_id, filter);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get the pipeline property to modify */
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
+
+ /* Check if there are any filters */
+ if (pline.filter) {
+ /* Delete filter */
+ if(H5Z_delete(&pline, filter) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't delete filter")
+
+ /* Put the I/O pipeline information back into the property list */
+ if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Premove_filter() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_deflate
+ *
+ * Purpose: Sets the compression method for a dataset or group link
+ * filter pipeline (depending on whether PLIST_ID is a dataset
+ * creation or group creation property list) to H5Z_FILTER_DEFLATE
+ * and the compression level to LEVEL which should be a value
+ * between zero and nine, inclusive. Lower compression levels
+ * are faster but result in less compression. This is the same
+ * algorithm as used by the GNU gzip program.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, April 15, 1998
+ *
+ * Modifications:
+ *
+ * Raymond Lu
+ * Tuesday, October 2, 2001
+ * Changed the way to check parameter and set property for
+ * generic property list.
+ *
+ * Neil Fortner
+ * Thursday, March 26, 2009
+ * Overloaded to accept gcpl's as well as dcpl's and moved to
+ * H5Pocpl.c
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_deflate(hid_t plist_id, unsigned level)
+{
+ H5P_genplist_t *plist; /* Property list */
+ H5O_pline_t pline; /* Filter pipeline */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(H5Pset_deflate, FAIL)
+ H5TRACE2("e", "iIu", plist_id, level);
+
+ /* Check arguments */
+ if(level > 9)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid deflate level")
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get the pipeline property to append to */
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
+
+ /* Add the filter */
+ if(H5Z_append(&pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &level) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add deflate filter to pipeline")
+
+ /* Put the I/O pipeline information back into the property list */
+ if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_deflate() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_fletcher32
+ *
+ * Purpose: Sets Fletcher32 checksum of EDC for a dataset creation
+ * property list or group creation property list.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Dec 19, 2002
+ *
+ * Modifications:
+ *
+ * Neil Fortner
+ * Wednesday, May 6, 2009
+ * Overloaded to accept gcpl's as well as dcpl's and moved to
+ * H5Pocpl.c
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_fletcher32(hid_t plist_id)
+{
+ H5P_genplist_t *plist; /* Property list */
+ H5O_pline_t pline; /* Filter pipeline */
+ herr_t ret_value=SUCCEED; /* return value */
+
+ FUNC_ENTER_API(H5Pset_fletcher32, FAIL)
+ H5TRACE1("e", "i", plist_id);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get the pipeline property to append to */
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
+
+ /* Add the Fletcher32 checksum as a filter */
+ if(H5Z_append(&pline, H5Z_FILTER_FLETCHER32, H5Z_FLAG_MANDATORY, (size_t)0, NULL) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add fletcher32 filter to pipeline")
+
+ /* Put the I/O pipeline information back into the property list */
+ if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_fletcher32() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_get_filter
+ *
+ * Purpose: Internal component of H5Pget_filter & H5Pget_filter_id
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, October 23, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P_get_filter(const H5Z_filter_info_t *filter, unsigned int *flags/*out*/,
+ size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/,
+ size_t namelen, char name[]/*out*/,
+ unsigned *filter_config /*out*/)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_filter)
+
+ /* Check arguments */
+ HDassert(filter);
+
+ /* Filter flags */
+ if(flags)
+ *flags = filter->flags;
+
+ /* Filter parameters */
+ if(cd_values) {
+ size_t i; /* Local index variable */
+
+ for(i = 0; i < filter->cd_nelmts && i < *cd_nelmts; i++)
+ cd_values[i] = filter->cd_values[i];
+ } /* end if */
+
+ /* Number of filter parameters */
+ if(cd_nelmts)
+ *cd_nelmts = filter->cd_nelmts;
+
+ /* Filter name */
+ if(namelen > 0 && name) {
+ const char *s = filter->name;
+
+ /* If there's no name on the filter, use the class's filter name */
+ if(!s) {
+ H5Z_class2_t *cls = H5Z_find(filter->id);
+
+ if(cls)
+ s = cls->name;
+ } /* end if */
+
+ /* Check for actual name */
+ if(s) {
+ HDstrncpy(name, s, namelen);
+ name[namelen - 1] = '\0';
+ } /* end if */
+ else {
+ /* Check for unknown library filter */
+ /* (probably from a future version of the library) */
+ if(filter->id < 256) {
+ HDstrncpy(name, "Unknown library filter", namelen);
+ name[namelen - 1] = '\0';
+ } /* end if */
+ else
+ name[0] = '\0';
+ } /* end if */
+ } /* end if */
+
+ /* Filter configuration (assume filter ID has already been checked) */
+ if(filter_config)
+ H5Zget_filter_info(filter->id, filter_config);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5P_get_filter() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_ocrt_pipeline_cmp
+ *
+ * Purpose: Callback routine which is called whenever a filter pipeline
+ * property in a property list is compared.
+ *
+ * Return: positive if VALUE1 is greater than VALUE2, negative if
+ * VALUE2 is greater than VALUE1 and zero if VALUE1 and
+ * VALUE2 are equal.
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, January 7, 2004
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5P_ocrt_pipeline_cmp(const void *_pline1, const void *_pline2, size_t UNUSED size)
+{
+ const H5O_pline_t *pline1 = (const H5O_pline_t *)_pline1, /* Create local aliases for values */
+ *pline2 = (const H5O_pline_t *)_pline2;
+ int cmp_value; /* Value from comparison */
+ herr_t ret_value = 0; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOFUNC(H5P_ocrt_pipeline_cmp)
+
+ /* Sanity check */
+ HDassert(pline1);
+ HDassert(pline2);
+ HDassert(size == sizeof(H5O_pline_t));
+
+ /* Check the number of allocated pipeline entries */
+ if(pline1->nalloc < pline2->nalloc) HGOTO_DONE(-1);
+ if(pline1->nalloc > pline2->nalloc) HGOTO_DONE(1);
+
+ /* Check the number of used pipeline entries */
+ if(pline1->nused < pline2->nused) HGOTO_DONE(-1);
+ if(pline1->nused > pline2->nused) HGOTO_DONE(1);
+
+ /* Check the filter entry information */
+ if(pline1->filter == NULL && pline2->filter != NULL) HGOTO_DONE(-1);
+ if(pline1->filter != NULL && pline2->filter == NULL) HGOTO_DONE(1);
+ if(pline1->filter != NULL && pline1->nused > 0) {
+ size_t u; /* Local index variable */
+
+ /* Loop through all filters, comparing them */
+ for(u = 0; u < pline1->nused; u++) {
+ /* Check the ID of the filter */
+ if(pline1->filter[u].id < pline2->filter[u].id) HGOTO_DONE(-1);
+ if(pline1->filter[u].id > pline2->filter[u].id) HGOTO_DONE(1);
+
+ /* Check the flags for the filter */
+ if(pline1->filter[u].flags < pline2->filter[u].flags) HGOTO_DONE(-1);
+ if(pline1->filter[u].flags > pline2->filter[u].flags) HGOTO_DONE(1);
+
+ /* Check the name of the filter */
+ if(pline1->filter[u].name == NULL && pline2->filter[u].name != NULL) HGOTO_DONE(-1);
+ if(pline1->filter[u].name != NULL && pline2->filter[u].name == NULL) HGOTO_DONE(1);
+ if(pline1->filter[u].name != NULL)
+ if((cmp_value = HDstrcmp(pline1->filter[u].name, pline2->filter[u].name)) != 0)
+ HGOTO_DONE(cmp_value);
+
+ /* Check the number of parameters for the filter */
+ if(pline1->filter[u].cd_nelmts < pline2->filter[u].cd_nelmts) HGOTO_DONE(-1);
+ if(pline1->filter[u].cd_nelmts > pline2->filter[u].cd_nelmts) HGOTO_DONE(1);
+
+ /* Check the filter parameter information */
+ if(pline1->filter[u].cd_values == NULL && pline2->filter[u].cd_values != NULL) HGOTO_DONE(-1);
+ if(pline1->filter[u].cd_values != NULL && pline2->filter[u].cd_values == NULL) HGOTO_DONE(1);
+ if(pline1->filter[u].cd_values != NULL && pline1->filter[u].cd_nelmts > 0) {
+ size_t v; /* Local index variable */
+
+ /* Loop through all parameters, comparing them */
+ for(v = 0; v < pline1->filter[u].cd_nelmts; v++) {
+ /* Check each parameter for the filter */
+ if(pline1->filter[u].cd_values[v] < pline2->filter[u].cd_values[v]) HGOTO_DONE(-1);
+ if(pline1->filter[u].cd_values[v] > pline2->filter[u].cd_values[v]) HGOTO_DONE(1);
+ } /* end for */
+ } /* end if */
+ } /* end for */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_ocrt_pipeline_cmp() */
+
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_filter1
+ *
+ * Purpose: This is the query counterpart of H5Pset_filter() and returns
+ * information about a particular filter number in a permanent
+ * or transient pipeline depending on whether PLIST_ID is a
+ * dataset creation or transfer property list. On input,
+ * CD_NELMTS indicates the number of entries in the CD_VALUES
+ * array allocated by the caller while on exit it contains the
+ * number of values defined by the filter. The IDX
+ * should be a value between zero and N-1 as described for
+ * H5Pget_nfilters() and the function will return failure if the
+ * filter number is out of range.
+ *
+ * Return: Success: Filter identification number.
+ *
+ * Failure: H5Z_FILTER_ERROR (Negative)
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, April 15, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+H5Z_filter_t
+H5Pget_filter1(hid_t plist_id, unsigned idx, unsigned int *flags/*out*/,
+ size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/,
+ size_t namelen, char name[]/*out*/)
+{
+ H5O_pline_t pline; /* Filter pipeline */
+ const H5Z_filter_info_t *filter; /* Pointer to filter information */
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5Z_filter_t ret_value; /* return value */
+
+ FUNC_ENTER_API(H5Pget_filter1, H5Z_FILTER_ERROR)
+ H5TRACE7("Zf", "iIux*zxzx", plist_id, idx, flags, cd_nelmts, cd_values, namelen,
+ name);
+
+ /* Check args */
+ if(cd_nelmts || cd_values) {
+ /*
+ * It's likely that users forget to initialize this on input, so
+ * we'll check that it has a reasonable value. The actual number
+ * is unimportant because the H5O layer will detect when a message
+ * is too large.
+ */
+ if(cd_nelmts && *cd_nelmts > 256)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "probable uninitialized *cd_nelmts argument")
+ if(cd_nelmts && *cd_nelmts > 0 && !cd_values)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "client data values not supplied")
+
+ /*
+ * If cd_nelmts is null but cd_values is non-null then just ignore
+ * cd_values
+ */
+ if(!cd_nelmts)
+ cd_values = NULL;
+ } /* end if */
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5Z_FILTER_ERROR, "can't find object for ID")
+
+ /* Get pipeline info */
+ if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline")
+
+ /* Check more args */
+ if(idx >= pline.nused)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "filter number is invalid")
+
+ /* Set pointer to particular filter to query */
+ filter = &pline.filter[idx];
+
+ /* Get filter information */
+ if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info")
+
+ /* Set return value */
+ ret_value = filter->id;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_filter1() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_filter_by_id1
+ *
+ * Purpose: This is an additional query counterpart of H5Pset_filter() and
+ * returns information about a particular filter in a permanent
+ * or transient pipeline depending on whether PLIST_ID is a
+ * dataset creation or transfer property list. On input,
+ * CD_NELMTS indicates the number of entries in the CD_VALUES
+ * array allocated by the caller while on exit it contains the
+ * number of values defined by the filter. The ID
+ * should be the filter ID to retrieve the parameters for. If the
+ * filter is not set for the property list, an error will be returned.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, April 5, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_filter_by_id1(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/,
+ size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/,
+ size_t namelen, char name[]/*out*/)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Pget_filter_by_id1, FAIL)
+ H5TRACE7("e", "iZfx*zxzx", plist_id, id, flags, cd_nelmts, cd_values, namelen,
+ name);
+
+ /* Check args */
+ if(cd_nelmts || cd_values) {
+ /*
+ * It's likely that users forget to initialize this on input, so
+ * we'll check that it has a reasonable value. The actual number
+ * is unimportant because the H5O layer will detect when a message
+ * is too large.
+ */
+ if(cd_nelmts && *cd_nelmts > 256)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "probable uninitialized *cd_nelmts argument")
+ if(cd_nelmts && *cd_nelmts > 0 && !cd_values)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "client data values not supplied")
+
+ /*
+ * If cd_nelmts is null but cd_values is non-null then just ignore
+ * cd_values
+ */
+ if(!cd_nelmts)
+ cd_values = NULL;
+ } /* end if */
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get filter info */
+ if(H5P_get_filter_by_id(plist, id, flags, cd_nelmts, cd_values, namelen, name, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_filter_by_id1() */
+
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
+
diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h
index 2959ddc..fd9c65a 100644
--- a/src/H5Ppkg.h
+++ b/src/H5Ppkg.h
@@ -178,6 +178,9 @@ H5_DLL char *H5P_get_class_path(H5P_genclass_t *pclass);
H5_DLL H5P_genclass_t *H5P_open_class_path(const char *path);
H5_DLL H5P_genclass_t *H5P_get_class_parent(const H5P_genclass_t *pclass);
H5_DLL herr_t H5P_close_class(void *_pclass);
+H5_DLL herr_t H5P_get_filter(const H5Z_filter_info_t *filter,
+ unsigned int *flags, size_t *cd_nelmts, unsigned cd_values[],
+ size_t namelen, char name[], unsigned *filter_config);
/* Testing functions */
#ifdef H5P_TESTING
diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h
index adb57c1..f544dbc 100644
--- a/src/H5Pprivate.h
+++ b/src/H5Pprivate.h
@@ -57,8 +57,8 @@ H5_DLL herr_t H5P_init(void);
/* Internal versions of API routines */
H5_DLL herr_t H5P_close(void *_plist);
-H5_DLL hid_t H5P_create_id(H5P_genclass_t *pclass);
-H5_DLL hid_t H5P_copy_plist(H5P_genplist_t *old_plist);
+H5_DLL hid_t H5P_create_id(H5P_genclass_t *pclass, hbool_t app_ref);
+H5_DLL hid_t H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref);
H5_DLL herr_t H5P_get(const H5P_genplist_t *plist, const char *name, void *value);
H5_DLL herr_t H5P_set(H5P_genplist_t *plist, const char *name, const void *value);
H5_DLL herr_t H5P_insert(H5P_genplist_t *plist, const char *name, size_t size,
@@ -86,10 +86,15 @@ H5_DLL herr_t H5P_is_fill_value_defined(const H5O_fill_t *fill,
H5D_fill_value_t *status);
H5_DLL int H5P_fill_value_cmp(const void *value1, const void *value2,
size_t size);
+H5_DLL herr_t H5P_modify_filter(H5P_genplist_t *plist, H5Z_filter_t filter,
+ unsigned flags, size_t cd_nelmts, const unsigned cd_values[]);
+H5_DLL herr_t H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id,
+ unsigned int *flags, size_t *cd_nelmts, unsigned cd_values[],
+ size_t namelen, char name[], unsigned *filter_config);
/* *SPECIAL* Don't make more of these! -QAK */
H5_DLL htri_t H5P_isa_class(hid_t plist_id, hid_t pclass_id);
-H5_DLL void *H5P_object_verify(hid_t plist_id, hid_t pclass_id);
+H5_DLL H5P_genplist_t *H5P_object_verify(hid_t plist_id, hid_t pclass_id);
/* Private functions to "peek" at properties of a certain type */
H5_DLL unsigned H5P_peek_unsigned(H5P_genplist_t *plist, const char *name);
@@ -98,12 +103,6 @@ H5_DLL void *H5P_peek_voidp(H5P_genplist_t *plist, const char *name);
H5_DLL size_t H5P_peek_size_t(H5P_genplist_t *plist, const char *name);
/* Private DCPL routines */
-H5_DLL herr_t H5P_modify_filter(H5P_genplist_t *plist, H5Z_filter_t filter,
- unsigned flags, size_t cd_nelmts, const unsigned cd_values[/*cd_nelmts*/]);
-H5_DLL herr_t H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id,
- unsigned int *flags/*out*/, size_t *cd_nelmts/*in_out*/,
- unsigned cd_values[]/*out*/, size_t namelen, char name[]/*out*/,
- unsigned *filter_config);
H5_DLL herr_t H5P_fill_value_defined(H5P_genplist_t *plist,
H5D_fill_value_t *status);
H5_DLL herr_t H5P_get_fill_value(H5P_genplist_t *plist, const H5T_t *type,
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index c5b4b8b..1c0bb61 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -29,6 +29,7 @@
#include "H5Fpublic.h"
#include "H5FDpublic.h"
#include "H5Ipublic.h"
+#include "H5Lpublic.h"
#include "H5MMpublic.h"
#include "H5Tpublic.h"
#include "H5Zpublic.h"
@@ -46,9 +47,6 @@
#define H5OPEN
#endif /* _H5private_H */
-/* Default value for all property list classes */
-#define H5P_DEFAULT 0
-
/*
* The library's property list classes
*/
@@ -208,11 +206,29 @@ H5_DLL herr_t H5Pset_attr_creation_order(hid_t plist_id, unsigned crt_order_flag
H5_DLL herr_t H5Pget_attr_creation_order(hid_t plist_id, unsigned *crt_order_flags);
H5_DLL herr_t H5Pset_obj_track_times(hid_t plist_id, hbool_t track_times);
H5_DLL herr_t H5Pget_obj_track_times(hid_t plist_id, hbool_t *track_times);
+H5_DLL herr_t H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter,
+ unsigned int flags, size_t cd_nelmts,
+ const unsigned int cd_values[/*cd_nelmts*/]);
+H5_DLL herr_t H5Pset_filter(hid_t plist_id, H5Z_filter_t filter,
+ unsigned int flags, size_t cd_nelmts,
+ const unsigned int c_values[]);
+H5_DLL int H5Pget_nfilters(hid_t plist_id);
+H5_DLL H5Z_filter_t H5Pget_filter2(hid_t plist_id, unsigned filter,
+ unsigned int *flags/*out*/,
+ size_t *cd_nelmts/*out*/,
+ unsigned cd_values[]/*out*/,
+ size_t namelen, char name[],
+ unsigned *filter_config /*out*/);
+H5_DLL herr_t H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id,
+ unsigned int *flags/*out*/, size_t *cd_nelmts/*out*/,
+ unsigned cd_values[]/*out*/, size_t namelen, char name[]/*out*/,
+ unsigned *filter_config/*out*/);
+H5_DLL htri_t H5Pall_filters_avail(hid_t plist_id);
+H5_DLL herr_t H5Premove_filter(hid_t plist_id, H5Z_filter_t filter);
+H5_DLL herr_t H5Pset_deflate(hid_t plist_id, unsigned aggression);
+H5_DLL herr_t H5Pset_fletcher32(hid_t plist_id);
/* File creation property list (FCPL) routines */
-H5_DLL herr_t H5Pget_version(hid_t plist_id, unsigned *boot/*out*/,
- unsigned *freelist/*out*/, unsigned *stab/*out*/,
- unsigned *shhdr/*out*/);
H5_DLL herr_t H5Pset_userblock(hid_t plist_id, hsize_t size);
H5_DLL herr_t H5Pget_userblock(hid_t plist_id, hsize_t *size);
H5_DLL herr_t H5Pset_sizes(hid_t plist_id, size_t sizeof_addr,
@@ -229,6 +245,8 @@ H5_DLL herr_t H5Pset_shared_mesg_index(hid_t plist_id, unsigned index_num, unsig
H5_DLL herr_t H5Pget_shared_mesg_index(hid_t plist_id, unsigned index_num, unsigned *mesg_type_flags, unsigned *min_mesg_size);
H5_DLL herr_t H5Pset_shared_mesg_phase_change(hid_t plist_id, unsigned max_list, unsigned min_btree);
H5_DLL herr_t H5Pget_shared_mesg_phase_change(hid_t plist_id, unsigned *max_list, unsigned *min_btree);
+H5_DLL herr_t H5Pset_file_space(hid_t plist_id, H5F_file_space_type_t strategy, hsize_t threshold);
+H5_DLL herr_t H5Pget_file_space(hid_t plist_id, H5F_file_space_type_t *strategy, hsize_t *threshold);
/* File access property list (FAPL) routines */
@@ -245,11 +263,11 @@ H5_DLL herr_t H5Pget_family_offset(hid_t fapl_id, hsize_t *offset);
H5_DLL herr_t H5Pset_multi_type(hid_t fapl_id, H5FD_mem_t type);
H5_DLL herr_t H5Pget_multi_type(hid_t fapl_id, H5FD_mem_t *type);
H5_DLL herr_t H5Pset_cache(hid_t plist_id, int mdc_nelmts,
- size_t rdcc_nelmts, size_t rdcc_nbytes,
+ size_t rdcc_nslots, size_t rdcc_nbytes,
double rdcc_w0);
H5_DLL herr_t H5Pget_cache(hid_t plist_id,
int *mdc_nelmts, /* out */
- size_t *rdcc_nelmts/*out*/,
+ size_t *rdcc_nslots/*out*/,
size_t *rdcc_nbytes/*out*/, double *rdcc_w0);
H5_DLL herr_t H5Pset_mdc_config(hid_t plist_id,
H5AC_cache_config_t * config_ptr);
@@ -281,31 +299,10 @@ H5_DLL int H5Pget_external_count(hid_t plist_id);
H5_DLL herr_t H5Pget_external(hid_t plist_id, unsigned idx, size_t name_size,
char *name/*out*/, off_t *offset/*out*/,
hsize_t *size/*out*/);
-H5_DLL herr_t H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter,
- unsigned int flags, size_t cd_nelmts,
- const unsigned int cd_values[/*cd_nelmts*/]);
-H5_DLL herr_t H5Pset_filter(hid_t plist_id, H5Z_filter_t filter,
- unsigned int flags, size_t cd_nelmts,
- const unsigned int c_values[]);
-H5_DLL int H5Pget_nfilters(hid_t plist_id);
-H5_DLL H5Z_filter_t H5Pget_filter2(hid_t plist_id, unsigned filter,
- unsigned int *flags/*out*/,
- size_t *cd_nelmts/*out*/,
- unsigned cd_values[]/*out*/,
- size_t namelen, char name[],
- unsigned *filter_config /*out*/);
-H5_DLL H5Z_filter_t H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id,
- unsigned int *flags/*out*/, size_t *cd_nelmts/*out*/,
- unsigned cd_values[]/*out*/, size_t namelen, char name[]/*out*/,
- unsigned *filter_config/*out*/);
-H5_DLL htri_t H5Pall_filters_avail(hid_t plist_id);
-H5_DLL herr_t H5Premove_filter(hid_t plist_id, H5Z_filter_t filter);
-H5_DLL herr_t H5Pset_deflate(hid_t plist_id, unsigned aggression);
H5_DLL herr_t H5Pset_szip(hid_t plist_id, unsigned options_mask, unsigned pixels_per_block);
H5_DLL herr_t H5Pset_shuffle(hid_t plist_id);
H5_DLL herr_t H5Pset_nbit(hid_t plist_id);
H5_DLL herr_t H5Pset_scaleoffset(hid_t plist_id, H5Z_SO_scale_type_t scale_type, int scale_factor);
-H5_DLL herr_t H5Pset_fletcher32(hid_t plist_id);
H5_DLL herr_t H5Pset_fill_value(hid_t plist_id, hid_t type_id,
const void *value);
H5_DLL herr_t H5Pget_fill_value(hid_t plist_id, hid_t type_id,
@@ -319,6 +316,14 @@ H5_DLL herr_t H5Pset_fill_time(hid_t plist_id, H5D_fill_time_t fill_time);
H5_DLL herr_t H5Pget_fill_time(hid_t plist_id, H5D_fill_time_t
*fill_time/*out*/);
+/* Dataset access property list (DAPL) routines */
+H5_DLL herr_t H5Pset_chunk_cache(hid_t dapl_id, size_t rdcc_nslots,
+ size_t rdcc_nbytes, double rdcc_w0);
+H5_DLL herr_t H5Pget_chunk_cache(hid_t dapl_id,
+ size_t *rdcc_nslots/*out*/,
+ size_t *rdcc_nbytes/*out*/,
+ double *rdcc_w0/*out*/);
+
/* Dataset xfer property list (DXPL) routines */
H5_DLL herr_t H5Pset_data_transform(hid_t plist_id, const char* expression);
H5_DLL ssize_t H5Pget_data_transform(hid_t plist_id, char* expression /*out*/, size_t size);
@@ -374,13 +379,19 @@ H5_DLL herr_t H5Pset_nlinks(hid_t plist_id, size_t nlinks);
H5_DLL herr_t H5Pget_nlinks(hid_t plist_id, size_t *nlinks);
H5_DLL herr_t H5Pset_elink_prefix(hid_t plist_id, const char *prefix);
H5_DLL ssize_t H5Pget_elink_prefix(hid_t plist_id, char *prefix, size_t size);
+H5_DLL hid_t H5Pget_elink_fapl(hid_t lapl_id);
+H5_DLL herr_t H5Pset_elink_fapl(hid_t lapl_id, hid_t fapl_id);
+H5_DLL herr_t H5Pset_elink_acc_flags(hid_t lapl_id, unsigned flags);
+H5_DLL herr_t H5Pget_elink_acc_flags(hid_t lapl_id, unsigned *flags);
+H5_DLL herr_t H5Pset_elink_cb(hid_t lapl_id, H5L_elink_traverse_t func, void *op_data);
+H5_DLL herr_t H5Pget_elink_cb(hid_t lapl_id, H5L_elink_traverse_t *func, void **op_data);
/* Object copy property list (OCPYPL) routines */
H5_DLL herr_t H5Pset_copy_object(hid_t plist_id, unsigned crt_intmd);
H5_DLL herr_t H5Pget_copy_object(hid_t plist_id, unsigned *crt_intmd /*out*/);
/* Symbols defined for compatibility with previous versions of the HDF5 API.
- *
+ *
* Use of these symbols is deprecated.
*/
#ifndef H5_NO_DEPRECATED_SYMBOLS
@@ -407,10 +418,12 @@ H5_DLL herr_t H5Pinsert1(hid_t plist_id, const char *name, size_t size,
H5_DLL H5Z_filter_t H5Pget_filter1(hid_t plist_id, unsigned filter,
unsigned int *flags/*out*/, size_t *cd_nelmts/*out*/,
unsigned cd_values[]/*out*/, size_t namelen, char name[]);
-H5_DLL H5Z_filter_t H5Pget_filter_by_id1(hid_t plist_id, H5Z_filter_t id,
+H5_DLL herr_t H5Pget_filter_by_id1(hid_t plist_id, H5Z_filter_t id,
unsigned int *flags/*out*/, size_t *cd_nelmts/*out*/,
unsigned cd_values[]/*out*/, size_t namelen, char name[]/*out*/);
-
+H5_DLL herr_t H5Pget_version(hid_t plist_id, unsigned *boot/*out*/,
+ unsigned *freelist/*out*/, unsigned *stab/*out*/,
+ unsigned *shhdr/*out*/);
#endif /* H5_NO_DEPRECATED_SYMBOLS */
#ifdef __cplusplus
diff --git a/src/H5Ptest.c b/src/H5Ptest.c
index 4a3bca5..575d6d3 100644
--- a/src/H5Ptest.c
+++ b/src/H5Ptest.c
@@ -63,18 +63,18 @@ H5P_get_class_path_test(hid_t pclass_id)
H5P_genclass_t *pclass; /* Property class to query */
char *ret_value; /* return value */
- FUNC_ENTER_NOAPI(H5P_get_class_path_test, NULL);
+ FUNC_ENTER_NOAPI(H5P_get_class_path_test, NULL)
/* Check arguments. */
- if (NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
+ if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property class");
/* Get the property list class path */
- if ((ret_value=H5P_get_class_path(pclass))==NULL)
- HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "unable to query full path of class");
+ if(NULL == (ret_value = H5P_get_class_path(pclass)))
+ HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "unable to query full path of class")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5P_get_class_path_test() */
@@ -115,7 +115,7 @@ H5P_open_class_path_test(const char *path)
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to find class with full path");
/* Get an atom for the class */
- if ((ret_value=H5I_register(H5I_GENPROP_CLS, pclass))<0)
+ if ((ret_value=H5I_register(H5I_GENPROP_CLS, pclass, TRUE))<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class");
done:
@@ -149,13 +149,13 @@ H5P_reset_external_file_test(hid_t dcpl_id)
H5P_genplist_t *plist; /* Property list */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5P_reset_external_file_test, FAIL);
+ FUNC_ENTER_NOAPI(H5P_reset_external_file_test, FAIL)
/* Check arguments */
- if(NULL == (plist = H5I_object(dcpl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list")
-
- /* get external file list */
+
+ /* get external file list */
if(H5P_get(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list")
@@ -163,11 +163,11 @@ H5P_reset_external_file_test(hid_t dcpl_id)
if(H5O_msg_reset(H5O_EFL_ID, &efl) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't release external file list info")
- /* set external file list */
+ /* set external file list */
if(H5P_set(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5P_reset_external_file_test() */
diff --git a/src/H5R.c b/src/H5R.c
index ae8720e..933f983 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -37,7 +37,8 @@
/* Static functions */
static herr_t H5R_create(void *ref, H5G_loc_t *loc, const char *name,
H5R_type_t ref_type, H5S_t *space, hid_t dxpl_id);
-static hid_t H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref);
+static hid_t H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type,
+ const void *_ref, hbool_t app_ref);
static H5S_t * H5R_get_region(H5F_t *file, hid_t dxpl_id, const void *_ref);
static ssize_t H5R_get_name(H5F_t *file, hid_t lapl_id, hid_t dxpl_id, hid_t id,
H5R_type_t ref_type, const void *_ref, char *name, size_t size);
@@ -123,7 +124,7 @@ H5R_term_interface(void)
if (H5_interface_initialize_g) {
if ((n=H5I_nmembers(H5I_REFERENCE))) {
- H5I_clear_type(H5I_REFERENCE, FALSE);
+ H5I_clear_type(H5I_REFERENCE, FALSE, FALSE);
} else {
H5I_dec_type_ref(H5I_REFERENCE);
H5_interface_initialize_g = 0;
@@ -235,7 +236,7 @@ H5R_create(void *_ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5
/* Allocate the space to store the serialized information */
H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t);
- if(NULL == (buf = H5MM_malloc((size_t)buf_size)))
+ if(NULL == (buf = (uint8_t *)H5MM_malloc((size_t)buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Serialize information for dataset OID into heap buffer */
@@ -264,7 +265,7 @@ H5R_create(void *_ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5
case H5R_BADTYPE:
case H5R_MAXTYPE:
default:
- assert("unknown reference type" && 0);
+ HDassert("unknown reference type" && 0);
HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)")
} /* end switch */
@@ -307,7 +308,7 @@ herr_t
H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t space_id)
{
H5G_loc_t loc; /* File location */
- H5S_t *space = NULL; /* Pointer to dataspace containing region */
+ H5S_t *space; /* Pointer to dataspace containing region */
herr_t ret_value; /* Return value */
FUNC_ENTER_API(H5Rcreate, FAIL)
@@ -324,7 +325,7 @@ H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type")
if(ref_type != H5R_OBJECT && ref_type != H5R_DATASET_REGION)
HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "reference type not supported")
- if(space_id != (-1) && (NULL == (space = H5I_object_verify(space_id, H5I_DATASPACE))))
+ if(space_id != (-1) && (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
/* Create reference */
@@ -359,7 +360,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static hid_t
-H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref)
+H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref, hbool_t app_ref)
{
H5O_loc_t oloc; /* Object location */
H5G_name_t path; /* Path of object */
@@ -394,7 +395,7 @@ H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_re
INT32DECODE(p, hobjid.idx);
/* Get the dataset region from the heap (allocate inside routine) */
- if((buf = H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL)) == NULL)
+ if(NULL == (buf = (uint8_t *)H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL)))
HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information")
/* Get the object oid for the dataset */
@@ -432,11 +433,11 @@ H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_re
{
H5G_t *group; /* Pointer to group to open */
- if((group = H5G_open(&loc, dxpl_id)) == NULL)
+ if(NULL == (group = H5G_open(&loc, dxpl_id)))
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found")
/* Create an atom for the group */
- if((ret_value = H5I_register(H5I_GROUP, group)) < 0) {
+ if((ret_value = H5I_register(H5I_GROUP, group, app_ref)) < 0) {
H5G_close(group);
HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, FAIL, "can't register group")
} /* end if */
@@ -447,11 +448,11 @@ H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_re
{
H5T_t *type; /* Pointer to datatype to open */
- if((type = H5T_open(&loc, dxpl_id)) == NULL)
+ if(NULL == (type = H5T_open(&loc, dxpl_id)))
HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "not found")
/* Create an atom for the datatype */
- if((ret_value = H5I_register(H5I_DATATYPE, type)) < 0) {
+ if((ret_value = H5I_register(H5I_DATATYPE, type, app_ref)) < 0) {
H5T_close(type);
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "can't register datatype")
} /* end if */
@@ -460,14 +461,15 @@ H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_re
case H5O_TYPE_DATASET:
{
+ hid_t dapl_id = H5P_DATASET_ACCESS_DEFAULT; /* dapl to use to open dataset */
H5D_t *dset; /* Pointer to dataset to open */
/* Open the dataset */
- if((dset = H5D_open(&loc, dxpl_id)) == NULL)
+ if(NULL == (dset = H5D_open(&loc, dapl_id, dxpl_id)))
HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found")
/* Create an atom for the dataset */
- if((ret_value = H5I_register(H5I_DATASET, dset)) < 0) {
+ if((ret_value = H5I_register(H5I_DATASET, dset, app_ref)) < 0) {
H5D_close(dset);
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "can't register dataset")
} /* end if */
@@ -527,7 +529,7 @@ H5Rdereference(hid_t id, H5R_type_t ref_type, const void *_ref)
file = loc.oloc->file;
/* Create reference */
- if((ret_value = H5R_dereference(file, H5AC_dxpl_id, ref_type, _ref)) < 0)
+ if((ret_value = H5R_dereference(file, H5AC_dxpl_id, ref_type, _ref, TRUE)) < 0)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable dereference object")
done:
@@ -580,7 +582,7 @@ H5R_get_region(H5F_t *file, hid_t dxpl_id, const void *_ref)
INT32DECODE(p, hobjid.idx);
/* Get the dataset region from the heap (allocate inside routine) */
- if((buf = H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL)) == NULL)
+ if((buf = (uint8_t *)H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL)) == NULL)
HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, NULL, "Unable to read dataset region information")
/* Get the object oid for the dataset */
@@ -650,7 +652,7 @@ H5Rget_region(hid_t id, H5R_type_t ref_type, const void *ref)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create dataspace")
/* Atomize */
- if((ret_value = H5I_register (H5I_DATASPACE, space)) < 0)
+ if((ret_value = H5I_register (H5I_DATASPACE, space, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom")
done:
@@ -714,7 +716,7 @@ H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type,
INT32DECODE(p, hobjid.idx);
/* Get the dataset region from the heap (allocate inside routine) */
- if((buf = H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL)) == NULL)
+ if((buf = (uint8_t *)H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL)) == NULL)
HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information")
/* Get the object oid for the dataset */
@@ -861,7 +863,7 @@ H5R_get_name(H5F_t *f, hid_t lapl_id, hid_t dxpl_id, hid_t id, H5R_type_t ref_ty
INT32DECODE(p, hobjid.idx);
/* Get the dataset region from the heap (allocate inside routine) */
- if((buf = H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL)) == NULL)
+ if((buf = (uint8_t *)H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL)) == NULL)
HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information")
/* Get the object oid for the dataset */
@@ -881,7 +883,7 @@ H5R_get_name(H5F_t *f, hid_t lapl_id, hid_t dxpl_id, hid_t id, H5R_type_t ref_ty
} /* end switch */
/* Retrieve file ID for name search */
- if((file_id = H5I_get_file_id(id)) < 0)
+ if((file_id = H5I_get_file_id(id, FALSE)) < 0)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't retrieve file ID")
/* Get name, length, etc. */
@@ -891,7 +893,7 @@ H5R_get_name(H5F_t *f, hid_t lapl_id, hid_t dxpl_id, hid_t id, H5R_type_t ref_ty
done:
/* Close file ID used for search */
if(file_id > 0)
- if(H5I_dec_ref(file_id) < 0)
+ if(H5I_dec_ref(file_id, FALSE) < 0)
HDONE_ERROR(H5E_REFERENCE, H5E_CANTCLOSEFILE, FAIL, "can't determine name")
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5RC.c b/src/H5RC.c
index 25a08a5..d9f62c3 100644
--- a/src/H5RC.c
+++ b/src/H5RC.c
@@ -55,25 +55,25 @@ H5FL_DEFINE_STATIC(H5RC_t);
H5RC_t *
H5RC_create(void *o, H5RC_free_func_t free_func)
{
- H5RC_t *ret_value=NULL; /* Return value */
+ H5RC_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5RC_create,NULL);
+ FUNC_ENTER_NOAPI(H5RC_create, NULL)
/* Sanity check */
HDassert(o);
HDassert(free_func);
/* Allocate ref-counted string structure */
- if((ret_value=H5FL_MALLOC(H5RC_t))==NULL)
- HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed");
+ if(NULL == (ret_value = H5FL_MALLOC(H5RC_t)))
+ HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed")
/* Set the internal fields */
- ret_value->o=o;
- ret_value->n=1;
- ret_value->free_func=free_func;
+ ret_value->o = o;
+ ret_value->n = 1;
+ ret_value->free_func = free_func;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5RC_create() */
@@ -99,29 +99,29 @@ done:
herr_t
H5RC_decr(H5RC_t *rc)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5RC_decr,FAIL);
+ FUNC_ENTER_NOAPI(H5RC_decr, FAIL)
/* Sanity check */
HDassert(rc);
HDassert(rc->o);
- HDassert(rc->n>0);
+ HDassert(rc->n > 0);
HDassert(rc->free_func);
/* Decrement reference count */
rc->n--;
/* Check if we should delete this object now */
- if(rc->n==0) {
- if((rc->free_func)(rc->o)<0) {
- H5FL_FREE(H5RC_t,rc);
- HGOTO_ERROR(H5E_RS,H5E_CANTFREE,FAIL,"memory release failed");
+ if(rc->n == 0) {
+ if((rc->free_func)(rc->o) < 0) {
+ (void)H5FL_FREE(H5RC_t, rc);
+ HGOTO_ERROR(H5E_RS, H5E_CANTFREE, FAIL, "memory release failed")
} /* end if */
- H5FL_FREE(H5RC_t,rc);
+ (void)H5FL_FREE(H5RC_t, rc);
} /* end if */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5RC_decr() */
diff --git a/src/H5RS.c b/src/H5RS.c
index 550e326..6456ac8 100644
--- a/src/H5RS.c
+++ b/src/H5RS.c
@@ -99,21 +99,21 @@ H5RS_xstrdup(const char *s)
H5RS_str_t *
H5RS_create(const char *s)
{
- H5RS_str_t *ret_value=NULL; /* Return value */
+ H5RS_str_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5RS_create,NULL);
+ FUNC_ENTER_NOAPI(H5RS_create, NULL)
/* Allocate ref-counted string structure */
- if((ret_value=H5FL_MALLOC(H5RS_str_t))==NULL)
- HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed");
+ if(NULL == (ret_value = H5FL_MALLOC(H5RS_str_t)))
+ HGOTO_ERROR(H5E_RS, H5E_NOSPACE, NULL, "memory allocation failed")
/* Set the internal fields */
- ret_value->s=H5RS_xstrdup(s);
- ret_value->wrapped=0;
- ret_value->n=1;
+ ret_value->s = H5RS_xstrdup(s);
+ ret_value->wrapped = 0;
+ ret_value->n = 1;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5RS_create() */
@@ -139,21 +139,21 @@ done:
H5RS_str_t *
H5RS_wrap(const char *s)
{
- H5RS_str_t *ret_value=NULL; /* Return value */
+ H5RS_str_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5RS_wrap,NULL);
+ FUNC_ENTER_NOAPI(H5RS_wrap, NULL)
/* Allocate ref-counted string structure */
- if((ret_value=H5FL_MALLOC(H5RS_str_t))==NULL)
- HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed");
+ if(NULL == (ret_value = H5FL_MALLOC(H5RS_str_t)))
+ HGOTO_ERROR(H5E_RS, H5E_NOSPACE, NULL, "memory allocation failed")
/* Set the internal fields */
- ret_value->s=(char*)s; /* (Cast away const OK - QAK) */
- ret_value->wrapped=1;
- ret_value->n=1;
+ ret_value->s = (char*)s; /* (Cast away const OK - QAK) */
+ ret_value->wrapped = 1;
+ ret_value->n = 1;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5RS_wrap() */
@@ -181,21 +181,21 @@ done:
H5RS_str_t *
H5RS_own(char *s)
{
- H5RS_str_t *ret_value=NULL; /* Return value */
+ H5RS_str_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5RS_own,NULL);
+ FUNC_ENTER_NOAPI(H5RS_own, NULL)
/* Allocate ref-counted string structure */
- if((ret_value=H5FL_MALLOC(H5RS_str_t))==NULL)
- HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed");
+ if(NULL == (ret_value = H5FL_MALLOC(H5RS_str_t)))
+ HGOTO_ERROR(H5E_RS, H5E_NOSPACE, NULL, "memory allocation failed")
/* Set the internal fields */
- ret_value->s=s;
- ret_value->wrapped=0;
- ret_value->n=1;
+ ret_value->s = s;
+ ret_value->wrapped = 0;
+ ret_value->n = 1;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5RS_own() */
@@ -221,20 +221,20 @@ done:
herr_t
H5RS_decr(H5RS_str_t *rs)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5RS_decr);
+ FUNC_ENTER_NOAPI_NOFUNC(H5RS_decr)
/* Sanity check */
- assert(rs);
- assert(rs->n > 0);
+ HDassert(rs);
+ HDassert(rs->n > 0);
/* Decrement reference count for string */
- if((--rs->n)==0) {
+ if((--rs->n) == 0) {
if(!rs->wrapped)
- (void)H5FL_BLK_FREE(str_buf,rs->s);
- H5FL_FREE(H5RS_str_t,rs);
+ (void)H5FL_BLK_FREE(str_buf, rs->s);
+ (void)H5FL_FREE(H5RS_str_t, rs);
} /* end if */
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5RS_decr() */
@@ -259,25 +259,25 @@ H5RS_decr(H5RS_str_t *rs)
herr_t
H5RS_incr(H5RS_str_t *rs)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5RS_incr);
+ FUNC_ENTER_NOAPI_NOFUNC(H5RS_incr)
/* Sanity check */
- assert(rs);
- assert(rs->n > 0);
+ HDassert(rs);
+ HDassert(rs->n > 0);
/* If the ref-counted string started life as a wrapper around an existing
* string, duplicate the string now, so that the wrapped string can go out
* scope appropriately.
*/
if(rs->wrapped) {
- rs->s=H5RS_xstrdup(rs->s);
- rs->wrapped=0;
+ rs->s = H5RS_xstrdup(rs->s);
+ rs->wrapped = 0;
} /* end if */
/* Increment reference count for string */
rs->n++;
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5RS_incr() */
@@ -303,14 +303,14 @@ H5RS_incr(H5RS_str_t *rs)
H5RS_str_t *
H5RS_dup(H5RS_str_t *ret_value)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5RS_dup);
+ FUNC_ENTER_NOAPI_NOFUNC(H5RS_dup)
/* Check for valid reference counted string */
- if(ret_value!=NULL)
+ if(ret_value != NULL)
/* Increment reference count for string */
ret_value->n++;
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5RS_dup() */
@@ -335,7 +335,7 @@ H5RS_dup(H5RS_str_t *ret_value)
H5RS_str_t *
H5RS_dup_str(const char *s)
{
- char *new_str = NULL; /* Duplicate of string */
+ char *new_str; /* Duplicate of string */
size_t path_len; /* Length of the path */
H5RS_str_t *ret_value;
@@ -387,15 +387,15 @@ int
H5RS_cmp(const H5RS_str_t *rs1, const H5RS_str_t *rs2)
{
/* Can't return invalid value from this function */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5RS_cmp);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5RS_cmp)
/* Sanity check */
- assert(rs1);
- assert(rs1->s);
- assert(rs2);
- assert(rs2->s);
+ HDassert(rs1);
+ HDassert(rs1->s);
+ HDassert(rs2);
+ HDassert(rs2->s);
- FUNC_LEAVE_NOAPI(HDstrcmp(rs1->s,rs2->s));
+ FUNC_LEAVE_NOAPI(HDstrcmp(rs1->s, rs2->s))
} /* end H5RS_cmp() */
@@ -420,13 +420,13 @@ H5RS_cmp(const H5RS_str_t *rs1, const H5RS_str_t *rs2)
ssize_t
H5RS_len(const H5RS_str_t *rs)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5RS_len);
+ FUNC_ENTER_NOAPI_NOFUNC(H5RS_len)
/* Sanity check */
- assert(rs);
- assert(rs->s);
+ HDassert(rs);
+ HDassert(rs->s);
- FUNC_LEAVE_NOAPI((ssize_t)HDstrlen(rs->s));
+ FUNC_LEAVE_NOAPI((ssize_t)HDstrlen(rs->s))
} /* end H5RS_len() */
@@ -454,13 +454,13 @@ H5RS_len(const H5RS_str_t *rs)
char *
H5RS_get_str(const H5RS_str_t *rs)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5RS_get_str);
+ FUNC_ENTER_NOAPI_NOFUNC(H5RS_get_str)
/* Sanity check */
- assert(rs);
- assert(rs->s);
+ HDassert(rs);
+ HDassert(rs->s);
- FUNC_LEAVE_NOAPI(rs->s);
+ FUNC_LEAVE_NOAPI(rs->s)
} /* end H5RS_get_str() */
@@ -486,12 +486,12 @@ H5RS_get_str(const H5RS_str_t *rs)
unsigned
H5RS_get_count(const H5RS_str_t *rs)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5RS_get_count);
+ FUNC_ENTER_NOAPI_NOFUNC(H5RS_get_count)
/* Sanity check */
- assert(rs);
- assert(rs->n>0);
+ HDassert(rs);
+ HDassert(rs->n > 0);
- FUNC_LEAVE_NOAPI(rs->n);
+ FUNC_LEAVE_NOAPI(rs->n)
} /* end H5RS_get_count() */
diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h
index 975104e..04d319b 100644
--- a/src/H5Rpublic.h
+++ b/src/H5Rpublic.h
@@ -68,7 +68,7 @@ H5_DLL ssize_t H5Rget_name(hid_t loc_id, H5R_type_t ref_type, const void *ref,
char *name/*out*/, size_t size);
/* Symbols defined for compatibility with previous versions of the HDF5 API.
- *
+ *
* Use of these symbols is deprecated.
*/
#ifndef H5_NO_DEPRECATED_SYMBOLS
diff --git a/src/H5S.c b/src/H5S.c
index dd16498..170c49c 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -19,7 +19,6 @@
#define H5_INTERFACE_INIT_FUNC H5S_init_interface
-#define _H5S_IN_H5S_C
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fprivate.h" /* Files */
@@ -122,7 +121,7 @@ H5S_term_interface(void)
if(H5_interface_initialize_g) {
if((n = H5I_nmembers(H5I_DATASPACE))) {
- H5I_clear_type(H5I_DATASPACE, FALSE);
+ H5I_clear_type(H5I_DATASPACE, FALSE, FALSE);
} /* end if */
else {
/* Free data types */
@@ -164,7 +163,7 @@ H5S_create(H5S_class_t type)
FUNC_ENTER_NOAPI(H5S_create, NULL)
- /* Create a new data space */
+ /* Create a new dataspace */
if(NULL == (new_ds = H5FL_MALLOC(H5S_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
@@ -249,8 +248,8 @@ H5Screate(H5S_class_t type)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create dataspace")
/* Atomize */
- if((ret_value = H5I_register (H5I_DATASPACE, new_ds)) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register data space atom")
+ if((ret_value = H5I_register (H5I_DATASPACE, new_ds, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom")
done:
if(ret_value < 0 && new_ds)
@@ -299,7 +298,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5S_close
*
- * Purpose: Releases all memory associated with a data space.
+ * Purpose: Releases all memory associated with a dataspace.
*
* Return: Non-negative on success/Negative on failure
*
@@ -324,7 +323,7 @@ H5S_close(H5S_t *ds)
H5S_extent_release(&ds->extent);
/* Release the main structure */
- H5FL_FREE(H5S_t, ds);
+ (void)H5FL_FREE(H5S_t, ds);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -334,7 +333,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5Sclose
*
- * Purpose: Release access to a data space object.
+ * Purpose: Release access to a dataspace object.
*
* Return: Non-negative on success/Negative on failure
*
@@ -357,10 +356,10 @@ H5Sclose(hid_t space_id)
/* Check args */
if (NULL == H5I_object_verify(space_id,H5I_DATASPACE))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
/* When the reference count reaches zero the resources are freed */
- if (H5I_dec_ref(space_id) < 0)
+ if (H5I_dec_ref(space_id, TRUE) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "problem freeing id")
done:
@@ -396,15 +395,15 @@ H5Scopy(hid_t space_id)
/* Check args */
if (NULL==(src=(H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
/* Copy */
if (NULL == (dst = H5S_copy(src, FALSE, TRUE)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy data space")
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy dataspace")
/* Atomize */
- if ((ret_value=H5I_register (H5I_DATASPACE, dst))<0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register data space atom")
+ if ((ret_value=H5I_register (H5I_DATASPACE, dst, TRUE))<0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom")
done:
if(ret_value<0) {
@@ -442,9 +441,9 @@ H5Sextent_copy(hid_t dst_id,hid_t src_id)
/* Check args */
if(NULL == (src = (H5S_t *)H5I_object_verify(src_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
if(NULL == (dst = (H5S_t *)H5I_object_verify(dst_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
/* Copy */
if(H5S_extent_copy(&(dst->extent), &(src->extent), TRUE) < 0)
@@ -508,7 +507,7 @@ H5S_extent_copy(H5S_extent_t *dst, const H5S_extent_t *src, hbool_t copy_max)
break;
default:
- HDassert("unknown data space type" && 0);
+ HDassert("unknown dataspace type" && 0);
break;
} /* end switch */
@@ -524,7 +523,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5S_copy
*
- * Purpose: Copies a data space, by copying the extent and selection through
+ * Purpose: Copies a dataspace, by copying the extent and selection through
* H5S_extent_copy and H5S_select_copy. If the SHARE_SELECTION flag
* is set, then the selection can be shared between the source and
* destination dataspaces. (This should only occur in situations
@@ -565,6 +564,10 @@ H5S_copy(const H5S_t *src, hbool_t share_selection, hbool_t copy_max)
ret_value = dst;
done:
+ if(NULL == ret_value)
+ if(dst)
+ dst = H5FL_FREE(H5S_t, dst);
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_copy() */
@@ -595,17 +598,17 @@ H5S_get_simple_extent_npoints(const H5S_t *ds)
{
hssize_t ret_value;
- FUNC_ENTER_NOAPI(H5S_get_simple_extent_npoints, -1);
+ FUNC_ENTER_NOAPI(H5S_get_simple_extent_npoints, -1)
/* check args */
- assert(ds);
+ HDassert(ds);
/* Get the number of elements in extent */
- ret_value = ds->extent.nelem;
+ ret_value = (hssize_t)ds->extent.nelem;
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_get_simple_extent_npoints() */
/*-------------------------------------------------------------------------
@@ -631,30 +634,30 @@ H5Sget_simple_extent_npoints(hid_t space_id)
H5S_t *ds;
hssize_t ret_value;
- FUNC_ENTER_API(H5Sget_simple_extent_npoints, FAIL);
+ FUNC_ENTER_API(H5Sget_simple_extent_npoints, FAIL)
H5TRACE1("Hs", "i", space_id);
/* Check args */
- if (NULL == (ds = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ if(NULL == (ds = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
- ret_value = H5S_GET_EXTENT_NPOINTS(ds);
+ ret_value = (hssize_t)H5S_GET_EXTENT_NPOINTS(ds);
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Sget_simple_extent_npoints() */
/*-------------------------------------------------------------------------
* Function: H5S_get_npoints_max
*
- * Purpose: Determines the maximum number of data points a data space may
+ * Purpose: Determines the maximum number of data points a dataspace may
* have. If the `max' array is null then the maximum number of
* data points is the same as the current number of data points
* without regard to the hyperslab. If any element of the `max'
* array is zero then the maximum possible size is returned.
*
- * Return: Success: Maximum number of data points the data space
+ * Return: Success: Maximum number of data points the dataspace
* may have.
*
* Failure: 0
@@ -704,8 +707,8 @@ H5S_get_npoints_max(const H5S_t *ds)
break;
default:
- assert("unknown data space class" && 0);
- HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, 0, "internal error (unknown data space class)")
+ assert("unknown dataspace class" && 0);
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, 0, "internal error (unknown dataspace class)")
}
done:
@@ -716,9 +719,9 @@ done:
/*-------------------------------------------------------------------------
* Function: H5Sget_simple_extent_ndims
*
- * Purpose: Determines the dimensionality of a data space.
+ * Purpose: Determines the dimensionality of a dataspace.
*
- * Return: Success: The number of dimensions in a data space.
+ * Return: Success: The number of dimensions in a dataspace.
*
* Failure: Negative
*
@@ -735,24 +738,24 @@ H5Sget_simple_extent_ndims(hid_t space_id)
H5S_t *ds;
int ret_value;
- FUNC_ENTER_API(H5Sget_simple_extent_ndims, FAIL);
+ FUNC_ENTER_API(H5Sget_simple_extent_ndims, FAIL)
H5TRACE1("Is", "i", space_id);
/* Check args */
- if (NULL == (ds = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ if(NULL == (ds = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
- ret_value = H5S_GET_EXTENT_NDIMS(ds);
+ ret_value = (int)H5S_GET_EXTENT_NDIMS(ds);
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Sget_simple_extent_ndims() */
/*-------------------------------------------------------------------------
* Function: H5S_get_simple_extent_ndims
*
- * Purpose: Returns the number of dimensions in a data space.
+ * Purpose: Returns the number of dimensions in a dataspace.
*
* Return: Success: Non-negative number of dimensions. Zero
* implies a scalar.
@@ -773,35 +776,35 @@ done:
int
H5S_get_simple_extent_ndims(const H5S_t *ds)
{
- int ret_value;
+ int ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5S_get_simple_extent_ndims, FAIL);
+ FUNC_ENTER_NOAPI(H5S_get_simple_extent_ndims, FAIL)
/* check args */
- assert(ds);
+ HDassert(ds);
- switch (H5S_GET_EXTENT_TYPE(ds)) {
+ switch(H5S_GET_EXTENT_TYPE(ds)) {
case H5S_NULL:
case H5S_SCALAR:
case H5S_SIMPLE:
- ret_value = ds->extent.rank;
+ ret_value = (int)ds->extent.rank;
break;
default:
- assert("unknown data space class" && 0);
- HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "internal error (unknown data space class)")
- }
+ HDassert("unknown dataspace class" && 0);
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "internal error (unknown dataspace class)")
+ } /* end switch */
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_get_simple_extent_ndims() */
/*-------------------------------------------------------------------------
* Function: H5Sget_simple_extent_dims
*
* Purpose: Returns the size and maximum sizes in each dimension of
- * a data space DS through the DIMS and MAXDIMS arguments.
+ * a dataspace DS through the DIMS and MAXDIMS arguments.
*
* Return: Success: Number of dimensions, the same value as
* returned by H5Sget_simple_extent_ndims().
@@ -841,67 +844,100 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5S_get_simple_extent_dims
+ * Function: H5S_extent_get_dims
*
- * Purpose: Returns the size in each dimension of a data space. This
- * function may not be meaningful for all types of data spaces.
+ * Purpose: Returns the size in each dimension of a dataspace. This
+ * function may not be meaningful for all types of dataspaces.
*
* Return: Success: Number of dimensions. Zero implies scalar.
- *
* Failure: Negative
*
- * Programmer: Robb Matzke
- * Thursday, December 11, 1997
- *
- * Modifications:
+ * Programmer: Quincey Koziol
+ * Tuesday, June 30, 2009
*
*-------------------------------------------------------------------------
*/
int
-H5S_get_simple_extent_dims(const H5S_t *ds, hsize_t dims[], hsize_t max_dims[])
+H5S_extent_get_dims(const H5S_extent_t *ext, hsize_t dims[], hsize_t max_dims[])
{
- int ret_value;
- int i;
+ int i; /* Local index variable */
+ int ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5S_get_simple_extent_dims, FAIL);
+ FUNC_ENTER_NOAPI(H5S_extent_get_dims, FAIL)
/* check args */
- assert(ds);
+ HDassert(ext);
- switch (H5S_GET_EXTENT_TYPE(ds)) {
+ switch(ext->type) {
case H5S_NULL:
case H5S_SCALAR:
ret_value = 0;
break;
case H5S_SIMPLE:
- ret_value = ds->extent.rank;
- for (i=0; i<ret_value; i++) {
- if (dims)
- dims[i] = ds->extent.size[i];
- if (max_dims) {
- if (ds->extent.max)
- max_dims[i] = ds->extent.max[i];
+ ret_value = (int)ext->rank;
+ for(i = 0; i < ret_value; i++) {
+ if(dims)
+ dims[i] = ext->size[i];
+ if(max_dims) {
+ if(ext->max)
+ max_dims[i] = ext->max[i];
else
- max_dims[i] = ds->extent.size[i];
- }
- }
+ max_dims[i] = ext->size[i];
+ } /* end if */
+ } /* end for */
break;
default:
- assert("unknown data space class" && 0);
- HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "internal error (unknown data space class)")
- }
+ HDassert("unknown dataspace class" && 0);
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "internal error (unknown dataspace class)")
+ } /* end switch */
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_extent_get_dims() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_get_simple_extent_dims
+ *
+ * Purpose: Returns the size in each dimension of a dataspace. This
+ * function may not be meaningful for all types of dataspaces.
+ *
+ * Return: Success: Number of dimensions. Zero implies scalar.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 11, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5S_get_simple_extent_dims(const H5S_t *ds, hsize_t dims[], hsize_t max_dims[])
+{
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_get_simple_extent_dims, FAIL)
+
+ /* check args */
+ HDassert(ds);
+
+ /* Get dims for extent */
+ if((ret_value = H5S_extent_get_dims(&ds->extent, dims, max_dims)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve dataspace extent dims")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_get_simple_extent_dims() */
/*-------------------------------------------------------------------------
* Function: H5S_write
*
- * Purpose: Updates a data space by writing a message to an object
+ * Purpose: Updates a dataspace by writing a message to an object
* header.
*
* Return: Non-negative on success/Negative on failure
@@ -935,7 +971,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5S_append
*
- * Purpose: Updates a data space by adding a message to an object
+ * Purpose: Updates a dataspace by adding a message to an object
* header.
*
* Return: Non-negative on success/Negative on failure
@@ -976,9 +1012,9 @@ done:
/*-------------------------------------------------------------------------
* Function: H5S_read
*
- * Purpose: Reads the data space from an object header.
+ * Purpose: Reads the dataspace from an object header.
*
- * Return: Success: Pointer to a new data space.
+ * Return: Success: Pointer to a new dataspace.
*
* Failure: NULL
*
@@ -1014,7 +1050,7 @@ H5S_read(const H5O_loc_t *loc, hid_t dxpl_id)
done:
if(ret_value == NULL) {
if(ds != NULL)
- H5FL_FREE(H5S_t, ds);
+ (void)H5FL_FREE(H5S_t, ds);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -1078,7 +1114,7 @@ H5Sis_simple(hid_t space_id)
/* Check args and all the boring stuff. */
if ((space = (H5S_t *)H5I_object_verify(space_id,H5I_DATASPACE)) == NULL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a data space")
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a dataspace")
ret_value = H5S_is_simple(space);
@@ -1132,7 +1168,7 @@ H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[/*rank*/],
/* Check args */
if ((space = (H5S_t *)H5I_object_verify(space_id,H5I_DATASPACE)) == NULL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a data space")
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a dataspace")
if (rank > 0 && dims == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no dimensions specified")
if (rank<0 || rank>H5S_MAX_RANK)
@@ -1245,7 +1281,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5Screate_simple
*
- * Purpose: Creates a new simple data space object and opens it for
+ * Purpose: Creates a new simple dataspace object and opens it for
* access. The DIMS argument is the size of the simple dataset
* and the MAXDIMS argument is the upper limit on the size of
* the dataset. MAXDIMS may be the null pointer in which case
@@ -1254,7 +1290,7 @@ done:
* unlimited, otherwise no element of MAXDIMS should be smaller
* than the corresponding element of DIMS.
*
- * Return: Success: The ID for the new simple data space object.
+ * Return: Success: The ID for the new simple dataspace object.
*
* Failure: Negative
*
@@ -1308,7 +1344,7 @@ H5Screate_simple(int rank, const hsize_t dims[/*rank*/],
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace")
/* Atomize */
- if ((ret_value=H5I_register (H5I_DATASPACE, space))<0)
+ if ((ret_value=H5I_register (H5I_DATASPACE, space, TRUE))<0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID")
done:
@@ -1326,7 +1362,7 @@ done:
*
* Purpose: Internal function to create simple dataspace
*
- * Return: Success: The ID for the new simple data space object.
+ * Return: Success: The ID for the new simple dataspace object.
* Failure: Negative
*
* Errors:
@@ -1405,7 +1441,7 @@ done:
* Function: H5S_encode
*
* Purpose: Private function for H5Sencode. Converts an object
- * description for data space and its selection into binary
+ * description for dataspace and its selection into binary
* in a buffer.
*
* Return: Success: non-negative
@@ -1429,7 +1465,7 @@ H5S_encode(H5S_t *obj, unsigned char *buf, size_t *nalloc)
FUNC_ENTER_NOAPI_NOINIT(H5S_encode)
/* Allocate "fake" file structure */
- if(NULL == (f = H5F_fake_alloc((size_t)0)))
+ if(NULL == (f = H5F_fake_alloc((uint8_t)0)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate fake file struct")
/* Find out the size of buffer needed for extent */
@@ -1509,7 +1545,7 @@ H5Sdecode(const void *buf)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDECODE, FAIL, "can't decode object")
/* Register the type and return the ID */
- if((ret_value = H5I_register(H5I_DATASPACE, ds)) < 0)
+ if((ret_value = H5I_register(H5I_DATASPACE, ds, TRUE)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTREGISTER, FAIL, "unable to register dataspace")
done:
@@ -1540,7 +1576,7 @@ H5S_decode(const unsigned char *buf)
H5S_extent_t *extent;
size_t extent_size; /* size of the extent message*/
H5F_t *f = NULL; /* Fake file structure*/
- size_t sizeof_size; /* 'Size of sizes' for file */
+ uint8_t sizeof_size; /* 'Size of sizes' for file */
H5S_t *ret_value;
FUNC_ENTER_NOAPI_NOINIT(H5S_decode)
@@ -1565,18 +1601,18 @@ H5S_decode(const unsigned char *buf)
/* Decode the extent part of dataspace */
/* (pass mostly bogus file pointer and bogus DXPL) */
- if((extent = (H5S_extent_t *)H5O_msg_decode(f, H5P_DEFAULT, H5O_SDSPACE_ID, buf))==NULL)
+ if((extent = (H5S_extent_t *)H5O_msg_decode(f, H5P_DEFAULT, NULL, H5O_SDSPACE_ID, buf))==NULL)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDECODE, NULL, "can't decode object")
buf += extent_size;
/* Copy the extent into dataspace structure */
if((ds = H5FL_CALLOC(H5S_t))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for data space conversion path table")
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for dataspace conversion path table")
if(H5O_msg_copy(H5O_SDSPACE_ID, extent, &(ds->extent)) == NULL)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy object")
if(H5S_extent_release(extent) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTDELETE, NULL, "can't release previous dataspace")
- H5FL_FREE(H5S_extent_t, extent);
+ (void)H5FL_FREE(H5S_extent_t, extent);
/* Initialize to "all" selection. Deserialization relies on valid existing selection. */
if(H5S_select_all(ds, FALSE) < 0)
@@ -1699,7 +1735,7 @@ H5Sset_extent_none(hid_t space_id)
/* Check args */
if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a data space")
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a dataspace")
/* Clear the previous extent from the dataspace */
if(H5S_extent_release(&space->extent)<0)
@@ -1739,7 +1775,7 @@ H5Soffset_simple(hid_t space_id, const hssize_t *offset)
/* Check args */
if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a data space")
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a dataspace")
if (space->extent.rank==0 || (H5S_GET_EXTENT_TYPE(space)==H5S_SCALAR
|| H5S_GET_EXTENT_TYPE(space)==H5S_NULL))
HGOTO_ERROR(H5E_ATOM, H5E_UNSUPPORTED, FAIL, "can't set offset on scalar or null dataspace")
@@ -1756,27 +1792,25 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5S_set_extent
- *
- * Purpose: Modify the dimensions of a data space. Based on H5S_extend
+ * Function: H5S_set_extent
*
- * Return: Success: Non-negative
+ * Purpose: Modify the dimensions of a dataspace. Based on H5S_extend
*
- * Failure: Negative
+ * Return: Success: Non-negative
+ * Failure: Negative
*
- * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
- *
- * Date: March 13, 2002
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ * March 13, 2002
*
*-------------------------------------------------------------------------
*/
-int
+htri_t
H5S_set_extent(H5S_t *space, const hsize_t *size)
{
unsigned u; /* Local index variable */
- herr_t ret_value = 0; /* Return value */
+ htri_t ret_value = FALSE; /* Return value */
- FUNC_ENTER_NOAPI(H5S_set_extent, FAIL);
+ FUNC_ENTER_NOAPI(H5S_set_extent, FAIL)
/* Check args */
HDassert(space && H5S_SIMPLE == H5S_GET_EXTENT_TYPE(space));
@@ -1785,21 +1819,26 @@ H5S_set_extent(H5S_t *space, const hsize_t *size)
/* Verify that the dimensions being changed are allowed to change */
for(u = 0; u < space->extent.rank; u++) {
if(space->extent.size[u] != size[u]) {
+ /* Check for invalid dimension size modification */
if(space->extent.max && H5S_UNLIMITED != space->extent.max[u] &&
space->extent.max[u] < size[u])
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dimension cannot be modified")
- ret_value++;
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "dimension cannot be modified")
+
+ /* Indicate that dimension size can be modified */
+ ret_value = TRUE;
} /* end if */
} /* end for */
- /* Update */
+ /* Update dimension size(s) */
if(ret_value)
- H5S_set_extent_real(space, size);
+ if(H5S_set_extent_real(space, size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "failed to change dimension size(s)")
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_set_extent() */
+
/*-------------------------------------------------------------------------
* Function: H5S_has_extent
*
@@ -1818,59 +1857,57 @@ done:
hbool_t
H5S_has_extent(const H5S_t *ds)
{
- htri_t ret_value;
- FUNC_ENTER_NOAPI(H5S_has_extent, FAIL)
+ hbool_t ret_value;
- assert(ds);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_has_extent)
+
+ HDassert(ds);
- if(ds->extent.rank==0 && ds->extent.nelem == 0 && ds->extent.type != H5S_NULL)
+ if(0 == ds->extent.rank && 0 == ds->extent.nelem && H5S_NULL != ds->extent.type)
ret_value = FALSE;
else
ret_value = TRUE;
-done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5S_has_extent() */
/*-------------------------------------------------------------------------
- * Function: H5S_set_extent_real
+ * Function: H5S_set_extent_real
*
- * Purpose: Modify the dimensions of a data space. Based on H5S_extend
+ * Purpose: Modify the dimensions of a dataspace. Based on H5S_extend
*
- * Return: Success: Non-negative
+ * Return: Success: Non-negative
+ * Failure: Negative
*
- * Failure: Negative
- *
- * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
- *
- * Date: March 13, 2002
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ * March 13, 2002
*
*-------------------------------------------------------------------------
*/
herr_t
-H5S_set_extent_real( H5S_t *space, const hsize_t *size )
+H5S_set_extent_real(H5S_t *space, const hsize_t *size)
{
hsize_t nelem; /* Number of elements in extent */
unsigned u; /* Local index variable */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5S_set_extent_real, FAIL );
+ FUNC_ENTER_NOAPI(H5S_set_extent_real, FAIL)
/* Check args */
- assert(space && H5S_SIMPLE==H5S_GET_EXTENT_TYPE(space));
- assert(size);
+ HDassert(space && H5S_SIMPLE == H5S_GET_EXTENT_TYPE(space));
+ HDassert(size);
/* Change the dataspace size & re-compute the number of elements in the extent */
- for (u=0, nelem=1; u < space->extent.rank; u++ ) {
+ for(u = 0, nelem = 1; u < space->extent.rank; u++ ) {
space->extent.size[u] = size[u];
- nelem*=space->extent.size[u];
+ nelem *= space->extent.size[u];
} /* end for */
space->extent.nelem = nelem;
/* If the selection is 'all', update the number of elements selected */
- if(H5S_GET_SELECT_TYPE(space)==H5S_SEL_ALL)
- if(H5S_select_all(space, FALSE)<0)
+ if(H5S_SEL_ALL == H5S_GET_SELECT_TYPE(space))
+ if(H5S_select_all(space, FALSE) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
/* Mark the dataspace as no longer shared if it was before */
@@ -1878,7 +1915,7 @@ H5S_set_extent_real( H5S_t *space, const hsize_t *size )
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRESET, FAIL, "can't stop sharing dataspace")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_set_extent_real() */
@@ -2040,7 +2077,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5S_extend
*
- * Purpose: Extend the dimensions of a data space.
+ * Purpose: Extend the dimensions of a dataspace.
*
* Return: Success: Number of dimensions whose size increased.
*
diff --git a/src/H5SL.c b/src/H5SL.c
index a720182..d28e5be 100644
--- a/src/H5SL.c
+++ b/src/H5SL.c
@@ -16,17 +16,34 @@
/*
* Purpose: Provides a skip list abstract data type.
*
+ * (See "Deterministic Skip Lists" by Munro, Papadakis & Sedgewick)
+ *
+ * (Implementation changed to a deterministic skip list from a
+ * probabilistic one. This implementation uses a 1-2-3 skip list
+ * using arrays, as described by Munro, Papadakis & Sedgewick.
+ *
+ * Arrays are allocated using a free list factory for each size
+ * that is a power of two. Factories are created as soon as they
+ * are needed, and are never destroyed until the package is shut
+ * down. There is no longer a maximum level or "p" value.
+ * -NAF 2008/11/05)
+ *
* (See "Skip Lists: A Probabilistic Alternative to Balanced Trees"
* by William Pugh for additional information)
*
* (This implementation has the optimization for reducing key
* key comparisons mentioned in section 3.5 of "A Skip List
- * Cookbook" by William Pugh)
+ * Cookbook" by William Pugh
+ * -Removed as our implementation of this was useless for a 1-2-3
+ * skip list. The implementation in that document hurts
+ * performance, at least for integer keys. -NAF)
*
* (Also, this implementation has a couple of home-grown
* optimizations, including setting the "update" vector to the
* actual 'forward' pointer to update, instead of the node
- * containing the forward pointer -QAK)
+ * containing the forward pointer -QAK
+ * -No longer uses update vector, as insertions/deletions are now
+ * always at level 0. -NAF)
*
* (Note: This implementation does not have the information for
* implementing the "Linear List Operations" (like insert/delete/
@@ -36,9 +53,6 @@
* (This implementation has an additional backward pointer, which
* allows the list to be iterated in reverse)
*
- * (We should also look into "Deterministic Skip Lists" (see
- * paper by Munro, Papadakis & Sedgewick))
- *
* (There's also an article on "Alternating Skip Lists", which
* are similar to deterministic skip lists, in the August 2000
* issue of Dr. Dobb's Journal)
@@ -54,61 +68,28 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5FLprivate.h" /* Free Lists */
#include "H5SLprivate.h" /* Skip list routines */
+#include "H5MMprivate.h" /* Memory management */
/* Local Macros */
-/* Define the code template for insertions for the "OP" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_INSERT_FOUND(SLIST,X,UPDATE,I) \
- HGOTO_ERROR(H5E_SLIST,H5E_CANTINSERT,NULL,"can't insert duplicate key");
-
-/* Define the code template for removals for the "OP" in the H5SL_LOCATE macro */
-/* (NOTE: the code in H5SL_remove_first() is largely the same, fix bugs in both places) */
-#define H5SL_LOCATE_REMOVE_FOUND(SLIST,X,UPDATE,I) \
- void *tmp; \
- \
- for(I=0; I<=(int)SLIST->curr_level; I++) { \
- if(*UPDATE[I]!=X) \
- break; \
- *UPDATE[I]=X->forward[I]; \
- } /* end for */ \
- if(SLIST->last==X) \
- SLIST->last=X->backward; \
- else \
- X->forward[0]->backward=X->backward; \
- tmp=X->item; \
- H5FL_ARR_FREE(H5SL_node_ptr_t,X); \
- while(SLIST->curr_level>0 && SLIST->header->forward[SLIST->curr_level]==NULL) \
- SLIST->curr_level--; \
- SLIST->nobjs--; \
- HGOTO_DONE(tmp);
-
/* Define the code template for searches for the "OP" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_SEARCH_FOUND(SLIST,X,UPDATE,I) \
+#define H5SL_LOCATE_SEARCH_FOUND(SLIST, X, I) \
HGOTO_DONE(X->item);
/* Define the code template for finds for the "OP" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_FIND_FOUND(SLIST,X,UPDATE,I) \
+#define H5SL_LOCATE_FIND_FOUND(SLIST, X, I) \
HGOTO_DONE(X);
-/* Define a code template for "OP"s that update the "update" vector for the H5SL_LOCATE macro */
-#define H5SL_LOCATE_INSERT_UPDATE(X, UPDATE, I) \
- UPDATE[I] = &X->forward[I];
-#define H5SL_LOCATE_REMOVE_UPDATE(X, UPDATE, I) \
- UPDATE[I] = &X->forward[I];
-
-/* Define a code template for "OP"s that _DON'T_ update the "update" vector for the H5SL_LOCATE macro */
-#define H5SL_LOCATE_SEARCH_UPDATE(X, UPDATE, I)
-#define H5SL_LOCATE_FIND_UPDATE(X, UPDATE, I)
-
-
/* Define a code template for comparing scalar keys for the "CMP" in the H5SL_LOCATE macro */
#define H5SL_LOCATE_SCALAR_CMP(TYPE, PNODE, PKEY, HASHVAL) \
(*(TYPE *)((PNODE)->key) < *(TYPE *)PKEY)
/* Define a code template for comparing string keys for the "CMP" in the H5SL_LOCATE macro */
#define H5SL_LOCATE_STRING_CMP(TYPE, PNODE, PKEY, HASHVAL) \
- (((PNODE)->hashval == HASHVAL) ? (HDstrcmp((PNODE)->key, PKEY) < 0) : ((PNODE)->hashval < HASHVAL))
+ (((PNODE)->hashval == HASHVAL) ? \
+ (HDstrcmp((const char *)(PNODE)->key, (const char *)PKEY) < 0) : \
+ ((PNODE)->hashval < HASHVAL))
/* Define a code template for comparing H5_obj_t keys for the "CMP" in the H5SL_LOCATE macro */
#define H5SL_LOCATE_OBJ_CMP(TYPE, PNODE, PKEY, HASHVAL) \
@@ -121,7 +102,7 @@
/* Define a code template for comparing string keys for the "EQ" in the H5SL_LOCATE macro */
#define H5SL_LOCATE_STRING_EQ(TYPE, PNODE, PKEY, HASHVAL) \
- (((PNODE)->hashval == HASHVAL) && (HDstrcmp(((PNODE)->key), PKEY) == 0))
+ (((PNODE)->hashval == HASHVAL) && (HDstrcmp((const char *)(PNODE)->key, (const char *)PKEY) == 0))
/* Define a code template for comparing H5_obj_t keys for the "EQ" in the H5SL_LOCATE macro */
#define H5SL_LOCATE_OBJ_EQ(TYPE, PNODE, PKEY, HASHVAL) \
@@ -133,50 +114,358 @@
/* Define a code template for initializing the hash value for string keys for the "HASHINIT" in the H5SL_LOCATE macro */
#define H5SL_LOCATE_STRING_HASHINIT(KEY, HASHVAL) \
- HASHVAL = H5_hash_string(KEY);
+ HASHVAL = H5_hash_string((const char *)KEY);
/* Define a code template for initializing the hash value for H5_obj_t keys for the "HASHINIT" in the H5SL_LOCATE macro */
#define H5SL_LOCATE_OBJ_HASHINIT(KEY, HASHVAL)
/* Macro used to find node for operation */
-#define H5SL_LOCATE(OP, CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL) \
+#define H5SL_LOCATE(OP, CMP, SLIST, X, TYPE, KEY, HASHVAL) \
{ \
- H5SL_node_t *_checked; /* Pointer to last node checked */ \
int _i; /* Local index variable */ \
+ unsigned _count; /* Num nodes searched at this height */ \
\
- _checked = NULL; \
H5_GLUE3(H5SL_LOCATE_,CMP,_HASHINIT)(KEY, HASHVAL) \
for(_i = (int)SLIST->curr_level; _i >= 0; _i--) { \
- if(X->forward[_i] != _checked) { \
- while(X->forward[_i] && H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE, X->forward[_i], KEY, HASHVAL) ) \
- X = X->forward[_i]; \
- _checked = X->forward[_i]; \
- } /* end if */ \
- H5_GLUE3(H5SL_LOCATE_,OP,_UPDATE)(X, UPDATE, _i) \
+ _count = 0; \
+ while(_count < 3 && X->forward[_i] && \
+ H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE, X->forward[_i], KEY, HASHVAL) ) { \
+ X = X->forward[_i]; \
+ _count++; \
+ } /* end while */ \
} /* end for */ \
X = X->forward[0]; \
if(X != NULL && H5_GLUE3(H5SL_LOCATE_,CMP,_EQ)(TYPE, X, KEY, HASHVAL) ) { \
/* What to do when a node is found */ \
- H5_GLUE3(H5SL_LOCATE_,OP,_FOUND)(SLIST, X, UPDATE, _i) \
+ H5_GLUE3(H5SL_LOCATE_,OP,_FOUND)(SLIST, X, _i) \
} /* end if */ \
}
-/* Macro used to insert node */
-#define H5SL_INSERT(CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL) \
- H5SL_LOCATE(INSERT, CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL)
+
+/* Macro used to grow a node by 1. Does not update pointers. LVL is the current
+ * level of X. Does not update LVL but does update X->lvl. */
+#define H5SL_GROW(X, LVL) \
+{ \
+ /* Check if we need to increase allocation of forward pointers */ \
+ if(LVL + 1 >= 1u << X->log_nalloc) { \
+ H5SL_node_t **_tmp; \
+ HDassert(LVL + 1 == 1u << X->log_nalloc); \
+ /* Double the amount of allocated space */ \
+ X->log_nalloc++; \
+ \
+ /* Check if we need to create a new factory */ \
+ if(X->log_nalloc >= H5SL_fac_nused_g) { \
+ HDassert(X->log_nalloc == H5SL_fac_nused_g); \
+ \
+ /* Check if we need to allocate space for the factory pointer*/ \
+ if(H5SL_fac_nused_g >= H5SL_fac_nalloc_g) { \
+ HDassert(H5SL_fac_nused_g == H5SL_fac_nalloc_g); \
+ /* Double the size of the array of factory pointers */ \
+ H5SL_fac_nalloc_g *= 2; \
+ H5SL_fac_g = (H5FL_fac_head_t **)H5MM_realloc((void *)H5SL_fac_g, \
+ H5SL_fac_nalloc_g * sizeof(H5FL_fac_head_t *)); \
+ } /* end if */ \
+ \
+ /* Create the new factory */ \
+ H5SL_fac_g[H5SL_fac_nused_g] = H5FL_fac_init((1u << H5SL_fac_nused_g) * sizeof(H5SL_node_t *)); \
+ H5SL_fac_nused_g++; \
+ } /* end if */ \
+ \
+ /* Allocate space for new forward pointers */ \
+ if(NULL == (_tmp = (H5SL_node_t **)H5FL_FAC_MALLOC(H5SL_fac_g[X->log_nalloc]))) \
+ HGOTO_ERROR(H5E_SLIST, H5E_NOSPACE, NULL, "memory allocation failed") \
+ HDmemcpy((void *)_tmp, (const void *)X->forward, (LVL + 1) * sizeof(H5SL_node_t *)); \
+ (void)H5FL_FAC_FREE(H5SL_fac_g[X->log_nalloc-1], (void *)X->forward); \
+ X->forward = _tmp; \
+ } /* end if */ \
+ \
+ X->level++; \
+}
+
+
+/* Macro used to shrink a node by 1. Does not update pointers. LVL is the
+ * current level of X. Does not update LVL but does update X->level. */
+#define H5SL_SHRINK(X, LVL) \
+{ \
+ /* Check if we can reduce the allocation of forward pointers */ \
+ if(LVL <= 1u << (X->log_nalloc - 1)) { \
+ H5SL_node_t **_tmp; \
+ HDassert(LVL == 1u << (X->log_nalloc - 1)); \
+ X->log_nalloc--; \
+ \
+ /* Allocate space for new forward pointers */ \
+ if(NULL == (_tmp = (H5SL_node_t **)H5FL_FAC_MALLOC(H5SL_fac_g[X->log_nalloc]))) \
+ HGOTO_ERROR(H5E_SLIST, H5E_NOSPACE, NULL, "memory allocation failed") \
+ HDmemcpy((void *)_tmp, (const void *)X->forward, (LVL) * sizeof(H5SL_node_t *)); \
+ (void)H5FL_FAC_FREE(H5SL_fac_g[X->log_nalloc+1], (void *)X->forward); \
+ X->forward = _tmp; \
+ } /* end if */ \
+ \
+ X->level--; \
+}
+
+
+/* Macro used to grow the level of a node by 1, with appropriate changes to the
+ * head node if necessary. PREV is the previous node of the height that X is to
+ * grow to. */
+#define H5SL_PROMOTE(SLIST, X, PREV) \
+{ \
+ size_t _lvl = X->level; \
+ \
+ H5SL_GROW(X, _lvl); \
+ \
+ if(_lvl == (size_t) SLIST->curr_level) { \
+ HDassert(PREV == SLIST->header); \
+ /* Grow the head */ \
+ H5SL_GROW(PREV, _lvl); \
+ SLIST->curr_level++; \
+ X->forward[_lvl+1] = NULL; \
+ } else { \
+ HDassert(_lvl < (size_t) SLIST->curr_level); \
+ X->forward[_lvl+1] = PREV->forward[_lvl+1]; \
+ } /* end else */ \
+ PREV->forward[_lvl+1] = X; \
+}
+
+
+/* Macro used to reduce the level of a node by 1. Does not update the head node
+ * "current level". PREV is the previous node of the currrent height of X. */
+#define H5SL_DEMOTE(X, PREV) \
+{ \
+ size_t _lvl = X->level; \
+ \
+ HDassert(PREV->forward[_lvl] == X); \
+ PREV->forward[_lvl] = X->forward[_lvl]; \
+ H5SL_SHRINK(X, _lvl); \
+}
+
+
+/* Macro used to insert node. Does not actually insert the node. After running
+ * this macro, X will contain the node before where the new node should be
+ * inserted (at level 0). */
+#define H5SL_INSERT(CMP, SLIST, X, TYPE, KEY, HASHVAL) \
+{ \
+ H5SL_node_t *_last = X; /* Lowest node in the current gap */ \
+ H5SL_node_t *_next = NULL; /* Highest node in the currect gap */ \
+ H5SL_node_t *_drop; /* Low node of the gap to drop into */ \
+ int _count; /* Number of nodes in the current gap */ \
+ int _i; \
+ \
+ H5_GLUE3(H5SL_LOCATE_,CMP,_HASHINIT)(KEY, HASHVAL) \
+ for(_i = (int)SLIST->curr_level; _i >= 0; _i--) { \
+ /* Search for the node to drop into, also count the number of nodes */ \
+ /* of height _i in this gap */ \
+ _drop = NULL; \
+ for(_count = 0; ; _count++) { \
+ /* Terminate if this is the last node in the gap */ \
+ if(X->forward[_i] == _next) { \
+ if(!_drop) \
+ _drop = X; \
+ break; \
+ } /* end if */ \
+ \
+ /* Check if this node is the start of the next gap */ \
+ if(!_drop && !H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE, X->forward[_i], KEY, HASHVAL)) \
+ _drop = X; \
+ \
+ /* No need to check the last node in the gap if there are 3, as */ \
+ /* there cannot be a fourth */ \
+ if(_count == 2) { \
+ if(!_drop) \
+ _drop = X->forward[_i]; \
+ _count = 3; \
+ break; \
+ } \
+ X = X->forward[_i]; \
+ } /* end for */ \
+ HDassert(!_drop->forward[_i] || \
+ !H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE, _drop->forward[_i], KEY, HASHVAL)); \
+ \
+ /* Promote the middle node if necessary */ \
+ if(_count == 3) { \
+ HDassert(X == _last->forward[_i]->forward[_i]); \
+ H5SL_PROMOTE(SLIST, X, _last) \
+ } \
+ \
+ /* Prepare to drop down */ \
+ X = _last = _drop; \
+ _next = _drop->forward[_i]; \
+ } /* end for */ \
+ \
+ if(_next && H5_GLUE3(H5SL_LOCATE_,CMP,_EQ)(TYPE, _next, KEY, HASHVAL)) \
+ HGOTO_ERROR(H5E_SLIST, H5E_CANTINSERT, NULL, "can't insert duplicate key") \
+}
+
/* Macro used to remove node */
-#define H5SL_REMOVE(CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL) \
- H5SL_LOCATE(REMOVE, CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL)
+#define H5SL_REMOVE(CMP, SLIST, X, TYPE, KEY, HASHVAL) \
+{ \
+ H5SL_node_t *_last = X; /* Lowest node in the current gap */ \
+ H5SL_node_t *_llast = X; /* Lowest node in the previous gap */ \
+ H5SL_node_t *_next = NULL; /* Highest node in the currect gap */ \
+ H5SL_node_t *_drop = NULL; /* Low node of the gap to drop into */ \
+ H5SL_node_t *_ldrop = NULL; /* Low node of gap before the one to drop into */ \
+ H5SL_node_t *_head = SLIST->header; /* Head of the skip list */ \
+ int _count; /* Number of nodes in the current gap */ \
+ int _i = (int)SLIST->curr_level; \
+ \
+ if(_i < 0) \
+ HGOTO_DONE(NULL); \
+ \
+ H5_GLUE3(H5SL_LOCATE_,CMP,_HASHINIT)(KEY, HASHVAL) \
+ \
+ /* Find the gap to drop in to at the highest level */ \
+ while(X && (!X->key || H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE, X, KEY, HASHVAL))) { \
+ _llast = _last; \
+ _last = X; \
+ X = X->forward[_i]; \
+ } \
+ _next = X; \
+ \
+ /* Main loop */ \
+ for(_i--; _i >= 0; _i--) { \
+ /* Search for the node to drop into, also count the number of nodes */ \
+ /* of height _i in this gap and keep track of of the node before */ \
+ /* the one to drop into (_ldrop will become _llast, _drop will */ \
+ /* become _last). */ \
+ X = _ldrop = _last; \
+ _drop = NULL; \
+ for(_count = 0; ; _count++) { \
+ /* Terminate if this is the last node in the gap */ \
+ if(X->forward[_i] == _next) { \
+ if(!_drop) \
+ _drop = X; \
+ break; \
+ } /* end if */ \
+ \
+ /* If we have already found the node to drop into and there is */ \
+ /* more than one node in this gap, we can stop searching */ \
+ if(_drop) { \
+ HDassert(_count >= 1); \
+ _count = 2; \
+ break; \
+ } else { /* !_drop */ \
+ /* Check if this node is the start of the next gap */ \
+ if (!H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE, X->forward[_i], KEY, HASHVAL)) { \
+ _drop = X; \
+ /* Again check if we can stop searching */ \
+ if(_count) { \
+ _count = 2; \
+ break; \
+ } /* end if */ \
+ } /* end if */ \
+ else \
+ _ldrop = X; \
+ } /* end else */ \
+ \
+ /* No need to check the last node in the gap if there are 3, as */ \
+ /* there cannot be a fourth */ \
+ if(_count == 2) { \
+ if(!_drop) \
+ _drop = X->forward[_i]; \
+ break; \
+ } /* end if */ \
+ X = X->forward[_i]; \
+ } /* end for */ \
+ HDassert(_count >= 1 && _count <= 3); \
+ HDassert(!_drop->forward[_i] || \
+ !H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE, _drop->forward[_i], KEY, HASHVAL)); \
+ \
+ /* Check if we need to adjust node heights */ \
+ if(_count == 1) { \
+ /* Check if we are in the first gap */ \
+ if(_llast == _last) { \
+ /* We are in the first gap, count the number of nodes of */ \
+ /* height _i in the next gap. We need only check one node */ \
+ /* to see if we should promote the first node in the next */ \
+ /* gap */ \
+ _llast = _next->forward[_i+1]; \
+ \
+ /* Demote the separator node */ \
+ H5SL_DEMOTE(_next, _last) \
+ \
+ /* If there are 2 or more nodes, promote the first */ \
+ if(_next->forward[_i]->forward[_i] != _llast) { \
+ X = _next->forward[_i]; \
+ H5SL_PROMOTE(SLIST, X, _last) \
+ } else if(!_head->forward[_i+1]) { \
+ /* shrink the header */ \
+ HDassert(_i == SLIST->curr_level - 1); \
+ HDassert((size_t) SLIST->curr_level == _head->level); \
+ \
+ H5SL_SHRINK(_head, (size_t) (_i+1)) \
+ SLIST->curr_level--; \
+ } /* end else */ \
+ } else { \
+ /* We are not in the first gap, count the number of nodes */ \
+ /* of height _i in the previous gap. Note we "look ahead" */ \
+ /* in this loop so X has the value of the last node in the */ \
+ /* previous gap. */ \
+ X = _llast->forward[_i]; \
+ for(_count = 1; _count < 3 && X->forward[_i] != _last; _count++) \
+ X = X->forward[_i]; \
+ HDassert(X->forward[_i] == _last); \
+ \
+ /* Demote the separator node */ \
+ H5SL_DEMOTE(_last, _llast) \
+ \
+ /* If there are 2 or more nodes, promote the last */ \
+ if(_count >= 2) \
+ H5SL_PROMOTE(SLIST, X, _llast) \
+ else if(!_head->forward[_i+1]) { \
+ /* shrink the header */ \
+ HDassert(_i == SLIST->curr_level - 1); \
+ HDassert((size_t) SLIST->curr_level == _head->level); \
+ \
+ H5SL_SHRINK(_head, (size_t) (_i+1)) \
+ SLIST->curr_level--; \
+ } /* end else */ \
+ } /* end else */ \
+ } /* end if */ \
+ \
+ /* Prepare to drop down */ \
+ _llast = _ldrop; \
+ _last = _drop; \
+ _next = _drop->forward[_i]; \
+ } /* end for */ \
+ \
+ /* Check if we've found the node */ \
+ if(_next && H5_GLUE3(H5SL_LOCATE_,CMP,_EQ)(TYPE, _next, KEY, HASHVAL)) { \
+ void *tmp = _next->item; \
+ X = _next; \
+ \
+ /* If the node has a height > 0, swap it with its (lower) neighbor */ \
+ if(X->level) { \
+ X = X->backward; \
+ _next->key = X->key; \
+ _next->item = X->item; \
+ _next->hashval = X->hashval; \
+ } /* end if */ \
+ HDassert(!X->level); \
+ \
+ /* Remove the node */ \
+ X->backward->forward[0] = X->forward[0]; \
+ if(SLIST->last == X) \
+ SLIST->last = X->backward; \
+ else \
+ X->forward[0]->backward = X->backward; \
+ SLIST->nobjs--; \
+ (void)H5FL_FAC_FREE(H5SL_fac_g[0], X->forward); \
+ (void)H5FL_FREE(H5SL_node_t, X); \
+ \
+ HGOTO_DONE(tmp); \
+ } /* end if */ \
+}
+
/* Macro used to search for node */
-#define H5SL_SEARCH(CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL) \
- H5SL_LOCATE(SEARCH, CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL)
+#define H5SL_SEARCH(CMP, SLIST, X, TYPE, KEY, HASHVAL) \
+ H5SL_LOCATE(SEARCH, CMP, SLIST, X, TYPE, KEY, HASHVAL)
/* Macro used to find a node */
-#define H5SL_FIND(CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL) \
- H5SL_LOCATE(FIND, CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL)
+#define H5SL_FIND(CMP, SLIST, X, TYPE, KEY, HASHVAL) \
+ H5SL_LOCATE(FIND, CMP, SLIST, X, TYPE, KEY, HASHVAL)
/* Private typedefs & structs */
@@ -186,6 +475,7 @@ struct H5SL_node_t {
const void *key; /* Pointer to node's key */
void *item; /* Pointer to node's item */
size_t level; /* The level of this node */
+ size_t log_nalloc; /* log2(Number of slots allocated in forward) */
uint32_t hashval; /* Hash value for key (only for strings, currently) */
struct H5SL_node_t **forward; /* Array of forward pointers from this node */
struct H5SL_node_t *backward; /* Backward pointer from this node */
@@ -195,9 +485,6 @@ struct H5SL_node_t {
struct H5SL_t {
/* Static values for each list */
H5SL_type_t type; /* Type of skip list */
- double p; /* Probability of using a higher level [0..1) */
- int p1; /* Probability converted into appropriate value for random # generator on this machine */
- size_t max_level; /* Maximum number of levels */
/* Dynamic values for each list */
int curr_level; /* Current top level used in list */
@@ -207,8 +494,7 @@ struct H5SL_t {
};
/* Static functions */
-static size_t H5SL_random_level(int p1, size_t max_level);
-static H5SL_node_t * H5SL_new_node(size_t lvl, void *item, const void *key, uint32_t hashval);
+static H5SL_node_t * H5SL_new_node(void *item, const void *key, uint32_t hashval);
static H5SL_node_t *H5SL_insert_common(H5SL_t *slist, void *item, const void *key);
static herr_t H5SL_release_common(H5SL_t *slist, H5SL_operator_t op, void *op_data);
static herr_t H5SL_close_common(H5SL_t *slist, H5SL_operator_t op, void *op_data);
@@ -216,9 +502,13 @@ static herr_t H5SL_close_common(H5SL_t *slist, H5SL_operator_t op, void *op_data
/* Declare a free list to manage the H5SL_t struct */
H5FL_DEFINE_STATIC(H5SL_t);
-/* Declare a "base + array" list to manage the H5SL_node_t struct */
-typedef H5SL_node_t *H5SL_node_ptr_t;
-H5FL_BARR_DEFINE_STATIC(H5SL_node_t,H5SL_node_ptr_t,H5SL_LEVEL_MAX);
+/* Declare a free list to manage the H5SL_node_t struct */
+H5FL_DEFINE_STATIC(H5SL_node_t);
+
+/* Global variables */
+static H5FL_fac_head_t **H5SL_fac_g;
+static size_t H5SL_fac_nused_g;
+static size_t H5SL_fac_nalloc_g;
/*--------------------------------------------------------------------------
@@ -241,13 +531,15 @@ H5FL_BARR_DEFINE_STATIC(H5SL_node_t,H5SL_node_ptr_t,H5SL_LEVEL_MAX);
static herr_t
H5SL_init_interface(void)
{
- time_t curr_time; /* Current time, for seeding random number generator */
-
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_init_interface)
- /* Create randomized set of numbers */
- curr_time=HDtime(NULL);
- HDsrand((unsigned)curr_time);
+ /* Allocate space for array of factories */
+ H5SL_fac_g = (H5FL_fac_head_t **)H5MM_malloc(sizeof(H5FL_fac_head_t *));
+ H5SL_fac_nalloc_g = 1;
+
+ /* Initialize first factory */
+ H5SL_fac_g[0] = H5FL_fac_init(sizeof(H5SL_node_t *));
+ H5SL_fac_nused_g = 1;
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5SL_init_interface() */
@@ -255,87 +547,45 @@ H5SL_init_interface(void)
/*--------------------------------------------------------------------------
NAME
- H5SL_random_level
- PURPOSE
- Generate a random level
- USAGE
- size_t H5SL_random_level(p,max_level)
- int p1; IN: probability distribution
- size_t max_level; IN: Maximum level for node height
-
- RETURNS
- Returns non-negative level value
- DESCRIPTION
- Count elements in a skip list.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- Do we really need a 'random' value, or is a series of nodes with the
- correct heights "good enough". We could track the state of the nodes
- allocated for this list and issue node heights appropriately (i.e. 1,2,
- 1,4,1,2,1,8,...) (or would that be 1,1,2,1,1,2,4,... ?)
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-static size_t
-H5SL_random_level(int p1, size_t max_level)
-{
- size_t lvl; /* Level generated */
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_random_level);
-
- /* Account for starting at zero offset */
- max_level--;
-
- lvl=0;
- while(HDrand()<p1 && lvl < max_level)
- lvl++;
-
- FUNC_LEAVE_NOAPI(lvl);
-} /* end H5SL_random_level() */
-
-
-/*--------------------------------------------------------------------------
- NAME
H5SL_new_node
PURPOSE
- Create a new skip list node
+ Create a new skip list node of level 0
USAGE
- H5SL_node_t *H5SL_new_node(lvl,item,key)
- size_t lvl; IN: Level for node height
+ H5SL_node_t *H5SL_new_node(item,key,hasval)
void *item; IN: Pointer to item info for node
void *key; IN: Pointer to key info for node
+ uint32_t hashval; IN: Hash value for node
RETURNS
Returns a pointer to a skip list node on success, NULL on failure.
DESCRIPTION
- Create a new skip list node of the specified height, setting the item
+ Create a new skip list node of the height 0, setting the item
and key values internally.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
This routine does _not_ initialize the 'forward' pointers
-
- We should set up a custom free-list for allocating & freeing these sort
- of nodes.
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
static H5SL_node_t *
-H5SL_new_node(size_t lvl, void *item, const void *key, uint32_t hashval)
+H5SL_new_node(void *item, const void *key, uint32_t hashval)
{
H5SL_node_t *ret_value; /* New skip list node */
FUNC_ENTER_NOAPI_NOINIT(H5SL_new_node)
/* Allocate the node */
- if(NULL == (ret_value = H5FL_ARR_MALLOC(H5SL_node_ptr_t, (lvl + 1))))
+ if(NULL == (ret_value = (H5SL_node_t *)H5FL_MALLOC(H5SL_node_t)))
HGOTO_ERROR(H5E_SLIST, H5E_NOSPACE, NULL, "memory allocation failed")
/* Initialize node */
ret_value->key = key;
ret_value->item = item;
- ret_value->level = lvl;
+ ret_value->level = 0;
ret_value->hashval = hashval;
- ret_value->forward = (H5SL_node_t **)((unsigned char *)ret_value + sizeof(H5SL_node_t));
+ if(NULL == (ret_value->forward = (H5SL_node_t **)H5FL_FAC_MALLOC(H5SL_fac_g[0])))
+ HGOTO_ERROR(H5E_SLIST, H5E_NOSPACE, NULL, "memory allocation failed")
+ ret_value->log_nalloc = 0;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -366,18 +616,16 @@ done:
static H5SL_node_t *
H5SL_insert_common(H5SL_t *slist, void *item, const void *key)
{
- H5SL_node_t **update[H5SL_LEVEL_MAX]; /* 'update' vector */
H5SL_node_t *x; /* Current node to examine */
+ H5SL_node_t *prev; /* Node before the new node */
uint32_t hashval = 0; /* Hash value for key */
- size_t lvl; /* Level of new node */
- int i; /* Local index value */
H5SL_node_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5SL_insert_common);
/* Check args */
- assert(slist);
- assert(key);
+ HDassert(slist);
+ HDassert(key);
/* Check internal consistency */
/* (Pre-condition) */
@@ -387,72 +635,60 @@ H5SL_insert_common(H5SL_t *slist, void *item, const void *key)
/* Work through the forward pointers for a node, finding the node at each
* level that is before the location to insert
*/
- x=slist->header;
+ prev=slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_INSERT(SCALAR, slist, x, update, const int, key, -)
+ H5SL_INSERT(SCALAR, slist, prev, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_INSERT(SCALAR, slist, x, update, const haddr_t, key, -)
+ H5SL_INSERT(SCALAR, slist, prev, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_INSERT(STRING, slist, x, update, char *, key, hashval)
+ H5SL_INSERT(STRING, slist, prev, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_INSERT(SCALAR, slist, x, update, const hsize_t, key, -)
+ H5SL_INSERT(SCALAR, slist, prev, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_INSERT(SCALAR, slist, x, update, const unsigned, key, -)
+ H5SL_INSERT(SCALAR, slist, prev, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_INSERT(SCALAR, slist, x, update, const size_t, key, -)
+ H5SL_INSERT(SCALAR, slist, prev, const size_t, key, -)
break;
case H5SL_TYPE_OBJ:
- H5SL_INSERT(OBJ, slist, x, update, const H5_obj_t, key, -)
+ H5SL_INSERT(OBJ, slist, prev, const H5_obj_t, key, -)
break;
- } /* end switch */
- /* 'key' must not have been found in existing list, if we get here */
+ default:
+ HDassert(0 && "Unknown skiplist type!");
+ } /* end switch */
- /* Generate level for new node */
- lvl=H5SL_random_level(slist->p1,slist->max_level);
- if((int)lvl>slist->curr_level) {
- /* Cap the increase in the current level to just one greater */
- lvl=slist->curr_level+1;
- /* Set the update pointer correctly */
- update[lvl]=&slist->header->forward[lvl];
+ /* 'key' must not have been found in existing list, if we get here */
- /* Increase the maximum level of the list */
- slist->curr_level=(int)lvl;
- } /* end if */
+ if(slist->curr_level < 0)
+ slist->curr_level = 0;
- /* Create new node of proper level */
- if(NULL == (x = H5SL_new_node(lvl, item, key, hashval)))
+ /* Create new node of level 0 */
+ if(NULL == (x = H5SL_new_node(item, key, hashval)))
HGOTO_ERROR(H5E_SLIST ,H5E_NOSPACE, NULL, "can't create new skip list node")
- /* Update the backward links */
- if(*update[0]!=NULL) {
- x->backward=(*update[0])->backward;
- (*update[0])->backward=x;
- } /* end if */
+ /* Update the links */
+ x->backward = prev;
+ x->forward[0] = prev->forward[0];
+ prev->forward[0] = x;
+ if(x->forward[0])
+ x->forward[0]->backward = x;
else {
HDassert(slist->last);
- x->backward=slist->last;
- slist->last=x;
- } /* end else */
-
- /* Link the new node into the existing forward pointers */
- for(i=0; i<=(int)lvl; i++) {
- x->forward[i]=*update[i];
- *update[i]=x;
- } /* end for */
+ slist->last = x;
+ }
/* Increment the number of nodes in the skip list */
slist->nobjs++;
@@ -471,7 +707,7 @@ done:
PURPOSE
Release all nodes from a skip list, optionally calling a 'free' operator
USAGE
- herr_t H5SL_release_common(slist)
+ herr_t H5SL_release_common(slist,op,opdata)
H5SL_t *slist; IN/OUT: Pointer to skip list to release nodes
H5SL_operator_t op; IN: Callback function to free item & key
void *op_data; IN/OUT: Pointer to application data for callback
@@ -493,9 +729,9 @@ herr_t
H5SL_release_common(H5SL_t *slist, H5SL_operator_t op, void *op_data)
{
H5SL_node_t *node, *next_node; /* Pointers to skip list nodes */
- size_t u; /* Local index variable */
+ herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_release_common);
+ FUNC_ENTER_NOAPI_NOINIT(H5SL_release_common);
/* Check args */
assert(slist);
@@ -513,13 +749,18 @@ H5SL_release_common(H5SL_t *slist, H5SL_operator_t op, void *op_data)
/* Casting away const OK -QAK */
(void)(op)(node->item,(void *)node->key,op_data);
- H5FL_ARR_FREE(H5SL_node_ptr_t,node);
+ (void)H5FL_FAC_FREE(H5SL_fac_g[node->log_nalloc], node->forward);
+ (void)H5FL_FREE(H5SL_node_t, node);
node=next_node;
} /* end while */
/* Reset the header pointers */
- for(u=0; u<slist->max_level; u++)
- slist->header->forward[u]=NULL;
+ (void)H5FL_FAC_FREE(H5SL_fac_g[slist->header->log_nalloc], slist->header->forward);
+ if(NULL == (slist->header->forward = (H5SL_node_t **) H5FL_FAC_MALLOC(H5SL_fac_g[0])))
+ HGOTO_ERROR(H5E_SLIST, H5E_NOSPACE, FAIL, "memory allocation failed")
+ slist->header->forward[0] = NULL;
+ slist->header->log_nalloc = 0;
+ slist->header->level = 0;
/* Reset the last pointer */
slist->last=slist->header;
@@ -528,7 +769,8 @@ H5SL_release_common(H5SL_t *slist, H5SL_operator_t op, void *op_data)
slist->curr_level=-1;
slist->nobjs=0;
- FUNC_LEAVE_NOAPI(SUCCEED);
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
} /* end H5SL_release_common() */
@@ -558,24 +800,29 @@ H5SL_release_common(H5SL_t *slist, H5SL_operator_t op, void *op_data)
herr_t
H5SL_close_common(H5SL_t *slist, H5SL_operator_t op, void *op_data)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_close_common);
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5SL_close_common)
/* Check args */
- assert(slist);
+ HDassert(slist);
/* Check internal consistency */
/* (Pre-condition) */
/* Free skip list nodes */
- (void)H5SL_release_common(slist,op,op_data); /* always succeeds */
+ if(H5SL_release_common(slist, op, op_data) < 0)
+ HGOTO_ERROR(H5E_SLIST, H5E_CANTFREE, FAIL, "can't release skip list nodes")
/* Release header node */
- H5FL_ARR_FREE(H5SL_node_ptr_t,slist->header);
+ (void)H5FL_FAC_FREE(H5SL_fac_g[slist->header->log_nalloc], slist->header->forward);
+ (void)H5FL_FREE(H5SL_node_t, slist->header);
/* Free skip list object */
- H5FL_FREE(H5SL_t,slist);
+ (void)H5FL_FREE(H5SL_t, slist);
- FUNC_LEAVE_NOAPI(SUCCEED);
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SL_close_common() */
@@ -585,7 +832,7 @@ H5SL_close_common(H5SL_t *slist, H5SL_operator_t op, void *op_data)
PURPOSE
Create a skip list
USAGE
- H5SL_t *H5SL_create(void)
+ H5SL_t *H5SL_create(H5SL_type_t type)
RETURNS
Returns a pointer to a skip list on success, NULL on failure.
@@ -597,61 +844,53 @@ H5SL_close_common(H5SL_t *slist, H5SL_operator_t op, void *op_data)
REVISION LOG
--------------------------------------------------------------------------*/
H5SL_t *
-H5SL_create(H5SL_type_t type, double p, size_t max_level)
+H5SL_create(H5SL_type_t type)
{
- H5SL_t *new_slist=NULL; /* Pointer to new skip list object created */
+ H5SL_t *new_slist = NULL; /* Pointer to new skip list object created */
H5SL_node_t *header; /* Pointer to skip list header node */
- size_t u; /* Local index variable */
H5SL_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5SL_create,NULL);
/* Check args */
- HDassert(p>0.0 && p<1.0);
- HDassert(max_level>0 && max_level<=H5SL_LEVEL_MAX);
HDassert(type>=H5SL_TYPE_INT && type<=H5SL_TYPE_OBJ);
/* Allocate skip list structure */
- if((new_slist=H5FL_MALLOC(H5SL_t))==NULL)
- HGOTO_ERROR(H5E_SLIST,H5E_NOSPACE,NULL,"memory allocation failed");
+ if(NULL == (new_slist = H5FL_MALLOC(H5SL_t)))
+ HGOTO_ERROR(H5E_SLIST, H5E_NOSPACE, NULL, "memory allocation failed")
/* Set the static internal fields */
- new_slist->type=type;
- new_slist->p=p;
- new_slist->p1=(int)(p*RAND_MAX);
- new_slist->max_level=max_level;
+ new_slist->type = type;
/* Set the dynamic internal fields */
- new_slist->curr_level=-1;
- new_slist->nobjs=0;
+ new_slist->curr_level = -1;
+ new_slist->nobjs = 0;
/* Allocate the header node */
- if(NULL == (header = H5SL_new_node((max_level - 1), NULL, NULL, ULONG_MAX)))
+ if(NULL == (header = H5SL_new_node(NULL, NULL, ULONG_MAX)))
HGOTO_ERROR(H5E_SLIST ,H5E_NOSPACE, NULL, "can't create new skip list node")
- /* Initialize header node's forward pointers */
- for(u=0; u<max_level; u++)
- header->forward[u]=NULL;
+ /* Initialize header node's forward pointer */
+ header->forward[0] = NULL;
/* Initialize header node's backward pointer */
- header->backward=NULL;
+ header->backward = NULL;
/* Attach the header */
- new_slist->header=header;
- new_slist->last=header;
+ new_slist->header = header;
+ new_slist->last = header;
/* Set the return value */
- ret_value=new_slist;
+ ret_value = new_slist;
done:
/* Error cleanup */
- if(ret_value==NULL) {
- if(new_slist!=NULL) {
- H5FL_FREE(H5SL_t,new_slist);
- } /* end if */
+ if(ret_value == NULL) {
+ if(new_slist != NULL)
+ (void)H5FL_FREE(H5SL_t, new_slist);
} /* end if */
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SL_create() */
@@ -801,16 +1040,15 @@ done:
void *
H5SL_remove(H5SL_t *slist, const void *key)
{
- H5SL_node_t **update[H5SL_LEVEL_MAX]; /* 'update' vector */
H5SL_node_t *x; /* Current node to examine */
uint32_t hashval = 0; /* Hash value for key */
- void *ret_value=NULL; /* Return value */
+ void *ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_remove);
+ FUNC_ENTER_NOAPI_NOINIT(H5SL_remove)
/* Check args */
- assert(slist);
- assert(key);
+ HDassert(slist);
+ HDassert(key);
/* Check internal consistency */
/* (Pre-condition) */
@@ -820,39 +1058,42 @@ H5SL_remove(H5SL_t *slist, const void *key)
/* Work through the forward pointers for a node, finding the node at each
* level that is before the location to remove
*/
- x=slist->header;
+ x = slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_REMOVE(SCALAR, slist, x, update, const int, key, -)
+ H5SL_REMOVE(SCALAR, slist, x, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_REMOVE(SCALAR, slist, x, update, const haddr_t, key, -)
+ H5SL_REMOVE(SCALAR, slist, x, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_REMOVE(STRING, slist, x, update, char *, key, hashval)
+ H5SL_REMOVE(STRING, slist, x, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_REMOVE(SCALAR, slist, x, update, const hsize_t, key, -)
+ H5SL_REMOVE(SCALAR, slist, x, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_REMOVE(SCALAR, slist, x, update, const unsigned, key, -)
+ H5SL_REMOVE(SCALAR, slist, x, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_REMOVE(SCALAR, slist, x, update, const size_t, key, -)
+ H5SL_REMOVE(SCALAR, slist, x, const size_t, key, -)
break;
case H5SL_TYPE_OBJ:
- H5SL_REMOVE(OBJ, slist, x, update, const H5_obj_t, key, -)
+ H5SL_REMOVE(OBJ, slist, x, const H5_obj_t, key, -)
break;
+
+ default:
+ HDassert(0 && "Unknown skiplist type!");
} /* end switch */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SL_remove() */
@@ -871,8 +1112,6 @@ done:
Remove first element from a skip list.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
- This algorithm is basically the same as the one in the
- H5SL_LOCATE_REMOVE_FOUND macro, fix bugs in both places
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
@@ -880,8 +1119,13 @@ void *
H5SL_remove_first(H5SL_t *slist)
{
void *ret_value = NULL; /* Return value */
+ H5SL_node_t *head = slist->header; /* Skip list header */
+ H5SL_node_t *tmp = slist->header->forward[0]; /* Temporary node pointer */
+ H5SL_node_t *next; /* Next node to search for */
+ size_t level = slist->curr_level; /* Skip list level */
+ size_t i; /* Index */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_remove_first)
+ FUNC_ENTER_NOAPI_NOINIT(H5SL_remove_first)
/* Check args */
HDassert(slist);
@@ -893,39 +1137,62 @@ H5SL_remove_first(H5SL_t *slist)
/* Check for empty list */
if(slist->last != slist->header) {
- H5SL_node_t *x; /* Current node to examine */
- int i; /* Local index value */
- /* Get pointer to first node on the list */
- x = slist->header->forward[0];
+ /* Assign return value */
+ ret_value = tmp->item;
+ HDassert(level == head->level);
+ HDassert(0 == tmp->level);
- /* Patch forward pointers in list header around node to remove */
- for(i = 0; i <= (int)slist->curr_level; i++) {
- if(slist->header->forward[i] != x)
- break;
- slist->header->forward[i] = x->forward[i];
- } /* end for */
-
- /* Update tail/backward pointer */
- if(slist->last == x)
- slist->last = x->backward;
+ /* Remove the first node */
+ head->forward[0] = tmp->forward[0];
+ if(slist->last == tmp)
+ slist->last = head;
else
- x->forward[0]->backward = x->backward;
-
- /* Get the item to return */
- ret_value = x->item;
-
- /* Free the skip list node */
- H5FL_ARR_FREE(H5SL_node_ptr_t, x);
-
- /* Lower the level of the list, if we removed the tallest node */
- while(slist->curr_level > 0 && slist->header->forward[slist->curr_level] == NULL)
- slist->curr_level--;
-
- /* Decrement the # of objects in the list */
+ tmp->forward[0]->backward = head;
slist->nobjs--;
+ /* Free memory */
+ (void)H5FL_FAC_FREE(H5SL_fac_g[0], tmp->forward);
+ (void)H5FL_FREE(H5SL_node_t, tmp);
+
+ /* Reshape the skip list as necessary to maintain 1-2-3 condition */
+ for(i=0; i < level; i++) {
+ next = head->forward[i+1];
+ HDassert(next);
+
+ /* Check if head->forward[i] == head->forward[i+1] (illegal) */
+ if(head->forward[i] == next) {
+ tmp = next;
+ next = next->forward[i+1];
+
+ HDassert(tmp->level == i+1);
+
+ /* Demote head->forward[i] */
+ H5SL_DEMOTE(tmp, head)
+
+ /* Check if we need to promote the following node to maintain
+ * 1-2-3 condition */
+ if(tmp->forward[i]->forward[i] != next) {
+ HDassert(tmp->forward[i]->forward[i]->forward[i] == next ||
+ tmp->forward[i]->forward[i]->forward[i]->forward[i] == next);
+ tmp = tmp->forward[i];
+ H5SL_PROMOTE(slist, tmp, head);
+ /* In this case, since there is a node of height = i+1 here
+ * now (tmp), we know the skip list must be valid and can
+ * break */
+ break;
+ } else if(!head->forward[i+1]) {
+ /* We just shrunk the largest node, shrink the header */
+ HDassert(i == level - 1);
+
+ H5SL_SHRINK(head, level)
+ slist->curr_level--;
+ } /* end else */
+ } else
+ break;
+ } /* end for */
} /* end if */
+done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SL_remove_first() */
@@ -973,32 +1240,35 @@ H5SL_search(H5SL_t *slist, const void *key)
x=slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_SEARCH(SCALAR, slist, x, -, const int, key, -)
+ H5SL_SEARCH(SCALAR, slist, x, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_SEARCH(SCALAR, slist, x, -, const haddr_t, key, -)
+ H5SL_SEARCH(SCALAR, slist, x, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_SEARCH(STRING, slist, x, -, char *, key, hashval)
+ H5SL_SEARCH(STRING, slist, x, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, const hsize_t, key, -)
+ H5SL_SEARCH(SCALAR, slist, x, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_SEARCH(SCALAR, slist, x, -, const unsigned, key, -)
+ H5SL_SEARCH(SCALAR, slist, x, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, const size_t, key, -)
+ H5SL_SEARCH(SCALAR, slist, x, const size_t, key, -)
break;
case H5SL_TYPE_OBJ:
- H5SL_SEARCH(OBJ, slist, x, -, const H5_obj_t, key, -)
+ H5SL_SEARCH(OBJ, slist, x, const H5_obj_t, key, -)
break;
+
+ default:
+ HDassert(0 && "Unknown skiplist type!");
} /* end switch */
/* 'key' must not have been found in list, if we get here */
@@ -1055,32 +1325,35 @@ H5SL_less(H5SL_t *slist, const void *key)
x=slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_SEARCH(SCALAR, slist, x, -, const int, key, -)
+ H5SL_SEARCH(SCALAR, slist, x, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_SEARCH(SCALAR, slist, x, -, const haddr_t, key, -)
+ H5SL_SEARCH(SCALAR, slist, x, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_SEARCH(STRING, slist, x, -, char *, key, hashval)
+ H5SL_SEARCH(STRING, slist, x, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, const hsize_t, key, -)
+ H5SL_SEARCH(SCALAR, slist, x, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_SEARCH(SCALAR, slist, x, -, const unsigned, key, -)
+ H5SL_SEARCH(SCALAR, slist, x, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, const size_t, key, -)
+ H5SL_SEARCH(SCALAR, slist, x, const size_t, key, -)
break;
case H5SL_TYPE_OBJ:
- H5SL_SEARCH(OBJ, slist, x, -, const H5_obj_t, key, -)
+ H5SL_SEARCH(OBJ, slist, x, const H5_obj_t, key, -)
break;
+
+ default:
+ HDassert(0 && "Unknown skiplist type!");
} /* end switch */
/* An exact match for 'key' must not have been found in list, if we get here */
@@ -1150,32 +1423,35 @@ H5SL_greater(H5SL_t *slist, const void *key)
x = slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_SEARCH(SCALAR, slist, x, -, const int, key, -)
+ H5SL_SEARCH(SCALAR, slist, x, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_SEARCH(SCALAR, slist, x, -, const haddr_t, key, -)
+ H5SL_SEARCH(SCALAR, slist, x, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_SEARCH(STRING, slist, x, -, char *, key, hashval)
+ H5SL_SEARCH(STRING, slist, x, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, const hsize_t, key, -)
+ H5SL_SEARCH(SCALAR, slist, x, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_SEARCH(SCALAR, slist, x, -, const unsigned, key, -)
+ H5SL_SEARCH(SCALAR, slist, x, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, const size_t, key, -)
+ H5SL_SEARCH(SCALAR, slist, x, const size_t, key, -)
break;
case H5SL_TYPE_OBJ:
- H5SL_SEARCH(OBJ, slist, x, -, const H5_obj_t, key, -)
+ H5SL_SEARCH(OBJ, slist, x, const H5_obj_t, key, -)
break;
+
+ default:
+ HDassert(0 && "Unknown skiplist type!");
} /* end switch */
/* An exact match for 'key' must not have been found in list, if we get here */
@@ -1235,32 +1511,35 @@ H5SL_find(H5SL_t *slist, const void *key)
x=slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_FIND(SCALAR, slist, x, -, const int, key, -)
+ H5SL_FIND(SCALAR, slist, x, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_FIND(SCALAR, slist, x, -, const haddr_t, key, -)
+ H5SL_FIND(SCALAR, slist, x, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_FIND(STRING, slist, x, -, char *, key, hashval)
+ H5SL_FIND(STRING, slist, x, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_FIND(SCALAR, slist, x, -, const hsize_t, key, -)
+ H5SL_FIND(SCALAR, slist, x, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_FIND(SCALAR, slist, x, -, const unsigned, key, -)
+ H5SL_FIND(SCALAR, slist, x, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_FIND(SCALAR, slist, x, -, const size_t, key, -)
+ H5SL_FIND(SCALAR, slist, x, const size_t, key, -)
break;
case H5SL_TYPE_OBJ:
- H5SL_FIND(OBJ, slist, x, -, const H5_obj_t, key, -)
+ H5SL_FIND(OBJ, slist, x, const H5_obj_t, key, -)
break;
+
+ default:
+ HDassert(0 && "Unknown skiplist type!");
} /* end switch */
/* 'key' must not have been found in list, if we get here */
@@ -1273,6 +1552,187 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5SL_below
+ PURPOSE
+ Search for _node_ in a skip list whose object is less than or equal to 'key'
+ USAGE
+ H5SL_node_t *H5SL_below(slist, key)
+ H5SL_t *slist; IN/OUT: Pointer to skip list
+ void *key; IN: Key for item to search for
+
+ RETURNS
+ Returns pointer to _node_ who key is less than or equal to 'key' on success,
+ NULL on failure
+ DESCRIPTION
+ Search for a node with an object in a skip list, according to it's key,
+ returning the node itself (for an exact match), or the node with the next
+ highest key that is less than 'key'
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+H5SL_node_t *
+H5SL_below(H5SL_t *slist, const void *key)
+{
+ H5SL_node_t *x; /* Current node to examine */
+ uint32_t hashval = 0; /* Hash value for key */
+ H5SL_node_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_below)
+
+ /* Check args */
+ HDassert(slist);
+ HDassert(key);
+
+ /* Check internal consistency */
+ /* (Pre-condition) */
+
+ /* Insert item into skip list */
+
+ /* Work through the forward pointers for a node, finding the node at each
+ * level that is before the location to insert
+ */
+ x = slist->header;
+ switch(slist->type) {
+ case H5SL_TYPE_INT:
+ H5SL_FIND(SCALAR, slist, x, const int, key, -)
+ break;
+
+ case H5SL_TYPE_HADDR:
+ H5SL_FIND(SCALAR, slist, x, const haddr_t, key, -)
+ break;
+
+ case H5SL_TYPE_STR:
+ H5SL_FIND(STRING, slist, x, char *, key, hashval)
+ break;
+
+ case H5SL_TYPE_HSIZE:
+ H5SL_FIND(SCALAR, slist, x, const hsize_t, key, -)
+ break;
+
+ case H5SL_TYPE_UNSIGNED:
+ H5SL_FIND(SCALAR, slist, x, const unsigned, key, -)
+ break;
+
+ case H5SL_TYPE_SIZE:
+ H5SL_FIND(SCALAR, slist, x, const size_t, key, -)
+ break;
+
+ case H5SL_TYPE_OBJ:
+ H5SL_FIND(OBJ, slist, x, const H5_obj_t, key, -)
+ break;
+ } /* end switch */
+
+ /* An exact match for 'key' must not have been found in list, if we get here */
+ /* Check for a node with a key that is less than the given 'key' */
+ if(NULL == x) {
+ /* Check for walking off the list */
+ if(slist->last != slist->header)
+ ret_value = slist->last;
+ else
+ ret_value = NULL;
+ } /* end if */
+ else {
+ if(x->backward != slist->header)
+ ret_value = x->backward;
+ else
+ ret_value = NULL;
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5SL_below() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5SL_above
+ PURPOSE
+ Search for _node_ in a skip list whose object is greater than or equal to 'key'
+ USAGE
+ H5SL_node_t *H5SL_above(slist, key)
+ H5SL_t *slist; IN/OUT: Pointer to skip list
+ void *key; IN: Key for item to search for
+
+ RETURNS
+ Returns pointer to _node_ with object that has a key is greater than or
+ equal to 'key' on success, NULL on failure
+ DESCRIPTION
+ Search for a node with an object in a skip list, according to it's key,
+ returning the node itself (for an exact match), or the node with the next
+ lowest key that is greater than 'key'
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+H5SL_node_t *
+H5SL_above(H5SL_t *slist, const void *key)
+{
+ H5SL_node_t *x; /* Current node to examine */
+ uint32_t hashval = 0; /* Hash value for key */
+ H5SL_node_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_above)
+
+ /* Check args */
+ HDassert(slist);
+ HDassert(key);
+
+ /* Check internal consistency */
+ /* (Pre-condition) */
+
+ /* Insert item into skip list */
+
+ /* Work through the forward pointers for a node, finding the node at each
+ * level that is before the location to insert
+ */
+ x = slist->header;
+ switch(slist->type) {
+ case H5SL_TYPE_INT:
+ H5SL_FIND(SCALAR, slist, x, const int, key, -)
+ break;
+
+ case H5SL_TYPE_HADDR:
+ H5SL_FIND(SCALAR, slist, x, const haddr_t, key, -)
+ break;
+
+ case H5SL_TYPE_STR:
+ H5SL_FIND(STRING, slist, x, char *, key, hashval)
+ break;
+
+ case H5SL_TYPE_HSIZE:
+ H5SL_FIND(SCALAR, slist, x, const hsize_t, key, -)
+ break;
+
+ case H5SL_TYPE_UNSIGNED:
+ H5SL_FIND(SCALAR, slist, x, const unsigned, key, -)
+ break;
+
+ case H5SL_TYPE_SIZE:
+ H5SL_FIND(SCALAR, slist, x, const size_t, key, -)
+ break;
+
+ case H5SL_TYPE_OBJ:
+ H5SL_FIND(OBJ, slist, x, const H5_obj_t, key, -)
+ break;
+ } /* end switch */
+
+ /* An exact match for 'key' must not have been found in list, if we get here */
+ /* ('x' must be the next node with a key greater than the 'key', or NULL) */
+ if(x)
+ ret_value = x;
+ else
+ ret_value = NULL;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5SL_above() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5SL_first
PURPOSE
Gets a pointer to the first node in a skip list
@@ -1479,28 +1939,28 @@ herr_t
H5SL_iterate(H5SL_t *slist, H5SL_operator_t op, void *op_data)
{
H5SL_node_t *node; /* Pointers to skip list nodes */
- herr_t ret_value=0; /* Return value */
+ herr_t ret_value = 0; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_iterate);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_iterate)
/* Check args */
- assert(slist);
+ HDassert(slist);
/* Check internal consistency */
/* (Pre-condition) */
/* Free skip list nodes */
- node=slist->header->forward[0];
- while(node!=NULL) {
+ node = slist->header->forward[0];
+ while(node != NULL) {
/* Call the iterator callback */
/* Casting away const OK -QAK */
- if((ret_value=(op)(node->item,(void *)node->key,op_data))!=0)
+ if((ret_value = (op)(node->item, (void *)node->key, op_data)) != 0)
break;
- node=node->forward[0];
+ node = node->forward[0];
} /* end while */
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SL_iterate() */
@@ -1670,3 +2130,50 @@ H5SL_close(H5SL_t *slist)
FUNC_LEAVE_NOAPI(SUCCEED);
} /* end H5SL_close() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5SL_term_interface
+ PURPOSE
+ Terminate all the H5FL factories used in this package, and clear memory
+ USAGE
+ int H5SL_term_interface()
+ RETURNS
+ Success: Positive if any action might have caused a change in some
+ other interface; zero otherwise.
+ Failure: Negative
+ DESCRIPTION
+ Release any resources allocated.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Can't report errors...
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+int H5SL_term_interface(void)
+{
+ size_t i;
+ herr_t ret;
+ int n = H5_interface_initialize_g ? 1 : 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_term_interface)
+
+ if(n) {
+ /* Terminate all the factories */
+ for(i=0; i<H5SL_fac_nused_g; i++) {
+ ret = H5FL_fac_term(H5SL_fac_g[i]);
+ HDassert(ret >= 0);
+ }
+ H5SL_fac_nused_g = 0;
+
+ /* Free the list of factories */
+ H5SL_fac_g = (H5FL_fac_head_t **)H5MM_xfree((void *)H5SL_fac_g);
+ H5SL_fac_nalloc_g = 0;
+
+ /* Mark the interface as uninitialized */
+ H5_interface_initialize_g = 0;
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(n);
+} /* H5SL_term_interface() */
+
diff --git a/src/H5SLprivate.h b/src/H5SLprivate.h
index 9f73893..40fbfa9 100644
--- a/src/H5SLprivate.h
+++ b/src/H5SLprivate.h
@@ -53,7 +53,6 @@ typedef enum {
/**********/
/* Macros */
/**********/
-#define H5SL_LEVEL_MAX 32 /* (for now) */
/* Typedef for iteration operations */
typedef herr_t (*H5SL_operator_t)(void *item, void *key,
@@ -62,7 +61,7 @@ typedef herr_t (*H5SL_operator_t)(void *item, void *key,
/********************/
/* Private routines */
/********************/
-H5_DLL H5SL_t *H5SL_create(H5SL_type_t type, double p, size_t max_level);
+H5_DLL H5SL_t *H5SL_create(H5SL_type_t type);
H5_DLL size_t H5SL_count(H5SL_t *slist);
H5_DLL herr_t H5SL_insert(H5SL_t *slist, void *item, const void *key);
H5_DLL H5SL_node_t *H5SL_add(H5SL_t *slist, void *item, const void *key);
@@ -72,6 +71,8 @@ H5_DLL void *H5SL_search(H5SL_t *slist, const void *key);
H5_DLL void *H5SL_less(H5SL_t *slist, const void *key);
H5_DLL void *H5SL_greater(H5SL_t *slist, const void *key);
H5_DLL H5SL_node_t *H5SL_find(H5SL_t *slist, const void *key);
+H5_DLL H5SL_node_t *H5SL_below(H5SL_t *slist, const void *key);
+H5_DLL H5SL_node_t *H5SL_above(H5SL_t *slist, const void *key);
H5_DLL H5SL_node_t *H5SL_first(H5SL_t *slist);
H5_DLL H5SL_node_t *H5SL_next(H5SL_node_t *slist_node);
H5_DLL H5SL_node_t *H5SL_prev(H5SL_node_t *slist_node);
@@ -82,6 +83,7 @@ H5_DLL herr_t H5SL_release(H5SL_t *slist);
H5_DLL herr_t H5SL_free(H5SL_t *slist, H5SL_operator_t op, void *op_data);
H5_DLL herr_t H5SL_close(H5SL_t *slist);
H5_DLL herr_t H5SL_destroy(H5SL_t *slist, H5SL_operator_t op, void *op_data);
+H5_DLL int H5SL_term_interface(void);
#endif /* _H5SLprivate_H */
diff --git a/src/H5SM.c b/src/H5SM.c
index 97ef635..9a97d88 100755
--- a/src/H5SM.c
+++ b/src/H5SM.c
@@ -43,6 +43,7 @@
/******************/
/* Local Typedefs */
/******************/
+
/* Udata struct for calls to H5SM_read_iter_op */
typedef struct H5SM_read_udata_t {
H5F_t *file; /* File in which sharing is happening (in) */
@@ -70,7 +71,7 @@ static herr_t H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
unsigned *cache_flags_ptr);
static herr_t H5SM_decr_ref(void *record, void *op_data, hbool_t *changed);
static herr_t H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
- H5SM_index_header_t *header, const H5O_shared_t * mesg,
+ H5SM_index_header_t *header, const H5O_shared_t * mesg,
unsigned *cache_flags, void ** /*out*/ encoded_mesg);
static herr_t H5SM_type_to_flag(unsigned type_id, unsigned *type_flag);
static herr_t H5SM_read_iter_op(H5O_t *oh, H5O_mesg_t *mesg, unsigned sequence,
@@ -139,34 +140,34 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d
/* File should not already have a SOHM table */
HDassert(f->shared->sohm_addr == HADDR_UNDEF);
- /* Initialize master table */
- if(NULL == (table = H5FL_MALLOC(H5SM_master_table_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for SOHM table")
-
/* Get information from fcpl */
if(H5P_get(fc_plist, H5F_CRT_SHMSG_NINDEXES_NAME, &num_indexes)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get number of indexes")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get number of indexes")
if(H5P_get(fc_plist, H5F_CRT_SHMSG_INDEX_TYPES_NAME, &index_type_flags)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM type flags")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get SOHM type flags")
if(H5P_get(fc_plist, H5F_CRT_SHMSG_LIST_MAX_NAME, &list_max)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM list maximum")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get SOHM list maximum")
if(H5P_get(fc_plist, H5F_CRT_SHMSG_BTREE_MIN_NAME, &btree_min)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM btree minimum")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get SOHM btree minimum")
if(H5P_get(fc_plist, H5F_CRT_SHMSG_INDEX_MINSIZE_NAME, &minsizes) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM message min sizes")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get SOHM message min sizes")
/* Verify that values are valid */
if(num_indexes > H5O_SHMESG_MAX_NINDEXES)
- HGOTO_ERROR(H5E_PLIST, H5E_BADRANGE, FAIL, "number of indexes in property list is too large")
+ HGOTO_ERROR(H5E_SOHM, H5E_BADRANGE, FAIL, "number of indexes in property list is too large")
/* Check that type flags weren't duplicated anywhere */
type_flags_used = 0;
for(x = 0; x < num_indexes; ++x) {
if(index_type_flags[x] & type_flags_used)
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "the same shared message type flag is assigned to more than one index")
+ HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, FAIL, "the same shared message type flag is assigned to more than one index")
type_flags_used |= index_type_flags[x];
} /* end for */
+ /* Initialize master table */
+ if(NULL == (table = H5FL_MALLOC(H5SM_master_table_t)))
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "memory allocation failed for SOHM table")
+
/* Set version and number of indexes in table and in superblock.
* Right now we just use one byte to hold the number of indexes.
*/
@@ -183,7 +184,7 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d
/* Allocate the SOHM indexes as an array. */
if(NULL == (table->indexes = (H5SM_index_header_t *)H5FL_ARR_MALLOC(H5SM_index_header_t, (size_t)table->num_indexes)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for SOHM indexes")
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "memory allocation failed for SOHM indexes")
/* Initialize all of the indexes, but don't allocate space for them to
* hold messages until we actually need to write to them.
@@ -206,13 +207,13 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d
} /* end for */
/* Allocate space for the table on disk */
- table_size = (hsize_t) H5SM_TABLE_SIZE(f) + (hsize_t) (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f));
+ table_size = H5SM_TABLE_SIZE(f) + (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f));
if(HADDR_UNDEF == (table_addr = H5MF_alloc(f, H5FD_MEM_SOHM_TABLE, dxpl_id, table_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for SOHM table")
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "file allocation failed for SOHM table")
/* Cache the new table */
if(H5AC_set(f, dxpl_id, H5AC_SOHM_TABLE, table_addr, table, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "can't add SOHM table to cache")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTINS, FAIL, "can't add SOHM table to cache")
/* Record the address of the master table in the file */
f->shared->sohm_addr = table_addr;
@@ -235,7 +236,7 @@ done:
if(table_addr != HADDR_UNDEF)
H5MF_xfree(f, H5FD_MEM_SOHM_TABLE, dxpl_id, table_addr, (hsize_t)H5SM_TABLE_SIZE(f));
if(table != NULL)
- H5FL_FREE(H5SM_master_table_t, table);
+ table = H5FL_FREE(H5SM_master_table_t, table);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -276,7 +277,7 @@ H5SM_type_to_flag(unsigned type_id, unsigned *type_flag)
break;
default:
- HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL, "unknown message type ID")
+ HGOTO_ERROR(H5E_SOHM, H5E_BADTYPE, FAIL, "unknown message type ID")
} /* end switch */
done:
@@ -311,7 +312,7 @@ H5SM_get_index(const H5SM_master_table_t *table, unsigned type_id)
/* Translate the H5O type_id into an H5SM type flag */
if(H5SM_type_to_flag(type_id, &type_flag) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't map message type to flag")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't map message type to flag")
/* Search the indexes until we find one that matches this flag or we've
* searched them all.
@@ -352,12 +353,12 @@ H5SM_type_shared(H5F_t *f, unsigned type_id, hid_t dxpl_id)
/* Translate the H5O type_id into an H5SM type flag */
if(H5SM_type_to_flag(type_id, &type_flag) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't map message type to flag")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't map message type to flag")
/* Look up the master SOHM table */
if(H5F_addr_defined(f->shared->sohm_addr)) {
if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
} /* end if */
else
/* No shared messages of any type */
@@ -373,7 +374,7 @@ H5SM_type_shared(H5F_t *f, unsigned type_id, hid_t dxpl_id)
done:
/* Release the master SOHM table */
if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_type_shared() */
@@ -407,7 +408,7 @@ H5SM_get_fheap_addr(H5F_t *f, hid_t dxpl_id, unsigned type_id, haddr_t *fheap_ad
/* Look up the master SOHM table */
if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
/* Look up index for message type */
if((index_num = H5SM_get_index(table, type_id)) < 0)
@@ -419,7 +420,7 @@ H5SM_get_fheap_addr(H5F_t *f, hid_t dxpl_id, unsigned type_id, haddr_t *fheap_ad
done:
/* Release the master SOHM table */
if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_get_fheap_addr() */
@@ -440,36 +441,50 @@ done:
static herr_t
H5SM_create_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id)
{
- haddr_t list_addr=HADDR_UNDEF; /* Address of SOHM list */
- haddr_t tree_addr=HADDR_UNDEF; /* Address of SOHM B-tree */
- H5HF_create_t fheap_cparam; /* Fractal heap creation parameters */
- H5HF_t *fheap = NULL;
+ H5HF_create_t fheap_cparam; /* Fractal heap creation parameters */
+ H5HF_t *fheap = NULL; /* Fractal heap handle */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5SM_create_index)
+ /* Sanity check */
HDassert(header);
HDassert(header->index_addr == HADDR_UNDEF);
HDassert(header->btree_min <= header->list_max + 1);
/* In most cases, the index starts as a list */
if(header->list_max > 0) {
- header->index_type = H5SM_LIST;
+ haddr_t list_addr = HADDR_UNDEF; /* Address of SOHM list */
+ /* Create the list index */
if((list_addr = H5SM_create_list(f, header, dxpl_id)) == HADDR_UNDEF)
HGOTO_ERROR(H5E_SOHM, H5E_CANTCREATE, FAIL, "list creation failed for SOHM index")
+ /* Set the index type & address */
+ header->index_type = H5SM_LIST;
header->index_addr = list_addr;
} /* end if */
/* index is a B-tree */
else {
+ H5B2_create_t bt2_cparam; /* v2 B-tree creation parameters */
+ haddr_t tree_addr = HADDR_UNDEF; /* Address of SOHM B-tree */
+
+ /* Create the v2 B-tree index */
+ bt2_cparam.cls = H5SM_INDEX;
+ bt2_cparam.node_size = (size_t)H5SM_B2_NODE_SIZE;
+ bt2_cparam.rrec_size = (size_t)H5SM_SOHM_ENTRY_SIZE(f);
+ bt2_cparam.split_percent = H5SM_B2_SPLIT_PERCENT;
+ bt2_cparam.merge_percent = H5SM_B2_MERGE_PERCENT;
+ if(NULL == (bt2 = H5B2_create(f, dxpl_id, &bt2_cparam, f)))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTCREATE, FAIL, "B-tree creation failed for SOHM index")
+
+ /* Retrieve the v2 B-tree's address in the file */
+ if(H5B2_get_addr(bt2, &tree_addr) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get v2 B-tree address for SOHM index")
+
+ /* Set the index type & address */
header->index_type = H5SM_BTREE;
-
- if(H5B2_create(f, dxpl_id, H5SM_INDEX, (size_t)H5SM_B2_NODE_SIZE,
- (size_t)H5SM_SOHM_ENTRY_SIZE(f), H5SM_B2_SPLIT_PERCENT,
- H5SM_B2_MERGE_PERCENT, &tree_addr) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTCREATE, FAIL, "B-tree creation failed for SOHM index")
-
header->index_addr = tree_addr;
} /* end else */
@@ -484,10 +499,10 @@ H5SM_create_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id)
fheap_cparam.id_len = 0;
fheap_cparam.max_man_size = H5O_FHEAP_MAX_MAN_SIZE;
if(NULL == (fheap = H5HF_create(f, dxpl_id, &fheap_cparam)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "unable to create fractal heap")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTINIT, FAIL, "unable to create fractal heap")
if(H5HF_get_heap_addr(fheap, &(header->heap_addr)) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTGETSIZE, FAIL, "can't get fractal heap address")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGETSIZE, FAIL, "can't get fractal heap address")
#ifndef NDEBUG
{
@@ -495,15 +510,17 @@ H5SM_create_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id)
/* Sanity check ID length */
if(H5HF_get_id_len(fheap, &fheap_id_len) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTGETSIZE, FAIL, "can't get fractal heap ID length")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGETSIZE, FAIL, "can't get fractal heap ID length")
HDassert(fheap_id_len == H5O_FHEAP_ID_LEN);
}
#endif /* NDEBUG */
done:
- /* Close the fractal heap if one has been created */
+ /* Release resources */
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap")
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_create_index */
@@ -529,30 +546,38 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5SM_delete_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id, hbool_t delete_heap)
+H5SM_delete_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id,
+ hbool_t delete_heap)
{
- hsize_t list_size; /* Size of list on disk */
- herr_t ret_value = SUCCEED;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5SM_delete_index)
/* Determine whether index is a list or a B-tree. */
if(header->index_type == H5SM_LIST) {
- /* Eject entry from cache */
- if(H5AC_expunge_entry(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "unable to remove list index from cache")
-
- /* Free the file space used */
- list_size = H5SM_LIST_SIZE(f, header->list_max);
- if(H5MF_xfree(f, H5FD_MEM_SOHM_INDEX, dxpl_id, header->index_addr, list_size) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to free shared message list")
+ unsigned index_status = 0; /* Index list's status in the metadata cache */
+
+ /* Check the index list's status in the metadata cache */
+ if(H5AC_get_entry_status(f, header->index_addr, &index_status) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "unable to check metadata cache status for direct block")
+
+ /* If the index list is in the cache, expunge it now */
+ if(index_status & H5AC_ES__IN_CACHE) {
+ /* Sanity checks on index list */
+ HDassert(!(index_status & H5AC_ES__IS_PINNED));
+ HDassert(!(index_status & H5AC_ES__IS_PROTECTED));
+
+ /* Evict the index list from the metadata cache */
+ if(H5AC_expunge_entry(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, H5AC__FREE_FILE_SPACE_FLAG) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTREMOVE, FAIL, "unable to remove list index from cache")
+ } /* end if */
} /* end if */
else {
HDassert(header->index_type == H5SM_BTREE);
- /* Delete from the B-tree. */
- if(H5B2_delete(f, dxpl_id, H5SM_INDEX, header->index_addr, NULL, NULL) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete B-tree")
+ /* Delete the B-tree. */
+ if(H5B2_delete(f, dxpl_id, header->index_addr, f, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTDELETE, FAIL, "unable to delete B-tree")
/* Revert to list unless B-trees can have zero records */
if(header->btree_min > 0)
@@ -609,9 +634,9 @@ H5SM_create_list(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id)
/* Allocate list in memory */
if((list = H5FL_MALLOC(H5SM_list_t)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list")
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list")
if((list->messages = (H5SM_sohm_t *)H5FL_ARR_MALLOC(H5SM_sohm_t, num_entries)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list")
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list")
/* Initialize messages in list */
HDmemset(list->messages, 0, sizeof(H5SM_sohm_t) * num_entries);
@@ -624,11 +649,11 @@ H5SM_create_list(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id)
/* Allocate space for the list on disk */
size = H5SM_LIST_SIZE(f, num_entries);
if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_SOHM_INDEX, dxpl_id, size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list")
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list")
/* Put the list into the cache */
if(H5AC_set(f, dxpl_id, H5AC_SOHM_LIST, addr, list, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, HADDR_UNDEF, "can't add SOHM list to cache")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTINS, HADDR_UNDEF, "can't add SOHM list to cache")
/* Set return value */
ret_value = addr;
@@ -638,7 +663,7 @@ done:
if(list != NULL) {
if(list->messages != NULL)
H5FL_ARR_FREE(H5SM_sohm_t, list->messages);
- H5FL_FREE(H5SM_list_t, list);
+ (void)H5FL_FREE(H5SM_list_t, list);
} /* end if */
if(addr != HADDR_UNDEF)
H5MF_xfree(f, H5FD_MEM_SOHM_INDEX, dxpl_id, addr, size);
@@ -675,11 +700,13 @@ H5SM_convert_list_to_btree(H5F_t *f, H5SM_index_header_t *header,
{
H5SM_list_t *list; /* Pointer to the existing message list */
H5SM_mesg_key_t key; /* Key for inserting records in v2 B-tree */
+ H5B2_create_t bt2_cparam; /* v2 B-tree creation parameters */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
haddr_t tree_addr; /* New v2 B-tree's address */
size_t num_messages; /* Number of messages being tracked */
size_t x;
void * encoding_buf = NULL;
- herr_t ret_value = SUCCEED;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5SM_convert_list_to_btree)
@@ -690,10 +717,17 @@ H5SM_convert_list_to_btree(H5F_t *f, H5SM_index_header_t *header,
list = *_list;
/* Create the new v2 B-tree for tracking the messages */
- if(H5B2_create(f, dxpl_id, H5SM_INDEX, (size_t)H5SM_B2_NODE_SIZE,
- (size_t)H5SM_SOHM_ENTRY_SIZE(f), H5SM_B2_SPLIT_PERCENT,
- H5SM_B2_MERGE_PERCENT, &tree_addr) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTCREATE, FAIL, "B-tree creation failed for SOHM index")
+ bt2_cparam.cls = H5SM_INDEX;
+ bt2_cparam.node_size = (size_t)H5SM_B2_NODE_SIZE;
+ bt2_cparam.rrec_size = (size_t)H5SM_SOHM_ENTRY_SIZE(f);
+ bt2_cparam.split_percent = H5SM_B2_SPLIT_PERCENT;
+ bt2_cparam.merge_percent = H5SM_B2_MERGE_PERCENT;
+ if(NULL == (bt2 = H5B2_create(f, dxpl_id, &bt2_cparam, f)))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTCREATE, FAIL, "B-tree creation failed for SOHM index")
+
+ /* Retrieve the v2 B-tree's address in the file */
+ if(H5B2_get_addr(bt2, &tree_addr) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get v2 B-tree address for SOHM index")
/* Set up key values that all messages will use. Since these messages
* are in the heap, they have a heap ID and no encoding or type_id.
@@ -717,8 +751,8 @@ H5SM_convert_list_to_btree(H5F_t *f, H5SM_index_header_t *header,
key.encoding = encoding_buf;
/* Insert the message into the B-tree */
- if(H5B2_insert(f, dxpl_id, H5SM_INDEX, tree_addr, &key) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "couldn't add SOHM to B-tree")
+ if(H5B2_insert(bt2, dxpl_id, &key) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "couldn't add SOHM to B-tree")
/* Free buffer from H5SM_read_mesg */
if(encoding_buf)
@@ -727,8 +761,8 @@ H5SM_convert_list_to_btree(H5F_t *f, H5SM_index_header_t *header,
} /* end for */
/* Unprotect list in cache and release heap */
- if(H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DELETED_FLAG) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to release SOHM list")
+ if(H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to release SOHM list")
*_list = list = NULL;
/* Delete the old list index (but not its heap, which the new index is
@@ -744,7 +778,9 @@ H5SM_convert_list_to_btree(H5F_t *f, H5SM_index_header_t *header,
header->num_messages = num_messages;
done:
- /* Free the buffer, if it hasn't already been freed (because of error) */
+ /* Release resources */
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index")
if(encoding_buf)
encoding_buf = H5MM_xfree(encoding_buf);
@@ -793,13 +829,13 @@ H5SM_convert_btree_to_list(H5F_t * f, H5SM_index_header_t * header, hid_t dxpl_i
/* Delete the B-tree and have messages copy themselves to the
* list as they're deleted
*/
- if(H5B2_delete(f, dxpl_id, H5SM_INDEX, btree_addr, H5SM_btree_convert_to_list_op, list) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete B-tree")
+ if(H5B2_delete(f, dxpl_id, btree_addr, f, H5SM_bt2_convert_to_list_op, list) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTDELETE, FAIL, "unable to delete B-tree")
done:
/* Release the SOHM list from the cache */
if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DIRTIED_FLAG) < 0)
- HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to unprotect SOHM index")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to unprotect SOHM index")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_convert_btree_to_list() */
@@ -904,7 +940,7 @@ H5SM_can_share(H5F_t *f, hid_t dxpl_id, H5SM_master_table_t *table,
/* If the message isn't big enough, don't bother sharing it */
if(0 == (mesg_size = H5O_msg_raw_size(f, type_id, TRUE, mesg)))
- HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "unable to get OH message size")
+ HGOTO_ERROR(H5E_SOHM, H5E_BADMESG, FAIL, "unable to get OH message size")
if(mesg_size < my_table->indexes[index_num].min_mesg_size)
HGOTO_DONE(FALSE)
@@ -915,7 +951,7 @@ H5SM_can_share(H5F_t *f, hid_t dxpl_id, H5SM_master_table_t *table,
done:
/* Release the master SOHM table, if we protected it */
if(my_table && my_table != table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, my_table, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_SOHM, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_can_share() */
@@ -997,7 +1033,7 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned type_id,
/* Look up the master SOHM table */
if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
/* "complex" sharing checks */
if((tri_ret = H5SM_can_share(f, dxpl_id, table, &index_num, type_id, mesg)) < 0)
@@ -1034,7 +1070,7 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned type_id,
done:
/* Release the master SOHM table */
if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, cache_flags) < 0)
- HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_try_share() */
@@ -1078,7 +1114,7 @@ H5SM_incr_ref(void *record, void *_op_data, hbool_t *changed)
/* Put the message in the heap and record its new heap ID */
if(H5HF_insert(op_data->key->fheap, op_data->dxpl_id, op_data->key->encoding_size, op_data->key->encoding, &message->u.heap_loc.fheap_id) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap")
message->location = H5SM_IN_HEAP;
message->u.heap_loc.ref_count = 2;
@@ -1134,6 +1170,7 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
H5O_shared_t shared; /* Shared H5O message */
hbool_t found = FALSE; /* Was the message in the index? */
H5HF_t *fheap = NULL; /* Fractal heap handle */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
size_t buf_size; /* Size of the encoded message */
void * encoding_buf = NULL; /* Buffer for encoded message */
size_t empty_pos = UFAIL; /* Empty entry in list */
@@ -1148,15 +1185,15 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
/* Encode the message to be written */
if((buf_size = H5O_msg_raw_size(f, type_id, TRUE, mesg)) == 0)
- HGOTO_ERROR(H5E_OHDR, H5E_BADSIZE, FAIL, "can't find message size")
+ HGOTO_ERROR(H5E_SOHM, H5E_BADSIZE, FAIL, "can't find message size")
if(NULL == (encoding_buf = H5MM_malloc(buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate buffer for encoding")
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "can't allocate buffer for encoding")
if(H5O_msg_encode(f, type_id, TRUE, (unsigned char *)encoding_buf, mesg) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "can't encode message to be shared")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTENCODE, FAIL, "can't encode message to be shared")
/* Open the fractal heap for this index */
if(NULL == (fheap = H5HF_open(f, dxpl_id, header->heap_addr)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
/* Set up a key for the message to be written */
key.dxpl_id = dxpl_id;
@@ -1176,7 +1213,7 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
/* The index is a list; get it from the cache */
if(NULL == (list = (H5SM_list_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, NULL, header, H5AC_WRITE)))
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM index")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM index")
/* See if the message is already in the index and get its location.
* Also record the first empty list position we find in case we need it
@@ -1190,7 +1227,7 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
if(list->messages[list_pos].location == H5SM_IN_OH) {
/* Put the message in the heap and record its new heap ID */
if(H5HF_insert(fheap, dxpl_id, key.encoding_size, key.encoding, &shared.u.heap_id) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap")
list->messages[list_pos].location = H5SM_IN_HEAP;
list->messages[list_pos].u.heap_loc.fheap_id = shared.u.heap_id;
@@ -1213,6 +1250,11 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
HDassert(header->index_type == H5SM_BTREE);
+ /* Open the index v2 B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr, f)))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index")
+
+ /* Set up callback info */
op_data.key = &key;
op_data.dxpl_id = dxpl_id;
@@ -1221,10 +1263,12 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
* return a heap ID, since a message with a reference count greater
* than 1 is always shared in the heap.
*/
- if(H5B2_modify(f, dxpl_id, H5SM_INDEX, header->index_addr, &key, H5SM_incr_ref, &op_data) >= 0) {
+ if(H5B2_modify(bt2, dxpl_id, &key, H5SM_incr_ref, &op_data) >= 0) {
shared.u.heap_id = op_data.fheap_id;
found = TRUE;
} /* end if */
+ else
+ H5E_clear_stack(NULL); /*ignore error*/
} /* end else */
if(found)
@@ -1299,8 +1343,14 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
else {
HDassert(header->index_type == H5SM_BTREE);
- if(H5B2_insert(f, dxpl_id, H5SM_INDEX, header->index_addr, &key) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "couldn't add SOHM to B-tree")
+ /* Open the index v2 B-tree, if it isn't already */
+ if(NULL == bt2) {
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr, f)))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index")
+ } /* end if */
+
+ if(H5B2_insert(bt2, dxpl_id, &key) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "couldn't add SOHM to B-tree")
} /* end else */
++(header->num_messages);
@@ -1313,16 +1363,18 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
/* Update the original message's shared component */
if(H5O_msg_set_share(type_id, &shared, mesg) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "unable to set sharing information")
+ HGOTO_ERROR(H5E_SOHM, H5E_BADMESG, FAIL, "unable to set sharing information")
done:
- /* Release the fractal heap if we opened it */
+ /* Release the fractal heap & v2 B-tree if we opened them */
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap")
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index")
/* If we got a list out of the cache, release it (it is always dirty after writing a message) */
if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DIRTIED_FLAG) < 0)
- HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index")
if(encoding_buf)
encoding_buf = H5MM_xfree(encoding_buf);
@@ -1371,7 +1423,7 @@ H5SM_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_shared_t *sh_mesg)
/* Look up the master SOHM table */
if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
/* Find the correct index and try to delete from it */
if((index_num = H5SM_get_index(table, type_id)) < 0)
@@ -1386,7 +1438,7 @@ H5SM_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_shared_t *sh_mesg)
/* Release the master SOHM table */
if(H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, cache_flags) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table")
table = NULL;
/* If buf was allocated, delete the message it holds. This message may
@@ -1394,17 +1446,17 @@ H5SM_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_shared_t *sh_mesg)
* master table needs to be unprotected when we do this.
*/
if(mesg_buf) {
- if(NULL == (native_mesg = H5O_msg_decode(f, dxpl_id, type_id, (const unsigned char *)mesg_buf)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "can't decode shared message.")
+ if(NULL == (native_mesg = H5O_msg_decode(f, dxpl_id, open_oh, type_id, (const unsigned char *)mesg_buf)))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTDECODE, FAIL, "can't decode shared message.")
if(H5O_msg_delete(f, dxpl_id, open_oh, type_id, native_mesg) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "can't delete shared message.")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "can't delete shared message.")
} /* end if */
done:
/* Release the master SOHM table (should only happen on error) */
if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, cache_flags) < 0)
- HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table")
/* Release any native message we decoded */
if(native_mesg)
@@ -1580,10 +1632,9 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
H5SM_sohm_t message; /* Deleted message returned from index */
H5SM_sohm_t *message_ptr; /* Pointer to deleted message returned from index */
H5HF_t *fheap = NULL; /* Fractal heap that contains the message */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
size_t buf_size; /* Size of the encoded message (out) */
void *encoding_buf = NULL; /* The encoded message (out) */
- H5O_loc_t oloc; /* Object location for message in object header */
- H5O_t *oh = NULL; /* Object header for message in object header */
unsigned type_id; /* Message type to operate on */
herr_t ret_value = SUCCEED;
@@ -1601,7 +1652,7 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
/* Open the heap for this type of message. */
if(NULL == (fheap = H5HF_open(f, dxpl_id, header->heap_addr)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
/* Get the message size and encoded message for the message to be deleted,
* either from its OH or from the heap.
@@ -1620,7 +1671,7 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
/* Get the encoded message */
if(H5SM_read_mesg(f, &key.message, fheap, open_oh, dxpl_id, &buf_size, &encoding_buf) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
/* Set up key for message to be deleted. */
key.file = f;
@@ -1652,9 +1703,14 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
/* Index is a B-tree */
HDassert(header->index_type == H5SM_BTREE);
+ /* Open the index v2 B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr, f)))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index")
+
/* If this returns failure, it means that the message wasn't found.
- * If it succeeds, a copy of the modified message will be returned. */
- if(H5B2_modify(f, dxpl_id, H5SM_INDEX, header->index_addr, &key, H5SM_decr_ref, &message) <0)
+ * If it succeeds, a copy of the modified message will be returned.
+ */
+ if(H5B2_modify(bt2, dxpl_id, &key, H5SM_decr_ref, &message) <0)
HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "message not in index")
/* Point to the message */
@@ -1676,8 +1732,14 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
if(header->index_type == H5SM_LIST)
message_ptr->location = H5SM_NO_LOC;
else {
- if(H5B2_remove(f, dxpl_id, H5SM_INDEX, header->index_addr, &key, NULL, NULL) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTREMOVE, FAIL, "unable to delete message")
+ /* Open the index v2 B-tree, if it isn't already */
+ if(NULL == bt2) {
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr, f)))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index")
+ } /* end if */
+
+ if(H5B2_remove(bt2, dxpl_id, &key, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTREMOVE, FAIL, "unable to delete message from index")
} /* end else */
/* Remove the message from the heap if it was stored in the heap*/
@@ -1693,13 +1755,13 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
if(header->num_messages == 0) {
/* Unprotect cache and release heap */
- if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DELETED_FLAG) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to release SOHM list")
+ if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to release SOHM list")
list = NULL;
HDassert(fheap);
if(H5HF_close(fheap, dxpl_id) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap")
fheap = NULL;
/* Delete the index and its heap */
@@ -1716,22 +1778,15 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
} /* end if */
done:
- /* Unprotect & close the object header if we opened one */
- if(oh && oh != open_oh) {
- if(H5AC_unprotect(oloc.file, dxpl_id, H5AC_OHDR, oloc.addr, oh, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
-
- if(H5O_close(&oloc) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object header")
- } /* end if */
-
/* Release the SOHM list */
if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DIRTIED_FLAG) < 0)
- HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index")
- /* Release the fractal heap if we opened it */
+ /* Release the fractal heap & v2 B-tree if we opened them */
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap")
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index")
/* Free the message encoding, if we're not returning it in encoded_mesg
* or if there's been an error.
@@ -1762,6 +1817,7 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id)
H5F_file_t *shared = f->shared; /* Shared file info (convenience variable) */
H5O_shmesg_table_t sohm_table; /* SOHM message from superblock extension */
H5SM_master_table_t *table = NULL; /* SOHM master table */
+ htri_t status; /* Status for message existing */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5SM_get_info, FAIL)
@@ -1771,27 +1827,20 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id)
HDassert(f && shared);
HDassert(fc_plist);
- /* Read in shared message information, if it exists */
- if(NULL == H5O_msg_read(ext_loc, H5O_SHMESG_ID, &sohm_table, dxpl_id)) {
- /* Reset error from "failed" message read */
- H5E_clear_stack(NULL);
-
- /* No SOHM info in file */
- shared->sohm_addr = HADDR_UNDEF;
- shared->sohm_nindexes = 0;
- shared->sohm_vers = 0;
-
- /* Shared object header messages are disabled */
- if(H5P_set(fc_plist, H5F_CRT_SHMSG_NINDEXES_NAME, &shared->sohm_nindexes) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set number of SOHM indexes")
- } /* end if */
- else {
+ /* Check for the extension having a 'shared message info' message */
+ if((status = H5O_msg_exists(ext_loc, H5O_SHMESG_ID, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "unable to read object header")
+ if(status) {
unsigned index_flags[H5O_SHMESG_MAX_NINDEXES]; /* Message flags for each index */
unsigned minsizes[H5O_SHMESG_MAX_NINDEXES]; /* Minimum message size for each index */
unsigned sohm_l2b; /* SOHM list-to-btree cutoff */
unsigned sohm_b2l; /* SOHM btree-to-list cutoff */
unsigned u; /* Local index variable */
+ /* Retrieve the 'shared message info' structure */
+ if(NULL == H5O_msg_read(ext_loc, H5O_SHMESG_ID, &sohm_table, dxpl_id))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "shared message info message not present")
+
/* Portably initialize the arrays */
HDmemset(index_flags, 0, sizeof(index_flags));
HDmemset(minsizes, 0, sizeof(minsizes));
@@ -1805,7 +1854,7 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id)
/* Read the rest of the SOHM table information from the cache */
if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, shared->sohm_addr, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
/* Get index conversion limits */
sohm_l2b = table->indexes[0].list_max;
@@ -1830,107 +1879,37 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id)
/* Set values in the property list */
if(H5P_set(fc_plist, H5F_CRT_SHMSG_NINDEXES_NAME, &shared->sohm_nindexes) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set number of SOHM indexes")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTSET, FAIL, "can't set number of SOHM indexes")
if(H5P_set(fc_plist, H5F_CRT_SHMSG_INDEX_TYPES_NAME, index_flags) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set type flags for indexes")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTSET, FAIL, "can't set type flags for indexes")
if(H5P_set(fc_plist, H5F_CRT_SHMSG_INDEX_MINSIZE_NAME, minsizes) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set type flags for indexes")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTSET, FAIL, "can't set type flags for indexes")
if(H5P_set(fc_plist, H5F_CRT_SHMSG_LIST_MAX_NAME, &sohm_l2b) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set SOHM cutoff in property list")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't set SOHM cutoff in property list")
if(H5P_set(fc_plist, H5F_CRT_SHMSG_BTREE_MIN_NAME, &sohm_b2l) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set SOHM cutoff in property list")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't set SOHM cutoff in property list")
+ } /* end if */
+ else {
+ /* No SOHM info in file */
+ shared->sohm_addr = HADDR_UNDEF;
+ shared->sohm_nindexes = 0;
+ shared->sohm_vers = 0;
+
+ /* Shared object header messages are disabled */
+ if(H5P_set(fc_plist, H5F_CRT_SHMSG_NINDEXES_NAME, &shared->sohm_nindexes) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTSET, FAIL, "can't set number of SOHM indexes")
} /* end else */
done:
/* Release the master SOHM table if we took it out of the cache */
if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_get_info() */
/*-------------------------------------------------------------------------
- * Function: H5SM_message_encode
- *
- * Purpose: Serialize a H5SM_sohm_t struct into a buffer RAW.
- *
- * Return: Non-negative on success
- * Negative on failure
- *
- * Programmer: James Laird
- * Monday, November 6, 2006
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5SM_message_encode(const H5F_t *f, uint8_t *raw, const void *_nrecord)
-{
- const H5SM_sohm_t *message = (const H5SM_sohm_t *)_nrecord;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_message_encode)
-
- *raw++ = message->location;
- UINT32ENCODE(raw, message->hash);
-
- if(message->location == H5SM_IN_HEAP) {
- UINT32ENCODE(raw, message->u.heap_loc.ref_count);
- UINT64ENCODE(raw, message->u.heap_loc.fheap_id);
- } /* end if */
- else {
- HDassert(message->location == H5SM_IN_OH);
-
- *raw++ = 0; /* reserved (possible flags byte) */
- *raw++ = message->msg_type_id;
- UINT16ENCODE(raw, message->u.mesg_loc.index);
- H5F_addr_encode(f, &raw, message->u.mesg_loc.oh_addr);
- } /* end else */
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_message_encode */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5SM_message_decode
- *
- * Purpose: Read an encoded SOHM message from RAW into an H5SM_sohm_t struct.
- *
- * Return: Non-negative on success
- * Negative on failure
- *
- * Programmer: James Laird
- * Monday, November 6, 2006
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5SM_message_decode(const H5F_t UNUSED *f, const uint8_t *raw, void *_nrecord)
-{
- H5SM_sohm_t *message = (H5SM_sohm_t *)_nrecord;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_message_decode)
-
- message->location = *raw++;
- UINT32DECODE(raw, message->hash);
-
- if(message->location == H5SM_IN_HEAP) {
- UINT32DECODE(raw, message->u.heap_loc.ref_count);
- UINT64DECODE(raw, message->u.heap_loc.fheap_id);
- } /* end if */
- else {
- HDassert(message->location == H5SM_IN_OH);
-
- raw++; /* reserved */
- message->msg_type_id = *raw++;
- UINT16DECODE(raw, message->u.mesg_loc.index);
- H5F_addr_decode(f, &raw, &message->u.mesg_loc.oh_addr);
- } /* end else */
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_message_decode */
-
-
-/*-------------------------------------------------------------------------
* Function: H5SM_reconstitute
*
* Purpose: Reconstitute a shared object header message structure from
@@ -2010,8 +1989,9 @@ H5SM_get_refcount_bt2_cb(const void *_record, void *_op_data)
herr_t
H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id,
const H5O_shared_t *sh_mesg, hsize_t *ref_count)
-{
+{
H5HF_t *fheap = NULL; /* Fractal heap that contains shared messages */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
H5SM_master_table_t *table = NULL; /* SOHM master table */
H5SM_list_t *list = NULL; /* SOHM index list for message type (if in list form) */
H5SM_index_header_t *header=NULL; /* Index header for message type */
@@ -2031,7 +2011,7 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id,
/* Look up the master SOHM table */
if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
/* Find the correct index and find the message in it */
if((index_num = H5SM_get_index(table, type_id)) < 0)
@@ -2040,7 +2020,7 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id,
/* Open the heap for this message type */
if(NULL == (fheap = H5HF_open(f, dxpl_id, header->heap_addr)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
/* Set up a SOHM message to correspond to the shared message passed in */
key.message.location = H5SM_IN_HEAP;
@@ -2049,7 +2029,7 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id,
/* Get the encoded message */
if(H5SM_read_mesg(f, &key.message, fheap, NULL, dxpl_id, &buf_size, &encoding_buf) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
/* Set up key for message to locate */
key.file = f;
@@ -2075,11 +2055,19 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id,
message = list->messages[list_pos];
} /* end if */
else {
+ htri_t msg_exists; /* Whether the message exists in the v2 B-tree */
+
/* Index is a B-tree */
HDassert(header->index_type == H5SM_BTREE);
+ /* Open the index v2 B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr, f)))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index")
+
/* Look up the message in the v2 B-tree */
- if(H5B2_find(f, dxpl_id, H5SM_INDEX, header->index_addr, &key, H5SM_get_refcount_bt2_cb, &message) < 0)
+ if((msg_exists = H5B2_find(bt2, dxpl_id, &key, H5SM_get_refcount_bt2_cb, &message)) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "error finding message in index")
+ if(!msg_exists)
HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "message not in index")
} /* end else */
@@ -2090,11 +2078,13 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id,
done:
/* Release resources */
if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index")
if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table")
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap")
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index")
if(encoding_buf)
encoding_buf = H5MM_xfree(encoding_buf);
@@ -2142,7 +2132,7 @@ H5SM_read_iter_op(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned sequence,
/* Check if the message is dirty & flush it to the object header if so */
if(mesg->dirty)
if(H5O_msg_flush(udata->file, oh, mesg) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, H5_ITER_ERROR, "unable to encode object header message")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTENCODE, H5_ITER_ERROR, "unable to encode object header message")
/* Get the message's encoded size */
udata->buf_size = mesg->raw_size;
@@ -2150,7 +2140,7 @@ H5SM_read_iter_op(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned sequence,
/* Allocate buffer to return the message in */
if(NULL == (udata->encoding_buf = H5MM_malloc(udata->buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed")
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed")
/* Copy the encoded message into the buffer to return */
HDmemcpy(udata->encoding_buf, mesg->raw, udata->buf_size);
@@ -2188,7 +2178,7 @@ H5SM_read_mesg_fh_cb(const void *obj, size_t obj_len, void *_udata)
/* Allocate a buffer to hold the message */
if(NULL == (udata->encoding_buf = H5MM_malloc(obj_len)))
- HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, FAIL, "memory allocation failed")
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Copy the message from the heap */
HDmemcpy(udata->encoding_buf, obj, obj_len);
@@ -2247,18 +2237,18 @@ H5SM_read_mesg(H5F_t *f, const H5SM_sohm_t *mesg, H5HF_t *fheap,
/* Reset object location for operation */
if(H5O_loc_reset(&oloc) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTRESET, FAIL, "unable to initialize location")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTRESET, FAIL, "unable to initialize location")
if(NULL == open_oh || mesg->u.mesg_loc.oh_addr != H5O_OH_GET_ADDR(open_oh)) {
/* Open the object in the file */
oloc.file = f;
oloc.addr = mesg->u.mesg_loc.oh_addr;
if(H5O_open(&oloc) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to open object header")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, FAIL, "unable to open object header")
/* Load the object header from the cache */
- if(NULL == (oh = H5AC_protect(oloc.file, dxpl_id, H5AC_OHDR, oloc.addr, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
+ if(NULL == (oh = (H5O_t *)H5AC_protect(oloc.file, dxpl_id, H5AC_OHDR, oloc.addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load object header")
} /* end if */
else
oh = open_oh;
@@ -2267,14 +2257,14 @@ H5SM_read_mesg(H5F_t *f, const H5SM_sohm_t *mesg, H5HF_t *fheap,
op.op_type = H5O_MESG_OP_LIB;
op.u.lib_op = H5SM_read_iter_op;
if((ret_value = H5O_msg_iterate_real(f, oh, type, &op, &udata, dxpl_id)) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "unable to iterate over object header messages")
+ HGOTO_ERROR(H5E_SOHM, H5E_BADITER, FAIL, "unable to iterate over object header messages")
} /* end if */
else {
HDassert(mesg->location == H5SM_IN_HEAP);
/* Copy the message from the heap */
if(H5HF_op(fheap, dxpl_id, &(mesg->u.heap_loc.fheap_id), H5SM_read_mesg_fh_cb, &udata) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "can't read message from fractal heap.")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, FAIL, "can't read message from fractal heap.")
} /* end else */
HDassert(udata.encoding_buf);
HDassert(udata.buf_size);
@@ -2287,10 +2277,9 @@ done:
/* Close the object header if we opened one and had an error */
if(oh && oh != open_oh) {
if(H5AC_unprotect(oloc.file, dxpl_id, H5AC_OHDR, oloc.addr, oh, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
-
+ HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
if(H5O_close(&oloc) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object header")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "unable to close object header")
} /* end if */
/* Release the encoding buffer on error */
@@ -2347,13 +2336,13 @@ H5SM_table_debug(H5F_t *f, hid_t dxpl_id, haddr_t table_addr,
/* Check arguments. Version must be 0, the only version implemented so far */
if(table_vers > HDF5_SHAREDHEADER_VERSION)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown shared message table version")
+ HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, FAIL, "unknown shared message table version")
if(num_indexes == 0 || num_indexes > H5O_SHMESG_MAX_NINDEXES)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "number of indexes must be between 1 and H5O_SHMESG_MAX_NINDEXES")
+ HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, FAIL, "number of indexes must be between 1 and H5O_SHMESG_MAX_NINDEXES")
/* Look up the master SOHM table */
if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, table_addr, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
HDfprintf(stream, "%*sShared Message Master Table...\n", indent, "");
for(x = 0; x < num_indexes; ++x) {
@@ -2381,7 +2370,7 @@ H5SM_table_debug(H5F_t *f, hid_t dxpl_id, haddr_t table_addr,
done:
if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, table_addr, table, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_table_debug() */
@@ -2422,9 +2411,9 @@ H5SM_list_debug(H5F_t *f, hid_t dxpl_id, haddr_t list_addr,
/* Check arguments. Version must be 0, the only version implemented so far */
if(table_vers > H5SM_LIST_VERSION)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown shared message list version")
+ HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, FAIL, "unknown shared message list version")
if(num_messages == 0 || num_messages > H5O_SHMESG_MAX_LIST_SIZE)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "number of indexes must be between 1 and H5O_SHMESG_MAX_NINDEXES")
+ HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, FAIL, "number of indexes must be between 1 and H5O_SHMESG_MAX_NINDEXES")
/* Create a temporary header using the arguments. The cache needs this to load the list. */
HDmemset(&header, 0, sizeof(H5SM_index_header_t));
@@ -2434,7 +2423,7 @@ H5SM_list_debug(H5F_t *f, hid_t dxpl_id, haddr_t list_addr,
/* Get the list from the cache */
if(NULL == (list = (H5SM_list_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_LIST, list_addr, NULL, &header, H5AC_READ)))
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM index")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM index")
HDfprintf(stream, "%*sShared Message List Index...\n", indent, "");
for(x = 0; x < num_messages; ++x) {
@@ -2466,7 +2455,7 @@ H5SM_list_debug(H5F_t *f, hid_t dxpl_id, haddr_t list_addr,
done:
if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, list_addr, list, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_list_debug() */
@@ -2477,7 +2466,7 @@ done:
*
* Purpose: Loop through the master SOHM table (if there is one) to:
* 1. collect storage used for header
- * 1. collect storage used for B-tree and List
+ * 1. collect storage used for B-tree and List
* (include btree storage used by huge objects in fractal heap)
* 2. collect fractal heap storage
*
@@ -2489,10 +2478,11 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5SM_ih_size(H5F_t *f, hid_t dxpl_id, H5F_info_t *finfo)
+H5SM_ih_size(H5F_t *f, hid_t dxpl_id, hsize_t *hdr_size, H5_ih_info_t *ih_info)
{
H5SM_master_table_t *table = NULL; /* SOHM master table */
H5HF_t *fheap = NULL; /* Fractal heap handle */
+ H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -2501,40 +2491,52 @@ H5SM_ih_size(H5F_t *f, hid_t dxpl_id, H5F_info_t *finfo)
/* Sanity check */
HDassert(f);
HDassert(H5F_addr_defined(f->shared->sohm_addr));
- HDassert(finfo);
+ HDassert(hdr_size);
+ HDassert(ih_info);
/* Look up the master SOHM table */
if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
/* Get SOHM header size */
- finfo->sohm.hdr_size = (hsize_t) H5SM_TABLE_SIZE(f) +
- (hsize_t)(table->num_indexes * H5SM_INDEX_HEADER_SIZE(f));
+ *hdr_size = H5SM_TABLE_SIZE(f) + (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f));
/* Loop over all the indices for shared messages */
for(u = 0; u < table->num_indexes; u++) {
/* Get index storage size (for either B-tree or list) */
if(table->indexes[u].index_type == H5SM_BTREE) {
- if(H5F_addr_defined(table->indexes[u].index_addr))
- if(H5B2_iterate_size(f, dxpl_id, H5SM_INDEX, table->indexes[u].index_addr, &(finfo->sohm.msgs_info.index_size)) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info")
+ if(H5F_addr_defined(table->indexes[u].index_addr)) {
+ /* Open the index v2 B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, table->indexes[u].index_addr, f)))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index")
+
+ if(H5B2_size(bt2, dxpl_id, &(ih_info->index_size)) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info")
+
+ /* Close the v2 B-tree */
+ if(H5B2_close(bt2, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index")
+ bt2 = NULL;
+ } /* end if */
} /* end if */
- else if(table->indexes[u].index_type == H5SM_LIST)
- finfo->sohm.msgs_info.index_size += H5SM_LIST_SIZE(f, table->indexes[u].list_max);
+ else {
+ HDassert(table->indexes[u].index_type == H5SM_LIST);
+ ih_info->index_size += H5SM_LIST_SIZE(f, table->indexes[u].list_max);
+ } /* end else */
/* Check for heap for this index */
if(H5F_addr_defined(table->indexes[u].heap_addr)) {
/* Open the fractal heap for this index */
if(NULL == (fheap = H5HF_open(f, dxpl_id, table->indexes[u].heap_addr)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
/* Get heap storage size */
- if(H5HF_size(fheap, dxpl_id, &(finfo->sohm.msgs_info.heap_size)) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve fractal heap storage info")
+ if(H5HF_size(fheap, dxpl_id, &(ih_info->heap_size)) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't retrieve fractal heap storage info")
- /* Release the fractal heap */
+ /* Close the fractal heap */
if(H5HF_close(fheap, dxpl_id) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap")
fheap = NULL;
} /* end if */
} /* end for */
@@ -2542,9 +2544,11 @@ H5SM_ih_size(H5F_t *f, hid_t dxpl_id, H5F_info_t *finfo)
done:
/* Release resources */
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap")
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index")
if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_ih_size() */
diff --git a/src/H5SMbtree2.c b/src/H5SMbtree2.c
index 8863287..95527f9 100755
--- a/src/H5SMbtree2.c
+++ b/src/H5SMbtree2.c
@@ -20,6 +20,7 @@
#define H5O_PACKAGE /*suppress error about including H5Opkg */
#define H5SM_PACKAGE /*suppress error about including H5SMpkg */
+
/***********/
/* Headers */
/***********/
@@ -38,24 +39,18 @@
/* Local Typedefs */
/******************/
-/* Udata struct for calls to H5SM_btree_compare_cb and H5SM_compare_iter_op*/
-typedef struct H5SM_compare_udata_t {
- const H5SM_mesg_key_t *key; /* Key; compare this against stored message */
- H5O_msg_crt_idx_t idx; /* Index of the message in the OH, if applicable */
- herr_t ret; /* Return value; set this to result of memcmp */
-} H5SM_compare_udata_t;
-
/********************/
/* Local Prototypes */
/********************/
/* v2 B-tree callbacks */
-static herr_t H5SM_btree_compare_cb(const void *obj, size_t obj_len, void *_udata);
-static herr_t H5SM_btree_store(void *native, const void *udata);
-static herr_t H5SM_btree_retrieve(void *udata, const void *native);
-static herr_t H5SM_btree_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
+static void *H5SM_bt2_crt_context(void *udata);
+static herr_t H5SM_bt2_dst_context(void *ctx);
+static herr_t H5SM_bt2_store(void *native, const void *udata);
+static herr_t H5SM_bt2_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
int indent, int fwidth, const void *record, const void *_udata);
+static void *H5SM_bt2_crt_dbg_context(H5F_t *f, hid_t dxpl_id, haddr_t addr);
/*****************************/
@@ -64,223 +59,101 @@ static herr_t H5SM_btree_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
/* v2 B-tree class for SOHM indexes*/
const H5B2_class_t H5SM_INDEX[1]={{ /* B-tree class information */
H5B2_SOHM_INDEX_ID, /* Type of B-tree */
+ "H5B2_SOHM_INDEX_ID", /* Name of B-tree class */
sizeof(H5SM_sohm_t), /* Size of native record */
- H5SM_btree_store, /* Record storage callback */
- H5SM_btree_retrieve, /* Record retrieval callback */
+ H5SM_bt2_crt_context, /* Create client callback context */
+ H5SM_bt2_dst_context, /* Destroy client callback context */
+ H5SM_bt2_store, /* Record storage callback */
H5SM_message_compare, /* Record comparison callback */
H5SM_message_encode, /* Record encoding callback */
H5SM_message_decode, /* Record decoding callback */
- H5SM_btree_debug /* Record debugging callback */
+ H5SM_bt2_debug, /* Record debugging callback */
+ H5SM_bt2_crt_dbg_context, /* Create debugging context */
+ H5SM_bt2_dst_context /* Destroy debugging context */
}};
+
/*******************/
/* Local Variables */
/*******************/
+/* Declare a free list to manage the H5SM_bt2_ctx_t struct */
+H5FL_DEFINE_STATIC(H5SM_bt2_ctx_t);
+
+
/*-------------------------------------------------------------------------
- * Function: H5SM_btree_compare_cb
+ * Function: H5SM_bt2_crt_context
*
- * Purpose: Callback for H5HF_op, used in H5SM_message_compare below.
- * Determines whether the search key passed in in _UDATA is
- * equal to OBJ or not.
+ * Purpose: Create client callback context
*
- * Passes back the result in _UDATA->RET
+ * Return: Success: non-NULL
+ * Failure: NULL
*
- * Return: Negative on error, non-negative on success
- *
- * Programmer: James Laird
- * Monday, January 8, 2007
+ * Programmer: Quincey Koziol
+ * Thursday, November 26, 2009
*
*-------------------------------------------------------------------------
*/
-static herr_t
-H5SM_btree_compare_cb(const void *obj, size_t obj_len, void *_udata)
+static void *
+H5SM_bt2_crt_context(void *_f)
{
- H5SM_compare_udata_t *udata = (H5SM_compare_udata_t *)_udata;
+ H5F_t *f = (H5F_t *)_f; /* User data for building callback context */
+ H5SM_bt2_ctx_t *ctx; /* Callback context structure */
+ void *ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_btree_compare_cb)
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_bt2_crt_context)
- /* If the encoding sizes are different, it's not the same object */
- if(udata->key->encoding_size > obj_len)
- udata->ret = 1;
- else if(udata->key->encoding_size < obj_len)
- udata->ret = -1;
- else
- /* Sizes are the same. Return result of memcmp */
- udata->ret = HDmemcmp(udata->key->encoding, obj, obj_len);
+ /* Sanity check */
+ HDassert(f);
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_btree_compare_cb() */
+ /* Allocate callback context */
+ if(NULL == (ctx = H5FL_MALLOC(H5SM_bt2_ctx_t)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate callback context")
-
-/*-------------------------------------------------------------------------
- * Function: H5SM_compare_iter_op
- *
- * Purpose: OH iteration callback to compare a key against a message in
- * an OH
- *
- * Return: 0 if this is not the message we're searching for
- * 1 if this is the message we're searching for (with memcmp
- * result returned in udata)
- * negative on error
- *
- * Programmer: James Laird
- * Wednesday, February 7, 2007
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5SM_compare_iter_op(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned sequence,
- hbool_t UNUSED *oh_modified, void *_udata/*in,out*/)
-{
- H5SM_compare_udata_t *udata = (H5SM_compare_udata_t *) _udata;
- herr_t ret_value = H5_ITER_CONT;
-
- FUNC_ENTER_NOAPI_NOINIT(H5SM_compare_iter_op)
-
- /*
- * Check arguments.
- */
- HDassert(oh);
- HDassert(mesg);
- HDassert(udata && udata->key);
-
- /* Check the creation index for this message */
- if(sequence == udata->idx) {
- size_t aligned_encoded_size = H5O_ALIGN_OH(oh, udata->key->encoding_size);
-
- /* Sanity check the message's length */
- HDassert(mesg->raw_size > 0);
-
- if(aligned_encoded_size > mesg->raw_size)
- udata->ret = 1;
- else if(aligned_encoded_size < mesg->raw_size)
- udata->ret = -1;
- else {
- /* Check if the message is dirty & flush it to the object header if so */
- if(mesg->dirty)
- if(H5O_msg_flush(udata->key->file, oh, mesg) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, H5_ITER_ERROR, "unable to encode object header message")
-
- HDassert(udata->key->encoding_size <= mesg->raw_size);
- udata->ret = HDmemcmp(udata->key->encoding, mesg->raw, udata->key->encoding_size);
- } /* end else */
-
- /* Indicate that we found the message we were looking for */
- ret_value = H5_ITER_STOP;
- } /* end if */
+ /* Determine the size of addresses & lengths in the file */
+ ctx->sizeof_addr = H5F_SIZEOF_ADDR(f);
+
+ /* Set return value */
+ ret_value = ctx;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5SM_compare_iter_op() */
+} /* H5SM_bt2_crt_context() */
/*-------------------------------------------------------------------------
- * Function: H5SM_message_compare
+ * Function: H5SM_bt2_dst_context
*
- * Purpose: Determine whether the search key rec1 represents a shared
- * message that is equal to rec2 or not, and if not, whether
- * rec1 is "greater than" or "less than" rec2.
+ * Purpose: Destroy client callback context
*
- * Return: 0 if rec1 == rec2
- * Negative if rec1 < rec2
- * Positive if rec1 > rec2
+ * Return: Success: non-negative
+ * Failure: negative
*
- * Programmer: James Laird
- * Monday, November 6, 2006
+ * Programmer: Quincey Koziol
+ * Thursday, November 26, 2009
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5SM_message_compare(const void *rec1, const void *rec2)
+static herr_t
+H5SM_bt2_dst_context(void *_ctx)
{
- const H5SM_mesg_key_t *key = (const H5SM_mesg_key_t *) rec1;
- const H5SM_sohm_t *mesg = (const H5SM_sohm_t *) rec2;
- herr_t ret_value = 0;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_message_compare)
-
- /* If the key has an fheap ID, we're looking for a message that's
- * already in the index; if the fheap ID matches, we've found the message
- * and can stop immediately.
- * Likewise, if the message has an OH location that is matched by the
- * message in the index, we've found the message.
- */
- if(mesg->location == H5SM_IN_HEAP && key->message.location == H5SM_IN_HEAP) {
- if(key->message.u.heap_loc.fheap_id == mesg->u.heap_loc.fheap_id)
- HGOTO_DONE(0);
- } /* end if */
- else if(mesg->location == H5SM_IN_OH && key->message.location == H5SM_IN_OH) {
- if(key->message.u.mesg_loc.oh_addr == mesg->u.mesg_loc.oh_addr &&
- key->message.u.mesg_loc.index == mesg->u.mesg_loc.index &&
- key->message.msg_type_id == mesg->msg_type_id)
- HGOTO_DONE(0);
- } /* end if */
-
- /* Compare hash values */
- if(key->message.hash > mesg->hash)
- ret_value = 1;
- else if(key->message.hash < mesg->hash)
- ret_value = -1;
- /* If the hash values match, make sure the messages are really the same */
- else {
- /* Hash values match; compare the encoded message with the one in
- * the index.
- */
- H5SM_compare_udata_t udata;
- herr_t status;
-
- HDassert(key->message.hash == mesg->hash);
- HDassert(key->encoding_size > 0 && key->encoding);
-
- /* Set up user data for callback */
- udata.key = key;
-
- /* Compare the encoded message with either the message in the heap or
- * the message in an object header.
- */
- if(mesg->location == H5SM_IN_HEAP) {
- /* Call heap op routine with comparison callback */
- status = H5HF_op(key->fheap, key->dxpl_id, &(mesg->u.heap_loc.fheap_id), H5SM_btree_compare_cb, &udata);
- HDassert(status >= 0);
- } /* end if */
- else {
- H5O_loc_t oloc; /* Object owning the message */
- H5O_mesg_operator_t op; /* Message operator */
-
- /* Sanity checks */
- HDassert(key->file);
- HDassert(mesg->location == H5SM_IN_OH);
-
- /* Reset the object location */
- status = H5O_loc_reset(&oloc);
- HDassert(status >= 0);
-
- /* Set up object location */
- oloc.file = key->file;
- oloc.addr = mesg->u.mesg_loc.oh_addr;
-
- /* Finish setting up user data for iterator */
- udata.idx = mesg->u.mesg_loc.index;
-
- /* Locate the right message and compare with it */
- op.op_type = H5O_MESG_OP_LIB;
- op.u.lib_op = H5SM_compare_iter_op;
- status = H5O_msg_iterate(&oloc, mesg->msg_type_id, &op, &udata, key->dxpl_id);
- HDassert(status >= 0);
- } /* end else */
-
- ret_value = udata.ret;
- } /* end if */
+ H5SM_bt2_ctx_t *ctx = (H5SM_bt2_ctx_t *)_ctx; /* Callback context structure */
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5SM_message_compare */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_bt2_dst_context)
+
+ /* Sanity check */
+ HDassert(ctx);
+
+ /* Release callback context */
+ ctx = H5FL_FREE(H5SM_bt2_ctx_t, ctx);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5SM_bt2_dst_context() */
/*-------------------------------------------------------------------------
- * Function: H5SM_btree_store
+ * Function: H5SM_bt2_store
*
* Purpose: Store a H5SM_sohm_t SOHM message in the B-tree. The message
* comes in UDATA as a H5SM_mesg_key_t* and is copied to
@@ -295,49 +168,21 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5SM_btree_store(void *native, const void *udata)
+H5SM_bt2_store(void *native, const void *udata)
{
const H5SM_mesg_key_t *key = (const H5SM_mesg_key_t *)udata;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_btree_store)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_bt2_store)
/* Copy the source message to the B-tree */
*(H5SM_sohm_t *)native = key->message;
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_btree_store */
+} /* end H5SM_bt2_store */
/*-------------------------------------------------------------------------
- * Function: H5SM_btree_retrieve
- *
- * Purpose: Retrieve a H5SM_sohm_t SOHM message from the B-tree by
- * copying it from NATIVE to UDATA.
- *
- * Quincey said this function may no longer be used.
- *
- * Return: Non-negative on success
- * Negative on failure
- *
- * Programmer: James Laird
- * Monday, November 6, 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5SM_btree_retrieve(void *udata, const void *native)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_btree_retrieve)
-
- /* Copy the B-tree's native message to the udata buffer */
- *(H5SM_sohm_t *)udata = *(const H5SM_sohm_t *)native;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_btree_retrieve */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5SM_btree_debug
+ * Function: H5SM_bt2_debug
*
* Purpose: Print debugging information for a H5SM_sohm_t.
*
@@ -350,12 +195,12 @@ H5SM_btree_retrieve(void *udata, const void *native)
*-------------------------------------------------------------------------
*/
static herr_t
-H5SM_btree_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
+H5SM_bt2_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
int indent, int fwidth, const void *record, const void UNUSED *_udata)
{
const H5SM_sohm_t *sohm = (const H5SM_sohm_t *)record;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_btree_debug)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_bt2_debug)
if(sohm->location == H5SM_IN_HEAP)
HDfprintf(stream, "%*s%-*s {%a, %lo, %Hx}\n", indent, "", fwidth,
@@ -369,11 +214,51 @@ H5SM_btree_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
} /* end else */
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_btree_debug */
+} /* end H5SM_bt2_debug */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_bt2_crt_dbg_context
+ *
+ * Purpose: Create context for debugging callback
+ *
+ * Return: Success: non-NULL
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, December 1, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5SM_bt2_crt_dbg_context(H5F_t *f, hid_t UNUSED dxpl_id, haddr_t UNUSED addr)
+{
+ H5SM_bt2_ctx_t *ctx; /* Callback context structure */
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_bt2_crt_dbg_context)
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+
+ /* Allocate callback context */
+ if(NULL == (ctx = H5FL_MALLOC(H5SM_bt2_ctx_t)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate callback context")
+
+ /* Determine the size of addresses & lengths in the file */
+ ctx->sizeof_addr = H5F_SIZEOF_ADDR(f);
+
+ /* Set return value */
+ ret_value = ctx;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5SM_bt2_crt_dbg_context() */
/*-------------------------------------------------------------------------
- * Function: H5SM_btree_convert_to_list_op
+ * Function: H5SM_bt2_convert_to_list_op
*
* Purpose: An H5B2_remove_t callback function to convert a SOHM
* B-tree index to a list.
@@ -389,13 +274,13 @@ H5SM_btree_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
*-------------------------------------------------------------------------
*/
herr_t
-H5SM_btree_convert_to_list_op(const void * record, void *op_data)
+H5SM_bt2_convert_to_list_op(const void * record, void *op_data)
{
const H5SM_sohm_t *message = (const H5SM_sohm_t *)record;
const H5SM_list_t *list = (const H5SM_list_t *)op_data;
size_t mesg_idx; /* Index of message to modify */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_btree_convert_to_list_op)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_bt2_convert_to_list_op)
/* Sanity checks */
HDassert(record);
@@ -411,5 +296,5 @@ H5SM_btree_convert_to_list_op(const void * record, void *op_data)
HDmemcpy(&(list->messages[mesg_idx]), message, sizeof(H5SM_sohm_t));
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_btree_convert_to_list_op() */
+} /* end H5SM_bt2_convert_to_list_op() */
diff --git a/src/H5SMcache.c b/src/H5SMcache.c
index 7c6cdfc..070b00e 100644
--- a/src/H5SMcache.c
+++ b/src/H5SMcache.c
@@ -27,6 +27,7 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
#include "H5FLprivate.h" /* Free Lists */
+#include "H5MFprivate.h" /* File memory management */
#include "H5MMprivate.h" /* Memory management */
#include "H5SMpkg.h" /* Shared object header messages */
#include "H5WBprivate.h" /* Wrapped Buffers */
@@ -75,6 +76,7 @@ const H5AC_class_t H5AC_SOHM_TABLE[1] = {{
(H5AC_flush_func_t)H5SM_table_flush,
(H5AC_dest_func_t)H5SM_table_dest,
(H5AC_clear_func_t)H5SM_table_clear,
+ (H5AC_notify_func_t)NULL,
(H5AC_size_func_t)H5SM_table_size,
}};
@@ -84,6 +86,7 @@ const H5AC_class_t H5AC_SOHM_LIST[1] = {{
(H5AC_flush_func_t)H5SM_list_flush,
(H5AC_dest_func_t)H5SM_list_dest,
(H5AC_clear_func_t)H5SM_list_clear,
+ (H5AC_notify_func_t)NULL,
(H5AC_size_func_t)H5SM_list_size,
}};
@@ -135,7 +138,7 @@ H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1
/* Allocate space for the master table in memory */
if(NULL == (table = H5FL_CALLOC(H5SM_master_table_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "memory allocation failed")
/* Read number of indexes and version from file superblock */
table->num_indexes = f->shared->sohm_nindexes;
@@ -154,7 +157,7 @@ H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1
size = H5SM_TABLE_SIZE(f) + (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f));
/* Get a pointer to a buffer that's large enough for serialized table */
- if(NULL == (buf = H5WB_actual(wb, size)))
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read header from disk */
@@ -165,9 +168,9 @@ H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1
p = buf;
/* Check magic number */
- if(HDmemcmp(p, H5SM_TABLE_MAGIC, (size_t)H5SM_SIZEOF_MAGIC))
+ if(HDmemcmp(p, H5SM_TABLE_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM table signature")
- p += H5SM_SIZEOF_MAGIC;
+ p += H5_SIZEOF_MAGIC;
/* Don't count the checksum in the table size yet, since it comes after
* all of the index headers
@@ -176,16 +179,16 @@ H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1
/* Allocate space for the index headers in memory*/
if(NULL == (table->indexes = (H5SM_index_header_t *)H5FL_ARR_MALLOC(H5SM_index_header_t, (size_t)table->num_indexes)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for SOHM indexes")
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "memory allocation failed for SOHM indexes")
/* Read in the index headers */
for(x = 0; x < table->num_indexes; ++x) {
/* Verify correct version of index list */
if(H5SM_LIST_VERSION != *p++)
- HGOTO_ERROR(H5E_FILE, H5E_VERSION, NULL, "bad shared message list version number")
+ HGOTO_ERROR(H5E_SOHM, H5E_VERSION, NULL, "bad shared message list version number")
/* Type of the index (list or B-tree) */
- table->indexes[x].index_type= *p++;
+ table->indexes[x].index_type= (H5SM_index_type_t)*p++;
/* Type of messages in the index */
UINT16DECODE(p, table->indexes[x].mesg_types);
@@ -233,7 +236,7 @@ done:
(void)H5SM_table_dest(f, table);
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5SM_table_load() */
+} /* end H5SM_table_load() */
/*-------------------------------------------------------------------------
@@ -283,15 +286,15 @@ H5SM_table_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_ma
size = H5SM_TABLE_SIZE(f) + (H5SM_INDEX_HEADER_SIZE(f) * table->num_indexes);
/* Get a pointer to a buffer that's large enough for serialized table */
- if(NULL == (buf = H5WB_actual(wb, size)))
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Get temporary pointer to buffer for serialized table */
p = buf;
/* Encode magic number */
- HDmemcpy(p, H5SM_TABLE_MAGIC, (size_t)H5SM_SIZEOF_MAGIC);
- p += H5SM_SIZEOF_MAGIC;
+ HDmemcpy(p, H5SM_TABLE_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
/* Encode each index header */
for(x = 0; x < table->num_indexes; ++x) {
@@ -371,7 +374,7 @@ H5SM_table_dest(H5F_t UNUSED *f, H5SM_master_table_t* table)
H5FL_ARR_FREE(H5SM_index_header_t, table->indexes);
- H5FL_FREE(H5SM_master_table_t, table);
+ (void)H5FL_FREE(H5SM_master_table_t, table);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5SM_table_dest() */
@@ -459,6 +462,7 @@ H5SM_list_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1,
{
H5SM_list_t *list; /* The SOHM list being read in */
H5SM_index_header_t *header = (H5SM_index_header_t *) udata2; /* Index header for this list */
+ H5SM_bt2_ctx_t ctx; /* Message encoding context */
size_t size; /* Size of SOHM list on disk */
H5WB_t *wb = NULL; /* Wrapped buffer for list index data */
uint8_t lst_buf[H5SM_LST_BUF_SIZE]; /* Buffer for list index */
@@ -476,12 +480,12 @@ H5SM_list_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1,
/* Allocate space for the SOHM list data structure */
if(NULL == (list = H5FL_MALLOC(H5SM_list_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "memory allocation failed")
HDmemset(&list->cache_info, 0, sizeof(H5AC_info_t));
/* Allocate list in memory as an array*/
if((list->messages = (H5SM_sohm_t *)H5FL_ARR_MALLOC(H5SM_sohm_t, header->list_max)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "file allocation failed for SOHM list")
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "file allocation failed for SOHM list")
list->header = header;
@@ -493,7 +497,7 @@ H5SM_list_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1,
size = H5SM_LIST_SIZE(f, header->num_messages);
/* Get a pointer to a buffer that's large enough for serialized list index */
- if(NULL == (buf = H5WB_actual(wb, size)))
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read list from disk */
@@ -504,13 +508,14 @@ H5SM_list_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1,
p = buf;
/* Check magic number */
- if(HDmemcmp(p, H5SM_LIST_MAGIC, (size_t)H5SM_SIZEOF_MAGIC))
+ if(HDmemcmp(p, H5SM_LIST_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM list signature")
- p += H5SM_SIZEOF_MAGIC;
+ p += H5_SIZEOF_MAGIC;
/* Read messages into the list array */
+ ctx.sizeof_addr = H5F_SIZEOF_ADDR(f);
for(x = 0; x < header->num_messages; x++) {
- if(H5SM_message_decode(f, p, &(list->messages[x])) < 0)
+ if(H5SM_message_decode(p, &(list->messages[x]), &ctx) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "can't decode shared message")
p += H5SM_SOHM_ENTRY_SIZE(f);
} /* end for */
@@ -542,7 +547,7 @@ done:
if(!ret_value && list) {
if(list->messages)
H5FL_ARR_FREE(H5SM_sohm_t, list->messages);
- H5FL_FREE(H5SM_list_t, list);
+ (void)H5FL_FREE(H5SM_list_t, list);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -577,6 +582,7 @@ H5SM_list_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_lis
HDassert(list->header);
if(list->cache_info.is_dirty) {
+ H5SM_bt2_ctx_t ctx; /* Message encoding context */
uint8_t *buf; /* Temporary buffer */
uint8_t *p; /* Pointer into raw data buffer */
size_t size; /* Header size on disk */
@@ -591,21 +597,22 @@ H5SM_list_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_lis
size = H5SM_LIST_SIZE(f, list->header->num_messages);
/* Get a pointer to a buffer that's large enough for serialized list index */
- if(NULL == (buf = H5WB_actual(wb, size)))
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Get temporary pointer to buffer for serialized list index */
p = buf;
/* Encode magic number */
- HDmemcpy(p, H5SM_LIST_MAGIC, (size_t)H5SM_SIZEOF_MAGIC);
- p += H5SM_SIZEOF_MAGIC;
+ HDmemcpy(p, H5SM_LIST_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
/* Write messages from the messages array to disk */
mesgs_written = 0;
+ ctx.sizeof_addr = H5F_SIZEOF_ADDR(f);
for(x = 0; x < list->header->list_max && mesgs_written < list->header->num_messages; x++) {
if(list->messages[x].location != H5SM_NO_LOC) {
- if(H5SM_message_encode(f, p, &(list->messages[x])) < 0)
+ if(H5SM_message_encode(p, &(list->messages[x]), &ctx) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to write shared message to disk")
p+=H5SM_SOHM_ENTRY_SIZE(f);
@@ -652,18 +659,34 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5SM_list_dest(H5F_t UNUSED *f, H5SM_list_t* list)
+H5SM_list_dest(H5F_t *f, H5SM_list_t* list)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_list_dest)
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_list_dest)
+ /* Sanity check */
HDassert(list);
+ HDassert(list->header);
HDassert(list->messages);
- H5FL_ARR_FREE(H5SM_sohm_t, list->messages);
+ /* If we're going to free the space on disk, the address must be valid */
+ HDassert(!list->cache_info.free_file_space_on_destroy || H5F_addr_defined(list->cache_info.addr));
+
+ /* Check for freeing file space for shared message index list */
+ if(list->cache_info.free_file_space_on_destroy) {
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_SOHM_INDEX, H5AC_dxpl_id, list->cache_info.addr, (hsize_t)H5SM_LIST_SIZE(f, list->header->list_max)) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "unable to free shared message list")
+ } /* end if */
- H5FL_FREE(H5SM_list_t, list);
+ /* Release resources */
+ H5FL_ARR_FREE(H5SM_sohm_t, list->messages);
+ (void)H5FL_FREE(H5SM_list_t, list);
- FUNC_LEAVE_NOAPI(SUCCEED)
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_list_dest() */
diff --git a/src/H5SMmessage.c b/src/H5SMmessage.c
new file mode 100644
index 0000000..9a214ea
--- /dev/null
+++ b/src/H5SMmessage.c
@@ -0,0 +1,358 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5O_PACKAGE /*suppress error about including H5Opkg */
+#define H5SM_PACKAGE /*suppress error about including H5SMpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Opkg.h" /* Object Headers */
+#include "H5SMpkg.h" /* Shared object header messages */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/* Udata struct for calls to H5SM_compare_cb and H5SM_compare_iter_op*/
+typedef struct H5SM_compare_udata_t {
+ const H5SM_mesg_key_t *key; /* Key; compare this against stored message */
+ H5O_msg_crt_idx_t idx; /* Index of the message in the OH, if applicable */
+ herr_t ret; /* Return value; set this to result of memcmp */
+} H5SM_compare_udata_t;
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+static herr_t H5SM_compare_cb(const void *obj, size_t obj_len, void *udata);
+static herr_t H5SM_compare_iter_op(H5O_t *oh, H5O_mesg_t *mesg, unsigned sequence,
+ hbool_t *oh_modified, void *udata);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_compare_cb
+ *
+ * Purpose: Callback for H5HF_op, used in H5SM_message_compare below.
+ * Determines whether the search key passed in in _UDATA is
+ * equal to OBJ or not.
+ *
+ * Passes back the result in _UDATA->RET
+ *
+ * Return: Negative on error, non-negative on success
+ *
+ * Programmer: James Laird
+ * Monday, January 8, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5SM_compare_cb(const void *obj, size_t obj_len, void *_udata)
+{
+ H5SM_compare_udata_t *udata = (H5SM_compare_udata_t *)_udata;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_compare_cb)
+
+ /* If the encoding sizes are different, it's not the same object */
+ if(udata->key->encoding_size > obj_len)
+ udata->ret = 1;
+ else if(udata->key->encoding_size < obj_len)
+ udata->ret = -1;
+ else
+ /* Sizes are the same. Return result of memcmp */
+ udata->ret = HDmemcmp(udata->key->encoding, obj, obj_len);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5SM_compare_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_compare_iter_op
+ *
+ * Purpose: OH iteration callback to compare a key against a message in
+ * an OH
+ *
+ * Return: 0 if this is not the message we're searching for
+ * 1 if this is the message we're searching for (with memcmp
+ * result returned in udata)
+ * negative on error
+ *
+ * Programmer: James Laird
+ * Wednesday, February 7, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5SM_compare_iter_op(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned sequence,
+ hbool_t UNUSED *oh_modified, void *_udata/*in,out*/)
+{
+ H5SM_compare_udata_t *udata = (H5SM_compare_udata_t *) _udata;
+ herr_t ret_value = H5_ITER_CONT;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_compare_iter_op)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(oh);
+ HDassert(mesg);
+ HDassert(udata && udata->key);
+
+ /* Check the creation index for this message */
+ if(sequence == udata->idx) {
+ size_t aligned_encoded_size = H5O_ALIGN_OH(oh, udata->key->encoding_size);
+
+ /* Sanity check the message's length */
+ HDassert(mesg->raw_size > 0);
+
+ if(aligned_encoded_size > mesg->raw_size)
+ udata->ret = 1;
+ else if(aligned_encoded_size < mesg->raw_size)
+ udata->ret = -1;
+ else {
+ /* Check if the message is dirty & flush it to the object header if so */
+ if(mesg->dirty)
+ if(H5O_msg_flush(udata->key->file, oh, mesg) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTENCODE, H5_ITER_ERROR, "unable to encode object header message")
+
+ HDassert(udata->key->encoding_size <= mesg->raw_size);
+ udata->ret = HDmemcmp(udata->key->encoding, mesg->raw, udata->key->encoding_size);
+ } /* end else */
+
+ /* Indicate that we found the message we were looking for */
+ ret_value = H5_ITER_STOP;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5SM_compare_iter_op() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_message_compare
+ *
+ * Purpose: Determine whether the search key rec1 represents a shared
+ * message that is equal to rec2 or not, and if not, whether
+ * rec1 is "greater than" or "less than" rec2.
+ *
+ * Return: 0 if rec1 == rec2
+ * Negative if rec1 < rec2
+ * Positive if rec1 > rec2
+ *
+ * Programmer: James Laird
+ * Monday, November 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5SM_message_compare(const void *rec1, const void *rec2)
+{
+ const H5SM_mesg_key_t *key = (const H5SM_mesg_key_t *) rec1;
+ const H5SM_sohm_t *mesg = (const H5SM_sohm_t *) rec2;
+ herr_t ret_value = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_message_compare)
+
+ /* If the key has an fheap ID, we're looking for a message that's
+ * already in the index; if the fheap ID matches, we've found the message
+ * and can stop immediately.
+ * Likewise, if the message has an OH location that is matched by the
+ * message in the index, we've found the message.
+ */
+ if(mesg->location == H5SM_IN_HEAP && key->message.location == H5SM_IN_HEAP) {
+ if(key->message.u.heap_loc.fheap_id == mesg->u.heap_loc.fheap_id)
+ HGOTO_DONE(0);
+ } /* end if */
+ else if(mesg->location == H5SM_IN_OH && key->message.location == H5SM_IN_OH) {
+ if(key->message.u.mesg_loc.oh_addr == mesg->u.mesg_loc.oh_addr &&
+ key->message.u.mesg_loc.index == mesg->u.mesg_loc.index &&
+ key->message.msg_type_id == mesg->msg_type_id)
+ HGOTO_DONE(0);
+ } /* end if */
+
+ /* Compare hash values */
+ if(key->message.hash > mesg->hash)
+ ret_value = 1;
+ else if(key->message.hash < mesg->hash)
+ ret_value = -1;
+ /* If the hash values match, make sure the messages are really the same */
+ else {
+ /* Hash values match; compare the encoded message with the one in
+ * the index.
+ */
+ H5SM_compare_udata_t udata;
+ herr_t status;
+
+ HDassert(key->message.hash == mesg->hash);
+ HDassert(key->encoding_size > 0 && key->encoding);
+
+ /* Set up user data for callback */
+ udata.key = key;
+
+ /* Compare the encoded message with either the message in the heap or
+ * the message in an object header.
+ */
+ if(mesg->location == H5SM_IN_HEAP) {
+ /* Call heap op routine with comparison callback */
+ status = H5HF_op(key->fheap, key->dxpl_id, &(mesg->u.heap_loc.fheap_id), H5SM_compare_cb, &udata);
+ HDassert(status >= 0);
+ } /* end if */
+ else {
+ H5O_loc_t oloc; /* Object owning the message */
+ H5O_mesg_operator_t op; /* Message operator */
+
+ /* Sanity checks */
+ HDassert(key->file);
+ HDassert(mesg->location == H5SM_IN_OH);
+
+ /* Reset the object location */
+ status = H5O_loc_reset(&oloc);
+ HDassert(status >= 0);
+
+ /* Set up object location */
+ oloc.file = key->file;
+ oloc.addr = mesg->u.mesg_loc.oh_addr;
+
+ /* Finish setting up user data for iterator */
+ udata.idx = mesg->u.mesg_loc.index;
+
+ /* Locate the right message and compare with it */
+ op.op_type = H5O_MESG_OP_LIB;
+ op.u.lib_op = H5SM_compare_iter_op;
+ status = H5O_msg_iterate(&oloc, mesg->msg_type_id, &op, &udata, key->dxpl_id);
+ HDassert(status >= 0);
+ } /* end else */
+
+ ret_value = udata.ret;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5SM_message_compare */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_message_encode
+ *
+ * Purpose: Serialize a H5SM_sohm_t struct into a buffer RAW.
+ *
+ * Return: Non-negative on success
+ * Negative on failure
+ *
+ * Programmer: James Laird
+ * Monday, November 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5SM_message_encode(uint8_t *raw, const void *_nrecord, void *_ctx)
+{
+ H5SM_bt2_ctx_t *ctx = (H5SM_bt2_ctx_t *)_ctx; /* Callback context structure */
+ const H5SM_sohm_t *message = (const H5SM_sohm_t *)_nrecord;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_message_encode)
+
+ /* Sanity check */
+ HDassert(ctx);
+
+ *raw++ = message->location;
+ UINT32ENCODE(raw, message->hash);
+
+ if(message->location == H5SM_IN_HEAP) {
+ UINT32ENCODE(raw, message->u.heap_loc.ref_count);
+ UINT64ENCODE(raw, message->u.heap_loc.fheap_id);
+ } /* end if */
+ else {
+ HDassert(message->location == H5SM_IN_OH);
+
+ *raw++ = 0; /* reserved (possible flags byte) */
+ *raw++ = (uint8_t)message->msg_type_id;
+ UINT16ENCODE(raw, message->u.mesg_loc.index);
+ H5F_addr_encode_len(ctx->sizeof_addr, &raw, message->u.mesg_loc.oh_addr);
+ } /* end else */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5SM_message_encode */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_message_decode
+ *
+ * Purpose: Read an encoded SOHM message from RAW into an H5SM_sohm_t struct.
+ *
+ * Return: Non-negative on success
+ * Negative on failure
+ *
+ * Programmer: James Laird
+ * Monday, November 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5SM_message_decode(const uint8_t *raw, void *_nrecord, void *_ctx)
+{
+ H5SM_bt2_ctx_t *ctx = (H5SM_bt2_ctx_t *)_ctx; /* Callback context structure */
+ H5SM_sohm_t *message = (H5SM_sohm_t *)_nrecord;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_message_decode)
+
+ message->location = (H5SM_storage_loc_t)*raw++;
+ UINT32DECODE(raw, message->hash);
+
+ if(message->location == H5SM_IN_HEAP) {
+ UINT32DECODE(raw, message->u.heap_loc.ref_count);
+ UINT64DECODE(raw, message->u.heap_loc.fheap_id);
+ } /* end if */
+ else {
+ HDassert(message->location == H5SM_IN_OH);
+
+ raw++; /* reserved */
+ message->msg_type_id = *raw++;
+ UINT16DECODE(raw, message->u.mesg_loc.index);
+ H5F_addr_decode_len(ctx->sizeof_addr, &raw, &message->u.mesg_loc.oh_addr);
+ } /* end else */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5SM_message_decode */
+
diff --git a/src/H5SMpkg.h b/src/H5SMpkg.h
index 8d987a9..64f0ccb 100755
--- a/src/H5SMpkg.h
+++ b/src/H5SMpkg.h
@@ -40,53 +40,46 @@
/* Package Macros */
/****************************/
-/* Size of signature information (on disk) */
-#define H5SM_SIZEOF_MAGIC 4
-
-/* Shared Message signatures */
-#define H5SM_TABLE_MAGIC "SMTB" /* Shared Message Table */
-#define H5SM_LIST_MAGIC "SMLI" /* Shared Message List */
-
/* Size of checksum information (on disk) */
#define H5SM_SIZEOF_CHECKSUM 4
#define H5SM_HEAP_LOC_SIZE ( \
- 4 /* Reference count */ \
+ (unsigned)4 /* Reference count */ \
+ sizeof(H5O_fheap_id_t) /* size of heap ID on disk */ \
)
#define H5SM_OH_LOC_SIZE(f) ( \
- 1 /* reserved (possible flags?) */ \
- + 1 /* message type ID */ \
- + 2 /* creation index of message in OH */ \
+ (unsigned)1 /* reserved (possible flags?) */ \
+ + (unsigned)1 /* message type ID */ \
+ + (unsigned)2 /* creation index of message in OH */ \
+ H5F_SIZEOF_ADDR(f) /* address of OH */ \
)
#define H5SM_SOHM_ENTRY_SIZE(f) ( \
- 1 /* Message location */ \
- + 4 /* Hash value */ \
+ (unsigned)1 /* Message location */ \
+ + (unsigned)4 /* Hash value */ \
+ MAX(H5SM_HEAP_LOC_SIZE, H5SM_OH_LOC_SIZE(f)) /* Entry */ \
)
#define H5SM_TABLE_SIZE(f) ( \
- H5SM_SIZEOF_MAGIC /* Signature */ \
- + H5SM_SIZEOF_CHECKSUM /* Checksum */ \
+ (unsigned)H5_SIZEOF_MAGIC /* Signature */ \
+ + (unsigned)H5SM_SIZEOF_CHECKSUM /* Checksum */ \
)
#define H5SM_INDEX_HEADER_SIZE(f) ( \
- 1 /* Whether index is a list or B-tree */ \
- + 1 /* Version of index format */ \
- + 2 /* Type of messages stored in the index */ \
- + 4 /* Minimum size of messages to share */ \
- + (3 * 2) /* B-tree cutoff, list cutoff, # of shared messages */ \
+ (unsigned)1 /* Whether index is a list or B-tree */ \
+ + (unsigned)1 /* Version of index format */ \
+ + (unsigned)2 /* Type of messages stored in the index */ \
+ + (unsigned)4 /* Minimum size of messages to share */ \
+ + (unsigned)(3 * 2) /* B-tree cutoff, list cutoff, # of shared messages */ \
+ H5F_SIZEOF_ADDR(f) /* Location of list or B-tree */ \
+ H5F_SIZEOF_ADDR(f) /* Address of heap */ \
)
#define H5SM_LIST_SIZE(f, num_mesg) ( \
- H5SM_SIZEOF_MAGIC /* Signature */ \
+ (unsigned) H5_SIZEOF_MAGIC /* Signature */ \
+ (H5SM_SOHM_ENTRY_SIZE(f) * num_mesg) /* Message entries */ \
- + H5SM_SIZEOF_CHECKSUM /* Checksum */ \
+ + (unsigned)H5SM_SIZEOF_CHECKSUM /* Checksum */ \
)
#define H5SM_B2_NODE_SIZE 512
@@ -220,6 +213,11 @@ typedef struct {
hid_t dxpl_id;
} H5SM_incr_ref_opdata;
+/* v2 B-tree client callback context */
+typedef struct H5SM_bt2_ctx_t {
+ uint8_t sizeof_addr; /* Size of file addresses */
+} H5SM_bt2_ctx_t;
+
/****************************/
/* Package Variables */
@@ -243,20 +241,12 @@ H5_DLLVAR const H5B2_class_t H5SM_INDEX[1];
H5_DLL ssize_t H5SM_get_index(const H5SM_master_table_t *table, unsigned type_id);
/* Encode and decode routines, used for B-tree and cache encoding/decoding */
-H5_DLL herr_t H5SM_message_encode(const H5F_t *f, uint8_t *raw,
- const void *native);
-H5_DLL herr_t H5SM_message_decode(const H5F_t *f, const uint8_t *raw,
- void *native);
-
-/* Callbacks to give to B-tree traversals */
-/* H5SM_message_compare is in H5SMbtree2.c, but is also used by list code
- * in H5SM.c.
- */
-H5_DLL herr_t H5SM_message_compare(const void *rec1,
- const void *rec2);
+H5_DLL herr_t H5SM_message_compare(const void *rec1, const void *rec2);
+H5_DLL herr_t H5SM_message_encode(uint8_t *raw, const void *native, void *ctx);
+H5_DLL herr_t H5SM_message_decode(const uint8_t *raw, void *native, void *ctx);
/* H5B2_remove_t callback to add messages to a list index */
-H5_DLL herr_t H5SM_btree_convert_to_list_op(const void * record, void *op_data);
+H5_DLL herr_t H5SM_bt2_convert_to_list_op(const void * record, void *op_data);
/* Fractal heap 'op' callback to compute hash value for message "in place" */
H5_DLL herr_t H5SM_get_hash_fh_cb(const void *obj, size_t obj_len, void *_udata);
diff --git a/src/H5SMprivate.h b/src/H5SMprivate.h
index 1465357..46a43ad 100755
--- a/src/H5SMprivate.h
+++ b/src/H5SMprivate.h
@@ -56,7 +56,7 @@ H5_DLL herr_t H5SM_reconstitute(H5O_shared_t *sh_mesg, H5F_t *f,
unsigned msg_type_id, H5O_fheap_id_t heap_id);
H5_DLL herr_t H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id,
const H5O_shared_t *sh_mesg, hsize_t *ref_count);
-H5_DLL herr_t H5SM_ih_size(H5F_t *f, hid_t dxpl_id, H5F_info_t *bh_info);
+H5_DLL herr_t H5SM_ih_size(H5F_t *f, hid_t dxpl_id, hsize_t *hdr_size, H5_ih_info_t *ih_info);
/* Debugging routines */
diff --git a/src/H5SMtest.c b/src/H5SMtest.c
index 5de8ce1..582bc0e 100644
--- a/src/H5SMtest.c
+++ b/src/H5SMtest.c
@@ -78,7 +78,7 @@
herr_t
H5SM_get_mesg_count_test(H5F_t *f, hid_t dxpl_id, unsigned type_id,
size_t *mesg_count)
-{
+{
H5SM_master_table_t *table = NULL; /* SOHM master table */
herr_t ret_value = SUCCEED; /* Return value */
@@ -95,7 +95,7 @@ H5SM_get_mesg_count_test(H5F_t *f, hid_t dxpl_id, unsigned type_id,
/* Look up the master SOHM table */
if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table")
/* Find the correct index for this message type */
if((index_num = H5SM_get_index(table, type_id)) < 0)
@@ -112,7 +112,7 @@ H5SM_get_mesg_count_test(H5F_t *f, hid_t dxpl_id, unsigned type_id,
done:
/* Release resources */
if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table")
+ HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_get_mesg_count_test() */
diff --git a/src/H5ST.c b/src/H5ST.c
index f36855e..6d14115 100644
--- a/src/H5ST.c
+++ b/src/H5ST.c
@@ -50,19 +50,19 @@ H5FL_DEFINE_STATIC(H5ST_tree_t);
H5ST_tree_t *
H5ST_create(void)
{
- H5ST_tree_t *ret_value=NULL; /* Return value */
+ H5ST_tree_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5ST_create,NULL);
+ FUNC_ENTER_NOAPI(H5ST_create, NULL)
/* Allocate wrapper for TST */
- if((ret_value=H5FL_MALLOC(H5ST_tree_t))==NULL)
- HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,NULL,"memory allocation failed");
+ if(NULL == (ret_value = H5FL_MALLOC(H5ST_tree_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Set the internal fields */
- ret_value->root=NULL;
+ ret_value->root = NULL;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_create() */
@@ -87,18 +87,18 @@ done:
static herr_t
H5ST_close_internal(H5ST_ptr_t p)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_close_internal);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_close_internal)
/* Recursively free TST */
if(p) {
H5ST_close_internal(p->lokid);
- if (p->splitchar)
+ if(p->splitchar)
H5ST_close_internal(p->eqkid);
H5ST_close_internal(p->hikid);
- H5FL_FREE(H5ST_node_t,p);
+ (void)H5FL_FREE(H5ST_node_t, p);
} /* end if */
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5ST_close_internal() */
@@ -123,23 +123,23 @@ H5ST_close_internal(H5ST_ptr_t p)
herr_t
H5ST_close(H5ST_tree_t *tree)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5ST_close,FAIL);
+ FUNC_ENTER_NOAPI(H5ST_close, FAIL)
/* Check arguments */
- if(tree==NULL)
- HGOTO_ERROR(H5E_ARGS,H5E_BADVALUE,FAIL,"invalid TST");
+ if(NULL == tree)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid TST")
/* Free the TST itself */
- if(H5ST_close_internal(tree->root)<0)
- HGOTO_ERROR(H5E_TST,H5E_CANTFREE,FAIL,"can't free TST");
+ if(H5ST_close_internal(tree->root) < 0)
+ HGOTO_ERROR(H5E_TST, H5E_CANTFREE, FAIL, "can't free TST")
/* Free root node itself */
- H5FL_FREE(H5ST_tree_t,tree);
+ (void)H5FL_FREE(H5ST_tree_t, tree);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_close() */
@@ -178,16 +178,16 @@ H5ST_insert(H5ST_tree_t *tree, const char *s, void *obj)
p = &tree->root;
while((pp = *p)) {
/* If this node matches the character in the key, then drop down to the lower tree */
- if ((d = *s - pp->splitchar) == 0) {
- if (*s++ == 0)
- HGOTO_ERROR(H5E_TST,H5E_EXISTS,FAIL,"key already in tree");
+ if(0 == (d = *s - pp->splitchar)) {
+ if(*s++ == 0)
+ HGOTO_ERROR(H5E_TST, H5E_EXISTS, FAIL, "key already in tree")
up=pp;
p = &(pp->eqkid);
} /* end if */
else {
/* Walk through the current tree, searching for the matching character */
- parent=pp;
- if (d < 0)
+ parent = pp;
+ if(d < 0)
p = &(pp->lokid);
else
p = &(pp->hikid);
@@ -196,8 +196,8 @@ H5ST_insert(H5ST_tree_t *tree, const char *s, void *obj)
/* Finish walking through the key string, adding nodes until the end */
for (;;) {
- if((*p = H5FL_MALLOC(H5ST_node_t))==NULL)
- HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed");
+ if(NULL == (*p = H5FL_MALLOC(H5ST_node_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
pp = *p;
pp->splitchar = *s;
pp->up = up;
@@ -205,19 +205,19 @@ H5ST_insert(H5ST_tree_t *tree, const char *s, void *obj)
pp->lokid = pp->eqkid = pp->hikid = NULL;
/* If this is the end of the key string, break out */
- if (*s++ == 0) {
- pp->eqkid = (H5ST_ptr_t) obj;
+ if(*s++ == 0) {
+ pp->eqkid = (H5ST_ptr_t)obj;
break;
} /* end if */
/* Continue to next character */
- parent=NULL;
- up=pp;
+ parent = NULL;
+ up = pp;
p = &(pp->eqkid);
} /* end for */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_insert() */
@@ -247,7 +247,7 @@ H5ST_search(H5ST_tree_t *tree, const char *s)
H5ST_ptr_t p; /* Temporary pointer to TST node */
htri_t ret_value=FALSE; /* Return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5ST_search);
+ FUNC_ENTER_NOAPI_NOFUNC(H5ST_search)
p = tree->root;
while (p) {
@@ -262,7 +262,7 @@ H5ST_search(H5ST_tree_t *tree, const char *s)
} /* end while */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_search() */
@@ -289,9 +289,9 @@ done:
static H5ST_ptr_t
H5ST_find_internal(H5ST_ptr_t p, const char *s)
{
- H5ST_ptr_t ret_value=NULL; /* Return value */
+ H5ST_ptr_t ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_find_internal);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_find_internal)
while (p) {
if (*s < p->splitchar)
@@ -305,7 +305,7 @@ H5ST_find_internal(H5ST_ptr_t p, const char *s)
} /* end while */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_find_internal() */
@@ -332,15 +332,15 @@ done:
H5ST_ptr_t
H5ST_find(H5ST_tree_t *tree, const char *s)
{
- H5ST_ptr_t ret_value=NULL; /* Return value */
+ H5ST_ptr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5ST_find,NULL);
+ FUNC_ENTER_NOAPI(H5ST_find, NULL)
- if((ret_value=H5ST_find_internal(tree->root,s))==NULL)
- HGOTO_ERROR(H5E_TST,H5E_NOTFOUND,NULL,"key not found in TST");
+ if(NULL == (ret_value = H5ST_find_internal(tree->root, s)))
+ HGOTO_ERROR(H5E_TST, H5E_NOTFOUND, NULL, "key not found in TST")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_find() */
@@ -369,17 +369,17 @@ H5ST_locate(H5ST_tree_t *tree, const char *s)
H5ST_ptr_t node; /* Pointer to node located */
void *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5ST_locate,NULL);
+ FUNC_ENTER_NOAPI(H5ST_locate, NULL)
/* Locate the node to remove */
- if((node=H5ST_find_internal(tree->root,s))==NULL)
- HGOTO_ERROR(H5E_TST,H5E_NOTFOUND,NULL,"key not found in TST");
+ if(NULL == (node = H5ST_find_internal(tree->root, s)))
+ HGOTO_ERROR(H5E_TST, H5E_NOTFOUND, NULL, "key not found in TST")
/* Get the pointer to the object to return */
- ret_value=node->eqkid;
+ ret_value = node->eqkid;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5ST_locate() */
@@ -404,28 +404,28 @@ done:
static H5ST_ptr_t
H5ST_findfirst_internal(H5ST_ptr_t p)
{
- H5ST_ptr_t ret_value=NULL; /* Return value */
+ H5ST_ptr_t ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_findfirst_internal);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_findfirst_internal)
while(p) {
/* Find least node in current tree */
while(p->lokid)
- p=p->lokid;
+ p = p->lokid;
/* Is least node '\0'? */
- if(p->splitchar=='\0') {
+ if(p->splitchar == '\0') {
/* Return it */
HGOTO_DONE(p);
} /* end if */
else {
/* Go down to next level of tree */
- p=p->eqkid;
+ p = p->eqkid;
} /* end else */
} /* end while */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_findfirst_internal() */
@@ -452,13 +452,13 @@ H5ST_findfirst(H5ST_tree_t *tree)
{
H5ST_ptr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5ST_findfirst,NULL);
+ FUNC_ENTER_NOAPI(H5ST_findfirst, NULL)
- if((ret_value=H5ST_findfirst_internal(tree->root))==NULL)
+ if(NULL == (ret_value = H5ST_findfirst_internal(tree->root)))
HGOTO_ERROR(H5E_TST,H5E_NOTFOUND,NULL,"no nodes in TST");
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_findfirst() */
@@ -483,40 +483,40 @@ done:
static H5ST_ptr_t
H5ST_getnext(H5ST_ptr_t p)
{
- H5ST_ptr_t ret_value=NULL; /* Return value */
+ H5ST_ptr_t ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_getnext);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_getnext)
/* If the node to continue from has higher-valued nodes attached */
if(p->hikid) {
/* Go to first higher-valued node */
- p=p->hikid;
+ p = p->hikid;
/* Find least node from here */
while(p->lokid)
- p=p->lokid;
+ p = p->lokid;
HGOTO_DONE(p);
} /* end if */
else {
H5ST_ptr_t q; /* Temporary TST node pointer */
/* Go up one level in current tree */
- q=p->parent;
- if(q==NULL)
+ q = p->parent;
+ if(q == NULL)
HGOTO_DONE(NULL);
/* While the previous node was the higher-valued node, keep backing up the tree */
- while(q->hikid==p) {
- p=q;
- q=p->parent;
- if(q==NULL)
+ while(q->hikid == p) {
+ p = q;
+ q = p->parent;
+ if(NULL == q)
HGOTO_DONE(NULL);
} /* end while */
HGOTO_DONE(q);
} /* end else */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_getnext() */
@@ -542,22 +542,22 @@ H5ST_ptr_t
H5ST_findnext(H5ST_ptr_t p)
{
H5ST_ptr_t q; /* Temporary pointer to TST node */
- H5ST_ptr_t ret_value=NULL; /* Return value */
+ H5ST_ptr_t ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5ST_findnext);
+ FUNC_ENTER_NOAPI_NOFUNC(H5ST_findnext)
/* Find the next node at the current level, or go back up the tree */
do {
- q=H5ST_getnext(p);
+ q = H5ST_getnext(p);
if(q) {
HGOTO_DONE(H5ST_findfirst_internal(q->eqkid));
} /* end if */
else
- p=p->up;
+ p = p->up;
} while(p);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_findnext() */
@@ -587,53 +587,54 @@ H5ST_delete_internal(H5ST_ptr_t *root, H5ST_ptr_t p)
H5ST_ptr_t q, /* Temporary pointer to TST node */
newp; /* Pointer to node which will replace deleted node in tree */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_delete_internal);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_delete_internal)
/* Find node to replace one being deleted */
if(p->lokid) {
/* If the deleted node has lo & hi kids, attach them together */
if(p->hikid) {
- q=p->lokid;
+ q = p->lokid;
while(q->hikid)
- q=q->hikid;
- q->hikid=p->hikid;
- p->hikid->parent=q;
+ q = q->hikid;
+ q->hikid = p->hikid;
+ p->hikid->parent = q;
} /* end if */
- newp=p->lokid;
+ newp = p->lokid;
} /* end if */
else if(p->hikid) {
- newp=p->hikid;
+ newp = p->hikid;
} /* end if */
else {
- newp=NULL;
+ newp = NULL;
} /* end else */
/* Deleted node is in middle of tree */
if(p->parent) {
/* Attach new node to correct side of parent */
- if(p==p->parent->lokid)
- p->parent->lokid=newp;
+ if(p == p->parent->lokid)
+ p->parent->lokid = newp;
else
- p->parent->hikid=newp;
+ p->parent->hikid = newp;
if(newp)
- newp->parent=p->parent;
+ newp->parent = p->parent;
} /* end if */
else {
if(newp)
- newp->parent=p->parent;
+ newp->parent = p->parent;
if(p->up) {
- p->up->eqkid=newp;
+ p->up->eqkid = newp;
+
/* If we deleted the last node in the TST, delete the upper node also */
- if(newp==NULL)
- H5ST_delete_internal(root,p->up);
+ if(NULL == newp)
+ H5ST_delete_internal(root, p->up);
} /* end if */
else /* Deleted last node at top level of tree */
- *root=newp;
+ *root = newp;
} /* end else */
- H5FL_FREE(H5ST_node_t,p);
+ (void)H5FL_FREE(H5ST_node_t, p);
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5ST_delete_internal() */
@@ -660,15 +661,15 @@ H5ST_delete_internal(H5ST_ptr_t *root, H5ST_ptr_t p)
herr_t
H5ST_delete(H5ST_tree_t *tree, H5ST_ptr_t p)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5ST_delete,FAIL);
+ FUNC_ENTER_NOAPI(H5ST_delete, FAIL)
- if(H5ST_delete_internal(&tree->root,p)<0)
- HGOTO_ERROR(H5E_TST,H5E_CANTDELETE,FAIL,"can't delete node from TST");
+ if(H5ST_delete_internal(&tree->root, p) < 0)
+ HGOTO_ERROR(H5E_TST, H5E_CANTDELETE, FAIL, "can't delete node from TST")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_delete() */
@@ -697,21 +698,21 @@ H5ST_remove(H5ST_tree_t *tree, const char *s)
H5ST_ptr_t node; /* Pointer to node to remove */
void *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5ST_remove,NULL);
+ FUNC_ENTER_NOAPI(H5ST_remove, NULL)
/* Locate the node to remove */
- if((node=H5ST_find_internal(tree->root,s))==NULL)
- HGOTO_ERROR(H5E_TST,H5E_NOTFOUND,NULL,"key not found in TST");
+ if(NULL == (node = H5ST_find_internal(tree->root, s)))
+ HGOTO_ERROR(H5E_TST, H5E_NOTFOUND, NULL, "key not found in TST")
/* Get the pointer to the object to return */
- ret_value=node->eqkid;
+ ret_value = node->eqkid;
/* Remove the node from the TST */
- if(H5ST_delete_internal(&tree->root,node)<0)
- HGOTO_ERROR(H5E_TST,H5E_CANTDELETE,NULL,"can't delete node from TST");
+ if(H5ST_delete_internal(&tree->root, node) < 0)
+ HGOTO_ERROR(H5E_TST, H5E_CANTDELETE, NULL, "can't delete node from TST")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5ST_remove() */
#ifdef H5ST_DEBUG
@@ -737,26 +738,26 @@ done:
herr_t
H5ST_dump_internal(H5ST_ptr_t p)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_dump_internal);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_dump_internal)
- if (p) {
- printf("p=%p\n",p);
- printf("\tp->up=%p\n",p->up);
- printf("\tp->parent=%p\n",p->parent);
- printf("\tp->lokid=%p\n",p->lokid);
- printf("\tp->hikid=%p\n",p->hikid);
- printf("\tp->eqkid=%p\n",p->eqkid);
- printf("\tp->splitchar=%c\n",p->splitchar);
+ if(p) {
+ printf("p=%p\n", p);
+ printf("\tp->up=%p\n", p->up);
+ printf("\tp->parent=%p\n", p->parent);
+ printf("\tp->lokid=%p\n", p->lokid);
+ printf("\tp->hikid=%p\n", p->hikid);
+ printf("\tp->eqkid=%p\n", p->eqkid);
+ printf("\tp->splitchar=%c\n", p->splitchar);
H5ST_dump_internal(p->lokid);
- if (p->splitchar)
+ if(p->splitchar)
H5ST_dump_internal(p->eqkid);
else
- printf("%s\n", (char *) p->eqkid);
+ printf("%s\n", (char *)p->eqkid);
H5ST_dump_internal(p->hikid);
} /* end if */
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5ST_dump_internal() */
@@ -781,11 +782,12 @@ H5ST_dump_internal(H5ST_ptr_t p)
herr_t
H5ST_dump(H5ST_tree_t *tree)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5ST_dump,NULL);
+ FUNC_ENTER_NOAPI_NOFUNC(H5ST_dump, NULL)
/* Dump the tree */
H5ST_dump_internal(tree->root);
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5ST_dump() */
#endif /* H5ST_DEBUG */
+
diff --git a/src/H5Sall.c b/src/H5Sall.c
index e8ed337..714624d 100644
--- a/src/H5Sall.c
+++ b/src/H5Sall.c
@@ -828,10 +828,11 @@ done:
herr_t
H5Sselect_all(hid_t spaceid)
{
- H5S_t *space = NULL; /* Dataspace to modify selection of */
+ H5S_t *space; /* Dataspace to modify selection of */
herr_t ret_value = SUCCEED; /* return value */
FUNC_ENTER_API(H5Sselect_all, FAIL)
+ H5TRACE1("e", "i", spaceid);
/* Check args */
if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 455a251..f55135f 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -23,12 +23,12 @@
#define H5S_PACKAGE /*suppress error about including H5Spkg */
-#include "H5private.h" /* Generic Functions */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5FLprivate.h" /* Free Lists */
-#include "H5Iprivate.h" /* ID Functions */
-#include "H5Spkg.h" /* Dataspace functions */
-#include "H5Vprivate.h" /* Vector functions */
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5Iprivate.h" /* ID Functions */
+#include "H5Spkg.h" /* Dataspace functions */
+#include "H5Vprivate.h" /* Vector functions */
/* Local datatypes */
@@ -301,10 +301,10 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space)
/* "Flatten" dataspace extent and selection information */
curr_dim=flat_rank-1;
- for(i=rank-1, acc=1; i>=0; i--) {
- if(tdiminfo[i].block==mem_size[i] && i>0) {
+ for(i = (int)rank - 1, acc = 1; i >= 0; i--) {
+ if(tdiminfo[i].block == mem_size[i] && i > 0) {
/* "Flatten" this dimension */
- assert(tdiminfo[i].start==0);
+ HDassert(tdiminfo[i].start == 0);
acc *= mem_size[i];
/* Indicate that the dimension was flattened */
@@ -322,7 +322,7 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space)
iter->u.hyp.diminfo[curr_dim].count = tdiminfo[i].count;
iter->u.hyp.diminfo[curr_dim].block = tdiminfo[i].block*acc;
iter->u.hyp.size[curr_dim] = mem_size[i]*acc;
- iter->u.hyp.sel_off[curr_dim] = space->select.offset[i]*acc;
+ iter->u.hyp.sel_off[curr_dim] = space->select.offset[i] * acc;
/* Reset the "last dim flattened" flag to avoid flattened any further dimensions */
last_dim_flattened=0;
@@ -441,8 +441,8 @@ H5S_hyper_iter_coords (const H5S_sel_iter_t *iter, hsize_t *coords)
int u, v; /* Dimension indices */
/* Set the starting rank of both the "natural" & "flattened" dimensions */
- u = iter->rank - 1;
- v = iter->u.hyp.iter_rank - 1;
+ u = (int)iter->rank - 1;
+ v = (int)iter->u.hyp.iter_rank - 1;
/* Construct the "natural" dimensions from a set of flattened coordinates */
while(u >= 0) {
@@ -677,7 +677,7 @@ H5S_hyper_iter_next(H5S_sel_iter_t *iter, size_t nelem)
} /* end else */
/* Set the fastest dimension rank */
- fast_dim=ndims-1;
+ fast_dim = (int)ndims - 1;
/* Set the local copy of the diminfo pointer */
tdiminfo=iter->u.hyp.diminfo;
@@ -753,7 +753,7 @@ H5S_hyper_iter_next(H5S_sel_iter_t *iter, size_t nelem)
/* Set the rank of the fastest changing dimension */
ndims=iter->rank;
- fast_dim=(ndims-1);
+ fast_dim = (int)ndims - 1;
/* Get the pointers to the current span info and span nodes */
abs_arr=iter->u.hyp.off;
@@ -892,7 +892,7 @@ H5S_hyper_iter_next_block(H5S_sel_iter_t *iter)
} /* end else */
/* Set the fastest dimension rank */
- fast_dim=ndims-1;
+ fast_dim = (int)ndims - 1;
/* Set the local copy of the diminfo pointer */
tdiminfo=iter->u.hyp.diminfo;
@@ -952,8 +952,8 @@ H5S_hyper_iter_next_block(H5S_sel_iter_t *iter)
int curr_dim; /* Temporary rank holder */
/* Set the rank of the fastest changing dimension */
- ndims=iter->rank;
- fast_dim=(ndims-1);
+ ndims = iter->rank;
+ fast_dim = (int)ndims - 1;
/* Get the pointers to the current span info and span nodes */
abs_arr=iter->u.hyp.off;
@@ -1246,7 +1246,7 @@ H5S_hyper_span_scratch (H5S_hyper_span_info_t *spans, void *scr_value)
/* Check if we've already set this down span tree */
if(spans->scratch!=scr_value) {
/* Set the tree's scratch pointer */
- spans->scratch=scr_value;
+ spans->scratch = (H5S_hyper_span_info_t *)scr_value;
/* Set the scratch pointers in all the nodes */
span=spans->head;
@@ -1543,7 +1543,7 @@ H5S_hyper_free_span_info (H5S_hyper_span_info_t *span_info)
} /* end while */
/* Free this span info */
- H5FL_FREE(H5S_hyper_span_info_t,span_info);
+ (void)H5FL_FREE(H5S_hyper_span_info_t, span_info);
} /* end if */
done:
@@ -1586,7 +1586,7 @@ H5S_hyper_free_span (H5S_hyper_span_t *span)
} /* end if */
/* Free this span */
- H5FL_FREE(H5S_hyper_span_t,span);
+ (void)H5FL_FREE(H5S_hyper_span_t, span);
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -1802,7 +1802,7 @@ done:
PURPOSE
Count the number of blocks in a span tree
USAGE
- hssize_t H5S_hyper_span_nblocks(spans)
+ hsize_t H5S_hyper_span_nblocks(spans)
const H5S_hyper_span_info_t *spans; IN: Hyperslab span tree to count elements of
RETURNS
Number of blocks in span tree on success; negative on failure
@@ -1813,34 +1813,31 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-static hssize_t
-H5S_hyper_span_nblocks (H5S_hyper_span_info_t *spans)
+static hsize_t
+H5S_hyper_span_nblocks(H5S_hyper_span_info_t *spans)
{
H5S_hyper_span_t *span; /* Hyperslab span */
- hssize_t ret_value;
+ hsize_t ret_value = 0; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_span_nblocks);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_span_nblocks)
/* Count the number of elements in the span tree */
- if(spans==NULL)
- ret_value=0;
- else {
- span=spans->head;
- ret_value=0;
- while(span!=NULL) {
+ if(spans != NULL) {
+ span = spans->head;
+ while(span != NULL) {
/* If there are down spans, add the total down span blocks */
if(span->down!=NULL)
- ret_value+=H5S_hyper_span_nblocks(span->down);
+ ret_value += H5S_hyper_span_nblocks(span->down);
/* If there are no down spans, just count the block in this span */
else
ret_value++;
/* Advance to next span */
- span=span->next;
+ span = span->next;
} /* end while */
} /* end else */
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_hyper_span_nblocks() */
@@ -1850,7 +1847,7 @@ H5S_hyper_span_nblocks (H5S_hyper_span_info_t *spans)
PURPOSE
Get the number of hyperslab blocks in current hyperslab selection
USAGE
- hssize_t H5S_get_select_hyper_nblocks(space)
+ hsize_t H5S_get_select_hyper_nblocks(space)
H5S_t *space; IN: Dataspace ptr of selection to query
RETURNS
The number of hyperslab blocks in selection on success, negative on failure
@@ -1861,26 +1858,27 @@ H5S_hyper_span_nblocks (H5S_hyper_span_info_t *spans)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-static hssize_t
+static hsize_t
H5S_get_select_hyper_nblocks(H5S_t *space)
{
- hssize_t ret_value; /* return value */
- unsigned u; /* Counter */
+ hsize_t ret_value; /* return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_get_select_hyper_nblocks);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_get_select_hyper_nblocks)
- assert(space);
+ HDassert(space);
/* Check for a "regular" hyperslab selection */
if(space->select.sel_info.hslab->diminfo_valid) {
+ unsigned u; /* Local index variable */
+
/* Check each dimension */
- for(ret_value=1,u=0; u<space->extent.rank; u++)
- ret_value*=space->select.sel_info.hslab->app_diminfo[u].count;
+ for(ret_value = 1, u = 0; u < space->extent.rank; u++)
+ ret_value *= space->select.sel_info.hslab->app_diminfo[u].count;
} /* end if */
else
ret_value = H5S_hyper_span_nblocks(space->select.sel_info.hslab->span_lst);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_get_select_hyper_nblocks() */
@@ -1904,22 +1902,22 @@ H5S_get_select_hyper_nblocks(H5S_t *space)
hssize_t
H5Sget_select_hyper_nblocks(hid_t spaceid)
{
- H5S_t *space = NULL; /* Dataspace to modify selection of */
- hssize_t ret_value; /* return value */
+ H5S_t *space; /* Dataspace to modify selection of */
+ hssize_t ret_value; /* return value */
- FUNC_ENTER_API(H5Sget_select_hyper_nblocks, FAIL);
+ FUNC_ENTER_API(H5Sget_select_hyper_nblocks, FAIL)
H5TRACE1("Hs", "i", spaceid);
/* Check args */
- if (NULL == (space=H5I_object_verify(spaceid, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
- if(H5S_GET_SELECT_TYPE(space)!=H5S_SEL_HYPERSLABS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a hyperslab selection");
+ if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ if(H5S_GET_SELECT_TYPE(space) != H5S_SEL_HYPERSLABS)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a hyperslab selection")
- ret_value = H5S_get_select_hyper_nblocks(space);
+ ret_value = (hssize_t)H5S_get_select_hyper_nblocks(space);
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* H5Sget_select_hyper_nblocks() */
@@ -1942,37 +1940,37 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-hssize_t
-H5S_hyper_serial_size (const H5S_t *space)
+static hssize_t
+H5S_hyper_serial_size(const H5S_t *space)
{
unsigned u; /* Counter */
- hssize_t block_count; /* block counter for regular hyperslabs */
+ hsize_t block_count; /* block counter for regular hyperslabs */
hssize_t ret_value; /* return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_hyper_serial_size);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_hyper_serial_size)
- assert(space);
+ HDassert(space);
/* Basic number of bytes required to serialize hyperslab selection:
* <type (4 bytes)> + <version (4 bytes)> + <padding (4 bytes)> +
* <length (4 bytes)> + <rank (4 bytes)> + <# of blocks (4 bytes)> = 24 bytes
*/
- ret_value=24;
+ ret_value = 24;
/* Check for a "regular" hyperslab selection */
if(space->select.sel_info.hslab->diminfo_valid) {
/* Check each dimension */
- for(block_count=1,u=0; u<space->extent.rank; u++)
- block_count*=space->select.sel_info.hslab->opt_diminfo[u].count;
- ret_value+=8*block_count*space->extent.rank;
+ for(block_count = 1, u = 0; u < space->extent.rank; u++)
+ block_count *= space->select.sel_info.hslab->opt_diminfo[u].count;
} /* end if */
- else {
+ else
/* Spin through hyperslab spans, adding 8 * rank bytes for each block */
- block_count=H5S_hyper_span_nblocks(space->select.sel_info.hslab->span_lst);
- ret_value+=8*space->extent.rank*block_count;
- } /* end else */
+ block_count = H5S_hyper_span_nblocks(space->select.sel_info.hslab->span_lst);
- FUNC_LEAVE_NOAPI(ret_value);
+ H5_CHECK_OVERFLOW((8 * space->extent.rank * block_count), hsize_t, hssize_t);
+ ret_value += (hssize_t)(8 * block_count * space->extent.rank);
+
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_hyper_serial_size() */
@@ -2083,50 +2081,51 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf)
hsize_t end[H5O_LAYOUT_NDIMS]; /* Location of end of hyperslab */
hsize_t temp_off; /* Offset in a given dimension */
uint8_t *lenp; /* pointer to length location for later storage */
- uint32_t len=0; /* number of bytes used */
- int i; /* local counting variable */
- hssize_t block_count; /* block counter for regular hyperslabs */
- int fast_dim; /* Rank of the fastest changing dimension for the dataspace */
- int temp_dim; /* Temporary rank holder */
- int ndims; /* Rank of the dataspace */
- int done; /* Whether we are done with the iteration */
+ uint32_t len = 0; /* number of bytes used */
+ hsize_t block_count; /* block counter for regular hyperslabs */
+ unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */
+ unsigned ndims; /* Rank of the dataspace */
+ int done; /* Whether we are done with the iteration */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_hyper_serialize);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_hyper_serialize)
- assert(space);
+ HDassert(space);
/* Store the preamble information */
UINT32ENCODE(buf, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */
UINT32ENCODE(buf, (uint32_t)1); /* Store the version number */
UINT32ENCODE(buf, (uint32_t)0); /* Store the un-used padding */
- lenp=buf; /* keep the pointer to the length location for later */
- buf+=4; /* skip over space for length */
+ lenp = buf; /* keep the pointer to the length location for later */
+ buf += 4; /* skip over space for length */
/* Encode number of dimensions */
UINT32ENCODE(buf, (uint32_t)space->extent.rank);
- len+=4;
+ len += 4;
/* Check for a "regular" hyperslab selection */
if(space->select.sel_info.hslab->diminfo_valid) {
+ unsigned u; /* Local counting variable */
+
/* Set some convienence values */
- ndims=space->extent.rank;
- fast_dim=ndims-1;
+ ndims = space->extent.rank;
+ fast_dim = ndims - 1;
diminfo=space->select.sel_info.hslab->opt_diminfo;
/* Check each dimension */
- for(block_count=1,i=0; i<ndims; i++)
- block_count*=diminfo[i].count;
+ for(block_count = 1, u = 0; u < ndims; u++)
+ block_count *= diminfo[u].count;
/* Encode number of hyperslabs */
+ H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t);
UINT32ENCODE(buf, (uint32_t)block_count);
len+=4;
/* Now serialize the information for the regular hyperslab */
/* Build the tables of count sizes as well as the initial offset */
- for(i=0; i<ndims; i++) {
- tmp_count[i]=diminfo[i].count;
- offset[i]=diminfo[i].start;
+ for(u = 0; u < ndims; u++) {
+ tmp_count[u] = diminfo[u].count;
+ offset[u] = diminfo[u].start;
} /* end for */
/* We're not done with the iteration */
@@ -2140,12 +2139,12 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf)
len+=8*ndims;
/* Encode hyperslab starting location */
- for(i=0; i<ndims; i++)
- UINT32ENCODE(buf, (uint32_t)offset[i]);
+ for(u = 0; u < ndims; u++)
+ UINT32ENCODE(buf, (uint32_t)offset[u]);
/* Encode hyperslab ending location */
- for(i=0; i<ndims; i++)
- UINT32ENCODE(buf, (uint32_t)(offset[i]+(diminfo[i].block-1)));
+ for(u = 0; u < ndims; u++)
+ UINT32ENCODE(buf, (uint32_t)(offset[u] + (diminfo[u].block - 1)));
/* Move the offset to the next sequence to start */
offset[fast_dim]+=diminfo[fast_dim].stride;
@@ -2155,26 +2154,28 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf)
} /* end while */
/* Work on other dimensions if necessary */
- if(fast_dim>0) {
+ if(fast_dim > 0) {
+ int temp_dim; /* Temporary rank holder */
+
/* Reset the block counts */
tmp_count[fast_dim]=diminfo[fast_dim].count;
/* Bubble up the decrement to the slower changing dimensions */
- temp_dim=fast_dim-1;
- while(temp_dim>=0 && done==0) {
+ temp_dim = (int)fast_dim - 1;
+ while(temp_dim >= 0 && done == 0) {
/* Decrement the block count */
tmp_count[temp_dim]--;
/* Check if we have more blocks left */
- if(tmp_count[temp_dim]>0)
+ if(tmp_count[temp_dim] > 0)
break;
/* Check for getting out of iterator */
- if(temp_dim==0)
- done=1;
+ if(temp_dim == 0)
+ done = 1;
/* Reset the block count in this dimension */
- tmp_count[temp_dim]=diminfo[temp_dim].count;
+ tmp_count[temp_dim] = diminfo[temp_dim].count;
/* Wrapped a dimension, go up to next dimension */
temp_dim--;
@@ -2184,32 +2185,31 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf)
break; /* Break out now, for 1-D selections */
/* Re-compute offset array */
- for(i=0; i<ndims; i++) {
- temp_off=diminfo[i].start
- +diminfo[i].stride*(diminfo[i].count-tmp_count[i]);
- offset[i]=temp_off;
+ for(u = 0; u < ndims; u++) {
+ temp_off = diminfo[u].start + diminfo[u].stride * (diminfo[u].count - tmp_count[u]);
+ offset[u] = temp_off;
} /* end for */
} /* end while */
} /* end if */
else {
/* Encode number of hyperslabs */
- block_count=H5S_hyper_span_nblocks(space->select.sel_info.hslab->span_lst);
+ block_count = H5S_hyper_span_nblocks(space->select.sel_info.hslab->span_lst);
+ H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t);
UINT32ENCODE(buf, (uint32_t)block_count);
len+=4;
/* Add 8 bytes times the rank for each hyperslab selected */
- H5_CHECK_OVERFLOW(block_count,hssize_t,hsize_t);
- H5_CHECK_OVERFLOW((8*space->extent.rank*(hsize_t)block_count),hsize_t,size_t);
- len+=(size_t)(8*space->extent.rank*block_count);
+ H5_CHECK_OVERFLOW((8 * space->extent.rank * block_count), hsize_t, size_t);
+ len += (size_t)(8 * space->extent.rank * block_count);
/* Encode each hyperslab in selection */
- H5S_hyper_serialize_helper(space->select.sel_info.hslab->span_lst,start,end,(hsize_t)0,&buf);
+ H5S_hyper_serialize_helper(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, &buf);
} /* end else */
/* Encode length */
UINT32ENCODE(lenp, (uint32_t)len); /* Store the length of the extra information */
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5S_hyper_serialize() */
@@ -2582,28 +2582,28 @@ herr_t
H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock,
hsize_t numblocks, hsize_t buf[/*numblocks*/])
{
- H5S_t *space = NULL; /* Dataspace to modify selection of */
- herr_t ret_value; /* return value */
+ H5S_t *space; /* Dataspace to modify selection of */
+ herr_t ret_value; /* return value */
- FUNC_ENTER_API(H5Sget_select_hyper_blocklist, FAIL);
+ FUNC_ENTER_API(H5Sget_select_hyper_blocklist, FAIL)
H5TRACE4("e", "ihh*[a2]h", spaceid, startblock, numblocks, buf);
/* Check args */
- if(buf==NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer");
- if (NULL == (space=H5I_object_verify(spaceid, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+ if(buf == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer")
+ if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
if(H5S_GET_SELECT_TYPE(space)!=H5S_SEL_HYPERSLABS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a hyperslab selection");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a hyperslab selection")
/* Go get the correct number of blocks */
- if(numblocks>0)
- ret_value = H5S_get_select_hyper_blocklist(space,0,startblock,numblocks,buf);
+ if(numblocks > 0)
+ ret_value = H5S_get_select_hyper_blocklist(space, 0, startblock, numblocks, buf);
else
ret_value=SUCCEED; /* Successfully got 0 blocks... */
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* H5Sget_select_hyper_blocklist() */
@@ -3193,7 +3193,7 @@ H5S_hyper_release (H5S_t *space)
} /* end if */
/* Release space for the hyperslab selection information */
- H5FL_FREE(H5S_hyper_sel_t,space->select.sel_info.hslab);
+ (void)H5FL_FREE(H5S_hyper_sel_t, space->select.sel_info.hslab);
space->select.sel_info.hslab=NULL;
done:
@@ -3531,58 +3531,58 @@ done:
herr_t
H5S_hyper_add_span_element(H5S_t *space, unsigned rank, hsize_t *coords)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_add_span_element);
+ FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_add_span_element)
- assert(space);
- assert(rank>0);
- assert(coords);
+ HDassert(space);
+ HDassert(rank > 0);
+ HDassert(coords);
/* Check if this is the first element in the selection */
- if(space->select.sel_info.hslab==NULL) {
+ if(NULL == space->select.sel_info.hslab) {
H5S_hyper_span_info_t *head; /* Pointer to new head of span tree */
/* Allocate a span info node */
- if((head = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span");
+ if(NULL == (head = H5FL_MALLOC(H5S_hyper_span_info_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Set the reference count */
- head->count=1;
+ head->count = 1;
/* Reset the scratch pad space */
- head->scratch=0;
+ head->scratch = 0;
/* Build span tree for this coordinate */
- if((head->head=H5S_hyper_coord_to_span(rank,coords))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span");
+ if(NULL == (head->head = H5S_hyper_coord_to_span(rank, coords)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Allocate selection info */
- if((space->select.sel_info.hslab=H5FL_MALLOC(H5S_hyper_sel_t))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info");
+ if(NULL == (space->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info")
/* Set the selection to the new span tree */
- space->select.sel_info.hslab->span_lst=head;
+ space->select.sel_info.hslab->span_lst = head;
/* Set selection type */
- space->select.type=H5S_sel_hyper;
+ space->select.type = H5S_sel_hyper;
/* Reset "regular" hyperslab flag */
- space->select.sel_info.hslab->diminfo_valid=FALSE;
+ space->select.sel_info.hslab->diminfo_valid = FALSE;
/* Set # of elements in selection */
- space->select.num_elem=1;
+ space->select.num_elem = 1;
} /* end if */
else {
- if(H5S_hyper_add_span_element_helper(space->select.sel_info.hslab->span_lst,rank,coords)<0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span");
+ if(H5S_hyper_add_span_element_helper(space->select.sel_info.hslab->span_lst,rank,coords) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Increment # of elements in selection */
space->select.num_elem++;
} /* end else */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_hyper_add_span_element() */
@@ -4382,13 +4382,13 @@ done:
static herr_t
H5S_hyper_append_span (H5S_hyper_span_t **prev_span, H5S_hyper_span_info_t ** span_tree, hsize_t low, hsize_t high, H5S_hyper_span_info_t *down, H5S_hyper_span_t *next)
{
- H5S_hyper_span_t *new_span;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5S_hyper_span_t *new_span = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_append_span);
- assert(prev_span);
- assert(span_tree);
+ HDassert(prev_span);
+ HDassert(span_tree);
/* Check for adding first node to merged spans */
if(*prev_span==NULL) {
@@ -4452,7 +4452,13 @@ H5S_hyper_append_span (H5S_hyper_span_t **prev_span, H5S_hyper_span_info_t ** sp
} /* end else */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ if(ret_value < 0) {
+ if(new_span)
+ if(H5S_hyper_free_span(new_span) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "failed to release new hyperslab span")
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_hyper_append_span() */
@@ -5264,9 +5270,15 @@ H5S_hyper_merge_spans_helper (H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf
} /* end else */
/* Set return value */
- ret_value=merged_spans;
+ ret_value = merged_spans;
done:
+ if(ret_value == NULL) {
+ if(merged_spans)
+ if(H5S_hyper_free_span_info(merged_spans) < 0)
+ HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, NULL, "failed to release merged hyperslab spans")
+ } /* end if */
+
FUNC_LEAVE_NOAPI(ret_value);
} /* H5S_hyper_merge_spans_helper() */
@@ -5929,14 +5941,6 @@ H5S_generate_hyperslab (H5S_t *space, H5S_seloper_t op,
HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation");
} /* end switch */
- /* Free the hyperslab trees generated from the clipping algorithm */
- if(a_not_b)
- H5S_hyper_free_span_info(a_not_b);
- if(a_and_b)
- H5S_hyper_free_span_info(a_and_b);
- if(b_not_a)
- H5S_hyper_free_span_info(b_not_a);
-
/* Check if the resulting hyperslab span tree is empty */
if(space->select.sel_info.hslab->span_lst==NULL) {
H5S_hyper_span_info_t *spans; /* Empty hyperslab span tree */
@@ -5973,10 +5977,19 @@ H5S_generate_hyperslab (H5S_t *space, H5S_seloper_t op,
} /* end else */
done:
- /* Free the new spans */
- if(new_spans!=NULL)
- if(H5S_hyper_free_span_info(new_spans)<0)
- HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans");
+ /* Free resources */
+ if(a_not_b)
+ if(H5S_hyper_free_span_info(a_not_b) < 0)
+ HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans")
+ if(a_and_b)
+ if(H5S_hyper_free_span_info(a_and_b) < 0)
+ HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans")
+ if(b_not_a)
+ if(H5S_hyper_free_span_info(b_not_a) < 0)
+ HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans")
+ if(new_spans)
+ if(H5S_hyper_free_span_info(new_spans) < 0)
+ HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans")
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5S_generate_hyperslab() */
@@ -6264,24 +6277,24 @@ herr_t
H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t start[],
const hsize_t stride[], const hsize_t count[], const hsize_t block[])
{
- H5S_t *space = NULL; /* Dataspace to modify selection of */
+ H5S_t *space; /* Dataspace to modify selection of */
unsigned u; /* Local index variable */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Sselect_hyperslab, FAIL);
H5TRACE6("e", "iSs*h*h*h*h", space_id, op, start, stride, count, block);
/* Check args */
- if (NULL == (space=H5I_object_verify(space_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
- if (H5S_SCALAR==H5S_GET_EXTENT_TYPE(space))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hyperslab doesn't support H5S_SCALAR space");
- if (H5S_NULL==H5S_GET_EXTENT_TYPE(space))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hyperslab doesn't support H5S_NULL space");
- if(start==NULL || count==NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab not specified");
- if(!(op>H5S_SELECT_NOOP && op<H5S_SELECT_INVALID))
- HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation");
+ if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ if(H5S_SCALAR == H5S_GET_EXTENT_TYPE(space))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hyperslab doesn't support H5S_SCALAR space")
+ if(H5S_NULL == H5S_GET_EXTENT_TYPE(space))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hyperslab doesn't support H5S_NULL space")
+ if(start == NULL || count == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab not specified")
+ if(!(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID))
+ HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
if(stride!=NULL) {
/* Check for 0-sized strides */
for(u=0; u<space->extent.rank; u++) {
@@ -6953,7 +6966,7 @@ H5Scombine_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t start[],
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set hyperslab selection");
/* Atomize */
- if ((ret_value=H5I_register (H5I_DATASPACE, new_space))<0)
+ if ((ret_value=H5I_register (H5I_DATASPACE, new_space, TRUE))<0)
HGOTO_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom");
done:
@@ -7081,7 +7094,7 @@ H5Scombine_select(hid_t space1_id, H5S_seloper_t op, hid_t space2_id)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to create hyperslab selection");
/* Atomize */
- if ((ret_value=H5I_register (H5I_DATASPACE, new_space))<0)
+ if ((ret_value=H5I_register (H5I_DATASPACE, new_space, TRUE))<0)
HGOTO_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom");
done:
diff --git a/src/H5Smpio.c b/src/H5Smpio.c
index 725b8fc..72d61e6 100644
--- a/src/H5Smpio.c
+++ b/src/H5Smpio.c
@@ -107,17 +107,17 @@ H5S_mpio_all_type( const H5S_t *space, size_t elmt_size,
hsize_t nelmts; /*total number of elmts */
herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_all_type);
+ FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_all_type)
/* Check args */
- assert (space);
+ HDassert(space);
/* Just treat the entire extent as a block of bytes */
- if((snelmts = H5S_GET_EXTENT_NPOINTS(space))<0)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection")
- H5_ASSIGN_OVERFLOW(nelmts,snelmts,hssize_t,hsize_t);
+ if((snelmts = H5S_GET_EXTENT_NPOINTS(space)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection")
+ H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, hsize_t);
- total_bytes = (hsize_t)elmt_size*nelmts;
+ total_bytes = (hsize_t)elmt_size * nelmts;
/* fill in the return values */
*new_type = MPI_BYTE;
@@ -126,7 +126,7 @@ H5S_mpio_all_type( const H5S_t *space, size_t elmt_size,
*is_derived_type = FALSE;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_mpio_all_type() */
@@ -210,7 +210,7 @@ H5S_mpio_hyper_type( const H5S_t *space, size_t elmt_size,
hbool_t *is_derived_type )
{
H5S_sel_iter_t sel_iter; /* Selection iteration info */
- hbool_t sel_iter_init=0; /* Selection iteration info has been initialized */
+ hbool_t sel_iter_init = FALSE; /* Selection iteration info has been initialized */
struct dim { /* less hassle than malloc/free & ilk */
hssize_t start;
@@ -234,27 +234,27 @@ H5S_mpio_hyper_type( const H5S_t *space, size_t elmt_size,
FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_hyper_type);
/* Check args */
- assert (space);
- assert(sizeof(MPI_Aint) >= sizeof(elmt_size));
- if (0==elmt_size)
+ HDassert(space);
+ HDassert(sizeof(MPI_Aint) >= sizeof(elmt_size));
+ if(0 == elmt_size)
goto empty;
/* Initialize selection iterator */
- if (H5S_select_iter_init(&sel_iter, space, elmt_size)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
- sel_iter_init=1; /* Selection iteration info has been initialized */
+ if(H5S_select_iter_init(&sel_iter, space, elmt_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
+ sel_iter_init = 1; /* Selection iteration info has been initialized */
/* Abbreviate args */
- diminfo=sel_iter.u.hyp.diminfo;
- assert (diminfo);
+ diminfo = sel_iter.u.hyp.diminfo;
+ HDassert(diminfo);
/* make a local copy of the dimension info so we can operate with them */
/* Check if this is a "flattened" regular hyperslab selection */
if(sel_iter.u.hyp.iter_rank!=0 && sel_iter.u.hyp.iter_rank<space->extent.rank) {
/* Flattened selection */
- rank=sel_iter.u.hyp.iter_rank;
- assert (rank >= 0 && rank<=H5S_MAX_RANK); /* within array bounds */
+ rank = sel_iter.u.hyp.iter_rank;
+ HDassert(rank >= 0 && rank <= H5S_MAX_RANK); /* within array bounds */
if (0==rank)
goto empty;
#ifdef H5S_DEBUG
@@ -288,12 +288,12 @@ H5S_mpio_hyper_type( const H5S_t *space, size_t elmt_size,
else {
/* Non-flattened selection */
rank = space->extent.rank;
- assert (rank >= 0 && rank<=H5S_MAX_RANK); /* within array bounds */
+ HDassert(rank >= 0 && rank<=H5S_MAX_RANK); /* within array bounds */
if (0==rank)
goto empty;
#ifdef H5S_DEBUG
if(H5DEBUG(S))
- HDfprintf(H5DEBUG(S),"%s: Non-flattened selection\n",FUNC);
+ HDfprintf(H5DEBUG(S),"%s: Non-flattened selection\n",FUNC);
#endif
for ( i=0; i<rank; ++i) {
d[i].start = diminfo[i].start+space->select.offset[i];
@@ -509,47 +509,39 @@ H5S_mpio_span_hyper_type( const H5S_t *space,
MPI_Datatype *new_type,/* out: */
size_t *count,
hsize_t *extra_offset,
- hbool_t *is_derived_type ){
-
- MPI_Datatype span_type;
- H5S_hyper_span_t *ospan;
- H5S_hyper_span_info_t *odown;
- hsize_t *size;
- int rank;
- int mpi_code;
- herr_t ret_value = SUCCEED;
- MPI_Aint extent,lb;
-
-
- FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_span_hyper_type);
-
- /* Check args */
- assert (space);
+ hbool_t *is_derived_type )
+{
- /* assert(sizeof(MPI_Aint) >= sizeof(elmt_size)); not sure the reason*/
+ MPI_Datatype span_type;
+ H5S_hyper_span_t *ospan;
+ H5S_hyper_span_info_t *odown;
+ hsize_t *size;
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
+ FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_span_hyper_type)
- rank = space->extent.rank;
+ /* Check args */
+ HDassert(space);
- /* size = HDcalloc((size_t)rank,sizeof(hsize_t)); */
- if (0==elmt_size)
+ if(0 == elmt_size)
goto empty;
size = space->extent.size;
- if(size == 0)
+ if(0 == size)
goto empty;
odown = space->select.sel_info.hslab->span_lst;
- if(odown == NULL)
- goto empty;
+ if(NULL == odown)
+ goto empty;
ospan = odown->head;
- if(ospan == NULL)
- goto empty;
+ if(NULL == ospan)
+ goto empty;
/* obtain derived data type */
- if(FAIL == H5S_obtain_datatype(space->extent.size,ospan,&span_type,elmt_size,rank))
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't obtain MPI derived data type");
+ if(FAIL == H5S_obtain_datatype(space->extent.size, ospan, &span_type, elmt_size, space->extent.rank))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't obtain MPI derived data type")
- if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(&span_type)))
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&span_type)))
HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
*new_type = span_type;
@@ -558,7 +550,7 @@ H5S_mpio_span_hyper_type( const H5S_t *space,
*extra_offset = 0;
*is_derived_type = TRUE;
- HGOTO_DONE(SUCCEED);
+ HGOTO_DONE(SUCCEED)
empty:
/* special case: empty hyperslab */
@@ -568,8 +560,8 @@ empty:
*is_derived_type = FALSE;
done:
- FUNC_LEAVE_NOAPI(ret_value);
- }
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_mpio_span_hyper_type() */
/*-------------------------------------------------------------------------
@@ -585,173 +577,162 @@ done:
* Programmer: kyang
*
*/
-static herr_t H5S_obtain_datatype(const hsize_t size[],
+static herr_t
+H5S_obtain_datatype(const hsize_t size[],
H5S_hyper_span_t* span,
MPI_Datatype *span_type,
size_t elmt_size,
int dimindex)
{
-
- int innercount,outercount;
- MPI_Datatype bas_type;
- MPI_Datatype temp_type;
- MPI_Datatype tempinner_type;
- MPI_Datatype *inner_type;
- int *blocklen;
- MPI_Aint *disp;
- MPI_Aint stride;
- MPI_Aint extent,lb;
- H5S_hyper_span_info_t *down;
- H5S_hyper_span_t *tspan;
- int mpi_code;
- herr_t ret_value = SUCCEED;
-
+ int innercount, outercount;
+ MPI_Datatype bas_type;
+ MPI_Datatype temp_type;
+ MPI_Datatype tempinner_type;
+ MPI_Datatype *inner_type;
+ int *blocklen;
+ MPI_Aint *disp;
+ MPI_Aint stride;
+ H5S_hyper_span_info_t *down;
+ H5S_hyper_span_t *tspan;
#ifdef H5_HAVE_MPI2
- MPI_Aint sizeaint,sizedtype;
+ MPI_Aint sizeaint, sizedtype;
#endif /* H5_HAVE_MPI2 */
- hsize_t total_lowd,total_lowd1;
- int i;
- int ret;
-
- FUNC_ENTER_NOAPI_NOINIT(H5S_obtain_datatype);
- assert(span);
-
- inner_type = NULL;
- down = NULL;
- tspan = NULL;
- down = span->down;
- tspan = span;
-
- outercount = 0;
-
-/* obtain the number of span tree for this dimension */
- while(tspan) {
- tspan = tspan->next;
- outercount ++;
- }
-
- if(outercount == 0) {
- span_type = NULL;
- return 0;
- }
+ hsize_t total_lowd, total_lowd1;
+ int i;
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5S_obtain_datatype)
+
+ HDassert(span);
+
+ inner_type = NULL;
+ down = NULL;
+ tspan = NULL;
+ down = span->down;
+ tspan = span;
+
+ /* obtain the number of span tree for this dimension */
+ outercount = 0;
+ while(tspan) {
+ tspan = tspan->next;
+ outercount++;
+ } /* end while */
+ if(outercount == 0)
+ HGOTO_DONE(SUCCEED)
/* MPI2 hasn't been widely acccepted, adding H5_HAVE_MPI2 for the future use */
#ifdef H5_HAVE_MPI2
- MPI_Type_extent(MPI_Aint,&sizeaint);
- MPI_Type_extent(MPI_Datatype,&sizedtype);
+ MPI_Type_extent(MPI_Aint, &sizeaint);
+ MPI_Type_extent(MPI_Datatype, &sizedtype);
- blocklen = (int *)HDcalloc((size_t)outercount,sizeof(int));
- disp = (MPI_Aint *)HDcalloc((size_t)outercount,sizeaint);
- inner_type = (MPI_Datatype *)HDcalloc((size_t)outercount,sizedtype);
+ blocklen = (int *)HDcalloc((size_t)outercount, sizeof(int));
+ disp = (MPI_Aint *)HDcalloc((size_t)outercount, sizeaint);
+ inner_type = (MPI_Datatype *)HDcalloc((size_t)outercount, sizedtype);
#else
- blocklen = (int *)HDcalloc((size_t)outercount,sizeof(int));
- disp = (MPI_Aint *)HDcalloc((size_t)outercount,sizeof(MPI_Aint));
- inner_type = (MPI_Datatype *)HDcalloc((size_t)outercount,sizeof(MPI_Datatype));
+ blocklen = (int *)HDcalloc((size_t)outercount, sizeof(int));
+ disp = (MPI_Aint *)HDcalloc((size_t)outercount, sizeof(MPI_Aint));
+ inner_type = (MPI_Datatype *)HDcalloc((size_t)outercount, sizeof(MPI_Datatype));
#endif
- tspan = span;
- outercount = 0;
+ tspan = span;
+ outercount = 0;
- /* if this is the fastest changing dimension, it is the base case for derived datatype. */
- if(down == NULL){
+ /* if this is the fastest changing dimension, it is the base case for derived datatype. */
+ if(down == NULL){
- assert(dimindex <= 1);
- if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE,&bas_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code);
+ HDassert(dimindex <= 1);
- if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&bas_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE,&bas_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code);
- while(tspan){
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&bas_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
- disp[outercount] = (MPI_Aint)elmt_size * tspan->low;
- blocklen[outercount] = tspan->nelem;
- tspan = tspan->next;
- outercount ++;
- }
+ while(tspan) {
+ disp[outercount] = (MPI_Aint)elmt_size * tspan->low;
+ blocklen[outercount] = tspan->nelem;
+ tspan = tspan->next;
+ outercount++;
+ } /* end while */
- if(MPI_SUCCESS != (mpi_code = MPI_Type_hindexed(outercount,blocklen,
- disp,bas_type,span_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_hindexed failed", mpi_code);
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_hindexed(outercount, blocklen, disp, bas_type, span_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_hindexed failed", mpi_code);
+ } /* end if */
+ else {/* dimindex is the rank of the dimension */
- }
- else {/* dimindex is the rank of the dimension */
+ HDassert(dimindex > 1);
- assert(dimindex >1);
- /* Calculate the total bytes of the lower dimension */
- total_lowd = 1; /* one dimension down */
- total_lowd1 = 1; /* two dimensions down */
+ /* Calculate the total bytes of the lower dimension */
+ total_lowd = 1; /* one dimension down */
+ total_lowd1 = 1; /* two dimensions down */
- for ( i = dimindex-1; i > 0; i--)
- total_lowd = total_lowd * size[i];
+ for ( i = dimindex-1; i > 0; i--)
+ total_lowd = total_lowd * size[i];
- for ( i = dimindex-1; i > 1; i--)
- total_lowd1 = total_lowd1 * size[i];
+ for ( i = dimindex-1; i > 1; i--)
+ total_lowd1 = total_lowd1 * size[i];
- while(tspan){
+ while(tspan) {
- /* Displacement should be in byte and should have dimension information */
- /* First using MPI Type vector to build derived data type for this span only */
- /* Need to calculate the disp in byte for this dimension. */
- /* Calculate the total bytes of the lower dimension */
+ /* Displacement should be in byte and should have dimension information */
+ /* First using MPI Type vector to build derived data type for this span only */
+ /* Need to calculate the disp in byte for this dimension. */
+ /* Calculate the total bytes of the lower dimension */
- disp[outercount] = tspan->low*total_lowd*elmt_size;
- blocklen[outercount] = 1;
+ disp[outercount] = tspan->low*total_lowd*elmt_size;
+ blocklen[outercount] = 1;
- /* generating inner derived datatype by using MPI_Type_hvector */
- if(FAIL == H5S_obtain_datatype(size,tspan->down->head,&temp_type,elmt_size,dimindex-1))
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't obtain MPI derived data type");
+ /* generating inner derived datatype by using MPI_Type_hvector */
+ if(FAIL == H5S_obtain_datatype(size,tspan->down->head,&temp_type,elmt_size,dimindex-1))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't obtain MPI derived data type")
- if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&temp_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&temp_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
- /* building the inner vector datatype */
- stride = total_lowd*elmt_size;
- innercount = tspan->nelem;
+ /* building the inner vector datatype */
+ stride = total_lowd*elmt_size;
+ innercount = tspan->nelem;
- if(MPI_SUCCESS != (mpi_code = MPI_Type_hvector(innercount,1,stride,temp_type,&tempinner_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_hvector failed", mpi_code);
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_hvector(innercount,1,stride,temp_type,&tempinner_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_hvector failed", mpi_code);
- if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&tempinner_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&tempinner_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
- if(MPI_SUCCESS != (mpi_code =MPI_Type_free(&temp_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed",mpi_code);
- inner_type[outercount] = tempinner_type;
- outercount ++;
- tspan = tspan->next;
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&temp_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code);
- }
+ inner_type[outercount] = tempinner_type;
+ outercount ++;
+ tspan = tspan->next;
+ } /* end while */
- /* building the whole vector datatype */
- if(MPI_SUCCESS != (mpi_code =
- MPI_Type_struct(outercount,blocklen,disp,inner_type,span_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_struct failed", mpi_code);
-
- }
+ /* building the whole vector datatype */
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_struct(outercount, blocklen, disp, inner_type, span_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_struct failed", mpi_code);
+ } /* end else */
- if(inner_type != NULL){
- if(down != NULL) {
- for(i=0;i<outercount;i++)
- if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&inner_type[i])))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed",mpi_code);
- }
- }
+ if(inner_type != NULL && down != NULL) {
+ for(i = 0; i < outercount; i++)
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&inner_type[i])))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code);
+ } /* end if */
- if(inner_type != NULL)
- HDfree(inner_type);
- if(blocklen != NULL)
- HDfree(blocklen);
- if(disp != NULL)
- HDfree(disp);
+ if(inner_type != NULL)
+ HDfree(inner_type);
+ if(blocklen != NULL)
+ HDfree(blocklen);
+ if(disp != NULL)
+ HDfree(disp);
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_obtain_datatype() */
@@ -791,7 +772,7 @@ H5S_mpio_space_type( const H5S_t *space, size_t elmt_size,
FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_space_type);
/* Check args */
- assert (space);
+ HDassert(space);
/* Creat MPI type based on the kind of selection */
switch (H5S_GET_EXTENT_TYPE(space)) {
@@ -830,13 +811,13 @@ H5S_mpio_space_type( const H5S_t *space, size_t elmt_size,
break;
default:
- assert("unknown selection type" && 0);
+ HDassert("unknown selection type" && 0);
break;
} /* end switch */
break;
default:
- assert("unknown data space type" && 0);
+ HDassert("unknown data space type" && 0);
break;
}
@@ -845,3 +826,4 @@ done:
}
#endif /* H5_HAVE_PARALLEL */
+
diff --git a/src/H5Snone.c b/src/H5Snone.c
index 8ed3c0a..c6e8a6a 100644
--- a/src/H5Snone.c
+++ b/src/H5Snone.c
@@ -288,12 +288,12 @@ H5S_none_iter_next(H5S_sel_iter_t UNUSED *iter, size_t UNUSED nelem)
static herr_t
H5S_none_iter_next_block(H5S_sel_iter_t UNUSED *iter)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_iter_next);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_iter_next)
/* Check args */
- assert (iter);
+ HDassert(iter);
- FUNC_LEAVE_NOAPI(FAIL);
+ FUNC_LEAVE_NOAPI(FAIL)
} /* H5S_none_iter_next_block() */
@@ -778,17 +778,18 @@ done:
herr_t
H5Sselect_none(hid_t spaceid)
{
- H5S_t *space; /* Dataspace to modify selection of */
- herr_t ret_value; /* return value */
+ H5S_t *space; /* Dataspace to modify selection of */
+ herr_t ret_value = SUCCEED; /* return value */
FUNC_ENTER_API(H5Sselect_none, FAIL)
+ H5TRACE1("e", "i", spaceid);
/* Check args */
if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
/* Change to "none" selection */
- if((ret_value = H5S_select_none(space)) < 0)
+ if(H5S_select_none(space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
done:
diff --git a/src/H5Spkg.h b/src/H5Spkg.h
index e13e6be..b7818a2 100644
--- a/src/H5Spkg.h
+++ b/src/H5Spkg.h
@@ -44,7 +44,7 @@
*/
#define H5O_SDSPACE_VERSION_2 2
-/* The latest version of the format. Look through the 'encode'
+/* The latest version of the format. Look through the 'encode'
* and 'size' callbacks for places to change when updating this. */
#define H5O_SDSPACE_VERSION_LATEST H5O_SDSPACE_VERSION_2
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index cf7751e..84b427e 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -401,7 +401,7 @@ H5S_point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *co
if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node")
- if(NULL == (new_node->pnt = H5MM_malloc(space->extent.rank * sizeof(hsize_t))))
+ if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(space->extent.rank * sizeof(hsize_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate coordinate information")
/* Copy over the coordinates */
@@ -481,12 +481,12 @@ H5S_point_release (H5S_t *space)
while(curr!=NULL) {
next=curr->next;
H5MM_xfree(curr->pnt);
- H5FL_FREE(H5S_pnt_node_t,curr);
+ (void)H5FL_FREE(H5S_pnt_node_t, curr);
curr=next;
} /* end while */
/* Free & reset the point list header */
- H5FL_FREE(H5S_pnt_list_t,space->select.sel_info.pnt_lst);
+ (void)H5FL_FREE(H5S_pnt_list_t, space->select.sel_info.pnt_lst);
space->select.sel_info.pnt_lst=NULL;
/* Reset the number of elements in the selection */
@@ -600,12 +600,12 @@ H5S_point_copy(H5S_t *dst, const H5S_t *src, hbool_t UNUSED share_selection)
new_head=NULL;
while(curr!=NULL) {
/* Create each point */
- if((new_node=H5FL_MALLOC(H5S_pnt_node_t))==NULL)
+ if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node");
- if((new_node->pnt = H5MM_malloc(src->extent.rank*sizeof(hsize_t)))==NULL)
+ if((new_node->pnt = (hsize_t *)H5MM_malloc(src->extent.rank*sizeof(hsize_t)))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate coordinate information");
- HDmemcpy(new_node->pnt,curr->pnt,(src->extent.rank*sizeof(hsize_t)));
- new_node->next=NULL;
+ HDmemcpy(new_node->pnt, curr->pnt, (src->extent.rank * sizeof(hsize_t)));
+ new_node->next = NULL;
/* Keep the order the same when copying */
if(new_head==NULL)
@@ -655,18 +655,18 @@ H5S_point_is_valid (const H5S_t *space)
assert(space);
/* Check each point to determine whether selection+offset is within extent */
- curr=space->select.sel_info.pnt_lst->head;
- while(curr!=NULL) {
+ curr = space->select.sel_info.pnt_lst->head;
+ while(curr != NULL) {
/* Check each dimension */
- for(u=0; u<space->extent.rank; u++) {
+ for(u = 0; u < space->extent.rank; u++) {
/* Check if an offset has been defined */
/* Bounds check the selected point + offset against the extent */
- if(((curr->pnt[u]+space->select.offset[u])>space->extent.size[u])
- || (((hssize_t)curr->pnt[u]+space->select.offset[u])<0))
+ if(((curr->pnt[u] + (hsize_t)space->select.offset[u]) > space->extent.size[u])
+ || (((hssize_t)curr->pnt[u] + space->select.offset[u]) < 0))
HGOTO_DONE(FALSE)
} /* end for */
- curr=curr->next;
+ curr = curr->next;
} /* end while */
done:
@@ -694,22 +694,22 @@ done:
hssize_t
H5Sget_select_elem_npoints(hid_t spaceid)
{
- H5S_t *space = NULL; /* Dataspace to modify selection of */
- hssize_t ret_value; /* return value */
+ H5S_t *space; /* Dataspace to modify selection of */
+ hssize_t ret_value; /* return value */
- FUNC_ENTER_API(H5Sget_select_elem_npoints, FAIL);
+ FUNC_ENTER_API(H5Sget_select_elem_npoints, FAIL)
H5TRACE1("Hs", "i", spaceid);
/* Check args */
- if (NULL == (space=H5I_object_verify(spaceid, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
- if(H5S_GET_SELECT_TYPE(space)!=H5S_SEL_POINTS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an element selection");
+ if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ if(H5S_GET_SELECT_TYPE(space) != H5S_SEL_POINTS)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an element selection")
- ret_value = H5S_GET_SELECT_NPOINTS(space);
+ ret_value = (hssize_t)H5S_GET_SELECT_NPOINTS(space);
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* H5Sget_select_elem_npoints() */
@@ -852,41 +852,41 @@ H5S_point_deserialize (H5S_t *space, const uint8_t *buf)
uint32_t rank; /* Rank of points */
size_t num_elem=0; /* Number of elements in selection */
hsize_t *coord=NULL, *tcoord; /* Pointer to array of elements */
- unsigned i,j; /* local counting variables */
- herr_t ret_value; /* return value */
+ unsigned i, j; /* local counting variables */
+ herr_t ret_value = SUCCEED; /* return value */
- FUNC_ENTER_NOAPI_NOINIT(H5S_point_deserialize);
+ FUNC_ENTER_NOAPI_NOINIT(H5S_point_deserialize)
/* Check args */
- assert(space);
- assert(buf);
+ HDassert(space);
+ HDassert(buf);
/* Deserialize points to select */
- buf+=16; /* Skip over selection header */
- UINT32DECODE(buf,rank); /* decode the rank of the point selection */
- if(rank!=space->extent.rank)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "rank of pointer does not match dataspace");
- UINT32DECODE(buf,num_elem); /* decode the number of points */
+ buf += 16; /* Skip over selection header */
+ UINT32DECODE(buf, rank); /* decode the rank of the point selection */
+ if(rank != space->extent.rank)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "rank of pointer does not match dataspace")
+ UINT32DECODE(buf, num_elem); /* decode the number of points */
/* Allocate space for the coordinates */
- if((coord = H5MM_malloc(num_elem*rank*sizeof(hsize_t)))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate coordinate information");
+ if(NULL == (coord = (hsize_t *)H5MM_malloc(num_elem * rank * sizeof(hsize_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate coordinate information")
/* Retrieve the coordinates from the buffer */
- for(tcoord=coord,i=0; i<num_elem; i++)
- for(j=0; j<(unsigned)rank; j++,tcoord++)
+ for(tcoord = coord, i = 0; i < num_elem; i++)
+ for(j = 0; j < (unsigned)rank; j++, tcoord++)
UINT32DECODE(buf, *tcoord);
/* Select points */
- if((ret_value=H5S_select_elements(space,op,num_elem,(const hsize_t **)coord))<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection");
+ if(H5S_select_elements(space, op, num_elem, (const hsize_t *)coord) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
done:
/* Free the coordinate array if necessary */
- if(coord!=NULL)
+ if(coord != NULL)
H5MM_xfree(coord);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_point_deserialize() */
@@ -923,34 +923,34 @@ static herr_t
H5S_get_select_elem_pointlist(H5S_t *space, hsize_t startpoint, hsize_t numpoints, hsize_t *buf)
{
H5S_pnt_node_t *node; /* Point node */
- int rank; /* Dataspace rank */
+ unsigned rank; /* Dataspace rank */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_get_select_elem_pointlist);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_get_select_elem_pointlist)
- assert(space);
- assert(buf);
+ HDassert(space);
+ HDassert(buf);
/* Get the dataspace extent rank */
- rank=space->extent.rank;
+ rank = space->extent.rank;
/* Get the head of the point list */
- node=space->select.sel_info.pnt_lst->head;
+ node = space->select.sel_info.pnt_lst->head;
/* Iterate to the first point to return */
- while(node!=NULL && startpoint>0) {
+ while(node != NULL && startpoint > 0) {
startpoint--;
- node=node->next;
+ node = node->next;
} /* end while */
/* Iterate through the node, copying each hyperslab's information */
- while(node!=NULL && numpoints>0) {
- HDmemcpy(buf,node->pnt,sizeof(hsize_t)*rank);
- buf+=rank;
+ while(node != NULL && numpoints > 0) {
+ HDmemcpy(buf, node->pnt, sizeof(hsize_t) * rank);
+ buf += rank;
numpoints--;
- node=node->next;
+ node = node->next;
} /* end while */
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5S_get_select_elem_pointlist() */
@@ -987,24 +987,24 @@ herr_t
H5Sget_select_elem_pointlist(hid_t spaceid, hsize_t startpoint,
hsize_t numpoints, hsize_t buf[/*numpoints*/])
{
- H5S_t *space = NULL; /* Dataspace to modify selection of */
- herr_t ret_value; /* return value */
+ H5S_t *space; /* Dataspace to modify selection of */
+ herr_t ret_value; /* return value */
- FUNC_ENTER_API(H5Sget_select_elem_pointlist, FAIL);
+ FUNC_ENTER_API(H5Sget_select_elem_pointlist, FAIL)
H5TRACE4("e", "ihh*[a2]h", spaceid, startpoint, numpoints, buf);
/* Check args */
- if(buf==NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer");
- if (NULL == (space=H5I_object_verify(spaceid, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
- if(H5S_GET_SELECT_TYPE(space)!=H5S_SEL_POINTS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a point selection");
+ if(NULL == buf)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer")
+ if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ if(H5S_GET_SELECT_TYPE(space) != H5S_SEL_POINTS)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a point selection")
- ret_value = H5S_get_select_elem_pointlist(space,startpoint,numpoints,buf);
+ ret_value = H5S_get_select_elem_pointlist(space, startpoint, numpoints, buf);
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* H5Sget_select_elem_pointlist() */
@@ -1105,7 +1105,6 @@ H5S_point_offset(const H5S_t *space, hsize_t *offset)
const hssize_t *sel_offset; /* Pointer to the selection's offset */
const hsize_t *dim_size; /* Pointer to a dataspace's extent */
hsize_t accum; /* Accumulator for dimension sizes */
- int rank; /* Dataspace rank */
int i; /* index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1123,9 +1122,8 @@ H5S_point_offset(const H5S_t *space, hsize_t *offset)
dim_size = space->extent.size;
/* Loop through coordinates, calculating the linear offset */
- rank = space->extent.rank;
accum = 1;
- for(i = (rank - 1); i >= 0; i--) {
+ for(i = (int)space->extent.rank - 1; i >= 0; i--) {
hssize_t pnt_offset = (hssize_t)pnt[i] + sel_offset[i]; /* Point's offset in this dimension */
/* Check for offset moving selection out of the dataspace */
@@ -1133,7 +1131,7 @@ H5S_point_offset(const H5S_t *space, hsize_t *offset)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
/* Add the point's offset in this dimension to the total linear offset */
- *offset += pnt_offset * accum;
+ *offset += (hsize_t)pnt_offset * accum;
/* Increase the accumulator */
accum *= dim_size[i];
@@ -1348,14 +1346,14 @@ herr_t
H5Sselect_elements(hid_t spaceid, H5S_seloper_t op, size_t num_elem,
const hsize_t *coord)
{
- H5S_t *space = NULL; /* Dataspace to modify selection of */
+ H5S_t *space; /* Dataspace to modify selection of */
herr_t ret_value; /* Return value */
FUNC_ENTER_API(H5Sselect_elements, FAIL)
H5TRACE4("e", "iSsz*h", spaceid, op, num_elem, coord);
/* Check args */
- if(NULL == (space = H5I_object_verify(spaceid, H5I_DATASPACE)))
+ if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
if(H5S_SCALAR == H5S_GET_EXTENT_TYPE(space))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "point doesn't support H5S_SCALAR space")
@@ -1448,9 +1446,9 @@ H5S_point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter,
curr_seq=0;
while(node!=NULL) {
/* Compute the offset of each selected point in the buffer */
- for(i=ndims-1,acc=iter->elmt_size,loc=0; i>=0; i--) {
- loc+=(node->pnt[i]+space->select.offset[i])*acc;
- acc*=dims[i];
+ for(i = ndims - 1, acc = iter->elmt_size, loc = 0; i >= 0; i--) {
+ loc += (node->pnt[i] + space->select.offset[i]) * acc;
+ acc *= dims[i];
} /* end for */
/* Check if this is a later point in the selection */
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index e78fb51..2858ddb 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -184,7 +184,7 @@ H5_DLL herr_t H5S_write(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned update_flag
H5S_t *ds);
H5_DLL herr_t H5S_append(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, H5S_t *ds);
H5_DLL H5S_t *H5S_read(const struct H5O_loc_t *loc, hid_t dxpl_id);
-H5_DLL int H5S_set_extent(H5S_t *space, const hsize_t *size);
+H5_DLL htri_t H5S_set_extent(H5S_t *space, const hsize_t *size);
H5_DLL herr_t H5S_set_extent_real(H5S_t *space, const hsize_t *size);
H5_DLL H5S_t *H5S_create(H5S_class_t type);
H5_DLL H5S_t *H5S_create_simple(unsigned rank, const hsize_t dims[/*rank*/],
@@ -198,6 +198,7 @@ H5_DLL int H5S_extend(H5S_t *space, const hsize_t *size);
/* Operations on dataspace extents */
H5_DLL hsize_t H5S_extent_nelem(const H5S_extent_t *ext);
+H5_DLL int H5S_extent_get_dims(const H5S_extent_t *ext, hsize_t dims[], hsize_t max_dims[]);
H5_DLL htri_t H5S_extent_equal(const H5S_t *ds1, const H5S_t *ds2);
/* Operations on selections */
@@ -259,11 +260,9 @@ H5_DLL herr_t H5S_select_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem);
H5_DLL herr_t H5S_select_iter_release(H5S_sel_iter_t *sel_iter);
#ifdef H5_HAVE_PARALLEL
-#ifndef _H5S_IN_H5S_C
/* Global vars whose value comes from environment variable */
/* (Defined in H5S.c) */
H5_DLLVAR hbool_t H5S_mpi_opt_types_g;
-#endif /* _H5S_IN_H5S_C */
H5_DLL herr_t
H5S_mpio_space_type( const H5S_t *space, size_t elmt_size,
diff --git a/src/H5Spublic.h b/src/H5Spublic.h
index 43f79b9..c62a7b7 100644
--- a/src/H5Spublic.h
+++ b/src/H5Spublic.h
@@ -148,4 +148,5 @@ H5_DLL H5S_sel_type H5Sget_select_type(hid_t spaceid);
#ifdef __cplusplus
}
#endif
-#endif
+#endif /* _H5Spublic_H */
+
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index ed3c740..a419131 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -291,20 +291,20 @@ H5S_select_serialize(const H5S_t *space, uint8_t *buf)
hssize_t
H5Sget_select_npoints(hid_t spaceid)
{
- H5S_t *space = NULL; /* Dataspace to modify selection of */
+ H5S_t *space; /* Dataspace to modify selection of */
hssize_t ret_value; /* return value */
- FUNC_ENTER_API(H5Sget_select_npoints, FAIL);
+ FUNC_ENTER_API(H5Sget_select_npoints, FAIL)
H5TRACE1("Hs", "i", spaceid);
/* Check args */
- if (NULL == (space=H5I_object_verify(spaceid, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace");
+ if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
- ret_value = H5S_GET_SELECT_NPOINTS(space);
+ ret_value = (hssize_t)H5S_GET_SELECT_NPOINTS(space);
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* H5Sget_select_npoints() */
@@ -331,12 +331,12 @@ done:
hssize_t
H5S_get_select_npoints(const H5S_t *space)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5S_get_select_npoints);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_get_select_npoints)
/* Check args */
- assert(space);
+ HDassert(space);
- FUNC_LEAVE_NOAPI(space->select.num_elem);
+ FUNC_LEAVE_NOAPI((hssize_t)space->select.num_elem)
} /* H5S_get_select_npoints() */
@@ -365,20 +365,20 @@ H5S_get_select_npoints(const H5S_t *space)
htri_t
H5Sselect_valid(hid_t spaceid)
{
- H5S_t *space = NULL; /* Dataspace to modify selection of */
- htri_t ret_value; /* return value */
+ H5S_t *space; /* Dataspace to modify selection of */
+ htri_t ret_value; /* return value */
- FUNC_ENTER_API(H5Sselect_valid, FAIL);
+ FUNC_ENTER_API(H5Sselect_valid, FAIL)
H5TRACE1("t", "i", spaceid);
/* Check args */
- if (NULL == (space=H5I_object_verify(spaceid, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace");
+ if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
ret_value = H5S_SELECT_VALID(space);
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* H5Sselect_valid() */
@@ -516,22 +516,22 @@ done:
herr_t
H5Sget_select_bounds(hid_t spaceid, hsize_t start[], hsize_t end[])
{
- H5S_t *space = NULL; /* Dataspace to modify selection of */
- herr_t ret_value; /* return value */
+ H5S_t *space; /* Dataspace to modify selection of */
+ herr_t ret_value; /* return value */
- FUNC_ENTER_API(H5Sget_select_bounds, FAIL);
+ FUNC_ENTER_API(H5Sget_select_bounds, FAIL)
H5TRACE3("e", "i*h*h", spaceid, start, end);
/* Check args */
- if(start==NULL || end==NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer");
- if (NULL == (space=H5I_object_verify(spaceid, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace");
+ if(start == NULL || end == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer")
+ if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
- ret_value = H5S_SELECT_BOUNDS(space,start,end);
+ ret_value = H5S_SELECT_BOUNDS(space, start, end);
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* H5Sget_select_bounds() */
@@ -1134,7 +1134,7 @@ H5S_select_iterate(void *buf, hid_t type_id, const H5S_t *space, H5D_operator_t
{
H5T_t *dt; /* Datatype structure */
H5S_sel_iter_t iter; /* Selection iteration info */
- hbool_t iter_init=0; /* Selection iteration info has been initialized */
+ hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */
uint8_t *loc; /* Current element location in buffer */
hsize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of element in dataspace */
hssize_t nelmts; /* Number of elements in selection */
@@ -1157,63 +1157,63 @@ H5S_select_iterate(void *buf, hid_t type_id, const H5S_t *space, H5D_operator_t
FUNC_ENTER_NOAPI(H5S_select_iterate, FAIL);
/* Check args */
- assert(buf);
- assert(H5I_DATATYPE == H5I_get_type(type_id));
- assert(space);
- assert(op);
+ HDassert(buf);
+ HDassert(H5I_DATATYPE == H5I_get_type(type_id));
+ HDassert(space);
+ HDassert(op);
/* Get the datatype size */
- if (NULL==(dt=H5I_object_verify(type_id,H5I_DATATYPE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype");
- if((elmt_size=H5T_get_size(dt))==0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid");
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype")
+ if(0 == (elmt_size = H5T_get_size(dt)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid")
/* Initialize iterator */
- if (H5S_select_iter_init(&iter, space, elmt_size)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
- iter_init=1; /* Selection iteration info has been initialized */
+ if(H5S_select_iter_init(&iter, space, elmt_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
+ iter_init = TRUE; /* Selection iteration info has been initialized */
/* Get the number of elements in selection */
- if((nelmts = H5S_GET_SELECT_NPOINTS(space))<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements selected");
+ if((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(space)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements selected")
/* Get the rank of the dataspace */
- ndims=space->extent.rank;
+ ndims = space->extent.rank;
- if (ndims > 0){
+ if(ndims > 0) {
/* Copy the size of the space */
- assert(space->extent.size);
- HDmemcpy(space_size, space->extent.size, ndims*sizeof(hsize_t));
- }
- space_size[ndims]=elmt_size;
+ HDassert(space->extent.size);
+ HDmemcpy(space_size, space->extent.size, ndims * sizeof(hsize_t));
+ } /* end if */
+ space_size[ndims] = elmt_size;
/* Compute the maximum number of bytes required */
- H5_ASSIGN_OVERFLOW(max_elem,nelmts,hssize_t,size_t);
+ H5_ASSIGN_OVERFLOW(max_elem, nelmts, hssize_t, size_t);
/* Loop, while elements left in selection */
- while(max_elem>0 && user_ret==0) {
+ while(max_elem > 0 && user_ret == 0) {
/* Get the sequences of bytes */
if(H5S_SELECT_GET_SEQ_LIST(space, 0, &iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, len) < 0)
- HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
+ HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
/* Loop, while sequences left to process */
for(curr_seq=0; curr_seq<nseq && user_ret==0; curr_seq++) {
/* Get the current offset */
- curr_off=off[curr_seq];
+ curr_off = off[curr_seq];
/* Get the number of bytes in sequence */
- curr_len=len[curr_seq];
+ curr_len = len[curr_seq];
/* Loop, while bytes left in sequence */
- while(curr_len>0 && user_ret==0) {
+ while(curr_len > 0 && user_ret == 0) {
/* Compute the coordinate from the offset */
- for(i=ndims, tmp_off=curr_off; i>=0; i--) {
- coords[i]=tmp_off%space_size[i];
- tmp_off/=space_size[i];
+ for(i = (int)ndims, tmp_off = curr_off; i >= 0; i--) {
+ coords[i] = tmp_off % space_size[i];
+ tmp_off /= space_size[i];
} /* end for */
/* Get the location within the user's buffer */
- loc=(unsigned char *)buf+curr_off;
+ loc = (unsigned char *)buf + curr_off;
/* Call user's callback routine */
user_ret=(*op)(loc,type_id,ndims,coords,operator_data);
@@ -1235,12 +1235,10 @@ H5S_select_iterate(void *buf, hid_t type_id, const H5S_t *space, H5D_operator_t
done:
/* Release selection iterator */
- if(iter_init) {
- if (H5S_SELECT_ITER_RELEASE(&iter)<0)
- HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
- } /* end if */
+ if(iter_init && H5S_SELECT_ITER_RELEASE(&iter) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_select_iterate() */
@@ -1262,21 +1260,21 @@ done:
H5S_sel_type
H5Sget_select_type(hid_t space_id)
{
- H5S_t *space = NULL; /* dataspace to modify */
- H5S_sel_type ret_value; /* Return value */
+ H5S_t *space; /* dataspace to modify */
+ H5S_sel_type ret_value; /* Return value */
- FUNC_ENTER_API(H5Sget_select_type, H5S_SEL_ERROR);
+ FUNC_ENTER_API(H5Sget_select_type, H5S_SEL_ERROR)
H5TRACE1("St", "i", space_id);
/* Check args */
- if (NULL == (space = H5I_object_verify(space_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5S_SEL_ERROR, "not a dataspace");
+ if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5S_SEL_ERROR, "not a dataspace")
/* Set return value */
- ret_value=H5S_GET_SELECT_TYPE(space);
+ ret_value = H5S_GET_SELECT_TYPE(space);
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* end H5Sget_select_type() */
@@ -1542,7 +1540,7 @@ H5S_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *_b
iter_init = 1; /* Selection iteration info has been initialized */
/* Get the number of elements in selection */
- if((nelmts = H5S_GET_SELECT_NPOINTS(space)) < 0)
+ if((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(space)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements selected")
/* Compute the number of bytes to process */
diff --git a/src/H5Stest.c b/src/H5Stest.c
index 85693da..5758263 100644
--- a/src/H5Stest.c
+++ b/src/H5Stest.c
@@ -52,16 +52,16 @@
htri_t
H5S_select_shape_same_test(hid_t sid1, hid_t sid2)
{
- H5S_t *space1 = NULL; /* Pointer to 1st dataspace */
- H5S_t *space2 = NULL; /* Pointer to 2nd dataspace */
+ H5S_t *space1; /* Pointer to 1st dataspace */
+ H5S_t *space2; /* Pointer to 2nd dataspace */
htri_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5S_select_shape_same_test, FAIL)
/* Get dataspace structures */
- if(NULL == (space1 = H5I_object_verify(sid1, H5I_DATASPACE)))
+ if(NULL == (space1 = (H5S_t *)H5I_object_verify(sid1, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
- if(NULL == (space2 = H5I_object_verify(sid2, H5I_DATASPACE)))
+ if(NULL == (space2 = (H5S_t *)H5I_object_verify(sid2, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
/* Check if the dataspace selections are the same shape */
@@ -94,16 +94,16 @@ done:
htri_t
H5S_get_rebuild_status_test(hid_t space_id)
{
- H5S_t *space = NULL; /* Pointer to 1st dataspace */
+ H5S_t *space; /* Pointer to 1st dataspace */
htri_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5S_get_rebuild_status_test, FAIL)
/* Get dataspace structures */
- if(NULL == (space = H5I_object_verify(space_id, H5I_DATASPACE)))
+ if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
- ret_value = space->select.sel_info.hslab->diminfo_valid;
+ ret_value = (htri_t)space->select.sel_info.hslab->diminfo_valid;
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5T.c b/src/H5T.c
index 2da5be4..0a7eec4 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -20,23 +20,30 @@
* one particular datatype class are in another module.
*/
+/****************/
+/* Module Setup */
+/****************/
+
#define H5T_PACKAGE /*suppress error about including H5Tpkg */
/* Interface initialization */
#define H5_INTERFACE_INIT_FUNC H5T_init_interface
-#include "H5private.h" /*generic functions */
-#include "H5Dprivate.h" /*datasets (for H5Tcopy) */
-#include "H5Eprivate.h" /*error handling */
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Dprivate.h" /* Datasets */
+#include "H5Eprivate.h" /* Error handling */
#include "H5Fprivate.h" /* Files */
#include "H5FLprivate.h" /* Free Lists */
#include "H5FOprivate.h" /* File objects */
-#include "H5Gprivate.h" /*groups */
-#include "H5Iprivate.h" /*ID functions */
-#include "H5MMprivate.h" /*memory management */
-#include "H5Pprivate.h" /* Property Lists */
-#include "H5Tpkg.h" /*data-type functions */
+#include "H5Gprivate.h" /* Groups */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Pprivate.h" /* Property lists */
+#include "H5Tpkg.h" /* Datatypes */
/* Check for header needed for SGI floating-point code */
#ifdef H5_HAVE_SYS_FPU_H
@@ -465,13 +472,13 @@ static H5T_t *H5T_decode(const unsigned char *buf);
#define H5T_INIT_TYPE_COPY_CREATE(BASE) { \
/* Base off of existing datatype */ \
if(NULL == (dt = H5T_copy(BASE, H5T_COPY_TRANSIENT))) \
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCOPY, FAIL, "duplicating base type failed") \
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "duplicating base type failed") \
}
#define H5T_INIT_TYPE_ALLOC_CREATE(BASE) { \
/* Allocate new datatype info */ \
if(NULL == (dt = H5T_alloc())) \
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") \
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "memory allocation failed") \
}
@@ -484,10 +491,10 @@ static H5T_t *H5T_decode(const unsigned char *buf);
H5_GLUE3(H5T_INIT_TYPE_,SIZE_TMPL,_SIZE)(SIZE) \
\
/* Adjust information for this type */ \
- H5_GLUE3(H5T_INIT_TYPE_,GUTS,_CORE) \
+ H5_GLUE3(H5T_INIT_TYPE_, GUTS, _CORE) \
\
/* Atomize result */ \
- if((GLOBAL = H5I_register(H5I_DATATYPE, dt)) < 0) \
+ if((GLOBAL = H5I_register(H5I_DATATYPE, dt, FALSE)) < 0) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype atom") \
}
@@ -546,9 +553,9 @@ H5T_init_inf(void)
uint8_t *d; /* Pointer to value to set */
size_t half_size; /* Half the type size */
size_t u; /* Local index value */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5T_init_inf);
+ FUNC_ENTER_NOAPI_NOINIT(H5T_init_inf)
/* Get the float datatype */
if (NULL==(dst_p=H5I_object(H5T_NATIVE_FLOAT_g)))
@@ -556,40 +563,40 @@ H5T_init_inf(void)
dst = &dst_p->shared->u.atomic;
/* Check that we can re-order the bytes correctly */
- if (H5T_ORDER_LE!=H5T_native_order_g && H5T_ORDER_BE!=H5T_native_order_g)
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
+ if(H5T_ORDER_LE != H5T_native_order_g && H5T_ORDER_BE != H5T_native_order_g)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order")
/* +Inf */
- d=(uint8_t *)&H5T_NATIVE_FLOAT_POS_INF_g;
- H5T_bit_set (d, dst->u.f.sign, (size_t)1, FALSE);
- H5T_bit_set (d, dst->u.f.epos, dst->u.f.esize, TRUE);
- H5T_bit_set (d, dst->u.f.mpos, dst->u.f.msize, FALSE);
+ d = (uint8_t *)&H5T_NATIVE_FLOAT_POS_INF_g;
+ H5T_bit_set(d, dst->u.f.sign, (size_t)1, FALSE);
+ H5T_bit_set(d, dst->u.f.epos, dst->u.f.esize, TRUE);
+ H5T_bit_set(d, dst->u.f.mpos, dst->u.f.msize, FALSE);
/* Swap the bytes if the machine architecture is big-endian */
- if (H5T_ORDER_BE==H5T_native_order_g) {
- half_size = dst_p->shared->size/2;
- for (u=0; u<half_size; u++) {
- uint8_t tmp = d[dst_p->shared->size-(u+1)];
- d[dst_p->shared->size-(u+1)] = d[u];
+ if (H5T_ORDER_BE == H5T_native_order_g) {
+ half_size = dst_p->shared->size / 2;
+ for(u = 0; u < half_size; u++) {
+ uint8_t tmp = d[dst_p->shared->size - (u + 1)];
+ d[dst_p->shared->size - (u + 1)] = d[u];
d[u] = tmp;
- }
- }
+ } /* end for */
+ } /* end if */
/* -Inf */
- d=(uint8_t *)&H5T_NATIVE_FLOAT_NEG_INF_g;
- H5T_bit_set (d, dst->u.f.sign, (size_t)1, TRUE);
- H5T_bit_set (d, dst->u.f.epos, dst->u.f.esize, TRUE);
- H5T_bit_set (d, dst->u.f.mpos, dst->u.f.msize, FALSE);
+ d = (uint8_t *)&H5T_NATIVE_FLOAT_NEG_INF_g;
+ H5T_bit_set(d, dst->u.f.sign, (size_t)1, TRUE);
+ H5T_bit_set(d, dst->u.f.epos, dst->u.f.esize, TRUE);
+ H5T_bit_set(d, dst->u.f.mpos, dst->u.f.msize, FALSE);
/* Swap the bytes if the machine architecture is big-endian */
- if (H5T_ORDER_BE==H5T_native_order_g) {
- half_size = dst_p->shared->size/2;
- for (u=0; u<half_size; u++) {
- uint8_t tmp = d[dst_p->shared->size-(u+1)];
- d[dst_p->shared->size-(u+1)] = d[u];
+ if(H5T_ORDER_BE == H5T_native_order_g) {
+ half_size = dst_p->shared->size / 2;
+ for(u = 0; u < half_size; u++) {
+ uint8_t tmp = d[dst_p->shared->size - (u + 1)];
+ d[dst_p->shared->size - (u + 1)] = d[u];
d[u] = tmp;
- }
- }
+ } /* end for */
+ } /* end if */
/* Get the double datatype */
if (NULL==(dst_p=H5I_object(H5T_NATIVE_DOUBLE_g)))
@@ -601,40 +608,40 @@ H5T_init_inf(void)
HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
/* +Inf */
- d=(uint8_t *)&H5T_NATIVE_DOUBLE_POS_INF_g;
- H5T_bit_set (d, dst->u.f.sign, (size_t)1, FALSE);
- H5T_bit_set (d, dst->u.f.epos, dst->u.f.esize, TRUE);
- H5T_bit_set (d, dst->u.f.mpos, dst->u.f.msize, FALSE);
+ d = (uint8_t *)&H5T_NATIVE_DOUBLE_POS_INF_g;
+ H5T_bit_set(d, dst->u.f.sign, (size_t)1, FALSE);
+ H5T_bit_set(d, dst->u.f.epos, dst->u.f.esize, TRUE);
+ H5T_bit_set(d, dst->u.f.mpos, dst->u.f.msize, FALSE);
/* Swap the bytes if the machine architecture is big-endian */
- if (H5T_ORDER_BE==H5T_native_order_g) {
- half_size = dst_p->shared->size/2;
- for (u=0; u<half_size; u++) {
- uint8_t tmp = d[dst_p->shared->size-(u+1)];
- d[dst_p->shared->size-(u+1)] = d[u];
+ if(H5T_ORDER_BE == H5T_native_order_g) {
+ half_size = dst_p->shared->size / 2;
+ for(u = 0; u < half_size; u++) {
+ uint8_t tmp = d[dst_p->shared->size - (u + 1)];
+ d[dst_p->shared->size - (u + 1)] = d[u];
d[u] = tmp;
- }
- }
+ } /* end for */
+ } /* end if */
/* -Inf */
- d=(uint8_t *)&H5T_NATIVE_DOUBLE_NEG_INF_g;
- H5T_bit_set (d, dst->u.f.sign, (size_t)1, TRUE);
- H5T_bit_set (d, dst->u.f.epos, dst->u.f.esize, TRUE);
- H5T_bit_set (d, dst->u.f.mpos, dst->u.f.msize, FALSE);
+ d = (uint8_t *)&H5T_NATIVE_DOUBLE_NEG_INF_g;
+ H5T_bit_set(d, dst->u.f.sign, (size_t)1, TRUE);
+ H5T_bit_set(d, dst->u.f.epos, dst->u.f.esize, TRUE);
+ H5T_bit_set(d, dst->u.f.mpos, dst->u.f.msize, FALSE);
/* Swap the bytes if the machine architecture is big-endian */
- if (H5T_ORDER_BE==H5T_native_order_g) {
- half_size = dst_p->shared->size/2;
- for (u=0; u<half_size; u++) {
- uint8_t tmp = d[dst_p->shared->size-(u+1)];
- d[dst_p->shared->size-(u+1)] = d[u];
+ if(H5T_ORDER_BE == H5T_native_order_g) {
+ half_size = dst_p->shared->size / 2;
+ for(u = 0; u < half_size; u++) {
+ uint8_t tmp = d[dst_p->shared->size - (u + 1)];
+ d[dst_p->shared->size - (u + 1)] = d[u];
d[u] = tmp;
- }
- }
+ } /* end for */
+ } /* end if */
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_init_inf() */
/*-------------------------------------------------------------------------
@@ -643,14 +650,11 @@ done:
* Purpose: Perform hardware specific [floating-point] initialization
*
* Return: Success: non-negative
- *
* Failure: negative
*
* Programmer: Quincey Koziol
* Monday, November 24, 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -659,25 +663,25 @@ H5T_init_hw(void)
#ifdef H5_HAVE_GET_FPC_CSR
union fpc_csr csr; /* Union to hold results of floating-point status register query */
#endif /* H5_HAVE_GET_FPC_CSR */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_init_hw);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_init_hw)
#ifdef H5_HAVE_GET_FPC_CSR
/* [This code is specific to SGI machines] */
/* Get the floating-point status register */
- csr.fc_word=get_fpc_csr();
+ csr.fc_word = get_fpc_csr();
/* If the "flush denormalized values to zero" flag is set, unset it */
if(csr.fc_struct.flush) {
- csr.fc_struct.flush=0;
+ csr.fc_struct.flush = 0;
set_fpc_csr(csr.fc_word);
} /* end if */
#endif /* H5_HAVE_GET_FPC_CSR */
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_init_hw() */
/*--------------------------------------------------------------------------
@@ -716,10 +720,8 @@ H5T_init_interface(void)
H5T_t *std_u16be=NULL; /* Datatype structure for unsigned 16-bit big-endian integer */
H5T_t *std_u32le=NULL; /* Datatype structure for unsigned 32-bit little-endian integer */
H5T_t *std_u32be=NULL; /* Datatype structure for unsigned 32-bit big-endian integer */
- H5T_t *std_i32le=NULL; /* Datatype structure for signed 32-bit little-endian integer */
H5T_t *std_u64le=NULL; /* Datatype structure for unsigned 64-bit little-endian integer */
H5T_t *std_u64be=NULL; /* Datatype structure for unsigned 64-bit big-endian integer */
- H5T_t *ieee_f64le=NULL; /* Datatype structure for IEEE 64-bit little-endian floating-point */
H5T_t *dt = NULL;
H5T_t *fixedpt=NULL; /* Datatype structure for native int */
H5T_t *floatpt=NULL; /* Datatype structure for native float */
@@ -734,7 +736,7 @@ H5T_init_interface(void)
herr_t status;
unsigned copied_dtype=1; /* Flag to indicate whether datatype was copied or allocated (for error cleanup) */
H5P_genclass_t *crt_pclass; /* Property list class for datatype creation properties */
- herr_t ret_value=SUCCEED;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5T_init_interface)
@@ -747,11 +749,11 @@ H5T_init_interface(void)
HDassert(H5T_NCLASSES < 16);
/* Perform any necessary hardware initializations */
- if(H5T_init_hw()<0)
+ if(H5T_init_hw() < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize interface")
/*
- * Initialize pre-defined native data types from code generated during
+ * Initialize pre-defined native datatypes from code generated during
* the library configuration by H5detect.
*/
if(H5TN_init_interface()<0)
@@ -788,7 +790,7 @@ H5T_init_interface(void)
#endif
/*------------------------------------------------------------
- * Native types
+ * Derived native types
*------------------------------------------------------------
*/
@@ -832,7 +834,6 @@ H5T_init_interface(void)
/* IEEE 8-byte little-endian float */
H5T_INIT_TYPE(DOUBLELE,H5T_IEEE_F64LE_g,COPY,native_double,SET,8)
- ieee_f64le=dt; /* Keep type for later */
/* IEEE 8-byte big-endian float */
H5T_INIT_TYPE(DOUBLEBE,H5T_IEEE_F64BE_g,COPY,native_double,SET,8)
@@ -849,7 +850,7 @@ H5T_init_interface(void)
H5T_INIT_TYPE(DOUBLEVAX,H5T_VAX_F64_g,COPY,native_double,SET,8)
/*------------------------------------------------------------
- * Other "standard" types
+ * C99 types
*------------------------------------------------------------
*/
@@ -867,7 +868,6 @@ H5T_init_interface(void)
/* 4-byte little-endian signed integer */
H5T_INIT_TYPE(SINTLE,H5T_STD_I32LE_g,COPY,native_int,SET,4)
- std_i32le=dt; /* Keep type for later */
/* 4-byte big-endian signed integer */
H5T_INIT_TYPE(SINTBE,H5T_STD_I32BE_g,COPY,native_int,SET,4)
@@ -911,34 +911,34 @@ H5T_init_interface(void)
std_u64be=dt; /* Keep type for later */
/*------------------------------------------------------------
- * Little- & Big-endian bitfields
+ * Native, Little- & Big-endian bitfields
*------------------------------------------------------------
*/
/* little-endian (order is irrelevant) 8-bit bitfield */
- H5T_INIT_TYPE(BITFIELD,H5T_STD_B8LE_g,COPY,std_u8le,NOSET,-)
+ H5T_INIT_TYPE(BITFIELD, H5T_STD_B8LE_g, COPY, std_u8le, NOSET, -)
bitfield=dt; /* Keep type for later */
/* big-endian (order is irrelevant) 8-bit bitfield */
- H5T_INIT_TYPE(BITFIELD,H5T_STD_B8BE_g,COPY,std_u8be,NOSET,-)
+ H5T_INIT_TYPE(BITFIELD, H5T_STD_B8BE_g, COPY, std_u8be, NOSET, -)
/* Little-endian 16-bit bitfield */
- H5T_INIT_TYPE(BITFIELD,H5T_STD_B16LE_g,COPY,std_u16le,NOSET,-)
+ H5T_INIT_TYPE(BITFIELD, H5T_STD_B16LE_g, COPY, std_u16le, NOSET, -)
/* Big-endian 16-bit bitfield */
- H5T_INIT_TYPE(BITFIELD,H5T_STD_B16BE_g,COPY,std_u16be,NOSET,-)
+ H5T_INIT_TYPE(BITFIELD, H5T_STD_B16BE_g, COPY, std_u16be, NOSET, -)
/* Little-endian 32-bit bitfield */
- H5T_INIT_TYPE(BITFIELD,H5T_STD_B32LE_g,COPY,std_u32le,NOSET,-)
+ H5T_INIT_TYPE(BITFIELD, H5T_STD_B32LE_g, COPY, std_u32le, NOSET, -)
/* Big-endian 32-bit bitfield */
- H5T_INIT_TYPE(BITFIELD,H5T_STD_B32BE_g,COPY,std_u32be,NOSET,-)
+ H5T_INIT_TYPE(BITFIELD, H5T_STD_B32BE_g, COPY, std_u32be, NOSET, -)
/* Little-endian 64-bit bitfield */
- H5T_INIT_TYPE(BITFIELD,H5T_STD_B64LE_g,COPY,std_u64le,NOSET,-)
+ H5T_INIT_TYPE(BITFIELD, H5T_STD_B64LE_g, COPY, std_u64le, NOSET, -)
/* Big-endian 64-bit bitfield */
- H5T_INIT_TYPE(BITFIELD,H5T_STD_B64BE_g,COPY,std_u64be,NOSET,-)
+ H5T_INIT_TYPE(BITFIELD, H5T_STD_B64BE_g, COPY, std_u64be, NOSET, -)
/*------------------------------------------------------------
* The Unix architecture for dates and times.
@@ -946,25 +946,25 @@ H5T_init_interface(void)
*/
/* Little-endian 32-bit UNIX time_t */
- H5T_INIT_TYPE(TIME,H5T_UNIX_D32LE_g,COPY,std_u32le,NOSET,-)
+ H5T_INIT_TYPE(TIME, H5T_UNIX_D32LE_g, COPY, std_u32le, NOSET, -)
/* Big-endian 32-bit UNIX time_t */
- H5T_INIT_TYPE(TIME,H5T_UNIX_D32BE_g,COPY,std_u32be,NOSET,-)
+ H5T_INIT_TYPE(TIME, H5T_UNIX_D32BE_g, COPY, std_u32be, NOSET, -)
/* Little-endian 64-bit UNIX time_t */
- H5T_INIT_TYPE(TIME,H5T_UNIX_D64LE_g,COPY,std_u64le,NOSET,-)
+ H5T_INIT_TYPE(TIME, H5T_UNIX_D64LE_g, COPY, std_u64le, NOSET, -)
/* Big-endian 64-bit UNIX time_t */
- H5T_INIT_TYPE(TIME,H5T_UNIX_D64BE_g,COPY,std_u64be,NOSET,-)
+ H5T_INIT_TYPE(TIME, H5T_UNIX_D64BE_g, COPY, std_u64be, NOSET, -)
/* Indicate that the types that are created from here down are allocated
* H5FL_ALLOC(), not copied with H5T_copy()
*/
- copied_dtype=0;
+ copied_dtype = FALSE;
/* Opaque data */
- H5T_INIT_TYPE(OPAQ,H5T_NATIVE_OPAQUE_g,ALLOC,-,SET,1)
+ H5T_INIT_TYPE(OPAQ, H5T_NATIVE_OPAQUE_g, ALLOC, -, SET, 1)
/*------------------------------------------------------------
* The `C' architecture
@@ -972,7 +972,7 @@ H5T_init_interface(void)
*/
/* One-byte character string */
- H5T_INIT_TYPE(CSTRING,H5T_C_S1_g,ALLOC,-,SET,1)
+ H5T_INIT_TYPE(CSTRING, H5T_C_S1_g, ALLOC, -, SET, 1)
string=dt; /* Keep type for later */
/*------------------------------------------------------------
@@ -981,19 +981,19 @@ H5T_init_interface(void)
*/
/* One-byte character string */
- H5T_INIT_TYPE(FORSTRING,H5T_FORTRAN_S1_g,ALLOC,-,SET,1)
+ H5T_INIT_TYPE(FORSTRING, H5T_FORTRAN_S1_g, ALLOC, -, SET, 1)
/*------------------------------------------------------------
- * Pointer types
+ * Reference types
*------------------------------------------------------------
*/
- /* Object pointer (i.e. object header address in file) */
- H5T_INIT_TYPE(OBJREF,H5T_STD_REF_OBJ_g,ALLOC,-,SET,H5R_OBJ_REF_BUF_SIZE)
+ /* Object reference (i.e. object header address in file) */
+ H5T_INIT_TYPE(OBJREF, H5T_STD_REF_OBJ_g, ALLOC, -, SET, H5R_OBJ_REF_BUF_SIZE)
objref=dt; /* Keep type for later */
- /* Dataset Region pointer (i.e. selection inside a dataset) */
- H5T_INIT_TYPE(REGREF,H5T_STD_REF_DSETREG_g,ALLOC,-,SET,H5R_DSET_REG_REF_BUF_SIZE)
+ /* Dataset Region reference (i.e. selection inside a dataset) */
+ H5T_INIT_TYPE(REGREF, H5T_STD_REF_DSETREG_g, ALLOC, -, SET, H5R_DSET_REG_REF_BUF_SIZE)
/*
* Register conversion functions beginning with the most general and
@@ -1048,7 +1048,7 @@ H5T_init_interface(void)
status |= H5T_register(H5T_PERS_HARD, "ldbl_dbl", native_ldouble, native_double, H5T_conv_ldouble_double, H5AC_dxpl_id, FALSE);
#endif /*H5T_CONV_INTERNAL_FP_LDOUBLE*/
- /* from long_long */
+ /* from long long */
status |= H5T_register(H5T_PERS_HARD, "llong_ullong", native_llong, native_ullong, H5T_conv_llong_ullong, H5AC_dxpl_id, FALSE);
status |= H5T_register(H5T_PERS_HARD, "ullong_llong", native_ullong, native_llong, H5T_conv_ullong_llong, H5AC_dxpl_id, FALSE);
status |= H5T_register(H5T_PERS_HARD, "llong_long", native_llong, native_long, H5T_conv_llong_long, H5AC_dxpl_id, FALSE);
@@ -1198,10 +1198,12 @@ H5T_init_interface(void)
#endif /* H5T_CONV_INTERNAL_INTEGER_LDOUBLE */
/* From unsigned long to floats */
-#if H5T_CONV_INTERNAL_ULONG_FP
+#if H5T_CONV_INTERNAL_ULONG_FLT
status |= H5T_register(H5T_PERS_HARD, "ulong_flt", native_ulong, native_float, H5T_conv_ulong_float, H5AC_dxpl_id, FALSE);
+#endif /* H5T_CONV_INTERNAL_ULONG_FLT */
+#if H5T_CONV_INTERNAL_ULONG_DBL
status |= H5T_register(H5T_PERS_HARD, "ulong_dbl", native_ulong, native_double, H5T_conv_ulong_double, H5AC_dxpl_id, FALSE);
-#endif /* H5T_CONV_INTERNAL_ULONG_FP */
+#endif /* H5T_CONV_INTERNAL_ULONG_DBL */
#if H5T_CONV_INTERNAL_ULONG_LDOUBLE
status |= H5T_register(H5T_PERS_HARD, "ulong_ldbl", native_ulong, native_ldouble, H5T_conv_ulong_ldouble, H5AC_dxpl_id, FALSE);
#endif /* H5T_CONV_INTERNAL_ULONG_LDOUBLE */
@@ -1312,7 +1314,7 @@ H5T_init_interface(void)
assert(H5P_CLS_DATATYPE_CREATE_g!=-1);
/* Get the pointer to group creation class */
- if(NULL == (crt_pclass = H5I_object(H5P_CLS_DATATYPE_CREATE_g)))
+ if(NULL == (crt_pclass = (H5P_genclass_t *)H5I_object(H5P_CLS_DATATYPE_CREATE_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class")
/* Register datatype creation property class properties here. See similar
@@ -1320,9 +1322,9 @@ H5T_init_interface(void)
*/
/* Only register the default property list if it hasn't been created yet */
- if(H5P_LST_DATATYPE_CREATE_g==(-1)) {
+ if(H5P_LST_DATATYPE_CREATE_g == (-1)) {
/* Register the default datatype creation property list */
- if((H5P_LST_DATATYPE_CREATE_g = H5P_create_id(crt_pclass))<0)
+ if((H5P_LST_DATATYPE_CREATE_g = H5P_create_id(crt_pclass, FALSE)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class")
} /* end if */
@@ -1338,16 +1340,15 @@ done:
H5T_close(array);
/* Error cleanup */
- if(ret_value<0) {
- if(dt!=NULL) {
+ if(ret_value < 0) {
+ if(dt) {
/* Check if we should call H5T_close or H5FL_FREE */
if(copied_dtype)
H5T_close(dt);
- else
- {
- H5FL_FREE(H5T_shared_t, dt->shared);
- H5FL_FREE(H5T_t,dt);
- }
+ else {
+ (void)H5FL_FREE(H5T_shared_t, dt->shared);
+ (void)H5FL_FREE(H5T_t,dt);
+ } /* end else */
} /* end if */
} /* end if */
@@ -1358,32 +1359,30 @@ done:
/*-------------------------------------------------------------------------
* Function: H5T_unlock_cb
*
- * Purpose: Clear the immutable flag for a data type. This function is
+ * Purpose: Clear the immutable flag for a datatype. This function is
* called when the library is closing in order to unlock all
- * registered data types and thus make them free-able.
+ * registered datatypes and thus make them free-able.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
* Monday, April 27, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static int
-H5T_unlock_cb (void *_dt, hid_t UNUSED id, void UNUSED *key)
+H5T_unlock_cb(void *_dt, hid_t UNUSED id, void UNUSED *key)
{
H5T_t *dt = (H5T_t *)_dt;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_unlock_cb);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_unlock_cb)
HDassert (dt && dt->shared);
if (H5T_STATE_IMMUTABLE==dt->shared->state)
dt->shared->state = H5T_STATE_RDONLY;
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5T_unlock_cb() */
/*-------------------------------------------------------------------------
@@ -1400,10 +1399,6 @@ H5T_unlock_cb (void *_dt, hid_t UNUSED id, void UNUSED *key)
* Programmer: Robb Matzke
* Friday, November 20, 1998
*
- * Modifications:
- * Robb Matzke, 1998-06-11
- * Statistics are only printed for conversion functions that were
- * called.
*-------------------------------------------------------------------------
*/
int
@@ -1412,7 +1407,7 @@ H5T_term_interface(void)
int i, nprint=0, n=0;
H5T_path_t *path = NULL;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_term_interface);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_term_interface)
if (H5_interface_initialize_g) {
/* Unregister all conversion functions */
@@ -1452,7 +1447,7 @@ H5T_term_interface(void)
H5T_g.nsoft = H5T_g.asoft = 0;
/* Unlock all datatypes, then free them */
- H5I_search (H5I_DATATYPE, H5T_unlock_cb, NULL);
+ H5I_search (H5I_DATATYPE, H5T_unlock_cb, NULL, FALSE);
H5I_dec_type_ref(H5I_DATATYPE);
/* Reset all the datatype IDs */
@@ -1554,9 +1549,10 @@ H5T_term_interface(void)
/* Mark interface as closed */
H5_interface_initialize_g = 0;
n = 1; /*H5I*/
- }
- FUNC_LEAVE_NOAPI(n);
-}
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(n)
+} /* end H5T_term_interface() */
/*-------------------------------------------------------------------------
@@ -1572,7 +1568,7 @@ H5T_term_interface(void)
* Errors:
* ARGS BADVALUE Invalid size.
* DATATYPE CANTINIT Can't create type.
- * DATATYPE CANTREGISTER Can't register data type atom.
+ * DATATYPE CANTREGISTER Can't register datatype atom.
*
* Programmer: Robb Matzke
* Friday, December 5, 1997
@@ -1584,37 +1580,37 @@ H5T_term_interface(void)
hid_t
H5Tcreate(H5T_class_t type, size_t size)
{
- H5T_t *dt = NULL;
- hid_t ret_value;
+ H5T_t *dt = NULL; /* New datatype constructed */
+ hid_t ret_value; /* Return value */
- FUNC_ENTER_API(H5Tcreate, FAIL);
+ FUNC_ENTER_API(H5Tcreate, FAIL)
H5TRACE2("i", "Ttz", type, size);
/* check args */
- if (size == 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid size");
+ if(size == 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid size")
/* create the type */
- if (NULL == (dt = H5T_create(type, size)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to create type");
+ if(NULL == (dt = H5T_create(type, size)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to create type")
- /* Make it an atom */
- if ((ret_value = H5I_register(H5I_DATATYPE, dt)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register data type atom");
+ /* Get an ID for the datatype */
+ if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype ID")
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Tcreate() */
/*-------------------------------------------------------------------------
* Function: H5Tcopy
*
- * Purpose: Copies a data type. The resulting data type is not locked.
- * The data type should be closed when no longer needed by
+ * Purpose: Copies a datatype. The resulting datatype is not locked.
+ * The datatype should be closed when no longer needed by
* calling H5Tclose().
*
- * Return: Success: The ID of a new data type.
+ * Return: Success: The ID of a new datatype.
*
* Failure: Negative
*
@@ -1625,64 +1621,66 @@ done:
*
* Robb Matzke, 4 Jun 1998
* The returned type is always transient and unlocked. If the TYPE_ID
- * argument is a dataset instead of a data type then this function
- * returns a transient, modifiable data type which is a copy of the
- * dataset's data type.
+ * argument is a dataset instead of a datatype then this function
+ * returns a transient, modifiable datatype which is a copy of the
+ * dataset's datatype.
*
*-------------------------------------------------------------------------
*/
hid_t
H5Tcopy(hid_t type_id)
{
- H5T_t *dt = NULL;
+ H5T_t *dt; /* Pointer to the datatype to copy */
H5T_t *new_dt = NULL;
- H5D_t *dset = NULL;
- hid_t ret_value;
+ hid_t ret_value; /* Return value */
- FUNC_ENTER_API(H5Tcopy, FAIL);
+ FUNC_ENTER_API(H5Tcopy, FAIL)
H5TRACE1("i", "i", type_id);
- switch (H5I_get_type (type_id)) {
+ switch(H5I_get_type(type_id)) {
case H5I_DATATYPE:
- /* The argument is a data type handle */
- if (NULL==(dt=H5I_object (type_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ /* The argument is a datatype handle */
+ if(NULL == (dt = (H5T_t *)H5I_object(type_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
break;
case H5I_DATASET:
- /* The argument is a dataset handle */
- if (NULL==(dset=H5I_object (type_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
- if (NULL==(dt=H5D_typeof (dset)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get the dataset data type");
+ {
+ H5D_t *dset; /* Dataset for datatype */
+
+ /* The argument is a dataset handle */
+ if(NULL == (dset = (H5D_t *)H5I_object(type_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+ if(NULL == (dt = H5D_typeof(dset)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get the dataset datatype")
+ }
break;
default:
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type or dataset");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype or dataset")
} /* end switch */
- /* Copy */
- if (NULL == (new_dt = H5T_copy(dt, H5T_COPY_TRANSIENT)))
+ /* Copy datatype */
+ if(NULL == (new_dt = H5T_copy(dt, H5T_COPY_TRANSIENT)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy");
/* Atomize result */
- if ((ret_value = H5I_register(H5I_DATATYPE, new_dt)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register data type atom");
+ if((ret_value = H5I_register(H5I_DATATYPE, new_dt, TRUE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype atom")
done:
- if(ret_value<0) {
- if(new_dt!=NULL)
- H5T_close(new_dt);
- } /* end if */
+ if(ret_value < 0)
+ if(new_dt && H5T_close(new_dt) < 0)
+ HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "unable to release datatype info")
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* end H5Tcopy() */
/*-------------------------------------------------------------------------
* Function: H5Tclose
*
- * Purpose: Frees a data type and all associated memory.
+ * Purpose: Frees a datatype and all associated memory.
*
* Return: Non-negative on success/Negative on failure
*
@@ -1696,76 +1694,73 @@ done:
herr_t
H5Tclose(hid_t type_id)
{
- H5T_t *dt = NULL;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5T_t *dt; /* Pointer to datatype to close */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API(H5Tclose, FAIL);
+ FUNC_ENTER_API(H5Tclose, FAIL)
H5TRACE1("e", "i", type_id);
/* Check args */
- if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- if (H5T_STATE_IMMUTABLE==dt->shared->state)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "immutable data type");
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+ if(H5T_STATE_IMMUTABLE==dt->shared->state)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "immutable datatype")
/* When the reference count reaches zero the resources are freed */
- if (H5I_dec_ref(type_id) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "problem freeing id");
+ if(H5I_dec_ref(type_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "problem freeing id")
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Tclose() */
/*-------------------------------------------------------------------------
* Function: H5Tequal
*
- * Purpose: Determines if two data types are equal.
+ * Purpose: Determines if two datatypes are equal.
*
* Return: Success: TRUE if equal, FALSE if unequal
*
* Failure: Negative
*
- * Errors:
- *
* Programmer: Robb Matzke
* Wednesday, December 10, 1997
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
htri_t
H5Tequal(hid_t type1_id, hid_t type2_id)
{
- const H5T_t *dt1 = NULL;
- const H5T_t *dt2 = NULL;
- htri_t ret_value;
+ const H5T_t *dt1; /* Pointer to first datatype */
+ const H5T_t *dt2; /* Pointer to second datatype */
+ htri_t ret_value; /* Return value */
- FUNC_ENTER_API(H5Tequal, FAIL);
+ FUNC_ENTER_API(H5Tequal, FAIL)
H5TRACE2("t", "ii", type1_id, type2_id);
/* check args */
- if (NULL == (dt1 = H5I_object_verify(type1_id,H5I_DATATYPE)) ||
- NULL == (dt2 = H5I_object_verify(type2_id,H5I_DATATYPE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ if(NULL == (dt1 = (H5T_t *)H5I_object_verify(type1_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+ if(NULL == (dt2 = (H5T_t *)H5I_object_verify(type2_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
ret_value = (0 == H5T_cmp(dt1, dt2, FALSE)) ? TRUE : FALSE;
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Tequal() */
/*-------------------------------------------------------------------------
* Function: H5Tlock
*
* Purpose: Locks a type, making it read only and non-destructable. This
- * is normally done by the library for predefined data types so
+ * is normally done by the library for predefined datatypes so
* the application doesn't inadvertently change or delete a
* predefined type.
*
- * Once a data type is locked it can never be unlocked unless
+ * Once a datatype is locked it can never be unlocked unless
* the entire library is closed.
*
* Return: Non-negative on success/Negative on failure
@@ -1776,7 +1771,7 @@ done:
* Modifications:
*
* Robb Matzke, 1 Jun 1998
- * It is illegal to lock a named data type since we must allow named
+ * It is illegal to lock a named datatype since we must allow named
* types to be closed (to release file resources) but locking a type
* prevents that.
*-------------------------------------------------------------------------
@@ -1784,32 +1779,32 @@ done:
herr_t
H5Tlock(hid_t type_id)
{
- H5T_t *dt = NULL;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5T_t *dt; /* Datatype to operate on */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API(H5Tlock, FAIL);
+ FUNC_ENTER_API(H5Tlock, FAIL)
H5TRACE1("e", "i", type_id);
/* Check args */
- if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- if (H5T_STATE_NAMED==dt->shared->state || H5T_STATE_OPEN==dt->shared->state)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to lock named data type");
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id,H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+ if(H5T_STATE_NAMED==dt->shared->state || H5T_STATE_OPEN==dt->shared->state)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to lock named datatype")
- if (H5T_lock (dt, TRUE)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient data type");
+ if(H5T_lock(dt, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient datatype")
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Tlock() */
/*-------------------------------------------------------------------------
* Function: H5Tget_class
*
- * Purpose: Returns the data type class identifier for data type TYPE_ID.
+ * Purpose: Returns the datatype class identifier for datatype TYPE_ID.
*
- * Return: Success: One of the non-negative data type class
+ * Return: Success: One of the non-negative datatype class
* constants.
*
* Failure: H5T_NO_CLASS (Negative)
@@ -1817,29 +1812,27 @@ done:
* Programmer: Robb Matzke
* Monday, December 8, 1997
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
H5T_class_t
H5Tget_class(hid_t type_id)
{
- H5T_t *dt = NULL;
- H5T_class_t ret_value; /* Return value */
+ H5T_t *dt; /* Pointer to datatype */
+ H5T_class_t ret_value; /* Return value */
- FUNC_ENTER_API(H5Tget_class, H5T_NO_CLASS);
+ FUNC_ENTER_API(H5Tget_class, H5T_NO_CLASS)
H5TRACE1("Tt", "i", type_id);
/* Check args */
- if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a data type");
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a datatype")
/* Set return value */
- ret_value= H5T_get_class(dt, FALSE);
+ ret_value = H5T_get_class(dt, FALSE);
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Tget_class() */
/*-------------------------------------------------------------------------
@@ -1908,28 +1901,25 @@ done:
htri_t
H5Tdetect_class(hid_t type, H5T_class_t cls)
{
- H5T_t *dt = NULL;
+ H5T_t *dt; /* Datatype to query */
htri_t ret_value; /* Return value */
- FUNC_ENTER_API(H5Tdetect_class, FAIL);
+ FUNC_ENTER_API(H5Tdetect_class, FAIL)
H5TRACE2("t", "iTt", type, cls);
/* Check args */
- if (NULL == (dt = H5I_object_verify(type,H5I_DATATYPE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a data type");
- if (!(cls>H5T_NO_CLASS && cls<H5T_NCLASSES))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a data type class");
-
- /* Set return value. Consider VL string as a string for API, as a VL for
- * internal use. */
- if(H5T_IS_VL_STRING(dt->shared))
- ret_value = (H5T_STRING==cls);
- else
- ret_value=H5T_detect_class(dt,cls);
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type,H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a datatype")
+ if(!(cls > H5T_NO_CLASS && cls < H5T_NCLASSES))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a datatype class")
+
+ /* Set return value */
+ if((ret_value = H5T_detect_class(dt, cls, TRUE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, H5T_NO_CLASS, "can't get datatype class")
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Tdetect_class() */
/*-------------------------------------------------------------------------
@@ -1944,11 +1934,18 @@ done:
* Wednesday, November 29, 2000
*
* Modifications:
- *
+ * Raymond Lu
+ * 4 December 2009
+ * Added a flag as a parameter to indicate whether the caller is
+ * H5Tdetect_class. I also added the check for VL string type
+ * just like the public function. Because we want to tell users
+ * VL string is a string type but we treat it as a VL type
+ * internally, H5T_detect_class needs to know where the caller
+ * is from.
*-------------------------------------------------------------------------
*/
htri_t
-H5T_detect_class (const H5T_t *dt, H5T_class_t cls)
+H5T_detect_class(const H5T_t *dt, H5T_class_t cls, hbool_t from_api)
{
unsigned i;
htri_t ret_value=FALSE; /* Return value */
@@ -1958,6 +1955,14 @@ H5T_detect_class (const H5T_t *dt, H5T_class_t cls)
assert(dt);
assert(cls>H5T_NO_CLASS && cls<H5T_NCLASSES);
+ /* Consider VL string as a string for API, as a VL for internal use. */
+ /* (note that this check must be performed before checking if the VL
+ * string belongs to the H5T_VLEN class, which would otherwise return
+ * true. -QAK)
+ */
+ if(from_api && H5T_IS_VL_STRING(dt->shared))
+ HGOTO_DONE(H5T_STRING == cls);
+
/* Check if this type is the correct type */
if(dt->shared->type==cls)
HGOTO_DONE(TRUE);
@@ -1974,7 +1979,7 @@ H5T_detect_class (const H5T_t *dt, H5T_class_t cls)
/* Recurse if it's VL, compound, enum or array */
if(H5T_IS_COMPLEX(dt->shared->u.compnd.memb[i].type->shared->type))
- if((nested_ret=H5T_detect_class(dt->shared->u.compnd.memb[i].type,cls))!=FALSE)
+ if((nested_ret=H5T_detect_class(dt->shared->u.compnd.memb[i].type, cls, from_api))!=FALSE)
HGOTO_DONE(nested_ret);
} /* end for */
break;
@@ -1982,7 +1987,7 @@ H5T_detect_class (const H5T_t *dt, H5T_class_t cls)
case H5T_ARRAY:
case H5T_VLEN:
case H5T_ENUM:
- HGOTO_DONE(H5T_detect_class(dt->shared->parent,cls));
+ HGOTO_DONE(H5T_detect_class(dt->shared->parent, cls, from_api));
default:
break;
@@ -2015,12 +2020,12 @@ H5Tis_variable_str(hid_t dtype_id)
H5TRACE1("t", "i", dtype_id);
/* Check args */
- if(NULL == (dt = H5I_object_verify(dtype_id, H5I_DATATYPE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
/* Set return value */
if((ret_value = H5T_is_variable_str(dt)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "can't determine if datatype is VL-string");
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "can't determine if datatype is VL-string")
done:
FUNC_LEAVE_API(ret_value);
@@ -2062,28 +2067,26 @@ H5T_is_variable_str(const H5T_t *dt)
* Programmer: Robb Matzke
* Monday, December 8, 1997
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
size_t
H5Tget_size(hid_t type_id)
{
- H5T_t *dt = NULL;
- size_t ret_value;
+ H5T_t *dt; /* Datatype to query */
+ size_t ret_value; /* Return value */
- FUNC_ENTER_API(H5Tget_size, 0);
+ FUNC_ENTER_API(H5Tget_size, 0)
H5TRACE1("z", "i", type_id);
/* Check args */
- if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype");
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype")
/* size */
- ret_value = H5T_get_size(dt);
+ ret_value = H5T_GET_SIZE(dt);
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* end H5Tget_size() */
@@ -2102,51 +2105,47 @@ done:
* Adjusting the size of an H5T_STRING automatically sets the
* precision to 8*size.
*
- * All data types have a positive size.
+ * All datatypes have a positive size.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
* Wednesday, January 7, 1998
*
- * Modifications:
- * Robb Matzke, 22 Dec 1998
- * Moved the real work into a private function.
- *
*-------------------------------------------------------------------------
*/
herr_t
H5Tset_size(hid_t type_id, size_t size)
{
- H5T_t *dt = NULL;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5T_t *dt; /* Datatype to modify */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API(H5Tset_size, FAIL);
+ FUNC_ENTER_API(H5Tset_size, FAIL)
H5TRACE2("e", "iz", type_id, size);
/* Check args */
- if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- if (H5T_STATE_TRANSIENT!=dt->shared->state)
- HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
- if (size <= 0 && size!=H5T_VARIABLE)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "size must be positive");
- if (size == H5T_VARIABLE && dt->shared->type!=H5T_STRING)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "only strings may be variable length");
- if (H5T_ENUM==dt->shared->type && dt->shared->u.enumer.nmembs>0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined");
- if (H5T_REFERENCE==dt->shared->type)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for this datatype");
- if (size==0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't adjust size to 0");
-
- /* Do the work */
- if (H5T_set_size(dt, size)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set size for data type");
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+ if(H5T_STATE_TRANSIENT!=dt->shared->state)
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "datatype is read-only")
+ if(size <= 0 && size != H5T_VARIABLE)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "size must be positive")
+ if(size == H5T_VARIABLE && !H5T_IS_STRING(dt->shared))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "only strings may be variable length")
+ if(H5T_ENUM == dt->shared->type && dt->shared->u.enumer.nmembs > 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined")
+ if(H5T_REFERENCE == dt->shared->type)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for this datatype")
+ if(size == 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't adjust size to 0")
+
+ /* Modify the datatype */
+ if(H5T_set_size(dt, size) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set size for datatype")
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Tset_size() */
/*-------------------------------------------------------------------------
@@ -2155,7 +2154,7 @@ done:
* Purpose: Returns the type from which TYPE is derived. In the case of
* an enumeration type the return value is an integer type.
*
- * Return: Success: Type ID for base data type.
+ * Return: Success: Type ID for base datatype.
*
* Failure: negative
*
@@ -2169,27 +2168,27 @@ done:
hid_t
H5Tget_super(hid_t type)
{
- H5T_t *dt=NULL, *super=NULL;
- hid_t ret_value;
+ H5T_t *dt; /* Datatype to query */
+ H5T_t *super = NULL; /* Supertype */
+ hid_t ret_value; /* Return value */
- FUNC_ENTER_API(H5Tget_super, FAIL);
+ FUNC_ENTER_API(H5Tget_super, FAIL)
H5TRACE1("i", "i", type);
- if (NULL==(dt=H5I_object_verify(type,H5I_DATATYPE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- if((super=H5T_get_super(dt))==NULL)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "not a data type");
- if ((ret_value=H5I_register(H5I_DATATYPE, super))<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register parent data type");
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type,H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+ if(NULL == (super = H5T_get_super(dt)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "not a datatype")
+ if((ret_value = H5I_register(H5I_DATATYPE, super, TRUE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register parent datatype")
done:
- if(ret_value<0) {
- if(super!=NULL)
- H5T_close(super);
- } /* end if */
+ if(ret_value < 0)
+ if(super && H5T_close(super) < 0)
+ HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "unable to release super datatype info")
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Tget_super() */
/*-------------------------------------------------------------------------
@@ -2323,15 +2322,15 @@ H5T_register(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst,
old_path->dst->shared->type!=dst->shared->type) {
continue;
}
- if ((tmp_sid = H5I_register(H5I_DATATYPE, H5T_copy(old_path->src, H5T_COPY_ALL)))<0 ||
- (tmp_did = H5I_register(H5I_DATATYPE, H5T_copy(old_path->dst, H5T_COPY_ALL)))<0)
+ if ((tmp_sid = H5I_register(H5I_DATATYPE, H5T_copy(old_path->src, H5T_COPY_ALL), FALSE))<0 ||
+ (tmp_did = H5I_register(H5I_DATATYPE, H5T_copy(old_path->dst, H5T_COPY_ALL), FALSE))<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register data types for conv query");
HDmemset(&cdata, 0, sizeof cdata);
cdata.command = H5T_CONV_INIT;
if ((func)(tmp_sid, tmp_did, &cdata, (size_t)0, (size_t)0, (size_t)0,
NULL, NULL, dxpl_id)<0) {
- H5I_dec_ref(tmp_sid);
- H5I_dec_ref(tmp_did);
+ H5I_dec_ref(tmp_sid, FALSE);
+ H5I_dec_ref(tmp_did, FALSE);
tmp_sid = tmp_did = -1;
H5E_clear_stack(NULL);
continue;
@@ -2368,11 +2367,11 @@ H5T_register(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst,
} /* end if */
H5T_close(old_path->src);
H5T_close(old_path->dst);
- H5FL_FREE(H5T_path_t,old_path);
+ old_path = H5FL_FREE(H5T_path_t, old_path);
/* Release temporary atoms */
- H5I_dec_ref(tmp_sid);
- H5I_dec_ref(tmp_did);
+ H5I_dec_ref(tmp_sid, FALSE);
+ H5I_dec_ref(tmp_did, FALSE);
tmp_sid = tmp_did = -1;
/* We don't care about any failures during the freeing process */
@@ -2381,18 +2380,18 @@ H5T_register(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst,
} /* end else */
done:
- if (ret_value<0) {
- if (new_path) {
- if (new_path->src)
+ if(ret_value < 0) {
+ if(new_path) {
+ if(new_path->src)
H5T_close(new_path->src);
- if (new_path->dst)
+ if(new_path->dst)
H5T_close(new_path->dst);
- H5FL_FREE(H5T_path_t,new_path);
+ new_path = H5FL_FREE(H5T_path_t, new_path);
} /* end if */
- if (tmp_sid>=0)
- H5I_dec_ref(tmp_sid);
- if (tmp_did>=0)
- H5I_dec_ref(tmp_did);
+ if(tmp_sid >= 0)
+ H5I_dec_ref(tmp_sid, FALSE);
+ if(tmp_did >= 0)
+ H5I_dec_ref(tmp_did, FALSE);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value);
@@ -2542,7 +2541,7 @@ H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst,
}
H5T_close(path->src);
H5T_close(path->dst);
- H5FL_FREE(H5T_path_t,path);
+ path = H5FL_FREE(H5T_path_t, path);
H5E_clear_stack(NULL); /*ignore all shutdown errors*/
} /* end else */
} /* end for */
@@ -2824,7 +2823,7 @@ H5Tdecode(const void *buf)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "can't decode object")
/* Register the type and return the ID */
- if((ret_value = H5I_register(H5I_DATATYPE, dt)) < 0)
+ if((ret_value = H5I_register(H5I_DATATYPE, dt, FALSE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register data type")
done:
@@ -2863,7 +2862,7 @@ H5T_encode(H5T_t *obj, unsigned char *buf, size_t *nalloc)
FUNC_ENTER_NOAPI_NOINIT(H5T_encode)
/* Allocate "fake" file structure */
- if(NULL == (f = H5F_fake_alloc((size_t)0)))
+ if(NULL == (f = H5F_fake_alloc((uint8_t)0)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "can't allocate fake file struct")
/* Find out the size of buffer needed */
@@ -2919,7 +2918,7 @@ H5T_decode(const unsigned char *buf)
FUNC_ENTER_NOAPI_NOINIT(H5T_decode)
/* Allocate "fake" file structure */
- if(NULL == (f = H5F_fake_alloc((size_t)0)))
+ if(NULL == (f = H5F_fake_alloc((uint8_t)0)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, NULL, "can't allocate fake file struct")
/* Decode the type of the information */
@@ -2931,9 +2930,13 @@ H5T_decode(const unsigned char *buf)
HGOTO_ERROR(H5E_DATATYPE, H5E_VERSION, NULL, "unknown version of encoded datatype")
/* Decode the serialized datatype message */
- if((ret_value = H5O_msg_decode(f, H5AC_dxpl_id, H5O_DTYPE_ID, buf)) == NULL)
+ if((ret_value = H5O_msg_decode(f, H5AC_dxpl_id, NULL, H5O_DTYPE_ID, buf)) == NULL)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL, "can't decode object")
+ /* Mark datatype as being in memory now */
+ if(H5T_set_loc(ret_value, NULL, H5T_LOC_MEMORY) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location")
+
done:
/* Release fake file structure */
if(f && H5F_fake_free(f) < 0)
@@ -2964,64 +2967,71 @@ done:
H5T_t *
H5T_create(H5T_class_t type, size_t size)
{
- H5T_t *dt = NULL;
- hid_t subtype;
- H5T_t *ret_value;
+ H5T_t *dt = NULL;
+ H5T_t *ret_value = NULL;
- FUNC_ENTER_NOAPI(H5T_create, NULL);
+ FUNC_ENTER_NOAPI(H5T_create, NULL)
- switch (type) {
+ switch(type) {
case H5T_INTEGER:
case H5T_FLOAT:
case H5T_TIME:
case H5T_STRING:
case H5T_BITFIELD:
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL, "type class is not appropriate - use H5Tcopy()");
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL, "type class is not appropriate - use H5Tcopy()")
case H5T_OPAQUE:
case H5T_COMPOUND:
if(NULL == (dt = H5T_alloc()))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
dt->shared->type = type;
- if(type==H5T_COMPOUND)
- dt->shared->u.compnd.packed=TRUE; /* Start out packed */
- else if(type==H5T_OPAQUE)
+ if(type == H5T_COMPOUND) {
+ dt->shared->u.compnd.packed=FALSE; /* Start out unpacked */
+ dt->shared->u.compnd.memb_size=0;
+ } /* end if */
+ else if(type == H5T_OPAQUE)
/* Initialize the tag in case it's not set later. A null tag will
* cause problems for later operations. */
dt->shared->u.opaque.tag = H5MM_strdup("");
break;
case H5T_ENUM:
- if (sizeof(char)==size) {
- subtype = H5T_NATIVE_SCHAR_g;
- } else if (sizeof(short)==size) {
- subtype = H5T_NATIVE_SHORT_g;
- } else if (sizeof(int)==size) {
- subtype = H5T_NATIVE_INT_g;
- } else if (sizeof(long)==size) {
- subtype = H5T_NATIVE_LONG_g;
- } else if (sizeof(long_long)==size) {
- subtype = H5T_NATIVE_LLONG_g;
- } else {
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "no applicable native integer type");
+ {
+ hid_t subtype;
+ H5T_t *sub_t_obj;
+
+ if(sizeof(char) == size)
+ subtype = H5T_NATIVE_SCHAR_g;
+ else if(sizeof(short) == size)
+ subtype = H5T_NATIVE_SHORT_g;
+ else if(sizeof(int) == size)
+ subtype = H5T_NATIVE_INT_g;
+ else if(sizeof(long) == size)
+ subtype = H5T_NATIVE_LONG_g;
+ else if(sizeof(long long) == size)
+ subtype = H5T_NATIVE_LLONG_g;
+ else
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "no applicable native integer type")
+ if(NULL == (dt = H5T_alloc()))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ dt->shared->type = type;
+ if(NULL == (sub_t_obj = (H5T_t *)H5I_object(subtype)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, NULL, "unable to get datatype object")
+ if(NULL == (dt->shared->parent = H5T_copy(sub_t_obj, H5T_COPY_ALL)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "unable to copy base datatype")
}
- if(NULL == (dt = H5T_alloc()))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- dt->shared->type = type;
- if (NULL==(dt->shared->parent=H5T_copy(H5I_object(subtype), H5T_COPY_ALL)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy base data type");
break;
case H5T_VLEN: /* Variable length datatype */
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL, "base type required - use H5Tvlen_create()");
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL, "base type required - use H5Tvlen_create()")
case H5T_ARRAY: /* Array datatype */
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL, "base type required - use H5Tarray_create2()");
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL, "base type required - use H5Tarray_create2()")
default:
- HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, NULL, "unknown data type class");
- }
+ HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, NULL, "unknown data type class")
+ } /* end switch */
dt->shared->size = size;
@@ -3029,15 +3039,15 @@ H5T_create(H5T_class_t type, size_t size)
ret_value = dt;
done:
- if(ret_value==NULL) {
- if(dt && (dt->shared != NULL))
- H5FL_FREE(H5T_shared_t, dt->shared);
- if(dt!=NULL)
- H5FL_FREE(H5T_t,dt);
+ if(NULL == ret_value) {
+ if(dt) {
+ dt->shared = H5FL_FREE(H5T_shared_t, dt->shared);
+ dt = H5FL_FREE(H5T_t, dt);
+ } /* end if */
} /* end if */
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_create() */
/*-------------------------------------------------------------------------
@@ -3170,115 +3180,122 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
break;
} /* end switch */
- /* Copy parent information, if we aren't sharing an already opened committed datatype */
- if(NULL == reopened_fo && old_dt->shared->parent)
- new_dt->shared->parent = H5T_copy(old_dt->shared->parent, method);
-
- switch(new_dt->shared->type) {
- case H5T_COMPOUND:
- {
- int accum_change = 0; /* Amount of change in the offset of the fields */
+ /* Update fields in the new struct, if we aren't sharing an already opened
+ * committed datatype */
+ if(!reopened_fo) {
+ /* Copy parent information */
+ if(old_dt->shared->parent)
+ new_dt->shared->parent = H5T_copy(old_dt->shared->parent, method);
- /*
- * Copy all member fields to new type, then overwrite the
- * name and type fields of each new member with copied values.
- * That is, H5T_copy() is a deep copy.
- */
- new_dt->shared->u.compnd.memb = H5MM_malloc(new_dt->shared->u.compnd.nalloc *
- sizeof(H5T_cmemb_t));
- if (NULL==new_dt->shared->u.compnd.memb)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
-
- HDmemcpy(new_dt->shared->u.compnd.memb, old_dt->shared->u.compnd.memb,
- new_dt->shared->u.compnd.nmembs * sizeof(H5T_cmemb_t));
-
- for(i = 0; i < new_dt->shared->u.compnd.nmembs; i++) {
- unsigned j;
- int old_match;
-
- s = new_dt->shared->u.compnd.memb[i].name;
- new_dt->shared->u.compnd.memb[i].name = H5MM_xstrdup(s);
- tmp = H5T_copy (old_dt->shared->u.compnd.memb[i].type, method);
- new_dt->shared->u.compnd.memb[i].type = tmp;
- HDassert(tmp != NULL);
-
- /* Apply the accumulated size change to the offset of the field */
- new_dt->shared->u.compnd.memb[i].offset += accum_change;
-
- if(old_dt->shared->u.compnd.sorted != H5T_SORT_VALUE) {
- for(old_match = -1, j = 0; j < old_dt->shared->u.compnd.nmembs; j++) {
- if(!HDstrcmp(new_dt->shared->u.compnd.memb[i].name, old_dt->shared->u.compnd.memb[j].name)) {
- old_match = j;
- break;
- } /* end if */
- } /* end for */
+ switch(new_dt->shared->type) {
+ case H5T_COMPOUND:
+ {
+ int accum_change = 0; /* Amount of change in the offset of the fields */
- /* check if we couldn't find a match */
- if(old_match < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "fields in datatype corrupted");
+ /*
+ * Copy all member fields to new type, then overwrite the
+ * name and type fields of each new member with copied values.
+ * That is, H5T_copy() is a deep copy.
+ */
+ /* Only malloc if space has been allocated for members - NAF */
+ if(new_dt->shared->u.compnd.nalloc > 0) {
+ new_dt->shared->u.compnd.memb = H5MM_malloc(new_dt->shared->u.compnd.nalloc *
+ sizeof(H5T_cmemb_t));
+ if (NULL==new_dt->shared->u.compnd.memb)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+
+ HDmemcpy(new_dt->shared->u.compnd.memb, old_dt->shared->u.compnd.memb,
+ new_dt->shared->u.compnd.nmembs * sizeof(H5T_cmemb_t));
} /* end if */
- else
- old_match = i;
- /* If the field changed size, add that change to the accumulated size change */
- if(new_dt->shared->u.compnd.memb[i].type->shared->size != old_dt->shared->u.compnd.memb[old_match].type->shared->size) {
- /* Adjust the size of the member */
- new_dt->shared->u.compnd.memb[i].size = (old_dt->shared->u.compnd.memb[old_match].size*tmp->shared->size)/old_dt->shared->u.compnd.memb[old_match].type->shared->size;
+ for(i = 0; i < new_dt->shared->u.compnd.nmembs; i++) {
+ unsigned j;
+ int old_match;
- accum_change += (new_dt->shared->u.compnd.memb[i].type->shared->size - old_dt->shared->u.compnd.memb[old_match].type->shared->size);
- } /* end if */
- } /* end for */
+ s = new_dt->shared->u.compnd.memb[i].name;
+ new_dt->shared->u.compnd.memb[i].name = H5MM_xstrdup(s);
+ tmp = H5T_copy (old_dt->shared->u.compnd.memb[i].type, method);
+ new_dt->shared->u.compnd.memb[i].type = tmp;
+ HDassert(tmp != NULL);
- /* Apply the accumulated size change to the size of the compound struct */
- new_dt->shared->size += accum_change;
+ /* Apply the accumulated size change to the offset of the field */
+ new_dt->shared->u.compnd.memb[i].offset += accum_change;
+
+ if(old_dt->shared->u.compnd.sorted != H5T_SORT_VALUE) {
+ for(old_match = -1, j = 0; j < old_dt->shared->u.compnd.nmembs; j++) {
+ if(!HDstrcmp(new_dt->shared->u.compnd.memb[i].name, old_dt->shared->u.compnd.memb[j].name)) {
+ old_match = j;
+ break;
+ } /* end if */
+ } /* end for */
+
+ /* check if we couldn't find a match */
+ if(old_match < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "fields in datatype corrupted");
+ } /* end if */
+ else
+ old_match = i;
- }
- break;
+ /* If the field changed size, add that change to the accumulated size change */
+ if(new_dt->shared->u.compnd.memb[i].type->shared->size != old_dt->shared->u.compnd.memb[old_match].type->shared->size) {
+ /* Adjust the size of the member */
+ new_dt->shared->u.compnd.memb[i].size = (old_dt->shared->u.compnd.memb[old_match].size*tmp->shared->size)/old_dt->shared->u.compnd.memb[old_match].type->shared->size;
- case H5T_ENUM:
- /*
- * Copy all member fields to new type, then overwrite the name fields
- * of each new member with copied values. That is, H5T_copy() is a
- * deep copy.
- */
- new_dt->shared->u.enumer.name = H5MM_malloc(new_dt->shared->u.enumer.nalloc *
- sizeof(char*));
- new_dt->shared->u.enumer.value = H5MM_malloc(new_dt->shared->u.enumer.nalloc *
- new_dt->shared->size);
- if(NULL == new_dt->shared->u.enumer.value)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- HDmemcpy(new_dt->shared->u.enumer.value, old_dt->shared->u.enumer.value,
- new_dt->shared->u.enumer.nmembs * new_dt->shared->size);
- for(i = 0; i < new_dt->shared->u.enumer.nmembs; i++) {
- s = old_dt->shared->u.enumer.name[i];
- new_dt->shared->u.enumer.name[i] = H5MM_xstrdup(s);
- } /* end for */
- break;
+ accum_change += (new_dt->shared->u.compnd.memb[i].type->shared->size - old_dt->shared->u.compnd.memb[old_match].type->shared->size);
+ } /* end if */
+ } /* end for */
- case H5T_VLEN:
- case H5T_REFERENCE:
- if(method == H5T_COPY_TRANSIENT || method == H5T_COPY_REOPEN) {
- /* H5T_copy converts any type into a memory type */
- if(H5T_set_loc(new_dt, NULL, H5T_LOC_MEMORY) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location");
- } /* end if */
- break;
+ /* Apply the accumulated size change to the size of the compound struct */
+ new_dt->shared->size += accum_change;
- case H5T_OPAQUE:
- /*
- * Copy the tag name.
- */
- new_dt->shared->u.opaque.tag = H5MM_xstrdup(new_dt->shared->u.opaque.tag);
- break;
+ }
+ break;
- case H5T_ARRAY:
- /* Re-compute the array's size, in case it's base type changed size */
- new_dt->shared->size=new_dt->shared->u.array.nelem*new_dt->shared->parent->shared->size;
- break;
+ case H5T_ENUM:
+ /*
+ * Copy all member fields to new type, then overwrite the name fields
+ * of each new member with copied values. That is, H5T_copy() is a
+ * deep copy.
+ */
+ new_dt->shared->u.enumer.name = H5MM_malloc(new_dt->shared->u.enumer.nalloc *
+ sizeof(char*));
+ new_dt->shared->u.enumer.value = H5MM_malloc(new_dt->shared->u.enumer.nalloc *
+ new_dt->shared->size);
+ if(NULL == new_dt->shared->u.enumer.value)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ HDmemcpy(new_dt->shared->u.enumer.value, old_dt->shared->u.enumer.value,
+ new_dt->shared->u.enumer.nmembs * new_dt->shared->size);
+ for(i = 0; i < new_dt->shared->u.enumer.nmembs; i++) {
+ s = old_dt->shared->u.enumer.name[i];
+ new_dt->shared->u.enumer.name[i] = H5MM_xstrdup(s);
+ } /* end for */
+ break;
- default:
- break;
- } /* end switch */
+ case H5T_VLEN:
+ case H5T_REFERENCE:
+ if(method == H5T_COPY_TRANSIENT || method == H5T_COPY_REOPEN) {
+ /* H5T_copy converts any type into a memory type */
+ if(H5T_set_loc(new_dt, NULL, H5T_LOC_MEMORY) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location");
+ } /* end if */
+ break;
+
+ case H5T_OPAQUE:
+ /*
+ * Copy the tag name.
+ */
+ new_dt->shared->u.opaque.tag = H5MM_xstrdup(new_dt->shared->u.opaque.tag);
+ break;
+
+ case H5T_ARRAY:
+ /* Re-compute the array's size, in case it's base type changed size */
+ new_dt->shared->size=new_dt->shared->u.array.nelem*new_dt->shared->parent->shared->size;
+ break;
+
+ default:
+ break;
+ } /* end switch */
+ } /* end if */
/* Set the cached location & name path if the original type was a named
* type and the new type is also named.
@@ -3312,10 +3329,11 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
done:
if(ret_value == NULL) {
- if(new_dt->shared != NULL)
- H5FL_FREE(H5T_shared_t, new_dt->shared);
- if(new_dt != NULL)
- H5FL_FREE(H5T_t, new_dt);
+ if(new_dt) {
+ if(new_dt->shared)
+ new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared);
+ new_dt = H5FL_FREE(H5T_t, new_dt);
+ } /* end if */
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -3407,8 +3425,8 @@ done:
if(ret_value == NULL)
if(dt) {
if(dt->shared)
- H5FL_FREE(H5T_shared_t, dt->shared);
- H5FL_FREE(H5T_t, dt);
+ dt->shared = H5FL_FREE(H5T_shared_t, dt->shared);
+ dt = H5FL_FREE(H5T_t, dt);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -3544,7 +3562,7 @@ H5T_close(H5T_t *dt)
if(H5T_free(dt) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free datatype");
- H5FL_FREE(H5T_shared_t, dt->shared);
+ dt->shared = H5FL_FREE(H5T_shared_t, dt->shared);
} else {
/*
* If a named type is being closed then close the object header and
@@ -3570,7 +3588,7 @@ H5T_close(H5T_t *dt)
} /* end else */
/* Free the datatype struct */
- H5FL_FREE(H5T_t,dt);
+ dt = H5FL_FREE(H5T_t, dt);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -3678,7 +3696,13 @@ H5T_set_size(H5T_t *dt, size_t size)
if(size<(max_offset+max_size))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "size shrinking will cut off last member ");
+
+ /* Compound must not have been packed previously */
+ /* We will check if resizing changed the packed state of
+ * this type at the end of this function */
+ HDassert(!dt->shared->u.compnd.packed);
}
+
break;
case H5T_STRING:
@@ -3754,6 +3778,10 @@ H5T_set_size(H5T_t *dt, size_t size)
dt->shared->u.atomic.prec = prec;
}
} /* end if */
+
+ /* Check if the new compound type is packed */
+ if(dt->shared->type == H5T_COMPOUND)
+ H5T_update_packed(dt);
}
done:
@@ -3806,84 +3834,85 @@ H5T_get_size(const H5T_t *dt)
* Programmer: Robb Matzke
* Wednesday, December 10, 1997
*
- * Modifications:
- * Robb Matzke, 22 Dec 1998
- * Able to compare enumeration data types.
- *
- * Robb Matzke, 20 May 1999
- * Compares bitfields and opaque types.
- *
- * Quincey Koziol, 19 Mar 2005
- * Allow an enumerated datatypes to compare equal, if the "superset"
- * flag is set and dt2 has a superset of the enumerated values in dt1
*-------------------------------------------------------------------------
*/
int
H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, hbool_t superset)
{
unsigned *idx1 = NULL, *idx2 = NULL;
- int ret_value = 0;
+ size_t base_size;
+ hbool_t swapped;
int i, j;
unsigned u;
int tmp;
- hbool_t swapped;
- size_t base_size;
+ int ret_value = 0;
- FUNC_ENTER_NOAPI(H5T_cmp, 0);
+ FUNC_ENTER_NOAPI(H5T_cmp, 0)
+ /* Sanity check */
+ HDassert(dt1);
+ HDassert(dt2);
+
/* the easy case */
- if (dt1 == dt2) HGOTO_DONE(0);
- assert(dt1);
- assert(dt2);
+ if(dt1 == dt2)
+ HGOTO_DONE(0);
/* compare */
- if (dt1->shared->type < dt2->shared->type) HGOTO_DONE(-1);
- if (dt1->shared->type > dt2->shared->type) HGOTO_DONE(1);
-
- if (dt1->shared->size < dt2->shared->size) HGOTO_DONE(-1);
- if (dt1->shared->size > dt2->shared->size) HGOTO_DONE(1);
-
- if (dt1->shared->parent && !dt2->shared->parent) HGOTO_DONE(-1);
- if (!dt1->shared->parent && dt2->shared->parent) HGOTO_DONE(1);
- if (dt1->shared->parent) {
+ if(dt1->shared->type < dt2->shared->type)
+ HGOTO_DONE(-1);
+ if(dt1->shared->type > dt2->shared->type)
+ HGOTO_DONE(1);
+
+ if(dt1->shared->size < dt2->shared->size)
+ HGOTO_DONE(-1);
+ if(dt1->shared->size > dt2->shared->size)
+ HGOTO_DONE(1);
+
+ if(dt1->shared->parent && !dt2->shared->parent)
+ HGOTO_DONE(-1);
+ if(!dt1->shared->parent && dt2->shared->parent)
+ HGOTO_DONE(1);
+ if(dt1->shared->parent) {
tmp = H5T_cmp(dt1->shared->parent, dt2->shared->parent, superset);
- if (tmp<0) HGOTO_DONE(-1);
- if (tmp>0) HGOTO_DONE(1);
- }
+ if(tmp < 0)
+ HGOTO_DONE(-1);
+ if(tmp > 0)
+ HGOTO_DONE(1);
+ } /* end if */
switch(dt1->shared->type) {
case H5T_COMPOUND:
/*
* Compound data types...
*/
- if (dt1->shared->u.compnd.nmembs < dt2->shared->u.compnd.nmembs)
+ if(dt1->shared->u.compnd.nmembs < dt2->shared->u.compnd.nmembs)
HGOTO_DONE(-1);
- if (dt1->shared->u.compnd.nmembs > dt2->shared->u.compnd.nmembs)
+ if(dt1->shared->u.compnd.nmembs > dt2->shared->u.compnd.nmembs)
HGOTO_DONE(1);
/* Build an index for each type so the names are sorted */
- if (NULL==(idx1 = H5MM_malloc(dt1->shared->u.compnd.nmembs * sizeof(unsigned))) ||
- NULL==(idx2 = H5MM_malloc(dt2->shared->u.compnd.nmembs * sizeof(unsigned))))
+ if(NULL == (idx1 = H5MM_malloc(dt1->shared->u.compnd.nmembs * sizeof(unsigned))) ||
+ NULL == (idx2 = H5MM_malloc(dt2->shared->u.compnd.nmembs * sizeof(unsigned))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed");
- for (u=0; u<dt1->shared->u.compnd.nmembs; u++)
+ for(u = 0; u < dt1->shared->u.compnd.nmembs; u++)
idx1[u] = idx2[u] = u;
if(dt1->shared->u.enumer.nmembs > 1) {
- for (i=dt1->shared->u.compnd.nmembs-1, swapped=TRUE; swapped && i>=0; --i)
- for (j=0, swapped=FALSE; j<i; j++)
- if (HDstrcmp(dt1->shared->u.compnd.memb[idx1[j]].name,
- dt1->shared->u.compnd.memb[idx1[j+1]].name) > 0) {
+ for(i = dt1->shared->u.compnd.nmembs - 1, swapped = TRUE; swapped && i >= 0; --i)
+ for(j = 0, swapped=FALSE; j < i; j++)
+ if(HDstrcmp(dt1->shared->u.compnd.memb[idx1[j]].name,
+ dt1->shared->u.compnd.memb[idx1[j + 1]].name) > 0) {
tmp = idx1[j];
- idx1[j] = idx1[j+1];
- idx1[j+1] = tmp;
+ idx1[j] = idx1[j + 1];
+ idx1[j + 1] = tmp;
swapped = TRUE;
}
- for (i=dt2->shared->u.compnd.nmembs-1, swapped=TRUE; swapped && i>=0; --i)
- for (j=0, swapped=FALSE; j<i; j++)
- if (HDstrcmp(dt2->shared->u.compnd.memb[idx2[j]].name,
- dt2->shared->u.compnd.memb[idx2[j+1]].name) > 0) {
+ for(i = dt2->shared->u.compnd.nmembs - 1, swapped = TRUE; swapped && i >= 0; --i)
+ for(j = 0, swapped = FALSE; j<i; j++)
+ if(HDstrcmp(dt2->shared->u.compnd.memb[idx2[j]].name,
+ dt2->shared->u.compnd.memb[idx2[j + 1]].name) > 0) {
tmp = idx2[j];
- idx2[j] = idx2[j+1];
- idx2[j+1] = tmp;
+ idx2[j] = idx2[j + 1];
+ idx2[j + 1] = tmp;
swapped = TRUE;
}
} /* end if */
@@ -4031,8 +4060,8 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, hbool_t superset)
case H5T_VLEN:
assert(dt1->shared->u.vlen.type>H5T_VLEN_BADTYPE && dt1->shared->u.vlen.type<H5T_VLEN_MAXTYPE);
assert(dt2->shared->u.vlen.type>H5T_VLEN_BADTYPE && dt2->shared->u.vlen.type<H5T_VLEN_MAXTYPE);
- assert(dt1->shared->u.vlen.loc>H5T_LOC_BADLOC && dt1->shared->u.vlen.loc<H5T_LOC_MAXLOC);
- assert(dt2->shared->u.vlen.loc>H5T_LOC_BADLOC && dt2->shared->u.vlen.loc<H5T_LOC_MAXLOC);
+ assert(dt1->shared->u.vlen.loc>=H5T_LOC_BADLOC && dt1->shared->u.vlen.loc<H5T_LOC_MAXLOC);
+ assert(dt2->shared->u.vlen.loc>=H5T_LOC_BADLOC && dt2->shared->u.vlen.loc<H5T_LOC_MAXLOC);
/* Arbitrarily sort sequence VL datatypes before string VL datatypes */
if (dt1->shared->u.vlen.type==H5T_VLEN_SEQUENCE &&
@@ -4049,7 +4078,11 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, hbool_t superset)
} else if (dt1->shared->u.vlen.loc==H5T_LOC_DISK &&
dt2->shared->u.vlen.loc==H5T_LOC_MEMORY) {
HGOTO_DONE(1);
+ } else if (dt1->shared->u.vlen.loc==H5T_LOC_BADLOC &&
+ dt2->shared->u.vlen.loc!=H5T_LOC_BADLOC) {
+ HGOTO_DONE(1);
}
+
/* Don't allow VL types in different files to compare as equal */
if (dt1->shared->u.vlen.f < dt2->shared->u.vlen.f)
HGOTO_DONE(-1);
@@ -4198,13 +4231,13 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, hbool_t superset)
} /* end switch */
done:
- if(idx1!=NULL)
+ if(NULL != idx1)
H5MM_xfree(idx1);
- if(idx2!=NULL)
+ if(NULL != idx2)
H5MM_xfree(idx2);
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_cmp() */
/*-------------------------------------------------------------------------
@@ -4246,48 +4279,47 @@ done:
*/
H5T_path_t *
H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name,
- H5T_conv_t func, hid_t dxpl_id, hbool_t is_api)
+ H5T_conv_t func, hid_t dxpl_id, hbool_t is_api)
{
int lt, rt; /*left and right edges */
int md; /*middle */
int cmp; /*comparison result */
int old_npaths; /* Previous number of paths in table */
- H5T_path_t *table=NULL; /*path existing in the table */
- H5T_path_t *path=NULL; /*new path */
- H5T_path_t *ret_value; /*return value */
- hid_t src_id=-1, dst_id=-1; /*src and dst type identifiers */
+ H5T_path_t *table = NULL; /*path existing in the table */
+ H5T_path_t *path = NULL; /*new path */
+ hid_t src_id = -1, dst_id = -1; /*src and dst type identifiers */
int i; /*counter */
- int nprint=0; /*lines of output printed */
+ int nprint = 0; /*lines of output printed */
+ H5T_path_t *ret_value; /*return value */
FUNC_ENTER_NOAPI(H5T_path_find, NULL);
- assert((!src && !dst) || (src && dst));
+ /* Sanity check */
+ HDassert(src);
+ HDassert(dst);
/*
* Make sure the first entry in the table is the no-op conversion path.
*/
- if (0==H5T_g.npaths) {
- if (NULL==(H5T_g.path=H5MM_malloc(128*sizeof(H5T_path_t*))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for type conversion path table");
+ if(0 == H5T_g.npaths) {
+ if(NULL == (H5T_g.path = H5MM_malloc(128 * sizeof(H5T_path_t *))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for type conversion path table")
H5T_g.apaths = 128;
- if (NULL==(H5T_g.path[0]=H5FL_CALLOC(H5T_path_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for no-op conversion path");
+ if(NULL == (H5T_g.path[0] = H5FL_CALLOC(H5T_path_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for no-op conversion path")
HDstrcpy(H5T_g.path[0]->name, "no-op");
H5T_g.path[0]->func = H5T_conv_noop;
H5T_g.path[0]->cdata.command = H5T_CONV_INIT;
- if (H5T_conv_noop(FAIL, FAIL, &(H5T_g.path[0]->cdata),
- (size_t)0, (size_t)0, (size_t)0, NULL, NULL, dxpl_id)<0) {
+ if(H5T_conv_noop(FAIL, FAIL, &(H5T_g.path[0]->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL, dxpl_id) < 0) {
#ifdef H5T_DEBUG
- if (H5DEBUG(T)) {
- fprintf(H5DEBUG(T), "H5T: unable to initialize no-op "
- "conversion function (ignored)\n");
- }
+ if(H5DEBUG(T))
+ fprintf(H5DEBUG(T), "H5T: unable to initialize no-op conversion function (ignored)\n");
#endif
H5E_clear_stack(NULL); /*ignore the error*/
- }
+ } /* end if */
H5T_g.path[0]->is_noop = TRUE;
H5T_g.npaths = 1;
- }
+ } /* end if */
/*
* Find the conversion path. If source and destination types are equal
@@ -4298,35 +4330,36 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name,
* Only allow the no-op conversion to occur if no "force conversion" flags
* are set
*/
- if (src->shared->force_conv==FALSE && dst->shared->force_conv==FALSE && 0==H5T_cmp(src, dst, TRUE)) {
+ if(src->shared->force_conv == FALSE && dst->shared->force_conv == FALSE && 0 == H5T_cmp(src, dst, TRUE)) {
table = H5T_g.path[0];
cmp = 0;
md = 0;
- } else {
+ } /* end if */
+ else {
lt = md = 1;
rt = H5T_g.npaths;
cmp = -1;
- while (cmp && lt<rt) {
- md = (lt+rt) / 2;
- assert(H5T_g.path[md]);
+ while(cmp && lt < rt) {
+ md = (lt + rt) / 2;
+ HDassert(H5T_g.path[md]);
cmp = H5T_cmp(src, H5T_g.path[md]->src, FALSE);
- if (0==cmp) cmp = H5T_cmp(dst, H5T_g.path[md]->dst, FALSE);
- if (cmp<0) {
+ if(0 == cmp)
+ cmp = H5T_cmp(dst, H5T_g.path[md]->dst, FALSE);
+ if(cmp < 0)
rt = md;
- } else if (cmp>0) {
- lt = md+1;
- } else {
+ else if(cmp > 0)
+ lt = md + 1;
+ else
table = H5T_g.path[md];
- }
- }
- }
+ } /* end while */
+ } /* end else */
/* Keep a record of the number of paths in the table, in case one of the
* initialization calls below (hard or soft) causes more entries to be
* added to the table - QAK, 1/26/02
*/
- old_npaths=H5T_g.npaths;
+ old_npaths = H5T_g.npaths;
/*
* If we didn't find the path, if the caller is an API function specifying
@@ -4334,21 +4367,22 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name,
* specifying a new hard conversion and the path is a soft conversion, then
* create a new path and add the new function to the path.
*/
- if (!table || (table && func && is_api) || (table && !table->is_hard && func && !is_api)) {
- if (NULL==(path=H5FL_CALLOC(H5T_path_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for type conversion path");
- if (name && *name) {
+ if(!table || (table && func && is_api) || (table && !table->is_hard && func && !is_api)) {
+ if(NULL == (path = H5FL_CALLOC(H5T_path_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for type conversion path")
+ if(name && *name) {
HDstrncpy(path->name, name, (size_t)H5T_NAMELEN);
- path->name[H5T_NAMELEN-1] = '\0';
- } else {
+ path->name[H5T_NAMELEN - 1] = '\0';
+ } /* end if */
+ else
HDstrcpy(path->name, "NONAME");
- }
- if ((src && NULL==(path->src=H5T_copy(src, H5T_COPY_ALL))) ||
- (dst && NULL==(path->dst=H5T_copy(dst, H5T_COPY_ALL))))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy data type for conversion path");
- } else {
+ if(NULL == (path->src = H5T_copy(src, H5T_COPY_ALL)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy datatype for conversion path")
+ if(NULL == (path->dst = H5T_copy(dst, H5T_COPY_ALL)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy datatype for conversion path")
+ } /* end if */
+ else
path = table;
- }
/*
* If a hard conversion function is specified and none is defined for the
@@ -4356,25 +4390,24 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name,
* the existing path is a soft function, then add the new conversion to the path
* and initialize its conversion data.
*/
- if (func && (!table || (table && is_api) || (table && !table->is_hard && !is_api))) {
- assert(path!=table);
- assert(NULL==path->func);
- if (path->src && (src_id=H5I_register(H5I_DATATYPE,
- H5T_copy(path->src, H5T_COPY_ALL)))<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register source conversion type for query");
- if (path->dst && (dst_id=H5I_register(H5I_DATATYPE,
- H5T_copy(path->dst, H5T_COPY_ALL)))<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register destination conversion type for query");
+ if(func && (!table || (table && is_api) || (table && !table->is_hard && !is_api))) {
+ HDassert(path != table);
+ HDassert(NULL == path->func);
+ if(path->src && (src_id = H5I_register(H5I_DATATYPE, H5T_copy(path->src, H5T_COPY_ALL), FALSE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register source conversion type for query")
+ if(path->dst && (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(path->dst, H5T_COPY_ALL), FALSE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register destination conversion type for query")
path->cdata.command = H5T_CONV_INIT;
- if ((func)(src_id, dst_id, &(path->cdata), (size_t)0, (size_t)0, (size_t)0,
- NULL, NULL, dxpl_id)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to initialize conversion function");
- if (src_id>=0) H5I_dec_ref(src_id);
- if (dst_id>=0) H5I_dec_ref(dst_id);
+ if((func)(src_id, dst_id, &(path->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to initialize conversion function")
+ if(src_id >= 0)
+ H5I_dec_ref(src_id, FALSE);
+ if(dst_id >= 0)
+ H5I_dec_ref(dst_id, FALSE);
src_id = dst_id = -1;
path->func = func;
path->is_hard = TRUE;
- }
+ } /* end if */
/*
* If the path doesn't have a function by now (because it's a new path
@@ -4382,116 +4415,118 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name,
* for an applicable function and add it to the path. This can't happen
* for the no-op conversion path.
*/
- assert(path->func || (src && dst));
- for (i=H5T_g.nsoft-1; i>=0 && !path->func; --i) {
- if (src->shared->type!=H5T_g.soft[i].src ||
- dst->shared->type!=H5T_g.soft[i].dst) {
+ HDassert(path->func || (src && dst));
+ for(i = H5T_g.nsoft - 1; i >= 0 && !path->func; --i) {
+ if(src->shared->type != H5T_g.soft[i].src || dst->shared->type != H5T_g.soft[i].dst)
continue;
- }
- if ((src_id=H5I_register(H5I_DATATYPE,
- H5T_copy(path->src, H5T_COPY_ALL)))<0 ||
- (dst_id=H5I_register(H5I_DATATYPE,
- H5T_copy(path->dst, H5T_COPY_ALL)))<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register conversion types for query");
+ if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(path->src, H5T_COPY_ALL), FALSE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register src conversion type for query")
+ if((dst_id = H5I_register(H5I_DATATYPE, H5T_copy(path->dst, H5T_COPY_ALL), FALSE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register dst conversion type for query")
path->cdata.command = H5T_CONV_INIT;
- if ((H5T_g.soft[i].func) (src_id, dst_id, &(path->cdata),
- (size_t)0, (size_t)0, (size_t)0, NULL, NULL, dxpl_id)<0) {
- HDmemset (&(path->cdata), 0, sizeof(H5T_cdata_t));
+ if((H5T_g.soft[i].func)(src_id, dst_id, &(path->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL, dxpl_id) < 0) {
+ HDmemset(&(path->cdata), 0, sizeof(H5T_cdata_t));
H5E_clear_stack(NULL); /*ignore the error*/
- } else {
- HDstrcpy (path->name, H5T_g.soft[i].name);
+ } /* end if */
+ else {
+ HDstrcpy(path->name, H5T_g.soft[i].name);
path->func = H5T_g.soft[i].func;
path->is_hard = FALSE;
- }
- H5I_dec_ref(src_id);
- H5I_dec_ref(dst_id);
+ } /* end else */
+ H5I_dec_ref(src_id, FALSE);
+ H5I_dec_ref(dst_id, FALSE);
src_id = dst_id = -1;
- }
- if (!path->func)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "no appropriate function for conversion path");
+ } /* end for */
+ if(!path->func)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "no appropriate function for conversion path")
/* Check if paths were inserted into the table through a recursive call
* and re-compute the correct location for this path if so. - QAK, 1/26/02
*/
- if(old_npaths!=H5T_g.npaths) {
+ if(old_npaths != H5T_g.npaths) {
lt = md = 1;
rt = H5T_g.npaths;
cmp = -1;
- while (cmp && lt<rt) {
- md = (lt+rt) / 2;
- assert(H5T_g.path[md]);
+ while(cmp && lt < rt) {
+ md = (lt + rt) / 2;
+ HDassert(H5T_g.path[md]);
cmp = H5T_cmp(src, H5T_g.path[md]->src, FALSE);
- if (0==cmp) cmp = H5T_cmp(dst, H5T_g.path[md]->dst, FALSE);
- if (cmp<0) {
+ if(0 == cmp)
+ cmp = H5T_cmp(dst, H5T_g.path[md]->dst, FALSE);
+ if(cmp < 0)
rt = md;
- } else if (cmp>0) {
- lt = md+1;
- } else {
+ else if(cmp > 0)
+ lt = md + 1;
+ else
table = H5T_g.path[md];
- }
- }
+ } /* end while */
} /* end if */
/* Replace an existing table entry or add a new entry */
- if (table && path!=table) {
- assert(table==H5T_g.path[md]);
+ if(table && path != table) {
+ HDassert(table == H5T_g.path[md]);
H5T_print_stats(table, &nprint/*in,out*/);
table->cdata.command = H5T_CONV_FREE;
- if ((table->func)(FAIL, FAIL, &(table->cdata), (size_t)0, (size_t)0, (size_t)0,
- NULL, NULL, dxpl_id)<0) {
+ if((table->func)(FAIL, FAIL, &(table->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL, dxpl_id) < 0) {
#ifdef H5T_DEBUG
- if (H5DEBUG(T)) {
+ if(H5DEBUG(T)) {
fprintf(H5DEBUG(T), "H5T: conversion function 0x%08lx free "
"failed for %s (ignored)\n",
(unsigned long)(path->func), path->name);
- }
+ } /* end if */
#endif
H5E_clear_stack(NULL); /*ignore the failure*/
- }
- if (table->src) H5T_close(table->src);
- if (table->dst) H5T_close(table->dst);
- H5FL_FREE(H5T_path_t,table);
+ } /* end if */
+ if(table->src)
+ H5T_close(table->src);
+ if(table->dst)
+ H5T_close(table->dst);
+ table = H5FL_FREE(H5T_path_t, table);
table = path;
H5T_g.path[md] = path;
- } else if (path!=table) {
- assert(cmp);
- if (H5T_g.npaths >= H5T_g.apaths) {
+ } else if(path != table) {
+ HDassert(cmp);
+ if(H5T_g.npaths >= H5T_g.apaths) {
size_t na = MAX(128, 2 * H5T_g.apaths);
- H5T_path_t **x = H5MM_realloc (H5T_g.path,
- na*sizeof(H5T_path_t*));
- if (!x)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ H5T_path_t **x = H5MM_realloc (H5T_g.path, na * sizeof(H5T_path_t*));
+
+ if(!x)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
H5T_g.apaths = (int)na;
H5T_g.path = x;
- }
- if (cmp>0) md++;
- HDmemmove(H5T_g.path+md+1, H5T_g.path+md,
- (H5T_g.npaths-md) * sizeof(H5T_path_t*));
+ } /* end if */
+ if(cmp > 0)
+ md++;
+ HDmemmove(H5T_g.path + md + 1, H5T_g.path + md, (H5T_g.npaths - md) * sizeof(H5T_path_t*));
H5T_g.npaths++;
H5T_g.path[md] = path;
table = path;
- }
+ } /* end else-if */
/* Set the flag to indicate both source and destination types are compound types
- * for the optimization of data reading (in H5Dio.c). */
- if(H5T_COMPOUND==H5T_get_class(src, TRUE) && H5T_COMPOUND==H5T_get_class(dst, TRUE))
+ * for the optimization of data reading (in H5Dio.c). */
+ if(H5T_COMPOUND == H5T_get_class(src, TRUE) && H5T_COMPOUND == H5T_get_class(dst, TRUE))
path->are_compounds = TRUE;
/* Set return value */
ret_value = path;
done:
- if (!ret_value && path && path!=table) {
- if (path->src) H5T_close(path->src);
- if (path->dst) H5T_close(path->dst);
- H5FL_FREE(H5T_path_t,path);
- }
- if (src_id>=0) H5I_dec_ref(src_id);
- if (dst_id>=0) H5I_dec_ref(dst_id);
+ if(!ret_value && path && path != table) {
+ if(path->src)
+ H5T_close(path->src);
+ if(path->dst)
+ H5T_close(path->dst);
+ path = H5FL_FREE(H5T_path_t, path);
+ } /* end if */
+ if(src_id >= 0)
+ H5I_dec_ref(src_id, FALSE);
+ if(dst_id >= 0)
+ H5I_dec_ref(dst_id, FALSE);
FUNC_LEAVE_NOAPI(ret_value);
-}
+} /* end H5T_path_find() */
/*-------------------------------------------------------------------------
@@ -4526,8 +4561,8 @@ H5T_path_noop(const H5T_path_t *p)
* Function: H5T_path_compound_subset
*
* Purpose: Checks if the source and destination types are both compound.
- * Tells whether whether the source members are a subset of
- * destination, and the order is the same, and no conversion
+ * Tells whether whether the source members are a subset of
+ * destination, and the order is the same, and no conversion
* is needed. For example:
* struct source { struct destination {
* TYPE1 A; --> TYPE1 A;
@@ -4537,19 +4572,23 @@ H5T_path_noop(const H5T_path_t *p)
* TYPE5 E;
* };
*
- * Return: One of the values of H5T_subset_t (can't fail).
+ * Return: A pointer to the subset info struct in p, or NULL if there are
+ * no compounds. Points directly into the H5T_path_t structure.
*
* Programmer: Raymond Lu
* 8 June 2007
*
- * Modifications:
+ * Modifications: Neil Fortner
+ * 19 September 2008
+ * Changed return value to H5T_subset_info_t
+ * (to allow it to return copy_size)
*
*-------------------------------------------------------------------------
*/
-H5T_subset_t
+H5T_subset_info_t *
H5T_path_compound_subset(const H5T_path_t *p)
{
- H5T_subset_t ret_value = FALSE;
+ H5T_subset_info_t *ret_value = NULL;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_path_compound_subset);
@@ -4967,7 +5006,7 @@ H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc)
FUNC_ENTER_NOAPI(H5T_set_loc, FAIL);
assert(dt);
- assert(loc>H5T_LOC_BADLOC && loc<H5T_LOC_MAXLOC);
+ assert(loc>=H5T_LOC_BADLOC && loc<H5T_LOC_MAXLOC);
/* Datatypes can't change in size if the force_conv flag is not set */
if(dt->shared->force_conv) {
@@ -5106,7 +5145,7 @@ H5T_is_relocatable(const H5T_t *dt)
HDassert(dt);
/* VL and reference datatypes are relocatable */
- if(H5T_detect_class(dt, H5T_VLEN) || H5T_detect_class(dt, H5T_REFERENCE))
+ if(H5T_detect_class(dt, H5T_VLEN, FALSE) || H5T_detect_class(dt, H5T_REFERENCE, FALSE))
ret_value = TRUE;
done:
@@ -5150,6 +5189,11 @@ H5T_upgrade_version_cb(H5T_t *dt, void *op_value)
dt->shared->version = *(unsigned *)op_value;
break;
+ case H5T_VLEN:
+ if(dt->shared->parent->shared->version > dt->shared->version)
+ dt->shared->version = dt->shared->parent->shared->version;
+ break;
+
default:
break;
} /* end switch */
diff --git a/src/H5Tarray.c b/src/H5Tarray.c
index 00f1177..f7cddb9 100644
--- a/src/H5Tarray.c
+++ b/src/H5Tarray.c
@@ -18,17 +18,65 @@
* the H5T interface.
*/
+/****************/
+/* Module Setup */
+/****************/
+
#define H5T_PACKAGE /*suppress error about including H5Tpkg */
/* Interface initialization */
#define H5_INTERFACE_INIT_FUNC H5T_init_array_interface
+/***********/
+/* Headers */
+/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5Iprivate.h" /* IDs */
#include "H5Tpkg.h" /* Datatypes */
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Public Variables */
+/*********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
/*--------------------------------------------------------------------------
NAME
@@ -46,16 +94,16 @@ DESCRIPTION
static herr_t
H5T_init_array_interface(void)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_init_array_interface);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_init_array_interface)
- FUNC_LEAVE_NOAPI(H5T_init());
+ FUNC_LEAVE_NOAPI(H5T_init())
} /* H5T_init_array_interface() */
/*-------------------------------------------------------------------------
* Function: H5Tarray_create2
*
- * Purpose: Create a new array data type based on the specified BASE_TYPE.
+ * Purpose: Create a new array datatype based on the specified BASE_TYPE.
* The type is an array with NDIMS dimensionality and the size of the
* array is DIMS. The total member size should be relatively small.
* Array datatypes are currently limited to H5S_MAX_RANK number of
@@ -63,7 +111,7 @@ H5T_init_array_interface(void)
* 0. (i.e. 0 > ndims <= H5S_MAX_RANK) All dimensions sizes must be greater
* than 0 also.
*
- * Return: Success: ID of new array data type
+ * Return: Success: ID of new array datatype
* Failure: Negative
*
* Programmer: Quincey Koziol
@@ -74,8 +122,8 @@ H5T_init_array_interface(void)
hid_t
H5Tarray_create2(hid_t base_id, unsigned ndims, const hsize_t dim[/* ndims */])
{
- H5T_t *base; /* base data type */
- H5T_t *dt; /* new array data type */
+ H5T_t *base; /* base datatype */
+ H5T_t *dt = NULL; /* new array datatype */
unsigned u; /* local index variable */
hid_t ret_value; /* return value */
@@ -90,18 +138,23 @@ H5Tarray_create2(hid_t base_id, unsigned ndims, const hsize_t dim[/* ndims */])
for(u = 0; u < ndims; u++)
if(!(dim[u] > 0))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "zero-sized dimension specified")
- if(NULL == (base = H5I_object_verify(base_id, H5I_DATATYPE)))
+ if(NULL == (base = (H5T_t *)H5I_object_verify(base_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype")
- /* Create the actual array datatype */
- if((dt = H5T_array_create(base, ndims, dim)) == NULL)
+ /* Create the array datatype */
+ if(NULL == (dt = H5T_array_create(base, ndims, dim)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to create datatype")
/* Atomize the type */
- if((ret_value = H5I_register(H5I_DATATYPE, dt)) < 0)
+ if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype")
done:
+ if(ret_value < 0) {
+ if(dt && H5T_close(dt) < 0)
+ HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "can't release datatype")
+ } /* end if */
+
FUNC_LEAVE_API(ret_value)
} /* end H5Tarray_create2() */
@@ -183,14 +236,14 @@ done:
int
H5Tget_array_ndims(hid_t type_id)
{
- H5T_t *dt; /* pointer to array data type */
+ H5T_t *dt; /* pointer to array datatype */
int ret_value; /* return value */
FUNC_ENTER_API(H5Tget_array_ndims, FAIL)
H5TRACE1("Is", "i", type_id);
/* Check args */
- if(NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
if(dt->shared->type != H5T_ARRAY)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an array datatype")
@@ -253,7 +306,7 @@ H5Tget_array_dims2(hid_t type_id, hsize_t dims[])
H5TRACE2("Is", "i*h", type_id, dims);
/* Check args */
- if(NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
if(dt->shared->type != H5T_ARRAY)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an array datatype")
@@ -308,7 +361,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5Tarray_create1
*
- * Purpose: Create a new array data type based on the specified BASE_TYPE.
+ * Purpose: Create a new array datatype based on the specified BASE_TYPE.
* The type is an array with NDIMS dimensionality and the size of the
* array is DIMS. The total member size should be relatively small.
* Array datatypes are currently limited to H5S_MAX_RANK number of
@@ -316,7 +369,7 @@ done:
* 0. (i.e. 0 > ndims <= H5S_MAX_RANK) All dimensions sizes must be greater
* than 0 also.
*
- * Return: Success: ID of new array data type
+ * Return: Success: ID of new array datatype
* Failure: Negative
*
* Programmer: Quincey Koziol
@@ -328,8 +381,8 @@ hid_t
H5Tarray_create1(hid_t base_id, int ndims, const hsize_t dim[/* ndims */],
const int UNUSED perm[/* ndims */])
{
- H5T_t *base; /* base data type */
- H5T_t *dt; /* new array data type */
+ H5T_t *base; /* base datatype */
+ H5T_t *dt = NULL; /* new array datatype */
unsigned u; /* local index variable */
hid_t ret_value; /* return value */
@@ -344,18 +397,23 @@ H5Tarray_create1(hid_t base_id, int ndims, const hsize_t dim[/* ndims */],
for(u = 0; u < (unsigned)ndims; u++)
if(!(dim[u] > 0))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "zero-sized dimension specified")
- if(NULL == (base = H5I_object_verify(base_id, H5I_DATATYPE)))
+ if(NULL == (base = (H5T_t *)H5I_object_verify(base_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype")
- /* Create the actual array datatype */
- if((dt = H5T_array_create(base, (unsigned)ndims, dim)) == NULL)
+ /* Create the array datatype */
+ if(NULL == (dt = H5T_array_create(base, (unsigned)ndims, dim)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to create datatype")
/* Atomize the type */
- if((ret_value = H5I_register(H5I_DATATYPE, dt)) < 0)
+ if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype")
done:
+ if(ret_value < 0) {
+ if(dt && H5T_close(dt) < 0)
+ HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "can't release datatype")
+ } /* end if */
+
FUNC_LEAVE_API(ret_value)
} /* end H5Tarray_create1() */
@@ -376,14 +434,14 @@ done:
int
H5Tget_array_dims1(hid_t type_id, hsize_t dims[], int UNUSED perm[])
{
- H5T_t *dt; /* pointer to array data type */
+ H5T_t *dt; /* Array datatype to query */
int ret_value; /* return value */
FUNC_ENTER_API(H5Tget_array_dims1, FAIL)
H5TRACE3("Is", "i*h*Is", type_id, dims, perm);
/* Check args */
- if(NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
if(dt->shared->type != H5T_ARRAY)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an array datatype")
@@ -391,9 +449,9 @@ H5Tget_array_dims1(hid_t type_id, hsize_t dims[], int UNUSED perm[])
/* Retrieve the sizes of the dimensions */
if((ret_value = H5T_get_array_dims(dt, dims)) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unable to get dimension sizes")
+
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Tget_array_dims1() */
-
#endif /* H5_NO_DEPRECATED_SYMBOLS */
diff --git a/src/H5Tbit.c b/src/H5Tbit.c
index 948a6eb..a5340a6 100644
--- a/src/H5Tbit.c
+++ b/src/H5Tbit.c
@@ -395,10 +395,10 @@ H5T_bit_set (uint8_t *buf, size_t offset, size_t size, hbool_t value)
*-------------------------------------------------------------------------
*/
ssize_t
-H5T_bit_find (uint8_t *buf, size_t offset, size_t size, H5T_sdir_t direction,
+H5T_bit_find(uint8_t *buf, size_t offset, size_t size, H5T_sdir_t direction,
hbool_t value)
{
- ssize_t base=(ssize_t)offset;
+ ssize_t base = (ssize_t)offset;
ssize_t idx, i;
size_t iu;
ssize_t ret_value=(-1); /* Return value */
@@ -407,78 +407,81 @@ H5T_bit_find (uint8_t *buf, size_t offset, size_t size, H5T_sdir_t direction,
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_bit_find);
/* Some functions call this with value=TRUE */
- assert (TRUE==1);
-
- switch (direction) {
- case H5T_BIT_LSB:
- /* Calculate index */
- idx = (ssize_t)(offset / 8);
- offset %= 8;
-
- /* Beginning */
- if (offset) {
- for (iu=offset; iu<8 && size>0; iu++, size--) {
- if (value==(hbool_t)((buf[idx]>>iu) & 0x01))
- HGOTO_DONE(8*idx+(ssize_t)iu - base);
- }
- offset = 0;
- idx++;
- }
- /* Middle */
- while (size>=8) {
- if ((value?0x00:0xff)!=buf[idx]) {
- for (i=0; i<8; i++) {
- if (value==(hbool_t)((buf[idx]>>i) & 0x01))
- HGOTO_DONE(8*idx+i - base);
- }
- }
- size -= 8;
- idx++;
- }
- /* End */
- for (i=0; i<(ssize_t)size; i++) {
- if (value==(hbool_t)((buf[idx]>>i) & 0x01))
- HGOTO_DONE(8*idx+i - base);
- }
- break;
-
- case H5T_BIT_MSB:
- /* Calculate index */
- idx = (ssize_t)((offset+size-1) / 8);
- offset %= 8;
-
- /* Beginning */
- if (size>8-offset && (offset+size)%8) {
- for (iu=(offset+size)%8; iu>0; --iu, --size) {
- if (value==(hbool_t)((buf[idx]>>(iu-1)) & 0x01))
- HGOTO_DONE(8*idx+(ssize_t)(iu-1) - base);
- }
- --idx;
- }
- /* Middle */
- while (size>=8) {
- if ((value?0x00:0xff)!=buf[idx]) {
- for (i=7; i>=0; --i) {
- if (value==(hbool_t)((buf[idx]>>i) & 0x01))
- HGOTO_DONE(8*idx+i - base);
- }
- }
- size -= 8;
- --idx;
- }
- /* End */
- if (size>0) {
- for (iu=offset+size; iu>offset; --iu) {
- if (value==(hbool_t)((buf[idx]>>(iu-1)) & 0x01))
- HGOTO_DONE(8*idx+(ssize_t)(iu-1) - base);
- }
- }
- break;
- }
+ HDassert(TRUE == 1);
+
+ switch(direction) {
+ case H5T_BIT_LSB:
+ /* Calculate index */
+ idx = (ssize_t)(offset / 8);
+ offset %= 8;
+
+ /* Beginning */
+ if (offset) {
+ for (iu=offset; iu<8 && size>0; iu++, size--) {
+ if (value==(hbool_t)((buf[idx]>>iu) & 0x01))
+ HGOTO_DONE(8*idx+(ssize_t)iu - base);
+ }
+ offset = 0;
+ idx++;
+ }
+ /* Middle */
+ while (size>=8) {
+ if ((value?0x00:0xff)!=buf[idx]) {
+ for (i=0; i<8; i++) {
+ if (value==(hbool_t)((buf[idx]>>i) & 0x01))
+ HGOTO_DONE(8*idx+i - base);
+ }
+ }
+ size -= 8;
+ idx++;
+ }
+ /* End */
+ for (i=0; i<(ssize_t)size; i++) {
+ if (value==(hbool_t)((buf[idx]>>i) & 0x01))
+ HGOTO_DONE(8*idx+i - base);
+ }
+ break;
+
+ case H5T_BIT_MSB:
+ /* Calculate index */
+ idx = (ssize_t)((offset+size-1) / 8);
+ offset %= 8;
+
+ /* Beginning */
+ if (size>8-offset && (offset+size)%8) {
+ for (iu=(offset+size)%8; iu>0; --iu, --size) {
+ if (value==(hbool_t)((buf[idx]>>(iu-1)) & 0x01))
+ HGOTO_DONE(8*idx+(ssize_t)(iu-1) - base);
+ }
+ --idx;
+ }
+ /* Middle */
+ while (size>=8) {
+ if ((value?0x00:0xff)!=buf[idx]) {
+ for (i=7; i>=0; --i) {
+ if (value==(hbool_t)((buf[idx]>>i) & 0x01))
+ HGOTO_DONE(8*idx+i - base);
+ }
+ }
+ size -= 8;
+ --idx;
+ }
+ /* End */
+ if (size>0) {
+ for (iu=offset+size; iu>offset; --iu) {
+ if (value==(hbool_t)((buf[idx]>>(iu-1)) & 0x01))
+ HGOTO_DONE(8*idx+(ssize_t)(iu-1) - base);
+ }
+ }
+ break;
+
+ default:
+ HDassert(0 && "Unknown bit search direction");
+ } /* end switch */
done:
FUNC_LEAVE_NOAPI(ret_value);
-}
+} /* end H5T_bit_find() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c
index bcb9962..46a1ac8 100644
--- a/src/H5Tcommit.c
+++ b/src/H5Tcommit.c
@@ -18,12 +18,19 @@
* to a file for the H5T interface.
*/
+/****************/
+/* Module Setup */
+/****************/
+
#define H5T_PACKAGE /*suppress error about including H5Tpkg */
/* Interface initialization */
#define H5_INTERFACE_INIT_FUNC H5T_init_commit_interface
+/***********/
+/* Headers */
+/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5FOprivate.h" /* File objects */
@@ -32,9 +39,48 @@
#include "H5Pprivate.h" /* Property lists */
#include "H5Tpkg.h" /* Datatypes */
-/* Static local functions */
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
static H5T_t *H5T_open_oid(const H5G_loc_t *loc, hid_t dxpl_id);
+
+/*********************/
+/* Public Variables */
+/*********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
/*--------------------------------------------------------------------------
NAME
@@ -87,7 +133,7 @@ H5Tcommit2(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id,
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
- if(NULL == (type = H5I_object_verify(type_id, H5I_DATATYPE)))
+ if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
/* Get correct property list */
@@ -224,17 +270,17 @@ done:
herr_t
H5Tcommit_anon(hid_t loc_id, hid_t type_id, hid_t tcpl_id, hid_t tapl_id)
{
- H5G_loc_t loc;
- H5T_t *type = NULL;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5G_loc_t loc; /* Group location for location */
+ H5T_t *type = NULL; /* Datatype created */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Tcommit_anon, FAIL)
H5TRACE4("e", "iiii", loc_id, type_id, tcpl_id, tapl_id);
/* Check arguments */
- if(H5G_loc (loc_id, &loc) < 0)
+ if(H5G_loc(loc_id, &loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
- if(NULL == (type = H5I_object_verify(type_id, H5I_DATATYPE)))
+ if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
/* Get correct property list */
@@ -288,6 +334,10 @@ H5T_commit(H5F_t *file, H5T_t *type, hid_t tcpl_id, hid_t dxpl_id)
HDassert(type);
HDassert(tcpl_id != H5P_DEFAULT);
+ /* Check if we are allowed to write to this file */
+ if(0 == (H5F_INTENT(file) & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "no write intent on file")
+
/*
* Check arguments. We cannot commit an immutable type because H5Tclose()
* normally fails on such types (try H5Tclose(H5T_NATIVE_INT)) but closing
@@ -302,8 +352,9 @@ H5T_commit(H5F_t *file, H5T_t *type, hid_t tcpl_id, hid_t dxpl_id)
if(H5T_is_sensible(type) <= 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "datatype is not sensible")
- /* Mark datatype as being on disk now. This step changes the size of datatype as
- * stored on disk. */
+ /* Mark datatype as being on disk now. This step changes the size of
+ * datatype as stored on disk.
+ */
if(H5T_set_loc(type, file, H5T_LOC_DISK) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk")
@@ -350,8 +401,9 @@ H5T_commit(H5F_t *file, H5T_t *type, hid_t tcpl_id, hid_t dxpl_id)
if(H5FO_insert(type->sh_loc.file, type->sh_loc.u.loc.oh_addr, type->shared, TRUE) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "can't insert datatype into list of open objects")
- /* Mark datatype as being on memory now. Since this datatype may still be used in memory
- * after committed to disk, change its size back as in memory. */
+ /* Mark datatype as being on memory again. Since this datatype may still be
+ * used in memory after committed to disk, change its size back as in memory.
+ */
if(H5T_set_loc(type, NULL, H5T_LOC_MEMORY) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype in memory")
@@ -391,14 +443,14 @@ done:
htri_t
H5Tcommitted(hid_t type_id)
{
- H5T_t *type = NULL;
- htri_t ret_value; /* Return value */
+ H5T_t *type; /* Datatype to query */
+ htri_t ret_value; /* Return value */
FUNC_ENTER_API(H5Tcommitted, FAIL)
H5TRACE1("t", "i", type_id);
/* Check arguments */
- if(NULL == (type = H5I_object_verify(type_id,H5I_DATATYPE)))
+ if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
/* Set return value */
@@ -440,7 +492,6 @@ H5T_committed(const H5T_t *type)
* ADJUST to the link count.
*
* Return: Success: New link count
- *
* Failure: Negative
*
* Programmer: Quincey Koziol
@@ -484,15 +535,15 @@ done:
hid_t
H5Topen2(hid_t loc_id, const char *name, hid_t tapl_id)
{
- H5T_t *type = NULL;
- H5G_loc_t loc;
+ H5T_t *type = NULL; /* Datatype opened in file */
+ H5G_loc_t loc; /* Group location of object to open */
H5G_name_t path; /* Datatype group hier. path */
H5O_loc_t oloc; /* Datatype object location */
H5O_type_t obj_type; /* Type of object at location */
H5G_loc_t type_loc; /* Group object for datatype */
hbool_t obj_found = FALSE; /* Object at 'name' found */
hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open datatype */
- hid_t ret_value = FAIL;
+ hid_t ret_value = FAIL; /* Return value */
FUNC_ENTER_API(H5Topen2, FAIL)
H5TRACE3("i", "i*si", loc_id, name, tapl_id);
@@ -530,11 +581,11 @@ H5Topen2(hid_t loc_id, const char *name, hid_t tapl_id)
HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a named datatype")
/* Open it */
- if((type = H5T_open(&type_loc, dxpl_id)) == NULL)
+ if(NULL == (type = H5T_open(&type_loc, dxpl_id)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to open named datatype")
/* Register the type and return the ID */
- if((ret_value = H5I_register(H5I_DATATYPE, type)) < 0)
+ if((ret_value = H5I_register(H5I_DATATYPE, type, TRUE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register named datatype")
done:
@@ -580,13 +631,13 @@ H5Tget_create_plist(hid_t dtype_id)
H5TRACE1("i", "i", dtype_id);
/* Check arguments */
- if(NULL == (type = H5I_object_verify(dtype_id, H5I_DATATYPE)))
+ if(NULL == (type = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
/* Copy the default datatype creation property list */
- if(NULL == (tcpl_plist = H5I_object(H5P_LST_DATATYPE_CREATE_g)))
+ if(NULL == (tcpl_plist = (H5P_genplist_t *)H5I_object(H5P_LST_DATATYPE_CREATE_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get default creation property list")
- if((new_tcpl_id = H5P_copy_plist(tcpl_plist)) < 0)
+ if((new_tcpl_id = H5P_copy_plist(tcpl_plist, TRUE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to copy the creation property list")
/* Check if the datatype is committed */
@@ -598,7 +649,7 @@ H5Tget_create_plist(hid_t dtype_id)
H5P_genplist_t *new_plist; /* New datatype creation property list */
/* Get property list object for new TCPL */
- if(NULL == (new_plist = H5I_object(new_tcpl_id)))
+ if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_tcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
/* Retrieve any object creation properties */
@@ -612,7 +663,7 @@ H5Tget_create_plist(hid_t dtype_id)
done:
if(ret_value < 0)
if(new_tcpl_id > 0)
- (void)H5I_dec_ref(new_tcpl_id);
+ (void)H5I_dec_ref(new_tcpl_id, TRUE);
FUNC_LEAVE_API(ret_value)
} /* end H5Tget_create_plist() */
@@ -644,12 +695,12 @@ H5T_open(const H5G_loc_t *loc, hid_t dxpl_id)
HDassert(loc);
/* Check if datatype was already open */
- if((shared_fo = H5FO_opened(loc->oloc->file, loc->oloc->addr)) == NULL) {
+ if(NULL == (shared_fo = (H5T_shared_t *)H5FO_opened(loc->oloc->file, loc->oloc->addr))) {
/* Clear any errors from H5FO_opened() */
H5E_clear_stack(NULL);
/* Open the datatype object */
- if((dt = H5T_open_oid(loc, dxpl_id)) == NULL)
+ if(NULL == (dt = H5T_open_oid(loc, dxpl_id)))
HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, NULL, "not found")
/* Add the datatype to the list of opened objects in the file */
@@ -694,6 +745,10 @@ H5T_open(const H5G_loc_t *loc, hid_t dxpl_id)
/* Point to shared datatype info */
dt->shared = shared_fo;
+ /* Mark any datatypes as being in memory now */
+ if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location")
+
/* Increment ref. count on shared info */
shared_fo->fo_count++;
@@ -715,12 +770,12 @@ done:
if(ret_value == NULL) {
if(dt) {
if(shared_fo == NULL) /* Need to free shared fo */
- H5FL_FREE(H5T_shared_t, dt->shared);
+ dt->shared = H5FL_FREE(H5T_shared_t, dt->shared);
H5O_loc_free(&(dt->oloc));
H5G_name_free(&(dt->path));
- H5FL_FREE(H5T_t, dt);
+ dt = H5FL_FREE(H5T_t, dt);
} /* end if */
if(shared_fo)
@@ -748,16 +803,19 @@ done:
static H5T_t *
H5T_open_oid(const H5G_loc_t *loc, hid_t dxpl_id)
{
- H5T_t *dt = NULL;
- H5T_t *ret_value;
+ H5T_t *dt = NULL; /* Datatype from the file */
+ H5T_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5T_open_oid)
HDassert(loc);
+ /* Open named datatype object in file */
if(H5O_open(loc->oloc) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to open named datatype")
- if(NULL == (dt = H5O_msg_read(loc->oloc, H5O_DTYPE_ID, NULL, dxpl_id)))
+
+ /* Deserialize the datatype message into a datatype in memory */
+ if(NULL == (dt = (H5T_t *)H5O_msg_read(loc->oloc, H5O_DTYPE_ID, NULL, dxpl_id)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to load type message from object header")
/* Mark the type as named and open */
diff --git a/src/H5Tcompound.c b/src/H5Tcompound.c
index dc7ae23..48192d2 100644
--- a/src/H5Tcompound.c
+++ b/src/H5Tcompound.c
@@ -18,34 +18,77 @@
* in the H5T interface.
*/
+/****************/
+/* Module Setup */
+/****************/
+
#define H5T_PACKAGE /*suppress error about including H5Tpkg */
/* Interface initialization */
#define H5_INTERFACE_INIT_FUNC H5T_init_compound_interface
+/***********/
+/* Headers */
+/***********/
#include "H5private.h" /*generic functions */
#include "H5Eprivate.h" /*error handling */
#include "H5Iprivate.h" /*ID functions */
#include "H5MMprivate.h" /*memory management */
#include "H5Tpkg.h" /*data-type functions */
-/* Static local functions */
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
static herr_t H5T_pack(const H5T_t *dt);
+
+/*********************/
+/* Public Variables */
+/*********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
/*--------------------------------------------------------------------------
NAME
H5T_init_compound_interface -- Initialize interface-specific information
USAGE
herr_t H5T_init_compound_interface()
-
RETURNS
Non-negative on success/Negative on failure
DESCRIPTION
Initializes any interface-specific data or routines. (Just calls
- H5T_init_iterface currently).
-
+ H5T_init() currently).
--------------------------------------------------------------------------*/
static herr_t
H5T_init_compound_interface(void)
@@ -79,24 +122,24 @@ H5T_init_compound_interface(void)
size_t
H5Tget_member_offset(hid_t type_id, unsigned membno)
{
- H5T_t *dt = NULL;
- size_t ret_value;
+ H5T_t *dt; /* Datatype to query */
+ size_t ret_value; /* Return value */
FUNC_ENTER_API(H5Tget_member_offset, 0)
H5TRACE2("z", "iIu", type_id, membno);
/* Check args */
- if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_COMPOUND != dt->shared->type)
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)) || H5T_COMPOUND != dt->shared->type)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a compound datatype")
- if (membno >= dt->shared->u.compnd.nmembs)
+ if(membno >= dt->shared->u.compnd.nmembs)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid member number")
/* Value */
- ret_value = H5T_get_member_offset(dt, membno);
+ ret_value = H5T_GET_MEMBER_OFFSET(dt->shared, membno);
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Tget_member_offset() */
/*-------------------------------------------------------------------------
@@ -116,25 +159,18 @@ done:
* Programmer: Raymond Lu
* October 8, 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
size_t
H5T_get_member_offset(const H5T_t *dt, unsigned membno)
{
- size_t ret_value;
-
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_get_member_offset)
- assert(dt);
- assert(membno < dt->shared->u.compnd.nmembs);
+ HDassert(dt);
+ HDassert(membno < dt->shared->u.compnd.nmembs);
- /* Value */
- ret_value = dt->shared->u.compnd.memb[membno].offset;
-
- FUNC_LEAVE_NOAPI(ret_value)
-}
+ FUNC_LEAVE_NOAPI(dt->shared->u.compnd.memb[membno].offset)
+} /* end H5T_get_member_offset() */
/*-------------------------------------------------------------------------
@@ -156,21 +192,22 @@ H5T_get_member_offset(const H5T_t *dt, unsigned membno)
H5T_class_t
H5Tget_member_class(hid_t type_id, unsigned membno)
{
- H5T_t *dt = NULL;
- H5T_class_t ret_value;
+ H5T_t *dt; /* Datatype to query */
+ H5T_class_t ret_value; /* Return value */
FUNC_ENTER_API(H5Tget_member_class, H5T_NO_CLASS)
H5TRACE2("Tt", "iIu", type_id, membno);
/* Check args */
- if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_COMPOUND != dt->shared->type)
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)) || H5T_COMPOUND != dt->shared->type)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a compound datatype")
- if (membno >= dt->shared->u.compnd.nmembs)
+ if(membno >= dt->shared->u.compnd.nmembs)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5T_NO_CLASS, "invalid member number")
/* Get the type's class. We have to use this function to get type class
- * because of the concern of variable-length string. */
- ret_value = H5T_get_class(dt->shared->u.compnd.memb[membno].type, FALSE);
+ * because of the concern of variable-length string.
+ */
+ ret_value = H5T_GET_CLASS(dt->shared->u.compnd.memb[membno].type->shared, FALSE);
done:
FUNC_LEAVE_API(ret_value)
@@ -193,42 +230,35 @@ done:
* Programmer: Robb Matzke
* Wednesday, January 7, 1998
*
- * Modifications:
- *
- * Robb Matzke, 4 Jun 1998
- * If the member type is a named type then this function returns a
- * handle to the re-opened named type.
- *
*-------------------------------------------------------------------------
*/
hid_t
H5Tget_member_type(hid_t type_id, unsigned membno)
{
- H5T_t *dt = NULL, *memb_dt = NULL;
- hid_t ret_value;
+ H5T_t *dt; /* Datatype to query */
+ H5T_t *memb_dt = NULL; /* Member datatype */
+ hid_t ret_value; /* Return value */
FUNC_ENTER_API(H5Tget_member_type, FAIL)
H5TRACE2("i", "iIu", type_id, membno);
/* Check args */
- if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_COMPOUND != dt->shared->type)
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)) || H5T_COMPOUND != dt->shared->type)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound datatype")
- if (membno >= dt->shared->u.compnd.nmembs)
+ if(membno >= dt->shared->u.compnd.nmembs)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid member number")
- if ((memb_dt=H5T_get_member_type(dt, membno, H5T_COPY_REOPEN))==NULL)
+ if(NULL == (memb_dt = H5T_get_member_type(dt, membno, H5T_COPY_REOPEN)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to retrieve member type")
- if ((ret_value = H5I_register(H5I_DATATYPE, memb_dt)) < 0)
+ if((ret_value = H5I_register(H5I_DATATYPE, memb_dt, TRUE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable register datatype atom")
done:
- if(ret_value<0) {
- if(memb_dt!=NULL)
- if(H5T_close(memb_dt)<0)
- HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close datatype")
- } /* end if */
+ if(ret_value < 0)
+ if(memb_dt && H5T_close(memb_dt) < 0)
+ HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close datatype")
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Tget_member_type() */
/*-------------------------------------------------------------------------
@@ -246,27 +276,25 @@ done:
* Programmer: Raymond Lu
* October 8, 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
H5T_t *
H5T_get_member_type(const H5T_t *dt, unsigned membno, H5T_copy_t method)
{
- H5T_t *ret_value = NULL;
+ H5T_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5T_get_member_type, NULL)
- assert(dt);
- assert(membno < dt->shared->u.compnd.nmembs);
+ HDassert(dt);
+ HDassert(membno < dt->shared->u.compnd.nmembs);
/* Copy datatype into an atom */
- if (NULL == (ret_value = H5T_copy(dt->shared->u.compnd.memb[membno].type, method)))
+ if(NULL == (ret_value = H5T_copy(dt->shared->u.compnd.memb[membno].type, method)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy member datatype")
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5T_get_member_type() */
/*-------------------------------------------------------------------------
@@ -275,31 +303,24 @@ done:
* Purpose: Returns the size of the specified member.
*
* Return: Success: The size in bytes of the member's datatype.
- *
* Failure: 0
*
* Programmer: Quincey Koziol
* October 4, 2004
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
size_t
H5T_get_member_size(const H5T_t *dt, unsigned membno)
{
- size_t ret_value = 0;
-
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_get_member_size)
- assert(dt);
- assert(membno < dt->shared->u.compnd.nmembs);
+ HDassert(dt);
+ HDassert(membno < dt->shared->u.compnd.nmembs);
- /* Value */
- ret_value = dt->shared->u.compnd.memb[membno].type->shared->size;
- FUNC_LEAVE_NOAPI(ret_value)
-}
+ FUNC_LEAVE_NOAPI(dt->shared->u.compnd.memb[membno].type->shared->size)
+} /* end H5T_get_member_size() */
/*-------------------------------------------------------------------------
@@ -329,32 +350,32 @@ H5T_get_member_size(const H5T_t *dt, unsigned membno)
herr_t
H5Tinsert(hid_t parent_id, const char *name, size_t offset, hid_t member_id)
{
- H5T_t *parent = NULL; /*the compound parent datatype */
- H5T_t *member = NULL; /*the atomic member type */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5T_t *parent; /* The compound parent datatype */
+ H5T_t *member; /* The member datatype */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Tinsert, FAIL)
H5TRACE4("e", "i*szi", parent_id, name, offset, member_id);
/* Check args */
- if (parent_id==member_id)
+ if(parent_id == member_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't insert compound datatype within itself")
- if (NULL == (parent = H5I_object_verify(parent_id,H5I_DATATYPE)) || H5T_COMPOUND != parent->shared->type)
+ if(NULL == (parent = (H5T_t *)H5I_object_verify(parent_id, H5I_DATATYPE)) || H5T_COMPOUND != parent->shared->type)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound datatype")
- if (H5T_STATE_TRANSIENT!=parent->shared->state)
+ if(H5T_STATE_TRANSIENT != parent->shared->state)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parent type read-only")
- if (!name || !*name)
+ if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no member name")
- if (NULL == (member = H5I_object_verify(member_id,H5I_DATATYPE)))
+ if(NULL == (member = (H5T_t *)H5I_object_verify(member_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
/* Insert */
- if (H5T_insert(parent, name, offset, member) < 0)
+ if(H5T_insert(parent, name, offset, member) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "unable to insert member")
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Tinsert() */
/*-------------------------------------------------------------------------
@@ -375,23 +396,23 @@ done:
herr_t
H5Tpack(hid_t type_id)
{
- H5T_t *dt = NULL;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5T_t *dt; /* Datatype to modify */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Tpack, FAIL)
H5TRACE1("e", "i", type_id);
/* Check args */
- if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_detect_class(dt,H5T_COMPOUND)<=0)
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)) || H5T_detect_class(dt, H5T_COMPOUND, TRUE) <= 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound datatype")
/* Pack */
- if (H5T_pack(dt) < 0)
+ if(H5T_pack(dt) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack compound datatype")
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Tpack() */
/*-------------------------------------------------------------------------
@@ -407,17 +428,15 @@ done:
* Programmer: Robb Matzke
* Monday, December 8, 1997
*
- * Modifications:
- * Took out arrayness parameters - QAK, 10/6/00
- *
*-------------------------------------------------------------------------
*/
herr_t
H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member)
{
- unsigned idx, i;
+ unsigned idx; /* Index of member to insert */
size_t total_size;
- herr_t ret_value = SUCCEED; /* Return value */
+ unsigned i; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5T_insert, FAIL)
@@ -435,12 +454,12 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member)
/* Does the new member overlap any existing member ? */
total_size = member->shared->size;
for(i = 0; i < parent->shared->u.compnd.nmembs; i++)
- if((offset <= parent->shared->u.compnd.memb[i].offset &&
- offset + total_size > parent->shared->u.compnd.memb[i].offset) ||
+ if((offset <= parent->shared->u.compnd.memb[i].offset &&
+ (offset + total_size) > parent->shared->u.compnd.memb[i].offset) ||
(parent->shared->u.compnd.memb[i].offset <= offset &&
- parent->shared->u.compnd.memb[i].offset +
- parent->shared->u.compnd.memb[i].size > offset))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member")
+ (parent->shared->u.compnd.memb[i].offset +
+ parent->shared->u.compnd.memb[i].size) > offset))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member")
/* Does the new member overlap the end of the compound type? */
if((offset + total_size) > parent->shared->size)
@@ -449,10 +468,10 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member)
/* Increase member array if necessary */
if(parent->shared->u.compnd.nmembs >= parent->shared->u.compnd.nalloc) {
unsigned na = MAX(1, parent->shared->u.compnd.nalloc * 2);
- H5T_cmemb_t *x = H5MM_realloc(parent->shared->u.compnd.memb, na * sizeof(H5T_cmemb_t));
+ H5T_cmemb_t *x = (H5T_cmemb_t *)H5MM_realloc(parent->shared->u.compnd.memb, na * sizeof(H5T_cmemb_t));
if(!x)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "memory allocation failed")
parent->shared->u.compnd.nalloc = na;
parent->shared->u.compnd.memb = x;
} /* end if */
@@ -466,29 +485,14 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member)
parent->shared->u.compnd.sorted = H5T_SORT_NONE;
parent->shared->u.compnd.nmembs++;
+ parent->shared->u.compnd.memb_size+=total_size;
- /* Determine if the compound datatype stayed packed */
- if(parent->shared->u.compnd.packed) {
- /* Check if the member type is packed */
- if(H5T_is_packed(parent->shared->u.compnd.memb[idx].type) > 0) {
- if(idx == 0) {
- /* If the is the first member, the datatype is not packed
- * if the first member isn't at offset 0
- */
- if(parent->shared->u.compnd.memb[idx].offset > 0)
- parent->shared->u.compnd.packed = FALSE;
- } /* end if */
- else {
- /* If the is not the first member, the datatype is not
- * packed if the new member isn't adjoining the previous member
- */
- if(parent->shared->u.compnd.memb[idx].offset != (parent->shared->u.compnd.memb[idx - 1].offset + parent->shared->u.compnd.memb[idx - 1].size))
- parent->shared->u.compnd.packed = FALSE;
- } /* end else */
- } /* end if */
- else
- parent->shared->u.compnd.packed = FALSE;
- } /* end if */
+ /* It should not be possible to get this far if the type is already packed
+ * - the new member would overlap something */
+ HDassert(!(parent->shared->u.compnd.packed));
+
+ /* Determine if the compound datatype becomes packed */
+ H5T_update_packed(parent);
/* Set the "force conversion" flag if the field's datatype indicates */
if(member->shared->force_conv == TRUE)
@@ -519,28 +523,24 @@ done:
* Programmer: Robb Matzke
* Wednesday, January 7, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
H5T_pack(const H5T_t *dt)
{
- unsigned i;
- size_t offset;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5T_pack)
- assert(dt);
+ HDassert(dt);
- if(H5T_detect_class(dt,H5T_COMPOUND)>0) {
+ if(H5T_detect_class(dt, H5T_COMPOUND, FALSE) > 0) {
/* If datatype has been packed, skip packing it and indicate success */
- if(H5T_is_packed(dt)== TRUE)
+ if(TRUE == H5T_is_packed(dt))
HGOTO_DONE(SUCCEED)
/* Check for packing unmodifiable datatype */
- if (H5T_STATE_TRANSIENT!=dt->shared->state)
+ if(H5T_STATE_TRANSIENT != dt->shared->state)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "datatype is read-only")
if(dt->shared->parent) {
@@ -548,25 +548,28 @@ H5T_pack(const H5T_t *dt)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack parent of datatype")
/* Adjust size of datatype appropriately */
- if(dt->shared->type==H5T_ARRAY)
+ if(dt->shared->type == H5T_ARRAY)
dt->shared->size = dt->shared->parent->shared->size * dt->shared->u.array.nelem;
- else if(dt->shared->type!=H5T_VLEN)
+ else if(dt->shared->type != H5T_VLEN)
dt->shared->size = dt->shared->parent->shared->size;
} /* end if */
- else if(dt->shared->type==H5T_COMPOUND) {
+ else if(dt->shared->type == H5T_COMPOUND) {
+ size_t offset; /* Offset of member */
+ unsigned i; /* Local index variable */
+
/* Recursively pack the members */
- for (i=0; i<dt->shared->u.compnd.nmembs; i++) {
- if (H5T_pack(dt->shared->u.compnd.memb[i].type) < 0)
+ for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
+ if(H5T_pack(dt->shared->u.compnd.memb[i].type) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack part of a compound datatype")
/* Update the member size */
dt->shared->u.compnd.memb[i].size = (dt->shared->u.compnd.memb[i].type)->shared->size;
- }
+ } /* end for */
/* Remove padding between members */
- if(H5T_sort_value(dt, NULL)<0)
+ if(H5T_sort_value(dt, NULL) < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOMPARE, FAIL, "value sort failed")
- for (i=0, offset=0; i<dt->shared->u.compnd.nmembs; i++) {
+ for(i = 0, offset = 0; i < dt->shared->u.compnd.nmembs; i++) {
dt->shared->u.compnd.memb[i].offset = offset;
offset += dt->shared->u.compnd.memb[i].size;
}
@@ -575,13 +578,13 @@ H5T_pack(const H5T_t *dt)
dt->shared->size = MAX(1, offset);
/* Mark the type as packed now */
- dt->shared->u.compnd.packed=TRUE;
+ dt->shared->u.compnd.packed = TRUE;
} /* end if */
} /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5T_pack() */
/*-------------------------------------------------------------------------
@@ -602,20 +605,67 @@ done:
htri_t
H5T_is_packed(const H5T_t *dt)
{
- htri_t ret_value=TRUE; /* Return value */
+ htri_t ret_value = TRUE; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_is_packed)
- assert(dt);
+ HDassert(dt);
/* Go up the chain as far as possible */
while(dt->shared->parent)
- dt=dt->shared->parent;
+ dt = dt->shared->parent;
/* If this is a compound datatype, check if it is packed */
- if(dt->shared->type==H5T_COMPOUND)
- ret_value=(htri_t)dt->shared->u.compnd.packed;
+ if(dt->shared->type == H5T_COMPOUND) {
+ ret_value = (htri_t)(dt->shared->u.compnd.packed);
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_is_packed() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_update_packed
+ *
+ * Purpose: Checks whether a datatype which is compound became packed
+ * after recent changes. This function does not assume that
+ * the status of the "packed" field is correct, and sets
+ * this field to the correct value.
+ *
+ * Return: void
+ *
+ * Programmer: Neil Fortner
+ * Monday, October 19, 2009
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5T_update_packed(const H5T_t *dt)
+{
+ unsigned i; /* Index */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_update_packed)
+
+ HDassert(dt);
+ HDassert(dt->shared->type == H5T_COMPOUND);
+
+ /* First check if all space is used in the "top level" type */
+ if(dt->shared->size == dt->shared->u.compnd.memb_size) {
+ /* Set the packed flag to TRUE */
+ dt->shared->u.compnd.packed = TRUE;
+
+ /* Now check if all members are packed */
+ for(i = 0; i < dt->shared->u.compnd.nmembs; i++)
+ if(!H5T_is_packed(dt->shared->u.compnd.memb[i].type)) {
+ dt->shared->u.compnd.packed = FALSE;
+ break;
+ } /* end if */
+ } /* end if */
+ else
+ dt->shared->u.compnd.packed = FALSE;
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5T_update_packed() */
+
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index a91c09a..bfa5d56 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -14,11 +14,22 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
- * Module Info: Data type conversions for the H5T interface.
+ * Module Info: Datatype conversions for the H5T interface.
*/
+/****************/
+/* Module Setup */
+/****************/
+
#define H5T_PACKAGE /*suppress error about including H5Tpkg */
+/* Interface initialization */
+#define H5_INTERFACE_INIT_FUNC H5T_init_conv_interface
+
+
+/***********/
+/* Headers */
+/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
@@ -29,33 +40,10 @@
#include "H5Pprivate.h" /* Property lists */
#include "H5Tpkg.h" /* Datatypes */
-/* Conversion data for H5T_conv_struct() */
-typedef struct H5T_conv_struct_t {
- int *src2dst; /*mapping from src to dst member num */
- hid_t *src_memb_id; /*source member type ID's */
- hid_t *dst_memb_id; /*destination member type ID's */
- H5T_path_t **memb_path; /*conversion path for each member */
- H5T_subset_t smembs_subset; /*are source and dest members a subset of each other? */
-} H5T_conv_struct_t;
-/* Conversion data for H5T_conv_enum() */
-typedef struct H5T_enum_struct_t {
- int base; /*lowest `in' value */
- int length; /*num elements in arrays */
- int *src2dst; /*map from src to dst index */
-} H5T_enum_struct_t;
-
-/* Conversion data for the hardware conversion functions */
-typedef struct H5T_conv_hw_t {
- size_t s_aligned; /*number source elements aligned */
- size_t d_aligned; /*number destination elements aligned*/
-} H5T_conv_hw_t;
-
-/* Declare a free list to manage pieces of vlen data */
-H5FL_BLK_DEFINE_STATIC(vlen_seq);
-
-/* Declare a free list to manage pieces of array data */
-H5FL_BLK_DEFINE_STATIC(array_seq);
+/****************/
+/* Local Macros */
+/****************/
/*
* These macros are for the bodies of functions that convert buffers of one
@@ -138,17 +126,17 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
* CDATA: A pointer to the H5T_cdata_t structure that was passed to the
* conversion function.
*
- * STYPE: The hid_t value for the source data type.
+ * STYPE: The hid_t value for the source datatype.
*
- * DTYPE: The hid_t value for the destination data type.
+ * DTYPE: The hid_t value for the destination datatype.
*
* BUF: A pointer to the conversion buffer.
*
* NELMTS: The number of values to be converted.
*
- * ST: The C name for source data type (e.g., int)
+ * ST: The C name for source datatype (e.g., int)
*
- * DT: The C name for the destination data type (e.g., signed char)
+ * DT: The C name for the destination datatype (e.g., signed char)
*
* D_MIN: The minimum possible destination value. For unsigned
* destination types this should be zero. For signed
@@ -206,7 +194,7 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
src_id, dst_id, S, D, cb_struct.user_data); \
if(except_ret == H5T_CONV_UNHANDLED) \
/* Let compiler convert if case is ignored by user handler*/ \
- *((DT*)D) = (D_MAX); \
+ *((DT*)D) = (DT)(D_MAX); \
else if(except_ret == H5T_CONV_ABORT) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
/* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
@@ -215,7 +203,7 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
src_id, dst_id, S, D, cb_struct.user_data); \
if(except_ret == H5T_CONV_UNHANDLED) \
/* Let compiler convert if case is ignored by user handler*/ \
- *((DT*)D) = (D_MIN); \
+ *((DT*)D) = (DT)(D_MIN); \
else if(except_ret == H5T_CONV_ABORT) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
/* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
@@ -224,9 +212,9 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
}
#define H5T_CONV_Xx_NOEX_CORE(S,D,ST,DT,D_MIN,D_MAX) { \
if (*((ST*)S) > (DT)(D_MAX)) { \
- *((DT*)D) = (D_MAX); \
+ *((DT*)D) = (DT)(D_MAX); \
} else if (*((ST*)S) < (DT)(D_MIN)) { \
- *((DT*)D) = (D_MIN); \
+ *((DT*)D) = (DT)(D_MIN); \
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
@@ -237,7 +225,7 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
src_id, dst_id, S, D, cb_struct.user_data); \
if(except_ret == H5T_CONV_UNHANDLED) \
/* Let compiler convert if case is ignored by user handler*/ \
- *((DT*)D) = (D_MAX); \
+ *((DT*)D) = (DT)(D_MAX); \
else if(except_ret == H5T_CONV_ABORT) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
/* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
@@ -246,14 +234,14 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
}
#define H5T_CONV_Ux_NOEX_CORE(S,D,ST,DT,D_MIN,D_MAX) { \
if (*((ST*)S) > (DT)(D_MAX)) { \
- *((DT*)D) = (D_MAX); \
+ *((DT*)D) = (DT)(D_MAX); \
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#define H5T_CONV_sS(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)<=sizeof(DT)); \
- H5T_CONV(H5T_CONV_xX, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+ H5T_CONV(H5T_CONV_xX, long long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
#define H5T_CONV_sU_CORE(S,D,ST,DT,D_MIN,D_MAX) { \
@@ -278,16 +266,16 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
#define H5T_CONV_sU(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)<=sizeof(DT)); \
- H5T_CONV(H5T_CONV_sU, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+ H5T_CONV(H5T_CONV_sU, long long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
#define H5T_CONV_uS_CORE(S,D,ST,DT,D_MIN,D_MAX) { \
- if (sizeof(ST)==sizeof(DT) && *((ST*)S) > (D_MAX)) { \
+ if (sizeof(ST)==sizeof(DT) && *((ST*)S) > (DT)(D_MAX)) { \
H5T_conv_ret_t except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, \
src_id, dst_id, S, D, cb_struct.user_data); \
if(except_ret == H5T_CONV_UNHANDLED) \
/* Let compiler convert if case is ignored by user handler*/ \
- *((DT*)D) = (D_MAX); \
+ *((DT*)D) = (DT)(D_MAX); \
else if(except_ret == H5T_CONV_ABORT) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
/* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
@@ -303,17 +291,17 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
#define H5T_CONV_uS(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)<=sizeof(DT)); \
- H5T_CONV(H5T_CONV_uS, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+ H5T_CONV(H5T_CONV_uS, long long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
#define H5T_CONV_uU(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)<=sizeof(DT)); \
- H5T_CONV(H5T_CONV_xX, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+ H5T_CONV(H5T_CONV_xX, long long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
#define H5T_CONV_Ss(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)>=sizeof(DT)); \
- H5T_CONV(H5T_CONV_Xx, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+ H5T_CONV(H5T_CONV_Xx, long long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
#define H5T_CONV_Su_CORE(S,D,ST,DT,D_MIN,D_MAX) { \
@@ -331,7 +319,7 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
src_id, dst_id, S, D, cb_struct.user_data); \
if(except_ret == H5T_CONV_UNHANDLED) \
/* Let compiler convert if case is ignored by user handler*/ \
- *((DT*)D) = (D_MAX); \
+ *((DT*)D) = (DT)(D_MAX); \
else if(except_ret == H5T_CONV_ABORT) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
/* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
@@ -342,24 +330,24 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
if (*((ST*)S) < 0) { \
*((DT*)D) = 0; \
} else if (sizeof(ST)>sizeof(DT) && *((ST*)S) > (DT)(D_MAX)) { \
- *((DT*)D) = (D_MAX); \
+ *((DT*)D) = (DT)(D_MAX); \
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#define H5T_CONV_Su(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)>=sizeof(DT)); \
- H5T_CONV(H5T_CONV_Su, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+ H5T_CONV(H5T_CONV_Su, long long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
#define H5T_CONV_Us(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)>=sizeof(DT)); \
- H5T_CONV(H5T_CONV_Ux, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+ H5T_CONV(H5T_CONV_Ux, long long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
#define H5T_CONV_Uu(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)>=sizeof(DT)); \
- H5T_CONV(H5T_CONV_Ux, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+ H5T_CONV(H5T_CONV_Ux, long long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
#define H5T_CONV_su_CORE(S,D,ST,DT,D_MIN,D_MAX) { \
@@ -386,7 +374,7 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
#define H5T_CONV_su(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)==sizeof(DT)); \
- H5T_CONV(H5T_CONV_su, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+ H5T_CONV(H5T_CONV_su, long long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
#define H5T_CONV_us_CORE(S,D,ST,DT,D_MIN,D_MAX) { \
@@ -396,7 +384,7 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
src_id, dst_id, S, D, cb_struct.user_data); \
if(except_ret == H5T_CONV_UNHANDLED) \
/* Let compiler convert if case is ignored by user handler*/ \
- *((DT*)D) = (D_MAX); \
+ *((DT*)D) = (DT)(D_MAX); \
else if(except_ret == H5T_CONV_ABORT) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
/* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
@@ -406,14 +394,14 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
#define H5T_CONV_us_NOEX_CORE(S,D,ST,DT,D_MIN,D_MAX) { \
/* Assumes memory format of unsigned & signed integers is same */ \
if (*((ST*)S) > (DT)(D_MAX)) { \
- *((DT*)D) = (D_MAX); \
+ *((DT*)D) = (DT)(D_MAX); \
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
#define H5T_CONV_us(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)==sizeof(DT)); \
- H5T_CONV(H5T_CONV_us, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+ H5T_CONV(H5T_CONV_us, long long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
#define H5T_CONV_fF(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
@@ -565,7 +553,7 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
src_id, dst_id, S, D, cb_struct.user_data); \
if(except_ret == H5T_CONV_UNHANDLED) \
/* Let compiler convert if case is ignored by user handler*/ \
- *((DT*)D) = (D_MAX); \
+ *((DT*)D) = (DT)(D_MAX); \
else if(except_ret == H5T_CONV_ABORT) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
/* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
@@ -574,7 +562,7 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
src_id, dst_id, S, D, cb_struct.user_data); \
if(except_ret == H5T_CONV_UNHANDLED) \
/* Let compiler convert if case is ignored by user handler*/ \
- *((DT*)D) = (D_MIN); \
+ *((DT*)D) = (DT)(D_MIN); \
else if(except_ret == H5T_CONV_ABORT) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
/* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
@@ -593,9 +581,9 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
}
#define H5T_CONV_Fx_NOEX_CORE(S,D,ST,DT,D_MIN,D_MAX) { \
if (*((ST*)S) > (DT)(D_MAX)) { \
- *((DT*)D) = (D_MAX); \
+ *((DT*)D) = (DT)(D_MAX); \
} else if (*((ST*)S) < (DT)(D_MIN)) { \
- *((DT*)D) = (D_MIN); \
+ *((DT*)D) = (DT)(D_MIN); \
} \
else \
*((DT*)D) = (DT)(*((ST*)S)); \
@@ -621,7 +609,7 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
uint8_t *src, *s; /*source buffer */ \
uint8_t *dst, *d; /*destination buffer */ \
H5T_class_t tclass; /*datatype's class */ \
- H5T_t *st, *dt; /*data type descriptors */ \
+ H5T_t *st, *dt; /*datatype descriptors */ \
ATYPE aligned; /*aligned type */ \
hbool_t s_mv, d_mv; /*move data to align it? */ \
ssize_t s_stride, d_stride; /*src and dst strides */ \
@@ -633,7 +621,7 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
case H5T_CONV_INIT: \
/* Sanity check and initialize statistics */ \
cdata->need_bkg = H5T_BKG_NO; \
- if (NULL==(st=H5I_object(src_id)) || NULL==(dt=H5I_object(dst_id))) \
+ if (NULL==(st=(H5T_t*)H5I_object(src_id)) || NULL==(dt=(H5T_t*)H5I_object(dst_id))) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, \
"unable to dereference datatype object ID") \
if (st->shared->size!=sizeof(ST) || dt->shared->size!=sizeof(DT)) \
@@ -681,7 +669,7 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback"); \
\
/* Get source and destination datatypes */ \
- if (NULL==(st=H5I_object(src_id)) || NULL==(dt=H5I_object(dst_id))) \
+ if (NULL==(st=(H5T_t*)H5I_object(src_id)) || NULL==(dt=(H5T_t*)H5I_object(dst_id))) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, \
"unable to dereference datatype object ID") \
\
@@ -726,7 +714,7 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} /* end if */ \
else { \
/* Single forward pass over all data */ \
- src = dst = buf; \
+ src = dst = (uint8_t*)buf; \
safe=nelmts; \
} /* end else */ \
\
@@ -885,9 +873,91 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
/* Minimum size of variable-length conversion buffer */
#define H5T_VLEN_MIN_CONF_BUF_SIZE 4096
+/******************/
+/* Local Typedefs */
+/******************/
+
+/* Conversion data for H5T_conv_struct() */
+typedef struct H5T_conv_struct_t {
+ int *src2dst; /*mapping from src to dst member num */
+ hid_t *src_memb_id; /*source member type ID's */
+ hid_t *dst_memb_id; /*destination member type ID's */
+ H5T_path_t **memb_path; /*conversion path for each member */
+ H5T_subset_info_t subset_info; /*info related to compound subsets */
+ unsigned src_nmembs; /*needed by free function */
+} H5T_conv_struct_t;
+
+/* Conversion data for H5T_conv_enum() */
+typedef struct H5T_enum_struct_t {
+ int base; /*lowest `in' value */
+ int length; /*num elements in arrays */
+ int *src2dst; /*map from src to dst index */
+} H5T_enum_struct_t;
+
+/* Conversion data for the hardware conversion functions */
+typedef struct H5T_conv_hw_t {
+ size_t s_aligned; /*number source elements aligned */
+ size_t d_aligned; /*number destination elements aligned*/
+} H5T_conv_hw_t;
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
static herr_t H5T_reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_order_t order);
+/*********************/
+/* Public Variables */
+/*********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage pieces of vlen data */
+H5FL_BLK_DEFINE_STATIC(vlen_seq);
+
+/* Declare a free list to manage pieces of array data */
+H5FL_BLK_DEFINE_STATIC(array_seq);
+
+
+/*--------------------------------------------------------------------------
+NAME
+ H5T_init_conv_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5T_init_conv_interface()
+RETURNS
+ Non-negative on success/Negative on failure
+DESCRIPTION
+ Initializes any interface-specific data or routines. (Just calls
+ H5T_init() currently).
+--------------------------------------------------------------------------*/
+static herr_t
+H5T_init_conv_interface(void)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_init_conv_interface)
+
+ FUNC_LEAVE_NOAPI(H5T_init())
+} /* H5T_init_conv_interface() */
+
+
/*-------------------------------------------------------------------------
* Function: H5T_conv_noop
*
@@ -899,8 +969,6 @@ static herr_t H5T_reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_order
* Programmer: Robb Matzke
* Wednesday, January 14, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -909,11 +977,11 @@ H5T_conv_noop(hid_t UNUSED src_id, hid_t UNUSED dst_id, H5T_cdata_t *cdata,
size_t UNUSED bkg_stride, void UNUSED *buf,
void UNUSED *background, hid_t UNUSED dxpl_id)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_noop, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_noop, FAIL)
- switch (cdata->command) {
+ switch(cdata->command) {
case H5T_CONV_INIT:
cdata->need_bkg = H5T_BKG_NO;
break;
@@ -926,12 +994,12 @@ H5T_conv_noop(hid_t UNUSED src_id, hid_t UNUSED dst_id, H5T_cdata_t *cdata,
break;
default:
- HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
- }
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command")
+ } /* end switch */
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_conv_noop() */
/*-------------------------------------------------------------------------
@@ -962,377 +1030,380 @@ H5T_conv_order_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
H5T_t *src = NULL;
H5T_t *dst = NULL;
size_t i;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_order_opt, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_order_opt, FAIL)
- switch (cdata->command) {
- case H5T_CONV_INIT:
- /* Capability query */
- if (NULL == (src = H5I_object(src_id)) ||
- NULL == (dst = H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- if (src->shared->size != dst->shared->size ||
- 0 != src->shared->u.atomic.offset ||
- 0 != dst->shared->u.atomic.offset)
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
- if((src->shared->type==H5T_REFERENCE && dst->shared->type!=H5T_REFERENCE) ||
- (dst->shared->type==H5T_REFERENCE && src->shared->type!=H5T_REFERENCE))
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
- if(src->shared->type!=H5T_REFERENCE &&
- !((H5T_ORDER_BE == src->shared->u.atomic.order && H5T_ORDER_LE == dst->shared->u.atomic.order) ||
- (H5T_ORDER_LE == src->shared->u.atomic.order && H5T_ORDER_BE == dst->shared->u.atomic.order)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
- if (src->shared->size!=1 && src->shared->size!=2 && src->shared->size!=4 &&
- src->shared->size!=8 && src->shared->size!=16)
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
- switch (src->shared->type) {
- case H5T_INTEGER:
- case H5T_BITFIELD:
- case H5T_REFERENCE:
- /* nothing to check */
- break;
-
- case H5T_FLOAT:
- if (src->shared->u.atomic.u.f.sign != dst->shared->u.atomic.u.f.sign ||
- src->shared->u.atomic.u.f.epos != dst->shared->u.atomic.u.f.epos ||
- src->shared->u.atomic.u.f.esize != dst->shared->u.atomic.u.f.esize ||
- src->shared->u.atomic.u.f.ebias != dst->shared->u.atomic.u.f.ebias ||
- src->shared->u.atomic.u.f.mpos != dst->shared->u.atomic.u.f.mpos ||
- src->shared->u.atomic.u.f.msize != dst->shared->u.atomic.u.f.msize ||
- src->shared->u.atomic.u.f.norm != dst->shared->u.atomic.u.f.norm ||
- src->shared->u.atomic.u.f.pad != dst->shared->u.atomic.u.f.pad)
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
- break;
+ switch(cdata->command) {
+ case H5T_CONV_INIT:
+ /* Capability query */
+ if(NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
+ if(src->shared->size != dst->shared->size ||
+ 0 != src->shared->u.atomic.offset ||
+ 0 != dst->shared->u.atomic.offset)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported")
+ if((src->shared->type == H5T_REFERENCE && dst->shared->type != H5T_REFERENCE) ||
+ (dst->shared->type == H5T_REFERENCE && src->shared->type != H5T_REFERENCE))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported")
+ if(src->shared->type != H5T_REFERENCE &&
+ !((H5T_ORDER_BE == src->shared->u.atomic.order && H5T_ORDER_LE == dst->shared->u.atomic.order) ||
+ (H5T_ORDER_LE == src->shared->u.atomic.order && H5T_ORDER_BE == dst->shared->u.atomic.order)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported")
+ if (src->shared->size != 1 && src->shared->size != 2 && src->shared->size != 4 &&
+ src->shared->size != 8 && src->shared->size != 16)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported")
+ switch(src->shared->type) {
+ case H5T_INTEGER:
+ case H5T_BITFIELD:
+ case H5T_REFERENCE:
+ /* nothing to check */
+ break;
- default:
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
- }
- cdata->need_bkg = H5T_BKG_NO;
- break;
-
- case H5T_CONV_CONV:
- /* The conversion */
- if (NULL == (src = H5I_object(src_id)) ||
- NULL == (dst = H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
-
- /* Check for "no op" reference conversion */
- if(src->shared->type==H5T_REFERENCE) {
- /* Sanity check */
- assert(dst->shared->type==H5T_REFERENCE);
-
- /* Check if we are on a little-endian machine (the order that
- * the addresses in the file must be) and just get out now, there
- * is no need to convert the object reference. Yes, this is
- * icky and non-portable, but I can't think of a better way to
- * support allowing the objno in the H5O_info_t struct and the
- * hobj_ref_t type to be compared directly without introducing a
- * "native" hobj_ref_t datatype and I think that would break a
- * lot of existing programs. -QAK
- */
- if(H5T_native_order_g == H5T_ORDER_LE)
- break;
- } /* end if */
+ case H5T_FLOAT:
+ if(src->shared->u.atomic.u.f.sign != dst->shared->u.atomic.u.f.sign ||
+ src->shared->u.atomic.u.f.epos != dst->shared->u.atomic.u.f.epos ||
+ src->shared->u.atomic.u.f.esize != dst->shared->u.atomic.u.f.esize ||
+ src->shared->u.atomic.u.f.ebias != dst->shared->u.atomic.u.f.ebias ||
+ src->shared->u.atomic.u.f.mpos != dst->shared->u.atomic.u.f.mpos ||
+ src->shared->u.atomic.u.f.msize != dst->shared->u.atomic.u.f.msize ||
+ src->shared->u.atomic.u.f.norm != dst->shared->u.atomic.u.f.norm ||
+ src->shared->u.atomic.u.f.pad != dst->shared->u.atomic.u.f.pad)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported")
+ break;
- buf_stride = buf_stride ? buf_stride : src->shared->size;
- switch (src->shared->size) {
- case 1:
- /*no-op*/
- break;
- case 2:
- for (/*void*/; nelmts>=20; nelmts-=20) {
- H5_SWAP_BYTES(buf, 0, 1); /* 0 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 1 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 2 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 3 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 4 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 5 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 6 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 7 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 8 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 9 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 10 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 11 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 12 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 13 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 14 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 15 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 16 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 17 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 18 */
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 1); /* 19 */
- buf += buf_stride;
- }
- for (i=0; i<nelmts; i++, buf+=buf_stride) {
- H5_SWAP_BYTES(buf, 0, 1);
- }
- break;
- case 4:
- for (/*void*/; nelmts>=20; nelmts-=20) {
- H5_SWAP_BYTES(buf, 0, 3); /* 0 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 1 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 2 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 3 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 4 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 5 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 6 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 7 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 8 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 9 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 10 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 11 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 12 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 13 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 14 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 15 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 16 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 17 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 18 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 3); /* 19 */
- H5_SWAP_BYTES(buf, 1, 2);
- buf += buf_stride;
- }
- for (i=0; i<nelmts; i++, buf+=buf_stride) {
- H5_SWAP_BYTES(buf, 0, 3);
- H5_SWAP_BYTES(buf, 1, 2);
- }
- break;
- case 8:
- for (/*void*/; nelmts>=10; nelmts-=10) {
- H5_SWAP_BYTES(buf, 0, 7); /* 0 */
- H5_SWAP_BYTES(buf, 1, 6);
- H5_SWAP_BYTES(buf, 2, 5);
- H5_SWAP_BYTES(buf, 3, 4);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 7); /* 1 */
- H5_SWAP_BYTES(buf, 1, 6);
- H5_SWAP_BYTES(buf, 2, 5);
- H5_SWAP_BYTES(buf, 3, 4);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 7); /* 2 */
- H5_SWAP_BYTES(buf, 1, 6);
- H5_SWAP_BYTES(buf, 2, 5);
- H5_SWAP_BYTES(buf, 3, 4);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 7); /* 3 */
- H5_SWAP_BYTES(buf, 1, 6);
- H5_SWAP_BYTES(buf, 2, 5);
- H5_SWAP_BYTES(buf, 3, 4);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 7); /* 4 */
- H5_SWAP_BYTES(buf, 1, 6);
- H5_SWAP_BYTES(buf, 2, 5);
- H5_SWAP_BYTES(buf, 3, 4);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 7); /* 5 */
- H5_SWAP_BYTES(buf, 1, 6);
- H5_SWAP_BYTES(buf, 2, 5);
- H5_SWAP_BYTES(buf, 3, 4);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 7); /* 6 */
- H5_SWAP_BYTES(buf, 1, 6);
- H5_SWAP_BYTES(buf, 2, 5);
- H5_SWAP_BYTES(buf, 3, 4);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 7); /* 7 */
- H5_SWAP_BYTES(buf, 1, 6);
- H5_SWAP_BYTES(buf, 2, 5);
- H5_SWAP_BYTES(buf, 3, 4);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 7); /* 8 */
- H5_SWAP_BYTES(buf, 1, 6);
- H5_SWAP_BYTES(buf, 2, 5);
- H5_SWAP_BYTES(buf, 3, 4);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 7); /* 9 */
- H5_SWAP_BYTES(buf, 1, 6);
- H5_SWAP_BYTES(buf, 2, 5);
- H5_SWAP_BYTES(buf, 3, 4);
- buf += buf_stride;
- }
- for (i=0; i<nelmts; i++, buf+=buf_stride) {
- H5_SWAP_BYTES(buf, 0, 7);
- H5_SWAP_BYTES(buf, 1, 6);
- H5_SWAP_BYTES(buf, 2, 5);
- H5_SWAP_BYTES(buf, 3, 4);
+ default:
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported")
}
+ cdata->need_bkg = H5T_BKG_NO;
break;
- case 16:
- for (/*void*/; nelmts>=10; nelmts-=10) {
- H5_SWAP_BYTES(buf, 0, 15); /* 0 */
- H5_SWAP_BYTES(buf, 1, 14);
- H5_SWAP_BYTES(buf, 2, 13);
- H5_SWAP_BYTES(buf, 3, 12);
- H5_SWAP_BYTES(buf, 4, 11);
- H5_SWAP_BYTES(buf, 5, 10);
- H5_SWAP_BYTES(buf, 6, 9);
- H5_SWAP_BYTES(buf, 7, 8);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 15); /* 1 */
- H5_SWAP_BYTES(buf, 1, 14);
- H5_SWAP_BYTES(buf, 2, 13);
- H5_SWAP_BYTES(buf, 3, 12);
- H5_SWAP_BYTES(buf, 4, 11);
- H5_SWAP_BYTES(buf, 5, 10);
- H5_SWAP_BYTES(buf, 6, 9);
- H5_SWAP_BYTES(buf, 7, 8);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 15); /* 2 */
- H5_SWAP_BYTES(buf, 1, 14);
- H5_SWAP_BYTES(buf, 2, 13);
- H5_SWAP_BYTES(buf, 3, 12);
- H5_SWAP_BYTES(buf, 4, 11);
- H5_SWAP_BYTES(buf, 5, 10);
- H5_SWAP_BYTES(buf, 6, 9);
- H5_SWAP_BYTES(buf, 7, 8);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 15); /* 3 */
- H5_SWAP_BYTES(buf, 1, 14);
- H5_SWAP_BYTES(buf, 2, 13);
- H5_SWAP_BYTES(buf, 3, 12);
- H5_SWAP_BYTES(buf, 4, 11);
- H5_SWAP_BYTES(buf, 5, 10);
- H5_SWAP_BYTES(buf, 6, 9);
- H5_SWAP_BYTES(buf, 7, 8);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 15); /* 4 */
- H5_SWAP_BYTES(buf, 1, 14);
- H5_SWAP_BYTES(buf, 2, 13);
- H5_SWAP_BYTES(buf, 3, 12);
- H5_SWAP_BYTES(buf, 4, 11);
- H5_SWAP_BYTES(buf, 5, 10);
- H5_SWAP_BYTES(buf, 6, 9);
- H5_SWAP_BYTES(buf, 7, 8);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 15); /* 5 */
- H5_SWAP_BYTES(buf, 1, 14);
- H5_SWAP_BYTES(buf, 2, 13);
- H5_SWAP_BYTES(buf, 3, 12);
- H5_SWAP_BYTES(buf, 4, 11);
- H5_SWAP_BYTES(buf, 5, 10);
- H5_SWAP_BYTES(buf, 6, 9);
- H5_SWAP_BYTES(buf, 7, 8);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 15); /* 6 */
- H5_SWAP_BYTES(buf, 1, 14);
- H5_SWAP_BYTES(buf, 2, 13);
- H5_SWAP_BYTES(buf, 3, 12);
- H5_SWAP_BYTES(buf, 4, 11);
- H5_SWAP_BYTES(buf, 5, 10);
- H5_SWAP_BYTES(buf, 6, 9);
- H5_SWAP_BYTES(buf, 7, 8);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 15); /* 7 */
- H5_SWAP_BYTES(buf, 1, 14);
- H5_SWAP_BYTES(buf, 2, 13);
- H5_SWAP_BYTES(buf, 3, 12);
- H5_SWAP_BYTES(buf, 4, 11);
- H5_SWAP_BYTES(buf, 5, 10);
- H5_SWAP_BYTES(buf, 6, 9);
- H5_SWAP_BYTES(buf, 7, 8);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 15); /* 8 */
- H5_SWAP_BYTES(buf, 1, 14);
- H5_SWAP_BYTES(buf, 2, 13);
- H5_SWAP_BYTES(buf, 3, 12);
- H5_SWAP_BYTES(buf, 4, 11);
- H5_SWAP_BYTES(buf, 5, 10);
- H5_SWAP_BYTES(buf, 6, 9);
- H5_SWAP_BYTES(buf, 7, 8);
- buf += buf_stride;
- H5_SWAP_BYTES(buf, 0, 15); /* 9 */
- H5_SWAP_BYTES(buf, 1, 14);
- H5_SWAP_BYTES(buf, 2, 13);
- H5_SWAP_BYTES(buf, 3, 12);
- H5_SWAP_BYTES(buf, 4, 11);
- H5_SWAP_BYTES(buf, 5, 10);
- H5_SWAP_BYTES(buf, 6, 9);
- H5_SWAP_BYTES(buf, 7, 8);
- buf += buf_stride;
- }
- for (i=0; i<nelmts; i++, buf+=buf_stride) {
- H5_SWAP_BYTES(buf, 0, 15);
- H5_SWAP_BYTES(buf, 1, 14);
- H5_SWAP_BYTES(buf, 2, 13);
- H5_SWAP_BYTES(buf, 3, 12);
- H5_SWAP_BYTES(buf, 4, 11);
- H5_SWAP_BYTES(buf, 5, 10);
- H5_SWAP_BYTES(buf, 6, 9);
- H5_SWAP_BYTES(buf, 7, 8);
- }
+
+ case H5T_CONV_CONV:
+ /* The conversion */
+ if(NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
+
+ /* Check for "no op" reference conversion */
+ if(src->shared->type == H5T_REFERENCE) {
+ /* Sanity check */
+ HDassert(dst->shared->type == H5T_REFERENCE);
+
+ /* Check if we are on a little-endian machine (the order that
+ * the addresses in the file must be) and just get out now, there
+ * is no need to convert the object reference. Yes, this is
+ * icky and non-portable, but I can't think of a better way to
+ * support allowing the objno in the H5O_info_t struct and the
+ * hobj_ref_t type to be compared directly without introducing a
+ * "native" hobj_ref_t datatype and I think that would break a
+ * lot of existing programs. -QAK
+ */
+ if(H5T_native_order_g == H5T_ORDER_LE)
+ break;
+ } /* end if */
+
+ buf_stride = buf_stride ? buf_stride : src->shared->size;
+ switch(src->shared->size) {
+ case 1:
+ /*no-op*/
+ break;
+
+ case 2:
+ for(/*void*/; nelmts >= 20; nelmts -= 20) {
+ H5_SWAP_BYTES(buf, 0, 1); /* 0 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 1 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 2 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 3 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 4 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 5 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 6 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 7 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 8 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 9 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 10 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 11 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 12 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 13 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 14 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 15 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 16 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 17 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 18 */
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 1); /* 19 */
+ buf += buf_stride;
+ } /* end for */
+ for(i = 0; i < nelmts; i++, buf += buf_stride)
+ H5_SWAP_BYTES(buf, 0, 1);
+ break;
+
+ case 4:
+ for(/*void*/; nelmts >= 20; nelmts -= 20) {
+ H5_SWAP_BYTES(buf, 0, 3); /* 0 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 1 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 2 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 3 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 4 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 5 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 6 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 7 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 8 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 9 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 10 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 11 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 12 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 13 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 14 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 15 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 16 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 17 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 18 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 3); /* 19 */
+ H5_SWAP_BYTES(buf, 1, 2);
+ buf += buf_stride;
+ } /* end for */
+ for(i = 0; i < nelmts; i++, buf += buf_stride) {
+ H5_SWAP_BYTES(buf, 0, 3);
+ H5_SWAP_BYTES(buf, 1, 2);
+ } /* end for */
+ break;
+
+ case 8:
+ for(/*void*/; nelmts >= 10; nelmts -= 10) {
+ H5_SWAP_BYTES(buf, 0, 7); /* 0 */
+ H5_SWAP_BYTES(buf, 1, 6);
+ H5_SWAP_BYTES(buf, 2, 5);
+ H5_SWAP_BYTES(buf, 3, 4);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 7); /* 1 */
+ H5_SWAP_BYTES(buf, 1, 6);
+ H5_SWAP_BYTES(buf, 2, 5);
+ H5_SWAP_BYTES(buf, 3, 4);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 7); /* 2 */
+ H5_SWAP_BYTES(buf, 1, 6);
+ H5_SWAP_BYTES(buf, 2, 5);
+ H5_SWAP_BYTES(buf, 3, 4);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 7); /* 3 */
+ H5_SWAP_BYTES(buf, 1, 6);
+ H5_SWAP_BYTES(buf, 2, 5);
+ H5_SWAP_BYTES(buf, 3, 4);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 7); /* 4 */
+ H5_SWAP_BYTES(buf, 1, 6);
+ H5_SWAP_BYTES(buf, 2, 5);
+ H5_SWAP_BYTES(buf, 3, 4);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 7); /* 5 */
+ H5_SWAP_BYTES(buf, 1, 6);
+ H5_SWAP_BYTES(buf, 2, 5);
+ H5_SWAP_BYTES(buf, 3, 4);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 7); /* 6 */
+ H5_SWAP_BYTES(buf, 1, 6);
+ H5_SWAP_BYTES(buf, 2, 5);
+ H5_SWAP_BYTES(buf, 3, 4);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 7); /* 7 */
+ H5_SWAP_BYTES(buf, 1, 6);
+ H5_SWAP_BYTES(buf, 2, 5);
+ H5_SWAP_BYTES(buf, 3, 4);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 7); /* 8 */
+ H5_SWAP_BYTES(buf, 1, 6);
+ H5_SWAP_BYTES(buf, 2, 5);
+ H5_SWAP_BYTES(buf, 3, 4);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 7); /* 9 */
+ H5_SWAP_BYTES(buf, 1, 6);
+ H5_SWAP_BYTES(buf, 2, 5);
+ H5_SWAP_BYTES(buf, 3, 4);
+ buf += buf_stride;
+ } /* end for */
+ for(i = 0; i < nelmts; i++, buf += buf_stride) {
+ H5_SWAP_BYTES(buf, 0, 7);
+ H5_SWAP_BYTES(buf, 1, 6);
+ H5_SWAP_BYTES(buf, 2, 5);
+ H5_SWAP_BYTES(buf, 3, 4);
+ } /* end for */
+ break;
+
+ case 16:
+ for(/*void*/; nelmts >= 10; nelmts -= 10) {
+ H5_SWAP_BYTES(buf, 0, 15); /* 0 */
+ H5_SWAP_BYTES(buf, 1, 14);
+ H5_SWAP_BYTES(buf, 2, 13);
+ H5_SWAP_BYTES(buf, 3, 12);
+ H5_SWAP_BYTES(buf, 4, 11);
+ H5_SWAP_BYTES(buf, 5, 10);
+ H5_SWAP_BYTES(buf, 6, 9);
+ H5_SWAP_BYTES(buf, 7, 8);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 15); /* 1 */
+ H5_SWAP_BYTES(buf, 1, 14);
+ H5_SWAP_BYTES(buf, 2, 13);
+ H5_SWAP_BYTES(buf, 3, 12);
+ H5_SWAP_BYTES(buf, 4, 11);
+ H5_SWAP_BYTES(buf, 5, 10);
+ H5_SWAP_BYTES(buf, 6, 9);
+ H5_SWAP_BYTES(buf, 7, 8);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 15); /* 2 */
+ H5_SWAP_BYTES(buf, 1, 14);
+ H5_SWAP_BYTES(buf, 2, 13);
+ H5_SWAP_BYTES(buf, 3, 12);
+ H5_SWAP_BYTES(buf, 4, 11);
+ H5_SWAP_BYTES(buf, 5, 10);
+ H5_SWAP_BYTES(buf, 6, 9);
+ H5_SWAP_BYTES(buf, 7, 8);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 15); /* 3 */
+ H5_SWAP_BYTES(buf, 1, 14);
+ H5_SWAP_BYTES(buf, 2, 13);
+ H5_SWAP_BYTES(buf, 3, 12);
+ H5_SWAP_BYTES(buf, 4, 11);
+ H5_SWAP_BYTES(buf, 5, 10);
+ H5_SWAP_BYTES(buf, 6, 9);
+ H5_SWAP_BYTES(buf, 7, 8);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 15); /* 4 */
+ H5_SWAP_BYTES(buf, 1, 14);
+ H5_SWAP_BYTES(buf, 2, 13);
+ H5_SWAP_BYTES(buf, 3, 12);
+ H5_SWAP_BYTES(buf, 4, 11);
+ H5_SWAP_BYTES(buf, 5, 10);
+ H5_SWAP_BYTES(buf, 6, 9);
+ H5_SWAP_BYTES(buf, 7, 8);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 15); /* 5 */
+ H5_SWAP_BYTES(buf, 1, 14);
+ H5_SWAP_BYTES(buf, 2, 13);
+ H5_SWAP_BYTES(buf, 3, 12);
+ H5_SWAP_BYTES(buf, 4, 11);
+ H5_SWAP_BYTES(buf, 5, 10);
+ H5_SWAP_BYTES(buf, 6, 9);
+ H5_SWAP_BYTES(buf, 7, 8);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 15); /* 6 */
+ H5_SWAP_BYTES(buf, 1, 14);
+ H5_SWAP_BYTES(buf, 2, 13);
+ H5_SWAP_BYTES(buf, 3, 12);
+ H5_SWAP_BYTES(buf, 4, 11);
+ H5_SWAP_BYTES(buf, 5, 10);
+ H5_SWAP_BYTES(buf, 6, 9);
+ H5_SWAP_BYTES(buf, 7, 8);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 15); /* 7 */
+ H5_SWAP_BYTES(buf, 1, 14);
+ H5_SWAP_BYTES(buf, 2, 13);
+ H5_SWAP_BYTES(buf, 3, 12);
+ H5_SWAP_BYTES(buf, 4, 11);
+ H5_SWAP_BYTES(buf, 5, 10);
+ H5_SWAP_BYTES(buf, 6, 9);
+ H5_SWAP_BYTES(buf, 7, 8);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 15); /* 8 */
+ H5_SWAP_BYTES(buf, 1, 14);
+ H5_SWAP_BYTES(buf, 2, 13);
+ H5_SWAP_BYTES(buf, 3, 12);
+ H5_SWAP_BYTES(buf, 4, 11);
+ H5_SWAP_BYTES(buf, 5, 10);
+ H5_SWAP_BYTES(buf, 6, 9);
+ H5_SWAP_BYTES(buf, 7, 8);
+ buf += buf_stride;
+ H5_SWAP_BYTES(buf, 0, 15); /* 9 */
+ H5_SWAP_BYTES(buf, 1, 14);
+ H5_SWAP_BYTES(buf, 2, 13);
+ H5_SWAP_BYTES(buf, 3, 12);
+ H5_SWAP_BYTES(buf, 4, 11);
+ H5_SWAP_BYTES(buf, 5, 10);
+ H5_SWAP_BYTES(buf, 6, 9);
+ H5_SWAP_BYTES(buf, 7, 8);
+ buf += buf_stride;
+ } /* end for */
+ for(i = 0; i < nelmts; i++, buf += buf_stride) {
+ H5_SWAP_BYTES(buf, 0, 15);
+ H5_SWAP_BYTES(buf, 1, 14);
+ H5_SWAP_BYTES(buf, 2, 13);
+ H5_SWAP_BYTES(buf, 3, 12);
+ H5_SWAP_BYTES(buf, 4, 11);
+ H5_SWAP_BYTES(buf, 5, 10);
+ H5_SWAP_BYTES(buf, 6, 9);
+ H5_SWAP_BYTES(buf, 7, 8);
+ } /* end for */
+ break;
+ } /* end switch */
break;
- }
- break;
- case H5T_CONV_FREE:
- /* Free private data */
- break;
+ case H5T_CONV_FREE:
+ /* Free private data */
+ break;
- default:
- HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
- }
+ default:
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command")
+ } /* end switch */
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_conv_order_opt() */
/*-------------------------------------------------------------------------
@@ -1368,73 +1439,72 @@ H5T_conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
H5T_t *dst = NULL;
size_t i;
size_t j, md;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_order, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_order, FAIL)
- switch (cdata->command) {
- case H5T_CONV_INIT:
- /* Capability query */
- if (NULL == (src = H5I_object(src_id)) ||
- NULL == (dst = H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- if (src->shared->size != dst->shared->size || 0 != src->shared->u.atomic.offset ||
- 0 != dst->shared->u.atomic.offset ||
- !((H5T_ORDER_BE == src->shared->u.atomic.order &&
- H5T_ORDER_LE == dst->shared->u.atomic.order) ||
- (H5T_ORDER_LE == src->shared->u.atomic.order &&
- H5T_ORDER_BE == dst->shared->u.atomic.order)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
- switch (src->shared->type) {
- case H5T_INTEGER:
- case H5T_BITFIELD:
- /* nothing to check */
- break;
+ switch(cdata->command) {
+ case H5T_CONV_INIT:
+ /* Capability query */
+ if(NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
+ if(src->shared->size != dst->shared->size || 0 != src->shared->u.atomic.offset ||
+ 0 != dst->shared->u.atomic.offset ||
+ !((H5T_ORDER_BE == src->shared->u.atomic.order &&
+ H5T_ORDER_LE == dst->shared->u.atomic.order) ||
+ (H5T_ORDER_LE == src->shared->u.atomic.order &&
+ H5T_ORDER_BE == dst->shared->u.atomic.order)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported")
+ switch(src->shared->type) {
+ case H5T_INTEGER:
+ case H5T_BITFIELD:
+ /* nothing to check */
+ break;
- case H5T_FLOAT:
- if (src->shared->u.atomic.u.f.sign != dst->shared->u.atomic.u.f.sign ||
- src->shared->u.atomic.u.f.epos != dst->shared->u.atomic.u.f.epos ||
- src->shared->u.atomic.u.f.esize != dst->shared->u.atomic.u.f.esize ||
- src->shared->u.atomic.u.f.ebias != dst->shared->u.atomic.u.f.ebias ||
- src->shared->u.atomic.u.f.mpos != dst->shared->u.atomic.u.f.mpos ||
- src->shared->u.atomic.u.f.msize != dst->shared->u.atomic.u.f.msize ||
- src->shared->u.atomic.u.f.norm != dst->shared->u.atomic.u.f.norm ||
- src->shared->u.atomic.u.f.pad != dst->shared->u.atomic.u.f.pad) {
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
- }
- break;
+ case H5T_FLOAT:
+ if(src->shared->u.atomic.u.f.sign != dst->shared->u.atomic.u.f.sign ||
+ src->shared->u.atomic.u.f.epos != dst->shared->u.atomic.u.f.epos ||
+ src->shared->u.atomic.u.f.esize != dst->shared->u.atomic.u.f.esize ||
+ src->shared->u.atomic.u.f.ebias != dst->shared->u.atomic.u.f.ebias ||
+ src->shared->u.atomic.u.f.mpos != dst->shared->u.atomic.u.f.mpos ||
+ src->shared->u.atomic.u.f.msize != dst->shared->u.atomic.u.f.msize ||
+ src->shared->u.atomic.u.f.norm != dst->shared->u.atomic.u.f.norm ||
+ src->shared->u.atomic.u.f.pad != dst->shared->u.atomic.u.f.pad) {
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported")
+ } /* end if */
+ break;
- default:
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
- }
- cdata->need_bkg = H5T_BKG_NO;
- break;
-
- case H5T_CONV_CONV:
- /* The conversion */
- if (NULL == (src = H5I_object(src_id)) ||
- NULL == (dst = H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
-
- buf_stride = buf_stride ? buf_stride : src->shared->size;
- md = src->shared->size / 2;
- for (i=0; i<nelmts; i++, buf+=buf_stride) {
- for (j=0; j<md; j++)
- H5_SWAP_BYTES(buf, j, src->shared->size-(j+1));
- }
- break;
+ default:
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported")
+ } /* end switch */
+ cdata->need_bkg = H5T_BKG_NO;
+ break;
- case H5T_CONV_FREE:
- /* Free private data */
- break;
+ case H5T_CONV_CONV:
+ /* The conversion */
+ if(NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
- default:
- HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
- }
+ buf_stride = buf_stride ? buf_stride : src->shared->size;
+ md = src->shared->size / 2;
+ for(i = 0; i < nelmts; i++, buf += buf_stride)
+ for(j = 0; j < md; j++)
+ H5_SWAP_BYTES(buf, j, src->shared->size - (j + 1));
+ break;
+
+ case H5T_CONV_FREE:
+ /* Free private data */
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command")
+ } /* end switch */
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_conv_order() */
/*-------------------------------------------------------------------------
@@ -1461,7 +1531,7 @@ H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
void UNUSED *background, hid_t dxpl_id)
{
uint8_t *buf = (uint8_t*)_buf;
- H5T_t *src=NULL, *dst=NULL; /*source and dest data types */
+ H5T_t *src = NULL, *dst = NULL; /*source and dest data types */
int direction; /*direction of traversal */
size_t elmtno; /*element number */
size_t olap; /*num overlapping elements */
@@ -1472,25 +1542,25 @@ H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
size_t i;
uint8_t *src_rev=NULL; /*order-reversed source buffer */
H5P_genplist_t *plist; /*property list pointer */
- H5T_conv_cb_t cb_struct={NULL, NULL}; /*conversion callback structure */
+ H5T_conv_cb_t cb_struct = {NULL, NULL}; /*conversion callback structure */
H5T_conv_ret_t except_ret; /*return of callback function */
hbool_t reverse; /*if reverse the order of destination */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_b_b, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_b_b, FAIL)
switch(cdata->command) {
case H5T_CONV_INIT:
/* Capability query */
- if (NULL == (src = H5I_object(src_id)) ||
+ if(NULL == (src = H5I_object(src_id)) ||
NULL == (dst = H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- if (H5T_ORDER_LE!=src->shared->u.atomic.order &&
- H5T_ORDER_BE!=src->shared->u.atomic.order)
- HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
- if (H5T_ORDER_LE!=dst->shared->u.atomic.order &&
- H5T_ORDER_BE!=dst->shared->u.atomic.order)
- HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
+ if(H5T_ORDER_LE != src->shared->u.atomic.order &&
+ H5T_ORDER_BE != src->shared->u.atomic.order)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order")
+ if(H5T_ORDER_LE != dst->shared->u.atomic.order &&
+ H5T_ORDER_BE != dst->shared->u.atomic.order)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order")
cdata->need_bkg = H5T_BKG_NO;
break;
@@ -1499,29 +1569,29 @@ H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
case H5T_CONV_CONV:
/* Get the data types */
- if (NULL==(src=H5I_object(src_id)) ||
- NULL==(dst=H5I_object(dst_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ if(NULL == (src = H5I_object(src_id)) ||
+ NULL == (dst = H5I_object(dst_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
/*
* Do we process the values from beginning to end or vice versa? Also,
* how many of the elements have the source and destination areas
* overlapping?
*/
- if (src->shared->size==dst->shared->size || buf_stride) {
+ if(src->shared->size == dst->shared->size || buf_stride) {
sp = dp = (uint8_t*)buf;
direction = 1;
olap = nelmts;
- } else if (src->shared->size>=dst->shared->size) {
- double olap_d = HDceil((double)(dst->shared->size)/
- (double)(src->shared->size-dst->shared->size));
+ } else if(src->shared->size >= dst->shared->size) {
+ double olap_d = HDceil((double)(dst->shared->size) /
+ (double)(src->shared->size - dst->shared->size));
olap = (size_t)olap_d;
sp = dp = (uint8_t*)buf;
direction = 1;
} else {
- double olap_d = HDceil((double)(src->shared->size)/
- (double)(dst->shared->size-src->shared->size));
+ double olap_d = HDceil((double)(src->shared->size) /
+ (double)(dst->shared->size - src->shared->size));
olap = (size_t)olap_d;
sp = (uint8_t*)buf + (nelmts-1) * src->shared->size;
dp = (uint8_t*)buf + (nelmts-1) * dst->shared->size;
@@ -1529,39 +1599,39 @@ H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
}
/* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID");
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID")
/* Get conversion exception callback property */
- if (H5P_get(plist,H5D_XFER_CONV_CB_NAME,&cb_struct)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback");
+ if(H5P_get(plist, H5D_XFER_CONV_CB_NAME, &cb_struct) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback")
/* Allocate space for order-reversed source buffer */
- src_rev = (uint8_t*)H5MM_calloc(src->shared->size);
+ src_rev = (uint8_t *)H5MM_calloc(src->shared->size);
/* The conversion loop */
- for (elmtno=0; elmtno<nelmts; elmtno++) {
+ for(elmtno = 0; elmtno < nelmts; elmtno++) {
/*
* If the source and destination buffers overlap then use a
* temporary buffer for the destination.
*/
- if (direction>0) {
+ if(direction > 0) {
s = sp;
- d = elmtno<olap ? dbuf : dp;
- } else {
+ d = elmtno < olap ? dbuf : dp;
+ } /* end if */
+ else {
s = sp;
- d = elmtno+olap >= nelmts ? dbuf : dp;
- }
+ d = (elmtno + olap) >= nelmts ? dbuf : dp;
+ } /* end else */
#ifndef NDEBUG
/* I don't quite trust the overlap calculations yet --rpm */
- if (d==dbuf) {
- assert ((dp>=sp && dp<sp+src->shared->size) ||
- (sp>=dp && sp<dp+dst->shared->size));
- } else {
- assert ((dp<sp && dp+dst->shared->size<=sp) ||
- (sp<dp && sp+src->shared->size<=dp));
- }
+ if(d == dbuf)
+ HDassert((dp >= sp && dp < sp + src->shared->size) ||
+ (sp >= dp && sp < dp + dst->shared->size));
+ else
+ HDassert((dp < sp && dp + dst->shared->size<=sp) ||
+ (sp < dp && sp + src->shared->size<=dp));
#endif
/*
@@ -1569,14 +1639,14 @@ H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
* complicated. We'll do all the conversion stuff assuming
* little endian and then we'll fix the order at the end.
*/
- if (H5T_ORDER_BE==src->shared->u.atomic.order) {
- half_size = src->shared->size/2;
- for (i=0; i<half_size; i++) {
- uint8_t tmp = s[src->shared->size-(i+1)];
- s[src->shared->size-(i+1)] = s[i];
+ if(H5T_ORDER_BE == src->shared->u.atomic.order) {
+ half_size = src->shared->size / 2;
+ for(i = 0; i < half_size; i++) {
+ uint8_t tmp = s[src->shared->size - (i + 1)];
+ s[src->shared->size - (i + 1)] = s[i];
s[i] = tmp;
- }
- }
+ } /* end for */
+ } /* end if */
/* Initiate these variables */
except_ret = H5T_CONV_UNHANDLED;
@@ -1587,13 +1657,13 @@ H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
* than the destination then invoke the overflow function or copy
* as many bits as possible. Zero extra bits in the destination.
*/
- if (src->shared->u.atomic.prec>dst->shared->u.atomic.prec) {
+ if(src->shared->u.atomic.prec > dst->shared->u.atomic.prec) {
/*overflow*/
if(cb_struct.func) { /*If user's exception handler is present, use it*/
H5T_reverse_order(src_rev, s, src->shared->size, src->shared->u.atomic.order); /*reverse order first*/
except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id,
src_rev, d, cb_struct.user_data);
- }
+ } /* end if */
if(except_ret == H5T_CONV_UNHANDLED) {
H5T_bit_copy(d, dst->shared->u.atomic.offset,
@@ -1614,67 +1684,112 @@ H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
/*
* Fill the destination padding areas.
*/
- switch (dst->shared->u.atomic.lsb_pad) {
+ switch(dst->shared->u.atomic.lsb_pad) {
case H5T_PAD_ZERO:
H5T_bit_set(d, (size_t)0, dst->shared->u.atomic.offset, FALSE);
break;
+
case H5T_PAD_ONE:
H5T_bit_set(d, (size_t)0, dst->shared->u.atomic.offset, TRUE);
break;
+
default:
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported LSB padding");
- }
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported LSB padding")
+ } /* end switch */
msb_pad_offset = dst->shared->u.atomic.offset + dst->shared->u.atomic.prec;
- switch (dst->shared->u.atomic.msb_pad) {
+ switch(dst->shared->u.atomic.msb_pad) {
case H5T_PAD_ZERO:
- H5T_bit_set(d, msb_pad_offset, 8*dst->shared->size-msb_pad_offset,
- FALSE);
+ H5T_bit_set(d, msb_pad_offset, 8 * dst->shared->size - msb_pad_offset, FALSE);
break;
+
case H5T_PAD_ONE:
- H5T_bit_set(d, msb_pad_offset, 8*dst->shared->size-msb_pad_offset,
- TRUE);
+ H5T_bit_set(d, msb_pad_offset, 8 * dst->shared->size - msb_pad_offset, TRUE);
break;
default:
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported MSB padding");
- }
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported MSB padding")
+ } /* end switch */
/*
* Put the destination in the correct byte order. See note at
* beginning of loop.
*/
- if (H5T_ORDER_BE==dst->shared->u.atomic.order && reverse) {
- half_size = dst->shared->size/2;
- for (i=0; i<half_size; i++) {
- uint8_t tmp = d[dst->shared->size-(i+1)];
- d[dst->shared->size-(i+1)] = d[i];
+ if(H5T_ORDER_BE == dst->shared->u.atomic.order && reverse) {
+ half_size = dst->shared->size / 2;
+ for(i = 0; i < half_size; i++) {
+ uint8_t tmp = d[dst->shared->size - (i + 1)];
+ d[dst->shared->size - (i + 1)] = d[i];
d[i] = tmp;
- }
- }
+ } /* end for */
+ } /* end if */
/*
* If we had used a temporary buffer for the destination then we
* should copy the value to the true destination buffer.
*/
- if (d==dbuf) HDmemcpy (dp, d, dst->shared->size);
- if (buf_stride) {
+ if(d == dbuf)
+ HDmemcpy(dp, d, dst->shared->size);
+ if(buf_stride) {
sp += direction * buf_stride;
dp += direction * buf_stride;
- } else {
+ } /* end if */
+ else {
sp += direction * src->shared->size;
dp += direction * dst->shared->size;
- }
- }
+ } /* end else */
+ } /* end for */
break;
default:
- HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
- }
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command")
+ } /* end switch */
done:
if(src_rev)
H5MM_free(src_rev);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_conv_b_b() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_conv_struct_free
+ *
+ * Purpose: Free the private data structure used by the compound
+ * conversion functions.
+ *
+ * Return: The result of H5MM_xfree(priv) (NULL)
+ *
+ * Programmer: Neil Fortner
+ * Wednesday, October 1, 2008
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5T_conv_struct_t *
+H5T_conv_struct_free(H5T_conv_struct_t *priv)
+{
+ int *src2dst = priv->src2dst;
+ hid_t *src_memb_id = priv->src_memb_id,
+ *dst_memb_id = priv->dst_memb_id;
+ unsigned i;
+ int status;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_conv_struct_free)
+
+ for (i=0; i<priv->src_nmembs; i++)
+ if (src2dst[i] >= 0) {
+ status = H5I_dec_ref(src_memb_id[i], FALSE);
+ HDassert(status >= 0);
+ status = H5I_dec_ref(dst_memb_id[src2dst[i]], FALSE);
+ HDassert(status >= 0);
+ }
+
+ H5MM_xfree(src2dst);
+ H5MM_xfree(src_memb_id);
+ H5MM_xfree(dst_memb_id);
+ H5MM_xfree(priv->memb_path);
+ FUNC_LEAVE_NOAPI(H5MM_xfree(priv));
}
@@ -1688,8 +1803,8 @@ done:
*
* Priv fields are indexed by source member number or
* destination member number depending on whether the field
- * contains information about the source data type or the
- * destination data type (fields that contains the same
+ * contains information about the source datatype or the
+ * destination datatype (fields that contains the same
* information for both source and destination are indexed by
* source member number). The src2dst[] priv array maps source
* member numbers to destination member numbers, but if the
@@ -1703,8 +1818,8 @@ done:
*
* Modifications:
* Raymond Lu, 3 May 2007
- * Added the detection for a special optimization case when the
- * source and destination members are a subset of each other, and
+ * Added the detection for a special optimization case when the
+ * source and destination members are a subset of each other, and
* the order is the same, and no conversion is needed. For example:
* struct source { struct destination {
* TYPE1 A; --> TYPE1 A;
@@ -1721,13 +1836,13 @@ done:
* }; TYPE4 D;
* TYPE5 E;
* };
- * The optimization is simply moving data to the appropriate
+ * The optimization is simply moving data to the appropriate
* places in the buffer.
- *
+ *
*-------------------------------------------------------------------------
*/
static herr_t
-H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id)
+H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id)
{
H5T_conv_struct_t *priv = (H5T_conv_struct_t*)(cdata->priv);
int *src2dst = NULL;
@@ -1737,25 +1852,27 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id)
hid_t tid;
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5T_conv_struct_init);
+ FUNC_ENTER_NOAPI_NOINIT(H5T_conv_struct_init)
src_nmembs = src->shared->u.compnd.nmembs;
dst_nmembs = dst->shared->u.compnd.nmembs;
- if (!priv) {
+ if(!priv) {
/*
* Allocate private data structure and arrays.
*/
- if (NULL==(priv=cdata->priv=H5MM_calloc(sizeof(H5T_conv_struct_t))) ||
- NULL==(priv->src2dst=H5MM_malloc(src_nmembs * sizeof(int))) ||
- NULL==(priv->src_memb_id=H5MM_malloc(src_nmembs * sizeof(hid_t))) ||
- NULL==(priv->dst_memb_id=H5MM_malloc(dst_nmembs * sizeof(hid_t))))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ if(NULL == (priv = cdata->priv=H5MM_calloc(sizeof(H5T_conv_struct_t))) ||
+ NULL == (priv->src2dst = H5MM_malloc(src_nmembs * sizeof(int))) ||
+ NULL == (priv->src_memb_id = H5MM_malloc(src_nmembs * sizeof(hid_t))) ||
+ NULL == (priv->dst_memb_id = H5MM_malloc(dst_nmembs * sizeof(hid_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
src2dst = priv->src2dst;
+ priv->src_nmembs = src_nmembs;
/* The flag of special optimization to indicate if source members and destination
* members are a subset of each other. Initialize it to FALSE */
- priv->smembs_subset = H5T_SUBSET_FALSE;
+ priv->subset_info.subset = H5T_SUBSET_FALSE;
+ priv->subset_info.copy_size = 0;
/*
* Insure that members are sorted.
@@ -1767,32 +1884,30 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id)
* Build a mapping from source member number to destination member
* number. If some source member is not a destination member then that
* mapping element will be negative. Also create atoms for each
- * source and destination member data type so we can look up the
- * member data type conversion functions later.
+ * source and destination member datatype so we can look up the
+ * member datatype conversion functions later.
*/
- for (i=0; i<src_nmembs; i++) {
+ for(i = 0; i < src_nmembs; i++) {
src2dst[i] = -1;
- for (j=0; j<dst_nmembs; j++) {
- if (!HDstrcmp (src->shared->u.compnd.memb[i].name,
- dst->shared->u.compnd.memb[j].name)) {
+ for(j = 0; j < dst_nmembs; j++) {
+ if(!HDstrcmp(src->shared->u.compnd.memb[i].name, dst->shared->u.compnd.memb[j].name)) {
src2dst[i] = j;
break;
- }
- }
- if (src2dst[i]>=0) {
- type = H5T_copy (src->shared->u.compnd.memb[i].type, H5T_COPY_ALL);
- tid = H5I_register (H5I_DATATYPE, type);
- assert (tid>=0);
+ } /* end if */
+ } /* end for */
+ if(src2dst[i] >= 0) {
+ type = H5T_copy(src->shared->u.compnd.memb[i].type, H5T_COPY_ALL);
+ tid = H5I_register(H5I_DATATYPE, type, FALSE);
+ HDassert(tid>=0);
priv->src_memb_id[i] = tid;
- type = H5T_copy (dst->shared->u.compnd.memb[src2dst[i]].type,
- H5T_COPY_ALL);
- tid = H5I_register (H5I_DATATYPE, type);
- assert (tid>=0);
+ type = H5T_copy(dst->shared->u.compnd.memb[src2dst[i]].type, H5T_COPY_ALL);
+ tid = H5I_register(H5I_DATATYPE, type, FALSE);
+ HDassert(tid >= 0);
priv->dst_memb_id[src2dst[i]] = tid;
- }
- }
- }
+ } /* end if */
+ } /* end for */
+ } /* end if */
else {
/* Restore sorted conditions for the datatypes */
/* (Required for the src2dst array to be valid) */
@@ -1806,61 +1921,68 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id)
*/
src2dst = priv->src2dst;
H5MM_xfree(priv->memb_path);
- if (NULL==(priv->memb_path=H5MM_malloc(src->shared->u.compnd.nmembs *
- sizeof(H5T_path_t*))))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ if(NULL == (priv->memb_path = H5MM_malloc(src->shared->u.compnd.nmembs * sizeof(H5T_path_t*))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- for (i=0; i<src_nmembs; i++) {
- if (src2dst[i]>=0) {
- H5T_path_t *tpath = H5T_path_find(src->shared->u.compnd.memb[i].type,
- dst->shared->u.compnd.memb[src2dst[i]].type, NULL, NULL, dxpl_id, FALSE);
-
- if (NULL==(priv->memb_path[i] = tpath)) {
- H5MM_xfree(priv->src2dst);
- H5MM_xfree(priv->src_memb_id);
- H5MM_xfree(priv->dst_memb_id);
- H5MM_xfree(priv->memb_path);
- cdata->priv = priv = H5MM_xfree (priv);
- HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert member data type");
- }
- }
- }
+ for(i = 0; i < src_nmembs; i++) {
+ if(src2dst[i] >= 0) {
+ H5T_path_t *tpath = H5T_path_find(src->shared->u.compnd.memb[i].type, dst->shared->u.compnd.memb[src2dst[i]].type, NULL, NULL, dxpl_id, FALSE);
- /* Check if we need a background buffer */
- if (H5T_detect_class(src,H5T_COMPOUND)==TRUE || H5T_detect_class(dst,H5T_COMPOUND)==TRUE) {
- cdata->need_bkg = H5T_BKG_YES;
-
- if(src_nmembs < dst_nmembs) {
- priv->smembs_subset = H5T_SUBSET_SRC;
- for (i=0; i<src_nmembs; i++) {
- /* If any of source members doesn't have counterpart in the same order or
- * there's conversion between members, don't do the optimization. */
- if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset !=
- dst->shared->u.compnd.memb[i].offset) || (priv->memb_path[i])->is_noop ==
- FALSE)
- priv->smembs_subset = H5T_SUBSET_FALSE;
- }
- } else if(dst_nmembs < src_nmembs) {
- priv->smembs_subset = H5T_SUBSET_DST;
- for (i=0; i<dst_nmembs; i++) {
- /* If any of source members doesn't have counterpart in the same order or
- * there's conversion between members, don't do the optimization. */
- if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset !=
- dst->shared->u.compnd.memb[i].offset) || (priv->memb_path[i])->is_noop ==
- FALSE)
- priv->smembs_subset = H5T_SUBSET_FALSE;
+ if(NULL == (priv->memb_path[i] = tpath)) {
+ cdata->priv = priv = H5T_conv_struct_free(priv);
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert member datatype")
+ } /* end if */
+ } /* end if */
+ } /* end for */
+
+ /* The compound conversion functions need a background buffer */
+ cdata->need_bkg = H5T_BKG_YES;
+
+ if(src_nmembs < dst_nmembs) {
+ priv->subset_info.subset = H5T_SUBSET_SRC;
+ for(i = 0; i < src_nmembs; i++) {
+ /* If any of source members doesn't have counterpart in the same
+ * order or there's conversion between members, don't do the
+ * optimization.
+ */
+ if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || (priv->memb_path[i])->is_noop == FALSE) {
+ priv->subset_info.subset = H5T_SUBSET_FALSE;
+ break;
+ } /* end if */
+ } /* end for */
+ /* Compute the size of the data to be copied for each element. It
+ * may be smaller than either src or dst if there is extra space at
+ * the end of src.
+ */
+ if(priv->subset_info.subset == H5T_SUBSET_SRC)
+ priv->subset_info.copy_size = src->shared->u.compnd.memb[src_nmembs-1].offset
+ + src->shared->u.compnd.memb[src_nmembs-1].size;
+ } else if(dst_nmembs < src_nmembs) {
+ priv->subset_info.subset = H5T_SUBSET_DST;
+ for(i = 0; i < dst_nmembs; i++) {
+ /* If any of source members doesn't have counterpart in the same order or
+ * there's conversion between members, don't do the optimization. */
+ if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || (priv->memb_path[i])->is_noop == FALSE) {
+ priv->subset_info.subset = H5T_SUBSET_FALSE;
+ break;
}
- } else /* If the numbers of source and dest members are equal and no conversion is needed,
- * the case should have been handled as noop earlier in H5Dio.c. */
- ;
-
- }
+ } /* end for */
+ /* Compute the size of the data to be copied for each element. It
+ * may be smaller than either src or dst if there is extra space at
+ * the end of dst.
+ */
+ if(priv->subset_info.subset == H5T_SUBSET_DST)
+ priv->subset_info.copy_size = dst->shared->u.compnd.memb[dst_nmembs-1].offset
+ + dst->shared->u.compnd.memb[dst_nmembs-1].size;
+ } else /* If the numbers of source and dest members are equal and no conversion is needed,
+ * the case should have been handled as noop earlier in H5Dio.c. */
+ ;
cdata->recalc = FALSE;
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_conv_struct_init() */
/*-------------------------------------------------------------------------
@@ -1868,7 +1990,7 @@ done:
*
* Purpose: A quick way to return a field in a struct private in this
* file. The flag SMEMBS_SUBSET indicates whether the source
- * members are a subset of destination or the destination
+ * members are a subset of destination or the destination
* members are a subset of the source, and the order is the
* same, and no conversion is needed. For example:
* struct source { struct destination {
@@ -1879,14 +2001,15 @@ done:
* TYPE5 E;
* };
*
- * Return: One of the value from H5T_subset_t.
+ * Return: A pointer to the subset info struct in p. Points directly
+ * into the structure.
*
* Programmer: Raymond Lu
* 8 June 2007
*
*-------------------------------------------------------------------------
*/
-H5T_subset_t
+H5T_subset_info_t *
H5T_conv_struct_subset(const H5T_cdata_t *cdata)
{
H5T_conv_struct_t *priv;
@@ -1898,14 +2021,14 @@ H5T_conv_struct_subset(const H5T_cdata_t *cdata)
priv = (H5T_conv_struct_t *)(cdata->priv);
- FUNC_LEAVE_NOAPI(priv->smembs_subset)
+ FUNC_LEAVE_NOAPI((H5T_subset_info_t *) &priv->subset_info)
} /* end H5T_conv_struct_subset() */
/*-------------------------------------------------------------------------
* Function: H5T_conv_struct
*
- * Purpose: Converts between compound data types. This is a soft
+ * Purpose: Converts between compound datatypes. This is a soft
* conversion function. The algorithm is basically:
*
* For each element do
@@ -1950,8 +2073,8 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
uint8_t *buf = (uint8_t *)_buf; /*cast for pointer arithmetic */
uint8_t *bkg = (uint8_t *)_bkg; /*background pointer arithmetic */
uint8_t *xbuf=buf, *xbkg=bkg; /*temp pointers into buf and bkg*/
- H5T_t *src = NULL; /*source data type */
- H5T_t *dst = NULL; /*destination data type */
+ H5T_t *src = NULL; /*source datatype */
+ H5T_t *dst = NULL; /*destination datatype */
int *src2dst = NULL; /*maps src member to dst member */
H5T_cmemb_t *src_memb = NULL; /*source struct member descript.*/
H5T_cmemb_t *dst_memb = NULL; /*destination struct memb desc. */
@@ -1963,7 +2086,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
H5T_conv_struct_t *priv = (H5T_conv_struct_t *)(cdata->priv);
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_struct, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_struct, FAIL)
switch (cdata->command) {
case H5T_CONV_INIT:
@@ -1975,7 +2098,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
*/
if (NULL == (src = H5I_object(src_id)) ||
NULL == (dst = H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
assert (H5T_COMPOUND==src->shared->type);
assert (H5T_COMPOUND==dst->shared->type);
@@ -1987,11 +2110,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
/*
* Free the private conversion data.
*/
- H5MM_xfree(priv->src2dst);
- H5MM_xfree(priv->src_memb_id);
- H5MM_xfree(priv->dst_memb_id);
- H5MM_xfree(priv->memb_path);
- cdata->priv = priv = H5MM_xfree (priv);
+ cdata->priv = priv = H5T_conv_struct_free(priv);
break;
case H5T_CONV_CONV:
@@ -2000,7 +2119,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
*/
if (NULL == (src = H5I_object(src_id)) ||
NULL == (dst = H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
assert (priv);
assert (bkg && cdata->need_bkg);
@@ -2052,7 +2171,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
(size_t)1, (size_t)0, (size_t)0, /*no striding (packed array)*/
xbuf + src_memb->offset, xbkg + dst_memb->offset,
dxpl_id) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound data type member");
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound datatype member");
HDmemmove(xbuf + offset, xbuf + src_memb->offset, dst_memb->size);
offset += dst_memb->size;
} else {
@@ -2081,7 +2200,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
(size_t)1, (size_t)0, (size_t)0, /*no striding (packed array)*/
xbuf + offset, xbkg + dst_memb->offset,
dxpl_id) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound data type member");
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound datatype member");
} else
offset -= dst_memb->size;
HDmemmove(xbkg + dst_memb->offset, xbuf + offset, dst_memb->size);
@@ -2116,14 +2235,14 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
}
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_struct_opt
*
- * Purpose: Converts between compound data types in a manner more
+ * Purpose: Converts between compound datatypes in a manner more
* efficient than the general-purpose H5T_conv_struct()
* function. This function isn't applicable if the destination
* is larger than the source type. This is a soft conversion
@@ -2173,8 +2292,8 @@ done:
* datatype.
*
* Raymond Lu, 3 May 2007
- * Optimize a special case when the source and destination members
- * are a subset of each other, and the order is the same, and no
+ * Optimize a special case when the source and destination members
+ * are a subset of each other, and the order is the same, and no
* conversion is needed. For example:
* struct source { struct destination {
* TYPE1 A; --> TYPE1 A;
@@ -2183,9 +2302,9 @@ done:
* }; TYPE4 D;
* TYPE5 E;
* };
- * The optimization is simply moving data to the appropriate
+ * The optimization is simply moving data to the appropriate
* places in the buffer.
- *
+ *
*-------------------------------------------------------------------------
*/
herr_t
@@ -2197,8 +2316,8 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
uint8_t *bkg = (uint8_t *)_bkg; /*background pointer arithmetic */
uint8_t *xbuf = NULL; /*temporary pointer into `buf' */
uint8_t *xbkg = NULL; /*temporary pointer into `bkg' */
- H5T_t *src = NULL; /*source data type */
- H5T_t *dst = NULL; /*destination data type */
+ H5T_t *src = NULL; /*source datatype */
+ H5T_t *dst = NULL; /*destination datatype */
int *src2dst = NULL; /*maps src member to dst member */
H5T_cmemb_t *src_memb = NULL; /*source struct member descript.*/
H5T_cmemb_t *dst_memb = NULL; /*destination struct memb desc. */
@@ -2211,7 +2330,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
hbool_t no_stride = FALSE; /*flag to indicate no stride */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_struct_opt, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_struct_opt, FAIL)
switch (cdata->command) {
case H5T_CONV_INIT:
@@ -2223,7 +2342,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
*/
if (NULL == (src = H5I_object(src_id)) ||
NULL == (dst = H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
assert (H5T_COMPOUND==src->shared->type);
assert (H5T_COMPOUND==dst->shared->type);
@@ -2260,11 +2379,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
if (dst_memb->size > src_memb->size) {
offset -= src_memb->size;
if (dst_memb->size > src->shared->size-offset) {
- H5MM_xfree(priv->src2dst);
- H5MM_xfree(priv->src_memb_id);
- H5MM_xfree(priv->dst_memb_id);
- H5MM_xfree(priv->memb_path);
- cdata->priv = priv = H5MM_xfree (priv);
+ cdata->priv = priv = H5T_conv_struct_free(priv);
HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "convertion is unsupported by this function");
}
}
@@ -2277,11 +2392,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
* Free the private conversion data.
*/
priv = (H5T_conv_struct_t *)(cdata->priv);
- H5MM_xfree(priv->src2dst);
- H5MM_xfree(priv->src_memb_id);
- H5MM_xfree(priv->dst_memb_id);
- H5MM_xfree(priv->memb_path);
- cdata->priv = priv = H5MM_xfree (priv);
+ cdata->priv = priv = H5T_conv_struct_free(priv);
break;
case H5T_CONV_CONV:
@@ -2290,7 +2401,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
*/
if (NULL == (src = H5I_object(src_id)) ||
NULL == (dst = H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
/* Update cached data if necessary */
if (cdata->recalc && H5T_conv_struct_init (src, dst, cdata, dxpl_id)<0)
@@ -2322,25 +2433,15 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
buf_stride = src->shared->size;
}
- if(priv->smembs_subset == H5T_SUBSET_SRC || priv->smembs_subset == H5T_SUBSET_DST) {
- /* If the optimization flag is set to indicate source members are a subset and
+ if(priv->subset_info.subset == H5T_SUBSET_SRC || priv->subset_info.subset == H5T_SUBSET_DST) {
+ /* If the optimization flag is set to indicate source members are a subset and
* in the top of the destination, simply copy the source members to background buffer. */
xbuf = buf;
xbkg = bkg;
- if(dst->shared->size <= src->shared->size)
- /* This is to deal with a very special situation when the fields and their
- * offset for both source and destination are identical but the datatype
- * sizes of source and destination are different. The library still
- * considers these two types different and does conversion. It happens
- * in table API test (hdf5/hl/test/test_table.c) when a table field is
- * deleted.
- */
- copy_size = dst->shared->size;
- else
- copy_size = src->shared->size;
+ copy_size = priv->subset_info.copy_size;
for (elmtno=0; elmtno<nelmts; elmtno++) {
- HDmemmove(xbkg, xbuf, copy_size);
+ HDmemmove(xbkg, xbuf, copy_size);
/* Update pointers */
xbuf += buf_stride;
@@ -2366,7 +2467,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
priv->src_memb_id[u],
priv->dst_memb_id[src2dst[u]], nelmts,
buf_stride, bkg_stride, xbuf, xbkg, dxpl_id)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound data type member");
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound datatype member");
for (elmtno=0; elmtno<nelmts; elmtno++) {
HDmemmove(xbkg, xbuf, dst_memb->size);
xbuf += buf_stride;
@@ -2404,7 +2505,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
buf_stride,
bkg_stride, xbuf, xbkg,
dxpl_id)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound data type member");
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound datatype member");
for (elmtno=0; elmtno<nelmts; elmtno++) {
HDmemmove(xbkg, xbuf, dst_memb->size);
xbuf += buf_stride;
@@ -2431,7 +2532,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
}
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -2462,7 +2563,7 @@ H5T_conv_enum_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata)
unsigned i, j; /*counters */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5T_conv_enum_init);
+ FUNC_ENTER_NOAPI_NOINIT(H5T_conv_enum_init)
cdata->need_bkg = H5T_BKG_NO;
if (NULL==(priv=cdata->priv=H5MM_calloc(sizeof(*priv))))
@@ -2495,7 +2596,7 @@ H5T_conv_enum_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata)
* value converted. However, if all of the following constraints are met
* then we can build a perfect hash table and use an O(1) lookup method.
*
- * A: The source data type size matches one of our native data type
+ * A: The source datatype size matches one of our native datatype
* sizes.
*
* B: After casting the source value bit pattern to a native type
@@ -2567,7 +2668,7 @@ done:
H5MM_xfree(priv);
cdata->priv = NULL;
}
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -2597,7 +2698,7 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
uint8_t *buf = (uint8_t*)_buf; /*cast for pointer arithmetic */
- H5T_t *src=NULL, *dst=NULL; /*src and dst data types */
+ H5T_t *src=NULL, *dst=NULL; /*src and dst datatypes */
uint8_t *s=NULL, *d=NULL; /*src and dst BUF pointers */
int src_delta, dst_delta; /*conversion strides */
int n; /*src value cast as native int */
@@ -2608,7 +2709,7 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
H5T_conv_ret_t except_ret; /*return of callback function */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_enum, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_enum, FAIL)
switch (cdata->command) {
case H5T_CONV_INIT:
@@ -2620,7 +2721,7 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
*/
if (NULL == (src = H5I_object(src_id)) ||
NULL == (dst = H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
assert (H5T_ENUM==src->shared->type);
assert (H5T_ENUM==dst->shared->type);
if (H5T_conv_enum_init(src, dst, cdata)<0)
@@ -2645,7 +2746,7 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
case H5T_CONV_CONV:
if (NULL == (src = H5I_object(src_id)) ||
NULL == (dst = H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
assert (H5T_ENUM==src->shared->type);
assert (H5T_ENUM==dst->shared->type);
@@ -2752,14 +2853,14 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
}
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_vlen
*
- * Purpose: Converts between VL data types in memory and on disk.
+ * Purpose: Converts between VL datatypes in memory and on disk.
* This is a soft conversion function. The algorithm is
* basically:
*
@@ -2795,8 +2896,7 @@ done:
*/
herr_t
H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
- size_t buf_stride, size_t bkg_stride, void *buf,
- void *bkg, hid_t dxpl_id)
+ size_t buf_stride, size_t bkg_stride, void *buf, void *bkg, hid_t dxpl_id)
{
H5T_vlen_alloc_info_t _vl_alloc_info; /* VL allocation info buffer */
H5T_vlen_alloc_info_t *vl_alloc_info=&_vl_alloc_info; /* VL allocation info */
@@ -2805,8 +2905,8 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
hbool_t write_to_file=FALSE; /* Flag to indicate writing to file */
hbool_t parent_is_vlen; /* Flag to indicate parent is vlen datatyp */
hid_t tsrc_id = -1, tdst_id = -1;/*temporary type atoms */
- H5T_t *src = NULL; /*source data type */
- H5T_t *dst = NULL; /*destination data type */
+ H5T_t *src = NULL; /*source datatype */
+ H5T_t *dst = NULL; /*destination datatype */
H5HG_t bg_hobjid, parent_hobjid;
uint8_t *s; /*source buffer */
uint8_t *d; /*destination buffer */
@@ -2825,7 +2925,7 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
size_t elmtno; /*element number counter */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_vlen, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_vlen, FAIL)
switch (cdata->command) {
case H5T_CONV_INIT:
@@ -2836,11 +2936,10 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
* information that remains (almost) constant for this
* conversion path.
*/
- if (NULL == (src = H5I_object(src_id)) ||
- NULL == (dst = H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- assert (H5T_VLEN==src->shared->type);
- assert (H5T_VLEN==dst->shared->type);
+ if(NULL == (src = H5I_object(src_id)) || NULL == (dst = H5I_object(dst_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+ HDassert(H5T_VLEN == src->shared->type);
+ HDassert(H5T_VLEN == dst->shared->type);
/* Variable-length types don't need a background buffer */
cdata->need_bkg = H5T_BKG_NO;
@@ -2855,66 +2954,66 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
/*
* Conversion.
*/
- if (NULL == (src = H5I_object(src_id)) ||
- NULL == (dst = H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ if(NULL == (src = H5I_object(src_id)) || NULL == (dst = H5I_object(dst_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
/* Initialize source & destination strides */
- if (buf_stride) {
- assert(buf_stride>=src->shared->size);
- assert(buf_stride>=dst->shared->size);
- H5_CHECK_OVERFLOW(buf_stride,size_t,ssize_t);
+ if(buf_stride) {
+ HDassert(buf_stride >= src->shared->size);
+ HDassert(buf_stride >= dst->shared->size);
+ H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t);
s_stride = d_stride = (ssize_t)buf_stride;
- } else {
- H5_CHECK_OVERFLOW(src->shared->size,size_t,ssize_t);
- H5_CHECK_OVERFLOW(dst->shared->size,size_t,ssize_t);
+ } /* end if */
+ else {
+ H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t);
+ H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t);
s_stride = (ssize_t)src->shared->size;
d_stride = (ssize_t)dst->shared->size;
- }
+ } /* end else */
if(bkg) {
if(bkg_stride) {
- H5_CHECK_OVERFLOW(bkg_stride,size_t,ssize_t);
- b_stride=(ssize_t)bkg_stride;
+ H5_CHECK_OVERFLOW(bkg_stride, size_t, ssize_t);
+ b_stride = (ssize_t)bkg_stride;
} /* end if */
else
- b_stride=d_stride;
+ b_stride = d_stride;
} /* end if */
else
- b_stride=0;
+ b_stride = 0;
/* Get the size of the base types in src & dst */
- src_base_size=H5T_get_size(src->shared->parent);
- dst_base_size=H5T_get_size(dst->shared->parent);
+ src_base_size = H5T_get_size(src->shared->parent);
+ dst_base_size = H5T_get_size(dst->shared->parent);
/* Set up conversion path for base elements */
- if (NULL==(tpath=H5T_path_find(src->shared->parent, dst->shared->parent, NULL, NULL, dxpl_id, FALSE))) {
- HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest datatypes");
- } else if (!H5T_path_noop(tpath)) {
- if ((tsrc_id = H5I_register(H5I_DATATYPE, H5T_copy(src->shared->parent, H5T_COPY_ALL)))<0 ||
- (tdst_id = H5I_register(H5I_DATATYPE, H5T_copy(dst->shared->parent, H5T_COPY_ALL)))<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion");
+ if(NULL == (tpath = H5T_path_find(src->shared->parent, dst->shared->parent, NULL, NULL, dxpl_id, FALSE)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest datatypes")
+ else if(!H5T_path_noop(tpath)) {
+ if((tsrc_id = H5I_register(H5I_DATATYPE, H5T_copy(src->shared->parent, H5T_COPY_ALL), FALSE)) < 0 ||
+ (tdst_id = H5I_register(H5I_DATATYPE, H5T_copy(dst->shared->parent, H5T_COPY_ALL), FALSE)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
} else
- noop_conv=TRUE;
+ noop_conv = TRUE;
/* Check if we need a temporary buffer for this conversion */
- parent_is_vlen=H5T_detect_class(dst->shared->parent,H5T_VLEN);
+ parent_is_vlen = H5T_detect_class(dst->shared->parent, H5T_VLEN, FALSE);
if(tpath->cdata.need_bkg || parent_is_vlen) {
/* Set up initial background buffer */
- tmp_buf_size=MAX(src_base_size,dst_base_size);
- if ((tmp_buf=H5FL_BLK_MALLOC(vlen_seq,tmp_buf_size))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
+ tmp_buf_size = MAX(src_base_size,dst_base_size);
+ if(NULL == (tmp_buf = H5FL_BLK_MALLOC(vlen_seq,tmp_buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion")
} /* end if */
/* Get the allocation info */
- if(H5T_vlen_get_alloc_info(dxpl_id,&vl_alloc_info)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info");
+ if(H5T_vlen_get_alloc_info(dxpl_id,&vl_alloc_info) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info")
/* Set flags to indicate we are writing to or reading from the file */
- if(dst->shared->u.vlen.f!=NULL)
+ if(dst->shared->u.vlen.f != NULL)
write_to_file = TRUE;
/* Set the flag for nested VL case */
- if(write_to_file && parent_is_vlen && bkg!=NULL)
+ if(write_to_file && parent_is_vlen && bkg != NULL)
nested = TRUE;
/* The outer loop of the type conversion macro, controlling which */
@@ -3049,7 +3148,7 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
uint8_t *tmp_p;
/* TMP_P is reset each time in the loop because DST_BASE_SIZE may include some data in addition to VL info. - SLU */
for(u=seq_len; u<bg_seq_len; u++) {
- tmp_p = (uint8_t*)tmp_buf + u*dst_base_size;
+ tmp_p = (uint8_t*)tmp_buf + u*dst_base_size;
UINT32DECODE(tmp_p, parent_seq_len);
if(parent_seq_len>0) {
H5F_addr_decode(dst->shared->u.vlen.f, (const uint8_t **)&tmp_p, &(parent_hobjid.addr));
@@ -3074,9 +3173,9 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
/* Release the temporary datatype IDs used */
if (tsrc_id >= 0)
- H5I_dec_ref(tsrc_id);
+ H5I_dec_ref(tsrc_id, FALSE);
if (tdst_id >= 0)
- H5I_dec_ref(tdst_id);
+ H5I_dec_ref(tdst_id, FALSE);
break;
default: /* Some other command we don't know about yet.*/
@@ -3094,14 +3193,14 @@ done:
if(tmp_buf)
tmp_buf = H5FL_BLK_FREE(vlen_seq, tmp_buf);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_array
*
- * Purpose: Converts between array data types in memory and on disk.
+ * Purpose: Converts between array datatypes in memory and on disk.
* This is a soft conversion function.
*
* Return: Non-negative on success/Negative on failure
@@ -3120,8 +3219,8 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
{
H5T_path_t *tpath; /* Type conversion path */
hid_t tsrc_id = -1, tdst_id = -1;/*temporary type atoms */
- H5T_t *src = NULL; /*source data type */
- H5T_t *dst = NULL; /*destination data type */
+ H5T_t *src = NULL; /*source datatype */
+ H5T_t *dst = NULL; /*destination datatype */
uint8_t *sp, *dp; /*source and dest traversal ptrs */
size_t src_delta, dst_delta; /*source & destination stride */
int direction; /*direction of traversal */
@@ -3142,7 +3241,7 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
* conversion path.
*/
if(NULL == (src = H5I_object(src_id)) || NULL == (dst = H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
HDassert(H5T_ARRAY==src->shared->type);
HDassert(H5T_ARRAY==dst->shared->type);
@@ -3167,7 +3266,7 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
* Conversion.
*/
if (NULL == (src = H5I_object(src_id)) || NULL == (dst = H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
/*
* Do we process the values from beginning to end or vice
@@ -3195,8 +3294,8 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
if(NULL == (tpath = H5T_path_find(src->shared->parent, dst->shared->parent, NULL, NULL, dxpl_id, FALSE))) {
HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest datatypes")
} else if (!H5T_path_noop(tpath)) {
- if((tsrc_id = H5I_register(H5I_DATATYPE, H5T_copy(src->shared->parent, H5T_COPY_ALL))) < 0 ||
- (tdst_id = H5I_register(H5I_DATATYPE, H5T_copy(dst->shared->parent, H5T_COPY_ALL))) < 0)
+ if((tsrc_id = H5I_register(H5I_DATATYPE, H5T_copy(src->shared->parent, H5T_COPY_ALL), FALSE)) < 0 ||
+ (tdst_id = H5I_register(H5I_DATATYPE, H5T_copy(dst->shared->parent, H5T_COPY_ALL), FALSE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
}
@@ -3226,9 +3325,9 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
/* Release the temporary datatype IDs used */
if(tsrc_id >= 0)
- H5I_dec_ref(tsrc_id);
+ H5I_dec_ref(tsrc_id, FALSE);
if(tdst_id >= 0)
- H5I_dec_ref(tdst_id);
+ H5I_dec_ref(tdst_id, FALSE);
break;
default: /* Some other command we don't know about yet.*/
@@ -3273,12 +3372,12 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5T_conv_i_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
- size_t buf_stride, size_t UNUSED bkg_stride, void *buf,
- void UNUSED *bkg, hid_t dxpl_id)
+H5T_conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ size_t buf_stride, size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
+ hid_t dxpl_id)
{
- H5T_t *src = NULL; /*source data type */
- H5T_t *dst = NULL; /*destination data type */
+ H5T_t *src = NULL; /*source datatype */
+ H5T_t *dst = NULL; /*destination datatype */
int direction; /*direction of traversal */
size_t elmtno; /*element number */
size_t half_size; /*half the type size */
@@ -3295,13 +3394,13 @@ H5T_conv_i_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
hbool_t reverse; /*if reverse the order of destination */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_i_i, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_i_i, FAIL)
switch (cdata->command) {
case H5T_CONV_INIT:
if (NULL==(src=H5I_object(src_id)) ||
NULL==(dst=H5I_object(dst_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
if (H5T_ORDER_LE!=src->shared->u.atomic.order &&
H5T_ORDER_BE!=src->shared->u.atomic.order)
HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
@@ -3317,10 +3416,10 @@ H5T_conv_i_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
break;
case H5T_CONV_CONV:
- /* Get the data types */
+ /* Get the datatypes */
if (NULL==(src=H5I_object(src_id)) ||
NULL==(dst=H5I_object(dst_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
/*
* Do we process the values from beginning to end or vice versa? Also,
@@ -3648,7 +3747,7 @@ H5T_conv_i_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
done:
if(src_rev)
H5MM_free(src_rev);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -3689,8 +3788,8 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
hid_t dxpl_id)
{
/* Traversal-related variables */
- H5T_t *src_p; /*source data type */
- H5T_t *dst_p; /*destination data type */
+ H5T_t *src_p; /*source datatype */
+ H5T_t *dst_p; /*destination datatype */
H5T_atomic_t src; /*atomic source info */
H5T_atomic_t dst; /*atomic destination info */
int direction; /*forward or backward traversal */
@@ -3721,13 +3820,13 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
hbool_t reverse; /*if reverse the order of destination */
herr_t ret_value=SUCCEED; /*return value */
- FUNC_ENTER_NOAPI(H5T_conv_f_f, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_f_f, FAIL)
switch (cdata->command) {
case H5T_CONV_INIT:
if (NULL==(src_p=H5I_object(src_id)) ||
NULL==(dst_p=H5I_object(dst_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
src = src_p->shared->u.atomic;
dst = dst_p->shared->u.atomic;
if (H5T_ORDER_LE!=src.order && H5T_ORDER_BE!=src.order && H5T_ORDER_VAX!=src.order)
@@ -3745,10 +3844,10 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
break;
case H5T_CONV_CONV:
- /* Get the data types */
+ /* Get the datatypes */
if (NULL==(src_p=H5I_object(src_id)) ||
NULL==(dst_p=H5I_object(dst_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
src = src_p->shared->u.atomic;
dst = dst_p->shared->u.atomic;
expo_max = ((hssize_t)1 << dst.u.f.esize) - 1;
@@ -4227,7 +4326,7 @@ done:
if(src_rev)
H5MM_free(src_rev);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -4250,12 +4349,12 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5T_conv_s_s (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
size_t buf_stride, size_t UNUSED bkg_stride, void *buf,
void UNUSED *bkg, hid_t UNUSED dxpl_id)
{
- H5T_t *src=NULL; /*source data type */
- H5T_t *dst=NULL; /*destination data type */
+ H5T_t *src=NULL; /*source datatype */
+ H5T_t *dst=NULL; /*destination datatype */
int direction; /*direction of traversal */
size_t elmtno; /*element number */
size_t olap; /*num overlapping elements */
@@ -4264,13 +4363,13 @@ H5T_conv_s_s (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
uint8_t *dbuf=NULL; /*temp buf for overlap convers. */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_s_s, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_s_s, FAIL)
switch (cdata->command) {
case H5T_CONV_INIT:
if (NULL==(src=H5I_object(src_id)) ||
NULL==(dst=H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
if (8*src->shared->size != src->shared->u.atomic.prec || 8*dst->shared->size != dst->shared->u.atomic.prec)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad precision");
if (0 != src->shared->u.atomic.offset || 0 != dst->shared->u.atomic.offset)
@@ -4289,10 +4388,10 @@ H5T_conv_s_s (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
break;
case H5T_CONV_CONV:
- /* Get the data types */
+ /* Get the datatypes */
if (NULL==(src=H5I_object(src_id)) ||
NULL==(dst=H5I_object(dst_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
/*
* Do we process the values from beginning to end or vice versa? Also,
@@ -4454,7 +4553,7 @@ H5T_conv_s_s (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
done:
H5MM_xfree(dbuf);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -4482,12 +4581,12 @@ H5T_conv_schar_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_schar_uchar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_schar_uchar, FAIL)
H5T_CONV_su(SCHAR, UCHAR, signed char, unsigned char, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -4515,12 +4614,12 @@ H5T_conv_uchar_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uchar_schar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uchar_schar, FAIL)
H5T_CONV_us(UCHAR, SCHAR, unsigned char, signed char, -, SCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -4548,12 +4647,12 @@ H5T_conv_schar_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_schar_short, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_schar_short, FAIL)
H5T_CONV_sS(SCHAR, SHORT, signed char, short, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -4581,12 +4680,12 @@ H5T_conv_schar_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_schar_ushort, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_schar_ushort, FAIL)
H5T_CONV_sU(SCHAR, USHORT, signed char, unsigned short, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -4614,12 +4713,12 @@ H5T_conv_uchar_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uchar_short, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uchar_short, FAIL)
H5T_CONV_uS(UCHAR, SHORT, unsigned char, short, -, SHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -4647,12 +4746,12 @@ H5T_conv_uchar_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uchar_ushort, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uchar_ushort, FAIL)
H5T_CONV_uU(UCHAR, USHORT, unsigned char, unsigned short, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -4679,12 +4778,12 @@ H5T_conv_schar_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_schar_int, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_schar_int, FAIL)
H5T_CONV_sS(SCHAR, INT, signed char, int, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -4711,12 +4810,12 @@ H5T_conv_schar_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_schar_uint, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_schar_uint, FAIL)
H5T_CONV_sU(SCHAR, UINT, signed char, unsigned, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -4743,12 +4842,12 @@ H5T_conv_uchar_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uchar_int, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uchar_int, FAIL)
H5T_CONV_uS(UCHAR, INT, unsigned char, int, -, INT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -4775,12 +4874,12 @@ H5T_conv_uchar_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uchar_uint, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uchar_uint, FAIL)
H5T_CONV_uU(UCHAR, UINT, unsigned char, unsigned, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -4807,12 +4906,12 @@ H5T_conv_schar_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_schar_long, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_schar_long, FAIL)
H5T_CONV_sS(SCHAR, LONG, signed char, long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -4840,12 +4939,12 @@ H5T_conv_schar_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_schar_ulong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_schar_ulong, FAIL)
H5T_CONV_sU(SCHAR, ULONG, signed char, unsigned long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -4872,12 +4971,12 @@ H5T_conv_uchar_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uchar_long, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uchar_long, FAIL)
H5T_CONV_uS(UCHAR, LONG, unsigned char, long, -, LONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -4905,19 +5004,19 @@ H5T_conv_uchar_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uchar_ulong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uchar_ulong, FAIL)
H5T_CONV_uU(UCHAR, ULONG, unsigned char, unsigned long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_schar_llong
*
- * Purpose: Converts `signed char' to `long_long'
+ * Purpose: Converts `signed char' to `long long'
*
* Return: Success: Non-negative
*
@@ -4938,19 +5037,19 @@ H5T_conv_schar_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_schar_llong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_schar_llong, FAIL)
- H5T_CONV_sS(SCHAR, LLONG, signed char, long_long, -, -);
+ H5T_CONV_sS(SCHAR, LLONG, signed char, long long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_schar_ullong
*
- * Purpose: Converts `signed char' to `unsigned long_long'
+ * Purpose: Converts `signed char' to `unsigned long long'
*
* Return: Success: Non-negative
*
@@ -4971,19 +5070,19 @@ H5T_conv_schar_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_schar_ullong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_schar_ullong, FAIL)
- H5T_CONV_sU(SCHAR, ULLONG, signed char, unsigned long_long, -, -);
+ H5T_CONV_sU(SCHAR, ULLONG, signed char, unsigned long long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_uchar_llong
*
- * Purpose: Converts `unsigned char' to `long_long'
+ * Purpose: Converts `unsigned char' to `long long'
*
* Return: Success: Non-negative
*
@@ -5004,19 +5103,19 @@ H5T_conv_uchar_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uchar_llong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uchar_llong, FAIL)
- H5T_CONV_uS(UCHAR, LLONG, unsigned char, long_long, -, LLONG_MAX);
+ H5T_CONV_uS(UCHAR, LLONG, unsigned char, long long, -, LLONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_uchar_ullong
*
- * Purpose: Converts `unsigned char' to `unsigned long_long'
+ * Purpose: Converts `unsigned char' to `unsigned long long'
*
* Return: Success: Non-negative
*
@@ -5037,12 +5136,12 @@ H5T_conv_uchar_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uchar_ullong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uchar_ullong, FAIL)
- H5T_CONV_uU(UCHAR, ULLONG, unsigned char, unsigned long_long, -, -);
+ H5T_CONV_uU(UCHAR, ULLONG, unsigned char, unsigned long long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5070,12 +5169,12 @@ H5T_conv_short_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_short_schar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_short_schar, FAIL)
H5T_CONV_Ss(SHORT, SCHAR, short, signed char, SCHAR_MIN, SCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5103,12 +5202,12 @@ H5T_conv_short_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_short_uchar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_short_uchar, FAIL)
H5T_CONV_Su(SHORT, UCHAR, short, unsigned char, -, UCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5136,12 +5235,12 @@ H5T_conv_ushort_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ushort_schar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ushort_schar, FAIL)
H5T_CONV_Us(USHORT, SCHAR, unsigned short, signed char, -, SCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5169,12 +5268,12 @@ H5T_conv_ushort_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ushort_uchar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ushort_uchar, FAIL)
H5T_CONV_Uu(USHORT, UCHAR, unsigned short, unsigned char, -, UCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5202,12 +5301,12 @@ H5T_conv_short_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_short_ushort, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_short_ushort, FAIL)
H5T_CONV_su(SHORT, USHORT, short, unsigned short, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5235,12 +5334,12 @@ H5T_conv_ushort_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ushort_short, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ushort_short, FAIL)
H5T_CONV_us(USHORT, SHORT, unsigned short, short, -, SHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5268,12 +5367,12 @@ H5T_conv_short_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_short_int, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_short_int, FAIL)
H5T_CONV_sS(SHORT, INT, short, int, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5301,12 +5400,12 @@ H5T_conv_short_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_short_uint, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_short_uint, FAIL)
H5T_CONV_sU(SHORT, UINT, short, unsigned, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5334,12 +5433,12 @@ H5T_conv_ushort_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ushort_int, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ushort_int, FAIL)
H5T_CONV_uS(USHORT, INT, unsigned short, int, -, INT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5367,12 +5466,12 @@ H5T_conv_ushort_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ushort_uint, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ushort_uint, FAIL)
H5T_CONV_uU(USHORT, UINT, unsigned short, unsigned, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5400,12 +5499,12 @@ H5T_conv_short_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_short_long, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_short_long, FAIL)
H5T_CONV_sS(SHORT, LONG, short, long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5433,12 +5532,12 @@ H5T_conv_short_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_short_ulong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_short_ulong, FAIL)
H5T_CONV_sU(SHORT, ULONG, short, unsigned long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5466,12 +5565,12 @@ H5T_conv_ushort_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ushort_long, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ushort_long, FAIL)
H5T_CONV_uS(USHORT, LONG, unsigned short, long, -, LONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5499,19 +5598,19 @@ H5T_conv_ushort_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ushort_ulong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ushort_ulong, FAIL)
H5T_CONV_uU(USHORT, ULONG, unsigned short, unsigned long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_short_llong
*
- * Purpose: Converts `short' to `long_long'
+ * Purpose: Converts `short' to `long long'
*
* Return: Success: Non-negative
*
@@ -5532,19 +5631,19 @@ H5T_conv_short_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_short_llong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_short_llong, FAIL)
- H5T_CONV_sS(SHORT, LLONG, short, long_long, -, -);
+ H5T_CONV_sS(SHORT, LLONG, short, long long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_short_ullong
*
- * Purpose: Converts `short' to `unsigned long_long'
+ * Purpose: Converts `short' to `unsigned long long'
*
* Return: Success: Non-negative
*
@@ -5565,19 +5664,19 @@ H5T_conv_short_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_short_ullong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_short_ullong, FAIL)
- H5T_CONV_sU(SHORT, ULLONG, short, unsigned long_long, -, -);
+ H5T_CONV_sU(SHORT, ULLONG, short, unsigned long long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_ushort_llong
*
- * Purpose: Converts `unsigned short' to `long_long'
+ * Purpose: Converts `unsigned short' to `long long'
*
* Return: Success: Non-negative
*
@@ -5598,19 +5697,19 @@ H5T_conv_ushort_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ushort_llong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ushort_llong, FAIL)
- H5T_CONV_uS(USHORT, LLONG, unsigned short, long_long, -, LLONG_MAX);
+ H5T_CONV_uS(USHORT, LLONG, unsigned short, long long, -, LLONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_ushort_ullong
*
- * Purpose: Converts `unsigned short' to `unsigned long_long'
+ * Purpose: Converts `unsigned short' to `unsigned long long'
*
* Return: Success: Non-negative
*
@@ -5631,12 +5730,12 @@ H5T_conv_ushort_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ushort_ullong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ushort_ullong, FAIL)
- H5T_CONV_uU(USHORT, ULLONG, unsigned short, unsigned long_long, -, -);
+ H5T_CONV_uU(USHORT, ULLONG, unsigned short, unsigned long long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5664,12 +5763,12 @@ H5T_conv_int_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_int_schar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_int_schar, FAIL)
H5T_CONV_Ss(INT, SCHAR, int, signed char, SCHAR_MIN, SCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5697,12 +5796,12 @@ H5T_conv_int_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_int_uchar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_int_uchar, FAIL)
H5T_CONV_Su(INT, UCHAR, int, unsigned char, -, UCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5730,12 +5829,12 @@ H5T_conv_uint_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uint_schar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uint_schar, FAIL)
H5T_CONV_Us(UINT, SCHAR, unsigned, signed char, -, SCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5763,12 +5862,12 @@ H5T_conv_uint_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uint_uchar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uint_uchar, FAIL)
H5T_CONV_Uu(UINT, UCHAR, unsigned, unsigned char, -, UCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5796,12 +5895,12 @@ H5T_conv_int_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_int_short, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_int_short, FAIL)
H5T_CONV_Ss(INT, SHORT, int, short, SHRT_MIN, SHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5829,12 +5928,12 @@ H5T_conv_int_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_int_ushort, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_int_ushort, FAIL)
H5T_CONV_Su(INT, USHORT, int, unsigned short, -, USHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5862,12 +5961,12 @@ H5T_conv_uint_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uint_short, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uint_short, FAIL)
H5T_CONV_Us(UINT, SHORT, unsigned, short, -, SHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5895,12 +5994,12 @@ H5T_conv_uint_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uint_ushort, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uint_ushort, FAIL)
H5T_CONV_Uu(UINT, USHORT, unsigned, unsigned short, -, USHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5927,12 +6026,12 @@ H5T_conv_int_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_int_uint, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_int_uint, FAIL)
H5T_CONV_su(INT, UINT, int, unsigned, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5959,12 +6058,12 @@ H5T_conv_uint_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uint_int, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uint_int, FAIL)
H5T_CONV_us(UINT, INT, unsigned, int, -, INT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5991,12 +6090,12 @@ H5T_conv_int_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_int_long, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_int_long, FAIL)
H5T_CONV_sS(INT, LONG, int, long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6023,12 +6122,12 @@ H5T_conv_int_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_int_ulong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_int_ulong, FAIL)
H5T_CONV_sU(INT, LONG, int, unsigned long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6055,12 +6154,12 @@ H5T_conv_uint_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uint_long, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uint_long, FAIL)
H5T_CONV_uS(UINT, LONG, unsigned, long, -, LONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6087,19 +6186,19 @@ H5T_conv_uint_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uint_ulong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uint_ulong, FAIL)
H5T_CONV_uU(UINT, ULONG, unsigned, unsigned long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_int_llong
*
- * Purpose: Converts `int' to `long_long'
+ * Purpose: Converts `int' to `long long'
*
* Return: Success: Non-negative
*
@@ -6119,19 +6218,19 @@ H5T_conv_int_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_int_llong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_int_llong, FAIL)
- H5T_CONV_sS(INT, LLONG, int, long_long, -, -);
+ H5T_CONV_sS(INT, LLONG, int, long long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_int_ullong
*
- * Purpose: Converts `int' to `unsigned long_long'
+ * Purpose: Converts `int' to `unsigned long long'
*
* Return: Success: Non-negative
*
@@ -6151,19 +6250,19 @@ H5T_conv_int_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_int_ullong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_int_ullong, FAIL)
- H5T_CONV_sU(INT, ULLONG, int, unsigned long_long, -, -);
+ H5T_CONV_sU(INT, ULLONG, int, unsigned long long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_uint_llong
*
- * Purpose: Converts `unsigned int' to `long_long'
+ * Purpose: Converts `unsigned int' to `long long'
*
* Return: Success: Non-negative
*
@@ -6183,19 +6282,19 @@ H5T_conv_uint_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uint_llong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uint_llong, FAIL)
- H5T_CONV_uS(UINT, LLONG, unsigned, long_long, -, LLONG_MAX);
+ H5T_CONV_uS(UINT, LLONG, unsigned, long long, -, LLONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_uint_ullong
*
- * Purpose: Converts `unsigned int' to `unsigned long_long'
+ * Purpose: Converts `unsigned int' to `unsigned long long'
*
* Return: Success: Non-negative
*
@@ -6216,12 +6315,12 @@ H5T_conv_uint_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uint_ullong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uint_ullong, FAIL)
- H5T_CONV_uU(UINT, ULLONG, unsigned, unsigned long_long, -, -);
+ H5T_CONV_uU(UINT, ULLONG, unsigned, unsigned long long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6248,12 +6347,12 @@ H5T_conv_long_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_long_schar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_long_schar, FAIL)
H5T_CONV_Ss(LONG, SCHAR, long, signed char, SCHAR_MIN, SCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6280,12 +6379,12 @@ H5T_conv_long_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_long_uchar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_long_uchar, FAIL)
H5T_CONV_Su(LONG, UCHAR, long, unsigned char, -, UCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6313,12 +6412,12 @@ H5T_conv_ulong_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ulong_schar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ulong_schar, FAIL)
H5T_CONV_Us(ULONG, SCHAR, unsigned long, signed char, -, SCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6346,12 +6445,12 @@ H5T_conv_ulong_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ulong_uchar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ulong_uchar, FAIL)
H5T_CONV_Uu(ULONG, UCHAR, unsigned long, unsigned char, -, UCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6378,12 +6477,12 @@ H5T_conv_long_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_long_short, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_long_short, FAIL)
H5T_CONV_Ss(LONG, SHORT, long, short, SHRT_MIN, SHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6411,12 +6510,12 @@ H5T_conv_long_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_long_ushort, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_long_ushort, FAIL)
H5T_CONV_Su(LONG, USHORT, long, unsigned short, -, USHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6443,12 +6542,12 @@ H5T_conv_ulong_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ulong_short, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ulong_short, FAIL)
H5T_CONV_Us(ULONG, SHORT, unsigned long, short, -, SHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6476,12 +6575,12 @@ H5T_conv_ulong_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ulong_ushort, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ulong_ushort, FAIL)
H5T_CONV_Uu(ULONG, USHORT, unsigned long, unsigned short, -, USHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6508,12 +6607,12 @@ H5T_conv_long_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_long_int, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_long_int, FAIL)
H5T_CONV_Ss(LONG, INT, long, int, INT_MIN, INT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6540,12 +6639,12 @@ H5T_conv_long_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_long_uint, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_long_uint, FAIL)
H5T_CONV_Su(LONG, UINT, long, unsigned, -, UINT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6572,12 +6671,12 @@ H5T_conv_ulong_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ulong_int, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ulong_int, FAIL)
H5T_CONV_Us(ULONG, INT, unsigned long, int, -, INT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6604,12 +6703,12 @@ H5T_conv_ulong_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ulong_uint, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ulong_uint, FAIL)
H5T_CONV_Uu(ULONG, UINT, unsigned long, unsigned, -, UINT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6636,12 +6735,12 @@ H5T_conv_long_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_long_ulong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_long_ulong, FAIL)
H5T_CONV_su(LONG, ULONG, long, unsigned long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -6668,19 +6767,19 @@ H5T_conv_ulong_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ulong_long, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ulong_long, FAIL)
H5T_CONV_us(ULONG, LONG, unsigned long, long, -, LONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_long_llong
*
- * Purpose: Converts `long' to `long_long'
+ * Purpose: Converts `long' to `long long'
*
* Return: Success: Non-negative
*
@@ -6700,19 +6799,19 @@ H5T_conv_long_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_long_llong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_long_llong, FAIL)
- H5T_CONV_sS(LONG, LLONG, long, long_long, -, -);
+ H5T_CONV_sS(LONG, LLONG, long, long long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_long_ullong
*
- * Purpose: Converts `long' to `unsigned long_long'
+ * Purpose: Converts `long' to `unsigned long long'
*
* Return: Success: Non-negative
*
@@ -6733,19 +6832,19 @@ H5T_conv_long_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_long_ullong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_long_ullong, FAIL)
- H5T_CONV_sU(LONG, ULLONG, long, unsigned long_long, -, -);
+ H5T_CONV_sU(LONG, ULLONG, long, unsigned long long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_ulong_llong
*
- * Purpose: Converts `unsigned long' to `long_long'
+ * Purpose: Converts `unsigned long' to `long long'
*
* Return: Success: Non-negative
*
@@ -6766,19 +6865,19 @@ H5T_conv_ulong_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ulong_llong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ulong_llong, FAIL)
- H5T_CONV_uS(ULONG, LLONG, unsigned long, long_long, -, LLONG_MAX);
+ H5T_CONV_uS(ULONG, LLONG, unsigned long, long long, -, LLONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_ulong_ullong
*
- * Purpose: Converts `unsigned long' to `unsigned long_long'
+ * Purpose: Converts `unsigned long' to `unsigned long long'
*
* Return: Success: Non-negative
*
@@ -6799,19 +6898,19 @@ H5T_conv_ulong_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ulong_ullong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ulong_ullong, FAIL)
- H5T_CONV_uU(ULONG, ULLONG, unsigned long, unsigned long_long, -, -);
+ H5T_CONV_uU(ULONG, ULLONG, unsigned long, unsigned long long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_llong_schar
*
- * Purpose: Converts `long_long' to `signed char'
+ * Purpose: Converts `long long' to `signed char'
*
* Return: Success: Non-negative
*
@@ -6832,19 +6931,19 @@ H5T_conv_llong_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_llong_schar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_llong_schar, FAIL)
- H5T_CONV_Ss(LLONG, SCHAR, long_long, signed char, SCHAR_MIN, SCHAR_MAX);
+ H5T_CONV_Ss(LLONG, SCHAR, long long, signed char, SCHAR_MIN, SCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_llong_uchar
*
- * Purpose: Converts `long_long' to `unsigned char'
+ * Purpose: Converts `long long' to `unsigned char'
*
* Return: Success: Non-negative
*
@@ -6865,19 +6964,19 @@ H5T_conv_llong_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_llong_uchar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_llong_uchar, FAIL)
- H5T_CONV_Su(LLONG, UCHAR, long_long, unsigned char, -, UCHAR_MAX);
+ H5T_CONV_Su(LLONG, UCHAR, long long, unsigned char, -, UCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_ullong_schar
*
- * Purpose: Converts `unsigned long_long' to `signed char'
+ * Purpose: Converts `unsigned long long' to `signed char'
*
* Return: Success: Non-negative
*
@@ -6898,19 +6997,19 @@ H5T_conv_ullong_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ullong_schar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ullong_schar, FAIL)
- H5T_CONV_Us(ULLONG, SCHAR, unsigned long_long, signed char, -, SCHAR_MAX);
+ H5T_CONV_Us(ULLONG, SCHAR, unsigned long long, signed char, -, SCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_ullong_uchar
*
- * Purpose: Converts `unsigned long_long' to `unsigned char'
+ * Purpose: Converts `unsigned long long' to `unsigned char'
*
* Return: Success: Non-negative
*
@@ -6931,19 +7030,19 @@ H5T_conv_ullong_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ullong_uchar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ullong_uchar, FAIL)
- H5T_CONV_Uu(ULLONG, UCHAR, unsigned long_long, unsigned char, -, UCHAR_MAX);
+ H5T_CONV_Uu(ULLONG, UCHAR, unsigned long long, unsigned char, -, UCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_llong_short
*
- * Purpose: Converts `long_long' to `short'
+ * Purpose: Converts `long long' to `short'
*
* Return: Success: Non-negative
*
@@ -6964,19 +7063,19 @@ H5T_conv_llong_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_llong_short, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_llong_short, FAIL)
- H5T_CONV_Ss(LLONG, SHORT, long_long, short, SHRT_MIN, SHRT_MAX);
+ H5T_CONV_Ss(LLONG, SHORT, long long, short, SHRT_MIN, SHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_llong_ushort
*
- * Purpose: Converts `long_long' to `unsigned short'
+ * Purpose: Converts `long long' to `unsigned short'
*
* Return: Success: Non-negative
*
@@ -6997,19 +7096,19 @@ H5T_conv_llong_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_llong_ushort, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_llong_ushort, FAIL)
- H5T_CONV_Su(LLONG, USHORT, long_long, unsigned short, -, USHRT_MAX);
+ H5T_CONV_Su(LLONG, USHORT, long long, unsigned short, -, USHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_ullong_short
*
- * Purpose: Converts `unsigned long_long' to `short'
+ * Purpose: Converts `unsigned long long' to `short'
*
* Return: Success: Non-negative
*
@@ -7030,19 +7129,19 @@ H5T_conv_ullong_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ullong_short, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ullong_short, FAIL)
- H5T_CONV_Us(ULLONG, SHORT, unsigned long_long, short, -, SHRT_MAX);
+ H5T_CONV_Us(ULLONG, SHORT, unsigned long long, short, -, SHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_ullong_ushort
*
- * Purpose: Converts `unsigned long_long' to `unsigned short'
+ * Purpose: Converts `unsigned long long' to `unsigned short'
*
* Return: Success: Non-negative
*
@@ -7063,19 +7162,19 @@ H5T_conv_ullong_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ullong_ushort, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ullong_ushort, FAIL)
- H5T_CONV_Uu(ULLONG, USHORT, unsigned long_long, unsigned short, -, USHRT_MAX);
+ H5T_CONV_Uu(ULLONG, USHORT, unsigned long long, unsigned short, -, USHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_llong_int
*
- * Purpose: Converts `long_long' to `int'
+ * Purpose: Converts `long long' to `int'
*
* Return: Success: Non-negative
*
@@ -7095,19 +7194,19 @@ H5T_conv_llong_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_llong_int, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_llong_int, FAIL)
- H5T_CONV_Ss(LLONG, INT, long_long, int, INT_MIN, INT_MAX);
+ H5T_CONV_Ss(LLONG, INT, long long, int, INT_MIN, INT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_llong_uint
*
- * Purpose: Converts `long_long' to `unsigned int'
+ * Purpose: Converts `long long' to `unsigned int'
*
* Return: Success: Non-negative
*
@@ -7127,19 +7226,19 @@ H5T_conv_llong_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_llong_uint, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_llong_uint, FAIL)
- H5T_CONV_Su(LLONG, UINT, long_long, unsigned, -, UINT_MAX);
+ H5T_CONV_Su(LLONG, UINT, long long, unsigned, -, UINT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_ullong_int
*
- * Purpose: Converts `unsigned long_long' to `int'
+ * Purpose: Converts `unsigned long long' to `int'
*
* Return: Success: Non-negative
*
@@ -7159,19 +7258,19 @@ H5T_conv_ullong_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ullong_int, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ullong_int, FAIL)
- H5T_CONV_Us(ULLONG, INT, unsigned long_long, int, -, INT_MAX);
+ H5T_CONV_Us(ULLONG, INT, unsigned long long, int, -, INT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_ullong_uint
*
- * Purpose: Converts `unsigned long_long' to `unsigned int'
+ * Purpose: Converts `unsigned long long' to `unsigned int'
*
* Return: Success: Non-negative
*
@@ -7192,19 +7291,19 @@ H5T_conv_ullong_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ullong_uint, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ullong_uint, FAIL)
- H5T_CONV_Uu(ULLONG, UINT, unsigned long_long, unsigned, -, UINT_MAX);
+ H5T_CONV_Uu(ULLONG, UINT, unsigned long long, unsigned, -, UINT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_llong_long
*
- * Purpose: Converts `long_long' to `long'
+ * Purpose: Converts `long long' to `long'
*
* Return: Success: Non-negative
*
@@ -7224,19 +7323,19 @@ H5T_conv_llong_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_llong_long, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_llong_long, FAIL)
- H5T_CONV_Ss(LLONG, LONG, long_long, long, LONG_MIN, LONG_MAX);
+ H5T_CONV_Ss(LLONG, LONG, long long, long, LONG_MIN, LONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_llong_ulong
*
- * Purpose: Converts `long_long' to `unsigned long'
+ * Purpose: Converts `long long' to `unsigned long'
*
* Return: Success: Non-negative
*
@@ -7257,19 +7356,19 @@ H5T_conv_llong_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_llong_ulong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_llong_ulong, FAIL)
- H5T_CONV_Su(LLONG, ULONG, long_long, unsigned long, -, ULONG_MAX);
+ H5T_CONV_Su(LLONG, ULONG, long long, unsigned long, -, ULONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_ullong_long
*
- * Purpose: Converts `unsigned long_long' to `long'
+ * Purpose: Converts `unsigned long long' to `long'
*
* Return: Success: Non-negative
*
@@ -7290,19 +7389,19 @@ H5T_conv_ullong_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ullong_long, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ullong_long, FAIL)
- H5T_CONV_Us(ULLONG, LONG, unsigned long_long, long, -, LONG_MAX);
+ H5T_CONV_Us(ULLONG, LONG, unsigned long long, long, -, LONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_ullong_ulong
*
- * Purpose: Converts `unsigned long_long' to `unsigned long'
+ * Purpose: Converts `unsigned long long' to `unsigned long'
*
* Return: Success: Non-negative
*
@@ -7323,19 +7422,19 @@ H5T_conv_ullong_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ullong_ulong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ullong_ulong, FAIL)
- H5T_CONV_Uu(ULLONG, ULONG, unsigned long_long, unsigned long, -, ULONG_MAX);
+ H5T_CONV_Uu(ULLONG, ULONG, unsigned long long, unsigned long, -, ULONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_llong_ullong
*
- * Purpose: Converts `long_long' to `unsigned long_long'
+ * Purpose: Converts `long long' to `unsigned long long'
*
* Return: Success: non-negative
*
@@ -7356,19 +7455,19 @@ H5T_conv_llong_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_llong_ullong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_llong_ullong, FAIL)
- H5T_CONV_su(LLONG, ULLONG, long_long, unsigned long_long, -, -);
+ H5T_CONV_su(LLONG, ULLONG, long long, unsigned long long, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_ullong_llong
*
- * Purpose: Converts `unsigned long_long' to `long_long'
+ * Purpose: Converts `unsigned long long' to `long long'
*
* Return: Success: non-negative
*
@@ -7389,12 +7488,12 @@ H5T_conv_ullong_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ullong_llong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ullong_llong, FAIL)
- H5T_CONV_us(ULLONG, LLONG, unsigned long_long, long_long, -, LLONG_MAX);
+ H5T_CONV_us(ULLONG, LLONG, unsigned long long, long long, -, LLONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -7426,12 +7525,12 @@ H5T_conv_float_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_float_double, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_float_double, FAIL)
H5T_CONV_fF(FLOAT, DOUBLE, float, double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_FP_FP */
@@ -7460,12 +7559,12 @@ H5T_conv_float_ldouble (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_float_ldouble, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_float_ldouble, FAIL)
H5T_CONV_fF(FLOAT, LDOUBLE, float, long double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /*H5T_CONV_INTERNAL_FP_LDOUBLE*/
@@ -7501,12 +7600,12 @@ H5T_conv_double_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_double_float, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_double_float, FAIL)
H5T_CONV_Ff(DOUBLE, FLOAT, double, float, -FLT_MAX, FLT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /*H5T_CONV_INTERNAL_FP_FP*/
@@ -7535,13 +7634,13 @@ H5T_conv_double_ldouble (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_double_ldouble, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_double_ldouble, FAIL)
H5T_CONV_fF(DOUBLE, LDOUBLE, double, long double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /*H5T_CONV_INTERNAL_FP_LDOUBLE*/
@@ -7570,12 +7669,12 @@ H5T_conv_ldouble_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ldouble_float, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ldouble_float, FAIL)
H5T_CONV_Ff(LDOUBLE, FLOAT, long double, float, -FLT_MAX, FLT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_FP_LDOUBLE */
@@ -7604,12 +7703,12 @@ H5T_conv_ldouble_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ldouble_double, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ldouble_double, FAIL)
H5T_CONV_Ff(LDOUBLE, DOUBLE, long double, double, -DBL_MAX, DBL_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /*H5T_CONV_INTERNAL_FP_LDOUBLE*/
@@ -7637,12 +7736,12 @@ H5T_conv_schar_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_schar_float, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_schar_float, FAIL)
H5T_CONV_xF(SCHAR, FLOAT, signed char, float, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -7669,12 +7768,12 @@ H5T_conv_schar_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_schar_double, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_schar_double, FAIL)
H5T_CONV_xF(SCHAR, DOUBLE, signed char, double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -7702,12 +7801,12 @@ H5T_conv_schar_ldouble (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_schar_ldouble, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_schar_ldouble, FAIL)
H5T_CONV_xF(SCHAR, LDOUBLE, signed char, long double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_INTEGER_LDOUBLE */
@@ -7735,12 +7834,12 @@ H5T_conv_uchar_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uchar_float, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uchar_float, FAIL)
H5T_CONV_xF(UCHAR, FLOAT, unsigned char, float, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -7767,12 +7866,12 @@ H5T_conv_uchar_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uchar_double, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uchar_double, FAIL)
H5T_CONV_xF(UCHAR, DOUBLE, unsigned char, double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -7800,12 +7899,12 @@ H5T_conv_uchar_ldouble (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uchar_ldouble, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uchar_ldouble, FAIL)
H5T_CONV_xF(UCHAR, LDOUBLE, unsigned char, long double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_INTEGER_LDOUBLE */
@@ -7833,12 +7932,12 @@ H5T_conv_short_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_short_float, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_short_float, FAIL)
H5T_CONV_xF(SHORT, FLOAT, short, float, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -7865,12 +7964,12 @@ H5T_conv_short_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_short_double, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_short_double, FAIL)
H5T_CONV_xF(SHORT, DOUBLE, short, double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -7898,12 +7997,12 @@ H5T_conv_short_ldouble (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_short_ldouble, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_short_ldouble, FAIL)
H5T_CONV_xF(SHORT, LDOUBLE, short, long double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_INTEGER_LDOUBLE */
@@ -7931,12 +8030,12 @@ H5T_conv_ushort_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ushort_float, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ushort_float, FAIL)
H5T_CONV_xF(USHORT, FLOAT, unsigned short, float, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -7963,12 +8062,12 @@ H5T_conv_ushort_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ushort_double, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ushort_double, FAIL)
H5T_CONV_xF(USHORT, DOUBLE, unsigned short, double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -7996,12 +8095,12 @@ H5T_conv_ushort_ldouble (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ushort_ldouble, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ushort_ldouble, FAIL)
H5T_CONV_xF(USHORT, LDOUBLE, unsigned short, long double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_INTEGER_LDOUBLE */
@@ -8029,12 +8128,12 @@ H5T_conv_int_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_int_float, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_int_float, FAIL)
H5T_CONV_xF(INT, FLOAT, int, float, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -8061,12 +8160,12 @@ H5T_conv_int_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_int_double, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_int_double, FAIL)
H5T_CONV_xF(INT, DOUBLE, int, double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -8094,12 +8193,12 @@ H5T_conv_int_ldouble (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_int_ldouble, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_int_ldouble, FAIL)
H5T_CONV_xF(INT, LDOUBLE, int, long double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_INTEGER_LDOUBLE */
@@ -8127,12 +8226,12 @@ H5T_conv_uint_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uint_float, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uint_float, FAIL)
H5T_CONV_xF(UINT, FLOAT, unsigned int, float, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -8159,12 +8258,12 @@ H5T_conv_uint_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uint_double, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uint_double, FAIL)
H5T_CONV_xF(UINT, DOUBLE, unsigned int, double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -8192,12 +8291,12 @@ H5T_conv_uint_ldouble (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_uint_ldouble, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_uint_ldouble, FAIL)
H5T_CONV_xF(UINT, LDOUBLE, unsigned int, long double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_INTEGER_LDOUBLE */
@@ -8225,12 +8324,12 @@ H5T_conv_long_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_long_float, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_long_float, FAIL)
H5T_CONV_xF(LONG, FLOAT, long, float, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -8257,12 +8356,12 @@ H5T_conv_long_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_long_double, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_long_double, FAIL)
H5T_CONV_xF(LONG, DOUBLE, long, double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -8290,12 +8389,12 @@ H5T_conv_long_ldouble (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_long_ldouble, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_long_ldouble, FAIL)
H5T_CONV_xF(LONG, LDOUBLE, long, long double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_INTEGER_LDOUBLE */
@@ -8315,7 +8414,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-#if H5T_CONV_INTERNAL_ULONG_FP
+#if H5T_CONV_INTERNAL_ULONG_FLT
herr_t
H5T_conv_ulong_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t nelmts, size_t buf_stride,
@@ -8324,14 +8423,14 @@ H5T_conv_ulong_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ulong_float, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ulong_float, FAIL)
H5T_CONV_xF(ULONG, FLOAT, unsigned long, float, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
-#endif /* H5T_CONV_INTERNAL_ULONG_FP */
+#endif /* H5T_CONV_INTERNAL_ULONG_FLT */
/*-------------------------------------------------------------------------
@@ -8349,7 +8448,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-#if H5T_CONV_INTERNAL_ULONG_FP
+#if H5T_CONV_INTERNAL_ULONG_DBL
herr_t
H5T_conv_ulong_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t nelmts, size_t buf_stride,
@@ -8358,14 +8457,14 @@ H5T_conv_ulong_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ulong_double, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ulong_double, FAIL)
H5T_CONV_xF(ULONG, DOUBLE, unsigned long, double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
-#endif /* H5T_CONV_INTERNAL_ULONG_FP */
+#endif /* H5T_CONV_INTERNAL_ULONG_DBL */
/*-------------------------------------------------------------------------
@@ -8392,12 +8491,12 @@ H5T_conv_ulong_ldouble (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ulong_ldouble, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ulong_ldouble, FAIL)
H5T_CONV_xF(ULONG, LDOUBLE, unsigned long, long double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_ULONG_LDOUBLE */
@@ -8425,12 +8524,12 @@ H5T_conv_llong_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_llong_float, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_llong_float, FAIL)
- H5T_CONV_xF(LLONG, FLOAT, long_long, float, -, -);
+ H5T_CONV_xF(LLONG, FLOAT, long long, float, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -8457,12 +8556,12 @@ H5T_conv_llong_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_llong_double, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_llong_double, FAIL)
- H5T_CONV_xF(LLONG, DOUBLE, long_long, double, -, -);
+ H5T_CONV_xF(LLONG, DOUBLE, long long, double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -8490,12 +8589,12 @@ H5T_conv_llong_ldouble (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_llong_ldouble, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_llong_ldouble, FAIL)
- H5T_CONV_xF(LLONG, LDOUBLE, long_long, long double, -, -);
+ H5T_CONV_xF(LLONG, LDOUBLE, long long, long double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_LLONG_LDOUBLE */
@@ -8524,12 +8623,12 @@ H5T_conv_ullong_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ullong_float, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ullong_float, FAIL)
- H5T_CONV_xF(ULLONG, FLOAT, unsigned long_long, float, -, -);
+ H5T_CONV_xF(ULLONG, FLOAT, unsigned long long, float, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /*H5T_CONV_INTERNAL_ULLONG_FP*/
@@ -8558,12 +8657,12 @@ H5T_conv_ullong_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ullong_double, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ullong_double, FAIL)
- H5T_CONV_xF(ULLONG, DOUBLE, unsigned long_long, double, -, -);
+ H5T_CONV_xF(ULLONG, DOUBLE, unsigned long long, double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /*H5T_CONV_INTERNAL_ULLONG_FP*/
@@ -8592,12 +8691,12 @@ H5T_conv_ullong_ldouble (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ullong_ldouble, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ullong_ldouble, FAIL)
- H5T_CONV_xF(ULLONG, LDOUBLE, unsigned long_long, long double, -, -);
+ H5T_CONV_xF(ULLONG, LDOUBLE, unsigned long long, long double, -, -);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /*H5T_CONV_INTERNAL_ULLONG_LDOUBLE*/
@@ -8625,12 +8724,12 @@ H5T_conv_float_schar (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_float_schar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_float_schar, FAIL)
H5T_CONV_Fx(FLOAT, SCHAR, float, signed char, SCHAR_MIN, SCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -8657,12 +8756,12 @@ H5T_conv_float_uchar (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_float_uchar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_float_uchar, FAIL)
H5T_CONV_Fx(FLOAT, UCHAR, float, unsigned char, 0, UCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -8689,12 +8788,12 @@ H5T_conv_double_schar (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_double_schar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_double_schar, FAIL)
H5T_CONV_Fx(DOUBLE, SCHAR, double, signed char, SCHAR_MIN, SCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -8721,12 +8820,12 @@ H5T_conv_double_uchar (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_double_uchar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_double_uchar, FAIL)
H5T_CONV_Fx(DOUBLE, UCHAR, double, unsigned char, 0, UCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -8754,12 +8853,12 @@ H5T_conv_ldouble_schar (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ldouble_schar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ldouble_schar, FAIL)
H5T_CONV_Fx(LDOUBLE, SCHAR, long double, signed char, SCHAR_MIN, SCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_LDOUBLE_INTEGER */
@@ -8788,12 +8887,12 @@ H5T_conv_ldouble_uchar (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ldouble_uchar, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ldouble_uchar, FAIL)
H5T_CONV_Fx(LDOUBLE, UCHAR, long double, unsigned char, 0, UCHAR_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_LDOUBLE_INTEGER */
@@ -8821,12 +8920,12 @@ H5T_conv_float_short (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_float_short, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_float_short, FAIL)
H5T_CONV_Fx(FLOAT, SHORT, float, short, SHRT_MIN, SHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -8853,12 +8952,12 @@ H5T_conv_float_ushort (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_float_ushort, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_float_ushort, FAIL)
H5T_CONV_Fx(FLOAT, USHORT, float, unsigned short, 0, USHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -8885,12 +8984,12 @@ H5T_conv_double_short (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_double_short, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_double_short, FAIL)
H5T_CONV_Fx(DOUBLE, SHORT, double, short, SHRT_MIN, SHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -8917,12 +9016,12 @@ H5T_conv_double_ushort (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_double_ushort, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_double_ushort, FAIL)
H5T_CONV_Fx(DOUBLE, USHORT, double, unsigned short, 0, USHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -8950,12 +9049,12 @@ H5T_conv_ldouble_short (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ldouble_short, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ldouble_short, FAIL)
H5T_CONV_Fx(LDOUBLE, SHORT, long double, short, SHRT_MIN, SHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /*H5T_CONV_INTERNAL_LDOUBLE_INTEGER*/
@@ -8984,12 +9083,12 @@ H5T_conv_ldouble_ushort (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ldouble_ushort, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ldouble_ushort, FAIL)
H5T_CONV_Fx(LDOUBLE, USHORT, long double, unsigned short, 0, USHRT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_LDOUBLE_INTEGER */
@@ -9017,12 +9116,12 @@ H5T_conv_float_int (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_float_int, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_float_int, FAIL)
H5T_CONV_Fx(FLOAT, INT, float, int, INT_MIN, INT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -9049,12 +9148,12 @@ H5T_conv_float_uint (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_float_uint, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_float_uint, FAIL)
H5T_CONV_Fx(FLOAT, UINT, float, unsigned int, 0, UINT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -9081,12 +9180,12 @@ H5T_conv_double_int (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_double_int, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_double_int, FAIL)
H5T_CONV_Fx(DOUBLE, INT, double, int, INT_MIN, INT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -9113,12 +9212,12 @@ H5T_conv_double_uint (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_double_uint, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_double_uint, FAIL)
H5T_CONV_Fx(DOUBLE, UINT, double, unsigned int, 0, UINT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -9146,12 +9245,12 @@ H5T_conv_ldouble_int (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ldouble_int, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ldouble_int, FAIL)
H5T_CONV_Fx(LDOUBLE, INT, long double, int, INT_MIN, INT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_LDOUBLE_INTEGER */
@@ -9180,12 +9279,12 @@ H5T_conv_ldouble_uint (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ldouble_uint, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ldouble_uint, FAIL)
H5T_CONV_Fx(LDOUBLE, UINT, long double, unsigned int, 0, UINT_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_LDOUBLE_UINT */
@@ -9213,12 +9312,12 @@ H5T_conv_float_long (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_float_long, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_float_long, FAIL)
H5T_CONV_Fx(FLOAT, LONG, float, long, LONG_MIN, LONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -9245,12 +9344,12 @@ H5T_conv_float_ulong (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_float_ulong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_float_ulong, FAIL)
H5T_CONV_Fx(FLOAT, ULONG, float, unsigned long, 0, ULONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -9277,12 +9376,12 @@ H5T_conv_double_long (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_double_long, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_double_long, FAIL)
H5T_CONV_Fx(DOUBLE, LONG, double, long, LONG_MIN, LONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -9309,12 +9408,12 @@ H5T_conv_double_ulong (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_double_ulong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_double_ulong, FAIL)
H5T_CONV_Fx(DOUBLE, ULONG, double, unsigned long, 0, ULONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -9342,12 +9441,12 @@ H5T_conv_ldouble_long (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ldouble_long, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ldouble_long, FAIL)
H5T_CONV_Fx(LDOUBLE, LONG, long double, long, LONG_MIN, LONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /*H5T_CONV_INTERNAL_LDOUBLE_INTEGER*/
@@ -9376,12 +9475,12 @@ H5T_conv_ldouble_ulong (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ldouble_ulong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ldouble_ulong, FAIL)
H5T_CONV_Fx(LDOUBLE, ULONG, long double, unsigned long, 0, ULONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_LDOUBLE_INTEGER */
@@ -9410,12 +9509,12 @@ H5T_conv_float_llong (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_float_llong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_float_llong, FAIL)
- H5T_CONV_Fx(FLOAT, LLONG, float, long_long, LLONG_MIN, LLONG_MAX);
+ H5T_CONV_Fx(FLOAT, LLONG, float, long long, LLONG_MIN, LLONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5T_CONV_INTERNAL_FP_LLONG */
@@ -9444,12 +9543,12 @@ H5T_conv_float_ullong (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_float_ullong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_float_ullong, FAIL)
- H5T_CONV_Fx(FLOAT, ULLONG, float, unsigned long_long, 0, ULLONG_MAX);
+ H5T_CONV_Fx(FLOAT, ULLONG, float, unsigned long long, 0, ULLONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /*H5T_CONV_INTERNAL_FP_ULLONG*/
@@ -9478,12 +9577,12 @@ H5T_conv_double_llong (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_double_llong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_double_llong, FAIL)
- H5T_CONV_Fx(DOUBLE, LLONG, double, long_long, LLONG_MIN, LLONG_MAX);
+ H5T_CONV_Fx(DOUBLE, LLONG, double, long long, LLONG_MIN, LLONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /*H5T_CONV_INTERNAL_FP_LLONG*/
@@ -9512,12 +9611,12 @@ H5T_conv_double_ullong (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_double_ullong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_double_ullong, FAIL)
- H5T_CONV_Fx(DOUBLE, ULLONG, double, unsigned long_long, 0, ULLONG_MAX);
+ H5T_CONV_Fx(DOUBLE, ULLONG, double, unsigned long long, 0, ULLONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /*H5T_CONV_INTERNAL_FP_ULLONG*/
@@ -9546,12 +9645,12 @@ H5T_conv_ldouble_llong (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ldouble_llong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ldouble_llong, FAIL)
- H5T_CONV_Fx(LDOUBLE, LLONG, long double, long_long, LLONG_MIN, LLONG_MAX);
+ H5T_CONV_Fx(LDOUBLE, LLONG, long double, long long, LLONG_MIN, LLONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /*H5T_CONV_INTERNAL_LDOUBLE_LLONG*/
@@ -9580,12 +9679,12 @@ H5T_conv_ldouble_ullong (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_ldouble_ullong, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_ldouble_ullong, FAIL)
- H5T_CONV_Fx(LDOUBLE, ULLONG, long double, unsigned long_long, 0, ULLONG_MAX);
+ H5T_CONV_Fx(LDOUBLE, ULLONG, long double, unsigned long long, 0, ULLONG_MAX);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
#endif /*H5T_CONV_INTERNAL_LDOUBLE_ULLONG*/
@@ -9620,8 +9719,8 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
hid_t dxpl_id)
{
/* Traversal-related variables */
- H5T_t *src_p; /*source data type */
- H5T_t *dst_p; /*destination data type */
+ H5T_t *src_p; /*source datatype */
+ H5T_t *dst_p; /*destination datatype */
H5T_atomic_t src; /*atomic source info */
H5T_atomic_t dst; /*atomic destination info */
int direction; /*forward or backward traversal */
@@ -9649,13 +9748,13 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
H5T_conv_ret_t except_ret; /*return of callback function */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_f_i, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_f_i, FAIL)
switch (cdata->command) {
case H5T_CONV_INIT:
- if (NULL==(src_p=H5I_object(src_id)) ||
- NULL==(dst_p=H5I_object(dst_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ if (NULL==(src_p=(H5T_t*)H5I_object(src_id)) ||
+ NULL==(dst_p=(H5T_t*)H5I_object(dst_id)))
+ HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
src = src_p->shared->u.atomic;
dst = dst_p->shared->u.atomic;
if (H5T_ORDER_LE!=src.order && H5T_ORDER_BE!=src.order && H5T_ORDER_VAX!=src.order)
@@ -9671,10 +9770,10 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
break;
case H5T_CONV_CONV:
- /* Get the data types */
- if (NULL==(src_p=H5I_object(src_id)) ||
- NULL==(dst_p=H5I_object(dst_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ /* Get the datatypes */
+ if (NULL==(src_p=(H5T_t*)H5I_object(src_id)) ||
+ NULL==(dst_p=(H5T_t*)H5I_object(dst_id)))
+ HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
src = src_p->shared->u.atomic;
dst = dst_p->shared->u.atomic;
@@ -10174,7 +10273,7 @@ done:
H5MM_xfree(int_buf);
if(src_rev)
H5MM_free(src_rev);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -10208,8 +10307,8 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
hid_t dxpl_id)
{
/* Traversal-related variables */
- H5T_t *src_p; /*source data type */
- H5T_t *dst_p; /*destination data type */
+ H5T_t *src_p; /*source datatype */
+ H5T_t *dst_p; /*destination datatype */
H5T_atomic_t src; /*atomic source info */
H5T_atomic_t dst; /*atomic destination info */
int direction; /*forward or backward traversal */
@@ -10239,13 +10338,13 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
hbool_t reverse; /*if reverse the order of destination */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_conv_i_f, FAIL);
+ FUNC_ENTER_NOAPI(H5T_conv_i_f, FAIL)
switch (cdata->command) {
case H5T_CONV_INIT:
- if (NULL==(src_p=H5I_object(src_id)) ||
- NULL==(dst_p=H5I_object(dst_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ if (NULL==(src_p=(H5T_t*)H5I_object(src_id)) ||
+ NULL==(dst_p=(H5T_t*)H5I_object(dst_id)))
+ HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
src = src_p->shared->u.atomic;
dst = dst_p->shared->u.atomic;
if (H5T_ORDER_LE!=dst.order && H5T_ORDER_BE!=dst.order && H5T_ORDER_VAX!=dst.order)
@@ -10261,10 +10360,10 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
break;
case H5T_CONV_CONV:
- /* Get the data types */
- if (NULL==(src_p=H5I_object(src_id)) ||
- NULL==(dst_p=H5I_object(dst_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ /* Get the datatypes */
+ if (NULL==(src_p=(H5T_t*)H5I_object(src_id)) ||
+ NULL==(dst_p=(H5T_t*)H5I_object(dst_id)))
+ HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
src = src_p->shared->u.atomic;
dst = dst_p->shared->u.atomic;
@@ -10603,7 +10702,7 @@ done:
H5MM_xfree(int_buf);
if(src_rev)
H5MM_free(src_rev);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
@@ -10633,7 +10732,7 @@ H5T_reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_order_t order)
{
size_t i;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_reverse_order);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_reverse_order)
assert(s);
assert(size);
@@ -10651,5 +10750,6 @@ H5T_reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_order_t order)
rev[i] = s[i];
}
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
}
+
diff --git a/src/H5Tcset.c b/src/H5Tcset.c
index c938cd2..4ec58ab 100644
--- a/src/H5Tcset.c
+++ b/src/H5Tcset.c
@@ -75,14 +75,14 @@ H5T_init_cset_interface(void)
H5T_cset_t
H5Tget_cset(hid_t type_id)
{
- H5T_t *dt = NULL;
+ H5T_t *dt;
H5T_cset_t ret_value;
FUNC_ENTER_API(H5Tget_cset, H5T_CSET_ERROR)
H5TRACE1("Tc", "i", type_id);
/* Check args */
- if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
+ if (NULL == (dt = (H5T_t *)H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_CSET_ERROR, "not a data type")
while (dt->shared->parent && !H5T_IS_STRING(dt->shared))
dt = dt->shared->parent; /*defer to parent*/
@@ -121,14 +121,14 @@ done:
herr_t
H5Tset_cset(hid_t type_id, H5T_cset_t cset)
{
- H5T_t *dt = NULL;
+ H5T_t *dt;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Tset_cset, FAIL)
H5TRACE2("e", "iTc", type_id, cset);
/* Check args */
- if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
+ if (NULL == (dt = (H5T_t *)H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
if (H5T_STATE_TRANSIENT!=dt->shared->state)
HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only")
diff --git a/src/H5Tdeprec.c b/src/H5Tdeprec.c
index 64386b1..9d9ad36 100644
--- a/src/H5Tdeprec.c
+++ b/src/H5Tdeprec.c
@@ -44,6 +44,7 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5FOprivate.h" /* File objects */
#include "H5Iprivate.h" /* IDs */
+#include "H5Ppublic.h" /* Property Lists */
#include "H5Tpkg.h" /* Datatypes */
@@ -135,7 +136,7 @@ H5Tcommit1(hid_t loc_id, const char *name, hid_t type_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
- if(NULL == (type = H5I_object_verify(type_id, H5I_DATATYPE)))
+ if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
/* Commit the datatype to the file, using default property list values */
@@ -210,7 +211,7 @@ H5Topen1(hid_t loc_id, const char *name)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to open named datatype")
/* Register the type and return the ID */
- if((ret_value = H5I_register(H5I_DATATYPE, type)) < 0)
+ if((ret_value = H5I_register(H5I_DATATYPE, type, TRUE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register named datatype")
done:
diff --git a/src/H5Tenum.c b/src/H5Tenum.c
index 5ab6964..f955a7e 100644
--- a/src/H5Tenum.c
+++ b/src/H5Tenum.c
@@ -94,7 +94,7 @@ H5Tenum_create(hid_t parent_id)
if((dt=H5T_enum_create(parent))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "cannot create enum type")
/* Atomize the type */
- if ((ret_value=H5I_register(H5I_DATATYPE, dt))<0)
+ if ((ret_value=H5I_register(H5I_DATATYPE, dt, TRUE))<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register data type atom")
done:
diff --git a/src/H5Tfields.c b/src/H5Tfields.c
index 0237fc4..43f1369 100644
--- a/src/H5Tfields.c
+++ b/src/H5Tfields.c
@@ -76,22 +76,22 @@ H5T_init_fields_interface(void)
int
H5Tget_nmembers(hid_t type_id)
{
- H5T_t *dt = NULL;
- int ret_value;
+ H5T_t *dt; /* Datatype to query */
+ int ret_value; /* Return value */
FUNC_ENTER_API(H5Tget_nmembers, FAIL)
H5TRACE1("Is", "i", type_id);
/* Check args */
- if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
+ if(NULL == (dt = H5I_object_verify(type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
- if((ret_value = H5T_get_nmembers(dt))<0)
+ if((ret_value = H5T_get_nmembers(dt)) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "cannot return member number")
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Tget_nmembers() */
/*-------------------------------------------------------------------------
@@ -121,18 +121,18 @@ H5T_get_nmembers(const H5T_t *dt)
FUNC_ENTER_NOAPI(H5T_get_nmembers, FAIL)
- assert(dt);
+ HDassert(dt);
- if (H5T_COMPOUND==dt->shared->type)
+ if(H5T_COMPOUND == dt->shared->type)
ret_value = (int)dt->shared->u.compnd.nmembs;
- else if (H5T_ENUM==dt->shared->type)
+ else if(H5T_ENUM == dt->shared->type)
ret_value = (int)dt->shared->u.enumer.nmembs;
else
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "operation not supported for type class")
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5T_get_nmembers() */
/*-------------------------------------------------------------------------
@@ -296,101 +296,94 @@ done:
* Programmer: Robb Matzke
* Wednesday, January 7, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5T_sort_value(const H5T_t *dt, int *map)
{
- unsigned i, j, nmembs;
+ unsigned nmembs; /* Number of members for datatype */
size_t size;
- hbool_t swapped;
+ hbool_t swapped; /* Whether we've swapped fields */
uint8_t tbuf[32];
- herr_t ret_value=SUCCEED; /* Return value */
+ unsigned i, j; /* Local index variables */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5T_sort_value, FAIL)
/* Check args */
- assert(dt);
- assert(H5T_COMPOUND==dt->shared->type || H5T_ENUM==dt->shared->type);
+ HDassert(dt);
+ HDassert(H5T_COMPOUND == dt->shared->type || H5T_ENUM == dt->shared->type);
/* Use a bubble sort because we can short circuit */
- if (H5T_COMPOUND==dt->shared->type) {
- if (H5T_SORT_VALUE!=dt->shared->u.compnd.sorted) {
+ if(H5T_COMPOUND == dt->shared->type) {
+ if(H5T_SORT_VALUE != dt->shared->u.compnd.sorted) {
dt->shared->u.compnd.sorted = H5T_SORT_VALUE;
nmembs = dt->shared->u.compnd.nmembs;
- for (i=nmembs-1, swapped=TRUE; i>0 && swapped; --i) {
- for (j=0, swapped=FALSE; j<i; j++) {
- if (dt->shared->u.compnd.memb[j].offset >
- dt->shared->u.compnd.memb[j+1].offset) {
- H5T_cmemb_t tmp = dt->shared->u.compnd.memb[j];
- dt->shared->u.compnd.memb[j] = dt->shared->u.compnd.memb[j+1];
- dt->shared->u.compnd.memb[j+1] = tmp;
- if (map) {
+ for(i = nmembs - 1, swapped = TRUE; i > 0 && swapped; --i) {
+ for(j = 0, swapped = FALSE; j < i; j++) {
+ if(dt->shared->u.compnd.memb[j].offset > dt->shared->u.compnd.memb[j + 1].offset) {
+ H5T_cmemb_t tmp = dt->shared->u.compnd.memb[j];
+ dt->shared->u.compnd.memb[j] = dt->shared->u.compnd.memb[j + 1];
+ dt->shared->u.compnd.memb[j + 1] = tmp;
+ if(map) {
int x = map[j];
- map[j] = map[j+1];
- map[j+1] = x;
- }
+
+ map[j] = map[j + 1];
+ map[j + 1] = x;
+ } /* end if */
swapped = TRUE;
- }
- }
- }
+ } /* end if */
+ } /* end for */
+ } /* end for */
#ifndef NDEBUG
/* I never trust a sort :-) -RPM */
- for (i=0; i<nmembs-1; i++) {
- assert(dt->shared->u.compnd.memb[i].offset <
- dt->shared->u.compnd.memb[i+1].offset);
- }
+ for(i = 0; i < (nmembs - 1); i++)
+ HDassert(dt->shared->u.compnd.memb[i].offset < dt->shared->u.compnd.memb[i + 1].offset);
#endif
- }
- } else if (H5T_ENUM==dt->shared->type) {
- if (H5T_SORT_VALUE!=dt->shared->u.enumer.sorted) {
+ } /* end if */
+ } else if(H5T_ENUM == dt->shared->type) {
+ if(H5T_SORT_VALUE != dt->shared->u.enumer.sorted) {
dt->shared->u.enumer.sorted = H5T_SORT_VALUE;
nmembs = dt->shared->u.enumer.nmembs;
size = dt->shared->size;
- assert(size<=sizeof(tbuf));
- for (i=nmembs-1, swapped=TRUE; i>0 && swapped; --i) {
- for (j=0, swapped=FALSE; j<i; j++) {
- if (HDmemcmp(dt->shared->u.enumer.value+j*size,
- dt->shared->u.enumer.value+(j+1)*size,
- size)>0) {
+ HDassert(size <= sizeof(tbuf));
+ for(i = (nmembs - 1), swapped = TRUE; i > 0 && swapped; --i) {
+ for(j = 0, swapped = FALSE; j < i; j++) {
+ if(HDmemcmp(dt->shared->u.enumer.value + (j * size), dt->shared->u.enumer.value + ((j + 1) * size), size) > 0) {
/* Swap names */
char *tmp = dt->shared->u.enumer.name[j];
- dt->shared->u.enumer.name[j] = dt->shared->u.enumer.name[j+1];
- dt->shared->u.enumer.name[j+1] = tmp;
+ dt->shared->u.enumer.name[j] = dt->shared->u.enumer.name[j + 1];
+ dt->shared->u.enumer.name[j + 1] = tmp;
/* Swap values */
- HDmemcpy(tbuf, dt->shared->u.enumer.value+j*size, size);
- HDmemcpy(dt->shared->u.enumer.value+j*size,
- dt->shared->u.enumer.value+(j+1)*size, size);
- HDmemcpy(dt->shared->u.enumer.value+(j+1)*size, tbuf, size);
+ HDmemcpy(tbuf, dt->shared->u.enumer.value + (j * size), size);
+ HDmemcpy(dt->shared->u.enumer.value + (j * size),
+ dt->shared->u.enumer.value + ((j + 1) * size), size);
+ HDmemcpy(dt->shared->u.enumer.value + ((j + 1) * size), tbuf, size);
/* Swap map */
- if (map) {
+ if(map) {
int x = map[j];
- map[j] = map[j+1];
- map[j+1] = x;
- }
+
+ map[j] = map[j + 1];
+ map[j + 1] = x;
+ } /* end if */
swapped = TRUE;
- }
- }
- }
+ } /* end if */
+ } /* end for */
+ } /* end for */
#ifndef NDEBUG
/* I never trust a sort :-) -RPM */
- for (i=0; i<nmembs-1; i++) {
- assert(HDmemcmp(dt->shared->u.enumer.value+i*size,
- dt->shared->u.enumer.value+(i+1)*size,
- size)<0);
- }
+ for(i = 0; i < (nmembs - 1); i++)
+ HDassert(HDmemcmp(dt->shared->u.enumer.value + (i * size), dt->shared->u.enumer.value + ((i + 1) * size), size) < 0);
#endif
- }
- }
+ } /* end if */
+ } /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5T_sort_value() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Tnative.c b/src/H5Tnative.c
index 0deba66..75b5d03 100644
--- a/src/H5Tnative.c
+++ b/src/H5Tnative.c
@@ -118,7 +118,7 @@ H5Tget_native_type(hid_t type_id, H5T_direction_t direction)
if((new_dt = H5T_get_native_type(dt, direction, NULL, NULL, &comp_size))==NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "cannot retrieve native type")
- if((ret_value=H5I_register(H5I_DATATYPE, new_dt)) < 0)
+ if((ret_value=H5I_register(H5I_DATATYPE, new_dt, TRUE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register data type")
done:
@@ -343,9 +343,9 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig
if((nat_super_type = H5T_get_native_type(super_type, direction, struct_align, offset, comp_size))==NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "base native type retrieval failed")
- if((super_type_id=H5I_register(H5I_DATATYPE, super_type))<0)
+ if((super_type_id=H5I_register(H5I_DATATYPE, super_type, FALSE))<0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot register datatype")
- if((nat_super_type_id=H5I_register(H5I_DATATYPE, nat_super_type))<0)
+ if((nat_super_type_id=H5I_register(H5I_DATATYPE, nat_super_type, FALSE))<0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot register datatype")
/* Allocate room for the enum values */
@@ -550,22 +550,22 @@ H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction,
native_size = sizeof(long);
} else if(prec<=H5Tget_precision(H5T_NATIVE_LLONG)) {
match=H5T_NATIVE_INT_MATCH_LLONG;
- native_size = sizeof(long_long);
+ native_size = sizeof(long long);
} else { /* If no native type matches the querried datatype, simply choose the type of biggest size. */
match=H5T_NATIVE_INT_MATCH_LLONG;
- native_size = sizeof(long_long);
+ native_size = sizeof(long long);
}
} else if(direction == H5T_DIR_DESCEND) {
if(prec>=H5Tget_precision(H5T_NATIVE_LLONG)) {
match=H5T_NATIVE_INT_MATCH_LLONG;
- native_size = sizeof(long_long);
+ native_size = sizeof(long long);
} else if(prec>=H5Tget_precision(H5T_NATIVE_LONG)) {
if(prec==H5Tget_precision(H5T_NATIVE_LONG)) {
match=H5T_NATIVE_INT_MATCH_LONG;
native_size = sizeof(long);
} else {
match=H5T_NATIVE_INT_MATCH_LLONG;
- native_size = sizeof(long_long);
+ native_size = sizeof(long long);
}
}
else if(prec>=H5Tget_precision(H5T_NATIVE_INT)) {
diff --git a/src/H5Toffset.c b/src/H5Toffset.c
index 5495368..17351f4 100644
--- a/src/H5Toffset.c
+++ b/src/H5Toffset.c
@@ -94,7 +94,7 @@ H5Tget_offset(hid_t type_id)
H5TRACE1("Is", "i", type_id);
/* Check args */
- if(NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type")
/* Get offset */
@@ -198,14 +198,14 @@ done:
herr_t
H5Tset_offset(hid_t type_id, size_t offset)
{
- H5T_t *dt = NULL;
+ H5T_t *dt;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Tset_offset, FAIL)
H5TRACE2("e", "iz", type_id, offset);
/* Check args */
- if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
+ if (NULL == (dt = (H5T_t *)H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type")
if (H5T_STATE_TRANSIENT!=dt->shared->state)
HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only")
diff --git a/src/H5Toh.c b/src/H5Toh.c
index 2a4ee86..886acc1 100644
--- a/src/H5Toh.c
+++ b/src/H5Toh.c
@@ -46,7 +46,8 @@
/********************/
static htri_t H5O_dtype_isa(H5O_t *loc);
-static hid_t H5O_dtype_open(const H5G_loc_t *obj_loc, hid_t dxpl_id);
+static hid_t H5O_dtype_open(const H5G_loc_t *obj_loc, hid_t lapl_id,
+ hid_t dxpl_id, hbool_t app_ref);
static void *H5O_dtype_create(H5F_t *f, void *_crt_info, H5G_loc_t *obj_loc,
hid_t dxpl_id);
static H5O_loc_t *H5O_dtype_get_oloc(hid_t obj_id);
@@ -75,7 +76,8 @@ const H5O_obj_class_t H5O_OBJ_DATATYPE[1] = {{
H5O_dtype_isa, /* "isa" */
H5O_dtype_open, /* open an object of this class */
H5O_dtype_create, /* create an object of this class */
- H5O_dtype_get_oloc /* get an object header location for an object */
+ H5O_dtype_get_oloc, /* get an object header location for an object */
+ NULL /* get the index & heap info for an object */
}};
@@ -127,7 +129,7 @@ done:
*-------------------------------------------------------------------------
*/
static hid_t
-H5O_dtype_open(const H5G_loc_t *obj_loc, hid_t dxpl_id)
+H5O_dtype_open(const H5G_loc_t *obj_loc, hid_t UNUSED lapl_id, hid_t dxpl_id, hbool_t app_ref)
{
H5T_t *type = NULL; /* Datatype opened */
hid_t ret_value; /* Return value */
@@ -141,7 +143,7 @@ H5O_dtype_open(const H5G_loc_t *obj_loc, hid_t dxpl_id)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to open datatype")
/* Register an ID for the datatype */
- if((ret_value = H5I_register(H5I_DATATYPE, type)) < 0)
+ if((ret_value = H5I_register(H5I_DATATYPE, type, app_ref)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype")
done:
diff --git a/src/H5Torder.c b/src/H5Torder.c
index 34dbd8e..6c0667b 100644
--- a/src/H5Torder.c
+++ b/src/H5Torder.c
@@ -158,6 +158,8 @@ H5Tset_order(hid_t type_id, H5T_order_t order)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined")
while (dt->shared->parent)
dt = dt->shared->parent; /*defer to parent*/
+ if (order == H5T_ORDER_NONE && !(H5T_REFERENCE == dt->shared->type || H5T_IS_FIXED_STRING(dt->shared)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal byte order")
if (!H5T_IS_ATOMIC(dt->shared))
HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "operation not defined for specified datatype")
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index b0abb9a..45b0e7f 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -53,10 +53,10 @@
#define H5T_NAMELEN 32
/* Macro to ease detecting "complex" datatypes (i.e. those with base types or fields) */
-#define H5T_IS_COMPLEX(t) ((t)==H5T_COMPOUND || (t)==H5T_ENUM || (t)==H5T_VLEN || (t)==H5T_ARRAY)
+#define H5T_IS_COMPLEX(t) ((t) == H5T_COMPOUND || (t) == H5T_ENUM || (t) == H5T_VLEN || (t) == H5T_ARRAY)
/* Macro to ease detecting fixed "string" datatypes */
-#define H5T_IS_FIXED_STRING(dt) (H5T_STRING == (dt)->type)
+#define H5T_IS_FIXED_STRING(dt) (H5T_STRING == (dt)->type)
/* Macro to ease detecting variable-length "string" datatypes */
#define H5T_IS_VL_STRING(dt) (H5T_VLEN == (dt)->type && H5T_VLEN_STRING == (dt)->u.vlen.type)
@@ -65,7 +65,14 @@
#define H5T_IS_STRING(dt) (H5T_IS_FIXED_STRING(dt) || H5T_IS_VL_STRING(dt))
/* Macro to ease detecting atomic datatypes */
-#define H5T_IS_ATOMIC(dt) (!(H5T_IS_COMPLEX((dt)->type) || (dt)->type==H5T_OPAQUE))
+#define H5T_IS_ATOMIC(dt) (!(H5T_IS_COMPLEX((dt)->type) || (dt)->type == H5T_OPAQUE))
+
+/* Macro to ease retrieving class of shared datatype */
+/* (Externally, a VL string is a string; internally, a VL string is a VL. Lie
+ * to the user if they have a VL string and tell them it's in the string
+ * class)
+ */
+#define H5T_GET_CLASS(shared, internal) ((internal) ? (shared)->type : (H5T_IS_VL_STRING(shared) ? H5T_STRING : (shared)->type))
/*
@@ -126,10 +133,18 @@
#define H5T_CONV_INTERNAL_INTEGER_LDOUBLE 1
#endif
-/* Define an internal macro for converting unsigned (long) long to floating numbers.
+/* Define an internal macro for converting unsigned long to float.
+ * Pathscale compiler on Sandia's Linux machine has some problem.
+ * 64-bit Solaris does different rounding. */
+#if (H5_WANT_DATA_ACCURACY && H5_ULONG_TO_FLOAT_ACCURATE && H5_ULONG_TO_FP_BOTTOM_BIT_ACCURATE) || \
+ (!H5_WANT_DATA_ACCURACY)
+#define H5T_CONV_INTERNAL_ULONG_FLT 1
+#endif
+
+/* Define an internal macro for converting unsigned (long) long to double.
* 64-bit Solaris does different rounding. */
#if (H5_WANT_DATA_ACCURACY && H5_ULONG_TO_FP_BOTTOM_BIT_ACCURATE) || (!H5_WANT_DATA_ACCURACY)
-#define H5T_CONV_INTERNAL_ULONG_FP 1
+#define H5T_CONV_INTERNAL_ULONG_DBL 1
#endif
/* Define an internal macro for converting unsigned long to long double. SGI compilers give some
@@ -226,8 +241,8 @@ struct H5T_stats_t {
/* The datatype conversion database */
struct H5T_path_t {
char name[H5T_NAMELEN]; /*name for debugging only */
- H5T_t *src; /*source datatype ID */
- H5T_t *dst; /*destination datatype ID */
+ H5T_t *src; /*source datatype */
+ H5T_t *dst; /*destination datatype */
H5T_conv_t func; /*data conversion function */
hbool_t is_hard; /*is it a hard function? */
hbool_t is_noop; /*is it the noop conversion? */
@@ -277,13 +292,22 @@ typedef enum H5T_sort_t {
H5T_SORT_VALUE = 2 /*sorted by memb offset or enum value*/
} H5T_sort_t;
+/* A compound datatype member */
+typedef struct H5T_cmemb_t {
+ char *name; /*name of this member */
+ size_t offset; /*offset from beginning of struct */
+ size_t size; /*size of this member */
+ struct H5T_t *type; /*type of this member */
+} H5T_cmemb_t;
+
/* A compound datatype */
typedef struct H5T_compnd_t {
unsigned nalloc; /*num entries allocated in MEMB array*/
unsigned nmembs; /*number of members defined in struct*/
H5T_sort_t sorted; /*how are members sorted? */
hbool_t packed; /*are members packed together? */
- struct H5T_cmemb_t *memb; /*array of struct members */
+ H5T_cmemb_t *memb; /*array of struct members */
+ size_t memb_size; /*total of all member sizes */
} H5T_compnd_t;
/* An enumeration datatype */
@@ -306,7 +330,7 @@ typedef herr_t (*H5T_vlen_setnullfunc_t)(H5F_t *f, hid_t dxpl_id, void *_vl, voi
/* VL types */
typedef enum {
H5T_VLEN_BADTYPE = -1, /* invalid VL Type */
- H5T_VLEN_SEQUENCE=0, /* VL sequence */
+ H5T_VLEN_SEQUENCE = 0, /* VL sequence */
H5T_VLEN_STRING, /* VL string */
H5T_VLEN_MAXTYPE /* highest type (Invalid as true type) */
} H5T_vlen_type_t;
@@ -374,14 +398,6 @@ struct H5T_t {
H5G_name_t path; /* group hier. path if the type is a named type */
};
-/* A compound datatype member */
-typedef struct H5T_cmemb_t {
- char *name; /*name of this member */
- size_t offset; /*offset from beginning of struct */
- size_t size; /*total size: dims * type_size */
- struct H5T_t *type; /*type of this member */
-} H5T_cmemb_t;
-
/* The master list of soft conversion functions */
typedef struct H5T_soft_t {
char name[H5T_NAMELEN]; /*name for debugging only */
@@ -1364,8 +1380,7 @@ H5_DLL H5T_t * H5T_vlen_create(const H5T_t *base);
H5_DLL htri_t H5T_vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc);
/* Array functions */
-H5_DLL H5T_t * H5T_array_create(H5T_t *base, unsigned ndims,
- const hsize_t dim[/* ndims */]);
+H5_DLL H5T_t *H5T_array_create(H5T_t *base, unsigned ndims, const hsize_t dim[/* ndims */]);
H5_DLL int H5T_get_array_ndims(const H5T_t *dt);
H5_DLL int H5T_get_array_dims(const H5T_t *dt, hsize_t dims[]);
@@ -1374,7 +1389,8 @@ H5_DLL herr_t H5T_insert(H5T_t *parent, const char *name, size_t offset,
const H5T_t *member);
H5_DLL size_t H5T_get_member_size(const H5T_t *dt, unsigned membno);
H5_DLL htri_t H5T_is_packed(const H5T_t *dt);
-H5_DLL H5T_subset_t H5T_conv_struct_subset(const H5T_cdata_t *cdata);
+H5_DLL void H5T_update_packed(const H5T_t *dt);
+H5_DLL H5T_subset_info_t *H5T_conv_struct_subset(const H5T_cdata_t *cdata);
/* Enumerated type functions */
H5_DLL H5T_t *H5T_enum_create(const H5T_t *parent);
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index 36f8006..afa6ceb 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -33,7 +33,20 @@
/* Macro for size of temporary buffers to contain a single element */
#define H5T_ELEM_BUF_SIZE 256
-/* Forward references of package typedefs */
+/* If the module using this macro is allowed access to the private variables, access them directly */
+#ifdef H5T_PACKAGE
+#define H5T_GET_SIZE(T) ((T)->shared->size)
+#define H5T_GET_SHARED(T) ((T)->shared)
+#define H5T_GET_MEMBER_OFFSET(T, I) ((T)->u.compnd.memb[I].offset)
+#define H5T_GET_MEMBER_SIZE(T, I) ((T)->u.compnd.memb[I].shared->size)
+#else /* H5T_PACKAGE */
+#define H5T_GET_SIZE(T) (H5T_get_size(T))
+#define H5T_GET_SHARED(T) (H5T_get_shared(T))
+#define H5T_GET_MEMBER_OFFSET(T, I) (H5T_get_member_offset((T), (I)))
+#define H5T_GET_MEMBER_SIZE(T, I) (H5T_get_member_size((T), (I)))
+#endif /* H5T_PACKAGE */
+
+/* Forward references of package typedefs (declared in H5Tpkg.h) */
typedef struct H5T_t H5T_t;
typedef struct H5T_stats_t H5T_stats_t;
typedef struct H5T_path_t H5T_path_t;
@@ -73,12 +86,17 @@ typedef struct H5T_conv_cb_t {
*/
typedef enum {
H5T_SUBSET_BADVALUE = -1, /* Invalid value */
- H5T_SUBSET_FALSE = 0, /* Source and destination aren't subset of each other */
+ H5T_SUBSET_FALSE = 0, /* Source and destination aren't subset of each other */
H5T_SUBSET_SRC, /* Source is the subset of dest and no conversion is needed */
H5T_SUBSET_DST, /* Dest is the subset of source and no conversion is needed */
H5T_SUBSET_CAP /* Must be the last value */
} H5T_subset_t;
+typedef struct H5T_subset_info_t {
+ H5T_subset_t subset; /* See above */
+ size_t copy_size; /* Size in bytes, to copy for each element */
+} H5T_subset_info_t;
+
/* Forward declarations for prototype arguments */
struct H5O_t;
@@ -93,7 +111,7 @@ H5_DLL herr_t H5T_lock(H5T_t *dt, hbool_t immutable);
H5_DLL herr_t H5T_close(H5T_t *dt);
H5_DLL H5T_t *H5T_get_super(const H5T_t *dt);
H5_DLL H5T_class_t H5T_get_class(const H5T_t *dt, htri_t internal);
-H5_DLL htri_t H5T_detect_class(const H5T_t *dt, H5T_class_t cls);
+H5_DLL htri_t H5T_detect_class(const H5T_t *dt, H5T_class_t cls, hbool_t from_api);
H5_DLL size_t H5T_get_size(const H5T_t *dt);
H5_DLL int H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, hbool_t superset);
H5_DLL herr_t H5T_debug(const H5T_t *dt, FILE * stream);
@@ -103,13 +121,13 @@ H5_DLL htri_t H5T_is_immutable(const H5T_t *dt);
H5_DLL htri_t H5T_is_named(const H5T_t *dt);
H5_DLL htri_t H5T_is_relocatable(const H5T_t *dt);
H5_DLL H5T_path_t *H5T_path_find(const H5T_t *src, const H5T_t *dst,
- const char *name, H5T_conv_t func, hid_t dxpl_id, hbool_t is_api);
+ const char *name, H5T_conv_t func, hid_t dxpl_id, hbool_t is_api);
H5_DLL hbool_t H5T_path_noop(const H5T_path_t *p);
H5_DLL H5T_bkg_t H5T_path_bkg(const H5T_path_t *p);
-H5_DLL H5T_subset_t H5T_path_compound_subset(const H5T_path_t *p);
+H5_DLL H5T_subset_info_t *H5T_path_compound_subset(const H5T_path_t *p);
H5_DLL herr_t H5T_convert(H5T_path_t *tpath, hid_t src_id, hid_t dst_id,
- size_t nelmts, size_t buf_stride, size_t bkg_stride,
- void *buf, void *bkg, hid_t dset_xfer_plist);
+ size_t nelmts, size_t buf_stride, size_t bkg_stride, void *buf, void *bkg,
+ hid_t dset_xfer_plist);
H5_DLL herr_t H5T_vlen_reclaim(void *elem, hid_t type_id, unsigned ndim, const hsize_t *point, void *_op_data);
H5_DLL herr_t H5T_vlen_get_alloc_info(hid_t dxpl_id, H5T_vlen_alloc_info_t **vl_alloc_info);
H5_DLL htri_t H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc);
diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h
index 40a2a4d..330a731 100644
--- a/src/H5Tpublic.h
+++ b/src/H5Tpublic.h
@@ -388,7 +388,7 @@ H5_DLLVAR hid_t H5T_VAX_F64_g;
* precision and byte order as the last component, they have a C-like type
* name. If the type begins with `U' then it is the unsigned version of the
* integer type; other integer types are signed. The type LLONG corresponds
- * to C's `long_long' and LDOUBLE is `long double' (these types might be the
+ * to C's `long long' and LDOUBLE is `long double' (these types might be the
* same as `LONG' and `DOUBLE' respectively).
*/
#define H5T_NATIVE_CHAR (CHAR_MIN?H5T_NATIVE_SCHAR:H5T_NATIVE_UCHAR)
@@ -592,7 +592,7 @@ H5_DLL herr_t H5Tconvert(hid_t src_id, hid_t dst_id, size_t nelmts,
void *buf, void *background, hid_t plist_id);
/* Symbols defined for compatibility with previous versions of the HDF5 API.
- *
+ *
* Use of these symbols is deprecated.
*/
#ifndef H5_NO_DEPRECATED_SYMBOLS
diff --git a/src/H5Tvisit.c b/src/H5Tvisit.c
index bd30a43..44e06fe 100644
--- a/src/H5Tvisit.c
+++ b/src/H5Tvisit.c
@@ -151,5 +151,5 @@ H5T_visit(H5T_t *dt, unsigned visit_flags, H5T_operator_t op, void *op_value)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5T_iterate() */
+} /* end H5T_visit() */
diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c
index bbc698f..412012a 100644
--- a/src/H5Tvlen.c
+++ b/src/H5Tvlen.c
@@ -123,7 +123,7 @@ H5Tvlen_create(hid_t base_id)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid VL location")
/* Atomize the type */
- if((ret_value = H5I_register(H5I_DATATYPE, dt)) < 0)
+ if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype")
done:
@@ -203,68 +203,63 @@ done:
* Programmer: Quincey Koziol
* Friday, June 4, 1999
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
htri_t
H5T_vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc)
{
- htri_t ret_value = 0; /* Indicate that success, but no location change */
+ htri_t ret_value = FALSE; /* Indicate success, but no location change */
FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_set_loc)
/* check parameters */
- assert(dt);
- assert(loc>H5T_LOC_BADLOC && loc<H5T_LOC_MAXLOC);
+ HDassert(dt);
+ HDassert(loc >= H5T_LOC_BADLOC && loc < H5T_LOC_MAXLOC);
/* Only change the location if it's different */
if(loc != dt->shared->u.vlen.loc || f != dt->shared->u.vlen.f) {
- /* Indicate that the location changed */
- ret_value=TRUE;
-
switch(loc) {
case H5T_LOC_MEMORY: /* Memory based VL datatype */
- assert(f==NULL);
+ HDassert(NULL == f);
/* Mark this type as being stored in memory */
- dt->shared->u.vlen.loc=H5T_LOC_MEMORY;
+ dt->shared->u.vlen.loc = H5T_LOC_MEMORY;
- if(dt->shared->u.vlen.type==H5T_VLEN_SEQUENCE) {
+ if(dt->shared->u.vlen.type == H5T_VLEN_SEQUENCE) {
/* size in memory, disk size is different */
dt->shared->size = sizeof(hvl_t);
/* Set up the function pointers to access the VL sequence in memory */
- dt->shared->u.vlen.getlen=H5T_vlen_seq_mem_getlen;
- dt->shared->u.vlen.getptr=H5T_vlen_seq_mem_getptr;
- dt->shared->u.vlen.isnull=H5T_vlen_seq_mem_isnull;
- dt->shared->u.vlen.read=H5T_vlen_seq_mem_read;
- dt->shared->u.vlen.write=H5T_vlen_seq_mem_write;
- dt->shared->u.vlen.setnull=H5T_vlen_seq_mem_setnull;
- } else if(dt->shared->u.vlen.type==H5T_VLEN_STRING) {
+ dt->shared->u.vlen.getlen = H5T_vlen_seq_mem_getlen;
+ dt->shared->u.vlen.getptr = H5T_vlen_seq_mem_getptr;
+ dt->shared->u.vlen.isnull = H5T_vlen_seq_mem_isnull;
+ dt->shared->u.vlen.read = H5T_vlen_seq_mem_read;
+ dt->shared->u.vlen.write = H5T_vlen_seq_mem_write;
+ dt->shared->u.vlen.setnull = H5T_vlen_seq_mem_setnull;
+ } else if(dt->shared->u.vlen.type == H5T_VLEN_STRING) {
/* size in memory, disk size is different */
dt->shared->size = sizeof(char *);
/* Set up the function pointers to access the VL string in memory */
- dt->shared->u.vlen.getlen=H5T_vlen_str_mem_getlen;
- dt->shared->u.vlen.getptr=H5T_vlen_str_mem_getptr;
- dt->shared->u.vlen.isnull=H5T_vlen_str_mem_isnull;
- dt->shared->u.vlen.read=H5T_vlen_str_mem_read;
- dt->shared->u.vlen.write=H5T_vlen_str_mem_write;
- dt->shared->u.vlen.setnull=H5T_vlen_str_mem_setnull;
+ dt->shared->u.vlen.getlen = H5T_vlen_str_mem_getlen;
+ dt->shared->u.vlen.getptr = H5T_vlen_str_mem_getptr;
+ dt->shared->u.vlen.isnull = H5T_vlen_str_mem_isnull;
+ dt->shared->u.vlen.read = H5T_vlen_str_mem_read;
+ dt->shared->u.vlen.write = H5T_vlen_str_mem_write;
+ dt->shared->u.vlen.setnull = H5T_vlen_str_mem_setnull;
} else {
- assert(0 && "Invalid VL type");
+ HDassert(0 && "Invalid VL type");
}
/* Reset file ID (since this VL is in memory) */
- dt->shared->u.vlen.f=NULL;
+ dt->shared->u.vlen.f = NULL;
break;
case H5T_LOC_DISK: /* Disk based VL datatype */
- assert(f);
+ HDassert(f);
/* Mark this type as being stored on disk */
- dt->shared->u.vlen.loc=H5T_LOC_DISK;
+ dt->shared->u.vlen.loc = H5T_LOC_DISK;
/*
* Size of element on disk is 4 bytes for the length, plus the size
@@ -275,20 +270,29 @@ H5T_vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc)
/* Set up the function pointers to access the VL information on disk */
/* VL sequences and VL strings are stored identically on disk, so use the same functions */
- dt->shared->u.vlen.getlen=H5T_vlen_disk_getlen;
- dt->shared->u.vlen.getptr=H5T_vlen_disk_getptr;
- dt->shared->u.vlen.isnull=H5T_vlen_disk_isnull;
- dt->shared->u.vlen.read=H5T_vlen_disk_read;
- dt->shared->u.vlen.write=H5T_vlen_disk_write;
- dt->shared->u.vlen.setnull=H5T_vlen_disk_setnull;
+ dt->shared->u.vlen.getlen = H5T_vlen_disk_getlen;
+ dt->shared->u.vlen.getptr = H5T_vlen_disk_getptr;
+ dt->shared->u.vlen.isnull = H5T_vlen_disk_isnull;
+ dt->shared->u.vlen.read = H5T_vlen_disk_read;
+ dt->shared->u.vlen.write = H5T_vlen_disk_write;
+ dt->shared->u.vlen.setnull = H5T_vlen_disk_setnull;
/* Set file ID (since this VL is on disk) */
- dt->shared->u.vlen.f=f;
+ dt->shared->u.vlen.f = f;
+ break;
+
+ case H5T_LOC_BADLOC:
+ /* Allow undefined location. In H5Odtype.c, H5O_dtype_decode sets undefined
+ * location for VL type and leaves it for the caller to decide.
+ */
break;
default:
HGOTO_ERROR(H5E_DATATYPE, H5E_BADRANGE, FAIL, "invalid VL datatype location")
} /* end switch */ /*lint !e788 All appropriate cases are covered */
+
+ /* Indicate that the location changed */
+ ret_value = TRUE;
} /* end if */
done:
@@ -306,21 +310,35 @@ done:
* Programmer: Quincey Koziol
* Wednesday, June 2, 1999
*
- * Modifications:
+ * Modifications: Neil Fortner
+ * Friday, August 22, 2008
+ * Changed function to be tolerant of an hvl_t that is not aligned
+ * properly in _vl.
*
*-------------------------------------------------------------------------
*/
static ssize_t
H5T_vlen_seq_mem_getlen(const void *_vl)
{
+#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
const hvl_t *vl=(const hvl_t *)_vl; /* Pointer to the user's hvl_t information */
+#else
+ hvl_t vl; /* User's hvl_t information */
+#endif
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_seq_mem_getlen)
- /* check parameters */
- assert(vl);
+ /* check parameters, return result */
+#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
+ HDassert(vl);
FUNC_LEAVE_NOAPI((ssize_t)vl->len)
+#else
+ HDassert(_vl);
+ HDmemcpy(&vl, _vl, sizeof(hvl_t));
+
+ FUNC_LEAVE_NOAPI((ssize_t)vl.len)
+#endif
} /* end H5T_vlen_seq_mem_getlen() */
@@ -334,21 +352,35 @@ H5T_vlen_seq_mem_getlen(const void *_vl)
* Programmer: Quincey Koziol
* Saturday, June 12, 2004
*
- * Modifications:
+ * Modifications: Neil Fortner
+ * Friday, August 22, 2008
+ * Changed function to be tolerant of an hvl_t that is not aligned
+ * properly in _vl.
*
*-------------------------------------------------------------------------
*/
static void *
H5T_vlen_seq_mem_getptr(void *_vl)
{
- hvl_t *vl=(hvl_t *)_vl; /* Pointer to the user's hvl_t information */
+#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
+ const hvl_t *vl=(const hvl_t *)_vl; /* Pointer to the user's hvl_t information */
+#else
+ hvl_t vl; /* User's hvl_t information */
+#endif
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_seq_mem_getptr)
- /* check parameters */
- assert(vl);
+ /* check parameters, return result */
+#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
+ HDassert(vl);
FUNC_LEAVE_NOAPI(vl->p)
+#else
+ HDassert(_vl);
+ HDmemcpy(&vl, _vl, sizeof(hvl_t));
+
+ FUNC_LEAVE_NOAPI(vl.p)
+#endif
} /* end H5T_vlen_seq_mem_getptr() */
@@ -362,7 +394,10 @@ H5T_vlen_seq_mem_getptr(void *_vl)
* Programmer: Quincey Koziol
* Saturday, November 8, 2003
*
- * Modifications:
+ * Modifications: Neil Fortner
+ * Friday, August 22, 2008
+ * Changed function to be tolerant of an hvl_t that is not aligned
+ * properly in _vl.
*
*-------------------------------------------------------------------------
*/
@@ -370,14 +405,25 @@ H5T_vlen_seq_mem_getptr(void *_vl)
static htri_t
H5T_vlen_seq_mem_isnull(const H5F_t UNUSED *f, void *_vl)
{
- hvl_t *vl=(hvl_t *)_vl; /* Pointer to the user's hvl_t information */
+#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
+ const hvl_t *vl=(const hvl_t *)_vl; /* Pointer to the user's hvl_t information */
+#else
+ hvl_t vl; /* User's hvl_t information */
+#endif
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_seq_mem_isnull)
- /* check parameters */
- assert(vl);
+ /* check parameters, return result */
+#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
+ HDassert(vl);
FUNC_LEAVE_NOAPI((vl->len==0 || vl->p==NULL) ? TRUE : FALSE)
+#else
+ HDassert(_vl);
+ HDmemcpy(&vl, _vl, sizeof(hvl_t));
+
+ FUNC_LEAVE_NOAPI((vl.len==0 || vl.p==NULL) ? TRUE : FALSE)
+#endif
} /* end H5T_vlen_seq_mem_isnull() */
@@ -391,7 +437,10 @@ H5T_vlen_seq_mem_isnull(const H5F_t UNUSED *f, void *_vl)
* Programmer: Quincey Koziol
* Wednesday, June 2, 1999
*
- * Modifications:
+ * Modifications: Neil Fortner
+ * Friday, August 22, 2008
+ * Changed function to be tolerant of an hvl_t that is not aligned
+ * properly in _vl.
*
*-------------------------------------------------------------------------
*/
@@ -399,15 +448,27 @@ H5T_vlen_seq_mem_isnull(const H5F_t UNUSED *f, void *_vl)
static herr_t
H5T_vlen_seq_mem_read(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void *buf, size_t len)
{
- hvl_t *vl=(hvl_t *)_vl; /* Pointer to the user's hvl_t information */
+#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
+ const hvl_t *vl=(const hvl_t *)_vl; /* Pointer to the user's hvl_t information */
+#else
+ hvl_t vl; /* User's hvl_t information */
+#endif
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_seq_mem_read)
- /* check parameters */
- assert(vl && vl->p);
- assert(buf);
+ /* check parameters, copy data */
+ HDassert(buf);
+#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
+ HDassert(vl && vl->p);
HDmemcpy(buf,vl->p,len);
+#else
+ HDassert(_vl);
+ HDmemcpy(&vl, _vl, sizeof(hvl_t));
+ HDassert(vl.p);
+
+ HDmemcpy(buf,vl.p,len);
+#endif
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5T_vlen_seq_mem_read() */
@@ -438,8 +499,8 @@ H5T_vlen_seq_mem_write(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const H5T_vlen_all
FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_seq_mem_write)
/* check parameters */
- assert(_vl);
- assert(buf);
+ HDassert(_vl);
+ HDassert(buf);
if(seq_len!=0) {
len=seq_len*base_size;
@@ -495,7 +556,7 @@ H5T_vlen_seq_mem_setnull(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_seq_mem_setnull)
/* check parameters */
- assert(_vl);
+ HDassert(_vl);
/* Set the "nil" hvl_t */
vl.len=0;
@@ -518,19 +579,31 @@ H5T_vlen_seq_mem_setnull(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void
* Programmer: Quincey Koziol
* Wednesday, June 2, 1999
*
- * Modifications:
+ * Modifications: Neil Fortner
+ * Friday, August 22, 2008
+ * Changed function to be tolerant of a char * that is not aligned
+ * properly in _vl.
*
*-------------------------------------------------------------------------
*/
static ssize_t
H5T_vlen_str_mem_getlen(const void *_vl)
{
+#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
const char *s=*(const char * const *)_vl; /* Pointer to the user's string information */
+#else
+ const char *s; /* Pointer to the user's string information */
+#endif
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_str_mem_getlen)
/* check parameters */
- assert(s);
+#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
+ HDassert(s);
+#else
+ HDassert(_vl);
+ HDmemcpy(&s, _vl, sizeof(char *));
+#endif
FUNC_LEAVE_NOAPI((ssize_t)HDstrlen(s))
} /* end H5T_vlen_str_mem_getlen() */
@@ -546,19 +619,32 @@ H5T_vlen_str_mem_getlen(const void *_vl)
* Programmer: Quincey Koziol
* Saturday, June 12, 2004
*
- * Modifications:
+ * Modifications: Neil Fortner
+ * Friday, August 22, 2008
+ * Changed function to be tolerant of a char * that is not aligned
+ * properly in _vl.
+ * Added assertion on _vl.
*
*-------------------------------------------------------------------------
*/
static void *
H5T_vlen_str_mem_getptr(void *_vl)
{
+#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
char *s=*(char **)_vl; /* Pointer to the user's string information */
+#else
+ char *s; /* Pointer to the user's string information */
+#endif
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_str_mem_getptr)
/* check parameters */
- assert(s);
+#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
+ HDassert(s);
+#else
+ HDassert(_vl);
+ HDmemcpy(&s, _vl, sizeof(char *));
+#endif
FUNC_LEAVE_NOAPI(s)
} /* end H5T_vlen_str_mem_getptr() */
@@ -574,7 +660,10 @@ H5T_vlen_str_mem_getptr(void *_vl)
* Programmer: Quincey Koziol
* Saturday, November 8, 2003
*
- * Modifications:
+ * Modifications: Neil Fortner
+ * Friday, August 22, 2008
+ * Changed function to be tolerant of a char * that is not aligned
+ * properly in _vl.
*
*-------------------------------------------------------------------------
*/
@@ -582,10 +671,18 @@ H5T_vlen_str_mem_getptr(void *_vl)
static htri_t
H5T_vlen_str_mem_isnull(const H5F_t UNUSED *f, void *_vl)
{
+#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
char *s=*(char **)_vl; /* Pointer to the user's string information */
+#else
+ char *s; /* Pointer to the user's string information */
+#endif
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_str_mem_isnull)
+#ifndef H5_NO_ALIGNMENT_RESTRICTIONS
+ HDmemcpy(&s, _vl, sizeof(char *));
+#endif
+
FUNC_LEAVE_NOAPI(s==NULL ? TRUE : FALSE)
} /* end H5T_vlen_str_mem_isnull() */
@@ -600,7 +697,10 @@ H5T_vlen_str_mem_isnull(const H5F_t UNUSED *f, void *_vl)
* Programmer: Quincey Koziol
* Wednesday, June 2, 1999
*
- * Modifications:
+ * Modifications: Neil Fortner
+ * Friday, August 22, 2008
+ * Changed function to be tolerant of a char * that is not aligned
+ * properly in _vl.
*
*-------------------------------------------------------------------------
*/
@@ -608,14 +708,23 @@ H5T_vlen_str_mem_isnull(const H5F_t UNUSED *f, void *_vl)
static herr_t
H5T_vlen_str_mem_read(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void *buf, size_t len)
{
- char *s=*(char **)_vl; /* Pointer to the user's hvl_t information */
+#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
+ char *s=*(char **)_vl; /* Pointer to the user's string information */
+#else
+ char *s; /* Pointer to the user's string information */
+#endif
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_str_mem_read)
if(len>0) {
/* check parameters */
- assert(s);
- assert(buf);
+ HDassert(buf);
+#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
+ HDassert(s);
+#else
+ HDassert(_vl);
+ HDmemcpy(&s, _vl, sizeof(char *));
+#endif
HDmemcpy(buf,s,len);
} /* end if */
@@ -649,7 +758,7 @@ H5T_vlen_str_mem_write(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const H5T_vlen_all
FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_str_mem_write)
/* check parameters */
- assert(buf);
+ HDassert(buf);
/* Use the user's memory allocation routine if one is defined */
if(vl_alloc_info->alloc_func!=NULL) {
@@ -725,7 +834,7 @@ H5T_vlen_disk_getlen(const void *_vl)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_disk_getlen)
/* check parameters */
- assert(vl);
+ HDassert(vl);
UINT32DECODE(vl, seq_len);
@@ -754,7 +863,7 @@ H5T_vlen_disk_getptr(void UNUSED *vl)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_disk_getptr)
/* check parameters */
- assert(vl);
+ HDassert(vl);
FUNC_LEAVE_NOAPI(NULL)
} /* end H5T_vlen_disk_getptr() */
@@ -783,7 +892,7 @@ H5T_vlen_disk_isnull(const H5F_t *f, void *_vl)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_disk_isnull)
/* check parameters */
- assert(vl);
+ HDassert(vl);
/* Skip the sequence's length */
vl+=4;
@@ -820,9 +929,9 @@ H5T_vlen_disk_read(H5F_t *f, hid_t dxpl_id, void *_vl, void *buf, size_t UNUSED
FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_disk_read)
/* check parameters */
- assert(vl);
- assert(buf);
- assert(f);
+ HDassert(vl);
+ HDassert(buf);
+ HDassert(f);
/* Skip the length of the sequence */
vl += 4;
@@ -874,9 +983,9 @@ H5T_vlen_disk_write(H5F_t *f, hid_t dxpl_id, const H5T_vlen_alloc_info_t UNUSED
FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_disk_write)
/* check parameters */
- assert(vl);
- assert(seq_len==0 || buf);
- assert(f);
+ HDassert(vl);
+ HDassert(seq_len==0 || buf);
+ HDassert(f);
/* Free heap object for old data. */
if(bg!=NULL) {
@@ -939,8 +1048,8 @@ H5T_vlen_disk_setnull(H5F_t *f, hid_t dxpl_id, void *_vl, void *_bg)
FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_disk_setnull)
/* check parameters */
- assert(f);
- assert(vl);
+ HDassert(f);
+ HDassert(vl);
/* Free heap object for old data. */
if(bg!=NULL) {
@@ -1002,8 +1111,8 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi
FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_reclaim_recurse)
- assert(elem);
- assert(dt);
+ HDassert(elem);
+ HDassert(dt);
/* Check the datatype of this element */
switch(dt->shared->type) {
@@ -1069,7 +1178,7 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi
else
H5MM_xfree(*(char **)elem);
} else {
- assert(0 && "Invalid VL type");
+ HDassert(0 && "Invalid VL type");
} /* end else */
break;
@@ -1116,9 +1225,9 @@ H5T_vlen_reclaim(void *elem, hid_t type_id, unsigned UNUSED ndim, const hsize_t
FUNC_ENTER_NOAPI(H5T_vlen_reclaim, FAIL)
- assert(elem);
- assert(vl_alloc_info);
- assert(H5I_DATATYPE == H5I_get_type(type_id));
+ HDassert(elem);
+ HDassert(vl_alloc_info);
+ HDassert(H5I_DATATYPE == H5I_get_type(type_id));
/* Check args */
if (NULL==(dt=H5I_object_verify(type_id,H5I_DATATYPE)))
@@ -1163,8 +1272,8 @@ H5T_vlen_get_alloc_info(hid_t dxpl_id, H5T_vlen_alloc_info_t **vl_alloc_info)
FUNC_ENTER_NOAPI(H5T_vlen_get_alloc_info, FAIL)
- assert(H5I_GENPROP_LST == H5I_get_type(dxpl_id));
- assert(vl_alloc_info);
+ HDassert(H5I_GENPROP_LST == H5I_get_type(dxpl_id));
+ HDassert(vl_alloc_info);
/* Check for the default DXPL */
if(dxpl_id==H5P_DATASET_XFER_DEFAULT)
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/H5WB.c b/src/H5WB.c
index e53c70c..c3e3a6f 100644
--- a/src/H5WB.c
+++ b/src/H5WB.c
@@ -284,7 +284,7 @@ H5WB_unwrap(H5WB_t *wb)
} /* end if */
/* Release the buffer wrapper info */
- H5FL_FREE(H5WB_t, wb);
+ wb = H5FL_FREE(H5WB_t, wb);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5WB_unwrap() */
diff --git a/src/H5Z.c b/src/H5Z.c
index cbd2f3e..c295df3 100644
--- a/src/H5Z.c
+++ b/src/H5Z.c
@@ -53,7 +53,7 @@ typedef enum {
/* Local variables */
static size_t H5Z_table_alloc_g = 0;
static size_t H5Z_table_used_g = 0;
-static H5Z_class_t *H5Z_table_g = NULL;
+static H5Z_class2_t *H5Z_table_g = NULL;
#ifdef H5Z_DEBUG
static H5Z_stats_t *H5Z_stat_table_g = NULL;
#endif /* H5Z_DEBUG */
@@ -133,7 +133,7 @@ done:
*-------------------------------------------------------------------------
*/
int
-H5Z_term_interface (void)
+H5Z_term_interface(void)
{
#ifdef H5Z_DEBUG
size_t i;
@@ -141,7 +141,7 @@ H5Z_term_interface (void)
char comment[16], bandwidth[32];
#endif
- if (H5_interface_initialize_g) {
+ if(H5_interface_initialize_g) {
#ifdef H5Z_DEBUG
if (H5DEBUG(Z)) {
for (i=0; i<H5Z_table_used_g; i++) {
@@ -191,15 +191,16 @@ H5Z_term_interface (void)
}
#endif /* H5Z_DEBUG */
/* Free the table of filters */
- H5Z_table_g = H5MM_xfree(H5Z_table_g);
+ H5Z_table_g = (H5Z_class2_t *)H5MM_xfree(H5Z_table_g);
#ifdef H5Z_DEBUG
- H5Z_stat_table_g = H5MM_xfree(H5Z_stat_table_g);
+ H5Z_stat_table_g = (H5Z_stats_t *)H5MM_xfree(H5Z_stat_table_g);
#endif /* H5Z_DEBUG */
H5Z_table_used_g = H5Z_table_alloc_g = 0;
H5_interface_initialize_g = 0;
- }
- return 0;
-}
+ } /* end if */
+
+ return(0);
+} /* end H5Z_term_interface() */
/*-------------------------------------------------------------------------
@@ -219,32 +220,62 @@ H5Z_term_interface (void)
*-------------------------------------------------------------------------
*/
herr_t
-H5Zregister(const H5Z_class_t *cls)
+H5Zregister(const void *cls)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ const H5Z_class2_t *cls_real = (const H5Z_class2_t *) cls; /* "Real" class pointer */
+ H5Z_class2_t cls_new; /* Translated class struct */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Zregister, FAIL)
- H5TRACE1("e", "*Zc", cls);
+ H5TRACE1("e", "*x", cls);
/* Check args */
- if (cls==NULL)
+ if (cls_real==NULL)
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter class")
/* Check H5Z_class_t version number; this is where a function to convert
* from an outdated version should be called.
+ *
+ * If the version number is invalid, we assume that the target of cls is the
+ * old style "H5Z_class1_t" structure, which did not contain a version
+ * field. In this structure, the first field is the id. Since both version
+ * and id are integers they will have the same value, and since id must be
+ * at least 256, there should be no overlap and the version of the struct
+ * can be determined by the value of the first field.
*/
- if(cls->version != H5Z_CLASS_T_VERS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid H5Z_class_t version number");
+ if(cls_real->version != H5Z_CLASS_T_VERS) {
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+ /* Assume it is an old "H5Z_class1_t" instead */
+ const H5Z_class1_t *cls_old = (const H5Z_class1_t *) cls;
+
+ /* Translate to new H5Z_class2_t */
+ cls_new.version = H5Z_CLASS_T_VERS;
+ cls_new.id = cls_old->id;
+ cls_new.encoder_present = 1;
+ cls_new.decoder_present = 1;
+ cls_new.name = cls_old->name;
+ cls_new.can_apply = cls_old->can_apply;
+ cls_new.set_local = cls_old->set_local;
+ cls_new.filter = cls_old->filter;
+
+ /* Set cls_real to point to the translated structure */
+ cls_real = &cls_new;
+
+#else /* H5_NO_DEPRECATED_SYMBOLS */
+ /* Deprecated symbols not allowed, throw an error */
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid H5Z_class_t version number");
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
+ } /* end if */
- if (cls->id<0 || cls->id>H5Z_FILTER_MAX)
+ if (cls_real->id<0 || cls_real->id>H5Z_FILTER_MAX)
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identification number")
- if (cls->id<H5Z_FILTER_RESERVED)
+ if (cls_real->id<H5Z_FILTER_RESERVED)
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "unable to modify predefined filters")
- if (cls->filter==NULL)
+ if (cls_real->filter==NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no filter function specified")
/* Do it */
- if (H5Z_register (cls)<0)
+ if (H5Z_register (cls_real)<0)
HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register filter")
done:
@@ -268,36 +299,34 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Z_register (const H5Z_class_t *cls)
+H5Z_register (const H5Z_class2_t *cls)
{
- size_t i;
- herr_t ret_value=SUCCEED; /* Return value */
+ size_t i;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5Z_register, FAIL)
- assert (cls);
- assert (cls->id>=0 && cls->id<=H5Z_FILTER_MAX);
+ HDassert(cls);
+ HDassert(cls->id >= 0 && cls->id <= H5Z_FILTER_MAX);
/* Is the filter already registered? */
- for (i=0; i<H5Z_table_used_g; i++)
- if (H5Z_table_g[i].id==cls->id)
+ for(i = 0; i < H5Z_table_used_g; i++)
+ if(H5Z_table_g[i].id == cls->id)
break;
/* Filter not already registered */
- if (i>=H5Z_table_used_g) {
- if (H5Z_table_used_g>=H5Z_table_alloc_g) {
+ if(i >= H5Z_table_used_g) {
+ if(H5Z_table_used_g >= H5Z_table_alloc_g) {
size_t n = MAX(H5Z_MAX_NFILTERS, 2*H5Z_table_alloc_g);
- H5Z_class_t *table = H5MM_realloc(H5Z_table_g,
- n*sizeof(H5Z_class_t));
+ H5Z_class2_t *table = (H5Z_class2_t *)H5MM_realloc(H5Z_table_g, n * sizeof(H5Z_class2_t));
#ifdef H5Z_DEBUG
- H5Z_stats_t *stat_table = H5MM_realloc(H5Z_stat_table_g,
- n*sizeof(H5Z_stats_t));
+ H5Z_stats_t *stat_table = (H5Z_stats_t *)H5MM_realloc(H5Z_stat_table_g, n * sizeof(H5Z_stats_t));
#endif /* H5Z_DEBUG */
- if (!table)
+ if(!table)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to extend filter table")
H5Z_table_g = table;
#ifdef H5Z_DEBUG
- if (!stat_table)
+ if(!stat_table)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to extend filter statistics table")
H5Z_stat_table_g = stat_table;
#endif /* H5Z_DEBUG */
@@ -306,7 +335,7 @@ H5Z_register (const H5Z_class_t *cls)
/* Initialize */
i = H5Z_table_used_g++;
- HDmemcpy(H5Z_table_g+i, cls, sizeof(H5Z_class_t));
+ HDmemcpy(H5Z_table_g+i, cls, sizeof(H5Z_class2_t));
#ifdef H5Z_DEBUG
HDmemset(H5Z_stat_table_g+i, 0, sizeof(H5Z_stats_t));
#endif /* H5Z_DEBUG */
@@ -314,7 +343,7 @@ H5Z_register (const H5Z_class_t *cls)
/* Filter already registered */
else {
/* Replace old contents */
- HDmemcpy(H5Z_table_g+i, cls, sizeof(H5Z_class_t));
+ HDmemcpy(H5Z_table_g+i, cls, sizeof(H5Z_class2_t));
} /* end else */
done:
@@ -395,7 +424,7 @@ H5Z_unregister (H5Z_filter_t id)
/* Remove filter from table */
/* Don't worry about shrinking table size (for now) */
- HDmemmove(&H5Z_table_g[i],&H5Z_table_g[i+1],sizeof(H5Z_class_t)*((H5Z_table_used_g-1)-i));
+ HDmemmove(&H5Z_table_g[i],&H5Z_table_g[i+1],sizeof(H5Z_class2_t)*((H5Z_table_used_g-1)-i));
#ifdef H5Z_DEBUG
HDmemmove(&H5Z_stat_table_g[i],&H5Z_stat_table_g[i+1],sizeof(H5Z_stats_t)*((H5Z_table_used_g-1)-i));
#endif /* H5Z_DEBUG */
@@ -461,27 +490,114 @@ done:
* of passing in the dataset's dataspace, since the chunk
* dimensions are what the I/O filter will actually see
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_type)
+H5Z_prelude_callback(const H5O_pline_t *pline, hid_t dcpl_id, hid_t type_id,
+ hid_t space_id, H5Z_prelude_type_t prelude_type)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ H5Z_class2_t *fclass; /* Individual filter information */
+ size_t u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5Z_prelude_callback)
- assert (H5I_GENPROP_LST==H5I_get_type(dcpl_id));
- assert (H5I_DATATYPE==H5I_get_type(type_id));
+ HDassert(pline->nused > 0);
+
+ /* Iterate over filters */
+ for(u = 0; u < pline->nused; u++) {
+ /* Get filter information */
+ if(NULL == (fclass = H5Z_find(pline->filter[u].id))) {
+ /* Ignore errors from optional filters */
+ if(pline->filter[u].flags & H5Z_FLAG_OPTIONAL)
+ H5E_clear_stack(NULL);
+ else
+ HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, FAIL, "required filter was not located")
+ } /* end if */
+ else {
+ /* Make correct callback */
+ switch(prelude_type) {
+ case H5Z_PRELUDE_CAN_APPLY:
+ /* Check if filter is configured to be able to encode */
+ if(!fclass->encoder_present)
+ HGOTO_ERROR(H5E_PLINE, H5E_NOENCODER, FAIL, "Filter present but encoding is disabled.");
+
+
+ /* Check if there is a "can apply" callback */
+ if(fclass->can_apply) {
+ /* Make callback to filter's "can apply" function */
+ herr_t status = (fclass->can_apply)(dcpl_id, type_id, space_id);
+
+ /* Check return value */
+ if(status <= 0) {
+ /* Indicate filter can't apply to this combination of parameters */
+ if(status == 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "filter parameters not appropriate")
+ /* Indicate error during filter callback */
+ else
+ HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "error during user callback")
+ } /* end if */
+ } /* end if */
+ break;
+
+ case H5Z_PRELUDE_SET_LOCAL:
+ /* Check if there is a "set local" callback */
+ if(fclass->set_local) {
+ /* Make callback to filter's "set local" function */
+ if((fclass->set_local)(dcpl_id, type_id, space_id) < 0)
+ /* Indicate error during filter callback */
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "error during user callback")
+ } /* end if */
+ break;
+
+ default:
+ HDassert("invalid prelude type" && 0);
+ } /* end switch */
+ } /* end else */
+ } /* end for */
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_prelude_callback() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_prepare_prelude_callback_dcpl
+ *
+ * Purpose: Prepares to make a dataset creation "prelude" callback
+ * for the "can_apply" or "set_local" routines.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, April 4, 2003
+ *
+ * Notes:
+ * The chunk dimensions are used to create a dataspace, instead
+ * of passing in the dataset's dataspace, since the chunk
+ * dimensions are what the I/O filter will actually see
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_prepare_prelude_callback_dcpl(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_type)
+{
+ hid_t space_id = -1; /* ID for dataspace describing chunk */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5Z_prepare_prelude_callback_dcpl)
+
+ HDassert(H5I_GENPROP_LST == H5I_get_type(dcpl_id));
+ HDassert(H5I_DATATYPE == H5I_get_type(type_id));
/* Check if the property list is non-default */
- if(dcpl_id!=H5P_DATASET_CREATE_DEFAULT) {
+ if(dcpl_id != H5P_DATASET_CREATE_DEFAULT) {
H5P_genplist_t *dc_plist; /* Dataset creation property list object */
- H5D_layout_t dcpl_layout; /* Dataset's layout information */
+ H5O_layout_t dcpl_layout; /* Dataset's layout information */
/* Get dataset creation property list object */
- if (NULL == (dc_plist = H5I_object(dcpl_id)))
+ if(NULL == (dc_plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get dataset creation property list")
/* Get layout information */
@@ -489,115 +605,44 @@ H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_ty
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve layout")
/* Check if the dataset is chunked */
- if(H5D_CHUNKED == dcpl_layout) {
- H5O_pline_t dcpl_pline; /* Dataset's I/O pipeline information */
+ if(H5D_CHUNKED == dcpl_layout.type) {
+ H5O_pline_t dcpl_pline; /* Object's I/O pipeline information */
/* Get I/O pipeline information */
- if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &dcpl_pline) < 0)
+ if(H5P_get(dc_plist, H5O_CRT_PIPELINE_NAME, &dcpl_pline) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve pipeline filter")
/* Check if the chunks have filters */
if(dcpl_pline.nused > 0) {
- unsigned chunk_ndims; /* # of chunk dimensions */
- uint32_t chunk_size[H5O_LAYOUT_NDIMS]; /* Size of chunk dimensions */
hsize_t chunk_dims[H5O_LAYOUT_NDIMS]; /* Size of chunk dimensions */
H5S_t *space; /* Dataspace describing chunk */
- hid_t space_id; /* ID for dataspace describing chunk */
size_t u; /* Local index variable */
- /* Get chunk information */
- if(H5P_get(dc_plist, H5D_CRT_CHUNK_DIM_NAME, &chunk_ndims) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve chunk dimensions")
- if(H5P_get(dc_plist, H5D_CRT_CHUNK_SIZE_NAME, chunk_size) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve chunk size")
-
/* Create a data space for a chunk & set the extent */
- for(u = 0; u < chunk_ndims; u++)
- chunk_dims[u] = chunk_size[u];
- if(NULL == (space = H5S_create_simple(chunk_ndims,chunk_dims,NULL)))
+ for(u = 0; u < dcpl_layout.u.chunk.ndims; u++)
+ chunk_dims[u] = dcpl_layout.u.chunk.dim[u];
+ if(NULL == (space = H5S_create_simple(dcpl_layout.u.chunk.ndims, chunk_dims, NULL)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace")
/* Get ID for dataspace to pass to filter routines */
- if ((space_id=H5I_register (H5I_DATASPACE, space))<0) {
+ if((space_id = H5I_register(H5I_DATASPACE, space, FALSE)) < 0) {
(void)H5S_close(space);
- HGOTO_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID")
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID")
} /* end if */
- /* Iterate over filters */
- for (u=0; u<dcpl_pline.nused; u++) {
- H5Z_class_t *fclass; /* Individual filter information */
-
- /* Get filter information */
- if (NULL==(fclass=H5Z_find(dcpl_pline.filter[u].id))) {
- /* Ignore errors from optional filters */
- if (dcpl_pline.filter[u].flags & H5Z_FLAG_OPTIONAL)
- H5E_clear_stack(NULL);
- else
- HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, FAIL, "required filter was not located")
- } /* end if */
- else {
- /* Make correct callback */
- switch(prelude_type) {
- case H5Z_PRELUDE_CAN_APPLY:
- /* Check if filter is configured to be able to encode */
- if(! fclass->encoder_present)
- HGOTO_ERROR(H5E_PLINE, H5E_NOENCODER, FAIL, "Filter present but encoding is disabled.");
-
-
- /* Check if there is a "can apply" callback */
- if(fclass->can_apply) {
- /* Make callback to filter's "can apply" function */
- herr_t status=(fclass->can_apply)(dcpl_id, type_id, space_id);
-
- /* Check return value */
- if(status<=0) {
- /* We're leaving, so close dataspace */
- if(H5I_dec_ref(space_id)<0)
- HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace")
-
- /* Indicate filter can't apply to this combination of parameters */
- if(status==0) {
- HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "filter parameters not appropriate")
- } /* end if */
- /* Indicate error during filter callback */
- else {
- HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "error during user callback")
- } /* end if */
- } /* end if */
- } /* end if */
- break;
-
- case H5Z_PRELUDE_SET_LOCAL:
- /* Check if there is a "set local" callback */
- if(fclass->set_local) {
- /* Make callback to filter's "set local" function */
- if((fclass->set_local)(dcpl_id, type_id, space_id)<0) {
- /* We're leaving, so close dataspace */
- if(H5I_dec_ref(space_id)<0)
- HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace")
-
- /* Indicate error during filter callback */
- HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "error during user callback")
- } /* end if */
- } /* end if */
- break;
-
- default:
- assert("invalid prelude type" && 0);
- } /* end switch */
- } /* end else */
- } /* end for */
-
- /* Close dataspace */
- if(H5I_dec_ref(space_id)<0)
- HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace")
+ /* Make the callbacks */
+ if(H5Z_prelude_callback(&dcpl_pline, dcpl_id, type_id, space_id, prelude_type) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "unable to apply filter")
} /* end if */
} /* end if */
} /* end if */
done:
+ if(space_id > 0 && H5I_dec_ref(space_id, FALSE) < 0)
+ HDONE_ERROR(H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace")
+
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5Z_prelude_callback() */
+} /* end H5Z_prepare_prelude_callback_dcpl() */
/*-------------------------------------------------------------------------
@@ -617,22 +662,17 @@ done:
* of passing in the dataset's dataspace, since the chunk
* dimensions are what the I/O filter will actually see
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5Z_can_apply (hid_t dcpl_id, hid_t type_id)
+H5Z_can_apply(hid_t dcpl_id, hid_t type_id)
{
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5Z_can_apply,FAIL)
+ herr_t ret_value = SUCCEED; /* Return value */
- assert (H5I_GENPROP_LST==H5I_get_type(dcpl_id));
- assert (H5I_DATATYPE==H5I_get_type(type_id));
+ FUNC_ENTER_NOAPI(H5Z_can_apply, FAIL)
/* Make "can apply" callbacks for filters in pipeline */
- if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_CAN_APPLY)<0)
+ if(H5Z_prepare_prelude_callback_dcpl(dcpl_id, type_id, H5Z_PRELUDE_CAN_APPLY) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "unable to apply filter")
done:
@@ -657,27 +697,91 @@ done:
* of passing in the dataset's dataspace, since the chunk
* dimensions are what the I/O filter will actually see
*
- * Modifications:
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Z_set_local(hid_t dcpl_id, hid_t type_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_set_local, FAIL)
+
+ /* Make "set local" callbacks for filters in pipeline */
+ if(H5Z_prepare_prelude_callback_dcpl(dcpl_id, type_id, H5Z_PRELUDE_SET_LOCAL) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "local filter parameters not set")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_set_local() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_can_apply_direct
+ *
+ * Purpose: Checks if all the filters defined in the pipeline can be
+ * applied to an opaque byte stream (currently only a group).
+ * The pipeline is assumed to have at least one filter.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, September 22, 2009
*
*-------------------------------------------------------------------------
*/
herr_t
-H5Z_set_local (hid_t dcpl_id, hid_t type_id)
+H5Z_can_apply_direct(const H5O_pline_t *pline)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_can_apply_direct, FAIL)
+
+ HDassert(pline->nused > 0);
+
+ /* Make "can apply" callbacks for filters in pipeline */
+ if(H5Z_prelude_callback(pline, -1, -1, -1, H5Z_PRELUDE_CAN_APPLY) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "unable to apply filter")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_can_apply_direct() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_set_local_direct
+ *
+ * Purpose: Makes callbacks to modify local settings for filters on a
+ * new opaque object. The pipeline is assumed to have at
+ * least one filter.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, September 22, 2009
+ *
+ * Notes:
+ * This callback will almost certainly not do anything
+ * useful, other than to make certain that the filter will
+ * accept opque data.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Z_set_local_direct(const H5O_pline_t *pline)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5Z_set_local,FAIL)
+ FUNC_ENTER_NOAPI(H5Z_set_local_direct, FAIL)
- assert (H5I_GENPROP_LST==H5I_get_type(dcpl_id));
- assert (H5I_DATATYPE==H5I_get_type(type_id));
+ HDassert(pline->nused > 0);
/* Make "set local" callbacks for filters in pipeline */
- if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_SET_LOCAL)<0)
+ if(H5Z_prelude_callback(pline, -1, -1, -1, H5Z_PRELUDE_SET_LOCAL) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "local filter parameters not set")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5Z_set_local() */
+} /* end H5Z_set_local_direct() */
/*-------------------------------------------------------------------------
@@ -731,7 +835,7 @@ H5Z_modify(const H5O_pline_t *pline, H5Z_filter_t filter, unsigned flags,
/* Allocate memory or point at internal buffer */
if(cd_nelmts > H5Z_COMMON_CD_VALUES) {
- pline->filter[idx].cd_values = H5MM_malloc(cd_nelmts * sizeof(unsigned));
+ pline->filter[idx].cd_values = (unsigned *)H5MM_malloc(cd_nelmts * sizeof(unsigned));
if(NULL == pline->filter[idx].cd_values)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for filter parameters")
} /* end if */
@@ -803,10 +907,10 @@ H5Z_append(H5O_pline_t *pline, H5Z_filter_t filter, unsigned flags,
*/
for(n = 0; n < pline->nalloc; ++n)
if(pline->filter[n].cd_values == pline->filter[n]._cd_values)
- pline->filter[n].cd_values = (void *) ~((size_t)NULL);
+ pline->filter[n].cd_values = (unsigned *)((void *) ~((size_t)NULL));
x.nalloc = MAX(H5Z_MAX_NFILTERS, 2 * pline->nalloc);
- x.filter = H5MM_realloc(pline->filter, x.nalloc * sizeof(x.filter[0]));
+ x.filter = (H5Z_filter_info_t *)H5MM_realloc(pline->filter, x.nalloc * sizeof(x.filter[0]));
if(NULL == x.filter)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for filter pipeline")
@@ -833,7 +937,7 @@ H5Z_append(H5O_pline_t *pline, H5Z_filter_t filter, unsigned flags,
/* Allocate memory or point at internal buffer */
if(cd_nelmts > H5Z_COMMON_CD_VALUES) {
- pline->filter[idx].cd_values = H5MM_malloc(cd_nelmts * sizeof(unsigned));
+ pline->filter[idx].cd_values = (unsigned *)H5MM_malloc(cd_nelmts * sizeof(unsigned));
if(NULL == pline->filter[idx].cd_values)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for filter")
} /* end if */
@@ -905,11 +1009,11 @@ done:
*
*-------------------------------------------------------------------------
*/
-H5Z_class_t *
+H5Z_class2_t *
H5Z_find(H5Z_filter_t id)
{
int idx; /* Filter index in global table */
- H5Z_class_t *ret_value=NULL; /* Return value */
+ H5Z_class2_t *ret_value=NULL; /* Return value */
FUNC_ENTER_NOAPI(H5Z_find, NULL)
@@ -961,7 +1065,7 @@ H5Z_pipeline(const H5O_pline_t *pline, unsigned flags,
{
size_t i, idx, new_nbytes;
int fclass_idx; /* Index of filter class in global table */
- H5Z_class_t *fclass=NULL; /* Filter class pointer */
+ H5Z_class2_t *fclass=NULL; /* Filter class pointer */
#ifdef H5Z_DEBUG
H5Z_stats_t *fstats=NULL; /* Filter stats pointer */
H5_timer_t timer;
@@ -1100,7 +1204,7 @@ H5Z_filter_info(const H5O_pline_t *pline, H5Z_filter_t filter)
break;
/* Check if the filter was not already in the pipeline */
- if(idx>pline->nused)
+ if(idx>=pline->nused)
HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, NULL, "filter not in pipeline")
/* Set return value */
@@ -1211,11 +1315,11 @@ H5Z_delete(H5O_pline_t *pline, H5Z_filter_t filter)
if(pline->filter[idx].name && pline->filter[idx].name != pline->filter[idx]._name)
HDassert((HDstrlen(pline->filter[idx].name) + 1) > H5Z_COMMON_NAME_LEN);
if(pline->filter[idx].name != pline->filter[idx]._name)
- pline->filter[idx].name = H5MM_xfree(pline->filter[idx].name);
+ pline->filter[idx].name = (char *)H5MM_xfree(pline->filter[idx].name);
if(pline->filter[idx].cd_values && pline->filter[idx].cd_values != pline->filter[idx]._cd_values)
HDassert(pline->filter[idx].cd_nelmts > H5Z_COMMON_CD_VALUES);
if(pline->filter[idx].cd_values != pline->filter[idx]._cd_values)
- pline->filter[idx].cd_values = H5MM_xfree(pline->filter[idx].cd_values);
+ pline->filter[idx].cd_values = (unsigned *)H5MM_xfree(pline->filter[idx].cd_values);
/* Remove filter from pipeline array */
if((idx + 1) < pline->nused) {
@@ -1257,7 +1361,7 @@ done:
herr_t
H5Zget_filter_info(H5Z_filter_t filter, unsigned int *filter_config_flags)
{
- H5Z_class_t *fclass;
+ H5Z_class2_t *fclass;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(H5Zget_filter_info, FAIL)
@@ -1281,33 +1385,3 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Zget_filter_info() */
-
-/*-------------------------------------------------------------------------
- * Function: H5Z_set_latest_version
- *
- * Purpose: Set the encoding for a I/O filter pipeline to the latest version.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Tuesday, July 24, 2007
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5Z_set_latest_version(H5O_pline_t *pline)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5Z_set_latest_version, FAIL)
-
- /* Sanity check */
- HDassert(pline);
-
- /* Set encoding of I/O pipeline to latest version */
- pline->version = H5O_PLINE_VERSION_LATEST;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5Z_set_latest_version() */
-
diff --git a/src/H5Zdeflate.c b/src/H5Zdeflate.c
index 56b910b..c490720 100644
--- a/src/H5Zdeflate.c
+++ b/src/H5Zdeflate.c
@@ -37,7 +37,7 @@ static size_t H5Z_filter_deflate (unsigned flags, size_t cd_nelmts,
const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
/* This message derives from H5Z */
-const H5Z_class_t H5Z_DEFLATE[1] = {{
+const H5Z_class2_t H5Z_DEFLATE[1] = {{
H5Z_CLASS_T_VERS, /* H5Z_class_t version */
H5Z_FILTER_DEFLATE, /* Filter id number */
1, /* encoder_present flag (set to true) */
@@ -78,6 +78,11 @@ H5Z_filter_deflate (unsigned flags, size_t cd_nelmts,
FUNC_ENTER_NOAPI(H5Z_filter_deflate, 0)
+ /* Sanity check */
+ HDassert(*buf_size > 0);
+ HDassert(buf);
+ HDassert(*buf);
+
/* Check arguments */
if (cd_nelmts!=1 || cd_values[0]>9)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid deflate aggression level")
@@ -94,9 +99,9 @@ H5Z_filter_deflate (unsigned flags, size_t cd_nelmts,
/* Set the uncompression parameters */
HDmemset(&z_strm, 0, sizeof(z_strm));
z_strm.next_in = *buf;
- H5_ASSIGN_OVERFLOW(z_strm.avail_in,nbytes,size_t,uInt);
+ H5_ASSIGN_OVERFLOW(z_strm.avail_in,nbytes,size_t,unsigned);
z_strm.next_out = outbuf;
- H5_ASSIGN_OVERFLOW(z_strm.avail_out,nalloc,size_t,uInt);
+ H5_ASSIGN_OVERFLOW(z_strm.avail_out,nalloc,size_t,unsigned);
/* Initialize the uncompression routines */
if (Z_OK!=inflateInit(&z_strm))
diff --git a/src/H5Zfletcher32.c b/src/H5Zfletcher32.c
index aa3a173..e3a77bd 100644
--- a/src/H5Zfletcher32.c
+++ b/src/H5Zfletcher32.c
@@ -34,7 +34,7 @@ static size_t H5Z_filter_fletcher32 (unsigned flags, size_t cd_nelmts,
const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
/* This message derives from H5Z */
-const H5Z_class_t H5Z_FLETCHER32[1] = {{
+const H5Z_class2_t H5Z_FLETCHER32[1] = {{
H5Z_CLASS_T_VERS, /* H5Z_class_t version */
H5Z_FILTER_FLETCHER32, /* Filter id number */
1, /* encoder_present flag (set to true) */
diff --git a/src/H5Znbit.c b/src/H5Znbit.c
index fabc7f0..6f090c3 100644
--- a/src/H5Znbit.c
+++ b/src/H5Znbit.c
@@ -80,7 +80,7 @@ static void H5Z_nbit_compress(unsigned char *data, unsigned d_nelmts, unsigned c
size_t *buffer_size, const unsigned parms[]);
/* This message derives from H5Z */
-H5Z_class_t H5Z_NBIT[1] = {{
+H5Z_class2_t H5Z_NBIT[1] = {{
H5Z_CLASS_T_VERS, /* H5Z_class_t version */
H5Z_FILTER_NBIT, /* Filter id number */
1, /* Assume encoder present: check before registering */
@@ -904,6 +904,9 @@ H5Z_filter_nbit(unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
/* decompress the buffer */
H5Z_nbit_decompress(outbuf, d_nelmts, *buf, cd_values);
+
+ *buf_size = size_out;
+ ret_value = size_out;
}
/* output; compress */
else {
@@ -917,6 +920,9 @@ H5Z_filter_nbit(unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
/* compress the buffer, size_out will be changed */
H5Z_nbit_compress(*buf, d_nelmts, outbuf, &size_out, cd_values);
+
+ *buf_size = nbytes;
+ ret_value = size_out;
}
/* free the input buffer */
@@ -925,8 +931,6 @@ H5Z_filter_nbit(unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
/* set return values */
*buf = outbuf;
outbuf = NULL;
- *buf_size = size_out;
- ret_value = size_out;
done:
if(outbuf)
diff --git a/src/H5Zpkg.h b/src/H5Zpkg.h
index 9cd126e..959ec28 100644
--- a/src/H5Zpkg.h
+++ b/src/H5Zpkg.h
@@ -24,64 +24,50 @@
#include "H5Zprivate.h" /* Filter functions */
-/* The initial version of the format */
-#define H5O_PLINE_VERSION_1 1
-
-/* This version encodes the message fields more efficiently */
-/* (Drops the reserved bytes, doesn't align the name and doesn't encode the
- * filter name at all if it's a filter provided by the library)
- */
-#define H5O_PLINE_VERSION_2 2
-
-/* The latest version of the format. Look through the 'encode' and 'size'
- * callbacks for places to change when updating this. */
-#define H5O_PLINE_VERSION_LATEST H5O_PLINE_VERSION_2
-
-
#ifdef H5_HAVE_FILTER_DEFLATE
/*
* Deflate filter
*/
-H5_DLLVAR const H5Z_class_t H5Z_DEFLATE[1];
+H5_DLLVAR const H5Z_class2_t H5Z_DEFLATE[1];
#endif /* H5_HAVE_FILTER_DEFLATE */
#ifdef H5_HAVE_FILTER_SHUFFLE
/*
* Shuffle filter
*/
-H5_DLLVAR const H5Z_class_t H5Z_SHUFFLE[1];
+H5_DLLVAR const H5Z_class2_t H5Z_SHUFFLE[1];
#endif /* H5_HAVE_FILTER_SHUFFLE */
#ifdef H5_HAVE_FILTER_FLETCHER32
/*
* Fletcher32 filter
*/
-H5_DLLVAR const H5Z_class_t H5Z_FLETCHER32[1];
+H5_DLLVAR const H5Z_class2_t H5Z_FLETCHER32[1];
#endif /* H5_HAVE_FILTER_FLETCHER32 */
#ifdef H5_HAVE_FILTER_SZIP
/*
* szip filter
*/
-H5_DLLVAR H5Z_class_t H5Z_SZIP[1];
+H5_DLLVAR H5Z_class2_t H5Z_SZIP[1];
#endif /* H5_HAVE_FILTER_SZIP */
#ifdef H5_HAVE_FILTER_NBIT
/*
* nbit filter
*/
-H5_DLLVAR H5Z_class_t H5Z_NBIT[1];
+H5_DLLVAR H5Z_class2_t H5Z_NBIT[1];
#endif /* H5_HAVE_FILTER_NBIT */
#ifdef H5_HAVE_FILTER_SCALEOFFSET
/*
* scaleoffset filter
*/
-H5_DLLVAR H5Z_class_t H5Z_SCALEOFFSET[1];
+H5_DLLVAR H5Z_class2_t H5Z_SCALEOFFSET[1];
#endif /* H5_HAVE_FILTER_SCALEOFFSET */
/* Package-local function prototypes */
-H5_DLL void H5Z_update_class_vers(H5Z_class_t * old_vers, H5Z_class_t * curr_vers);
+H5_DLL void H5Z_update_class_vers(H5Z_class2_t * old_vers, H5Z_class2_t * curr_vers);
#endif /* _H5Zpkg_H */
diff --git a/src/H5Zprivate.h b/src/H5Zprivate.h
index cd67e96..c2d6f7e 100644
--- a/src/H5Zprivate.h
+++ b/src/H5Zprivate.h
@@ -72,7 +72,8 @@ typedef struct {
struct H5O_pline_t; /*forward decl*/
/* Internal API routines */
-H5_DLL herr_t H5Z_register(const H5Z_class_t *cls);
+H5_DLL herr_t H5Z_init(void);
+H5_DLL herr_t H5Z_register(const H5Z_class2_t *cls);
H5_DLL herr_t H5Z_unregister(H5Z_filter_t id);
H5_DLL herr_t H5Z_append(struct H5O_pline_t *pline, H5Z_filter_t filter,
unsigned flags, size_t cd_nelmts, const unsigned int cd_values[]);
@@ -83,14 +84,15 @@ H5_DLL herr_t H5Z_pipeline(const struct H5O_pline_t *pline,
H5Z_EDC_t edc_read, H5Z_cb_t cb_struct,
size_t *nbytes/*in,out*/, size_t *buf_size/*in,out*/,
void **buf/*in,out*/);
-H5_DLL H5Z_class_t *H5Z_find(H5Z_filter_t id);
+H5_DLL H5Z_class2_t *H5Z_find(H5Z_filter_t id);
H5_DLL herr_t H5Z_can_apply(hid_t dcpl_id, hid_t type_id);
H5_DLL herr_t H5Z_set_local(hid_t dcpl_id, hid_t type_id);
+H5_DLL herr_t H5Z_can_apply_direct(const struct H5O_pline_t *pline);
+H5_DLL herr_t H5Z_set_local_direct(const struct H5O_pline_t *pline);
H5_DLL H5Z_filter_info_t *H5Z_filter_info(const struct H5O_pline_t *pline,
H5Z_filter_t filter);
H5_DLL htri_t H5Z_all_filters_avail(const struct H5O_pline_t *pline);
H5_DLL herr_t H5Z_delete(struct H5O_pline_t *pline, H5Z_filter_t filter);
-H5_DLL herr_t H5Z_set_latest_version(struct H5O_pline_t *pline);
/* Data Transform Functions */
typedef struct H5Z_data_xform_t H5Z_data_xform_t; /* Defined in H5Ztrans.c */
@@ -98,7 +100,8 @@ typedef struct H5Z_data_xform_t H5Z_data_xform_t; /* Defined in H5Ztrans.c */
H5_DLL H5Z_data_xform_t *H5Z_xform_create(const char *expr);
H5_DLL herr_t H5Z_xform_copy(H5Z_data_xform_t **data_xform_prop);
H5_DLL herr_t H5Z_xform_destroy(H5Z_data_xform_t *data_xform_prop);
-H5_DLL herr_t H5Z_xform_eval(H5Z_data_xform_t *data_xform_prop, void* array, size_t array_size, const H5T_t *buf_type);
+H5_DLL herr_t H5Z_xform_eval(H5Z_data_xform_t *data_xform_prop, void *array,
+ size_t array_size, const H5T_t *buf_type);
H5_DLL hbool_t H5Z_xform_noop(const H5Z_data_xform_t *data_xform_prop);
H5_DLL char* H5Z_xform_extract_xform_str(const H5Z_data_xform_t *data_xform_prop);
diff --git a/src/H5Zpublic.h b/src/H5Zpublic.h
index 7211a2b..44d2bbb 100644
--- a/src/H5Zpublic.h
+++ b/src/H5Zpublic.h
@@ -77,7 +77,7 @@ typedef int H5Z_filter_t;
/* Macros for the shuffle filter */
#define H5Z_SHUFFLE_USER_NPARMS 0 /* Number of parameters that users can set */
#define H5Z_SHUFFLE_TOTAL_NPARMS 1 /* Total number of parameters for filter */
-
+
/* Macros for the szip filter */
#define H5Z_SZIP_USER_NPARMS 2 /* Number of parameters that users can set */
#define H5Z_SZIP_TOTAL_NPARMS 4 /* Total number of parameters for filter */
@@ -85,7 +85,7 @@ typedef int H5Z_filter_t;
#define H5Z_SZIP_PARM_PPB 1 /* "User" parameter for pixels-per-block */
#define H5Z_SZIP_PARM_BPP 2 /* "Local" parameter for bits-per-pixel */
#define H5Z_SZIP_PARM_PPS 3 /* "Local" parameter for pixels-per-scanline */
-
+
/* Macros for the nbit filter */
#define H5Z_NBIT_USER_NPARMS 0 /* Number of parameters that users can set */
@@ -206,7 +206,7 @@ typedef size_t (*H5Z_func_t)(unsigned int flags, size_t cd_nelmts,
* The filter table maps filter identification numbers to structs that
* contain a pointers to the filter function and timing statistics.
*/
-typedef struct H5Z_class_t {
+typedef struct H5Z_class2_t {
int version; /* Version number of the H5Z_class_t struct */
H5Z_filter_t id; /* Filter ID number */
unsigned encoder_present; /* Does this filter have an encoder? */
@@ -215,13 +215,33 @@ typedef struct H5Z_class_t {
H5Z_can_apply_func_t can_apply; /* The "can apply" callback for a filter */
H5Z_set_local_func_t set_local; /* The "set local" callback for a filter */
H5Z_func_t filter; /* The actual filter function */
-} H5Z_class_t;
+} H5Z_class2_t;
-H5_DLL herr_t H5Zregister(const H5Z_class_t *cls);
+H5_DLL herr_t H5Zregister(const void *cls);
H5_DLL herr_t H5Zunregister(H5Z_filter_t id);
H5_DLL htri_t H5Zfilter_avail(H5Z_filter_t id);
H5_DLL herr_t H5Zget_filter_info(H5Z_filter_t filter, unsigned int *filter_config_flags);
+/* Symbols defined for compatibility with previous versions of the HDF5 API.
+ *
+ * Use of these symbols is deprecated.
+ */
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+
+/*
+ * The filter table maps filter identification numbers to structs that
+ * contain a pointers to the filter function and timing statistics.
+ */
+typedef struct H5Z_class1_t {
+ H5Z_filter_t id; /* Filter ID number */
+ const char *name; /* Comment for debugging */
+ H5Z_can_apply_func_t can_apply; /* The "can apply" callback for a filter */
+ H5Z_set_local_func_t set_local; /* The "set local" callback for a filter */
+ H5Z_func_t filter; /* The actual filter function */
+} H5Z_class1_t;
+
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
+
#ifdef __cplusplus
}
#endif
diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c
index 84d404e..8e32ab7 100644
--- a/src/H5Zscaleoffset.c
+++ b/src/H5Zscaleoffset.c
@@ -50,19 +50,19 @@ static herr_t H5Z_set_local_scaleoffset(hid_t dcpl_id, hid_t type_id, hid_t spac
static size_t H5Z_filter_scaleoffset(unsigned flags, size_t cd_nelmts,
const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
static void H5Z_scaleoffset_convert(void *buf, unsigned d_nelmts, size_t dtype_size);
-static unsigned H5Z_scaleoffset_log2(unsigned long_long num);
+static unsigned H5Z_scaleoffset_log2(unsigned long long num);
static void H5Z_scaleoffset_precompress_i(void *data, unsigned d_nelmts,
enum H5Z_scaleoffset_type type, unsigned filavail, const void *filval_buf,
- uint32_t *minbits, unsigned long_long *minval);
+ uint32_t *minbits, unsigned long long *minval);
static void H5Z_scaleoffset_postdecompress_i(void *data, unsigned d_nelmts,
enum H5Z_scaleoffset_type type, unsigned filavail, const void *filval_buf,
- uint32_t minbits, unsigned long_long minval);
+ uint32_t minbits, unsigned long long minval);
static herr_t H5Z_scaleoffset_precompress_fd(void *data, unsigned d_nelmts,
enum H5Z_scaleoffset_type type, unsigned filavail, const void *filval_buf,
- uint32_t *minbits, unsigned long_long *minval, double D_val);
+ uint32_t *minbits, unsigned long long *minval, double D_val);
static herr_t H5Z_scaleoffset_postdecompress_fd(void *data, unsigned d_nelmts,
enum H5Z_scaleoffset_type type, unsigned filavail, const void *filval_buf,
- uint32_t minbits, unsigned long_long minval, double D_val);
+ uint32_t minbits, unsigned long long minval, double D_val);
static void H5Z_scaleoffset_next_byte(size_t *j, int *buf_len);
static void H5Z_scaleoffset_decompress_one_byte(unsigned char *data, size_t data_offset,
int k, int begin_i, unsigned char *buffer, size_t *j, int *buf_len,
@@ -80,7 +80,7 @@ static void H5Z_scaleoffset_compress(unsigned char *data, unsigned d_nelmts, uns
size_t buffer_size, parms_atomic p);
/* This message derives from H5Z */
-H5Z_class_t H5Z_SCALEOFFSET[1] = {{
+H5Z_class2_t H5Z_SCALEOFFSET[1] = {{
H5Z_CLASS_T_VERS, /* H5Z_class_t version */
H5Z_FILTER_SCALEOFFSET, /* Filter id number */
1, /* Assume encoder present: check before registering */
@@ -188,8 +188,8 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
H5Z_scaleoffset_save_filval(unsigned int, cd_values, *(int *)&fill_val) \
else if(sizeof(type) == sizeof(long)) \
H5Z_scaleoffset_save_filval(unsigned long, cd_values, *(long *)&fill_val) \
- else if(sizeof(type) == sizeof(long_long)) \
- H5Z_scaleoffset_save_filval(unsigned long_long, cd_values, *(long_long *)&fill_val)\
+ else if(sizeof(type) == sizeof(long long)) \
+ H5Z_scaleoffset_save_filval(unsigned long long, cd_values, *(long long *)&fill_val)\
else \
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype")\
}
@@ -216,8 +216,8 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
H5Z_scaleoffset_get_filval_1(i, int, filval_buf, *(int *)&filval) \
else if(sizeof(type)==sizeof(long)) \
H5Z_scaleoffset_get_filval_1(i, long, filval_buf, *(long *)&filval) \
- else if(sizeof(type)==sizeof(long_long)) \
- H5Z_scaleoffset_get_filval_1(i, long_long, filval_buf, *(long_long *)&filval) \
+ else if(sizeof(type)==sizeof(long long)) \
+ H5Z_scaleoffset_get_filval_1(i, long long, filval_buf, *(long long *)&filval) \
else \
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype")\
}
@@ -303,10 +303,10 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
> HDpow(2.0, (double)(sizeof(long)*8 - 1))) { \
*minbits = sizeof(long)*8; goto done; \
} \
- } else if(sizeof(type)==sizeof(long_long)) { \
+ } else if(sizeof(type)==sizeof(long long)) { \
if(H5Z_scaleoffset_rnd(max*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)) \
- > HDpow(2.0, (double)(sizeof(long_long)*8 - 1))) { \
- *minbits = sizeof(long_long)*8; goto done; \
+ > HDpow(2.0, (double)(sizeof(long long)*8 - 1))) { \
+ *minbits = sizeof(long long)*8; goto done; \
} \
} else \
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype")\
@@ -323,7 +323,7 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
H5Z_scaleoffset_max_min_1(i, d_nelmts, buf, filval, max, min) \
H5Z_scaleoffset_check_1(type, max, min, minbits) \
span = max - min + 1; \
- *minbits = H5Z_scaleoffset_log2((unsigned long_long)(span+1)); \
+ *minbits = H5Z_scaleoffset_log2((unsigned long long)(span+1)); \
} else /* minbits already set, only calculate min */ \
H5Z_scaleoffset_min_1(i, d_nelmts, buf, filval, min) \
if(*minbits != sizeof(type)*8) /* change values if minbits != full precision */ \
@@ -334,7 +334,7 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
H5Z_scaleoffset_max_min_2(i, d_nelmts, buf, max, min) \
H5Z_scaleoffset_check_1(type, max, min, minbits) \
span = max - min + 1; \
- *minbits = H5Z_scaleoffset_log2((unsigned long_long)span); \
+ *minbits = H5Z_scaleoffset_log2((unsigned long long)span); \
} else /* minbits already set, only calculate min */ \
H5Z_scaleoffset_min_2(i, d_nelmts, buf, min) \
if(*minbits != sizeof(type)*8) /* change values if minbits != full precision */ \
@@ -355,7 +355,7 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
H5Z_scaleoffset_max_min_1(i, d_nelmts, buf, filval, max, min) \
H5Z_scaleoffset_check_2(type, max, min, minbits) \
span = max - min + 1; \
- *minbits = H5Z_scaleoffset_log2((unsigned long_long)(span+1)); \
+ *minbits = H5Z_scaleoffset_log2((unsigned long long)(span+1)); \
} else /* minbits already set, only calculate min */ \
H5Z_scaleoffset_min_1(i, d_nelmts, buf, filval, min) \
if(*minbits != sizeof(type)*8) /* change values if minbits != full precision */ \
@@ -366,7 +366,7 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
H5Z_scaleoffset_max_min_2(i, d_nelmts, buf, max, min) \
H5Z_scaleoffset_check_2(type, max, min, minbits) \
span = max - min + 1; \
- *minbits = H5Z_scaleoffset_log2((unsigned long_long)span); \
+ *minbits = H5Z_scaleoffset_log2((unsigned long long)span); \
} else /* minbits already set, only calculate min */ \
H5Z_scaleoffset_min_2(i, d_nelmts, buf, min) \
if(*minbits != sizeof(type)*8) /* change values if minbits != full precision */ \
@@ -394,12 +394,12 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
*(long *)&buf[i] = H5Z_scaleoffset_rnd( \
buf[i]*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)); \
} \
- else if(sizeof(type)==sizeof(long_long)) \
+ else if(sizeof(type)==sizeof(long long)) \
for(i = 0; i < d_nelmts; i++) { \
if(HDfabs(buf[i] - filval) < HDpow(10.0, -D_val)) \
- *(long_long *)&buf[i] = ((unsigned long_long)1 << *minbits) - 1; \
+ *(long long *)&buf[i] = ((unsigned long long)1 << *minbits) - 1; \
else \
- *(long_long *)&buf[i] = H5Z_scaleoffset_rnd( \
+ *(long long *)&buf[i] = H5Z_scaleoffset_rnd( \
buf[i]*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)); \
} \
else \
@@ -417,9 +417,9 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
for(i = 0; i < d_nelmts; i++) \
*(long *)&buf[i] = H5Z_scaleoffset_rnd( \
buf[i]*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)); \
- else if(sizeof(type)==sizeof(long_long)) \
+ else if(sizeof(type)==sizeof(long long)) \
for(i = 0; i < d_nelmts; i++) \
- *(long_long *)&buf[i] = H5Z_scaleoffset_rnd( \
+ *(long long *)&buf[i] = H5Z_scaleoffset_rnd( \
buf[i]*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)); \
else \
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype")\
@@ -434,9 +434,9 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
else if(sizeof(type)==sizeof(long)) \
for(i = 0; i < sizeof(long); i++) \
((unsigned char *)minval)[i] = (unsigned char)((*(long *)&min & ((long)0xff << i*8)) >> i*8); \
- else if(sizeof(type)==sizeof(long_long)) \
- for(i = 0; i < sizeof(long_long); i++) \
- ((unsigned char *)minval)[i] = (unsigned char)((*(long_long *)&min & ((long_long)0xff << i*8)) >> i*8);\
+ else if(sizeof(type)==sizeof(long long)) \
+ for(i = 0; i < sizeof(long long); i++) \
+ ((unsigned char *)minval)[i] = (unsigned char)((*(long long *)&min & ((long long)0xff << i*8)) >> i*8);\
else \
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype")\
}
@@ -446,21 +446,21 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
minbits, minval, D_val) \
{ \
type *buf = data, min = 0, max = 0, filval = 0; \
- unsigned long_long span; unsigned i; *minval = 0; \
+ unsigned long long span; unsigned i; *minval = 0; \
\
if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ \
H5Z_scaleoffset_get_filval_2(i, type, filval_buf, filval) \
H5Z_scaleoffset_max_min_3(i, d_nelmts, buf, filval, max, min, D_val) \
H5Z_scaleoffset_check_3(i, type, max, min, minbits, D_val) \
span = H5Z_scaleoffset_rnd(max*HDpow(10.0,D_val) - min*HDpow(10.0,D_val)) + 1; \
- *minbits = H5Z_scaleoffset_log2((unsigned long_long)(span+1)); \
+ *minbits = H5Z_scaleoffset_log2((unsigned long long)(span+1)); \
if(*minbits != sizeof(type)*8) /* change values if minbits != full precision */ \
H5Z_scaleoffset_modify_1(i, type, buf, d_nelmts, filval, minbits, min, D_val) \
} else { /* fill value undefined */ \
H5Z_scaleoffset_max_min_2(i, d_nelmts, buf, max, min) \
H5Z_scaleoffset_check_3(i, type, max, min, minbits, D_val) \
span = H5Z_scaleoffset_rnd(max*HDpow(10.0,D_val) - min*HDpow(10.0,D_val)) + 1; \
- *minbits = H5Z_scaleoffset_log2((unsigned long_long)span); \
+ *minbits = H5Z_scaleoffset_log2((unsigned long long)span); \
if(*minbits != sizeof(type)*8) /* change values if minbits != full precision */ \
H5Z_scaleoffset_modify_2(i, type, buf, d_nelmts, min, D_val) \
} \
@@ -506,10 +506,10 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
for(i = 0; i < sizeof(long); i++) { \
mask = ((unsigned char *)&minval)[i]; mask <<= i*8; *(long *)&min |= mask; \
} \
- } else if(sizeof(type)==sizeof(long_long)) { \
- long_long mask; \
- for(i = 0; i < sizeof(long_long); i++) { \
- mask = ((unsigned char *)&minval)[i]; mask <<= i*8; *(long_long *)&min |= mask;\
+ } else if(sizeof(type)==sizeof(long long)) { \
+ long long mask; \
+ for(i = 0; i < sizeof(long long); i++) { \
+ mask = ((unsigned char *)&minval)[i]; mask <<= i*8; *(long long *)&min |= mask;\
} \
} else \
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype")\
@@ -526,10 +526,10 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
for(i = 0; i < d_nelmts; i++) \
buf[i] = (*(long *)&buf[i]==(((unsigned long)1 << minbits) - 1))? \
filval:(*(long *)&buf[i])/HDpow(10.0, D_val) + min; \
- else if(sizeof(type)==sizeof(long_long)) \
+ else if(sizeof(type)==sizeof(long long)) \
for(i = 0; i < d_nelmts; i++) \
- buf[i] = (*(long_long *)&buf[i]==(((unsigned long_long)1 << minbits) - 1))? \
- filval:(*(long_long *)&buf[i])/HDpow(10.0, D_val) + min; \
+ buf[i] = (*(long long *)&buf[i]==(((unsigned long long)1 << minbits) - 1))? \
+ filval:(*(long long *)&buf[i])/HDpow(10.0, D_val) + min; \
else \
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \
}
@@ -543,9 +543,9 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
else if(sizeof(type)==sizeof(long)) \
for(i = 0; i < d_nelmts; i++) \
buf[i] = (*(long *)&buf[i])/HDpow(10.0, D_val) + min; \
- else if(sizeof(type)==sizeof(long_long)) \
+ else if(sizeof(type)==sizeof(long long)) \
for(i = 0; i < d_nelmts; i++) \
- buf[i] = (*(long_long *)&buf[i])/HDpow(10.0, D_val) + min; \
+ buf[i] = (*(long long *)&buf[i])/HDpow(10.0, D_val) + min; \
else \
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \
}
@@ -651,7 +651,7 @@ H5Z_scaleoffset_get_type(unsigned dtype_class, unsigned dtype_size, unsigned dty
else if(dtype_size == sizeof(unsigned short)) type = t_ushort;
else if(dtype_size == sizeof(unsigned int)) type = t_uint;
else if(dtype_size == sizeof(unsigned long)) type = t_ulong;
- else if(dtype_size == sizeof(unsigned long_long)) type = t_ulong_long;
+ else if(dtype_size == sizeof(unsigned long long)) type = t_ulong_long;
else
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, t_bad, "cannot find matched memory dataype")
}
@@ -661,7 +661,7 @@ H5Z_scaleoffset_get_type(unsigned dtype_class, unsigned dtype_size, unsigned dty
else if(dtype_size == sizeof(short)) type = t_short;
else if(dtype_size == sizeof(int)) type = t_int;
else if(dtype_size == sizeof(long)) type = t_long;
- else if(dtype_size == sizeof(long_long)) type = t_long_long;
+ else if(dtype_size == sizeof(long long)) type = t_long_long;
else
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, t_bad, "cannot find matched memory dataype")
}
@@ -713,7 +713,7 @@ H5Z_scaleoffset_set_parms_fillval(H5P_genplist_t *dcpl_plist,
else if(scale_type == t_ulong)
H5Z_scaleoffset_set_filval_1(unsigned long, dcpl_plist, type, cd_values, need_convert, dxpl_id)
else if(scale_type == t_ulong_long)
- H5Z_scaleoffset_set_filval_1(unsigned long_long, dcpl_plist, type, cd_values, need_convert, dxpl_id)
+ H5Z_scaleoffset_set_filval_1(unsigned long long, dcpl_plist, type, cd_values, need_convert, dxpl_id)
else if(scale_type == t_schar)
H5Z_scaleoffset_set_filval_3(signed char, dcpl_plist, type, cd_values, need_convert, dxpl_id)
else if(scale_type == t_short)
@@ -723,7 +723,7 @@ H5Z_scaleoffset_set_parms_fillval(H5P_genplist_t *dcpl_plist,
else if(scale_type == t_long)
H5Z_scaleoffset_set_filval_2(long, dcpl_plist, type, cd_values, need_convert, dxpl_id)
else if(scale_type == t_long_long)
- H5Z_scaleoffset_set_filval_2(long_long, dcpl_plist, type, cd_values, need_convert, dxpl_id)
+ H5Z_scaleoffset_set_filval_2(long long, dcpl_plist, type, cd_values, need_convert, dxpl_id)
else if(scale_type == t_float)
H5Z_scaleoffset_set_filval_4(float, dcpl_plist, type, cd_values, need_convert, dxpl_id)
else if(scale_type == t_double)
@@ -916,11 +916,11 @@ H5Z_filter_scaleoffset (unsigned flags, size_t cd_nelmts, const unsigned cd_valu
unsigned dtype_class; /* datatype class */
unsigned dtype_sign; /* integer datatype sign */
unsigned filavail; /* flag indicating if fill value is defined or not */
- H5Z_SO_scale_type_t scale_type = 0;/* scale type */
+ H5Z_SO_scale_type_t scale_type = H5Z_SO_FLOAT_DSCALE;/* scale type */
int scale_factor = 0; /* scale factor */
double D_val = 0.0; /* decimal scale factor */
uint32_t minbits = 0; /* minimum number of bits to store values */
- unsigned long_long minval= 0; /* minimum value of input buffer */
+ unsigned long long minval= 0; /* minimum value of input buffer */
enum H5Z_scaleoffset_type type; /* memory type corresponding to dataset datatype */
int need_convert = FALSE; /* flag indicating convertion of byte order */
unsigned char *outbuf = NULL; /* pointer to new output buffer */
@@ -955,8 +955,8 @@ H5Z_filter_scaleoffset (unsigned flags, size_t cd_nelmts, const unsigned cd_valu
dtype_class = cd_values[H5Z_SCALEOFFSET_PARM_CLASS];
dtype_sign = cd_values[H5Z_SCALEOFFSET_PARM_SIGN];
filavail = cd_values[H5Z_SCALEOFFSET_PARM_FILAVAIL];
- scale_factor = (int) cd_values[H5Z_SCALEOFFSET_PARM_SCALEFACTOR];
- scale_type = cd_values[H5Z_SCALEOFFSET_PARM_SCALETYPE];
+ scale_factor = (int)cd_values[H5Z_SCALEOFFSET_PARM_SCALEFACTOR];
+ scale_type = (H5Z_SO_scale_type_t)cd_values[H5Z_SCALEOFFSET_PARM_SCALETYPE];
/* check and assign proper values set by user to related parameters
* scale type can be H5Z_SO_FLOAT_DSCALE (0), H5Z_SO_FLOAT_ESCALE (1) or H5Z_SO_INT (other)
@@ -1009,7 +1009,7 @@ H5Z_filter_scaleoffset (unsigned flags, size_t cd_nelmts, const unsigned cd_valu
* retrieve them corresponding to how they are stored during compression
*/
uint32_t minbits_mask = 0;
- unsigned long_long minval_mask = 0;
+ unsigned long long minval_mask = 0;
unsigned minval_size = 0;
minbits = 0;
@@ -1020,11 +1020,11 @@ H5Z_filter_scaleoffset (unsigned flags, size_t cd_nelmts, const unsigned cd_valu
}
/* retrieval of minval takes into consideration situation where sizeof
- * unsigned long_long (datatype of minval) may change from compression
+ * unsigned long long (datatype of minval) may change from compression
* to decompression, only smaller size is used
*/
- minval_size = sizeof(unsigned long_long) <= ((unsigned char *)*buf)[4] ?
- sizeof(unsigned long_long) : ((unsigned char *)*buf)[4];
+ minval_size = sizeof(unsigned long long) <= ((unsigned char *)*buf)[4] ?
+ sizeof(unsigned long long) : ((unsigned char *)*buf)[4];
minval = 0;
for(i = 0; i < minval_size; i++) {
minval_mask = ((unsigned char *)*buf)[5+i];
@@ -1129,18 +1129,18 @@ H5Z_filter_scaleoffset (unsigned flags, size_t cd_nelmts, const unsigned cd_valu
for(i = 0; i < 4; i++)
((unsigned char *)outbuf)[i] = (minbits & ((uint32_t)0xff << i*8)) >> i*8;
- ((unsigned char *)outbuf)[4] = sizeof(unsigned long_long);
+ ((unsigned char *)outbuf)[4] = sizeof(unsigned long long);
- for(i = 0; i < sizeof(unsigned long_long); i++)
- ((unsigned char *)outbuf)[5+i] = (unsigned char)((minval & ((unsigned long_long)0xff << i*8)) >> i*8);
+ for(i = 0; i < sizeof(unsigned long long); i++)
+ ((unsigned char *)outbuf)[5+i] = (unsigned char)((minval & ((unsigned long long)0xff << i*8)) >> i*8);
/* special case: minbits equal to full precision */
if(minbits == p.size * 8) {
HDmemcpy(outbuf+buf_offset, *buf, nbytes);
*buf = outbuf;
outbuf = NULL;
- *buf_size = buf_offset+nbytes;
- ret_value = *buf_size;
+ *buf_size = size_out;
+ ret_value = buf_offset+nbytes;
goto done;
}
@@ -1221,11 +1221,11 @@ static double H5Z_scaleoffset_rnd(double val)
/* return ceiling of floating-point log2 function
* receive unsigned integer as argument 3/10/2005
*/
-static unsigned H5Z_scaleoffset_log2(unsigned long_long num)
+static unsigned H5Z_scaleoffset_log2(unsigned long long num)
{
unsigned v = 0;
- unsigned long_long lower_bound = 1; /* is power of 2, largest value <= num */
- unsigned long_long val = num;
+ unsigned long long lower_bound = 1; /* is power of 2, largest value <= num */
+ unsigned long long val = num;
while(val >>= 1) { v++; lower_bound <<= 1; }
@@ -1236,7 +1236,7 @@ static unsigned H5Z_scaleoffset_log2(unsigned long_long num)
/* precompress for integer type */
static void
H5Z_scaleoffset_precompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleoffset_type type,
- unsigned filavail, const void *filval_buf, uint32_t *minbits, unsigned long_long *minval)
+ unsigned filavail, const void *filval_buf, uint32_t *minbits, unsigned long long *minval)
{
if(type == t_uchar)
H5Z_scaleoffset_precompress_1(unsigned char, data, d_nelmts,
@@ -1251,7 +1251,7 @@ H5Z_scaleoffset_precompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleoffse
H5Z_scaleoffset_precompress_1(unsigned long, data, d_nelmts,
filavail, filval_buf, minbits, minval)
else if(type == t_ulong_long)
- H5Z_scaleoffset_precompress_1(unsigned long_long, data, d_nelmts,
+ H5Z_scaleoffset_precompress_1(unsigned long long, data, d_nelmts,
filavail, filval_buf, minbits, minval)
else if(type == t_schar) {
signed char *buf = data, min = 0, max = 0, filval = 0;
@@ -1264,7 +1264,7 @@ H5Z_scaleoffset_precompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleoffse
if((unsigned char)(max - min) > (unsigned char)(~(unsigned char)0 - 2))
{ *minbits = sizeof(signed char)*8; return; }
span = max - min + 1;
- *minbits = H5Z_scaleoffset_log2((unsigned long_long)(span+1));
+ *minbits = H5Z_scaleoffset_log2((unsigned long long)(span+1));
} else /* minbits already set, only calculate min */
H5Z_scaleoffset_min_1(i, d_nelmts, buf, filval, min)
if(*minbits != sizeof(signed char)*8) /* change values if minbits != full precision */
@@ -1278,7 +1278,7 @@ H5Z_scaleoffset_precompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleoffse
*minval = min; return;
}
span = max - min + 1;
- *minbits = H5Z_scaleoffset_log2((unsigned long_long)span);
+ *minbits = H5Z_scaleoffset_log2((unsigned long long)span);
} else /* minbits already set, only calculate min */
H5Z_scaleoffset_min_2(i, d_nelmts, buf, min)
if(*minbits != sizeof(signed char)*8) /* change values if minbits != full precision */
@@ -1296,16 +1296,16 @@ H5Z_scaleoffset_precompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleoffse
H5Z_scaleoffset_precompress_2(long, data, d_nelmts,
filavail, filval_buf, minbits, minval)
else if(type == t_long_long)
- H5Z_scaleoffset_precompress_2(long_long, data, d_nelmts,
+ H5Z_scaleoffset_precompress_2(long long, data, d_nelmts,
filavail, filval_buf, minbits, minval)
}
/* postdecompress for integer type */
static void
H5Z_scaleoffset_postdecompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleoffset_type type,
- unsigned filavail, const void *filval_buf, uint32_t minbits, unsigned long_long minval)
+ unsigned filavail, const void *filval_buf, uint32_t minbits, unsigned long long minval)
{
- long_long sminval = *(long_long*)&minval; /* for signed integer types */
+ long long sminval = *(long long*)&minval; /* for signed integer types */
if(type == t_uchar)
H5Z_scaleoffset_postdecompress_1(unsigned char, data, d_nelmts, filavail,
@@ -1320,7 +1320,7 @@ H5Z_scaleoffset_postdecompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleof
H5Z_scaleoffset_postdecompress_1(unsigned long, data, d_nelmts, filavail,
filval_buf, minbits, minval)
else if(type == t_ulong_long)
- H5Z_scaleoffset_postdecompress_1(unsigned long_long, data, d_nelmts, filavail,
+ H5Z_scaleoffset_postdecompress_1(unsigned long long, data, d_nelmts, filavail,
filval_buf, minbits, minval)
else if(type == t_schar) {
signed char *buf = data, filval = 0; unsigned i;
@@ -1342,7 +1342,7 @@ H5Z_scaleoffset_postdecompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleof
H5Z_scaleoffset_postdecompress_2(long, data, d_nelmts, filavail,
filval_buf, minbits, sminval)
else if(type == t_long_long)
- H5Z_scaleoffset_postdecompress_2(long_long, data, d_nelmts, filavail,
+ H5Z_scaleoffset_postdecompress_2(long long, data, d_nelmts, filavail,
filval_buf, minbits, sminval)
}
@@ -1350,7 +1350,7 @@ H5Z_scaleoffset_postdecompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleof
success: non-negative, failure: negative 4/15/05 */
static herr_t
H5Z_scaleoffset_precompress_fd(void *data, unsigned d_nelmts, enum H5Z_scaleoffset_type type,
-unsigned filavail, const void *filval_buf, uint32_t *minbits, unsigned long_long *minval, double D_val)
+unsigned filavail, const void *filval_buf, uint32_t *minbits, unsigned long long *minval, double D_val)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -1371,9 +1371,9 @@ done:
success: non-negative, failure: negative 4/15/05 */
static herr_t
H5Z_scaleoffset_postdecompress_fd(void *data, unsigned d_nelmts, enum H5Z_scaleoffset_type type,
-unsigned filavail, const void *filval_buf, uint32_t minbits, unsigned long_long minval, double D_val)
+unsigned filavail, const void *filval_buf, uint32_t minbits, unsigned long long minval, double D_val)
{
- long_long sminval = *(long_long*)&minval; /* for signed integer types */
+ long long sminval = *(long long*)&minval; /* for signed integer types */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5Z_scaleoffset_postdecompress_fd, FAIL)
diff --git a/src/H5Zshuffle.c b/src/H5Zshuffle.c
index 3f40707..2e4f1fa 100644
--- a/src/H5Zshuffle.c
+++ b/src/H5Zshuffle.c
@@ -32,7 +32,7 @@ static size_t H5Z_filter_shuffle(unsigned flags, size_t cd_nelmts,
const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
/* This message derives from H5Z */
-const H5Z_class_t H5Z_SHUFFLE[1] = {{
+const H5Z_class2_t H5Z_SHUFFLE[1] = {{
H5Z_CLASS_T_VERS, /* H5Z_class_t version */
H5Z_FILTER_SHUFFLE, /* Filter id number */
1, /* encoder_present flag (set to true) */
diff --git a/src/H5Zszip.c b/src/H5Zszip.c
index 9201a80..5da92ac 100644
--- a/src/H5Zszip.c
+++ b/src/H5Zszip.c
@@ -40,7 +40,7 @@ static size_t H5Z_filter_szip (unsigned flags, size_t cd_nelmts,
const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
/* This message derives from H5Z */
-H5Z_class_t H5Z_SZIP[1] = {{
+H5Z_class2_t H5Z_SZIP[1] = {{
H5Z_CLASS_T_VERS, /* H5Z_class_t version */
H5Z_FILTER_SZIP, /* Filter id number */
1, /* Assume encoder present: check before registering */
@@ -333,7 +333,7 @@ H5Z_filter_szip (unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
*buf = outbuf;
outbuf = NULL;
*buf_size = nalloc;
- ret_value = nalloc;
+ ret_value = size_out;
}
/* Output; compress */
else {
@@ -359,7 +359,7 @@ H5Z_filter_szip (unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
/* Set return values */
*buf = outbuf;
outbuf = NULL;
- *buf_size = size_out+4;
+ *buf_size = nbytes+4;
ret_value = size_out+4;
}
diff --git a/src/H5Ztrans.c b/src/H5Ztrans.c
index a58988e..6ea5b27 100644
--- a/src/H5Ztrans.c
+++ b/src/H5Ztrans.c
@@ -20,8 +20,8 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
-#include "H5Zpkg.h" /* Data filters */
#include "H5Vprivate.h" /* H5V_array_fill */
+#include "H5Zpkg.h" /* Data filters */
/* Token types */
@@ -193,9 +193,9 @@ static void H5Z_print(H5Z_node *tree, FILE *stream);
else if((TYPE) == H5T_NATIVE_ULONG) \
H5Z_XFORM_DO_OP1((RESL), (RESR), unsigned long, OP, (SIZE)) \
else if((TYPE) == H5T_NATIVE_LLONG) \
- H5Z_XFORM_LL_DO_OP1((RESL), (RESR), long_long, OP, (SIZE)) \
+ H5Z_XFORM_LL_DO_OP1((RESL), (RESR), long long, OP, (SIZE)) \
else if((TYPE) == H5T_NATIVE_ULLONG) \
- H5Z_XFORM_ULL_DO_OP1((RESL), (RESR), unsigned long_long, OP, (SIZE)) \
+ H5Z_XFORM_ULL_DO_OP1((RESL), (RESR), unsigned long long, OP, (SIZE)) \
else if((TYPE) == H5T_NATIVE_FLOAT) \
H5Z_XFORM_DO_OP1((RESL), (RESR), float, OP, (SIZE)) \
else if((TYPE) == H5T_NATIVE_DOUBLE) \
@@ -225,9 +225,9 @@ static void H5Z_print(H5Z_node *tree, FILE *stream);
else if((TYPE) == H5T_NATIVE_ULONG) \
H5Z_XFORM_DO_OP1((RESL), (RESR), unsigned long, OP, (SIZE)) \
else if((TYPE) == H5T_NATIVE_LLONG) \
- H5Z_XFORM_LL_DO_OP1((RESL), (RESR), long_long, OP, (SIZE)) \
+ H5Z_XFORM_LL_DO_OP1((RESL), (RESR), long long, OP, (SIZE)) \
else if((TYPE) == H5T_NATIVE_ULLONG) \
- H5Z_XFORM_ULL_DO_OP1((RESL), (RESR), unsigned long_long, OP, (SIZE)) \
+ H5Z_XFORM_ULL_DO_OP1((RESL), (RESR), unsigned long long, OP, (SIZE)) \
else if((TYPE) == H5T_NATIVE_FLOAT) \
H5Z_XFORM_DO_OP1((RESL), (RESR), float, OP, (SIZE)) \
else if((TYPE) == H5T_NATIVE_DOUBLE) \
@@ -335,29 +335,29 @@ H5Z_unget_token(H5Z_token *current)
/*-------------------------------------------------------------------------
* Function: H5Z_get_token
+ *
* Purpose: Determine what the next valid H5Z_token is in the expression
* string. The current position within the H5Z_token string is
* kept internal to the H5Z_token and handled by this and the
* unget_H5Z_token function.
+ *
* Return: Succeess: The passed in H5Z_token with a valid tok_type
* field.
* Failure: The passed in H5Z_token but with the tok_type
* field set to ERROR.
+ *
* Programmer: Bill Wendling
* 26. August 2003
- * Modifications:
- * Leon Arber: Added FUNC_ENTER / FUNC_LEAVE pairs
+ *
*-------------------------------------------------------------------------
*/
static H5Z_token *
H5Z_get_token(H5Z_token *current)
{
-
- void* ret_value=current;
+ void *ret_value = current;
FUNC_ENTER_NOAPI(H5Z_get_token, NULL)
-
/* check args */
assert(current);
@@ -463,11 +463,11 @@ H5Z_get_token(H5Z_token *current)
if (current->tok_begin[0] == '\0')
current->tok_type = H5Z_XFORM_END;
- HGOTO_DONE(current);
+ /* Set return value */
+ ret_value = (void *)current;
done:
FUNC_LEAVE_NOAPI(ret_value)
-
}
@@ -498,17 +498,17 @@ H5Z_xform_destroy_parse_tree(H5Z_node *tree)
FUNC_LEAVE_NOAPI_VOID
}
-
/*-------------------------------------------------------------------------
* Function: H5Z_parse
+ *
* Purpose: Entry function for parsing the expression string.
+ *
* Return: Success: Valid H5Z_node ptr to an expression tree.
* NULLure: NULL
+ *
* Programmer: Bill Wendling
* 26. August 2003
- * Modifications:
- * Leon Arber: Added FUNC_ENTER / FUNC_LEAVE pairs
*
*-------------------------------------------------------------------------
*/
@@ -518,11 +518,10 @@ H5Z_xform_parse(const char *expression, H5Z_datval_ptrs* dat_val_pointers)
H5Z_token tok;
void* ret_value;
- FUNC_ENTER_NOAPI_NOFUNC(H5Z_xform_parse)
-
- if (!expression)
- HGOTO_DONE(NULL)
+ FUNC_ENTER_NOAPI(H5Z_xform_parse, NULL)
+ if(!expression)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "No expression provided?")
/* Set up the initial H5Z_token for parsing */
tok.tok_expr = tok.tok_begin = tok.tok_end = expression;
@@ -573,7 +572,7 @@ H5Z_parse_expression(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers)
if (!new_node) {
H5Z_xform_destroy_parse_tree(expr);
- HGOTO_DONE(expr)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Unable to allocate new node")
}
new_node->lchild = expr;
@@ -592,7 +591,7 @@ H5Z_parse_expression(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers)
if (!new_node) {
H5Z_xform_destroy_parse_tree(expr);
- HGOTO_DONE(expr)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Unable to allocate new node")
}
new_node->lchild = expr;
@@ -643,7 +642,7 @@ static H5Z_node *
H5Z_parse_term(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers)
{
H5Z_node *term = NULL;
- void* ret_value;
+ H5Z_node *ret_value;
FUNC_ENTER_NOAPI(H5Z_parse_term, NULL);
term = H5Z_parse_factor(current, dat_val_pointers);
@@ -659,7 +658,7 @@ H5Z_parse_term(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers)
if (!new_node) {
H5Z_xform_destroy_parse_tree(term);
- HGOTO_DONE(term)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Unable to allocate new node")
}
new_node->lchild = term;
@@ -678,7 +677,7 @@ H5Z_parse_term(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers)
if (!new_node) {
H5Z_xform_destroy_parse_tree(term);
- HGOTO_DONE(term)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Unable to allocate new node")
}
new_node->lchild = term;
@@ -733,7 +732,7 @@ H5Z_parse_factor(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers)
{
H5Z_node *factor=NULL;
H5Z_node *new_node;
- void* ret_value;
+ H5Z_node *ret_value;
FUNC_ENTER_NOAPI(H5Z_parse_factor, NULL);
@@ -744,7 +743,7 @@ H5Z_parse_factor(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers)
factor = H5Z_new_node(H5Z_XFORM_INTEGER);
if (!factor)
- HGOTO_DONE(factor)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Unable to allocate new node")
sscanf(current->tok_begin, "%ld", &factor->value.int_val);
break;
@@ -752,7 +751,7 @@ H5Z_parse_factor(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers)
factor = H5Z_new_node(H5Z_XFORM_FLOAT);
if (!factor)
- HGOTO_DONE(factor)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Unable to allocate new node")
sscanf(current->tok_begin, "%lf", &factor->value.float_val);
break;
@@ -760,7 +759,7 @@ H5Z_parse_factor(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers)
factor = H5Z_new_node(H5Z_XFORM_SYMBOL);
if (!factor)
- HGOTO_DONE(factor)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Unable to allocate new node")
factor->value.dat_val = &(dat_val_pointers->ptr_dat_val[dat_val_pointers->num_ptrs]);
dat_val_pointers->num_ptrs++;
@@ -770,7 +769,7 @@ H5Z_parse_factor(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers)
factor = H5Z_parse_expression(current, dat_val_pointers);
if (!factor)
- HGOTO_DONE(factor)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Unable to allocate new node")
current = H5Z_get_token(current);
@@ -872,20 +871,20 @@ done:
static H5Z_node *
H5Z_new_node(H5Z_token_type type)
{
- H5Z_node* ret_value = NULL;
+ H5Z_node *ret_value;
- FUNC_ENTER_NOAPI(H5Z_new_node, NULL);
+ FUNC_ENTER_NOAPI(H5Z_new_node, NULL)
- ret_value = H5MM_calloc(sizeof(H5Z_node));
- if(ret_value == NULL)
+ if(NULL == (ret_value = (H5Z_node *)H5MM_calloc(sizeof(H5Z_node))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Ran out of memory trying to allocate space for nodes in the parse tree")
ret_value->type = type;
+
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
}
-
+
/*-------------------------------------------------------------------------
* Function: H5Z_xform_eval
* Purpose: If the transform is trivial, this function applies it.
@@ -898,32 +897,31 @@ done:
*
*-------------------------------------------------------------------------
*/
-
herr_t
H5Z_xform_eval(H5Z_data_xform_t *data_xform_prop, void* array, size_t array_size, const H5T_t *buf_type)
{
H5Z_node *tree;
hid_t array_type;
- size_t i;
H5Z_result res;
- herr_t ret_value = SUCCEED;
+ size_t i;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5Z_xform_eval, FAIL)
HDassert(data_xform_prop);
- tree=data_xform_prop->parse_root;
+ tree = data_xform_prop->parse_root;
/* Get the datatype ID for the buffer's type */
- if( (array_type = H5Z_xform_find_type(buf_type)) < 0)
+ if((array_type = H5Z_xform_find_type(buf_type)) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Cannot perform data transform on this type.")
- /*After this point, we're assured that the type of the array is handled by the eval code, so we no
- * longer have to check for valid types */
+ /* After this point, we're assured that the type of the array is handled by the eval code,
+ * so we no longer have to check for valid types
+ */
/* If it's a trivial data transform, perform it */
- if( tree->type == H5Z_XFORM_INTEGER || tree->type == H5Z_XFORM_FLOAT)
- {
+ if(tree->type == H5Z_XFORM_INTEGER || tree->type == H5Z_XFORM_FLOAT) {
if(array_type == H5T_NATIVE_CHAR)
H5Z_XFORM_DO_OP5(char, array_size)
else if(array_type == H5T_NATIVE_UCHAR)
@@ -943,9 +941,9 @@ H5Z_xform_eval(H5Z_data_xform_t *data_xform_prop, void* array, size_t array_size
else if(array_type == H5T_NATIVE_ULONG)
H5Z_XFORM_DO_OP5(unsigned long, array_size)
else if(array_type == H5T_NATIVE_LLONG)
- H5Z_XFORM_DO_OP5(long_long, array_size)
+ H5Z_XFORM_DO_OP5(long long, array_size)
else if(array_type == H5T_NATIVE_ULLONG)
- H5Z_XFORM_DO_OP5(unsigned long_long, array_size)
+ H5Z_XFORM_DO_OP5(unsigned long long, array_size)
else if(array_type == H5T_NATIVE_FLOAT)
H5Z_XFORM_DO_OP5(float, array_size)
else if(array_type == H5T_NATIVE_DOUBLE)
@@ -955,51 +953,47 @@ H5Z_xform_eval(H5Z_data_xform_t *data_xform_prop, void* array, size_t array_size
H5Z_XFORM_DO_OP5(long double, array_size)
#endif
- }
+ } /* end if */
/* Otherwise, do the full data transform */
- else
- {
+ else {
/* Optimization for linear transform: */
if(data_xform_prop->dat_val_pointers->num_ptrs == 1)
data_xform_prop->dat_val_pointers->ptr_dat_val[0] = array;
+
/* If it's a quadratic transform, we have no choice but to store multiple copies of the data */
- else
- {
- for(i=0; i<data_xform_prop->dat_val_pointers->num_ptrs; i++)
- {
- if( (data_xform_prop->dat_val_pointers->ptr_dat_val[i] = (void*)H5MM_malloc(array_size*H5Tget_size(array_type))) == NULL)
+ else {
+ for(i = 0; i < data_xform_prop->dat_val_pointers->num_ptrs; i++) {
+ if(NULL == (data_xform_prop->dat_val_pointers->ptr_dat_val[i] = (void*)H5MM_malloc(array_size * H5Tget_size(array_type))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "Ran out of memory trying to allocate space for data in data transform")
- HDmemcpy(data_xform_prop->dat_val_pointers->ptr_dat_val[i], array, array_size*H5Tget_size(array_type));
- }
- }
+ HDmemcpy(data_xform_prop->dat_val_pointers->ptr_dat_val[i], array, array_size * H5Tget_size(array_type));
+ } /* end for */
+ } /* end else */
if(H5Z_xform_eval_full(tree, array_size, array_type, &res) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "error while performing data transform")
- if(data_xform_prop->dat_val_pointers->num_ptrs > 1)
+ if(data_xform_prop->dat_val_pointers->num_ptrs > 1)
HDmemcpy(array, res.value.dat_val, array_size * H5Tget_size(array_type));
/* Free the temporary arrays we used */
if(data_xform_prop->dat_val_pointers->num_ptrs > 1)
for(i=0; i<data_xform_prop->dat_val_pointers->num_ptrs; i++)
HDfree(data_xform_prop->dat_val_pointers->ptr_dat_val[i]);
- }
+ } /* end else */
done:
- if(ret_value < 0)
- {
+ if(ret_value < 0) {
/* If we ran out of memory above copying the array for temp storage (which we easily can for
* polynomial transforms of high order) we free those arrays which we already allocated */
if(data_xform_prop->dat_val_pointers->num_ptrs > 1)
- for(i=0; i<data_xform_prop->dat_val_pointers->num_ptrs; i++)
- if(data_xform_prop->dat_val_pointers->ptr_dat_val[i] != NULL)
+ for(i = 0; i < data_xform_prop->dat_val_pointers->num_ptrs; i++)
+ if(data_xform_prop->dat_val_pointers->ptr_dat_val[i])
HDfree(data_xform_prop->dat_val_pointers->ptr_dat_val[i]);
- }
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
+ } /* end if */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_xform_eval() */
/*-------------------------------------------------------------------------
@@ -1017,38 +1011,34 @@ done:
* will accumulate changes and, at the end, the new data will be copied from the lhs.
*-------------------------------------------------------------------------
*/
-static herr_t
-H5Z_xform_eval_full(H5Z_node *tree, const size_t array_size, const hid_t array_type, H5Z_result* res)
+static herr_t
+H5Z_xform_eval_full(H5Z_node *tree, const size_t array_size, const hid_t array_type, H5Z_result *res)
{
H5Z_result resl, resr;
- herr_t ret_value = SUCCEED;
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5Z_xform_eval_full, FAIL);
+ FUNC_ENTER_NOAPI(H5Z_xform_eval_full, FAIL)
/* check args */
- assert(tree);
+ HDassert(tree);
- if (tree->type == H5Z_XFORM_INTEGER)
- {
+ if (tree->type == H5Z_XFORM_INTEGER) {
res->type = H5Z_XFORM_INTEGER;
res->value.int_val = tree->value.int_val;
- }
- else if (tree->type == H5Z_XFORM_FLOAT)
- {
+ } /* end if */
+ else if (tree->type == H5Z_XFORM_FLOAT) {
res->type = H5Z_XFORM_FLOAT;
res->value.float_val = tree->value.float_val;
- }
- else if (tree->type == H5Z_XFORM_SYMBOL)
- {
+ } /* end if */
+ else if (tree->type == H5Z_XFORM_SYMBOL) {
res->type = H5Z_XFORM_SYMBOL;
/*since dat_val stores the address of the array which is really stored in the dat_val_pointers,
* here we make dat_val store a pointer to the array itself instead of the address of it so that the
* rest of the code below works normally. */
res->value.dat_val = *((void**)(tree->value.dat_val));
- }
- else
- {
+ } /* end if */
+ else {
if(H5Z_xform_eval_full(tree->lchild, array_size, array_type, &resl) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "error while performing data transform")
if(H5Z_xform_eval_full(tree->rchild, array_size, array_type, &resr) < 0)
@@ -1081,7 +1071,8 @@ H5Z_xform_eval_full(H5Z_node *tree, const size_t array_size, const hid_t array_
default:
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Invalid expression tree")
- }
+ } /* end switch */
+
/* The result stores a pointer to the new data */
/* So, if the left hand side got its data modified, the result stores a pointers
* to the left hand side's data, ditto for rhs */
@@ -1091,14 +1082,11 @@ H5Z_xform_eval_full(H5Z_node *tree, const size_t array_size, const hid_t array_
res->value.dat_val = resr.value.dat_val;
else
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "error during transform evaluation")
-
- }
-
+ } /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
-
+} /* end H5Z_xform_eval_full() */
/*-------------------------------------------------------------------------
@@ -1113,77 +1101,62 @@ done:
static hid_t
H5Z_xform_find_type(const H5T_t* type)
{
- hid_t ret_value = SUCCEED;
+ hid_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI_NOINIT(H5Z_xform_find_type);
+ FUNC_ENTER_NOAPI_NOINIT(H5Z_xform_find_type)
- assert(type);
+ HDassert(type);
/* Check for SHORT type */
- if((H5T_cmp(type, H5I_object_verify(H5T_NATIVE_SHORT,H5I_DATATYPE), FALSE ))==0)
+ if((H5T_cmp(type, (const H5T_t *)H5I_object_verify(H5T_NATIVE_SHORT, H5I_DATATYPE), FALSE)) == 0)
HGOTO_DONE(H5T_NATIVE_SHORT)
-
- /* Check for INT type */
- else if((H5T_cmp(type, H5I_object_verify(H5T_NATIVE_INT,H5I_DATATYPE), FALSE))==0)
+ /* Check for INT type */
+ else if((H5T_cmp(type, (const H5T_t *)H5I_object_verify(H5T_NATIVE_INT, H5I_DATATYPE), FALSE)) == 0)
HGOTO_DONE(H5T_NATIVE_INT)
-
- /* Check for LONG type */
- else if((H5T_cmp(type, H5I_object_verify(H5T_NATIVE_LONG,H5I_DATATYPE), FALSE))==0)
+ /* Check for LONG type */
+ else if((H5T_cmp(type, (const H5T_t *)H5I_object_verify(H5T_NATIVE_LONG, H5I_DATATYPE), FALSE)) == 0)
HGOTO_DONE(H5T_NATIVE_LONG)
-
- /* Check for LONGLONG type */
- else if((H5T_cmp(type, H5I_object_verify(H5T_NATIVE_LLONG,H5I_DATATYPE), FALSE))==0)
+ /* Check for LONGLONG type */
+ else if((H5T_cmp(type, (const H5T_t *)H5I_object_verify(H5T_NATIVE_LLONG, H5I_DATATYPE), FALSE)) == 0)
HGOTO_DONE(H5T_NATIVE_LLONG)
-
- /* Check for UCHAR type */
- else if((H5T_cmp(type, H5I_object_verify(H5T_NATIVE_UCHAR,H5I_DATATYPE), FALSE))==0)
+ /* Check for UCHAR type */
+ else if((H5T_cmp(type, (const H5T_t *)H5I_object_verify(H5T_NATIVE_UCHAR, H5I_DATATYPE), FALSE)) == 0)
HGOTO_DONE(H5T_NATIVE_UCHAR)
-
- /* Check for CHAR type */
- else if((H5T_cmp(type, H5I_object_verify(H5T_NATIVE_CHAR,H5I_DATATYPE), FALSE))==0)
+ /* Check for CHAR type */
+ else if((H5T_cmp(type, (const H5T_t *)H5I_object_verify(H5T_NATIVE_CHAR, H5I_DATATYPE), FALSE)) == 0)
HGOTO_DONE(H5T_NATIVE_CHAR)
-
- /* Check for SCHAR type */
- else if((H5T_cmp(type, H5I_object_verify(H5T_NATIVE_SCHAR,H5I_DATATYPE), FALSE))==0)
+ /* Check for SCHAR type */
+ else if((H5T_cmp(type, (const H5T_t *)H5I_object_verify(H5T_NATIVE_SCHAR, H5I_DATATYPE), FALSE)) == 0)
HGOTO_DONE(H5T_NATIVE_SCHAR)
-
- /* Check for USHORT type */
- else if((H5T_cmp(type, H5I_object_verify(H5T_NATIVE_USHORT,H5I_DATATYPE), FALSE))==0)
+ /* Check for USHORT type */
+ else if((H5T_cmp(type, (const H5T_t *)H5I_object_verify(H5T_NATIVE_USHORT, H5I_DATATYPE), FALSE)) == 0)
HGOTO_DONE(H5T_NATIVE_USHORT)
-
- /* Check for UINT type */
- else if((H5T_cmp(type, H5I_object_verify(H5T_NATIVE_UINT,H5I_DATATYPE), FALSE))==0)
+ /* Check for UINT type */
+ else if((H5T_cmp(type, (const H5T_t *)H5I_object_verify(H5T_NATIVE_UINT, H5I_DATATYPE), FALSE)) == 0)
HGOTO_DONE(H5T_NATIVE_UINT)
-
- /* Check for ULONG type */
- else if((H5T_cmp(type, H5I_object_verify(H5T_NATIVE_ULONG,H5I_DATATYPE), FALSE))==0)
+ /* Check for ULONG type */
+ else if((H5T_cmp(type, (const H5T_t *)H5I_object_verify(H5T_NATIVE_ULONG, H5I_DATATYPE), FALSE)) == 0)
HGOTO_DONE(H5T_NATIVE_ULONG)
-
- /* Check for ULONGLONG type */
- else if((H5T_cmp(type, H5I_object_verify(H5T_NATIVE_ULLONG,H5I_DATATYPE), FALSE))==0)
+ /* Check for ULONGLONG type */
+ else if((H5T_cmp(type, (const H5T_t *)H5I_object_verify(H5T_NATIVE_ULLONG, H5I_DATATYPE), FALSE)) == 0)
HGOTO_DONE(H5T_NATIVE_ULLONG)
-
- /* Check for FLOAT type */
- else if((H5T_cmp(type, H5I_object_verify(H5T_NATIVE_FLOAT,H5I_DATATYPE), FALSE))==0)
+ /* Check for FLOAT type */
+ else if((H5T_cmp(type, (const H5T_t *)H5I_object_verify(H5T_NATIVE_FLOAT, H5I_DATATYPE), FALSE)) == 0)
HGOTO_DONE(H5T_NATIVE_FLOAT)
-
- /* Check for DOUBLE type */
- else if((H5T_cmp(type, H5I_object_verify(H5T_NATIVE_DOUBLE,H5I_DATATYPE), FALSE))==0)
+ /* Check for DOUBLE type */
+ else if((H5T_cmp(type, (const H5T_t *)H5I_object_verify(H5T_NATIVE_DOUBLE, H5I_DATATYPE), FALSE)) == 0)
HGOTO_DONE(H5T_NATIVE_DOUBLE)
-
#if H5_SIZEOF_LONG_DOUBLE !=0
- /* Check for LONGDOUBLE type */
- else if((H5T_cmp(type, H5I_object_verify(H5T_NATIVE_LDOUBLE,H5I_DATATYPE), FALSE))==0)
+ /* Check for LONGDOUBLE type */
+ else if((H5T_cmp(type, (const H5T_t *)H5I_object_verify(H5T_NATIVE_LDOUBLE, H5I_DATATYPE), FALSE)) == 0)
HGOTO_DONE(H5T_NATIVE_LDOUBLE)
#endif
else
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not find matching type");
-
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not find matching type")
done:
FUNC_LEAVE_NOAPI(ret_value)
-
-}
+} /* end H5Z_xform_find_type() */
/*-------------------------------------------------------------------------
@@ -1369,22 +1342,20 @@ H5Z_xform_create(const char *expr)
assert(expr);
/* Allocate space for the data transform information */
- if((data_xform_prop = H5MM_calloc(sizeof(H5Z_data_xform_t)))==NULL)
+ if(NULL == (data_xform_prop = (H5Z_data_xform_t *)H5MM_calloc(sizeof(H5Z_data_xform_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for data transform info")
- if((data_xform_prop->dat_val_pointers = H5MM_malloc(sizeof(H5Z_datval_ptrs))) == NULL)
+ if(NULL == (data_xform_prop->dat_val_pointers = (H5Z_datval_ptrs *)H5MM_malloc(sizeof(H5Z_datval_ptrs))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for data transform array storage")
/* copy the user's string into the property */
- if((data_xform_prop->xform_exp = H5MM_xstrdup(expr))==NULL)
+ if(NULL == (data_xform_prop->xform_exp = (char *)H5MM_xstrdup(expr)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for data transform expression")
/* Find the number of times "x" is used in this equation, and allocate room for storing that many points */
- for(i=0; i<strlen(expr); i++)
- {
- if(isalpha(expr[i]))
+ for(i = 0; i < HDstrlen(expr); i++)
+ if(HDisalpha(expr[i]))
count++;
- }
/* When there are no "x"'s in the equation (ie, simple transform case),
* we don't need to allocate any space since no array will have to be
@@ -1509,22 +1480,20 @@ H5Z_xform_copy(H5Z_data_xform_t **data_xform_prop)
if(*data_xform_prop) {
/* Allocate new node */
- if((new_data_xform_prop = H5MM_calloc(sizeof(H5Z_data_xform_t)))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for data transform info")
+ if(NULL == (new_data_xform_prop = (H5Z_data_xform_t *)H5MM_calloc(sizeof(H5Z_data_xform_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for data transform info")
/* Copy string */
- if((new_data_xform_prop->xform_exp = H5MM_xstrdup((*data_xform_prop)->xform_exp))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for data transform expression")
+ if(NULL == (new_data_xform_prop->xform_exp = (char *)H5MM_xstrdup((*data_xform_prop)->xform_exp)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for data transform expression")
- if((new_data_xform_prop->dat_val_pointers = H5MM_malloc(sizeof(H5Z_datval_ptrs))) == NULL)
+ if(NULL == (new_data_xform_prop->dat_val_pointers = (H5Z_datval_ptrs *)H5MM_malloc(sizeof(H5Z_datval_ptrs))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for data transform array storage")
/* Find the number of times "x" is used in this equation, and allocate room for storing that many points */
- for(i=0; i<strlen(new_data_xform_prop->xform_exp); i++)
- {
- if(isalpha(new_data_xform_prop->xform_exp[i]))
+ for(i = 0; i < HDstrlen(new_data_xform_prop->xform_exp); i++)
+ if(HDisalpha(new_data_xform_prop->xform_exp[i]))
count++;
- }
if(count > 0)
if((new_data_xform_prop->dat_val_pointers->ptr_dat_val = (void**) H5MM_calloc(count * sizeof(void**))) == NULL)
@@ -1533,7 +1502,6 @@ H5Z_xform_copy(H5Z_data_xform_t **data_xform_prop)
/* Zero out num_pointers prior to H5Z_xform_cop_tree call; that call will increment it to the right amount */
new_data_xform_prop->dat_val_pointers->num_ptrs = 0;
-
/* Copy parse tree */
if((new_data_xform_prop->parse_root = (H5Z_node*)H5Z_xform_copy_tree((*data_xform_prop)->parse_root, (*data_xform_prop)->dat_val_pointers, new_data_xform_prop->dat_val_pointers)) == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "error copying the parse tree")
diff --git a/src/H5checksum.c b/src/H5checksum.c
index 3359722..6c01508 100644
--- a/src/H5checksum.c
+++ b/src/H5checksum.c
@@ -270,7 +270,7 @@ This was tested for:
the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
is commonly produced by subtraction) look like a single 1-bit
difference.
-* the base values were pseudorandom, all zero but one bit set, or
+* the base values were pseudorandom, all zero but one bit set, or
all zero plus a counter that starts at zero.
Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
@@ -280,7 +280,7 @@ satisfy this are
14 9 3 7 17 3
Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
for "differ" defined as + with a one-bit base and a two-bit delta. I
-used http://burtleburtle.net/bob/hash/avalanche.html to choose
+used http://burtleburtle.net/bob/hash/avalanche.html to choose
the operations, constants, and arrangements of the variables.
This does not achieve avalanche. There are input bits of (a,b,c)
@@ -320,7 +320,7 @@ produce values of c that look totally different. This was tested for
the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
is commonly produced by subtraction) look like a single 1-bit
difference.
-* the base values were pseudorandom, all zero but one bit set, or
+* the base values were pseudorandom, all zero but one bit set, or
all zero plus a counter that starts at zero.
These constants passed:
diff --git a/src/H5config.h.in b/src/H5config.h.in
index 429b613..bdc8ed4 100644
--- a/src/H5config.h.in
+++ b/src/H5config.h.in
@@ -1,5 +1,8 @@
/* src/H5config.h.in. Generated from configure.in by autoheader. */
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
/* Define if your system generates wrong code for log2 routine. */
#undef BAD_LOG2_CODE_GENERATED
@@ -58,6 +61,13 @@
/* Define to 1 if you have the `BSDgettimeofday' function. */
#undef HAVE_BSDGETTIMEOFDAY
+/* Define if the compiler understands C99 designated initialization of structs
+ and unions */
+#undef HAVE_C99_DESIGNATED_INITIALIZER
+
+/* Define if the compiler understands the __func__ keyword */
+#undef HAVE_C99_FUNC
+
/* Define if the function stack tracing code is to be compiled in */
#undef HAVE_CODESTACK
@@ -77,6 +87,9 @@
/* Define to 1 if you have the <dmalloc.h> header file. */
#undef HAVE_DMALLOC_H
+/* Define if library information should be embedded in the executables */
+#undef HAVE_EMBEDDED_LIBINFO
+
/* Define to 1 if you have the <features.h> header file. */
#undef HAVE_FEATURES_H
@@ -119,7 +132,10 @@
/* Define to 1 if you have the `ftello' function. */
#undef HAVE_FTELLO
-/* Define if the compiler understand the __FUNCTION__ keyword */
+/* Define to 1 if you have the `ftruncate64' function. */
+#undef HAVE_FTRUNCATE64
+
+/* Define if the compiler understands the __FUNCTION__ keyword */
#undef HAVE_FUNCTION
/* Define to 1 if you have the `GetConsoleScreenBufferInfo' function. */
@@ -204,6 +220,9 @@
/* Define to 1 if you have the `lseek64' function. */
#undef HAVE_LSEEK64
+/* Define to 1 if you have the `lstat' function. */
+#undef HAVE_LSTAT
+
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
@@ -240,9 +259,6 @@
/* Define to 1 if you have the `setsysinfo' function. */
#undef HAVE_SETSYSINFO
-/* Define to 1 if you have the `sigaction' function. */
-#undef HAVE_SIGACTION
-
/* Define to 1 if you have the `siglongjmp' function. */
#undef HAVE_SIGLONGJMP
@@ -285,12 +301,15 @@
/* Define if `struct timezone' is defined */
#undef HAVE_STRUCT_TIMEZONE
-/* Define to 1 if `tm_zone' is member of `struct tm'. */
+/* Define to 1 if `struct tm' is a member of `tm_zone'. */
#undef HAVE_STRUCT_TM_TM_ZONE
/* Define if `struct videoconfig' is defined */
#undef HAVE_STRUCT_VIDEOCONFIG
+/* Define to 1 if you have the `symlink' function. */
+#undef HAVE_SYMLINK
+
/* Define to 1 if you have the `system' function. */
#undef HAVE_SYSTEM
@@ -433,6 +452,9 @@
/* Define if your system can handle special collective IO properly. */
#undef MPI_SPECIAL_COLLECTIVE_IO_WORKS
+/* Define if we can violate pointer alignment restrictions */
+#undef NO_ALIGNMENT_RESTRICTIONS
+
/* Define if deprecated public API symbols are disabled */
#undef NO_DEPRECATED_SYMBOLS
@@ -454,6 +476,9 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
/* Define to the version of this package. */
#undef PACKAGE_VERSION
@@ -568,6 +593,9 @@
/* The size of `uint_least8_t', as computed by sizeof. */
#undef SIZEOF_UINT_LEAST8_T
+/* The size of `unsigned', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED
+
/* The size of `__int64', as computed by sizeof. */
#undef SIZEOF___INT64
@@ -595,12 +623,16 @@
correct precision. */
#undef ULLONG_TO_LDOUBLE_PRECISION
+/* Define if your system accurately converting unsigned long to float values.
+ */
+#undef ULONG_TO_FLOAT_ACCURATE
+
/* Define if your system can accurately convert unsigned (long) long values to
floating-point values. */
#undef ULONG_TO_FP_BOTTOM_BIT_ACCURATE
/* Define using v1.6 public API symbols by default */
-#undef USE_16_API
+#undef USE_16_API_DEFAULT
/* Define if a memory checking tool will be used on the library, to cause
library to be very picky about memory operations and also disable the
@@ -620,9 +652,17 @@
/* Check exception handling functions during data conversions */
#undef WANT_DCONV_EXCEPTION
-/* Define to 1 if your processor stores words with the most significant byte
- first (like Motorola and SPARC, unlike Intel and VAX). */
-#undef WORDS_BIGENDIAN
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
diff --git a/src/H5detect.c b/src/H5detect.c
index 11a4d47..ebd042d 100644
--- a/src/H5detect.c
+++ b/src/H5detect.c
@@ -108,6 +108,8 @@ static void detect_C99_integers16(void);
static void detect_C99_integers32(void);
static void detect_C99_integers64(void);
static void detect_alignments(void);
+static void insert_libhdf5_settings(FILE *flibinfo);
+static void make_libinfo(void);
static size_t align_g[] = {1, 2, 4, 8, 16};
static jmp_buf jbuf_g;
@@ -202,34 +204,36 @@ precision (detected_t *d)
int _i, _j; \
unsigned char *_x; \
\
- memset (&INFO, 0, sizeof(INFO)); \
+ HDmemset(&INFO, 0, sizeof(INFO)); \
INFO.varname = #VAR; \
INFO.size = sizeof(TYPE); \
\
- if(sizeof(TYPE)!=1) { \
- for (_i=sizeof(TYPE),_v=0; _i>0; --_i) _v = (_v<<8) + _i; \
- for (_i=0,_x=(unsigned char *)&_v; _i<(signed)sizeof(TYPE); _i++) { \
- _j = (*_x++)-1; \
- assert (_j<(signed)sizeof(TYPE)); \
+ if(sizeof(TYPE) != 1) { \
+ for(_i = sizeof(TYPE), _v = 0; _i > 0; --_i) \
+ _v = (_v << 8) + _i; \
+ for(_i = 0, _x = (unsigned char *)&_v; _i < (signed)sizeof(TYPE); _i++) { \
+ _j = (*_x++) - 1; \
+ assert(_j < (signed)sizeof(TYPE)); \
INFO.perm[_i] = _j; \
- } \
+ } /* end for */ \
} else { /*Not able to detect order if type size is 1 byte. Use native int \
*instead. No effect on data, just make it look correct. */ \
- for (_i=sizeof(int),_int_v=0; _i>0; --_i) _int_v = (_int_v<<8) + _i; \
- for (_i=0,_x=(unsigned char *)&_int_v; _i<(signed)sizeof(int); _i++) { \
+ for(_i = sizeof(int), _int_v = 0; _i > 0; --_i) \
+ _int_v = (_int_v << 8) + _i; \
+ for(_i = 0, _x = (unsigned char *)&_int_v; _i < (signed)sizeof(int); _i++) { \
_j = (*_x++)-1; \
- assert (_j<(signed)sizeof(int)); \
+ assert(_j < (signed)sizeof(int)); \
INFO.perm[_i] = _j; \
- } \
- } \
+ } /* end for */ \
+ } /* end else */ \
\
- INFO.sign = ('U'!=*(#VAR)); \
+ INFO.sign = ('U' != *(#VAR)); \
precision (&(INFO)); \
ALIGNMENT(TYPE, INFO); \
- if(!strcmp(INFO.varname, "SCHAR") || !strcmp(INFO.varname, "SHORT") || \
- !strcmp(INFO.varname, "INT") || !strcmp(INFO.varname, "LONG") || \
- !strcmp(INFO.varname, "LLONG")) { \
- COMP_ALIGNMENT(TYPE,INFO.comp_align); \
+ if(!HDstrcmp(INFO.varname, "SCHAR") || !HDstrcmp(INFO.varname, "SHORT") || \
+ !HDstrcmp(INFO.varname, "INT") || !HDstrcmp(INFO.varname, "LONG") || \
+ !HDstrcmp(INFO.varname, "LLONG")) { \
+ COMP_ALIGNMENT(TYPE, INFO.comp_align); \
} \
}
@@ -358,16 +362,16 @@ precision (detected_t *d)
#if defined(H5_HAVE_LONGJMP) && defined(H5_HAVE_SIGNAL)
#define ALIGNMENT(TYPE,INFO) { \
- char *volatile _buf=NULL; \
- volatile TYPE _val=1; \
+ char *volatile _buf = NULL; \
+ volatile TYPE _val = 1; \
volatile TYPE _val2; \
- volatile size_t _ano=0; \
+ volatile size_t _ano = 0; \
void (*_handler)(int) = signal(SIGBUS, sigbus_handler); \
void (*_handler2)(int) = signal(SIGSEGV, sigsegv_handler); \
\
- _buf = (char*)malloc(sizeof(TYPE)+align_g[NELMTS(align_g)-1]); \
- if (setjmp(jbuf_g)) _ano++; \
- if (_ano<NELMTS(align_g)) { \
+ _buf = (char*)malloc(sizeof(TYPE) + align_g[NELMTS(align_g) - 1]); \
+ if(setjmp(jbuf_g)) _ano++; \
+ if(_ano < NELMTS(align_g)) { \
*((TYPE*)(_buf+align_g[_ano])) = _val; /*possible SIGBUS or SEGSEGV*/ \
_val2 = *((TYPE*)(_buf+align_g[_ano])); /*possible SIGBUS or SEGSEGV*/ \
/* Cray Check: This section helps detect alignment on Cray's */ \
@@ -500,6 +504,99 @@ sigbus_handler(int UNUSED signo)
/*-------------------------------------------------------------------------
+ * Function: insert_libhdf5_settings
+ *
+ * Purpose: insert the contents of libhdf5.settings into a file
+ * represented by flibinfo.
+ * Make it an empty string if H5_HAVE_EMBEDDED_LIBINFO is not
+ * defined, i.e., not enabled.
+ *
+ * Return: void
+ *
+ * Programmer: Albert Cheng
+ * Apr 20, 2009
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+#define LIBSETTINGSFNAME "libhdf5.settings"
+static void
+insert_libhdf5_settings(FILE *flibinfo)
+{
+#ifdef H5_HAVE_EMBEDDED_LIBINFO
+ FILE *fsettings; /* for files libhdf5.settings */
+ int inchar;
+ int bol=0; /* indicates the beginning of a new line */
+
+ if (NULL==(fsettings=HDfopen(LIBSETTINGSFNAME, "r"))){
+ perror(LIBSETTINGSFNAME);
+ exit(1);
+ }
+ /* print variable definition and the string */
+ fprintf(flibinfo, "char H5libhdf5_settings[]=\n");
+ bol++;
+ while (EOF != (inchar = getc(fsettings))){
+ if (bol){
+ /* Start a new line */
+ fprintf(flibinfo, "\t\"");
+ bol = 0;
+ }
+ if (inchar == '\n'){
+ /* end of a line */
+ fprintf(flibinfo, "\\n\"\n");
+ bol++;
+ }else{
+ putc(inchar, flibinfo);
+ }
+ }
+ if (feof(fsettings)){
+ /* wrap up */
+ if (!bol){
+ /* EOF found without a new line */
+ fprintf(flibinfo, "\\n\"\n");
+ };
+ fprintf(flibinfo, ";\n\n");
+ }else{
+ fprintf(stderr, "Read errors encountered with %s\n", LIBSETTINGSFNAME);
+ exit(1);
+ }
+ if (0 != fclose(fsettings)){
+ perror(LIBSETTINGSFNAME);
+ exit(1);
+ }
+#else
+ /* print variable definition and an empty string */
+ fprintf(flibinfo, "char H5libhdf5_settings[]=\"\";\n");
+#endif
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: make_libinfo
+ *
+ * Purpose: Create the embedded library information definition.
+ * This sets up for a potential extension that the declaration
+ * is printed to a file different from stdout.
+ *
+ * Return: void
+ *
+ * Programmer: Albert Cheng
+ * Sep 15, 2009
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+make_libinfo(void)
+{
+ /* print variable definition and then the string as a macro. */
+ insert_libhdf5_settings(stdout);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: print_results
*
* Purpose: Prints information about the detected data types.
@@ -522,27 +619,93 @@ print_results(int nd, detected_t *d, int na, malign_t *misc_align)
/* Include files */
printf("\
+/****************/\n\
+/* Module Setup */\n\
+/****************/\n\
+\n\
#define H5T_PACKAGE /*suppress error about including H5Tpkg.h*/\n\
\n\
-#include \"H5private.h\"\n\
-#include \"H5Iprivate.h\"\n\
-#include \"H5Eprivate.h\"\n\
-#include \"H5FLprivate.h\"\n\
-#include \"H5Tpkg.h\"\n\
\n\
+/***********/\n\
+/* Headers */\n\
+/***********/\n\
+#include \"H5private.h\" /* Generic Functions */\n\
+#include \"H5Eprivate.h\" /* Error handling */\n\
+#include \"H5FLprivate.h\" /* Free Lists */\n\
+#include \"H5Iprivate.h\" /* IDs */\n\
+#include \"H5Tpkg.h\" /* Datatypes */\n\
+\n\
+\n\
+/****************/\n\
+/* Local Macros */\n\
+/****************/\n\
+\n\
+\n\
+/******************/\n\
+/* Local Typedefs */\n\
+/******************/\n\
+\n\
+\n\
+/********************/\n\
+/* Package Typedefs */\n\
+/********************/\n\
+\n\
+\n\
+/********************/\n\
+/* Local Prototypes */\n\
+/********************/\n\
+\n\
+\n\
+/********************/\n\
+/* Public Variables */\n\
+/********************/\n\
+\n\
+\n\
+/*****************************/\n\
+/* Library Private Variables */\n\
+/*****************************/\n\
+\n\
+\n\
+/*********************/\n\
+/* Package Variables */\n\
+/*********************/\n\
+\n\
+\n");
+ printf("\n\
+/*******************/\n\
+/* Local Variables */\n\
+/*******************/\n\
\n");
+ /* Generate embedded library information variable definition */
+ make_libinfo();
+
/* The interface initialization function */
printf("\n\
+ \n\
+/*-------------------------------------------------------------------------\n\
+ * Function: H5TN_init_interface\n\
+ *\n\
+ * Purpose: Initialize pre-defined native datatypes from code generated\n\
+ * during the library configuration by H5detect.\n\
+ *\n\
+ * Return: Success: non-negative\n\
+ * Failure: negative\n\
+ *\n\
+ * Programmer: Robb Matzke\n\
+ * Wednesday, December 16, 1998\n\
+ *\n\
+ *-------------------------------------------------------------------------\n\
+ */\n\
herr_t\n\
H5TN_init_interface(void)\n\
{\n\
H5T_t *dt = NULL;\n\
herr_t ret_value = SUCCEED;\n\
\n\
- FUNC_ENTER_NOAPI(H5TN_init_interface, FAIL);\n");
+ FUNC_ENTER_NOAPI(H5TN_init_interface, FAIL)\n");
- for (i = 0; i < nd; i++) {
+ for(i = 0; i < nd; i++) {
/* The native endianess of this machine */
/* The INFO.perm now contains `-1' for bytes that aren't used and
* are always zero. This happens on the Cray for `short' where
@@ -568,7 +731,7 @@ H5TN_init_interface(void)\n\
/* The part common to fixed and floating types */
printf("\
if(NULL == (dt = H5T_alloc()))\n\
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,\"memory allocation failed\")\n\
+ HGOTO_ERROR(H5E_DATATYPE, H5E_NOSPACE, FAIL, \"datatype allocation failed\")\n\
dt->shared->state = H5T_STATE_IMMUTABLE;\n\
dt->shared->type = H5T_%s;\n\
dt->shared->size = %d;\n",
@@ -621,8 +784,8 @@ H5TN_init_interface(void)\n\
/* Atomize the type */
printf("\
- if ((H5T_NATIVE_%s_g = H5I_register (H5I_DATATYPE, dt))<0)\n\
- HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,\"can't initialize type system (atom registration failure\");\n",
+ if((H5T_NATIVE_%s_g = H5I_register(H5I_DATATYPE, dt, FALSE)) < 0)\n\
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, \"can't register ID for built-in datatype\")\n",
d[i].varname);
printf(" H5T_NATIVE_%s_ALIGN_g = %lu;\n",
d[i].varname, (unsigned long)(d[i].align));
@@ -656,16 +819,15 @@ H5TN_init_interface(void)\n\
printf("\
\n\
done:\n\
- if(ret_value<0) {\n\
+ if(ret_value < 0) {\n\
if(dt != NULL) {\n\
- if(dt->shared != NULL)\n\
- H5FL_FREE(H5T_shared_t, dt->shared);\n\
- H5FL_FREE(H5T_t, dt);\n\
+ H5FL_FREE(H5T_shared_t, dt->shared);\n\
+ dt = H5FL_FREE(H5T_t, dt);\n\
} /* end if */\n\
- }\n\
+ } /* end if */\n\
\n\
- FUNC_LEAVE_NOAPI(ret_value);\n}\n");
-}
+ FUNC_LEAVE_NOAPI(ret_value);\n} /* end H5TN_init_interface() */\n");
+} /* end print_results() */
/*-------------------------------------------------------------------------
@@ -992,8 +1154,8 @@ find_bias(int epos, int esize, int *perm, void *_a)
/*-------------------------------------------------------------------------
* Function: print_header
- *
- * Purpose: Prints the C file header for the generated file.
+ *
+ * Purpose: Prints the C file header for the generated file.
*
* Return: void
*
@@ -1333,8 +1495,8 @@ detect_C99_integers64(void)
#endif
#if H5_SIZEOF_LONG_LONG>0
- DETECT_I(long_long, LLONG, d_g[nd_g]); nd_g++;
- DETECT_I(unsigned long_long, ULLONG, d_g[nd_g]); nd_g++;
+ DETECT_I(long long, LLONG, d_g[nd_g]); nd_g++;
+ DETECT_I(unsigned long long, ULLONG, d_g[nd_g]); nd_g++;
#else
/*
* This architecture doesn't support an integer type larger than `long'
diff --git a/src/H5err.txt b/src/H5err.txt
index 844bd57..67b6448 100644
--- a/src/H5err.txt
+++ b/src/H5err.txt
@@ -74,6 +74,8 @@ MAJOR, H5E_ERROR, Error API
MAJOR, H5E_SLIST, Skip Lists
MAJOR, H5E_FSPACE, Free Space Manager
MAJOR, H5E_SOHM, Shared Object Header Messages
+MAJOR, H5E_EARRAY, Extensible Array
+MAJOR, H5E_FARRAY, Fixed Array
MAJOR, H5E_NONE_MAJOR, No error
# Sections (for grouping minor errors)
@@ -168,6 +170,9 @@ MINOR, CACHE, H5E_CANTMARKDIRTY, Unable to mark a pinned entry as dirty
MINOR, CACHE, H5E_CANTDIRTY, Unable to mark metadata as dirty
MINOR, CACHE, H5E_CANTEXPUNGE, Unable to expunge a metadata cache entry
MINOR, CACHE, H5E_CANTRESIZE, Unable to resize a metadata cache entry
+MINOR, CACHE, H5E_CANTDEPEND, Unable to create a flush dependency
+MINOR, CACHE, H5E_CANTUNDEPEND, Unable to destroy a flush dependency
+MINOR, CACHE, H5E_CANTNOTIFY, Unable to notify object about action
# B-tree related errors
MINOR, BTREE, H5E_NOTFOUND, Object not found
diff --git a/src/H5overflow.h b/src/H5overflow.h
new file mode 100644
index 0000000..1c00acf
--- /dev/null
+++ b/src/H5overflow.h
@@ -0,0 +1,1381 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* Generated automatically by bin/make_overflow -- do not edit */
+/* Add new types to H5overflow.txt file */
+
+
+#ifndef _H5overflow_H
+#define _H5overflow_H
+
+
+/* Each type in this file is tested for assignment to the other types,
+ * and range checks are defined for bad assignments at run-time.
+ */
+
+/* Assignment checks for unsigned */
+
+/* src: unsigned, dst: int */
+#if H5_SIZEOF_UNSIGNED < H5_SIZEOF_INT
+ #define ASSIGN_unsigned_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UNSIGNED > H5_SIZEOF_INT
+ #define ASSIGN_unsigned_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UNSIGNED == H5_SIZEOF_INT */
+ #define ASSIGN_unsigned_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: unsigned dst: int */
+
+/* src: unsigned, dst: uint8_t */
+#if H5_SIZEOF_UNSIGNED < H5_SIZEOF_UINT8_T
+ #define ASSIGN_unsigned_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UNSIGNED > H5_SIZEOF_UINT8_T
+ #define ASSIGN_unsigned_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UNSIGNED == H5_SIZEOF_UINT8_T */
+ #define ASSIGN_unsigned_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: unsigned dst: uint8_t */
+
+/* src: unsigned, dst: uint32_t */
+#if H5_SIZEOF_UNSIGNED < H5_SIZEOF_UINT32_T
+ #define ASSIGN_unsigned_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UNSIGNED > H5_SIZEOF_UINT32_T
+ #define ASSIGN_unsigned_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UNSIGNED == H5_SIZEOF_UINT32_T */
+ #define ASSIGN_unsigned_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: unsigned dst: uint32_t */
+
+/* src: unsigned, dst: uint64_t */
+#if H5_SIZEOF_UNSIGNED < H5_SIZEOF_UINT64_T
+ #define ASSIGN_unsigned_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UNSIGNED > H5_SIZEOF_UINT64_T
+ #define ASSIGN_unsigned_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UNSIGNED == H5_SIZEOF_UINT64_T */
+ #define ASSIGN_unsigned_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: unsigned dst: uint64_t */
+
+/* src: unsigned, dst: size_t */
+#if H5_SIZEOF_UNSIGNED < H5_SIZEOF_SIZE_T
+ #define ASSIGN_unsigned_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UNSIGNED > H5_SIZEOF_SIZE_T
+ #define ASSIGN_unsigned_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UNSIGNED == H5_SIZEOF_SIZE_T */
+ #define ASSIGN_unsigned_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: unsigned dst: size_t */
+
+/* src: unsigned, dst: ssize_t */
+#if H5_SIZEOF_UNSIGNED < H5_SIZEOF_SSIZE_T
+ #define ASSIGN_unsigned_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UNSIGNED > H5_SIZEOF_SSIZE_T
+ #define ASSIGN_unsigned_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UNSIGNED == H5_SIZEOF_SSIZE_T */
+ #define ASSIGN_unsigned_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: unsigned dst: ssize_t */
+
+/* src: unsigned, dst: haddr_t */
+#if H5_SIZEOF_UNSIGNED < H5_SIZEOF_HADDR_T
+ #define ASSIGN_unsigned_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UNSIGNED > H5_SIZEOF_HADDR_T
+ #define ASSIGN_unsigned_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UNSIGNED == H5_SIZEOF_HADDR_T */
+ #define ASSIGN_unsigned_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: unsigned dst: haddr_t */
+
+/* src: unsigned, dst: hsize_t */
+#if H5_SIZEOF_UNSIGNED < H5_SIZEOF_HSIZE_T
+ #define ASSIGN_unsigned_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UNSIGNED > H5_SIZEOF_HSIZE_T
+ #define ASSIGN_unsigned_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UNSIGNED == H5_SIZEOF_HSIZE_T */
+ #define ASSIGN_unsigned_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: unsigned dst: hsize_t */
+
+/* src: unsigned, dst: hssize_t */
+#if H5_SIZEOF_UNSIGNED < H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_unsigned_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UNSIGNED > H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_unsigned_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UNSIGNED == H5_SIZEOF_HSSIZE_T */
+ #define ASSIGN_unsigned_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: unsigned dst: hssize_t */
+
+/* src: unsigned, dst: h5_stat_size_t */
+#if H5_SIZEOF_UNSIGNED < H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_unsigned_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UNSIGNED > H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_unsigned_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UNSIGNED == H5_SIZEOF_H5_STAT_SIZE_T */
+ #define ASSIGN_unsigned_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: unsigned dst: h5_stat_size_t */
+
+
+/* Assignment checks for int */
+
+/* src: int, dst: unsigned */
+#if H5_SIZEOF_INT < H5_SIZEOF_UNSIGNED
+ #define ASSIGN_int_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_INT > H5_SIZEOF_UNSIGNED
+ #define ASSIGN_int_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_INT == H5_SIZEOF_UNSIGNED */
+ #define ASSIGN_int_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: int dst: unsigned */
+
+/* src: int, dst: uint8_t */
+#if H5_SIZEOF_INT < H5_SIZEOF_UINT8_T
+ #define ASSIGN_int_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_INT > H5_SIZEOF_UINT8_T
+ #define ASSIGN_int_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_INT == H5_SIZEOF_UINT8_T */
+ #define ASSIGN_int_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: int dst: uint8_t */
+
+/* src: int, dst: uint32_t */
+#if H5_SIZEOF_INT < H5_SIZEOF_UINT32_T
+ #define ASSIGN_int_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_INT > H5_SIZEOF_UINT32_T
+ #define ASSIGN_int_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_INT == H5_SIZEOF_UINT32_T */
+ #define ASSIGN_int_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: int dst: uint32_t */
+
+/* src: int, dst: uint64_t */
+#if H5_SIZEOF_INT < H5_SIZEOF_UINT64_T
+ #define ASSIGN_int_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_INT > H5_SIZEOF_UINT64_T
+ #define ASSIGN_int_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_INT == H5_SIZEOF_UINT64_T */
+ #define ASSIGN_int_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: int dst: uint64_t */
+
+/* src: int, dst: size_t */
+#if H5_SIZEOF_INT < H5_SIZEOF_SIZE_T
+ #define ASSIGN_int_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_INT > H5_SIZEOF_SIZE_T
+ #define ASSIGN_int_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_INT == H5_SIZEOF_SIZE_T */
+ #define ASSIGN_int_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: int dst: size_t */
+
+/* src: int, dst: ssize_t */
+#if H5_SIZEOF_INT < H5_SIZEOF_SSIZE_T
+ #define ASSIGN_int_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_INT > H5_SIZEOF_SSIZE_T
+ #define ASSIGN_int_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_INT == H5_SIZEOF_SSIZE_T */
+ #define ASSIGN_int_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: int dst: ssize_t */
+
+/* src: int, dst: haddr_t */
+#if H5_SIZEOF_INT < H5_SIZEOF_HADDR_T
+ #define ASSIGN_int_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_INT > H5_SIZEOF_HADDR_T
+ #define ASSIGN_int_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_INT == H5_SIZEOF_HADDR_T */
+ #define ASSIGN_int_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: int dst: haddr_t */
+
+/* src: int, dst: hsize_t */
+#if H5_SIZEOF_INT < H5_SIZEOF_HSIZE_T
+ #define ASSIGN_int_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_INT > H5_SIZEOF_HSIZE_T
+ #define ASSIGN_int_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_INT == H5_SIZEOF_HSIZE_T */
+ #define ASSIGN_int_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: int dst: hsize_t */
+
+/* src: int, dst: hssize_t */
+#if H5_SIZEOF_INT < H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_int_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_INT > H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_int_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_INT == H5_SIZEOF_HSSIZE_T */
+ #define ASSIGN_int_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: int dst: hssize_t */
+
+/* src: int, dst: h5_stat_size_t */
+#if H5_SIZEOF_INT < H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_int_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_INT > H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_int_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_INT == H5_SIZEOF_H5_STAT_SIZE_T */
+ #define ASSIGN_int_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: int dst: h5_stat_size_t */
+
+
+/* Assignment checks for uint8_t */
+
+/* src: uint8_t, dst: unsigned */
+#if H5_SIZEOF_UINT8_T < H5_SIZEOF_UNSIGNED
+ #define ASSIGN_uint8_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT8_T > H5_SIZEOF_UNSIGNED
+ #define ASSIGN_uint8_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT8_T == H5_SIZEOF_UNSIGNED */
+ #define ASSIGN_uint8_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint8_t dst: unsigned */
+
+/* src: uint8_t, dst: int */
+#if H5_SIZEOF_UINT8_T < H5_SIZEOF_INT
+ #define ASSIGN_uint8_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT8_T > H5_SIZEOF_INT
+ #define ASSIGN_uint8_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT8_T == H5_SIZEOF_INT */
+ #define ASSIGN_uint8_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint8_t dst: int */
+
+/* src: uint8_t, dst: uint32_t */
+#if H5_SIZEOF_UINT8_T < H5_SIZEOF_UINT32_T
+ #define ASSIGN_uint8_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT8_T > H5_SIZEOF_UINT32_T
+ #define ASSIGN_uint8_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT8_T == H5_SIZEOF_UINT32_T */
+ #define ASSIGN_uint8_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint8_t dst: uint32_t */
+
+/* src: uint8_t, dst: uint64_t */
+#if H5_SIZEOF_UINT8_T < H5_SIZEOF_UINT64_T
+ #define ASSIGN_uint8_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT8_T > H5_SIZEOF_UINT64_T
+ #define ASSIGN_uint8_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT8_T == H5_SIZEOF_UINT64_T */
+ #define ASSIGN_uint8_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint8_t dst: uint64_t */
+
+/* src: uint8_t, dst: size_t */
+#if H5_SIZEOF_UINT8_T < H5_SIZEOF_SIZE_T
+ #define ASSIGN_uint8_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT8_T > H5_SIZEOF_SIZE_T
+ #define ASSIGN_uint8_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT8_T == H5_SIZEOF_SIZE_T */
+ #define ASSIGN_uint8_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint8_t dst: size_t */
+
+/* src: uint8_t, dst: ssize_t */
+#if H5_SIZEOF_UINT8_T < H5_SIZEOF_SSIZE_T
+ #define ASSIGN_uint8_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT8_T > H5_SIZEOF_SSIZE_T
+ #define ASSIGN_uint8_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT8_T == H5_SIZEOF_SSIZE_T */
+ #define ASSIGN_uint8_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint8_t dst: ssize_t */
+
+/* src: uint8_t, dst: haddr_t */
+#if H5_SIZEOF_UINT8_T < H5_SIZEOF_HADDR_T
+ #define ASSIGN_uint8_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT8_T > H5_SIZEOF_HADDR_T
+ #define ASSIGN_uint8_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT8_T == H5_SIZEOF_HADDR_T */
+ #define ASSIGN_uint8_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint8_t dst: haddr_t */
+
+/* src: uint8_t, dst: hsize_t */
+#if H5_SIZEOF_UINT8_T < H5_SIZEOF_HSIZE_T
+ #define ASSIGN_uint8_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT8_T > H5_SIZEOF_HSIZE_T
+ #define ASSIGN_uint8_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT8_T == H5_SIZEOF_HSIZE_T */
+ #define ASSIGN_uint8_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint8_t dst: hsize_t */
+
+/* src: uint8_t, dst: hssize_t */
+#if H5_SIZEOF_UINT8_T < H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_uint8_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT8_T > H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_uint8_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT8_T == H5_SIZEOF_HSSIZE_T */
+ #define ASSIGN_uint8_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint8_t dst: hssize_t */
+
+/* src: uint8_t, dst: h5_stat_size_t */
+#if H5_SIZEOF_UINT8_T < H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_uint8_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT8_T > H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_uint8_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT8_T == H5_SIZEOF_H5_STAT_SIZE_T */
+ #define ASSIGN_uint8_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint8_t dst: h5_stat_size_t */
+
+
+/* Assignment checks for uint32_t */
+
+/* src: uint32_t, dst: unsigned */
+#if H5_SIZEOF_UINT32_T < H5_SIZEOF_UNSIGNED
+ #define ASSIGN_uint32_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT32_T > H5_SIZEOF_UNSIGNED
+ #define ASSIGN_uint32_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT32_T == H5_SIZEOF_UNSIGNED */
+ #define ASSIGN_uint32_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint32_t dst: unsigned */
+
+/* src: uint32_t, dst: int */
+#if H5_SIZEOF_UINT32_T < H5_SIZEOF_INT
+ #define ASSIGN_uint32_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT32_T > H5_SIZEOF_INT
+ #define ASSIGN_uint32_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT32_T == H5_SIZEOF_INT */
+ #define ASSIGN_uint32_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint32_t dst: int */
+
+/* src: uint32_t, dst: uint8_t */
+#if H5_SIZEOF_UINT32_T < H5_SIZEOF_UINT8_T
+ #define ASSIGN_uint32_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT32_T > H5_SIZEOF_UINT8_T
+ #define ASSIGN_uint32_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT32_T == H5_SIZEOF_UINT8_T */
+ #define ASSIGN_uint32_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint32_t dst: uint8_t */
+
+/* src: uint32_t, dst: uint64_t */
+#if H5_SIZEOF_UINT32_T < H5_SIZEOF_UINT64_T
+ #define ASSIGN_uint32_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT32_T > H5_SIZEOF_UINT64_T
+ #define ASSIGN_uint32_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT32_T == H5_SIZEOF_UINT64_T */
+ #define ASSIGN_uint32_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint32_t dst: uint64_t */
+
+/* src: uint32_t, dst: size_t */
+#if H5_SIZEOF_UINT32_T < H5_SIZEOF_SIZE_T
+ #define ASSIGN_uint32_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT32_T > H5_SIZEOF_SIZE_T
+ #define ASSIGN_uint32_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT32_T == H5_SIZEOF_SIZE_T */
+ #define ASSIGN_uint32_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint32_t dst: size_t */
+
+/* src: uint32_t, dst: ssize_t */
+#if H5_SIZEOF_UINT32_T < H5_SIZEOF_SSIZE_T
+ #define ASSIGN_uint32_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT32_T > H5_SIZEOF_SSIZE_T
+ #define ASSIGN_uint32_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT32_T == H5_SIZEOF_SSIZE_T */
+ #define ASSIGN_uint32_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint32_t dst: ssize_t */
+
+/* src: uint32_t, dst: haddr_t */
+#if H5_SIZEOF_UINT32_T < H5_SIZEOF_HADDR_T
+ #define ASSIGN_uint32_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT32_T > H5_SIZEOF_HADDR_T
+ #define ASSIGN_uint32_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT32_T == H5_SIZEOF_HADDR_T */
+ #define ASSIGN_uint32_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint32_t dst: haddr_t */
+
+/* src: uint32_t, dst: hsize_t */
+#if H5_SIZEOF_UINT32_T < H5_SIZEOF_HSIZE_T
+ #define ASSIGN_uint32_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT32_T > H5_SIZEOF_HSIZE_T
+ #define ASSIGN_uint32_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT32_T == H5_SIZEOF_HSIZE_T */
+ #define ASSIGN_uint32_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint32_t dst: hsize_t */
+
+/* src: uint32_t, dst: hssize_t */
+#if H5_SIZEOF_UINT32_T < H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_uint32_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT32_T > H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_uint32_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT32_T == H5_SIZEOF_HSSIZE_T */
+ #define ASSIGN_uint32_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint32_t dst: hssize_t */
+
+/* src: uint32_t, dst: h5_stat_size_t */
+#if H5_SIZEOF_UINT32_T < H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_uint32_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT32_T > H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_uint32_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT32_T == H5_SIZEOF_H5_STAT_SIZE_T */
+ #define ASSIGN_uint32_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint32_t dst: h5_stat_size_t */
+
+
+/* Assignment checks for uint64_t */
+
+/* src: uint64_t, dst: unsigned */
+#if H5_SIZEOF_UINT64_T < H5_SIZEOF_UNSIGNED
+ #define ASSIGN_uint64_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT64_T > H5_SIZEOF_UNSIGNED
+ #define ASSIGN_uint64_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT64_T == H5_SIZEOF_UNSIGNED */
+ #define ASSIGN_uint64_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint64_t dst: unsigned */
+
+/* src: uint64_t, dst: int */
+#if H5_SIZEOF_UINT64_T < H5_SIZEOF_INT
+ #define ASSIGN_uint64_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT64_T > H5_SIZEOF_INT
+ #define ASSIGN_uint64_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT64_T == H5_SIZEOF_INT */
+ #define ASSIGN_uint64_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint64_t dst: int */
+
+/* src: uint64_t, dst: uint8_t */
+#if H5_SIZEOF_UINT64_T < H5_SIZEOF_UINT8_T
+ #define ASSIGN_uint64_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT64_T > H5_SIZEOF_UINT8_T
+ #define ASSIGN_uint64_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT64_T == H5_SIZEOF_UINT8_T */
+ #define ASSIGN_uint64_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint64_t dst: uint8_t */
+
+/* src: uint64_t, dst: uint32_t */
+#if H5_SIZEOF_UINT64_T < H5_SIZEOF_UINT32_T
+ #define ASSIGN_uint64_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT64_T > H5_SIZEOF_UINT32_T
+ #define ASSIGN_uint64_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT64_T == H5_SIZEOF_UINT32_T */
+ #define ASSIGN_uint64_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint64_t dst: uint32_t */
+
+/* src: uint64_t, dst: size_t */
+#if H5_SIZEOF_UINT64_T < H5_SIZEOF_SIZE_T
+ #define ASSIGN_uint64_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT64_T > H5_SIZEOF_SIZE_T
+ #define ASSIGN_uint64_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT64_T == H5_SIZEOF_SIZE_T */
+ #define ASSIGN_uint64_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint64_t dst: size_t */
+
+/* src: uint64_t, dst: ssize_t */
+#if H5_SIZEOF_UINT64_T < H5_SIZEOF_SSIZE_T
+ #define ASSIGN_uint64_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT64_T > H5_SIZEOF_SSIZE_T
+ #define ASSIGN_uint64_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT64_T == H5_SIZEOF_SSIZE_T */
+ #define ASSIGN_uint64_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint64_t dst: ssize_t */
+
+/* src: uint64_t, dst: haddr_t */
+#if H5_SIZEOF_UINT64_T < H5_SIZEOF_HADDR_T
+ #define ASSIGN_uint64_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT64_T > H5_SIZEOF_HADDR_T
+ #define ASSIGN_uint64_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT64_T == H5_SIZEOF_HADDR_T */
+ #define ASSIGN_uint64_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint64_t dst: haddr_t */
+
+/* src: uint64_t, dst: hsize_t */
+#if H5_SIZEOF_UINT64_T < H5_SIZEOF_HSIZE_T
+ #define ASSIGN_uint64_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT64_T > H5_SIZEOF_HSIZE_T
+ #define ASSIGN_uint64_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT64_T == H5_SIZEOF_HSIZE_T */
+ #define ASSIGN_uint64_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint64_t dst: hsize_t */
+
+/* src: uint64_t, dst: hssize_t */
+#if H5_SIZEOF_UINT64_T < H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_uint64_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT64_T > H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_uint64_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT64_T == H5_SIZEOF_HSSIZE_T */
+ #define ASSIGN_uint64_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint64_t dst: hssize_t */
+
+/* src: uint64_t, dst: h5_stat_size_t */
+#if H5_SIZEOF_UINT64_T < H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_uint64_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_UINT64_T > H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_uint64_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_UINT64_T == H5_SIZEOF_H5_STAT_SIZE_T */
+ #define ASSIGN_uint64_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: uint64_t dst: h5_stat_size_t */
+
+
+/* Assignment checks for size_t */
+
+/* src: size_t, dst: unsigned */
+#if H5_SIZEOF_SIZE_T < H5_SIZEOF_UNSIGNED
+ #define ASSIGN_size_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SIZE_T > H5_SIZEOF_UNSIGNED
+ #define ASSIGN_size_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SIZE_T == H5_SIZEOF_UNSIGNED */
+ #define ASSIGN_size_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: size_t dst: unsigned */
+
+/* src: size_t, dst: int */
+#if H5_SIZEOF_SIZE_T < H5_SIZEOF_INT
+ #define ASSIGN_size_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SIZE_T > H5_SIZEOF_INT
+ #define ASSIGN_size_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SIZE_T == H5_SIZEOF_INT */
+ #define ASSIGN_size_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: size_t dst: int */
+
+/* src: size_t, dst: uint8_t */
+#if H5_SIZEOF_SIZE_T < H5_SIZEOF_UINT8_T
+ #define ASSIGN_size_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SIZE_T > H5_SIZEOF_UINT8_T
+ #define ASSIGN_size_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SIZE_T == H5_SIZEOF_UINT8_T */
+ #define ASSIGN_size_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: size_t dst: uint8_t */
+
+/* src: size_t, dst: uint32_t */
+#if H5_SIZEOF_SIZE_T < H5_SIZEOF_UINT32_T
+ #define ASSIGN_size_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SIZE_T > H5_SIZEOF_UINT32_T
+ #define ASSIGN_size_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SIZE_T == H5_SIZEOF_UINT32_T */
+ #define ASSIGN_size_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: size_t dst: uint32_t */
+
+/* src: size_t, dst: uint64_t */
+#if H5_SIZEOF_SIZE_T < H5_SIZEOF_UINT64_T
+ #define ASSIGN_size_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SIZE_T > H5_SIZEOF_UINT64_T
+ #define ASSIGN_size_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SIZE_T == H5_SIZEOF_UINT64_T */
+ #define ASSIGN_size_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: size_t dst: uint64_t */
+
+/* src: size_t, dst: ssize_t */
+#if H5_SIZEOF_SIZE_T < H5_SIZEOF_SSIZE_T
+ #define ASSIGN_size_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SIZE_T > H5_SIZEOF_SSIZE_T
+ #define ASSIGN_size_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SIZE_T == H5_SIZEOF_SSIZE_T */
+ #define ASSIGN_size_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: size_t dst: ssize_t */
+
+/* src: size_t, dst: haddr_t */
+#if H5_SIZEOF_SIZE_T < H5_SIZEOF_HADDR_T
+ #define ASSIGN_size_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SIZE_T > H5_SIZEOF_HADDR_T
+ #define ASSIGN_size_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SIZE_T == H5_SIZEOF_HADDR_T */
+ #define ASSIGN_size_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: size_t dst: haddr_t */
+
+/* src: size_t, dst: hsize_t */
+#if H5_SIZEOF_SIZE_T < H5_SIZEOF_HSIZE_T
+ #define ASSIGN_size_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SIZE_T > H5_SIZEOF_HSIZE_T
+ #define ASSIGN_size_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SIZE_T == H5_SIZEOF_HSIZE_T */
+ #define ASSIGN_size_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: size_t dst: hsize_t */
+
+/* src: size_t, dst: hssize_t */
+#if H5_SIZEOF_SIZE_T < H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_size_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SIZE_T > H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_size_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SIZE_T == H5_SIZEOF_HSSIZE_T */
+ #define ASSIGN_size_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: size_t dst: hssize_t */
+
+/* src: size_t, dst: h5_stat_size_t */
+#if H5_SIZEOF_SIZE_T < H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_size_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SIZE_T > H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_size_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SIZE_T == H5_SIZEOF_H5_STAT_SIZE_T */
+ #define ASSIGN_size_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: size_t dst: h5_stat_size_t */
+
+
+/* Assignment checks for ssize_t */
+
+/* src: ssize_t, dst: unsigned */
+#if H5_SIZEOF_SSIZE_T < H5_SIZEOF_UNSIGNED
+ #define ASSIGN_ssize_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SSIZE_T > H5_SIZEOF_UNSIGNED
+ #define ASSIGN_ssize_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SSIZE_T == H5_SIZEOF_UNSIGNED */
+ #define ASSIGN_ssize_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: ssize_t dst: unsigned */
+
+/* src: ssize_t, dst: int */
+#if H5_SIZEOF_SSIZE_T < H5_SIZEOF_INT
+ #define ASSIGN_ssize_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SSIZE_T > H5_SIZEOF_INT
+ #define ASSIGN_ssize_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SSIZE_T == H5_SIZEOF_INT */
+ #define ASSIGN_ssize_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: ssize_t dst: int */
+
+/* src: ssize_t, dst: uint8_t */
+#if H5_SIZEOF_SSIZE_T < H5_SIZEOF_UINT8_T
+ #define ASSIGN_ssize_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SSIZE_T > H5_SIZEOF_UINT8_T
+ #define ASSIGN_ssize_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SSIZE_T == H5_SIZEOF_UINT8_T */
+ #define ASSIGN_ssize_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: ssize_t dst: uint8_t */
+
+/* src: ssize_t, dst: uint32_t */
+#if H5_SIZEOF_SSIZE_T < H5_SIZEOF_UINT32_T
+ #define ASSIGN_ssize_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SSIZE_T > H5_SIZEOF_UINT32_T
+ #define ASSIGN_ssize_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SSIZE_T == H5_SIZEOF_UINT32_T */
+ #define ASSIGN_ssize_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: ssize_t dst: uint32_t */
+
+/* src: ssize_t, dst: uint64_t */
+#if H5_SIZEOF_SSIZE_T < H5_SIZEOF_UINT64_T
+ #define ASSIGN_ssize_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SSIZE_T > H5_SIZEOF_UINT64_T
+ #define ASSIGN_ssize_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SSIZE_T == H5_SIZEOF_UINT64_T */
+ #define ASSIGN_ssize_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: ssize_t dst: uint64_t */
+
+/* src: ssize_t, dst: size_t */
+#if H5_SIZEOF_SSIZE_T < H5_SIZEOF_SIZE_T
+ #define ASSIGN_ssize_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SSIZE_T > H5_SIZEOF_SIZE_T
+ #define ASSIGN_ssize_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SSIZE_T == H5_SIZEOF_SIZE_T */
+ #define ASSIGN_ssize_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: ssize_t dst: size_t */
+
+/* src: ssize_t, dst: haddr_t */
+#if H5_SIZEOF_SSIZE_T < H5_SIZEOF_HADDR_T
+ #define ASSIGN_ssize_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SSIZE_T > H5_SIZEOF_HADDR_T
+ #define ASSIGN_ssize_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SSIZE_T == H5_SIZEOF_HADDR_T */
+ #define ASSIGN_ssize_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: ssize_t dst: haddr_t */
+
+/* src: ssize_t, dst: hsize_t */
+#if H5_SIZEOF_SSIZE_T < H5_SIZEOF_HSIZE_T
+ #define ASSIGN_ssize_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SSIZE_T > H5_SIZEOF_HSIZE_T
+ #define ASSIGN_ssize_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SSIZE_T == H5_SIZEOF_HSIZE_T */
+ #define ASSIGN_ssize_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: ssize_t dst: hsize_t */
+
+/* src: ssize_t, dst: hssize_t */
+#if H5_SIZEOF_SSIZE_T < H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_ssize_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SSIZE_T > H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_ssize_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SSIZE_T == H5_SIZEOF_HSSIZE_T */
+ #define ASSIGN_ssize_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: ssize_t dst: hssize_t */
+
+/* src: ssize_t, dst: h5_stat_size_t */
+#if H5_SIZEOF_SSIZE_T < H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_ssize_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_SSIZE_T > H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_ssize_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_SSIZE_T == H5_SIZEOF_H5_STAT_SIZE_T */
+ #define ASSIGN_ssize_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: ssize_t dst: h5_stat_size_t */
+
+
+/* Assignment checks for haddr_t */
+
+/* src: haddr_t, dst: unsigned */
+#if H5_SIZEOF_HADDR_T < H5_SIZEOF_UNSIGNED
+ #define ASSIGN_haddr_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HADDR_T > H5_SIZEOF_UNSIGNED
+ #define ASSIGN_haddr_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HADDR_T == H5_SIZEOF_UNSIGNED */
+ #define ASSIGN_haddr_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: haddr_t dst: unsigned */
+
+/* src: haddr_t, dst: int */
+#if H5_SIZEOF_HADDR_T < H5_SIZEOF_INT
+ #define ASSIGN_haddr_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HADDR_T > H5_SIZEOF_INT
+ #define ASSIGN_haddr_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HADDR_T == H5_SIZEOF_INT */
+ #define ASSIGN_haddr_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: haddr_t dst: int */
+
+/* src: haddr_t, dst: uint8_t */
+#if H5_SIZEOF_HADDR_T < H5_SIZEOF_UINT8_T
+ #define ASSIGN_haddr_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HADDR_T > H5_SIZEOF_UINT8_T
+ #define ASSIGN_haddr_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HADDR_T == H5_SIZEOF_UINT8_T */
+ #define ASSIGN_haddr_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: haddr_t dst: uint8_t */
+
+/* src: haddr_t, dst: uint32_t */
+#if H5_SIZEOF_HADDR_T < H5_SIZEOF_UINT32_T
+ #define ASSIGN_haddr_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HADDR_T > H5_SIZEOF_UINT32_T
+ #define ASSIGN_haddr_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HADDR_T == H5_SIZEOF_UINT32_T */
+ #define ASSIGN_haddr_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: haddr_t dst: uint32_t */
+
+/* src: haddr_t, dst: uint64_t */
+#if H5_SIZEOF_HADDR_T < H5_SIZEOF_UINT64_T
+ #define ASSIGN_haddr_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HADDR_T > H5_SIZEOF_UINT64_T
+ #define ASSIGN_haddr_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HADDR_T == H5_SIZEOF_UINT64_T */
+ #define ASSIGN_haddr_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: haddr_t dst: uint64_t */
+
+/* src: haddr_t, dst: size_t */
+#if H5_SIZEOF_HADDR_T < H5_SIZEOF_SIZE_T
+ #define ASSIGN_haddr_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HADDR_T > H5_SIZEOF_SIZE_T
+ #define ASSIGN_haddr_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HADDR_T == H5_SIZEOF_SIZE_T */
+ #define ASSIGN_haddr_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: haddr_t dst: size_t */
+
+/* src: haddr_t, dst: ssize_t */
+#if H5_SIZEOF_HADDR_T < H5_SIZEOF_SSIZE_T
+ #define ASSIGN_haddr_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HADDR_T > H5_SIZEOF_SSIZE_T
+ #define ASSIGN_haddr_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HADDR_T == H5_SIZEOF_SSIZE_T */
+ #define ASSIGN_haddr_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: haddr_t dst: ssize_t */
+
+/* src: haddr_t, dst: hsize_t */
+#if H5_SIZEOF_HADDR_T < H5_SIZEOF_HSIZE_T
+ #define ASSIGN_haddr_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HADDR_T > H5_SIZEOF_HSIZE_T
+ #define ASSIGN_haddr_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HADDR_T == H5_SIZEOF_HSIZE_T */
+ #define ASSIGN_haddr_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: haddr_t dst: hsize_t */
+
+/* src: haddr_t, dst: hssize_t */
+#if H5_SIZEOF_HADDR_T < H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_haddr_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HADDR_T > H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_haddr_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HADDR_T == H5_SIZEOF_HSSIZE_T */
+ #define ASSIGN_haddr_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: haddr_t dst: hssize_t */
+
+/* src: haddr_t, dst: h5_stat_size_t */
+#if H5_SIZEOF_HADDR_T < H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_haddr_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HADDR_T > H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_haddr_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HADDR_T == H5_SIZEOF_H5_STAT_SIZE_T */
+ #define ASSIGN_haddr_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: haddr_t dst: h5_stat_size_t */
+
+
+/* Assignment checks for hsize_t */
+
+/* src: hsize_t, dst: unsigned */
+#if H5_SIZEOF_HSIZE_T < H5_SIZEOF_UNSIGNED
+ #define ASSIGN_hsize_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSIZE_T > H5_SIZEOF_UNSIGNED
+ #define ASSIGN_hsize_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSIZE_T == H5_SIZEOF_UNSIGNED */
+ #define ASSIGN_hsize_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: hsize_t dst: unsigned */
+
+/* src: hsize_t, dst: int */
+#if H5_SIZEOF_HSIZE_T < H5_SIZEOF_INT
+ #define ASSIGN_hsize_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSIZE_T > H5_SIZEOF_INT
+ #define ASSIGN_hsize_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSIZE_T == H5_SIZEOF_INT */
+ #define ASSIGN_hsize_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: hsize_t dst: int */
+
+/* src: hsize_t, dst: uint8_t */
+#if H5_SIZEOF_HSIZE_T < H5_SIZEOF_UINT8_T
+ #define ASSIGN_hsize_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSIZE_T > H5_SIZEOF_UINT8_T
+ #define ASSIGN_hsize_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSIZE_T == H5_SIZEOF_UINT8_T */
+ #define ASSIGN_hsize_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: hsize_t dst: uint8_t */
+
+/* src: hsize_t, dst: uint32_t */
+#if H5_SIZEOF_HSIZE_T < H5_SIZEOF_UINT32_T
+ #define ASSIGN_hsize_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSIZE_T > H5_SIZEOF_UINT32_T
+ #define ASSIGN_hsize_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSIZE_T == H5_SIZEOF_UINT32_T */
+ #define ASSIGN_hsize_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: hsize_t dst: uint32_t */
+
+/* src: hsize_t, dst: uint64_t */
+#if H5_SIZEOF_HSIZE_T < H5_SIZEOF_UINT64_T
+ #define ASSIGN_hsize_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSIZE_T > H5_SIZEOF_UINT64_T
+ #define ASSIGN_hsize_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSIZE_T == H5_SIZEOF_UINT64_T */
+ #define ASSIGN_hsize_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: hsize_t dst: uint64_t */
+
+/* src: hsize_t, dst: size_t */
+#if H5_SIZEOF_HSIZE_T < H5_SIZEOF_SIZE_T
+ #define ASSIGN_hsize_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSIZE_T > H5_SIZEOF_SIZE_T
+ #define ASSIGN_hsize_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSIZE_T == H5_SIZEOF_SIZE_T */
+ #define ASSIGN_hsize_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: hsize_t dst: size_t */
+
+/* src: hsize_t, dst: ssize_t */
+#if H5_SIZEOF_HSIZE_T < H5_SIZEOF_SSIZE_T
+ #define ASSIGN_hsize_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSIZE_T > H5_SIZEOF_SSIZE_T
+ #define ASSIGN_hsize_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSIZE_T == H5_SIZEOF_SSIZE_T */
+ #define ASSIGN_hsize_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: hsize_t dst: ssize_t */
+
+/* src: hsize_t, dst: haddr_t */
+#if H5_SIZEOF_HSIZE_T < H5_SIZEOF_HADDR_T
+ #define ASSIGN_hsize_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSIZE_T > H5_SIZEOF_HADDR_T
+ #define ASSIGN_hsize_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSIZE_T == H5_SIZEOF_HADDR_T */
+ #define ASSIGN_hsize_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: hsize_t dst: haddr_t */
+
+/* src: hsize_t, dst: hssize_t */
+#if H5_SIZEOF_HSIZE_T < H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_hsize_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSIZE_T > H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_hsize_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSIZE_T == H5_SIZEOF_HSSIZE_T */
+ #define ASSIGN_hsize_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: hsize_t dst: hssize_t */
+
+/* src: hsize_t, dst: h5_stat_size_t */
+#if H5_SIZEOF_HSIZE_T < H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_hsize_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSIZE_T > H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_hsize_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSIZE_T == H5_SIZEOF_H5_STAT_SIZE_T */
+ #define ASSIGN_hsize_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: hsize_t dst: h5_stat_size_t */
+
+
+/* Assignment checks for hssize_t */
+
+/* src: hssize_t, dst: unsigned */
+#if H5_SIZEOF_HSSIZE_T < H5_SIZEOF_UNSIGNED
+ #define ASSIGN_hssize_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSSIZE_T > H5_SIZEOF_UNSIGNED
+ #define ASSIGN_hssize_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSSIZE_T == H5_SIZEOF_UNSIGNED */
+ #define ASSIGN_hssize_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: hssize_t dst: unsigned */
+
+/* src: hssize_t, dst: int */
+#if H5_SIZEOF_HSSIZE_T < H5_SIZEOF_INT
+ #define ASSIGN_hssize_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSSIZE_T > H5_SIZEOF_INT
+ #define ASSIGN_hssize_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSSIZE_T == H5_SIZEOF_INT */
+ #define ASSIGN_hssize_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: hssize_t dst: int */
+
+/* src: hssize_t, dst: uint8_t */
+#if H5_SIZEOF_HSSIZE_T < H5_SIZEOF_UINT8_T
+ #define ASSIGN_hssize_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSSIZE_T > H5_SIZEOF_UINT8_T
+ #define ASSIGN_hssize_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSSIZE_T == H5_SIZEOF_UINT8_T */
+ #define ASSIGN_hssize_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: hssize_t dst: uint8_t */
+
+/* src: hssize_t, dst: uint32_t */
+#if H5_SIZEOF_HSSIZE_T < H5_SIZEOF_UINT32_T
+ #define ASSIGN_hssize_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSSIZE_T > H5_SIZEOF_UINT32_T
+ #define ASSIGN_hssize_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSSIZE_T == H5_SIZEOF_UINT32_T */
+ #define ASSIGN_hssize_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: hssize_t dst: uint32_t */
+
+/* src: hssize_t, dst: uint64_t */
+#if H5_SIZEOF_HSSIZE_T < H5_SIZEOF_UINT64_T
+ #define ASSIGN_hssize_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSSIZE_T > H5_SIZEOF_UINT64_T
+ #define ASSIGN_hssize_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSSIZE_T == H5_SIZEOF_UINT64_T */
+ #define ASSIGN_hssize_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: hssize_t dst: uint64_t */
+
+/* src: hssize_t, dst: size_t */
+#if H5_SIZEOF_HSSIZE_T < H5_SIZEOF_SIZE_T
+ #define ASSIGN_hssize_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSSIZE_T > H5_SIZEOF_SIZE_T
+ #define ASSIGN_hssize_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSSIZE_T == H5_SIZEOF_SIZE_T */
+ #define ASSIGN_hssize_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: hssize_t dst: size_t */
+
+/* src: hssize_t, dst: ssize_t */
+#if H5_SIZEOF_HSSIZE_T < H5_SIZEOF_SSIZE_T
+ #define ASSIGN_hssize_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSSIZE_T > H5_SIZEOF_SSIZE_T
+ #define ASSIGN_hssize_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSSIZE_T == H5_SIZEOF_SSIZE_T */
+ #define ASSIGN_hssize_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: hssize_t dst: ssize_t */
+
+/* src: hssize_t, dst: haddr_t */
+#if H5_SIZEOF_HSSIZE_T < H5_SIZEOF_HADDR_T
+ #define ASSIGN_hssize_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSSIZE_T > H5_SIZEOF_HADDR_T
+ #define ASSIGN_hssize_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSSIZE_T == H5_SIZEOF_HADDR_T */
+ #define ASSIGN_hssize_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: hssize_t dst: haddr_t */
+
+/* src: hssize_t, dst: hsize_t */
+#if H5_SIZEOF_HSSIZE_T < H5_SIZEOF_HSIZE_T
+ #define ASSIGN_hssize_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSSIZE_T > H5_SIZEOF_HSIZE_T
+ #define ASSIGN_hssize_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSSIZE_T == H5_SIZEOF_HSIZE_T */
+ #define ASSIGN_hssize_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: hssize_t dst: hsize_t */
+
+/* src: hssize_t, dst: h5_stat_size_t */
+#if H5_SIZEOF_HSSIZE_T < H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_hssize_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_HSSIZE_T > H5_SIZEOF_H5_STAT_SIZE_T
+ #define ASSIGN_hssize_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_HSSIZE_T == H5_SIZEOF_H5_STAT_SIZE_T */
+ #define ASSIGN_hssize_t_TO_h5_stat_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype)
+#endif /* src: hssize_t dst: h5_stat_size_t */
+
+
+/* Assignment checks for h5_stat_size_t */
+
+/* src: h5_stat_size_t, dst: unsigned */
+#if H5_SIZEOF_H5_STAT_SIZE_T < H5_SIZEOF_UNSIGNED
+ #define ASSIGN_h5_stat_size_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_H5_STAT_SIZE_T > H5_SIZEOF_UNSIGNED
+ #define ASSIGN_h5_stat_size_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_H5_STAT_SIZE_T == H5_SIZEOF_UNSIGNED */
+ #define ASSIGN_h5_stat_size_t_TO_unsigned(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: h5_stat_size_t dst: unsigned */
+
+/* src: h5_stat_size_t, dst: int */
+#if H5_SIZEOF_H5_STAT_SIZE_T < H5_SIZEOF_INT
+ #define ASSIGN_h5_stat_size_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_H5_STAT_SIZE_T > H5_SIZEOF_INT
+ #define ASSIGN_h5_stat_size_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_H5_STAT_SIZE_T == H5_SIZEOF_INT */
+ #define ASSIGN_h5_stat_size_t_TO_int(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: h5_stat_size_t dst: int */
+
+/* src: h5_stat_size_t, dst: uint8_t */
+#if H5_SIZEOF_H5_STAT_SIZE_T < H5_SIZEOF_UINT8_T
+ #define ASSIGN_h5_stat_size_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_H5_STAT_SIZE_T > H5_SIZEOF_UINT8_T
+ #define ASSIGN_h5_stat_size_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_H5_STAT_SIZE_T == H5_SIZEOF_UINT8_T */
+ #define ASSIGN_h5_stat_size_t_TO_uint8_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: h5_stat_size_t dst: uint8_t */
+
+/* src: h5_stat_size_t, dst: uint32_t */
+#if H5_SIZEOF_H5_STAT_SIZE_T < H5_SIZEOF_UINT32_T
+ #define ASSIGN_h5_stat_size_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_H5_STAT_SIZE_T > H5_SIZEOF_UINT32_T
+ #define ASSIGN_h5_stat_size_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_H5_STAT_SIZE_T == H5_SIZEOF_UINT32_T */
+ #define ASSIGN_h5_stat_size_t_TO_uint32_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: h5_stat_size_t dst: uint32_t */
+
+/* src: h5_stat_size_t, dst: uint64_t */
+#if H5_SIZEOF_H5_STAT_SIZE_T < H5_SIZEOF_UINT64_T
+ #define ASSIGN_h5_stat_size_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_H5_STAT_SIZE_T > H5_SIZEOF_UINT64_T
+ #define ASSIGN_h5_stat_size_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_H5_STAT_SIZE_T == H5_SIZEOF_UINT64_T */
+ #define ASSIGN_h5_stat_size_t_TO_uint64_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: h5_stat_size_t dst: uint64_t */
+
+/* src: h5_stat_size_t, dst: size_t */
+#if H5_SIZEOF_H5_STAT_SIZE_T < H5_SIZEOF_SIZE_T
+ #define ASSIGN_h5_stat_size_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_H5_STAT_SIZE_T > H5_SIZEOF_SIZE_T
+ #define ASSIGN_h5_stat_size_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_H5_STAT_SIZE_T == H5_SIZEOF_SIZE_T */
+ #define ASSIGN_h5_stat_size_t_TO_size_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: h5_stat_size_t dst: size_t */
+
+/* src: h5_stat_size_t, dst: ssize_t */
+#if H5_SIZEOF_H5_STAT_SIZE_T < H5_SIZEOF_SSIZE_T
+ #define ASSIGN_h5_stat_size_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_H5_STAT_SIZE_T > H5_SIZEOF_SSIZE_T
+ #define ASSIGN_h5_stat_size_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_H5_STAT_SIZE_T == H5_SIZEOF_SSIZE_T */
+ #define ASSIGN_h5_stat_size_t_TO_ssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: h5_stat_size_t dst: ssize_t */
+
+/* src: h5_stat_size_t, dst: haddr_t */
+#if H5_SIZEOF_H5_STAT_SIZE_T < H5_SIZEOF_HADDR_T
+ #define ASSIGN_h5_stat_size_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_H5_STAT_SIZE_T > H5_SIZEOF_HADDR_T
+ #define ASSIGN_h5_stat_size_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_H5_STAT_SIZE_T == H5_SIZEOF_HADDR_T */
+ #define ASSIGN_h5_stat_size_t_TO_haddr_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: h5_stat_size_t dst: haddr_t */
+
+/* src: h5_stat_size_t, dst: hsize_t */
+#if H5_SIZEOF_H5_STAT_SIZE_T < H5_SIZEOF_HSIZE_T
+ #define ASSIGN_h5_stat_size_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_H5_STAT_SIZE_T > H5_SIZEOF_HSIZE_T
+ #define ASSIGN_h5_stat_size_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_H5_STAT_SIZE_T == H5_SIZEOF_HSIZE_T */
+ #define ASSIGN_h5_stat_size_t_TO_hsize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: h5_stat_size_t dst: hsize_t */
+
+/* src: h5_stat_size_t, dst: hssize_t */
+#if H5_SIZEOF_H5_STAT_SIZE_T < H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_h5_stat_size_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#elif H5_SIZEOF_H5_STAT_SIZE_T > H5_SIZEOF_HSSIZE_T
+ #define ASSIGN_h5_stat_size_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype)
+#else /* H5_SIZEOF_H5_STAT_SIZE_T == H5_SIZEOF_HSSIZE_T */
+ #define ASSIGN_h5_stat_size_t_TO_hssize_t(dst, dsttype, src, srctype) \
+ ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype)
+#endif /* src: h5_stat_size_t dst: hssize_t */
+
+#endif /* H5overflow_H */
+
diff --git a/src/H5overflow.txt b/src/H5overflow.txt
new file mode 100644
index 0000000..ea62fa0
--- /dev/null
+++ b/src/H5overflow.txt
@@ -0,0 +1,43 @@
+# 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.
+#
+
+# This file is used to generate the headers that is needed for detecting
+# overflows between types at run-time
+#
+# The bin/make_overflow script reads in this file and creates the appropriate
+# file in the src/ directory when the generated header is out of date with
+# respect to this file.
+#
+# Blank lines and lines beginning with '#' are ignored
+#
+# The format of this file is as follows:
+# <type>, <SIGNED|UNSIGNED>;
+#
+# Where <type> is a valid C type (like 'int8_t', 'hssize_t', etc. and whether
+# the type is signed or unsigned follows.
+#
+# Programmer: Quincey Koziol
+# Creation Date: 2009/04/09
+
+unsigned, UNSIGNED;
+int, SIGNED;
+uint8_t, UNSIGNED;
+uint32_t, UNSIGNED;
+uint64_t, UNSIGNED;
+size_t, UNSIGNED;
+ssize_t, SIGNED;
+haddr_t, UNSIGNED;
+hsize_t, UNSIGNED;
+hssize_t, SIGNED;
+h5_stat_size_t, UNSIGNED;
diff --git a/src/H5private.h b/src/H5private.h
index 1f94104..c0b5054 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -144,6 +144,7 @@
#define VC_EXTRALEAN /*Exclude rarely-used stuff from Windows headers */
#include <windows.h>
+#include <direct.h> /* For _getcwd() */
#endif /*_WIN32*/
@@ -313,6 +314,9 @@
/* (from: http://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2) */
# define POWER_OF_TWO(n) (!(n & (n - 1)) && n)
+/* Raise an integer to a power of 2 */
+# define H5_EXP2(n) (1 << (n))
+
/*
* HDF Boolean type.
*/
@@ -401,12 +405,12 @@
* most part.
*/
#ifndef LLONG_MAX
-# define LLONG_MAX ((long_long)(((unsigned long_long)1 \
- <<(8*sizeof(long_long)-1))-1))
-# define LLONG_MIN ((long_long)(-LLONG_MAX)-1)
+# define LLONG_MAX ((long long)(((unsigned long long)1 \
+ <<(8*sizeof(long long)-1))-1))
+# define LLONG_MIN ((long long)(-LLONG_MAX)-1)
#endif
#ifndef ULLONG_MAX
-# define ULLONG_MAX ((unsigned long_long)((long_long)(-1)))
+# define ULLONG_MAX ((unsigned long long)((long long)(-1)))
#endif
#ifndef SIZET_MAX
# define SIZET_MAX ((size_t)(ssize_t)(-1))
@@ -435,35 +439,6 @@
#endif
/*
- * A macro for detecting over/under-flow when casting between types
- */
-#ifndef NDEBUG
-#define H5_CHECK_OVERFLOW(var, vartype, casttype) \
-{ \
- casttype _tmp_overflow = (casttype)(var); \
- assert((var) == (vartype)_tmp_overflow); \
-}
-#else /* NDEBUG */
-#define H5_CHECK_OVERFLOW(var, vartype, casttype)
-#endif /* NDEBUG */
-
-/*
- * A macro for detecting over/under-flow when assigning between types
- */
-#ifndef NDEBUG
-#define H5_ASSIGN_OVERFLOW(dst, src, srctype, dsttype) \
-{ \
- srctype _tmp_overflow = (srctype)(src); \
- dsttype _tmp_overflow2 = (dsttype)(_tmp_overflow); \
- assert((dsttype)_tmp_overflow == _tmp_overflow2); \
- (dst) = _tmp_overflow2; \
-}
-#else /* NDEBUG */
-#define H5_ASSIGN_OVERFLOW(dst, src, srctype, dsttype) \
- (dst) = (dsttype)(src);
-#endif /* NDEBUG */
-
-/*
* Data types and functions for timing certain parts of the library.
*/
typedef struct {
@@ -485,6 +460,11 @@ typedef enum {
H5_COPY_DEEP /* Deep copy from source to destination, including duplicating fields pointed to */
} H5_copy_depth_t;
+/* Common object copying udata (right now only used for groups and datasets) */
+typedef struct H5O_copy_file_ud_common_t {
+ struct H5O_pline_t *src_pline; /* Copy of filter pipeline for object */
+} H5O_copy_file_ud_common_t;
+
/* Unique object "position" */
typedef struct {
unsigned long fileno; /* The unique identifier for the file of the object */
@@ -495,7 +475,7 @@ typedef struct {
* Redefine all the POSIX functions. We should never see a POSIX
* function (or any other non-HDF5 function) in the source!
*/
-
+
/* Use platform-specific versions if necessary */
#include "H5win32defs.h"
@@ -503,7 +483,7 @@ typedef struct {
#define HDabort() abort()
#endif /* HDabort */
#ifndef HDabs
- #define HDabs(X) abs(X)
+ #define HDabs(X) abs(X)
#endif /* HDabs */
#ifndef HDaccess
#define HDaccess(F,M) access(F, M)
@@ -645,6 +625,9 @@ typedef struct {
#ifndef HDexp
#define HDexp(X) exp(X)
#endif /* HDexp */
+#ifndef HDexp2
+ #define HDexp2(X) exp2(X)
+#endif /* HDexp2 */
#ifndef HDfabs
#define HDfabs(X) fabs(X)
#endif /* HDfabs */
@@ -747,25 +730,33 @@ H5_DLL int HDfprintf (FILE *stream, const char *fmt, ...);
* For Unix, if off_t is not 64bit big, try use the pseudo-standard
* xxx64 versions if available.
*/
-#if !defined(HDfstat) || !defined(HDstat)
+#if !defined(HDfstat) || !defined(HDstat) || !defined(HDlstat)
#if H5_SIZEOF_OFF_T!=8 && H5_SIZEOF_OFF64_T==8 && defined(H5_HAVE_STAT64)
#ifndef HDfstat
#define HDfstat(F,B) fstat64(F,B)
#endif /* HDfstat */
+ #ifndef HDlstat
+ #define HDlstat(S,B) lstat64(S,B)
+ #endif /* HDlstat */
#ifndef HDstat
#define HDstat(S,B) stat64(S,B)
#endif /* HDstat */
typedef struct stat64 h5_stat_t;
typedef off64_t h5_stat_size_t;
+ #define H5_SIZEOF_H5_STAT_SIZE_T H5_SIZEOF_OFF64_T
#else /* H5_SIZEOF_OFF_T!=8 && ... */
#ifndef HDfstat
#define HDfstat(F,B) fstat(F,B)
#endif /* HDfstat */
+ #ifndef HDlstat
+ #define HDlstat(S,B) lstat(S,B)
+ #endif /* HDlstat */
#ifndef HDstat
#define HDstat(S,B) stat(S,B)
#endif /* HDstat */
typedef struct stat h5_stat_t;
typedef off_t h5_stat_size_t;
+ #define H5_SIZEOF_H5_STAT_SIZE_T H5_SIZEOF_OFF_T
#endif /* H5_SIZEOF_OFF_T!=8 && ... */
#endif /* !defined(HDfstat) || !defined(HDstat) */
@@ -773,7 +764,11 @@ H5_DLL int HDfprintf (FILE *stream, const char *fmt, ...);
#define HDftell(F) ftell(F)
#endif /* HDftell */
#ifndef HDftruncate
+ #ifdef H5_HAVE_FTRUNCATE64
+ #define HDftruncate(F,L) ftruncate64(F,L)
+ #else
#define HDftruncate(F,L) ftruncate(F,L)
+ #endif
#endif /* HDftruncate */
#ifndef HDfwrite
#define HDfwrite(M,Z,N,F) fwrite(M,Z,N,F)
@@ -914,7 +909,7 @@ H5_DLL int HDfprintf (FILE *stream, const char *fmt, ...);
#define HDlongjmp(J,N) longjmp(J,N)
#endif /* HDlongjmp */
#ifndef HDlseek
- #ifdef H5_HAVE_FSEEK64
+ #ifdef H5_HAVE_LSEEK64
#define HDlseek(F,O,W) lseek64(F,O,W)
#else
#define HDlseek(F,O,W) lseek(F,O,W)
@@ -1038,6 +1033,9 @@ H5_DLL int HDfprintf (FILE *stream, const char *fmt, ...);
#ifndef HDrealloc
#define HDrealloc(M,Z) realloc(M,Z)
#endif /* HDrealloc */
+#ifndef HDrealpath
+ #define HDrealpath(F1,F2) realpath(F1,F2)
+#endif /* HDrealloc */
#ifdef H5_VMS
#ifdef __cplusplus
extern "C" {
@@ -1091,9 +1089,6 @@ H5_DLL int HDfprintf (FILE *stream, const char *fmt, ...);
#ifndef HDsetvbuf
#define HDsetvbuf(F,S,M,Z) setvbuf(F,S,M,Z)
#endif /* HDsetvbuf */
-#ifndef HDsigaction
- #define HDsigaction(N,A) sigaction(N,A)
-#endif /* HDsigaction */
#ifndef HDsigaddset
#define HDsigaddset(S,N) sigaddset(S,N)
#endif /* HDsigaddset */
@@ -1172,8 +1167,11 @@ H5_DLL int HDfprintf (FILE *stream, const char *fmt, ...);
#define HDstrchr(S,C) strchr(S,C)
#endif /* HDstrchr */
#ifndef HDstrcmp
- #define HDstrcmp(X,Y) strcmp(X,Y)
+ #define HDstrcmp(X,Y) strcmp(X,Y)
#endif /* HDstrcmp */
+#ifndef HDstrcasecmp
+ #define HDstrcasecmp(X,Y) strcasecmp(X,Y)
+#endif /* HDstrcasecmp */
#ifndef HDstrcoll
#define HDstrcoll(X,Y) strcoll(X,Y)
#endif /* HDstrcoll */
@@ -1226,9 +1224,17 @@ H5_DLL int64_t HDstrtoll (const char *s, const char **rest, int base);
#ifndef HDstrtoul
#define HDstrtoul(S,R,N) strtoul(S,R,N)
#endif /* HDstrtoul */
+#ifndef HDstrtoull
+ #define HDstrtoull(S,R,N) strtoull(S,R,N)
+#endif /* HDstrtoul */
#ifndef HDstrxfrm
#define HDstrxfrm(X,Y,Z) strxfrm(X,Y,Z)
#endif /* HDstrxfrm */
+#ifdef H5_HAVE_SYMLINK
+ #ifndef HDsymlink
+ #define HDsymlink(F1,F2) symlink(F1,F2)
+ #endif /* HDsymlink */
+#endif /* H5_HAVE_SYMLINK */
#ifndef HDsysconf
#define HDsysconf(N) sysconf(N)
#endif /* HDsysconf */
@@ -1365,8 +1371,79 @@ extern char *strdup(const char *s);
#define HDpthread_self_ulong() ((unsigned long)pthread_self())
#endif /* HDpthread_self_ulong */
+/*
+ * A macro for detecting over/under-flow when casting between types
+ */
+#ifndef NDEBUG
+#define H5_CHECK_OVERFLOW(var, vartype, casttype) \
+{ \
+ casttype _tmp_overflow = (casttype)(var); \
+ assert((var) == (vartype)_tmp_overflow); \
+}
+#else /* NDEBUG */
+#define H5_CHECK_OVERFLOW(var, vartype, casttype)
+#endif /* NDEBUG */
+
+/*
+ * A macro for detecting over/under-flow when assigning between types
+ */
+#ifndef NDEBUG
+#define ASSIGN_TO_SMALLER_SIZE(dst, dsttype, src, srctype) \
+{ \
+ srctype _tmp_src = (srctype)(src); \
+ dsttype _tmp_dst = (dsttype)(_tmp_src); \
+ assert(_tmp_src == (srctype)_tmp_dst); \
+ (dst) = _tmp_dst; \
+}
+
+#define ASSIGN_TO_LARGER_SIZE_SAME_SIGNED(dst, dsttype, src, srctype) \
+ (dst) = (dsttype)(src);
+
+#define ASSIGN_TO_LARGER_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype) \
+{ \
+ srctype _tmp_src = (srctype)(src); \
+ dsttype _tmp_dst = (dsttype)(_tmp_src); \
+ assert(_tmp_src >= 0); \
+ assert(_tmp_src == _tmp_dst); \
+ (dst) = _tmp_dst; \
+}
+
+#define ASSIGN_TO_LARGER_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype) \
+ (dst) = (dsttype)(src);
+
+#define ASSIGN_TO_SAME_SIZE_UNSIGNED_TO_SIGNED(dst, dsttype, src, srctype) \
+{ \
+ srctype _tmp_src = (srctype)(src); \
+ dsttype _tmp_dst = (dsttype)(_tmp_src); \
+ assert(_tmp_dst >= 0); \
+ assert(_tmp_src == (srctype)_tmp_dst); \
+ (dst) = _tmp_dst; \
+}
+
+#define ASSIGN_TO_SAME_SIZE_SIGNED_TO_UNSIGNED(dst, dsttype, src, srctype) \
+{ \
+ srctype _tmp_src = (srctype)(src); \
+ dsttype _tmp_dst = (dsttype)(_tmp_src); \
+ assert(_tmp_src >= 0); \
+ assert(_tmp_src == (srctype)_tmp_dst); \
+ (dst) = _tmp_dst; \
+}
+
+#define ASSIGN_TO_SAME_SIZE_SAME_SIGNED(dst, dsttype, src, srctype) \
+ (dst) = (dsttype)(src);
+
+/* Include the generated overflow header file */
+#include "H5overflow.h"
-#ifdef H5_HAVE_WINDOW_PATH
+#define H5_ASSIGN_OVERFLOW(dst, src, srctype, dsttype) \
+ H5_GLUE4(ASSIGN_,srctype,_TO_,dsttype)(dst,dsttype,src,srctype)\
+
+#else /* NDEBUG */
+#define H5_ASSIGN_OVERFLOW(dst, src, srctype, dsttype) \
+ (dst) = (dsttype)(src);
+#endif /* NDEBUG */
+
+#if defined(H5_HAVE_WINDOW_PATH)
/* directory delimiter for Windows: slash and backslash are acceptable on Windows */
#define DIR_SLASH_SEPC '/'
@@ -1387,6 +1464,18 @@ extern char *strdup(const char *s);
(ptr = slash); \
}
+#elif defined(H5_HAVE_VMS_PATH)
+
+/* OpenVMS pathname: <disk name>$<partition>:[path]<file name>
+ * i.g. SYS$SYSUSERS:[LU.HDF5.SRC]H5system.c */
+#define DIR_SEPC '.'
+#define DIR_SEPS "."
+#define CHECK_DELIMITER(SS) (SS == DIR_SEPC)
+#define CHECK_ABSOLUTE(NAME) (strrchr(NAME, ':') && strrchr(NAME, '['))
+#define CHECK_ABS_DRIVE(NAME) (0)
+#define CHECK_ABS_PATH(NAME) (0)
+#define GET_LAST_DELIMITER(NAME, ptr) ptr = strrchr(NAME, ']');
+
#else
#define DIR_SEPC '/'
@@ -1400,7 +1489,6 @@ extern char *strdup(const char *s);
#endif
#define COLON_SEPC ':'
-H5_DLL herr_t H5_build_extpath(const char *, char ** /*out*/ );
/*
@@ -1447,6 +1535,7 @@ typedef struct H5_debug_t {
extern H5_debug_t H5_debug_g;
#define H5DEBUG(X) (H5_debug_g.pkg[H5_PKG_##X].stream)
+extern char H5libhdf5_settings[]; /* embedded library information */
/*-------------------------------------------------------------------------
* Purpose: These macros are inserted automatically just after the
@@ -1612,8 +1701,8 @@ extern hbool_t H5_libinit_g; /* Has the library been initialized? */
/* Include required function stack header */
#include "H5CSprivate.h"
-#define H5_PUSH_FUNC(func_name) H5CS_push(#func_name)
-#define H5_POP_FUNC H5CS_pop()
+#define H5_PUSH_FUNC(func_name) H5CS_push(func_name);
+#define H5_POP_FUNC H5CS_pop();
#else /* H5_HAVE_CODESTACK */
#define H5_PUSH_FUNC(func_name) /* void */
#define H5_POP_FUNC /* void */
@@ -1669,9 +1758,14 @@ static herr_t H5_INTERFACE_INIT_FUNC(void);
#define FUNC_ENTER_COMMON_NOFUNC(func_name,asrt)
#endif /* NDEBUG */
-#define FUNC_ENTER_COMMON(func_name,asrt) \
- static const char FUNC[]=#func_name; \
- FUNC_ENTER_COMMON_NOFUNC(func_name,asrt);
+#define FUNC_ENTER_COMMON(func_name, asrt) \
+ static const char FUNC[] = #func_name; \
+ hbool_t err_occurred = FALSE; \
+ FUNC_ENTER_COMMON_NOFUNC(func_name, asrt);
+
+#define FUNC_ENTER_COMMON_NOERR(func_name, asrt) \
+ static const char FUNC[] = #func_name; \
+ FUNC_ENTER_COMMON_NOFUNC(func_name, asrt);
/* Threadsafety initialization code for API routines */
#define FUNC_ENTER_API_THREADSAFE \
@@ -1682,22 +1776,37 @@ static herr_t H5_INTERFACE_INIT_FUNC(void);
H5_API_UNSET_CANCEL \
H5_API_LOCK
-/* Threadsafety termination code for API routines */
-#define FUNC_LEAVE_API_THREADSAFE \
- H5_API_UNLOCK \
- H5_API_SET_CANCEL
-
/* Local variables for API routines */
#define FUNC_ENTER_API_VARS(func_name) \
MPE_LOG_VARS(func_name) \
H5TRACE_DECL
+#define FUNC_ENTER_API_COMMON(func_name) \
+ FUNC_ENTER_API_VARS(func_name) \
+ FUNC_ENTER_COMMON(func_name, H5_IS_API(#func_name)); \
+ FUNC_ENTER_API_THREADSAFE;
+
+#define FUNC_ENTER_API_INIT(func_name,err) \
+ /* Initialize the library */ \
+ if(!(H5_INIT_GLOBAL)) { \
+ H5_INIT_GLOBAL = TRUE; \
+ if(H5_init_library() < 0) \
+ HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, err, \
+ "library initialization failed") \
+ } \
+ \
+ /* Initialize the interface, if appropriate */ \
+ H5_INTERFACE_INIT(err) \
+ \
+ /* Push the name of this function on the function stack */ \
+ H5_PUSH_FUNC(#func_name) \
+ \
+ BEGIN_MPE_LOG(func_name)
+
/* Use this macro for all "normal" API functions */
#define FUNC_ENTER_API(func_name,err) {{ \
- FUNC_ENTER_API_VARS(func_name) \
- FUNC_ENTER_COMMON(func_name,H5_IS_API(#func_name)); \
- FUNC_ENTER_API_THREADSAFE; \
- FUNC_ENTER_API_COMMON(func_name,err); \
+ FUNC_ENTER_API_COMMON(func_name) \
+ FUNC_ENTER_API_INIT(func_name,err); \
/* Clear thread error stack entering public functions */ \
H5E_clear_stack(NULL); \
{
@@ -1707,10 +1816,8 @@ static herr_t H5_INTERFACE_INIT_FUNC(void);
* like H5Eprint and H5Ewalk.
*/
#define FUNC_ENTER_API_NOCLEAR(func_name,err) {{ \
- FUNC_ENTER_API_VARS(func_name) \
- FUNC_ENTER_COMMON(func_name,H5_IS_API(#func_name)); \
- FUNC_ENTER_API_THREADSAFE; \
- FUNC_ENTER_API_COMMON(func_name,err); \
+ FUNC_ENTER_API_COMMON(func_name) \
+ FUNC_ENTER_API_INIT(func_name,err); \
{
/*
@@ -1720,10 +1827,8 @@ static herr_t H5_INTERFACE_INIT_FUNC(void);
*
*/
#define FUNC_ENTER_API_NOINIT(func_name) {{ \
- FUNC_ENTER_API_VARS(func_name) \
- FUNC_ENTER_COMMON(func_name,H5_IS_API(#func_name)); \
- FUNC_ENTER_API_THREADSAFE; \
- H5_PUSH_FUNC(func_name); \
+ FUNC_ENTER_API_COMMON(func_name) \
+ H5_PUSH_FUNC(#func_name) \
BEGIN_MPE_LOG(func_name); \
{
@@ -1734,16 +1839,30 @@ static herr_t H5_INTERFACE_INIT_FUNC(void);
* are: H5close, H5check_version, etc.
*
*/
-#define FUNC_ENTER_API_NOINIT_NOFS(func_name) {{ \
+#define FUNC_ENTER_API_NOINIT_NOERR_NOFS(func_name) {{ \
FUNC_ENTER_API_VARS(func_name) \
- FUNC_ENTER_COMMON(func_name,H5_IS_API(#func_name)); \
- FUNC_ENTER_API_THREADSAFE; \
+ FUNC_ENTER_COMMON_NOERR(func_name, H5_IS_API(#func_name)); \
+ FUNC_ENTER_API_THREADSAFE; \
BEGIN_MPE_LOG(func_name); \
{
+/* Note: this macro only works when there's _no_ interface initialization routine for the module */
+#define FUNC_ENTER_NOAPI_INIT(func_name,err) \
+ /* Initialize the interface, if appropriate */ \
+ H5_INTERFACE_INIT(err) \
+ \
+ /* Push the name of this function on the function stack */ \
+ H5_PUSH_FUNC(#func_name)
+
/* Use this macro for all "normal" non-API functions */
#define FUNC_ENTER_NOAPI(func_name,err) { \
- FUNC_ENTER_COMMON(func_name,!H5_IS_API(#func_name)); \
+ FUNC_ENTER_COMMON(func_name, !H5_IS_API(#func_name)); \
+ FUNC_ENTER_NOAPI_INIT(func_name,err) \
+ {
+
+/* Use this macro for all non-API functions, which propagate errors, but don't issue them */
+#define FUNC_ENTER_NOAPI_NOERR(func_name,err) { \
+ FUNC_ENTER_COMMON_NOERR(func_name, !H5_IS_API(#func_name)); \
FUNC_ENTER_NOAPI_INIT(func_name,err) \
{
@@ -1761,9 +1880,23 @@ static herr_t H5_INTERFACE_INIT_FUNC(void);
* - functions which are called during library shutdown, since we don't
* want to re-initialize the library.
*/
-#define FUNC_ENTER_NOAPI_NOINIT(func_name) { \
- FUNC_ENTER_COMMON(func_name,!H5_IS_API(#func_name)); \
- H5_PUSH_FUNC(func_name); \
+#define FUNC_ENTER_NOAPI_NOINIT(func_name) { \
+ FUNC_ENTER_COMMON(func_name, !H5_IS_API(#func_name)); \
+ H5_PUSH_FUNC(#func_name) \
+ {
+
+/*
+ * Use this macro for non-API functions which fall into these categories:
+ * - static functions, since they must be called from a function in the
+ * interface, the library and interface must already be
+ * initialized.
+ * - functions which are called during library shutdown, since we don't
+ * want to re-initialize the library.
+ * - functions that propagate, but don't issue errors
+ */
+#define FUNC_ENTER_NOAPI_NOINIT_NOERR(func_name) { \
+ FUNC_ENTER_COMMON_NOERR(func_name, !H5_IS_API(#func_name)); \
+ H5_PUSH_FUNC(#func_name) \
{
/*
@@ -1780,7 +1913,7 @@ static herr_t H5_INTERFACE_INIT_FUNC(void);
*/
#define FUNC_ENTER_NOAPI_NOINIT_NOFUNC(func_name) { \
FUNC_ENTER_COMMON_NOFUNC(func_name,!H5_IS_API(#func_name)); \
- H5_PUSH_FUNC(func_name); \
+ H5_PUSH_FUNC(#func_name) \
{
/*
@@ -1796,31 +1929,6 @@ static herr_t H5_INTERFACE_INIT_FUNC(void);
FUNC_ENTER_COMMON_NOFUNC(func_name,!H5_IS_API(#func_name)); \
{
-#define FUNC_ENTER_API_COMMON(func_name,err) \
- /* Initialize the library */ \
- if (!(H5_INIT_GLOBAL)) { \
- H5_INIT_GLOBAL = TRUE; \
- if (H5_init_library()<0) \
- HGOTO_ERROR (H5E_FUNC, H5E_CANTINIT, err, \
- "library initialization failed") \
- } \
- \
- /* Initialize the interface, if appropriate */ \
- H5_INTERFACE_INIT(err) \
- \
- /* Push the name of this function on the function stack */ \
- H5_PUSH_FUNC(func_name); \
- \
- BEGIN_MPE_LOG(func_name)
-
-/* Note: this macro only works when there's _no_ interface initialization routine for the module */
-#define FUNC_ENTER_NOAPI_INIT(func_name,err) \
- /* Initialize the interface, if appropriate */ \
- H5_INTERFACE_INIT(err) \
- \
- /* Push the name of this function on the function stack */ \
- H5_PUSH_FUNC(func_name);
-
/*-------------------------------------------------------------------------
* Purpose: Register function exit for code profiling. This should be
* the last statement executed by a function.
@@ -1829,12 +1937,19 @@ static herr_t H5_INTERFACE_INIT_FUNC(void);
*
*-------------------------------------------------------------------------
*/
+/* Threadsafety termination code for API routines */
+#define FUNC_LEAVE_API_THREADSAFE \
+ H5_API_UNLOCK \
+ H5_API_SET_CANCEL
+
#define FUNC_LEAVE_API(ret_value) \
FINISH_MPE_LOG; \
H5TRACE_RETURN(ret_value); \
- H5_POP_FUNC; \
+ H5_POP_FUNC \
+ if(err_occurred) \
+ (void)H5E_dump_api_stack(TRUE); \
FUNC_LEAVE_API_THREADSAFE \
- return (ret_value); \
+ return(ret_value); \
} /*end scope from end of FUNC_ENTER*/ \
}} /*end scope from beginning of FUNC_ENTER*/
@@ -1843,18 +1958,18 @@ static herr_t H5_INTERFACE_INIT_FUNC(void);
FINISH_MPE_LOG; \
H5TRACE_RETURN(ret_value); \
FUNC_LEAVE_API_THREADSAFE \
- return (ret_value); \
+ return(ret_value); \
} /*end scope from end of FUNC_ENTER*/ \
}} /*end scope from beginning of FUNC_ENTER*/
#define FUNC_LEAVE_NOAPI(ret_value) \
- H5_POP_FUNC; \
- return (ret_value); \
+ H5_POP_FUNC \
+ return(ret_value); \
} /*end scope from end of FUNC_ENTER*/ \
} /*end scope from beginning of FUNC_ENTER*/
#define FUNC_LEAVE_NOAPI_VOID \
- H5_POP_FUNC; \
+ H5_POP_FUNC \
return; \
} /*end scope from end of FUNC_ENTER*/ \
} /*end scope from beginning of FUNC_ENTER*/
@@ -1865,14 +1980,283 @@ static herr_t H5_INTERFACE_INIT_FUNC(void);
* (so far, just the H5CS routines themselves)
*/
#define FUNC_LEAVE_NOAPI_NOFS(ret_value) \
- return (ret_value); \
+ return(ret_value); \
} /*end scope from end of FUNC_ENTER*/ \
} /*end scope from beginning of FUNC_ENTER*/
+/****************************************/
+/* Revisions to FUNC_ENTER/LEAVE Macros */
+/****************************************/
+
+/* `S' is the name of a function which is being tested to check if it's */
+/* a public API function */
+#define H5_IS_PUB(S) (((HDisdigit(S[1]) || HDisupper(S[1])) && HDislower(S[2])) || \
+ ((HDisdigit(S[2]) || HDisupper(S[2])) && HDislower(S[3])) || \
+ (!S[4] || ((HDisdigit(S[3]) || HDisupper(S[3])) && HDislower(S[4]))))
+
+/* `S' is the name of a function which is being tested to check if it's */
+/* a private library function */
+#define H5_IS_PRIV(S) (((HDisdigit(S[1]) || HDisupper(S[1])) && '_' == S[2] && HDislower(S[3])) || \
+ ((HDisdigit(S[2]) || HDisupper(S[2])) && '_' == S[3] && HDislower(S[4])) || \
+ ((HDisdigit(S[3]) || HDisupper(S[3])) && '_' == S[4] && HDislower(S[5])))
+
+/* `S' is the name of a function which is being tested to check if it's */
+/* a package private function */
+#define H5_IS_PKG(S) (((HDisdigit(S[1]) || HDisupper(S[1])) && '_' == S[2] && '_' == S[3] && HDislower(S[4])) || \
+ ((HDisdigit(S[2]) || HDisupper(S[2])) && '_' == S[3] && '_' == S[4] && HDislower(S[5])) || \
+ ((HDisdigit(S[3]) || HDisupper(S[3])) && '_' == S[4] && '_' == S[5] && HDislower(S[6])))
+
+#ifndef NDEBUG
+#define FUNC_ENTER_NAME_CHECK(asrt) \
+ { \
+ static hbool_t func_check = FALSE; \
+ \
+ if(!func_check) { \
+ /* Check function naming status */ \
+ HDassert(asrt); \
+ \
+ /* Don't check again */ \
+ func_check = TRUE; \
+ } /* end if */ \
+ } /* end scope */
+#else /* NDEBUG */
+#define FUNC_ENTER_NAME_CHECK(asrt)
+#endif /* NDEBUG */
+
+/* Macros for referencing package initialization symbols */
+#define H5_PACKAGE_INIT_VAR(x) H5_GLUE3(H5_, x, _init_g)
+#define H5_PACKAGE_INIT_FUNC(x) H5_GLUE(x, __pkg_init)
+
+/* Macros to check if a package is initialized */
+#define H5_CHECK_PACKAGE_INIT_REG_YES(asrt) HDassert(H5_PACKAGE_INIT_VAR(pkg));
+#define H5_CHECK_PACKAGE_INIT_REG_NO(asrt)
+#define H5_CHECK_PACKAGE_INIT_INIT_YES(asrt)
+#define H5_CHECK_PACKAGE_INIT_INIT_NO(asrt)
+
+/* Macros to initialize package, if a package initialization routine is defined */
+#define H5_PKG_YES_INIT(pkg) \
+ if(!H5_PACKAGE_INIT_VAR(pkg)) { \
+ if(H5_GLUE(pkg, _pkg_init)() < 0) { \
+ /* (Can't use H5E_THROW here) */ \
+ H5E_PRINTF(H5E_CANTINIT, "interface initialization failed"); \
+ ret_value = fail_value; \
+ goto func_init_failed; \
+ } /* end if */ \
+ } /* end if */
+#define H5_PKG_NO_INIT(pkg)
+
+/* Macros to declare package initialization symbols, if a package initialization routine is defined */
+#define H5_PKG_YES_INIT_VAR(pkg) extern hbool_t H5_PACKAGE_INIT_VAR(H5_MY_PKG);
+#define H5_PKG_NO_INIT_VAR(pkg)
+#define H5_PKG_YES_INIT_FUNC(pkg) extern herr_t H5_PACKAGE_INIT_FUNC(pkg)(void);
+#define H5_PKG_NO_INIT_FUNC(pkg)
+
+/* Declare package initialization symbols (if in a package) */
+#define H5_DECLARE_PKG_VAR(pkg_init, pkg) H5_GLUE3(H5_PKG_, pkg_init, _INIT_VAR)(pkg)
+#define H5_DECLARE_PKG_FUNC(pkg_init, pkg) H5_GLUE3(H5_PKG_, pkg_init, _INIT_FUNC)(pkg)
+#ifdef H5_MY_PKG
+H5_DECLARE_PKG_VAR(H5_MY_PKG_INIT, H5_MY_PKG)
+H5_DECLARE_PKG_FUNC(H5_MY_PKG_INIT, H5_MY_PKG)
+#endif /* H5_MY_PKG */
+
+/* API re-entrance variable */
+extern hbool_t H5_api_entered_g; /* Has library already been entered through API? */
+
+/* Use FUNCNAME to safely handle variations of C99 __func__ keyword handling */
+#ifdef H5_HAVE_C99_FUNC
+#define FUNCNAME __func__
+#elif defined(H5_HAVE_FUNCTION)
+#define FUNCNAME __FUNCTION__
+#else
+#error "We need __func__ or __FUNCTION__ to test function names!"
+#endif
+
+/* Macros for entering different scopes of routines */
+#define H5_PACKAGE_ENTER(pkg, pkg_init, init) \
+ FUNC_ENTER_NAME_CHECK(H5_IS_PKG(FUNCNAME)) \
+ \
+ /* The library should be initialized already */ \
+ HDassert(H5_INIT_GLOBAL); \
+ \
+ /* This interface should be initialized already */ \
+ /* (except for package initialization routines :-) */ \
+ H5_GLUE4(H5_CHECK_PACKAGE_INIT_, init, _, pkg_init)(pkg) \
+ \
+ /* Push the name of this function on the function stack */ \
+ H5_PUSH_FUNC(FUNCNAME) \
+ \
+ /* Enter scope for this type of function */ \
+ {
+
+#define H5_PRIVATE_ENTER(pkg, pkg_init) \
+ FUNC_ENTER_NAME_CHECK(H5_IS_PRIV(FUNCNAME)) \
+ \
+ /* The library should be initialized already */ \
+ HDassert(H5_INIT_GLOBAL); \
+ \
+ /* Initialize this interface if desired */ \
+ H5_GLUE3(H5_PKG_, pkg_init, _INIT)(pkg) \
+ \
+ /* Push the name of this function on the function stack */ \
+ H5_PUSH_FUNC(FUNCNAME) \
+ \
+ /* Enter scope for this type of function */ \
+ {{
+
+#define H5_PUBLIC_ENTER(pkg, pkg_init) \
+ FUNC_ENTER_API_VARS(FUNCNAME) \
+ FUNC_ENTER_API_THREADSAFE; \
+ FUNC_ENTER_NAME_CHECK(H5_IS_PUB(FUNCNAME)) \
+ \
+ /* Clear thread error stack when entering public functions */ \
+ H5E_clear_stack(NULL); \
+ \
+ /* Initialize the library or bust */ \
+ if(!(H5_INIT_GLOBAL)) { \
+ H5_INIT_GLOBAL = TRUE; \
+ if(H5_init_library() < 0) { \
+ /* (Can't use H5E_THROW here) */ \
+ H5E_PRINTF(H5E_CANTINIT, "interface initialization failed"); \
+ ret_value = fail_value; \
+ goto func_init_failed; \
+ } /* end if */ \
+ } /* end if */ \
+ \
+ /* Initialize this interface if desired */ \
+ H5_GLUE3(H5_PKG_, pkg_init, _INIT)(pkg) \
+ \
+ /* Check for re-entering API routine */ \
+ HDassert(!H5_api_entered_g); \
+ H5_api_entered_g = TRUE; \
+ \
+ /* Start logging MPI's MPE information */ \
+ BEGIN_MPE_LOG(FUNCNAME) \
+ \
+ /* Push the name of this function on the function stack */ \
+ H5_PUSH_FUNC(FUNCNAME) \
+ \
+ /* Enter scope for this type of function */ \
+ {{{
+
+/* Macros for substituting the package name */
+#define FUNC_ENTER_STATIC H5_PACKAGE_ENTER(H5_MY_PKG, H5_MY_PKG_INIT, REG)
+#define FUNC_ENTER_PKGINIT H5_PACKAGE_ENTER(H5_MY_PKG, H5_MY_PKG_INIT, INIT)
+#define FUNC_ENTER_PKG H5_PACKAGE_ENTER(H5_MY_PKG, H5_MY_PKG_INIT, REG)
+#define FUNC_ENTER_PRIV H5_PRIVATE_ENTER(H5_MY_PKG, H5_MY_PKG_INIT)
+#define FUNC_ENTER_PUB H5_PUBLIC_ENTER(H5_MY_PKG, H5_MY_PKG_INIT)
+
+/* Macros for substituting a function prefix */
+#define FUNC_PREFIX_STATIC static
+#define FUNC_PREFIX_PKGINIT
+#define FUNC_PREFIX_PKG
+#define FUNC_PREFIX_PRIV
+#define FUNC_PREFIX_PUB
+
+/* Macros for declaring error variables */
+#define FUNC_ERR_VAR_ERR(ret_typ, err) \
+ hbool_t past_catch = FALSE; \
+ ret_typ fail_value = err;
+#define FUNC_ERR_VAR_ERRCATCH(ret_typ, err) \
+ hbool_t past_catch = FALSE;
+#define FUNC_ERR_VAR_NOERR(ret_typ, err)
+
+/* Use this macro when entering all functions */
+#define BEGIN_FUNC(scope, use_err, ret_typ, ret_init, err, func) \
+H5_GLUE(FUNC_PREFIX_, scope) \
+ret_typ \
+func \
+/* Open function */ \
+{ \
+ ret_typ ret_value = ret_init; \
+ H5_GLUE(FUNC_ERR_VAR_, use_err)(ret_typ, err) \
+ H5_GLUE(FUNC_ENTER_, scope)
+
+/* Macros for label when a function initialization can fail */
+#define H5_PRIV_YES_FUNC_INIT_FAILED func_init_failed:
+#define H5_PRIV_NO_FUNC_INIT_FAILED
+#define H5_PRIV_FUNC_INIT_FAILED(pkg_init) H5_GLUE3(H5_PRIV_, pkg_init, _FUNC_INIT_FAILED)
+
+/* Macros for leaving different scopes of routines */
+#define FUNC_LEAVE_PKGINIT \
+ /* Leave scope for this type of function */ \
+ } \
+ \
+ /* Pop the name of this function off the function stack */ \
+ H5_POP_FUNC
+
+#define FUNC_LEAVE_STATIC \
+ /* Leave scope for this type of function */ \
+ } \
+ \
+ /* Pop the name of this function off the function stack */ \
+ H5_POP_FUNC
+
+#define FUNC_LEAVE_PKG \
+ /* Leave scope for this type of function */ \
+ } \
+ \
+ /* Pop the name of this function off the function stack */ \
+ H5_POP_FUNC
+
+#define FUNC_LEAVE_PRIV \
+ /* Leave scope for this type of function */ \
+ }} \
+ \
+ /* Label for errors during FUNC_ENTER */ \
+ H5_PRIV_FUNC_INIT_FAILED(H5_MY_PKG_INIT) \
+ \
+ /* Pop the name of this function off the function stack */ \
+ H5_POP_FUNC
+
+#define FUNC_LEAVE_PUB \
+ /* Leave scope for this type of function */ \
+ }}} \
+ \
+ /* Label for errors during FUNC_ENTER */ \
+func_init_failed: \
+ \
+ /* Dump error stack if an error occurred during API routine */ \
+ if(ret_value == fail_value) \
+ (void)H5E_dump_api_stack(TRUE); \
+ \
+ /* Finish the API tracing info */ \
+ H5TRACE_RETURN(ret_value); \
+ \
+ /* Pop the name of this function off the function stack */ \
+ H5_POP_FUNC \
+ \
+ /* Finish the MPE tracing info */ \
+ FINISH_MPE_LOG; \
+ \
+ /* Check for leaving API routine */ \
+ HDassert(H5_api_entered_g); \
+ H5_api_entered_g = FALSE; \
+ \
+ /* Release thread-safety semaphore */ \
+ FUNC_LEAVE_API_THREADSAFE
+
+/* Use this macro when leaving all functions */
+#define END_FUNC(scope) \
+ /* Scope-specific function conclusion */ \
+ H5_GLUE(FUNC_LEAVE_, scope) \
+ \
+ /* Leave routine */ \
+ return(ret_value); \
+ \
+ /* Close Function */ \
+}
+
+
+/* Macro for "stringizing" an integer in the C preprocessor (use H5_TOSTRING) */
+/* (use H5_TOSTRING, H5_STRINGIZE is just part of the implementation) */
+#define H5_STRINGIZE(x) #x
+#define H5_TOSTRING(x) H5_STRINGIZE(x)
+
/* Macro for "glueing" together items, for re-scanning macros */
#define H5_GLUE(x,y) x##y
#define H5_GLUE3(x,y,z) x##y##z
+#define H5_GLUE4(w,x,y,z) w##x##y##z
/* Compile-time "assert" macro */
#define HDcompile_assert(e) do { enum { compile_assert__ = 1 / (e) }; } while(0)
@@ -1904,6 +2288,9 @@ H5_DLL uint32_t H5_checksum_lookup3(const void *data, size_t len, uint32_t initv
H5_DLL uint32_t H5_checksum_metadata(const void *data, size_t len, uint32_t initval);
H5_DLL uint32_t H5_hash_string(const char *str);
+/* Functions for building paths, etc. */
+H5_DLL herr_t H5_build_extpath(const char *, char ** /*out*/ );
+
/* Functions for debugging */
H5_DLL herr_t H5_buffer_dump(FILE *stream, int indent, uint8_t *buf,
uint8_t *marker, size_t buf_offset, size_t buf_size);
diff --git a/src/H5public.h b/src/H5public.h
index 1612565..d7c6899 100644
--- a/src/H5public.h
+++ b/src/H5public.h
@@ -71,10 +71,10 @@ extern "C" {
/* Version numbers */
#define H5_VERS_MAJOR 1 /* For major interface/format changes */
#define H5_VERS_MINOR 9 /* For minor interface/format changes */
-#define H5_VERS_RELEASE 14 /* For tweaks, bug-fixes, or development */
+#define H5_VERS_RELEASE 55 /* For tweaks, bug-fixes, or development */
#define H5_VERS_SUBRELEASE "" /* For pre-releases like snap0 */
/* Empty string for real releases. */
-#define H5_VERS_INFO "HDF5 library version: 1.9.14" /* Full version string */
+#define H5_VERS_INFO "HDF5 library version: 1.9.55" /* Full version string */
#define H5check() H5check_version(H5_VERS_MAJOR,H5_VERS_MINOR, \
H5_VERS_RELEASE)
@@ -110,24 +110,6 @@ typedef int herr_t;
typedef unsigned int hbool_t;
typedef int htri_t;
-/*
- * Although `long long' is part of the revised ANSI-C some compilers don't
- * support it yet. We define `long_long' as the longest integral integer type
- * supported by the compiler, usually 64 bits. It must be legal to qualify
- * `long_long' with `unsigned'.
- */
-#if H5_SIZEOF_LONG_LONG>0
-# define long_long long long
-#elif H5_SIZEOF___INT64>0
-# define long_long __int64 /*Win32*/
-# undef H5_SIZEOF_LONG_LONG
-# define H5_SIZEOF_LONG_LONG H5_SIZEOF___INT64
-#else
-# define long_long long int
-# undef H5_SIZEOF_LONG_LONG
-# define H5_SIZEOF_LONG_LONG H5_SIZEOF_LONG
-#endif
-
/* Define the ssize_t type if it not is defined */
#if H5_SIZEOF_SSIZE_T==0
/* Undefine this size, we will re-define it in one of the sections below */
@@ -139,7 +121,7 @@ typedef int ssize_t;
typedef long ssize_t;
# define H5_SIZEOF_SSIZE_T H5_SIZEOF_LONG
#elif H5_SIZEOF_SIZE_T==H5_SIZEOF_LONG_LONG
-typedef long_long ssize_t;
+typedef long long ssize_t;
# define H5_SIZEOF_SSIZE_T H5_SIZEOF_LONG_LONG
#else /* Can't find matching type for ssize_t */
# error "nothing appropriate for ssize_t"
@@ -151,8 +133,8 @@ typedef long_long ssize_t;
* type.
*/
#if H5_SIZEOF_LONG_LONG >= 8
-typedef unsigned long_long hsize_t;
-typedef signed long_long hssize_t;
+typedef unsigned long long hsize_t;
+typedef signed long long hssize_t;
# define H5_SIZEOF_HSIZE_T H5_SIZEOF_LONG_LONG
# define H5_SIZEOF_HSSIZE_T H5_SIZEOF_LONG_LONG
#else
@@ -184,8 +166,8 @@ typedef signed long_long hssize_t;
# define HADDR_AS_MPI_TYPE MPI_UNSIGNED_LONG
# endif /* H5_HAVE_PARALLEL */
#elif H5_SIZEOF_LONG_LONG>=8
- typedef unsigned long_long haddr_t;
-# define HADDR_UNDEF ((haddr_t)(long_long)(-1))
+ typedef unsigned long long haddr_t;
+# define HADDR_UNDEF ((haddr_t)(long long)(-1))
# define H5_SIZEOF_HADDR_T H5_SIZEOF_LONG_LONG
# ifdef H5_HAVE_PARALLEL
# define HADDR_AS_MPI_TYPE MPI_LONG_LONG_INT
@@ -237,7 +219,7 @@ typedef signed long_long hssize_t;
# undef H5_SIZEOF_INT64_T
# define H5_SIZEOF_INT64_T H5_SIZEOF_LONG
#elif H5_SIZEOF_LONG_LONG>=8
- typedef long_long int64_t;
+ typedef long long int64_t;
# undef H5_SIZEOF_INT64_T
# define H5_SIZEOF_INT64_T H5_SIZEOF_LONG_LONG
#else
@@ -257,13 +239,16 @@ typedef signed long_long hssize_t;
# undef H5_SIZEOF_UINT64_T
# define H5_SIZEOF_UINT64_T H5_SIZEOF_LONG
#elif H5_SIZEOF_LONG_LONG>=8
- typedef unsigned long_long uint64_t;
+ typedef unsigned long long uint64_t;
# undef H5_SIZEOF_UINT64_T
# define H5_SIZEOF_UINT64_T H5_SIZEOF_LONG_LONG
#else
# error "nothing appropriate for uint64_t"
#endif
+/* Default value for all property list classes */
+#define H5P_DEFAULT 0
+
/* Common iteration orders */
typedef enum {
H5_ITER_UNKNOWN = -1, /* Unknown order */
diff --git a/src/H5system.c b/src/H5system.c
index 6a8a91a..9d93d9c 100644
--- a/src/H5system.c
+++ b/src/H5system.c
@@ -580,23 +580,68 @@ HDremove_all(const char *fname)
}
#endif
-
-/*
- *-------------------------------------------------------------------------
+/*-------------------------------------------------------------------------
+ * Function: HDgettimeofday
+ *
+ * Purpose: Wrapper function for gettimeofday on Windows systems
+ *
+ * This function can get the time as well as a timezone
+ *
+ * Return: 0
+ *
+ * This implementation is taken from the Cygwin source distribution at
+ * src/winsup/mingw/mingwex/gettimeofday.c
+ *
+ * The original source code was contributed by
+ * Danny Smith <dannysmith@users.sourceforge.net>
+ * and released in the public domain.
*
+ * Programmer: Scott Wegner
+ * May 19, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+#if !defined(H5_HAVE_GETTIMEOFDAY) && defined(_WIN32)
+
+/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
+#define _W32_FT_OFFSET (116444736000000000ULL)
+
+int
+HDgettimeofday(struct timeval *tv, void *tz)
+ {
+ union {
+ unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
+ FILETIME ft;
+ } _now;
+
+ if(tv)
+ {
+ GetSystemTimeAsFileTime (&_now.ft);
+ tv->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
+ tv->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
+ }
+ /* Always return 0 as per Open Group Base Specifications Issue 6.
+ Do not set errno on error. */
+ return 0;
+}
+#endif
+
+
+/*-------------------------------------------------------------------------
* Function: H5_build_extpath
*
- * Purpose: To build the path for later searching of target file for external link.
- * This path can be either:
- * 1. The absolute path of NAME
+ * Purpose: To build the path for later searching of target file for external
+ * link. This path can be either:
+ * 1. The absolute path of NAME
* or
- * 2. The current working directory + relative path of NAME
+ * 2. The current working directory + relative path of NAME
*
* Return: Success: 0
* Failure: -1
*
* Programmer: Vailin Choi
* April 2, 2008
+ *
*-------------------------------------------------------------------------
*/
#define MAX_PATH_LEN 1024
@@ -604,76 +649,111 @@ HDremove_all(const char *fname)
herr_t
H5_build_extpath(const char *name, char **extpath/*out*/)
{
- char *full_path=NULL, *ptr=NULL;
- char *retcwd=NULL, *cwdpath=NULL, *new_name=NULL;
- int drive;
- size_t cwdlen, path_len;
+ char *full_path = NULL; /* Pointer to the full path, as built or passed in */
+ char *cwdpath = NULL; /* Pointer to the current working directory path */
+ char *new_name = NULL; /* Pointer to the name of the file */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5_build_extpath)
+ /* Clear external path pointer to begin with */
*extpath = NULL;
- /*
+ /*
* Unix: name[0] is a "/"
* Windows: name[0-2] is "<drive letter>:\" or "<drive-letter>:/"
+ * OpenVMS: <disk name>$<partition>:[path]<file name>
+ * i.g. SYS$SYSUSERS:[LU.HDF5.SRC]H5system.c
*/
- if (CHECK_ABSOLUTE(name)) {
- if ((full_path=H5MM_strdup(name)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- } else { /* relative pathname */
- if (NULL == (cwdpath = (char *)H5MM_malloc(MAX_PATH_LEN)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- if (NULL == (new_name = (char *)H5MM_strdup(name)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
-
- /*
+ if(CHECK_ABSOLUTE(name)) {
+ if(NULL == (full_path = (char *)H5MM_strdup(name)))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_NOSPACE, FAIL, "memory allocation failed")
+ } /* end if */
+ else { /* relative pathname */
+ char *retcwd;
+ int drive;
+
+ if(NULL == (cwdpath = (char *)H5MM_malloc(MAX_PATH_LEN)))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(NULL == (new_name = (char *)H5MM_strdup(name)))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /*
* Windows: name[0-1] is "<drive-letter>:"
- * Get current working directory on the drive specified in NAME
+ * Get current working directory on the drive specified in NAME
* Unix: does not apply
+ * OpenVMS: does not apply
*/
- if (CHECK_ABS_DRIVE(name)) {
+ if(CHECK_ABS_DRIVE(name)) {
drive = name[0] - 'A' + 1;
retcwd = HDgetdcwd(drive, cwdpath, MAX_PATH_LEN);
HDstrcpy(new_name, &name[2]);
- /*
- * Windows: name[0] is a '/' or '\'
+ } /* end if */
+ /*
+ * Windows: name[0] is a '/' or '\'
* Get current drive
* Unix: does not apply
+ * OpenVMS: does not apply
*/
- } else if (CHECK_ABS_PATH(name) && (drive=HDgetdrive())) {
+ else if(CHECK_ABS_PATH(name) && (0 != (drive = HDgetdrive()))) {
sprintf(cwdpath, "%c:%c", (drive+'A'-1), name[0]);
retcwd = cwdpath;
HDstrcpy(new_name, &name[1]);
- } else /* totally relative for both Unix and Windows: get current working directory */
+ }
+ /* totally relative for Unix, Windows, and OpenVMS: get current working directory */
+ else
retcwd = HDgetcwd(cwdpath, MAX_PATH_LEN);
- if (retcwd != NULL) {
+ if(retcwd != NULL) {
+ size_t cwdlen;
+ size_t path_len;
+
cwdlen = HDstrlen(cwdpath);
HDassert(cwdlen);
path_len = cwdlen + HDstrlen(new_name) + 2;
- if (NULL == (full_path = (char *)H5MM_malloc(path_len)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(NULL == (full_path = (char *)H5MM_malloc(path_len)))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_NOSPACE, FAIL, "memory allocation failed")
HDstrcpy(full_path, cwdpath);
- if (!CHECK_DELIMITER(cwdpath[cwdlen-1]))
+#ifdef H5_VMS
+ /* If the file name contains relative path, cut off the beginning bracket. Also cut off the
+ * ending bracket of CWDPATH to combine the full path name. i.g.
+ * cwdpath = SYS$SYSUSERS:[LU.HDF5.TEST]
+ * new_name = [.tmp]extlinks.h5
+ * full_path = SYS$SYSUSERS:[LU.HDF5.TEST.tmp]extlinks.h5
+ */
+ if(new_name[0] == '[') {
+ char *tmp = new_name;
+ full_path[cwdlen - 1] = '\0';
+ HDstrcat(full_path, ++tmp);
+ } /* end if */
+ else
+ HDstrcat(full_path, new_name);
+#else
+ if(!CHECK_DELIMITER(cwdpath[cwdlen - 1]))
HDstrcat(full_path, DIR_SEPS);
HDstrcat(full_path, new_name);
- }
- }
+#endif
+ } /* end if */
+ } /* end else */
/* strip out the last component (the file name itself) from the path */
- if (full_path) {
+ if(full_path) {
+ char *ptr = NULL;
+
GET_LAST_DELIMITER(full_path, ptr)
HDassert(ptr);
*++ptr = '\0';
*extpath = full_path;
- }
+ } /* end if */
done:
- if (cwdpath)
+ /* Release resources */
+ if(cwdpath)
H5MM_xfree(cwdpath);
- if (new_name)
+ if(new_name)
H5MM_xfree(new_name);
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5_build_extpath() */
+
diff --git a/src/H5trace.c b/src/H5trace.c
index 4a42f0b..b554b80 100644
--- a/src/H5trace.c
+++ b/src/H5trace.c
@@ -293,234 +293,257 @@ H5_trace (const double *returning, const char *func, const char *type, ...)
break;
case 'D':
- switch (type[1]) {
- case 'a':
- if (ptr) {
- if (vp) {
- fprintf (out, "0x%lx", (unsigned long)vp);
- } else {
- fprintf(out, "NULL");
- }
- } else {
- H5D_alloc_time_t alloc_time = va_arg (ap, H5D_alloc_time_t); /*lint !e64 Type mismatch not really occuring */
- switch (alloc_time) {
- case H5D_ALLOC_TIME_ERROR:
- fprintf (out, "H5D_ALLOC_TIME_ERROR");
- break;
- case H5D_ALLOC_TIME_DEFAULT:
- fprintf (out, "H5D_ALLOC_TIME_DEFAULT");
- break;
- case H5D_ALLOC_TIME_EARLY:
- fprintf (out, "H5D_ALLOC_TIME_EARLY");
- break;
- case H5D_ALLOC_TIME_LATE:
- fprintf (out, "H5D_ALLOC_TIME_LATE");
- break;
- case H5D_ALLOC_TIME_INCR:
- fprintf (out, "H5D_ALLOC_TIME_INCR");
- break;
- default:
- fprintf (out, "%ld", (long)alloc_time);
- break;
- }
- }
- break;
+ switch(type[1]) {
+ case 'a':
+ if(ptr) {
+ if(vp)
+ fprintf (out, "0x%lx", (unsigned long)vp);
+ else
+ fprintf(out, "NULL");
+ } /* end if */
+ else {
+ H5D_alloc_time_t alloc_time = (H5D_alloc_time_t)va_arg(ap, int);
- case 'c':
- if (ptr) {
- if (vp) {
- fprintf (out, "0x%lx", (unsigned long)vp);
- } else {
- fprintf(out, "NULL");
- }
- } else {
- H5FD_mpio_collective_opt_t opt= va_arg(ap, H5FD_mpio_collective_opt_t); /*lint !e64 Type mismatch not really occuring */
- switch (opt) {
- case H5FD_MPIO_COLLECTIVE_IO:
- fprintf (out, "H5FD_MPIO_COLLECTIVE_IO");
- break;
- case H5FD_MPIO_INDIVIDUAL_IO:
- fprintf (out, "H5FD_MPIO_INDIVIDUAL_IO");
- break;
- default:
- fprintf (out, "%ld", (long)opt);
- break;
- }
- }
- break;
+ switch(alloc_time) {
+ case H5D_ALLOC_TIME_ERROR:
+ fprintf(out, "H5D_ALLOC_TIME_ERROR");
+ break;
- case 'f':
- if (ptr) {
- if (vp) {
- fprintf (out, "0x%lx", (unsigned long)vp);
- } else {
- fprintf(out, "NULL");
- }
- } else {
- H5D_fill_time_t fill_time = va_arg (ap, H5D_fill_time_t); /*lint !e64 Type mismatch not really occuring */
- switch (fill_time) {
- case H5D_FILL_TIME_ERROR:
- fprintf (out, "H5D_FILL_TIME_ERROR");
- break;
- case H5D_FILL_TIME_ALLOC:
- fprintf (out, "H5D_FILL_TIME_ALLOC");
- break;
- case H5D_FILL_TIME_NEVER:
- fprintf (out, "H5D_FILL_TIME_NEVER");
- break;
- case H5D_FILL_TIME_IFSET:
- fprintf (out, "H5D_FILL_TIME_IFSET");
- break;
- default:
- fprintf (out, "%ld", (long)fill_time);
- break;
- }
- }
- break;
+ case H5D_ALLOC_TIME_DEFAULT:
+ fprintf(out, "H5D_ALLOC_TIME_DEFAULT");
+ break;
- case 'F':
- if (ptr) {
- if (vp) {
- fprintf (out, "0x%lx", (unsigned long)vp);
- } else {
- fprintf(out, "NULL");
- }
- } else {
- H5D_fill_value_t fill_value = va_arg (ap, H5D_fill_value_t); /*lint !e64 Type mismatch not really occuring */
- switch (fill_value) {
- case H5D_FILL_VALUE_ERROR:
- fprintf (out, "H5D_FILL_VALUE_ERROR");
- break;
- case H5D_FILL_VALUE_UNDEFINED:
- fprintf (out, "H5D_FILL_VALUE_UNDEFINED");
- break;
- case H5D_FILL_VALUE_DEFAULT:
- fprintf (out, "H5D_FILL_VALUE_DEFAULT");
- break;
- case H5D_FILL_VALUE_USER_DEFINED:
- fprintf (out, "H5D_FILL_VALUE_USER_DEFINED");
- break;
- default:
- fprintf (out, "%ld", (long)fill_value);
- break;
- }
- }
- break;
+ case H5D_ALLOC_TIME_EARLY:
+ fprintf(out, "H5D_ALLOC_TIME_EARLY");
+ break;
- case 'h':
- if (ptr) {
- if (vp) {
- fprintf (out, "0x%lx", (unsigned long)vp);
- } else {
- fprintf(out, "NULL");
- }
- } else {
- H5FD_mpio_chunk_opt_t opt = va_arg(ap, H5FD_mpio_chunk_opt_t); /*lint !e64 Type mismatch not really occuring */
- switch (opt) {
- case H5FD_MPIO_CHUNK_DEFAULT:
- fprintf (out, "H5FD_MPIO_CHUNK_DEFAULT");
- break;
- case H5FD_MPIO_CHUNK_ONE_IO:
- fprintf (out, "H5FD_MPIO_CHUNK_ONE_IO");
- break;
- case H5FD_MPIO_CHUNK_MULTI_IO:
- fprintf (out, "H5FD_MPIO_CHUNK_MULTI_IO");
- break;
- default:
- fprintf (out, "%ld", (long)opt);
- break;
- }
- }
- break;
+ case H5D_ALLOC_TIME_LATE:
+ fprintf(out, "H5D_ALLOC_TIME_LATE");
+ break;
- case 'l':
- if (ptr) {
- if (vp) {
- fprintf (out, "0x%lx", (unsigned long)vp);
- } else {
- fprintf(out, "NULL");
- }
- } else {
- H5D_layout_t layout = va_arg (ap, H5D_layout_t); /*lint !e64 Type mismatch not really occuring */
- switch (layout) {
- case H5D_LAYOUT_ERROR:
- fprintf (out, "H5D_LAYOUT_ERROR");
- break;
- case H5D_COMPACT:
- fprintf (out, "H5D_COMPACT");
- break;
- case H5D_CONTIGUOUS:
- fprintf (out, "H5D_CONTIGUOUS");
- break;
- case H5D_CHUNKED:
- fprintf (out, "H5D_CHUNKED");
- break;
- case H5D_NLAYOUTS:
- fprintf (out, "H5D_NLAYOUTS");
- break;
- default:
- fprintf (out, "%ld", (long)layout);
- break;
- }
- }
- break;
+ case H5D_ALLOC_TIME_INCR:
+ fprintf(out, "H5D_ALLOC_TIME_INCR");
+ break;
- case 's':
- if (ptr) {
- if (vp) {
- fprintf (out, "0x%lx", (unsigned long)vp);
- } else {
- fprintf(out, "NULL");
- }
- } else {
- H5D_space_status_t space_status = va_arg(ap, H5D_space_status_t); /*lint !e64 Type mismatch not really occuring */
- switch (space_status) {
- case H5D_SPACE_STATUS_NOT_ALLOCATED:
- fprintf (out, "H5D_SPACE_STATUS_NOT_ALLOCATED");
- break;
- case H5D_SPACE_STATUS_PART_ALLOCATED:
- fprintf (out, "H5D_SPACE_STATUS_PART_ALLOCATED");
- break;
- case H5D_SPACE_STATUS_ALLOCATED:
- fprintf (out, "H5D_SPACE_STATUS_ALLOCATED");
- break;
- case H5D_SPACE_STATUS_ERROR:
- fprintf (out, "H5D_SPACE_STATUS_ERROR");
- break;
- default:
- fprintf (out, "%ld", (long)space_status);
- break;
- }
- }
- break;
+ default:
+ fprintf(out, "%ld", (long)alloc_time);
+ break;
+ } /* end switch */
+ } /* end else */
+ break;
- case 't':
- if (ptr) {
- if (vp) {
- fprintf (out, "0x%lx", (unsigned long)vp);
- } else {
- fprintf(out, "NULL");
- }
- } else {
- H5FD_mpio_xfer_t transfer = va_arg(ap, H5FD_mpio_xfer_t); /*lint !e64 Type mismatch not really occuring */
- switch (transfer) {
- case H5FD_MPIO_INDEPENDENT:
- fprintf (out, "H5FD_MPIO_INDEPENDENT");
- break;
- case H5FD_MPIO_COLLECTIVE:
- fprintf (out, "H5FD_MPIO_COLLECTIVE");
- break;
- default:
- fprintf (out, "%ld", (long)transfer);
- break;
- }
- }
- break;
+ case 'c':
+ if(ptr) {
+ if(vp)
+ fprintf(out, "0x%lx", (unsigned long)vp);
+ else
+ fprintf(out, "NULL");
+ } /* end if */
+ else {
+ H5FD_mpio_collective_opt_t opt = (H5FD_mpio_collective_opt_t)va_arg(ap, int);
- default:
- fprintf (out, "BADTYPE(D%c)", type[1]);
- goto error;
- }
+ switch(opt) {
+ case H5FD_MPIO_COLLECTIVE_IO:
+ fprintf(out, "H5FD_MPIO_COLLECTIVE_IO");
+ break;
+
+ case H5FD_MPIO_INDIVIDUAL_IO:
+ fprintf(out, "H5FD_MPIO_INDIVIDUAL_IO");
+ break;
+
+ default:
+ fprintf(out, "%ld", (long)opt);
+ break;
+ } /* end switch */
+ } /* end else */
+ break;
+
+ case 'f':
+ if(ptr) {
+ if(vp)
+ fprintf(out, "0x%lx", (unsigned long)vp);
+ else
+ fprintf(out, "NULL");
+ } /* end if */
+ else {
+ H5D_fill_time_t fill_time = (H5D_fill_time_t)va_arg(ap, int);
+
+ switch(fill_time) {
+ case H5D_FILL_TIME_ERROR:
+ fprintf(out, "H5D_FILL_TIME_ERROR");
+ break;
+
+ case H5D_FILL_TIME_ALLOC:
+ fprintf(out, "H5D_FILL_TIME_ALLOC");
+ break;
+
+ case H5D_FILL_TIME_NEVER:
+ fprintf(out, "H5D_FILL_TIME_NEVER");
+ break;
+
+ case H5D_FILL_TIME_IFSET:
+ fprintf(out, "H5D_FILL_TIME_IFSET");
+ break;
+
+ default:
+ fprintf(out, "%ld", (long)fill_time);
+ break;
+ } /* end switch */
+ } /* end else */
+ break;
+
+ case 'F':
+ if(ptr) {
+ if(vp)
+ fprintf(out, "0x%lx", (unsigned long)vp);
+ else
+ fprintf(out, "NULL");
+ } /* end if */
+ else {
+ H5D_fill_value_t fill_value = (H5D_fill_value_t)va_arg(ap, int);
+
+ switch(fill_value) {
+ case H5D_FILL_VALUE_ERROR:
+ fprintf(out, "H5D_FILL_VALUE_ERROR");
+ break;
+
+ case H5D_FILL_VALUE_UNDEFINED:
+ fprintf(out, "H5D_FILL_VALUE_UNDEFINED");
+ break;
+
+ case H5D_FILL_VALUE_DEFAULT:
+ fprintf(out, "H5D_FILL_VALUE_DEFAULT");
+ break;
+
+ case H5D_FILL_VALUE_USER_DEFINED:
+ fprintf(out, "H5D_FILL_VALUE_USER_DEFINED");
+ break;
+
+ default:
+ fprintf(out, "%ld", (long)fill_value);
+ break;
+ } /* end switch */
+ } /* end else */
+ break;
+
+ case 'h':
+ if(ptr) {
+ if(vp)
+ fprintf(out, "0x%lx", (unsigned long)vp);
+ else
+ fprintf(out, "NULL");
+ } /* end if */
+ else {
+ H5FD_mpio_chunk_opt_t opt = (H5FD_mpio_chunk_opt_t)va_arg(ap, int);
+
+ switch(opt) {
+ case H5FD_MPIO_CHUNK_DEFAULT:
+ fprintf(out, "H5FD_MPIO_CHUNK_DEFAULT");
+ break;
+
+ case H5FD_MPIO_CHUNK_ONE_IO:
+ fprintf(out, "H5FD_MPIO_CHUNK_ONE_IO");
+ break;
+
+ case H5FD_MPIO_CHUNK_MULTI_IO:
+ fprintf(out, "H5FD_MPIO_CHUNK_MULTI_IO");
+ break;
+
+ default:
+ fprintf(out, "%ld", (long)opt);
+ break;
+ } /* end switch */
+ } /* end else */
+ break;
+
+ case 'l':
+ if (ptr) {
+ if (vp) {
+ fprintf (out, "0x%lx", (unsigned long)vp);
+ } else {
+ fprintf(out, "NULL");
+ }
+ } else {
+ H5D_layout_t layout = va_arg (ap, H5D_layout_t); /*lint !e64 Type mismatch not really occuring */
+ switch (layout) {
+ case H5D_LAYOUT_ERROR:
+ fprintf (out, "H5D_LAYOUT_ERROR");
+ break;
+ case H5D_COMPACT:
+ fprintf (out, "H5D_COMPACT");
+ break;
+ case H5D_CONTIGUOUS:
+ fprintf (out, "H5D_CONTIGUOUS");
+ break;
+ case H5D_CHUNKED:
+ fprintf (out, "H5D_CHUNKED");
+ break;
+ case H5D_NLAYOUTS:
+ fprintf (out, "H5D_NLAYOUTS");
+ break;
+ default:
+ fprintf (out, "%ld", (long)layout);
+ break;
+ }
+ }
+ break;
+
+ case 's':
+ if (ptr) {
+ if (vp) {
+ fprintf (out, "0x%lx", (unsigned long)vp);
+ } else {
+ fprintf(out, "NULL");
+ }
+ } else {
+ H5D_space_status_t space_status = va_arg(ap, H5D_space_status_t); /*lint !e64 Type mismatch not really occuring */
+ switch (space_status) {
+ case H5D_SPACE_STATUS_NOT_ALLOCATED:
+ fprintf (out, "H5D_SPACE_STATUS_NOT_ALLOCATED");
+ break;
+ case H5D_SPACE_STATUS_PART_ALLOCATED:
+ fprintf (out, "H5D_SPACE_STATUS_PART_ALLOCATED");
+ break;
+ case H5D_SPACE_STATUS_ALLOCATED:
+ fprintf (out, "H5D_SPACE_STATUS_ALLOCATED");
+ break;
+ case H5D_SPACE_STATUS_ERROR:
+ fprintf (out, "H5D_SPACE_STATUS_ERROR");
+ break;
+ default:
+ fprintf (out, "%ld", (long)space_status);
+ break;
+ }
+ }
+ break;
+
+ case 't':
+ if (ptr) {
+ if (vp) {
+ fprintf (out, "0x%lx", (unsigned long)vp);
+ } else {
+ fprintf(out, "NULL");
+ }
+ } else {
+ H5FD_mpio_xfer_t transfer = va_arg(ap, H5FD_mpio_xfer_t); /*lint !e64 Type mismatch not really occuring */
+ switch (transfer) {
+ case H5FD_MPIO_INDEPENDENT:
+ fprintf (out, "H5FD_MPIO_INDEPENDENT");
+ break;
+ case H5FD_MPIO_COLLECTIVE:
+ fprintf (out, "H5FD_MPIO_COLLECTIVE");
+ break;
+ default:
+ fprintf (out, "%ld", (long)transfer);
+ break;
+ }
+ }
+ break;
+
+ default:
+ fprintf (out, "BADTYPE(D%c)", type[1]);
+ goto error;
+ } /* end switch */
break;
case 'e':
@@ -635,6 +658,81 @@ H5_trace (const double *returning, const char *func, const char *type, ...)
}
break;
+ case 'f':
+ if(ptr) {
+ if(vp)
+ fprintf(out, "0x%lx", (unsigned long)vp);
+ else
+ fprintf(out, "NULL");
+ } /* end if */
+ else {
+ H5F_file_space_type_t fs_type = va_arg(ap, H5F_file_space_type_t); /*lint !e64 Type mismatch not really occuring */
+
+ switch(fs_type) {
+ case H5F_FILE_SPACE_DEFAULT:
+ fprintf(out, "H5F_FILE_SPACE_DEFAULT");
+ break;
+ case H5F_FILE_SPACE_ALL_PERSIST:
+ fprintf(out, "H5F_FILE_SPACE_ALL_PERSIST");
+ break;
+ case H5F_FILE_SPACE_ALL:
+ fprintf(out, "H5F_FILE_SPACE_ALL");
+ break;
+ case H5F_FILE_SPACE_AGGR_VFD:
+ fprintf(out, "H5F_FILE_SPACE_AGGR_VFD");
+ break;
+ case H5F_FILE_SPACE_VFD:
+ fprintf(out, "H5F_FILE_SPACE_VFD");
+ break;
+ default:
+ fprintf(out, "%ld", (long)fs_type);
+ break;
+ } /* end switch */
+ } /* end else */
+ break;
+
+ case 'm':
+ if(ptr) {
+ if(vp)
+ fprintf(out, "0x%lx", (unsigned long)vp);
+ else
+ fprintf(out, "NULL");
+ } /* end if */
+ else {
+ H5F_mem_t mem_type = va_arg(ap, H5F_mem_t); /*lint !e64 Type mismatch not really occuring */
+
+ switch(mem_type) {
+ case H5FD_MEM_NOLIST:
+ fprintf(out, "H5FD_MEM_NOLIST");
+ break;
+ case H5FD_MEM_DEFAULT:
+ fprintf(out, "H5FD_MEM_DEFAULT");
+ break;
+ case H5FD_MEM_SUPER:
+ fprintf(out, "H5FD_MEM_SUPER");
+ break;
+ case H5FD_MEM_BTREE:
+ fprintf(out, "H5FD_MEM_BTREE");
+ break;
+ case H5FD_MEM_DRAW:
+ fprintf(out, "H5FD_MEM_DRAW");
+ break;
+ case H5FD_MEM_GHEAP:
+ fprintf(out, "H5FD_MEM_GHEAP");
+ break;
+ case H5FD_MEM_LHEAP:
+ fprintf(out, "H5FD_MEM_LHEAP");
+ break;
+ case H5FD_MEM_OHDR:
+ fprintf(out, "H5FD_MEM_OHDR");
+ break;
+ default:
+ fprintf(out, "%ld", (long)mem_type);
+ break;
+ } /* end switch */
+ } /* end else */
+ break;
+
case 's':
if(ptr) {
if(vp)
@@ -651,10 +749,6 @@ H5_trace (const double *returning, const char *func, const char *type, ...)
case H5F_SCOPE_GLOBAL:
fprintf(out, "H5F_SCOPE_GLOBAL");
break;
- case H5F_SCOPE_DOWN:
- fprintf(out, "H5F_SCOPE_DOWN "
- "/*FOR INTERNAL USE ONLY!*/");
- break;
default:
fprintf(out, "%ld", (long)scope);
break;
@@ -1360,7 +1454,7 @@ H5_trace (const double *returning, const char *func, const char *type, ...)
/* This may generate recursive call to the library... -QAK */
if(NULL != (pclass = (H5P_genclass_t *)H5I_object(pclass_id)) &&
(class_name = H5P_get_class_name(pclass))!=NULL) {
- fprintf (out, class_name);
+ fprintf(out, "%s", class_name);
H5MM_xfree(class_name);
} /* end if */
else {
@@ -1978,7 +2072,7 @@ H5_trace (const double *returning, const char *func, const char *type, ...)
fprintf(out, "NULL");
}
} else {
- H5Z_class_t *filter = va_arg (ap, H5Z_class_t*); /*lint !e64 Type mismatch not really occuring */
+ H5Z_class2_t *filter = va_arg (ap, H5Z_class2_t*); /*lint !e64 Type mismatch not really occuring */
fprintf (out, "0x%lx", (unsigned long)filter);
}
break;
diff --git a/src/H5vers.txt b/src/H5vers.txt
index 00ab84b..89f7bc6 100644
--- a/src/H5vers.txt
+++ b/src/H5vers.txt
@@ -55,6 +55,7 @@ FUNCTION: H5Eprint; ; v10, v18
FUNCTION: H5Epush; ; v14, v18
FUNCTION: H5Eset_auto; ; v10, v18
FUNCTION: H5Ewalk; H5E_walk, H5E_error; v10, v18
+FUNCTION: H5Fget_info; H5F_info; v18, v110
FUNCTION: H5Gcreate; ; v10, v18
FUNCTION: H5Gopen; ; v10, v18
FUNCTION: H5Pget_filter; ; v10, v18
@@ -71,4 +72,5 @@ FUNCTION: H5Topen; ; v10, v18
# (although not required, it's easier to compare this file with the headers
# generated if the list below is in alphanumeric sort order - QAK)
TYPEDEF: H5E_auto; v10, v18
+TYPEDEF: H5Z_class; v16, v18
diff --git a/src/H5version.h b/src/H5version.h
index eab972c..296768e 100644
--- a/src/H5version.h
+++ b/src/H5version.h
@@ -21,9 +21,9 @@
#define _H5version_H
/* Issue error if contradicting macros have been defined. */
-#if defined(H5_USE_16_API) && defined(H5_NO_DEPRECATED_SYMBOLS)
+#if (defined(H5_USE_16_API) || defined(H5_USE_18_API)) && defined(H5_NO_DEPRECATED_SYMBOLS)
#error "Can't choose old API versions when deprecated APIs are disabled"
-#endif /* defined(H5_USE_16_API) && defined(H5_NO_DEPRECATED_SYMBOLS) */
+#endif /* (defined(H5_USE_16_API) || defined(H5_USE_18_API)) && defined(H5_NO_DEPRECATED_SYMBOLS) */
/* If a particular "global" version of the library's interfaces is chosen,
@@ -32,6 +32,15 @@
* Note: If an application has already chosen a particular version for an
* API symbol, the individual API version macro takes priority.
*/
+#if defined(H5_USE_16_API_DEFAULT) && !defined(H5_USE_16_API)
+#define H5_USE_16_API 1
+#endif /* H5_USE_16_API_DEFAULT && !H5_USE_16_API */
+
+#if defined(H5_USE_18_API_DEFAULT) && !defined(H5_USE_18_API)
+#define H5_USE_18_API 1
+#endif /* H5_USE_18_API_DEFAULT && !H5_USE_18_API */
+
+
#ifdef H5_USE_16_API
/*************/
@@ -130,8 +139,120 @@
#define H5E_auto_t_vers 1
#endif /* !defined(H5E_auto_t_vers) */
+#if !defined(H5Z_class_t_vers)
+#define H5Z_class_t_vers 1
+#endif /* !defined(H5Z_class_t_vers) */
+
#endif /* H5_USE_16_API */
+#ifdef H5_USE_18_API
+
+/*************/
+/* Functions */
+/*************/
+
+#if !defined(H5Acreate_vers)
+#define H5Acreate_vers 2
+#endif /* !defined(H5Acreate_vers) */
+
+#if !defined(H5Aiterate_vers)
+#define H5Aiterate_vers 2
+#endif /* !defined(H5Aiterate_vers) */
+
+#if !defined(H5Dcreate_vers)
+#define H5Dcreate_vers 2
+#endif /* !defined(H5Dcreate_vers) */
+
+#if !defined(H5Dopen_vers)
+#define H5Dopen_vers 2
+#endif /* !defined(H5Dopen_vers) */
+
+#if !defined(H5Eclear_vers)
+#define H5Eclear_vers 2
+#endif /* !defined(H5Eclear_vers) */
+
+#if !defined(H5Eget_auto_vers)
+#define H5Eget_auto_vers 2
+#endif /* !defined(H5Eget_auto_vers) */
+
+#if !defined(H5Eprint_vers)
+#define H5Eprint_vers 2
+#endif /* !defined(H5Eprint_vers) */
+
+#if !defined(H5Epush_vers)
+#define H5Epush_vers 2
+#endif /* !defined(H5Epush_vers) */
+
+#if !defined(H5Eset_auto_vers)
+#define H5Eset_auto_vers 2
+#endif /* !defined(H5Eset_auto_vers) */
+
+#if !defined(H5Ewalk_vers)
+#define H5Ewalk_vers 2
+#endif /* !defined(H5Ewalk_vers) */
+
+#if !defined(H5Fget_info_vers)
+#define H5Fget_info_vers 1
+#endif /* !defined(H5Fget_info_vers) */
+
+#if !defined(H5Gcreate_vers)
+#define H5Gcreate_vers 2
+#endif /* !defined(H5Gcreate_vers) */
+
+#if !defined(H5Gopen_vers)
+#define H5Gopen_vers 2
+#endif /* !defined(H5Gopen_vers) */
+
+#if !defined(H5Pget_filter_vers)
+#define H5Pget_filter_vers 2
+#endif /* !defined(H5Pget_filter_vers) */
+
+#if !defined(H5Pget_filter_by_id_vers)
+#define H5Pget_filter_by_id_vers 2
+#endif /* !defined(H5Pget_filter_by_id_vers) */
+
+#if !defined(H5Pinsert_vers)
+#define H5Pinsert_vers 2
+#endif /* !defined(H5Pinsert_vers) */
+
+#if !defined(H5Pregister_vers)
+#define H5Pregister_vers 2
+#endif /* !defined(H5Pregister_vers) */
+
+#if !defined(H5Rget_obj_type_vers)
+#define H5Rget_obj_type_vers 2
+#endif /* !defined(H5Rget_obj_type_vers) */
+
+#if !defined(H5Tarray_create_vers)
+#define H5Tarray_create_vers 2
+#endif /* !defined(H5Tarray_create_vers) */
+
+#if !defined(H5Tcommit_vers)
+#define H5Tcommit_vers 2
+#endif /* !defined(H5Tcommit_vers) */
+
+#if !defined(H5Tget_array_dims_vers)
+#define H5Tget_array_dims_vers 2
+#endif /* !defined(H5Tget_array_dims_vers) */
+
+#if !defined(H5Topen_vers)
+#define H5Topen_vers 2
+#endif /* !defined(H5Topen_vers) */
+
+/************/
+/* Typedefs */
+/************/
+
+#if !defined(H5E_auto_t_vers)
+#define H5E_auto_t_vers 2
+#endif /* !defined(H5E_auto_t_vers) */
+
+#if !defined(H5Z_class_t_vers)
+#define H5Z_class_t_vers 2
+#endif /* !defined(H5Z_class_t_vers) */
+
+#endif /* H5_USE_18_API */
+
/* Choose the correct version of each API symbol, defaulting to the latest
* version of each. The "best" name for API parameters/data structures
@@ -259,6 +380,19 @@
#error "H5Ewalk_vers set to invalid value"
#endif /* H5Ewalk_vers */
+#if !defined(H5Fget_info_vers) || H5Fget_info_vers == 2
+#ifndef H5Fget_info_vers
+#define H5Fget_info_vers 2
+#endif /* H5Fget_info_vers */
+#define H5Fget_info H5Fget_info2
+#define H5F_info_t H5F_info2_t
+#elif H5Fget_info_vers == 1
+#define H5Fget_info H5Fget_info1
+#define H5F_info_t H5F_info1_t
+#else /* H5Fget_info_vers */
+#error "H5Fget_info_vers set to invalid value"
+#endif /* H5Fget_info_vers */
+
#if !defined(H5Gcreate_vers) || H5Gcreate_vers == 2
#ifndef H5Gcreate_vers
#define H5Gcreate_vers 2
@@ -395,5 +529,17 @@
#error "H5E_auto_t_vers set to invalid value"
#endif /* H5E_auto_t_vers */
+
+#if !defined(H5Z_class_t_vers) || H5Z_class_t_vers == 2
+#ifndef H5Z_class_t_vers
+#define H5Z_class_t_vers 2
+#endif /* H5Z_class_t_vers */
+#define H5Z_class_t H5Z_class2_t
+#elif H5Z_class_t_vers == 1
+#define H5Z_class_t H5Z_class1_t
+#else /* H5Z_class_t_vers */
+#error "H5Z_class_t_vers set to invalid value"
+#endif /* H5Z_class_t_vers */
+
#endif /* H5version_H */
diff --git a/src/H5win32defs.h b/src/H5win32defs.h
index 6ce8f77..141ec82 100644
--- a/src/H5win32defs.h
+++ b/src/H5win32defs.h
@@ -33,11 +33,27 @@ typedef __int64 h5_stat_size_t;
#define HDdup(F) _dup(F)
#define HDfdopen(N,S) _fdopen(N,S)
#define HDfileno(F) _fileno(F)
+#if _MSC_VER > 1310 /* Newer than VS.NET 2003 */
+#define HDftruncate(F,L) _chsize_s(F,L)
+#else
+#define HDftruncate(F,L) chsize(F,L)
+#endif
#define HDfstat(F,B) _fstati64(F,B)
#define HDisatty(F) _isatty(F)
+#define HDlstat(S,B) _lstati64(S,B)
#define HDstat(S,B) _stati64(S,B)
#define HDgetcwd(S,Z) _getcwd(S,Z)
#define HDgetdcwd(D,S,Z) _getdcwd(D,S,Z)
+#ifndef H5_HAVE_GETTIMEOFDAY
+ #ifdef __cplusplus
+ extern "C" {
+ #endif /* __cplusplus */
+ H5_DLL int HDgettimeofday(struct timeval *tv, void *tz);
+ #ifdef __cplusplus
+ }
+ #endif /* __cplusplus */
+ #define HDgettimeofday(V,Z) HDgettimeofday(V,Z)
+#endif /* H5_HAVE_GETTIMEOFDAY */
#define HDgetdrive() _getdrive()
#define HDlseek(F,O,W) _lseeki64(F,O,W)
#define HDmemset(X,C,Z) memset((void*)(X),C,Z)
@@ -45,6 +61,9 @@ typedef __int64 h5_stat_size_t;
#define HDopen(S,F,M) _open(S,F|_O_BINARY,M)
#define HDread(F,M,Z) _read(F,M,Z)
#define HDsetvbuf(F,S,M,Z) setvbuf(F,S,M,(Z>1?Z:2))
+#define HDsleep(S) Sleep(S*1000)
+#define HDstrcasecmp(A,B) _stricmp(A,B)
+#define HDstrtoull(S,R,N) _strtoui64(S,R,N)
#define HDstrdup(S) _strdup(S)
#define HDsnprintf _snprintf /*varargs*/
#define HDtzset() _tzset()
diff --git a/src/Makefile.am b/src/Makefile.am
index fcb47e2..b71033e 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -27,13 +27,13 @@ include $(top_srcdir)/config/lt_vers.am
# a long time to compile it with any optimization on. H5detect is used
# to generate H5Tinit.c once. So, optimization is not critical.
noinst_PROGRAMS = H5detect
-H5detect_CFLAGS = -g
+H5detect_CFLAGS = -g $(AM_CFLAGS)
# Our main target, the HDF5 library
lib_LTLIBRARIES=libhdf5.la
# Add libtool numbers to the HDF5 library (from config/lt_vers.am)
-libhdf5_la_LDFLAGS= -version-info $(LT_VERS_INTERFACE):$(LT_VERS_REVISION):$(LT_VERS_AGE)
+libhdf5_la_LDFLAGS= -version-info $(LT_VERS_INTERFACE):$(LT_VERS_REVISION):$(LT_VERS_AGE) $(AM_LDFLAGS)
# H5Tinit.c is a generated file, and should be cleaned.
MOSTLYCLEANFILES=H5Tinit.c
@@ -43,38 +43,48 @@ DISTCLEANFILES=H5pubconf.h
# library sources
libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5A.c H5Abtree2.c H5Adense.c H5Adeprec.c H5Aint.c H5Atest.c \
- H5AC.c H5B.c H5Bcache.c \
- H5B2.c H5B2cache.c H5B2dbg.c H5B2int.c H5B2stat.c H5B2test.c \
+ H5AC.c H5B.c H5Bcache.c H5Bdbg.c \
+ H5B2.c H5B2cache.c H5B2dbg.c H5B2hdr.c H5B2int.c H5B2stat.c H5B2test.c \
H5C.c H5CS.c \
- H5D.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \
+ H5D.c H5Dbtree.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \
H5Ddeprec.c H5Defl.c H5Dfill.c H5Dint.c \
- H5Dio.c \
- H5Distore.c H5Dmpio.c H5Doh.c H5Dscatgath.c H5Dselect.c H5Dtest.c \
+ H5Dio.c H5Dlayout.c \
+ H5Dmpio.c H5Doh.c H5Dscatgath.c H5Dselect.c H5Dtest.c \
H5E.c H5Edeprec.c H5Eint.c \
- H5F.c H5Fdbg.c H5Ffake.c H5Fmount.c H5Fsfile.c H5Fsuper.c H5Ftest.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 H5Fdeprec.c H5Ffake.c H5Fio.c H5Fmount.c \
+ H5Fmpi.c H5Fquery.c \
+ H5Fsfile.c H5Fsuper.c H5Fsuper_cache.c H5Ftest.c \
+ H5FA.c H5FAcache.c H5FAdbg.c H5FAdblock.c H5FAdblkpage.c H5FAhdr.c \
+ H5FAstat.c H5FAtest.c \
H5FD.c H5FDcore.c \
- H5FDdirect.c H5FDfamily.c H5FDlog.c H5FDmpi.c H5FDmpio.c \
+ H5FDdirect.c H5FDfamily.c H5FDint.c H5FDlog.c H5FDmpi.c H5FDmpio.c \
H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDspace.c H5FDstdio.c \
- H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSsection.c \
- H5G.c H5Gbtree2.c H5Gcompact.c H5Gdense.c H5Gdeprec.c H5Gent.c \
+ H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSsection.c H5FSstat.c H5FStest.c \
+ H5G.c H5Gbtree2.c H5Gcache.c \
+ H5Gcompact.c H5Gdense.c H5Gdeprec.c H5Gent.c \
H5Gint.c H5Glink.c \
- H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c H5Goh.c H5Gstab.c H5Gtest.c \
+ H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c H5Goh.c H5Groot.c H5Gstab.c H5Gtest.c \
H5Gtraverse.c \
H5HF.c H5HFbtree2.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c \
H5HFhdr.c H5HFhuge.c H5HFiblock.c H5HFiter.c H5HFman.c H5HFsection.c \
H5HFspace.c H5HFstat.c H5HFtest.c H5HFtiny.c \
- H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5L.c H5Lexternal.c \
- H5MF.c H5MM.c H5MP.c H5MPtest.c \
+ H5HG.c H5HGcache.c H5HGdbg.c \
+ H5HL.c H5HLcache.c H5HLdbg.c \
+ H5HP.c H5I.c H5L.c H5Lexternal.c \
+ H5MF.c H5MFaggr.c H5MFdbg.c H5MFsection.c \
+ H5MM.c H5MP.c H5MPtest.c \
H5O.c H5Oainfo.c H5Oalloc.c H5Oattr.c \
H5Oattribute.c H5Obogus.c H5Obtreek.c H5Ocache.c \
H5Ocont.c H5Ocopy.c H5Odbg.c H5Odrvinfo.c H5Odtype.c H5Oefl.c \
- H5Ofill.c H5Oginfo.c \
+ H5Ofill.c H5Ofsinfo.c H5Oginfo.c \
H5Olayout.c \
H5Olinfo.c H5Olink.c H5Omessage.c H5Omtime.c \
H5Oname.c H5Onull.c H5Opline.c H5Orefcount.c \
H5Osdspace.c H5Oshared.c H5Ostab.c \
H5Oshmesg.c H5Otest.c H5Ounknown.c \
- H5P.c H5Pacpl.c H5Pdcpl.c \
+ H5P.c H5Pacpl.c H5Pdapl.c H5Pdcpl.c \
H5Pdeprec.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \
H5Pgcpl.c H5Pint.c \
H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pocpypl.c H5Pstrcpl.c H5Ptest.c \
@@ -82,8 +92,10 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5RC.c \
H5RS.c \
H5S.c H5Sall.c H5Sdbg.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c \
- H5Sselect.c H5Stest.c H5SL.c H5SM.c H5SMbtree2.c \
- H5SMcache.c H5SMtest.c H5ST.c \
+ H5Sselect.c H5Stest.c \
+ H5SL.c \
+ H5SM.c H5SMbtree2.c H5SMcache.c H5SMmessage.c H5SMtest.c \
+ H5ST.c \
H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c H5Tcompound.c H5Tconv.c \
H5Tcset.c H5Tdbg.c H5Tdeprec.c H5Tenum.c H5Tfields.c \
H5Tfixed.c \
@@ -96,7 +108,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
# Public headers
-include_HEADERS = hdf5.h H5api_adpt.h H5pubconf.h H5public.h H5version.h \
+include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5version.h \
H5Apublic.h H5ACpublic.h \
H5Cpublic.h H5Dpublic.h \
H5Epubgen.h H5Epublic.h H5Fpublic.h H5FDpublic.h H5FDcore.h H5FDdirect.h \
@@ -118,7 +130,7 @@ settings_DATA=libhdf5.settings
H5Tinit.c: H5detect$(EXEEXT)
LD_LIBRARY_PATH="$$LD_LIBRARY_PATH`echo $(LDFLAGS) | \
sed -e 's/-L/:/g' -e 's/ //g'`" \
- $(RUNSERIAL) ./H5detect > H5Tinit.c || \
+ $(RUNSERIAL) ./H5detect$(EXEEXT) > H5Tinit.c || \
(test $$HDF5_Make_Ignore && echo "*** Error ignored") || \
($(RM) $@ ; exit 1)
@@ -134,6 +146,10 @@ $(top_srcdir)/src/H5Edefin.h: $(top_srcdir)/src/H5err.txt
$(top_srcdir)/src/H5version.h: $(top_srcdir)/src/H5vers.txt
perl $(top_srcdir)/bin/make_vers $?
+# Assignment overflow macro generation
+$(top_srcdir)/src/H5overflow.h: $(top_srcdir)/src/H5overflow.txt
+ perl $(top_srcdir)/bin/make_overflow $?
+
# Add TRACE macros to library source files. This is done via the trace script
# in the hdf5/bin directory. If the file contains HDF5 API macros, a "clean"
# version of the source file is saved with a tilde (~) after its name and
diff --git a/src/Makefile.in b/src/Makefile.in
index bad04f1..ca41785 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,8 +1,9 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.11 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -36,8 +37,9 @@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
@@ -67,59 +69,83 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
mkinstalldirs = $(SHELL) $(top_srcdir)/bin/mkinstalldirs
CONFIG_HEADER = H5config.h
CONFIG_CLEAN_FILES = libhdf5.settings
+CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
-am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(settingsdir)" \
"$(DESTDIR)$(includedir)"
-libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
libhdf5_la_LIBADD =
am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \
H5timer.lo H5trace.lo H5A.lo H5Abtree2.lo H5Adense.lo \
H5Adeprec.lo H5Aint.lo H5Atest.lo H5AC.lo H5B.lo H5Bcache.lo \
- H5B2.lo H5B2cache.lo H5B2dbg.lo H5B2int.lo H5B2stat.lo \
- H5B2test.lo H5C.lo H5CS.lo H5D.lo H5Dchunk.lo H5Dcompact.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 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 \
- H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo \
- H5FSsection.lo H5G.lo H5Gbtree2.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 \
- H5HGdbg.lo H5HL.lo H5HLdbg.lo H5HP.lo H5I.lo H5L.lo \
- H5Lexternal.lo H5MF.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 \
+ H5Bdbg.lo H5B2.lo H5B2cache.lo H5B2dbg.lo H5B2hdr.lo \
+ H5B2int.lo H5B2stat.lo H5B2test.lo H5C.lo H5CS.lo H5D.lo \
+ H5Dbtree.lo H5Dchunk.lo H5Dcompact.lo H5Dcontig.lo H5Ddbg.lo \
+ H5Ddeprec.lo H5Defl.lo H5Dfill.lo H5Dint.lo H5Dio.lo \
+ H5Dlayout.lo H5Dmpio.lo H5Doh.lo H5Dscatgath.lo H5Dselect.lo \
+ H5Dtest.lo H5E.lo H5Edeprec.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 H5Fdeprec.lo H5Ffake.lo H5Fio.lo \
+ H5Fmount.lo H5Fmpi.lo H5Fquery.lo H5Fsfile.lo H5Fsuper.lo \
+ H5Fsuper_cache.lo H5Ftest.lo H5FA.lo H5FAcache.lo H5FAdbg.lo \
+ H5FAdblock.lo H5FAdblkpage.lo H5FAhdr.lo H5FAstat.lo \
+ H5FAtest.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 \
+ H5Groot.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 H5Ofsinfo.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 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 \
+ 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 \
- H5Tcset.lo H5Tdbg.lo H5Tdeprec.lo H5Tenum.lo H5Tfields.lo \
- H5Tfixed.lo H5Tfloat.lo H5Tinit.lo H5Tnative.lo H5Toffset.lo \
- H5Toh.lo H5Topaque.lo H5Torder.lo H5Tpad.lo H5Tprecis.lo \
- H5Tstrpad.lo H5Tvisit.lo H5Tvlen.lo H5TS.lo H5V.lo H5WB.lo \
- H5Z.lo H5Zdeflate.lo H5Zfletcher32.lo H5Znbit.lo H5Zshuffle.lo \
- H5Zszip.lo H5Zscaleoffset.lo H5Ztrans.lo
+ H5SMbtree2.lo H5SMcache.lo H5SMmessage.lo H5SMtest.lo H5ST.lo \
+ H5T.lo H5Tarray.lo H5Tbit.lo H5Tcommit.lo H5Tcompound.lo \
+ H5Tconv.lo H5Tcset.lo H5Tdbg.lo H5Tdeprec.lo H5Tenum.lo \
+ H5Tfields.lo H5Tfixed.lo H5Tfloat.lo H5Tinit.lo H5Tnative.lo \
+ H5Toffset.lo H5Toh.lo H5Topaque.lo H5Torder.lo H5Tpad.lo \
+ H5Tprecis.lo H5Tstrpad.lo H5Tvisit.lo H5Tvlen.lo H5TS.lo \
+ H5V.lo H5WB.lo H5Z.lo H5Zdeflate.lo H5Zfletcher32.lo \
+ H5Znbit.lo H5Zshuffle.lo H5Zszip.lo H5Zscaleoffset.lo \
+ H5Ztrans.lo
libhdf5_la_OBJECTS = $(am_libhdf5_la_OBJECTS)
libhdf5_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -134,6 +160,7 @@ H5detect_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/bin/depcomp
am__depfiles_maybe = depfiles
+am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
@@ -145,16 +172,26 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libhdf5_la_SOURCES) H5detect.c
DIST_SOURCES = $(libhdf5_la_SOURCES) H5detect.c
-settingsDATA_INSTALL = $(INSTALL_DATA)
DATA = $(settings_DATA)
-includeHEADERS_INSTALL = $(INSTALL_HEADER)
HEADERS = $(include_HEADERS)
ETAGS = etags
CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = /home1/packages/automake/automake-1.9.6/bin/aclocal-1.9 -I /afs/ncsa/projects/hdf/packages/libtool_1.5.14/Linux_2.4/share/aclocal
ADD_PARALLEL_FILES = @ADD_PARALLEL_FILES@
AMTAR = @AMTAR@
+
+# H5_CFLAGS holds flags that should be used when building hdf5,
+# but which should not be exported to h5cc for building other programs.
+# AM_CFLAGS is an automake construct which should be used by Makefiles
+# instead of CFLAGS, as CFLAGS is reserved solely for the user to define.
+AM_CFLAGS = @AM_CFLAGS@ @H5_CFLAGS@
+AM_CPPFLAGS = @AM_CPPFLAGS@ @H5_CPPFLAGS@
+AM_CXXFLAGS = @AM_CXXFLAGS@ @H5_CXXFLAGS@
+AM_FCFLAGS = @AM_FCFLAGS@ @H5_FCFLAGS@
+AM_LDFLAGS = @AM_LDFLAGS@
AM_MAKEFLAGS = @AM_MAKEFLAGS@
AR = @AR@
@@ -168,21 +205,18 @@ BYTESEX = @BYTESEX@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CC_VERSION = @CC_VERSION@
-
-# H5_CFLAGS holds flags that should be used as CFLAGS when building hdf5,
-# but which shouldn't be exported to h5cc for building other programs.
-CFLAGS = @CFLAGS@ @H5_CFLAGS@
+CFLAGS = @CFLAGS@
CLEARFILEBUF = @CLEARFILEBUF@
CODESTACK = @CODESTACK@
CONFIG_DATE = @CONFIG_DATE@
CONFIG_MODE = @CONFIG_MODE@
CONFIG_USER = @CONFIG_USER@
CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@ @H5_CPPFLAGS@
+CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@ @H5_CXXFLAGS@
+CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEBUG_PKG = @DEBUG_PKG@
DEFAULT_API_VERSION = @DEFAULT_API_VERSION@
@@ -205,7 +239,7 @@ F9XMODEXT = @F9XMODEXT@
F9XMODFLAG = @F9XMODFLAG@
F9XSUFFIXFLAG = @F9XSUFFIXFLAG@
FC = @FC@
-FCFLAGS = @FCFLAGS@ @H5_FCFLAGS@
+FCFLAGS = @FCFLAGS@
FCFLAGS_f90 = @FCFLAGS_f90@
FCLIBS = @FCLIBS@
FGREP = @FGREP@
@@ -243,6 +277,8 @@ LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LINUX_LFS = @LINUX_LFS@
+LIPO = @LIPO@
+LL_PATH = @LL_PATH@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_STATIC_EXEC = @LT_STATIC_EXEC@
@@ -253,13 +289,17 @@ MPE = @MPE@
MPI_GET_SIZE = @MPI_GET_SIZE@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJECT_NAMELEN_DEFAULT_F = @OBJECT_NAMELEN_DEFAULT_F@
OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PARALLEL = @PARALLEL@
PATH_SEPARATOR = @PATH_SEPARATOR@
@@ -275,12 +315,7 @@ SEARCH = @SEARCH@
SED = @SED@
SETX = @SETX@
SET_MAKE = @SET_MAKE@
-
-# Hardcode SHELL to be /bin/sh. Most machines have this shell, and
-# on at least one machine configure fails to detect its existence (janus).
-# Also, when HDF5 is configured on one machine but run on another,
-# configure's automatic SHELL detection may not work on the build machine.
-SHELL = /bin/sh
+SHELL = @SHELL@
SIZE_T = @SIZE_T@
STATIC_EXEC = @STATIC_EXEC@
STATIC_SHARED = @STATIC_SHARED@
@@ -300,6 +335,7 @@ USE_FILTER_SHUFFLE = @USE_FILTER_SHUFFLE@
USE_FILTER_SZIP = @USE_FILTER_SZIP@
USINGMEMCHECKER = @USINGMEMCHECKER@
VERSION = @VERSION@
+WORDS_BIGENDIAN = @WORDS_BIGENDIAN@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
@@ -322,6 +358,8 @@ build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
+
+# Install directories that automake doesn't know about
docdir = $(exec_prefix)/doc
dvidir = @dvidir@
enable_shared = @enable_shared@
@@ -333,9 +371,7 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
-
-# Install directories that automake doesn't know about
-includedir = $(exec_prefix)/include
+includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
@@ -355,6 +391,7 @@ sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@@ -403,15 +440,15 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog
# Add libtool shared library version numbers to the HDF5 library
# See libtool versioning documentation online.
LT_VERS_INTERFACE = 6
-LT_VERS_REVISION = 4
+LT_VERS_REVISION = 45
LT_VERS_AGE = 0
-H5detect_CFLAGS = -g
+H5detect_CFLAGS = -g $(AM_CFLAGS)
# Our main target, the HDF5 library
lib_LTLIBRARIES = libhdf5.la
# Add libtool numbers to the HDF5 library (from config/lt_vers.am)
-libhdf5_la_LDFLAGS = -version-info $(LT_VERS_INTERFACE):$(LT_VERS_REVISION):$(LT_VERS_AGE)
+libhdf5_la_LDFLAGS = -version-info $(LT_VERS_INTERFACE):$(LT_VERS_REVISION):$(LT_VERS_AGE) $(AM_LDFLAGS)
# H5Tinit.c is a generated file, and should be cleaned.
MOSTLYCLEANFILES = H5Tinit.c
@@ -421,38 +458,48 @@ DISTCLEANFILES = H5pubconf.h
# library sources
libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5A.c H5Abtree2.c H5Adense.c H5Adeprec.c H5Aint.c H5Atest.c \
- H5AC.c H5B.c H5Bcache.c \
- H5B2.c H5B2cache.c H5B2dbg.c H5B2int.c H5B2stat.c H5B2test.c \
+ H5AC.c H5B.c H5Bcache.c H5Bdbg.c \
+ H5B2.c H5B2cache.c H5B2dbg.c H5B2hdr.c H5B2int.c H5B2stat.c H5B2test.c \
H5C.c H5CS.c \
- H5D.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \
+ H5D.c H5Dbtree.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \
H5Ddeprec.c H5Defl.c H5Dfill.c H5Dint.c \
- H5Dio.c \
- H5Distore.c H5Dmpio.c H5Doh.c H5Dscatgath.c H5Dselect.c H5Dtest.c \
+ H5Dio.c H5Dlayout.c \
+ H5Dmpio.c H5Doh.c H5Dscatgath.c H5Dselect.c H5Dtest.c \
H5E.c H5Edeprec.c H5Eint.c \
- H5F.c H5Fdbg.c H5Ffake.c H5Fmount.c H5Fsfile.c H5Fsuper.c H5Ftest.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 H5Fdeprec.c H5Ffake.c H5Fio.c H5Fmount.c \
+ H5Fmpi.c H5Fquery.c \
+ H5Fsfile.c H5Fsuper.c H5Fsuper_cache.c H5Ftest.c \
+ H5FA.c H5FAcache.c H5FAdbg.c H5FAdblock.c H5FAdblkpage.c H5FAhdr.c \
+ H5FAstat.c H5FAtest.c \
H5FD.c H5FDcore.c \
- H5FDdirect.c H5FDfamily.c H5FDlog.c H5FDmpi.c H5FDmpio.c \
+ H5FDdirect.c H5FDfamily.c H5FDint.c H5FDlog.c H5FDmpi.c H5FDmpio.c \
H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDspace.c H5FDstdio.c \
- H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSsection.c \
- H5G.c H5Gbtree2.c H5Gcompact.c H5Gdense.c H5Gdeprec.c H5Gent.c \
+ H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSsection.c H5FSstat.c H5FStest.c \
+ H5G.c H5Gbtree2.c H5Gcache.c \
+ H5Gcompact.c H5Gdense.c H5Gdeprec.c H5Gent.c \
H5Gint.c H5Glink.c \
- H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c H5Goh.c H5Gstab.c H5Gtest.c \
+ H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c H5Goh.c H5Groot.c H5Gstab.c H5Gtest.c \
H5Gtraverse.c \
H5HF.c H5HFbtree2.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c \
H5HFhdr.c H5HFhuge.c H5HFiblock.c H5HFiter.c H5HFman.c H5HFsection.c \
H5HFspace.c H5HFstat.c H5HFtest.c H5HFtiny.c \
- H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5L.c H5Lexternal.c \
- H5MF.c H5MM.c H5MP.c H5MPtest.c \
+ H5HG.c H5HGcache.c H5HGdbg.c \
+ H5HL.c H5HLcache.c H5HLdbg.c \
+ H5HP.c H5I.c H5L.c H5Lexternal.c \
+ H5MF.c H5MFaggr.c H5MFdbg.c H5MFsection.c \
+ H5MM.c H5MP.c H5MPtest.c \
H5O.c H5Oainfo.c H5Oalloc.c H5Oattr.c \
H5Oattribute.c H5Obogus.c H5Obtreek.c H5Ocache.c \
H5Ocont.c H5Ocopy.c H5Odbg.c H5Odrvinfo.c H5Odtype.c H5Oefl.c \
- H5Ofill.c H5Oginfo.c \
+ H5Ofill.c H5Ofsinfo.c H5Oginfo.c \
H5Olayout.c \
H5Olinfo.c H5Olink.c H5Omessage.c H5Omtime.c \
H5Oname.c H5Onull.c H5Opline.c H5Orefcount.c \
H5Osdspace.c H5Oshared.c H5Ostab.c \
H5Oshmesg.c H5Otest.c H5Ounknown.c \
- H5P.c H5Pacpl.c H5Pdcpl.c \
+ H5P.c H5Pacpl.c H5Pdapl.c H5Pdcpl.c \
H5Pdeprec.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \
H5Pgcpl.c H5Pint.c \
H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pocpypl.c H5Pstrcpl.c H5Ptest.c \
@@ -460,8 +507,10 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5RC.c \
H5RS.c \
H5S.c H5Sall.c H5Sdbg.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c \
- H5Sselect.c H5Stest.c H5SL.c H5SM.c H5SMbtree2.c \
- H5SMcache.c H5SMtest.c H5ST.c \
+ H5Sselect.c H5Stest.c \
+ H5SL.c \
+ H5SM.c H5SMbtree2.c H5SMcache.c H5SMmessage.c H5SMtest.c \
+ H5ST.c \
H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c H5Tcompound.c H5Tconv.c \
H5Tcset.c H5Tdbg.c H5Tdeprec.c H5Tenum.c H5Tfields.c \
H5Tfixed.c \
@@ -474,7 +523,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
# Public headers
-include_HEADERS = hdf5.h H5api_adpt.h H5pubconf.h H5public.h H5version.h \
+include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5version.h \
H5Apublic.h H5ACpublic.h \
H5Cpublic.h H5Dpublic.h \
H5Epubgen.h H5Epublic.h H5Fpublic.h H5FDpublic.h H5FDcore.h H5FDdirect.h \
@@ -513,14 +562,14 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --foreign src/Makefile
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -538,6 +587,7 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
H5config.h: stamp-h1
@if test ! -f $@; then \
@@ -549,7 +599,7 @@ stamp-h1: $(srcdir)/H5config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status src/H5config.h
$(srcdir)/H5config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- cd $(top_srcdir) && $(AUTOHEADER)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
touch $@
@@ -560,20 +610,24 @@ libhdf5.settings: $(top_builddir)/config.status $(srcdir)/libhdf5.settings.in
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
if test -f $$p; then \
- f=$(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ list2="$$list2 $$p"; \
else :; fi; \
- done
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- p=$(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
@@ -588,11 +642,13 @@ libhdf5.la: $(libhdf5_la_OBJECTS) $(libhdf5_la_DEPENDENCIES)
$(libhdf5_la_LINK) -rpath $(libdir) $(libhdf5_la_OBJECTS) $(libhdf5_la_LIBADD) $(LIBS)
clean-noinstPROGRAMS:
- @list='$(noinst_PROGRAMS)'; for p in $$list; do \
- f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
- echo " rm -f $$p $$f"; \
- rm -f $$p $$f ; \
- done
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
H5detect$(EXEEXT): $(H5detect_OBJECTS) $(H5detect_DEPENDENCIES)
@rm -f H5detect$(EXEEXT)
$(H5detect_LINK) $(H5detect_OBJECTS) $(H5detect_LDADD) $(LIBS)
@@ -615,13 +671,16 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5B2.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5B2cache.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5B2dbg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5B2hdr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5B2int.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5B2stat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5B2test.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Bcache.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Bdbg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5C.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5CS.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5D.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dbtree.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dchunk.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dcompact.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dcontig.Plo@am__quote@
@@ -631,20 +690,40 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dfill.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dint.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dio.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Distore.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dlayout.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dmpio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Doh.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dscatgath.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dselect.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dtest.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5E.Plo@am__quote@
+@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@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAint.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAsblock.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAstat.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAtest.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Edeprec.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Eint.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5F.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FA.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FAcache.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FAdbg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FAdblkpage.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FAdblock.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FAhdr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FAstat.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FAtest.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FD.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDcore.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDdirect.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDfamily.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDint.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDlog.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDmpi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDmpio.Plo@am__quote@
@@ -659,14 +738,23 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FScache.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FSdbg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FSsection.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FSstat.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FStest.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Faccum.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fdbg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fdeprec.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ffake.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fmount.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fmpi.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fquery.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fsfile.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fsuper.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fsuper_cache.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ftest.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5G.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gbtree2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gcache.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gcompact.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gdense.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gdeprec.Plo@am__quote@
@@ -678,6 +766,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gnode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gobj.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Goh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Groot.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gstab.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gtest.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gtraverse.Plo@am__quote@
@@ -698,14 +787,19 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HFtest.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HFtiny.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HG.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HGcache.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HGdbg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HL.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HLcache.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HLdbg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HP.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5I.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5L.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Lexternal.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MF.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MFaggr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MFdbg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MFsection.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MM.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MP.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MPtest.Plo@am__quote@
@@ -724,6 +818,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Odtype.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Oefl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ofill.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ofsinfo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Oginfo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Olayout.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Olinfo.Plo@am__quote@
@@ -742,6 +837,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ounknown.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5P.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pacpl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pdapl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pdcpl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pdeprec.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pdxpl.Plo@am__quote@
@@ -765,6 +861,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5SM.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5SMbtree2.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5SMcache.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5SMmessage.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5SMtest.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5ST.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Sall.Plo@am__quote@
@@ -819,35 +916,35 @@ distclean-compile:
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
H5detect-H5detect.o: H5detect.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(H5detect_CFLAGS) $(CFLAGS) -MT H5detect-H5detect.o -MD -MP -MF $(DEPDIR)/H5detect-H5detect.Tpo -c -o H5detect-H5detect.o `test -f 'H5detect.c' || echo '$(srcdir)/'`H5detect.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/H5detect-H5detect.Tpo $(DEPDIR)/H5detect-H5detect.Po
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/H5detect-H5detect.Tpo $(DEPDIR)/H5detect-H5detect.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='H5detect.c' object='H5detect-H5detect.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(H5detect_CFLAGS) $(CFLAGS) -c -o H5detect-H5detect.o `test -f 'H5detect.c' || echo '$(srcdir)/'`H5detect.c
H5detect-H5detect.obj: H5detect.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(H5detect_CFLAGS) $(CFLAGS) -MT H5detect-H5detect.obj -MD -MP -MF $(DEPDIR)/H5detect-H5detect.Tpo -c -o H5detect-H5detect.obj `if test -f 'H5detect.c'; then $(CYGPATH_W) 'H5detect.c'; else $(CYGPATH_W) '$(srcdir)/H5detect.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/H5detect-H5detect.Tpo $(DEPDIR)/H5detect-H5detect.Po
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/H5detect-H5detect.Tpo $(DEPDIR)/H5detect-H5detect.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='H5detect.c' object='H5detect-H5detect.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(H5detect_CFLAGS) $(CFLAGS) -c -o H5detect-H5detect.obj `if test -f 'H5detect.c'; then $(CYGPATH_W) 'H5detect.c'; else $(CYGPATH_W) '$(srcdir)/H5detect.c'; fi`
@@ -860,51 +957,57 @@ clean-libtool:
install-settingsDATA: $(settings_DATA)
@$(NORMAL_INSTALL)
test -z "$(settingsdir)" || $(MKDIR_P) "$(DESTDIR)$(settingsdir)"
- @list='$(settings_DATA)'; for p in $$list; do \
+ @list='$(settings_DATA)'; test -n "$(settingsdir)" || list=; \
+ for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- f=$(am__strip_dir) \
- echo " $(settingsDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(settingsdir)/$$f'"; \
- $(settingsDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(settingsdir)/$$f"; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(settingsdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(settingsdir)" || exit $$?; \
done
uninstall-settingsDATA:
@$(NORMAL_UNINSTALL)
- @list='$(settings_DATA)'; for p in $$list; do \
- f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(settingsdir)/$$f'"; \
- rm -f "$(DESTDIR)$(settingsdir)/$$f"; \
- done
+ @list='$(settings_DATA)'; test -n "$(settingsdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(settingsdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(settingsdir)" && rm -f $$files
install-includeHEADERS: $(include_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
- @list='$(include_HEADERS)'; for p in $$list; do \
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- f=$(am__strip_dir) \
- echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \
- $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
done
uninstall-includeHEADERS:
@$(NORMAL_UNINSTALL)
- @list='$(include_HEADERS)'; for p in $$list; do \
- f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \
- rm -f "$(DESTDIR)$(includedir)/$$f"; \
- done
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(includedir)" && rm -f $$files
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) H5config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
- tags=; \
+ set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) H5config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
@@ -912,29 +1015,34 @@ TAGS: $(HEADERS) $(SOURCES) H5config.h.in $(TAGS_DEPENDENCIES) \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
- if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$tags $$unique; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) H5config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
- tags=; \
list='$(SOURCES) $(HEADERS) H5config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
- test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$tags $$unique
+ $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
- && cd $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) $$here
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
@@ -955,13 +1063,17 @@ distdir: $(DISTFILES)
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@@ -995,6 +1107,7 @@ clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic:
@@ -1017,6 +1130,8 @@ dvi-am:
html: html-am
+html-am:
+
info: info-am
info-am:
@@ -1025,18 +1140,28 @@ install-data-am: install-includeHEADERS install-settingsDATA
install-dvi: install-dvi-am
+install-dvi-am:
+
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
+install-html-am:
+
install-info: install-info-am
+install-info-am:
+
install-man:
install-pdf: install-pdf-am
+install-pdf-am:
+
install-ps: install-ps-am
+install-ps-am:
+
installcheck-am:
maintainer-clean: maintainer-clean-am
@@ -1060,7 +1185,7 @@ ps-am:
uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES \
uninstall-settingsDATA
-.MAKE: install-am install-strip
+.MAKE: all check-am install-am install-strip
.PHONY: CTAGS GTAGS all all-am all-local check check-TESTS check-am \
clean clean-generic clean-libLTLIBRARIES clean-libtool \
@@ -1112,7 +1237,7 @@ help:
H5Tinit.c: H5detect$(EXEEXT)
LD_LIBRARY_PATH="$$LD_LIBRARY_PATH`echo $(LDFLAGS) | \
sed -e 's/-L/:/g' -e 's/ //g'`" \
- $(RUNSERIAL) ./H5detect > H5Tinit.c || \
+ $(RUNSERIAL) ./H5detect$(EXEEXT) > H5Tinit.c || \
(test $$HDF5_Make_Ignore && echo "*** Error ignored") || \
($(RM) $@ ; exit 1)
@@ -1128,6 +1253,10 @@ $(top_srcdir)/src/H5Edefin.h: $(top_srcdir)/src/H5err.txt
$(top_srcdir)/src/H5version.h: $(top_srcdir)/src/H5vers.txt
perl $(top_srcdir)/bin/make_vers $?
+# Assignment overflow macro generation
+$(top_srcdir)/src/H5overflow.h: $(top_srcdir)/src/H5overflow.txt
+ perl $(top_srcdir)/bin/make_overflow $?
+
# Add TRACE macros to library source files. This is done via the trace script
# in the hdf5/bin directory. If the file contains HDF5 API macros, a "clean"
# version of the source file is saved with a tilde (~) after its name and
@@ -1340,6 +1469,7 @@ check-vfd: $(LIB) $(PROGS) $(TESTS)
HDF5_DRIVER=$$vfd $(MAKE) $(AM_MAKEFLAGS) check || exit 1; \
fi; \
done
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/src/libhdf5.settings.in b/src/libhdf5.settings.in
index 380d26b..a3032e5 100644
--- a/src/libhdf5.settings.in
+++ b/src/libhdf5.settings.in
@@ -11,53 +11,58 @@ General Information:
Uname information: @UNAME_INFO@
Byte sex: @BYTESEX@
Libraries: @STATIC_SHARED@
- Parallel support: @PARALLEL@
Installation point: @prefix@
- Compiler: @CC_VERSION@
- Compiler switches: @CFLAGS@ @CPPFLAGS@
- Extra libraries: @LDFLAGS@ @LIBS@
- Archiver: @AR@
- Ranlib: @RANLIB@
- Debugged Packages: @DEBUG_PKG@
- API Tracing: @TRACE_API@
Compiling Options:
------------------
Compilation Mode: @CONFIG_MODE@
C Compiler: @CC_VERSION@
- CFLAGS/H5_CFLAGS: @CFLAGS@/@H5_CFLAGS@
- CPPFLAGS/H5_CPPFLAGS: @CPPFLAGS@/@H5_CPPFLAGS@
- LDFLAGS: @LDFLAGS@
- Debug Mode: @DEBUG_PKG@
+ CFLAGS: @CFLAGS@
+ H5_CFLAGS: @H5_CFLAGS@
+ AM_CFLAGS: @AM_CFLAGS@
+ CPPFLAGS: @CPPFLAGS@
+ H5_CPPFLAGS: @H5_CPPFLAGS@
+ AM_CPPFLAGS: @AM_CPPFLAGS@
Shared Libraries: @enable_shared@
Static Libraries: @enable_static@
Statically Linked Executables: @STATIC_EXEC@
- Default Public Symbols Version: @DEFAULT_API_VERSION@
- With Deprecated Public Symbols: @DEPRECATED_SYMBOLS@
- Tracing: @TRACE_API@
-Clear file buffers before write: @CLEARFILEBUF@
- Using memory checker: @USINGMEMCHECKER@
- Optimization Instrumentation: @INSTRUMENT@
+ LDFLAGS: @LDFLAGS@
+ AM_LDFLAGS: @AM_LDFLAGS@
+ Extra libraries: @LIBS@
+ Archiver: @AR@
+ Ranlib: @RANLIB@
+ Debugged Packages: @DEBUG_PKG@
+ API Tracing: @TRACE_API@
Languages:
----------
Fortran: @HDF_FORTRAN@
-@BUILD_FORTRAN_CONDITIONAL_TRUE@ Fortran Compiler: @FC@@FCFLAGS@
+@BUILD_FORTRAN_CONDITIONAL_TRUE@ Fortran Compiler: @FC@
+@BUILD_FORTRAN_CONDITIONAL_TRUE@ Fortran Flags: @FCFLAGS@
+@BUILD_FORTRAN_CONDITIONAL_TRUE@ H5 Fortran Flags: @H5_FCFLAGS@
+@BUILD_FORTRAN_CONDITIONAL_TRUE@ AM Fortran Flags: @AM_FCFLAGS@
C++: @HDF_CXX@
-@BUILD_CXX_CONDITIONAL_TRUE@ C++ Compiler: @CXX@@CXXFLAGS@
+@BUILD_CXX_CONDITIONAL_TRUE@ C++ Compiler: @CXX@
+@BUILD_CXX_CONDITIONAL_TRUE@ C++ Flags: @CXXFLAGS@
+@BUILD_CXX_CONDITIONAL_TRUE@ H5 C++ Flags: @H5_CXXFLAGS@
+@BUILD_CXX_CONDITIONAL_TRUE@ AM C++ Flags: @AM_CXXFLAGS@
Features:
---------
- dmalloc: @HAVE_DMALLOC@
- Function Stack Tracing: @CODESTACK@
- GPFS: @GPFS@
- Strict File Format Checks: @STRICT_FORMAT_CHECKS@
+ Parallel HDF5: @PARALLEL@
+ High Level library: @HDF5_HL@
+ Threadsafety: @THREADSAFE@
Default API Mapping: @DEFAULT_API_VERSION@
+ With Deprecated Public Symbols: @DEPRECATED_SYMBOLS@
I/O filters (external): @EXTERNAL_FILTERS@
I/O filters (internal): @FILTERS@
- Linux Large File Support (LFS): @LINUX_LFS@
MPE: @MPE@
- Parallel HDF5: @PARALLEL@
Direct VFD: @DIRECT_VFD@
- Threadsafety: @THREADSAFE@
- High Level library: @HDF5_HL@
+ dmalloc: @HAVE_DMALLOC@
+Clear file buffers before write: @CLEARFILEBUF@
+ Using memory checker: @USINGMEMCHECKER@
+ Function Stack Tracing: @CODESTACK@
+ GPFS: @GPFS@
+ Strict File Format Checks: @STRICT_FORMAT_CHECKS@
+ Optimization Instrumentation: @INSTRUMENT@
+ Linux Large File Support (LFS): @LINUX_LFS@