From 37ec6dc75e85ebd7f9fb9b32fe978e47ab3fe918 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 1 Oct 2009 21:08:59 -0500 Subject: [svn-r17582] Description: Bring changes from file free space branch back to the trunk. *yay!* Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/Intel compilers, w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in debug mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode Mac OS X/32 10.5.8 (amazon) in debug mode Mac OS X/32 10.5.8 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode --- MANIFEST | 7 + bin/make_vers | 35 +- bin/trace | 5 +- c++/src/H5FcreatProp.cpp | 2 + c++/src/H5FcreatProp.h | 2 + configure | 14 +- configure.in | 11 +- fortran/src/H5Pf.c | 14 +- src/H5F.c | 87 +- src/H5FS.c | 180 ++- src/H5FScache.c | 17 +- src/H5FSdbg.c | 6 +- src/H5FSprivate.h | 5 + src/H5FSsection.c | 65 ++ src/H5Fdeprec.c | 172 +++ src/H5Fpkg.h | 7 +- src/H5Fprivate.h | 7 + src/H5Fpublic.h | 65 +- src/H5Fsuper.c | 87 ++ src/H5Fsuper_cache.c | 36 + src/H5MF.c | 314 +++++- src/H5MFaggr.c | 8 +- src/H5MFdbg.c | 62 +- src/H5MFprivate.h | 4 +- src/H5O.c | 1 + src/H5Ofsinfo.c | 309 ++++++ src/H5Opkg.h | 4 +- src/H5Oprivate.h | 12 + src/H5Pdeprec.c | 54 + src/H5Pfcpl.c | 152 ++- src/H5Ppublic.h | 9 +- src/H5SM.c | 13 +- src/H5SMprivate.h | 2 +- src/H5trace.c | 75 ++ src/H5vers.txt | 1 + src/H5version.h | 130 ++- src/Makefile.am | 5 +- src/Makefile.in | 29 +- test/Makefile.am | 2 +- test/Makefile.in | 38 +- test/filespace_1_6.h5 | Bin 0 -> 2448 bytes test/filespace_1_8.h5 | Bin 0 -> 2448 bytes test/gen_filespace.c | 81 ++ test/mf.c | 1513 ++++++++++++++++++++++++-- test/tfile.c | 705 ++++++++++++ test/tmisc.c | 67 +- tools/h5dump/h5dump.c | 33 +- tools/h5dump/h5dumpgentest.c | 32 +- tools/h5dump/testh5dump.sh.in | 1 + tools/h5repack/h5repack.c | 7 +- tools/h5repack/h5repack.h | 17 +- tools/h5repack/h5repack_copy.c | 46 +- tools/h5repack/h5repack_main.c | 30 +- tools/h5repack/h5repack_verify.c | 111 +- tools/h5repack/h5repacktst.c | 229 ++-- tools/h5stat/h5stat.c | 321 +++++- tools/h5stat/h5stat_gentest.c | 24 +- tools/h5stat/testfiles/h5stat_filters-F.ddl | 21 +- tools/h5stat/testfiles/h5stat_filters-d.ddl | 3 +- tools/h5stat/testfiles/h5stat_filters-dT.ddl | 3 +- tools/h5stat/testfiles/h5stat_filters.ddl | 28 +- tools/h5stat/testfiles/h5stat_help1.ddl | 3 +- tools/h5stat/testfiles/h5stat_help2.ddl | 3 +- tools/h5stat/testfiles/h5stat_newgrat.ddl | 38 +- tools/h5stat/testfiles/h5stat_newgrat.h5 | Bin 6363081 -> 6367669 bytes tools/h5stat/testfiles/h5stat_tsohm.ddl | 26 +- tools/testfiles/file_space.ddl | 23 + tools/testfiles/file_space.h5 | Bin 0 -> 792 bytes tools/testfiles/tboot1.ddl | 2 + tools/testfiles/tboot2.ddl | 2 + 70 files changed, 4868 insertions(+), 549 deletions(-) create mode 100644 src/H5Fdeprec.c create mode 100644 src/H5Ofsinfo.c create mode 100644 test/filespace_1_6.h5 create mode 100644 test/filespace_1_8.h5 create mode 100644 test/gen_filespace.c create mode 100644 tools/testfiles/file_space.ddl create mode 100644 tools/testfiles/file_space.h5 diff --git a/MANIFEST b/MANIFEST index 1e26b56..489baab 100644 --- a/MANIFEST +++ b/MANIFEST @@ -517,6 +517,7 @@ ./src/H5F.c ./src/H5Faccum.c ./src/H5Fdbg.c +./src/H5Fdeprec.c ./src/H5Ffake.c ./src/H5Fio.c ./src/H5Fmount.c @@ -671,6 +672,7 @@ ./src/H5Odtype.c ./src/H5Oefl.c ./src/H5Ofill.c +./src/H5Ofsinfo.c ./src/H5Oginfo.c ./src/H5Olayout.c ./src/H5Olinfo.c @@ -826,6 +828,8 @@ ./test/family_v16_00003.h5 ./test/farray.c ./test/fheap.c +./test/filespace_1_8.h5 +./test/filespace_1_6.h5 ./test/freespace.c ./test/fill_old.h5 ./test/fillval.c @@ -835,6 +839,7 @@ ./test/gen_bogus.c _DO_NOT_DISTRIBUTE_ ./test/gen_cross.c _DO_NOT_DISTRIBUTE_ ./test/gen_deflate.c _DO_NOT_DISTRIBUTE_ +./test/gen_filespace.c _DO_NOT_DISTRIBUTE_ ./test/gen_mergemsg.c _DO_NOT_DISTRIBUTE_ ./test/gen_new_array.c _DO_NOT_DISTRIBUTE_ ./test/gen_new_fill.c _DO_NOT_DISTRIBUTE_ @@ -1129,6 +1134,8 @@ ./tools/testfiles/family_file00015.h5 ./tools/testfiles/family_file00016.h5 ./tools/testfiles/family_file00017.h5 +./tools/testfiles/file_space.h5 +./tools/testfiles/file_space.ddl ./tools/testfiles/tall-1.ddl ./tools/testfiles/tall-2.ddl ./tools/testfiles/tall-3.ddl diff --git a/bin/make_vers b/bin/make_vers index 2cfad4c..8541501 100755 --- a/bin/make_vers +++ b/bin/make_vers @@ -4,7 +4,7 @@ require 5.003; # Global settings # Max. library "index" (0 = v1.0, 1 = 1.2, etc) -$max_idx = 4; +$max_idx = 5; # Min. supported previous library version "index" (0 = v1.0, 1 = 1.2, etc) $min_sup_idx = 3; @@ -86,9 +86,9 @@ sub print_checkoptions ($) { # Print the option checking print $fh "\n/* Issue error if contradicting macros have been defined. */\n"; - print $fh "#if defined(H5_USE_16_API) && defined(H5_NO_DEPRECATED_SYMBOLS)\n"; + print $fh "#if (defined(H5_USE_16_API) || defined(H5_USE_18_API)) && defined(H5_NO_DEPRECATED_SYMBOLS)\n"; print $fh "#error \"Can't choose old API versions when deprecated APIs are disabled\"\n"; - print $fh "#endif /* defined(H5_USE_16_API) && defined(H5_NO_DEPRECATED_SYMBOLS) */\n"; + print $fh "#endif /* (defined(H5_USE_16_API) || defined(H5_USE_18_API)) && defined(H5_NO_DEPRECATED_SYMBOLS) */\n"; } ############################################################################## @@ -118,7 +118,7 @@ sub print_globalapivers ($) { # Loop over supported older library APIs and define the appropriate macros for $curr_idx ($min_sup_idx .. ($max_idx - 1)) { # Print API version ifdef - print $fh "#ifdef H5_USE_1", ($curr_idx * 2), "_API\n"; + print $fh "\n#ifdef H5_USE_1", ($curr_idx * 2), "_API\n"; # Print the version macro info for each function that is defined for # this API version @@ -271,6 +271,7 @@ sub parse_line ($) { my $params; # Typedefs for function parameters my $vers; # The version info for the function my @vers_list; # Version info, as a list + my @vers_nums; # Version info, as a numeric list my $num_versions; # Number of versions for function my %sym_versions; # Versions for a symbol my $last_idx; # The previous version index seen for a function @@ -308,15 +309,12 @@ sub parse_line ($) { @vers_list = split(/\s*,\s*/, $vers); #print "parse_line: vers_list=(@vers_list)\n"; - # Check for invalid version info given - $last_idx = -1; - $last_vers = 1; - foreach(sort(@vers_list)) { + # Parse the version list into numbers, checking for invalid input + foreach(@vers_list) { my $vers_idx; # Index of version in array -#print "parse_line: _=$_ last_idx='$last_idx'\n"; # Do some validation on the input - if(!($_ =~ /v1[02468]/)) { + if(!( $_ =~ /v1[02468]/ || $_ =~ /v11[02468]/ )) { die "bad version information: $name"; } if(exists($sym_versions{$_})) { @@ -326,18 +324,29 @@ sub parse_line ($) { # Store the versions for the function in a local hash table, indexed by the version $sym_versions{$_}=$_; +#print "parse_line: _=$_\n"; # Get the index of the version - ($vers_idx) = ($_ =~ /v1(\d)/); + ($vers_idx) = ($_ =~ /v1(\d+)/); $vers_idx /= 2; #print "parse_line: vers_idx='$vers_idx'\n"; + push(@vers_nums, $vers_idx); + } +#print "parse_line: vers_nums=(@vers_nums)\n"; + # Check for invalid version info given + $last_idx = -1; + $last_vers = 1; + foreach(sort(@vers_nums)) { +#print "parse_line: _=$_ last_idx='$last_idx'\n"; # Update intermediate versions of the library that included the API routine if($last_idx >= 0) { +#print "parse_line: name='$name'\n"; +#print "parse_line: last_vers='$last_vers'\n"; #print "parse_line: last_idx='$last_idx'\n"; # Add the function to the list of API routines available in # different versions of the library - while($last_idx < $vers_idx) { + while($last_idx <= $_) { if($line_type == 1) { $func_vers[$last_idx]{$name} = $last_vers; } elsif($line_type == 2) { @@ -353,7 +362,7 @@ sub parse_line ($) { } # Keep track of last version index seen - $last_idx = $vers_idx; + $last_idx = $_; } # Finish updating versions of the library that included the API routine diff --git a/bin/trace b/bin/trace index 951d349..e0a4dd0 100755 --- a/bin/trace +++ b/bin/trace @@ -44,6 +44,8 @@ $Source = ""; "H5E_error_t" => "Ee", "H5E_type_t" => "Et", "H5F_close_degree_t" => "Fd", + "H5F_file_space_type_t" => "Ff", + "H5F_mem_t" => "Fm", "H5F_scope_t" => "Fs", "H5F_libver_t" => "Fv", "H5G_obj_t" => "Go", @@ -98,7 +100,8 @@ $Source = ""; "H5E_walk_t" => "x", "H5E_walk1_t" => "x", "H5E_walk2_t" => "x", - "H5F_info_t" => "x", + "H5F_info1_t" => "x", + "H5F_info2_t" => "x", "H5FD_t" => "x", "H5FD_class_t" => "x", "H5FD_stream_fapl_t" => "x", diff --git a/c++/src/H5FcreatProp.cpp b/c++/src/H5FcreatProp.cpp index cdf976a..53d18f6 100644 --- a/c++/src/H5FcreatProp.cpp +++ b/c++/src/H5FcreatProp.cpp @@ -55,6 +55,7 @@ FileCreatPropList::FileCreatPropList( const FileCreatPropList& original ) : Prop //-------------------------------------------------------------------------- FileCreatPropList::FileCreatPropList(const hid_t plist_id) : PropList(plist_id) {} +#ifndef H5_NO_DEPRECATED_SYMBOLS //-------------------------------------------------------------------------- // Function: FileCreatPropList::getVersion ///\brief Retrieves version information for various parts of a file. @@ -76,6 +77,7 @@ void FileCreatPropList::getVersion(unsigned& super, unsigned& freelist, unsigned "H5Pget_version failed"); } } +#endif /* H5_NO_DEPRECATED_SYMBOLS */ //-------------------------------------------------------------------------- // Function: FileCreatPropList::setUserblock diff --git a/c++/src/H5FcreatProp.h b/c++/src/H5FcreatProp.h index ae9c1b0..1aa102f 100644 --- a/c++/src/H5FcreatProp.h +++ b/c++/src/H5FcreatProp.h @@ -30,8 +30,10 @@ class H5_DLLCPP FileCreatPropList : public PropList { // Creates a file create property list. FileCreatPropList(); +#ifndef H5_NO_DEPRECATED_SYMBOLS // Retrieves version information for various parts of a file. void getVersion( unsigned& super, unsigned& freelist, unsigned& stab, unsigned& shhdr ) const; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ // Sets the userblock size field of a file creation property list. void setUserblock( hsize_t size ) const; diff --git a/configure b/configure index 6522367..4ccee6e 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Id: configure.in 17542 2009-09-28 15:44:35Z acheng . +# From configure.in Id: configure.in 17575 2009-10-01 20:10:49Z koziol . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.64 for HDF5 1.9.47. # @@ -1738,9 +1738,9 @@ Optional Packages: --with-mpe=DIR Use MPE instrumentation [default=no] --with-default-vfd=driver Specify default file driver [default=sec2] - --with-default-api-version=(v16|v18) + --with-default-api-version=(v16|v18|v110) Specify default release version of public symbols - [default=v18] + [default=v110] Some influential environment variables: CC C compiler command @@ -27976,7 +27976,7 @@ $as_echo_n "checking which version of public symbols to use by default... " >&6; if test "${with_default_api_version+set}" = set; then : withval=$with_default_api_version; else - withval=v18 + withval=v110 fi @@ -27991,11 +27991,15 @@ elif test "X$withval" = "Xv18"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: v18" >&5 $as_echo "v18" >&6; } DEFAULT_API_VERSION=v18 +elif test "X$withval" = "Xv110"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: v110" >&5 +$as_echo "v110" >&6; } + DEFAULT_API_VERSION=v110 else as_fn_error "invalid version of public symbols given" "$LINENO" 5 fi -if test "X${DEFAULT_API_VERSION}" != "Xv18" -a "X${DEPRECATED_SYMBOLS}" = "Xno" ; then +if test "X${DEFAULT_API_VERSION}" != "Xv110" -a "X${DEPRECATED_SYMBOLS}" = "Xno" ; then as_fn_error "Removing old public API symbols not allowed when using them as default public API symbols" "$LINENO" 5 fi diff --git a/configure.in b/configure.in index 54ab501..def7f6e 100644 --- a/configure.in +++ b/configure.in @@ -3811,10 +3811,10 @@ dnl AC_SUBST([DEFAULT_API_VERSION]) AC_MSG_CHECKING([which version of public symbols to use by default]) AC_ARG_WITH([default-api-version], - [AC_HELP_STRING([--with-default-api-version=(v16|v18)], + [AC_HELP_STRING([--with-default-api-version=(v16|v18|v110)], [Specify default release version of public symbols - [default=v18]])],, - withval=v18) + [default=v110]])],, + withval=v110) if test "X$withval" = "Xv16"; then AC_MSG_RESULT([v16]) @@ -3824,13 +3824,16 @@ if test "X$withval" = "Xv16"; then elif test "X$withval" = "Xv18"; then AC_MSG_RESULT([v18]) DEFAULT_API_VERSION=v18 +elif test "X$withval" = "Xv110"; then + AC_MSG_RESULT([v110]) + DEFAULT_API_VERSION=v110 else AC_MSG_ERROR([invalid version of public symbols given]) fi dnl It's an error to try to disable deprecated public API symbols while dnl choosing an older version of the public API as the default. -if test "X${DEFAULT_API_VERSION}" != "Xv18" -a "X${DEPRECATED_SYMBOLS}" = "Xno" ; then +if test "X${DEFAULT_API_VERSION}" != "Xv110" -a "X${DEPRECATED_SYMBOLS}" = "Xno" ; then AC_MSG_ERROR([Removing old public API symbols not allowed when using them as default public API symbols]) fi diff --git a/fortran/src/H5Pf.c b/fortran/src/H5Pf.c index 95616db..0929d7a 100644 --- a/fortran/src/H5Pf.c +++ b/fortran/src/H5Pf.c @@ -509,7 +509,7 @@ int_f nh5pget_version_c (hid_t_f *prp_id, int_f * boot,int_f * freelist, int_f * stab, int_f *shhdr) { int ret_value = -1; - hid_t c_prp_id; +#ifndef H5_NO_DEPRECATED_SYMBOLS herr_t ret; unsigned c_boot; unsigned c_freelist; @@ -519,14 +519,22 @@ nh5pget_version_c (hid_t_f *prp_id, int_f * boot,int_f * freelist, int_f * stab, /* * Call H5Pget_version function. */ - c_prp_id = *prp_id; - ret = H5Pget_version(c_prp_id, &c_boot, &c_freelist, &c_stab, &c_shhdr); + ret = H5Pget_version((hid_t)*prp_id, &c_boot, &c_freelist, &c_stab, &c_shhdr); if (ret < 0) return ret_value; *boot = (int_f)c_boot; *freelist = (int_f)c_freelist; *stab = (int_f)c_stab; *shhdr = (int_f)c_shhdr; +#else /* H5_NO_DEPRECATED_SYMBOLS */ + /* + * Fill in fake values [since we need a file ID to call H5Fget_info :-( -QAK ] + */ + *boot = (int_f)0; + *freelist = (int_f)0; + *stab = (int_f)0; + *shhdr = (int_f)0; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ ret_value = 0; return ret_value; diff --git a/src/H5F.c b/src/H5F.c index d259db4..0195b5a 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -891,6 +891,10 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) 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 = (H5P_genplist_t *)H5I_object(fapl_id))) @@ -1025,9 +1029,11 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) * and also because releasing free space can shrink the file's * 'eoa' value) */ - 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") + 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) @@ -2775,11 +2781,13 @@ 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 @@ -2790,12 +2798,12 @@ done: *------------------------------------------------------------------------- */ 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 */ @@ -2821,18 +2829,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)); + + /* 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") - /* Check for superblock extension info */ - 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") + /* 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/H5FS.c b/src/H5FS.c index deb9378..5e3392e 100644 --- a/src/H5FS.c +++ b/src/H5FS.c @@ -477,9 +477,6 @@ HDfprintf(stderr, "%s: Section info is NOT for file free space\n", FUNC); if(fspace->serial_sect_count > 0) /* Sanity check that section info has address */ HDassert(H5F_addr_defined(fspace->sect_addr)); - else - /* Sanity check that section info doesn't have address */ - HDassert(!H5F_addr_defined(fspace->sect_addr)); } /* end else */ /* Decrement the reference count on the free space manager header */ @@ -723,6 +720,183 @@ 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 /*------------------------------------------------------------------------- diff --git a/src/H5FScache.c b/src/H5FScache.c index a7978f5..482b9cb 100644 --- a/src/H5FScache.c +++ b/src/H5FScache.c @@ -334,10 +334,7 @@ HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu, fspace->sect_size = %Hu\n" 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 */ - else { - /* Sanity check that section info doesn't have address */ - HDassert(!H5F_addr_defined(fspace->sect_addr)); - } /* end else */ + #ifdef QAK HDfprintf(stderr, "%s: Check 2.0\n", FUNC); HDfprintf(stderr, "%s: fspace->sect_addr = %a, fspace->sinfo = %p\n", FUNC, fspace->sect_addr, fspace->sinfo); @@ -348,15 +345,9 @@ HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu, fspace->sect_size = %Hu\n" fspace->sinfo->dirty = FALSE; } /* end if */ } /* end if */ - else { - /* Just sanity checks... */ - if(fspace->serial_sect_count > 0) - /* Sanity check that section info has address */ - HDassert(H5F_addr_defined(fspace->sect_addr)); - else - /* Sanity check that section info doesn't have address */ - HDassert(!H5F_addr_defined(fspace->sect_addr)); - } /* end else */ + 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 */ diff --git a/src/H5FSdbg.c b/src/H5FSdbg.c index df48240..8cf64ef 100644 --- a/src/H5FSdbg.c +++ b/src/H5FSdbg.c @@ -286,10 +286,8 @@ H5FS_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, FILE *stream, int break; case H5FS_CLIENT_FILE_ID: -#ifdef NOT_YET - 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") -#endif /* NOT_YET */ + 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: diff --git a/src/H5FSprivate.h b/src/H5FSprivate.h index 056449d..145c374 100644 --- a/src/H5FSprivate.h +++ b/src/H5FSprivate.h @@ -180,10 +180,15 @@ H5_DLL H5FS_t *H5FS_open(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr, 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, diff --git a/src/H5FSsection.c b/src/H5FSsection.c index 26ff7b9..30885a9 100644 --- a/src/H5FSsection.c +++ b/src/H5FSsection.c @@ -1562,6 +1562,71 @@ done: /*------------------------------------------------------------------------- + * 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, §, 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 diff --git a/src/H5Fdeprec.c b/src/H5Fdeprec.c new file mode 100644 index 0000000..46d7979 --- /dev/null +++ b/src/H5Fdeprec.c @@ -0,0 +1,172 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 + * + * 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 */ + + +/****************/ +/* 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/H5Fpkg.h b/src/H5Fpkg.h index cf40a86..94a24df 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -69,7 +69,9 @@ #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) TRUE /* Currently always have 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 */ @@ -229,6 +231,8 @@ typedef struct H5F_file_t { 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) */ @@ -303,6 +307,7 @@ H5_DLL herr_t H5F_super_size(H5F_t *f, hid_t dxpl_id, hsize_t *super_size, hsize /* 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 */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 574c4dc..8dae885 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -350,6 +350,8 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_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 */ @@ -401,6 +403,11 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t; 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) */ diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index 20814b6..a26c814 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -101,14 +101,23 @@ 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 @@ -128,12 +137,30 @@ typedef enum H5F_mem_t { 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 { H5F_LIBVER_EARLIEST, /* Use the earliest possible format for storing objects */ 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 @@ -169,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/H5Fsuper.c b/src/H5Fsuper.c index 9c12f15..c24cfa1 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -400,6 +400,12 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id) /* 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. @@ -495,6 +501,12 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id) HDassert(super_vers >= HDF5_SUPERBLOCK_VERSION_2); need_ext = TRUE; } /* end if */ + /* 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. @@ -571,6 +583,18 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update driver info header message") } /* end if */ + /* 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") @@ -769,3 +793,66 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5F_super_ext_write_msg() */ + +/*------------------------------------------------------------------------- + * Function: H5F_super_ext_remove_msg + * + * Purpose: Remove the message with ID from the superblock extension + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; Feb 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_super_ext_remove_msg(H5F_t *f, hid_t dxpl_id, unsigned id) +{ + 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_remove_msg() */ + diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index 39899f0..ada9e57 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -480,6 +480,7 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1 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 @@ -564,6 +565,41 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1 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") diff --git a/src/H5MF.c b/src/H5MF.c index b59af88..0129c1d 100644 --- a/src/H5MF.c +++ b/src/H5MF.c @@ -65,6 +65,13 @@ typedef enum { 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 */ @@ -628,6 +635,12 @@ HDfprintf(stderr, "%s: Trying to avoid starting up free space manager\n", FUNC); 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 */ /* If we are deleting the free space manager, leave now, to avoid @@ -654,7 +667,6 @@ HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", FUNC, a 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 */ - HDassert(f->shared->fs_man[fs_type]); /* Create free space section for block */ if(NULL == (node = H5MF_sect_simple_new(addr, size))) @@ -666,16 +678,31 @@ HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", FUNC, a udata.alloc_type = alloc_type; udata.allow_sect_absorb = TRUE; - /* Add to the free space for the file */ + /* 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 */ - 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; + /* 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 */ @@ -970,55 +997,147 @@ HDfprintf(stderr, "%s: Entering\n", FUNC); if(H5MF_free_aggrs(f, dxpl_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't free aggregators") - /* 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)) { + /* 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") + + 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 */ + + /* 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") + + /* 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]) { + /* 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 */ + 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 */ - /* (XXX: Make this optional when free space for a file can be persistant) */ - if(H5F_addr_defined(f->shared->fs_addr[type])) { - haddr_t tmp_fs_addr; /* Temporary holder for free space manager address */ + /* 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; + /* 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; + /* 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; + /* 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") - /* 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 */ + /* 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) */ @@ -1032,3 +1151,126 @@ HDfprintf(stderr, "%s: Leaving\n", FUNC); 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, §_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) +} /* H5MF_get_free_sections() */ + diff --git a/src/H5MFaggr.c b/src/H5MFaggr.c index aa982da..db13408 100644 --- a/src/H5MFaggr.c +++ b/src/H5MFaggr.c @@ -177,11 +177,11 @@ HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size); HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, HADDR_UNDEF, "Unable to get eoa") /* - * If the aggregation feature is enabled for this file, allocate "generic" - * space and sub-allocate out of that, if possible. Otherwise just allocate - * through H5FD_alloc() + * 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) { + 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 */ diff --git a/src/H5MFdbg.c b/src/H5MFdbg.c index ca87c83..31cff15 100644 --- a/src/H5MFdbg.c +++ b/src/H5MFdbg.c @@ -41,7 +41,6 @@ #include "H5Fpkg.h" /* File access */ #include "H5MFpkg.h" /* File memory management */ -#ifdef H5MF_ALLOC_DEBUG_DUMP /****************/ /* Local Macros */ @@ -139,6 +138,67 @@ 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 diff --git a/src/H5MFprivate.h b/src/H5MFprivate.h index 3f2a427..b471aa3 100644 --- a/src/H5MFprivate.h +++ b/src/H5MFprivate.h @@ -73,6 +73,8 @@ 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); @@ -82,10 +84,8 @@ H5_DLL herr_t H5MF_free_aggrs(H5F_t *f, hid_t dxpl_id); /* Debugging routines */ #ifdef H5MF_DEBUGGING -#ifdef NOT_YET H5_DLL herr_t H5MF_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth); -#endif /* NOT_YET */ #endif /* H5MF_DEBUGGING */ #endif /* end _H5MFprivate_H */ diff --git a/src/H5O.c b/src/H5O.c index c294d01..24b8fee 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -126,6 +126,7 @@ const H5O_msg_class_t *const H5O_msg_class_g[] = { H5O_MSG_AINFO, /*0x0015 Attribute information */ H5O_MSG_REFCOUNT, /*0x0016 Object's ref. count */ H5O_MSG_UNKNOWN, /*0x0017 Placeholder for unknown message */ + H5O_MSG_FSINFO, /*0x0018 Free-space manager info message */ }; /* Declare a free list to manage the H5O_t struct */ 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/H5Opkg.h b/src/H5Opkg.h index e0a0971..3cae227 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 */ @@ -452,6 +452,8 @@ 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. (0x0018) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_FSINFO[1]; /* * Object header "object" types diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 74b9754..a47a40d 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -167,6 +167,7 @@ typedef struct H5O_copy_t { #define H5O_REFCOUNT_ID 0x0016 /* Reference count message. */ #define H5O_UNKNOWN_ID 0x0017 /* Placeholder message ID for unknown message. */ /* (this should never exist in a file) */ +#define H5O_FSINFO_ID 0x0018 /* Free-space manager info message. */ /* Shared object message types. @@ -551,6 +552,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, diff --git a/src/H5Pdeprec.c b/src/H5Pdeprec.c index 208fcb2..5c72247 100644 --- a/src/H5Pdeprec.c +++ b/src/H5Pdeprec.c @@ -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/H5Pfcpl.c b/src/H5Pfcpl.c index 406dbe1..0653c46 100644 --- a/src/H5Pfcpl.c +++ b/src/H5Pfcpl.c @@ -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 /******************/ @@ -150,6 +155,8 @@ H5P_fcrt_reg_prop(H5P_genclass_t *pclass) 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 @@ -943,3 +904,88 @@ 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/H5Ppublic.h b/src/H5Ppublic.h index 495ba42..1e4cf2f 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -208,9 +208,6 @@ 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); /* 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, @@ -227,6 +224,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 */ @@ -422,7 +421,9 @@ H5_DLL H5Z_filter_t H5Pget_filter1(hid_t plist_id, unsigned filter, 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/H5SM.c b/src/H5SM.c index fad639c..cccddc6 100755 --- a/src/H5SM.c +++ b/src/H5SM.c @@ -2494,7 +2494,7 @@ 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 */ @@ -2506,14 +2506,15 @@ 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") /* Get SOHM header size */ - finfo->sohm.hdr_size = (hsize_t) H5SM_TABLE_SIZE(f) + + *hdr_size = (hsize_t) H5SM_TABLE_SIZE(f) + (hsize_t)(table->num_indexes * H5SM_INDEX_HEADER_SIZE(f)); /* Loop over all the indices for shared messages */ @@ -2521,11 +2522,11 @@ H5SM_ih_size(H5F_t *f, hid_t dxpl_id, H5F_info_t *finfo) /* 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) + if(H5B2_iterate_size(f, dxpl_id, H5SM_INDEX, table->indexes[u].index_addr, &(ih_info->index_size)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") } /* 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); + ih_info->index_size += H5SM_LIST_SIZE(f, table->indexes[u].list_max); /* Check for heap for this index */ if(H5F_addr_defined(table->indexes[u].heap_addr)) { @@ -2534,7 +2535,7 @@ H5SM_ih_size(H5F_t *f, hid_t dxpl_id, H5F_info_t *finfo) HGOTO_ERROR(H5E_HEAP, 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) + if(H5HF_size(fheap, dxpl_id, &(ih_info->heap_size)) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve fractal heap storage info") /* Release the fractal heap */ 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/H5trace.c b/src/H5trace.c index 5f1e128..87696d3 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -658,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_ALL_DEFAULT: + fprintf(out, "H5F_FILE_SPACE_ALL_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) diff --git a/src/H5vers.txt b/src/H5vers.txt index 18a88d9..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 diff --git a/src/H5version.h b/src/H5version.h index 58de2ab..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, @@ -36,6 +36,11 @@ #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 /*************/ @@ -140,6 +145,114 @@ #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 @@ -267,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 diff --git a/src/Makefile.am b/src/Makefile.am index eb31afb..a9f82d7 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -53,7 +53,8 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5E.c H5Edeprec.c H5Eint.c \ H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \ H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ - H5F.c H5Faccum.c H5Fdbg.c H5Ffake.c H5Fio.c H5Fmount.c H5Fmpi.c H5Fquery.c \ + 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 \ @@ -77,7 +78,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.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 \ diff --git a/src/Makefile.in b/src/Makefile.in index ef006a7..d9d05d5 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -106,8 +106,8 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.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 H5Ffake.lo H5Fio.lo H5Fmount.lo \ - H5Fmpi.lo H5Fquery.lo H5Fsfile.lo H5Fsuper.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 \ @@ -127,15 +127,15 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5MPtest.lo H5O.lo H5Oainfo.lo H5Oalloc.lo H5Oattr.lo \ H5Oattribute.lo H5Obogus.lo H5Obtreek.lo H5Ocache.lo \ H5Ocont.lo H5Ocopy.lo H5Odbg.lo H5Odrvinfo.lo H5Odtype.lo \ - H5Oefl.lo H5Ofill.lo H5Oginfo.lo H5Olayout.lo H5Olinfo.lo \ - H5Olink.lo H5Omessage.lo H5Omtime.lo H5Oname.lo H5Onull.lo \ - H5Opline.lo H5Orefcount.lo H5Osdspace.lo H5Oshared.lo \ - H5Ostab.lo H5Oshmesg.lo H5Otest.lo H5Ounknown.lo H5P.lo \ - H5Pacpl.lo H5Pdapl.lo H5Pdcpl.lo H5Pdeprec.lo H5Pdxpl.lo \ - H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo H5Pgcpl.lo H5Pint.lo \ - H5Plapl.lo H5Plcpl.lo H5Pocpl.lo H5Pocpypl.lo H5Pstrcpl.lo \ - H5Ptest.lo H5R.lo H5Rdeprec.lo H5RC.lo H5RS.lo H5S.lo \ - H5Sall.lo H5Sdbg.lo H5Shyper.lo H5Smpio.lo H5Snone.lo \ + 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 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 \ @@ -460,7 +460,8 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5E.c H5Edeprec.c H5Eint.c \ H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \ H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ - H5F.c H5Faccum.c H5Fdbg.c H5Ffake.c H5Fio.c H5Fmount.c H5Fmpi.c H5Fquery.c \ + 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 \ @@ -484,7 +485,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.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 \ @@ -730,6 +731,7 @@ distclean-compile: @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@ @@ -805,6 +807,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@ diff --git a/test/Makefile.am b/test/Makefile.am index 85409dc..d233f96 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -62,7 +62,7 @@ check_PROGRAMS=$(TEST_PROG) error_test err_compat tcheck_version testmeta # so do not appear in this list. BUILD_ALL_PROGS=gen_bad_ohdr gen_bogus gen_cross gen_deflate gen_filters gen_new_array \ gen_new_fill gen_new_group gen_new_mtime gen_new_super gen_noencoder \ - gen_nullspace gen_udlinks space_overflow + gen_nullspace gen_udlinks space_overflow gen_filespace if BUILD_ALL_CONDITIONAL noinst_PROGRAMS=$(BUILD_ALL_PROGS) diff --git a/test/Makefile.in b/test/Makefile.in index 39fc2ef..b52c920 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -92,7 +92,7 @@ am__EXEEXT_2 = gen_bad_ohdr$(EXEEXT) gen_bogus$(EXEEXT) \ gen_new_group$(EXEEXT) gen_new_mtime$(EXEEXT) \ gen_new_super$(EXEEXT) gen_noencoder$(EXEEXT) \ gen_nullspace$(EXEEXT) gen_udlinks$(EXEEXT) \ - space_overflow$(EXEEXT) + space_overflow$(EXEEXT) gen_filespace$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) app_ref_SOURCES = app_ref.c app_ref_OBJECTS = app_ref.$(OBJEXT) @@ -210,6 +210,10 @@ gen_deflate_SOURCES = gen_deflate.c gen_deflate_OBJECTS = gen_deflate.$(OBJEXT) gen_deflate_LDADD = $(LDADD) gen_deflate_DEPENDENCIES = libh5test.la $(LIBHDF5) +gen_filespace_SOURCES = gen_filespace.c +gen_filespace_OBJECTS = gen_filespace.$(OBJEXT) +gen_filespace_LDADD = $(LDADD) +gen_filespace_DEPENDENCIES = libh5test.la $(LIBHDF5) gen_filters_SOURCES = gen_filters.c gen_filters_OBJECTS = gen_filters.$(OBJEXT) gen_filters_LDADD = $(LDADD) @@ -366,11 +370,11 @@ SOURCES = $(libh5test_la_SOURCES) app_ref.c big.c bittests.c btree2.c \ dt_arith.c dtransform.c dtypes.c earray.c enum.c err_compat.c \ error_test.c extend.c external.c farray.c fheap.c fillval.c \ flush1.c flush2.c freespace.c gen_bad_ohdr.c gen_bogus.c \ - gen_cross.c gen_deflate.c gen_filters.c gen_new_array.c \ - gen_new_fill.c gen_new_group.c gen_new_mtime.c gen_new_super.c \ - gen_noencoder.c gen_nullspace.c gen_udlinks.c getname.c \ - gheap.c hyperslab.c istore.c lheap.c links.c mf.c mount.c \ - mtime.c ntypes.c objcopy.c ohdr.c pool.c reserved.c \ + gen_cross.c gen_deflate.c gen_filespace.c gen_filters.c \ + gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c \ + gen_new_super.c gen_noencoder.c gen_nullspace.c gen_udlinks.c \ + getname.c gheap.c hyperslab.c istore.c lheap.c links.c mf.c \ + mount.c mtime.c ntypes.c objcopy.c ohdr.c pool.c reserved.c \ set_extent.c space_overflow.c stab.c tcheck_version.c \ $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c \ vfd.c @@ -379,14 +383,14 @@ DIST_SOURCES = $(libh5test_la_SOURCES) app_ref.c big.c bittests.c \ dsets.c dt_arith.c dtransform.c dtypes.c earray.c enum.c \ err_compat.c error_test.c extend.c external.c farray.c fheap.c \ fillval.c flush1.c flush2.c freespace.c gen_bad_ohdr.c \ - gen_bogus.c gen_cross.c gen_deflate.c gen_filters.c \ - gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c \ - gen_new_super.c gen_noencoder.c gen_nullspace.c gen_udlinks.c \ - getname.c gheap.c hyperslab.c istore.c lheap.c links.c mf.c \ - mount.c mtime.c ntypes.c objcopy.c ohdr.c pool.c reserved.c \ - set_extent.c space_overflow.c stab.c tcheck_version.c \ - $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c \ - vfd.c + gen_bogus.c gen_cross.c gen_deflate.c gen_filespace.c \ + gen_filters.c gen_new_array.c gen_new_fill.c gen_new_group.c \ + gen_new_mtime.c gen_new_super.c gen_noencoder.c \ + gen_nullspace.c gen_udlinks.c getname.c gheap.c hyperslab.c \ + istore.c lheap.c links.c mf.c mount.c mtime.c ntypes.c \ + objcopy.c ohdr.c pool.c reserved.c set_extent.c \ + space_overflow.c stab.c tcheck_version.c $(testhdf5_SOURCES) \ + testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c ETAGS = etags CTAGS = ctags am__tty_colors = \ @@ -701,7 +705,7 @@ TEST_PROG = testhdf5 lheap ohdr stab gheap cache cache_api \ # so do not appear in this list. BUILD_ALL_PROGS = gen_bad_ohdr gen_bogus gen_cross gen_deflate gen_filters gen_new_array \ gen_new_fill gen_new_group gen_new_mtime gen_new_super gen_noencoder \ - gen_nullspace gen_udlinks space_overflow + gen_nullspace gen_udlinks space_overflow gen_filespace # The libh5test library provides common support code for the tests. @@ -899,6 +903,9 @@ gen_cross$(EXEEXT): $(gen_cross_OBJECTS) $(gen_cross_DEPENDENCIES) gen_deflate$(EXEEXT): $(gen_deflate_OBJECTS) $(gen_deflate_DEPENDENCIES) @rm -f gen_deflate$(EXEEXT) $(LINK) $(gen_deflate_OBJECTS) $(gen_deflate_LDADD) $(LIBS) +gen_filespace$(EXEEXT): $(gen_filespace_OBJECTS) $(gen_filespace_DEPENDENCIES) + @rm -f gen_filespace$(EXEEXT) + $(LINK) $(gen_filespace_OBJECTS) $(gen_filespace_LDADD) $(LIBS) gen_filters$(EXEEXT): $(gen_filters_OBJECTS) $(gen_filters_DEPENDENCIES) @rm -f gen_filters$(EXEEXT) $(LINK) $(gen_filters_OBJECTS) $(gen_filters_LDADD) $(LIBS) @@ -1032,6 +1039,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_bogus.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_cross.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_deflate.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_filespace.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_filters.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_new_array.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_new_fill.Po@am__quote@ diff --git a/test/filespace_1_6.h5 b/test/filespace_1_6.h5 new file mode 100644 index 0000000..5afc718 Binary files /dev/null and b/test/filespace_1_6.h5 differ diff --git a/test/filespace_1_8.h5 b/test/filespace_1_8.h5 new file mode 100644 index 0000000..85138b0 Binary files /dev/null and b/test/filespace_1_8.h5 differ diff --git a/test/gen_filespace.c b/test/gen_filespace.c new file mode 100644 index 0000000..e9dee1c --- /dev/null +++ b/test/gen_filespace.c @@ -0,0 +1,81 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "hdf5.h" + +#define NELMTS(X) (sizeof(X)/sizeof(X[0])) /* # of elements */ +#define TEST_THRESHOLD2 2 /* Free space section threshold */ + +const char *FILENAMES[] = { + "filespace_persist.h5", /* H5F_FILE_SPACE_ALL_PERSIST */ + "filespace_default.h5", /* H5F_FILE_SPACE_ALL */ + "filespace_aggr_vfd.h5", /* H5F_FILE_SPACE_AGGR_VFD */ + "filespace_vfd.h5", /* H5F_FILE_SPACE_VFD */ + "filespace_threshold.h5" /* H5F_FILE_SPACE_ALL, non-default threshold */ +}; + +#define DATASET "dset" +#define NUM_ELMTS 100 + +/* + * Compile and run this program in file-space branch to generate + * HDF5 files with different kinds of file space strategies + * Move the HDF5 files to the 1.6 and 1.8 branch for compatibility + * testing:test_filespace_compatible() will use the files + */ +static void gen_file(void) +{ + hid_t fid; + hid_t fcpl; + hid_t dataset, space; + hsize_t dim[1]; + int data[NUM_ELMTS]; + unsigned i, j; /* Local index variable */ + H5F_file_space_type_t fs_type; /* File space handling strategy */ + + for(j = 0, fs_type = H5F_FILE_SPACE_ALL_PERSIST; j < NELMTS(FILENAMES); j++, (H5F_file_space_type_t)(fs_type)++) { + /* Get a copy of the default file creation property */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + + if(fs_type == H5F_FILE_SPACE_NTYPES) /* last file */ + /* Set default strategy but non-default threshold */ + H5Pset_file_space(fcpl, H5F_FILE_SPACE_ALL, (hsize_t)TEST_THRESHOLD2); + else + /* Set specified file space strategy and free space section threshold */ + H5Pset_file_space(fcpl, fs_type, (hsize_t)0); + + /* Create the file with the file space info */ + fid = H5Fcreate(FILENAMES[j], H5F_ACC_TRUNC, fcpl, H5P_DEFAULT); + + dim[0] = NUM_ELMTS; + space = H5Screate_simple(1, dim, NULL); + dataset = H5Dcreate2(fid, DATASET, H5T_NATIVE_INT, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + for(i = 0; i < NUM_ELMTS; i++) + data[i] = i; + + H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data); + H5Dclose(dataset); + H5Sclose(space); + H5Fclose(fid); + } +} + +int main(void) +{ + gen_file(); + + return 0; +} diff --git a/test/mf.c b/test/mf.c index 3c88501..ca89b79 100644 --- a/test/mf.c +++ b/test/mf.c @@ -19,6 +19,7 @@ * test_mf_fs_*() tests for file memory that interact with the free-space manager * test_mf_aggr_*() tests for file memory that interact with the aggregators * test_mf_align_*() tests for file memory with alignment setting + * test_filespace_*() tests for file space management */ #include "h5test.h" @@ -39,7 +40,14 @@ #define FILENAME_LEN 1024 +#define TEST_BLOCK_SIZE1 1 +#define TEST_BLOCK_SIZE2 2 +#define TEST_BLOCK_SIZE3 3 +#define TEST_BLOCK_SIZE4 4 #define TEST_BLOCK_SIZE5 5 +#define TEST_BLOCK_SIZE6 6 +#define TEST_BLOCK_SIZE7 7 +#define TEST_BLOCK_SIZE8 8 #define TEST_BLOCK_SIZE20 20 #define TEST_BLOCK_SIZE30 30 #define TEST_BLOCK_SIZE40 40 @@ -60,6 +68,12 @@ #define TEST_ALIGN1024 1024 #define TEST_ALIGN4096 4096 +#define TEST_THRESHOLD10 10 +#define TEST_THRESHOLD3 3 + +#define CORE_INCREMENT 1024 +#define FAMILY_SIZE 1024 + const char *FILENAME[] = { "mf", NULL @@ -105,6 +119,11 @@ static unsigned test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t static unsigned test_mf_align_alloc4(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl); static unsigned test_mf_align_alloc5(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl); static unsigned test_mf_align_alloc6(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl); +static unsigned test_mf_fs_persist(hid_t fapl_new, hid_t fcpl); +static unsigned test_mf_fs_gone(hid_t fapl_new, hid_t fcpl); +static unsigned test_mf_fs_split(hid_t fapl_new, hid_t fcpl); +static unsigned test_mf_fs_multi(hid_t fapl, hid_t fcpl); +static unsigned test_mf_fs_drivers(hid_t fapl); /* * Verify statistics for the free-space manager @@ -5846,104 +5865,1450 @@ error: } /* test_mf_align_alloc6() */ -int -main(void) +/* + * Verify that the file's free-space manager persists where there are free sections in the manager + */ +static unsigned +test_mf_fs_persist(hid_t fapl_new, hid_t fcpl) { - hid_t fapl = -1; /* File access property list for data files */ - hid_t new_fapl = -1; /* File access property list for alignment & aggr setting */ - unsigned nerrors = 0; /* Cumulative error count */ - test_type_t curr_test; /* Current test being worked on */ - const char *env_h5_drvr; /* File Driver value from environment */ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5FD_mem_t type; /* File allocation type */ + H5FS_stat_t fs_stat; /* Information for free-space manager */ + haddr_t addr1, addr2, addr3, addr4, addr5, addr6; /* File address for H5FD_MEM_SUPER */ + haddr_t tmp_addr; /* Temporary variable for address */ - /* Get the VFD to use */ - env_h5_drvr = HDgetenv("HDF5_DRIVER"); - if(env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + TESTING("file's free-space manager is persistent"); - fapl = h5_fileaccess(); + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl_new, filename, sizeof(filename)); - /* Make a copy of the FAPL before adjusting the alignment */ - if((new_fapl = H5Pcopy(fapl)) < 0) TEST_ERROR + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl_new)) < 0) + FAIL_STACK_ERROR - /* alignment is not set for the following tests */ - if(H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)1) < 0) + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate 6 blocks */ + type = H5FD_MEM_SUPER; + if(HADDR_UNDEF == (addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE2))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE3))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr4 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE4))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr5 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE5))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr6 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE6))) + FAIL_STACK_ERROR + + /* Put block #1, #3, #5 to H5FD_MEM_SUPER free-space manager */ + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE1) < 0) + FAIL_STACK_ERROR + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr3, (hsize_t)TEST_BLOCK_SIZE3) < 0) + FAIL_STACK_ERROR + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr5, (hsize_t)TEST_BLOCK_SIZE5) < 0) + FAIL_STACK_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* Verify that H5FD_MEM_SUPER free-space manager is there */ + if(!H5F_addr_defined(f->shared->fs_addr[type])) + TEST_ERROR + + /* Start up H5FD_MEM_SUPER free-space manager */ + if(H5MF_alloc_open(f, H5P_DATASET_XFER_DEFAULT, type) < 0) + FAIL_STACK_ERROR + + /* Get info for free-space manager */ + if(H5FS_stat_info(f, f->shared->fs_man[type], &fs_stat) < 0) + FAIL_STACK_ERROR + + /* Verify free-space info */ + if(fs_stat.tot_space < (TEST_BLOCK_SIZE1+TEST_BLOCK_SIZE3+TEST_BLOCK_SIZE5)) TEST_ERROR - /* meta/small data is set to 2048 for the following tests */ - if(H5Pset_meta_block_size(fapl, (hsize_t)TEST_BLOCK_SIZE2048) < 0) + if(fs_stat.serial_sect_count < 3) TEST_ERROR - if(H5Pset_small_data_block_size(fapl, (hsize_t)TEST_BLOCK_SIZE2048) < 0) + + /* Retrieve block #3 from H5FD_MEM_SUPER free-space manager */ + if(HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE3))) + FAIL_STACK_ERROR + if(tmp_addr != addr3) TEST_ERROR - /* interaction with file allocation */ - nerrors += test_mf_eoa(env_h5_drvr, fapl); - nerrors += test_mf_eoa_shrink(env_h5_drvr, fapl); - nerrors += test_mf_eoa_extend(env_h5_drvr, fapl); + /* Retrieve block #1 from H5FD_MEM_SUPER free-space manager */ + if(HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1))) + FAIL_STACK_ERROR + if(tmp_addr != addr1) + TEST_ERROR - /* interaction with temporary file space allocation */ - nerrors += test_mf_tmp(env_h5_drvr, fapl); + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR - /* interaction with free-space manager */ - nerrors += test_mf_fs_start(fapl); - nerrors += test_mf_fs_alloc_free(fapl); - nerrors += test_mf_fs_extend(fapl); - nerrors += test_mf_fs_absorb(env_h5_drvr, fapl); + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR - /* interaction with meta/sdata aggregator */ - nerrors += test_mf_aggr_alloc1(env_h5_drvr, fapl); - nerrors += test_mf_aggr_alloc2(env_h5_drvr, fapl); - nerrors += test_mf_aggr_alloc3(env_h5_drvr, fapl); - nerrors += test_mf_aggr_alloc4(env_h5_drvr, fapl); - nerrors += test_mf_aggr_alloc5(env_h5_drvr, fapl); - nerrors += test_mf_aggr_alloc6(env_h5_drvr, fapl); - nerrors += test_mf_aggr_alloc7(env_h5_drvr, fapl); - nerrors += test_mf_aggr_extend(env_h5_drvr, fapl); - nerrors += test_mf_aggr_absorb(env_h5_drvr, fapl); + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR - /* Tests for alignment */ - for(curr_test = TEST_NORMAL; curr_test < TEST_NTESTS; curr_test++) { + /* Verify that H5FD_MEM_SUPER free-space manager is there */ + if(!H5F_addr_defined(f->shared->fs_addr[type])) + TEST_ERROR - switch(curr_test) { + /* Retrieve block #5 from H5FD_MEM_SUPER free-space manager */ + if(HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE5))) + FAIL_STACK_ERROR + if(tmp_addr != addr5) + TEST_ERROR - case TEST_NORMAL: /* set alignment = 1024 */ - if(H5Pset_alignment(new_fapl, (hsize_t)0, (hsize_t)TEST_ALIGN1024) < 0) - TEST_ERROR - break; + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR - case TEST_AGGR_SMALL: /* set alignment = 4096 */ - if(H5Pset_alignment(new_fapl, (hsize_t)0, (hsize_t)TEST_ALIGN4096) < 0) - TEST_ERROR - break; + PASSED() - default: - TEST_ERROR; - break; - } /* end switch */ + return(0); - nerrors += test_mf_align_eoa(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_fs(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc1(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc2(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc3(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc4(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc5(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc6(env_h5_drvr, fapl, new_fapl); - } /* end if */ +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_fs_persist() */ - if (H5Pclose(new_fapl) < 0) +/* + * Verify that the free-space manager goes away + */ +static unsigned +test_mf_fs_gone(hid_t fapl_new, hid_t fcpl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5FD_mem_t type; /* File allocation type */ + H5FS_stat_t fs_stat; /* Information for free-space manager */ + haddr_t addr1, addr2, addr3, addr4; /* File address for H5FD_MEM_SUPER */ + + TESTING("file's free-space manager is going away"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl_new, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl_new)) < 0) FAIL_STACK_ERROR - h5_cleanup(FILENAME, fapl); - if(nerrors) - goto error; - puts("All free-space manager tests for file memory passed."); + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR - return (0); + /* Allocate 4 blocks */ + type = H5FD_MEM_SUPER; + if(HADDR_UNDEF == (addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE2))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE3))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr4 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE4))) + FAIL_STACK_ERROR + + /* Put block #1, #3 to H5FD_MEM_SUPER free-space manager */ + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE1) < 0) + FAIL_STACK_ERROR + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr3, (hsize_t)TEST_BLOCK_SIZE3) < 0) + FAIL_STACK_ERROR + + /* Retrieve block #1, #3 from H5FD_MEM_SUPER free-space manager */ + if(HADDR_UNDEF == (addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE3))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1))) + FAIL_STACK_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* Verify that the H5FD_MEM_SUPER free-space manager is not there */ + if(H5F_addr_defined(f->shared->fs_addr[type])) + TEST_ERROR + + /* Put block #3 to H5FD_MEM_SUPER free-space manager */ + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr3, (hsize_t)TEST_BLOCK_SIZE3) < 0) + FAIL_STACK_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* Verify that H5FD_MEM_SUPER free-space manager is there */ + if(!H5F_addr_defined(f->shared->fs_addr[type])) + TEST_ERROR + + /* Start up H5FD_MEM_SUPER free-space manager */ + if(H5MF_alloc_open(f, H5P_DATASET_XFER_DEFAULT, type) < 0) + FAIL_STACK_ERROR + + /* Get info for H5FD_MEM_SUPER free-space manager */ + if(H5FS_stat_info(f, f->shared->fs_man[type], &fs_stat) < 0) + FAIL_STACK_ERROR + + /* Verify free-space info */ + if(!H5F_addr_defined(fs_stat.addr) || !H5F_addr_defined(fs_stat.sect_addr)) + TEST_ERROR + if(fs_stat.tot_space < TEST_BLOCK_SIZE3) + TEST_ERROR + + /* Put block #4 to H5FD_MEM_SUPER free-space manager */ + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr4, (hsize_t)TEST_BLOCK_SIZE4) < 0) + FAIL_STACK_ERROR + + /* The H5FD_MEM_SUPER free-space manager will go away at H5MF_close() */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* Verify that the H5FD_MEM_SUPER free-space manager is not there */ + if(H5F_addr_defined(f->shared->fs_addr[type])) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + return(0); error: - puts("*** TESTS FAILED ***"); H5E_BEGIN_TRY { - H5Pclose(fapl); + H5Fclose(file); } H5E_END_TRY; - return (1); -} /* main() */ + return(1); +} /* test_mf_fs_gone() */ + + +/* + * Verify that the file's free-space manager(s) are persistent for a split-file + */ +static unsigned +test_mf_fs_split(hid_t fapl_new, hid_t fcpl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5FD_mem_t type, stype, btype; /* File allocation type */ + H5FS_stat_t fs_stat; /* Information for free-space manager */ + haddr_t addr1, addr2, addr3, addr4; /* File address for H5FD_MEM_SUPER */ + haddr_t saddr1, saddr2, saddr3, saddr4; /* File address for H5FD_MEM_DRAW */ + haddr_t baddr5, baddr6, baddr7, baddr8; /* File address for H5FD_MEM_BTREE */ + haddr_t tmp_addr; /* temporary variable for address */ + + TESTING("file's free-space managers are persistent for split-file"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl_new, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate 4 blocks of type H5FD_MEM_SUPER */ + type = H5FD_MEM_SUPER; + if(HADDR_UNDEF == (addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE2))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE3))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr4 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE4))) + FAIL_STACK_ERROR + + /* Put block #1, #3 into H5FD_MEM_SUPER free-space manager */ + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE1) < 0) + FAIL_STACK_ERROR + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr3, (hsize_t)TEST_BLOCK_SIZE3) < 0) + FAIL_STACK_ERROR + + /* Allocate 4 blocks of type H5FD_MEM_DRAW */ + stype = H5FD_MEM_DRAW; + if(HADDR_UNDEF == (saddr1 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (saddr2 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE2))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (saddr3 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE3))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (saddr4 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE4))) + FAIL_STACK_ERROR + + /* Put block #1, #3 into H5FD_MEM_DRAW free-space manager */ + if(H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr1, (hsize_t)TEST_BLOCK_SIZE1) < 0) + FAIL_STACK_ERROR + if(H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr3, (hsize_t)TEST_BLOCK_SIZE3) < 0) + FAIL_STACK_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* Verify that the H5FD_MEM_SUPER free-space manager is there */ + if(!H5F_addr_defined(f->shared->fs_addr[type])) + TEST_ERROR + + /* Start up H5FD_MEM_SUPER free-space manager */ + if(H5MF_alloc_open(f, H5P_DATASET_XFER_DEFAULT, type) < 0) + FAIL_STACK_ERROR + + /* Get free-space info */ + if(H5FS_stat_info(f, f->shared->fs_man[type], &fs_stat) < 0) + FAIL_STACK_ERROR + + /* Verify free-space info */ + if(fs_stat.tot_space < (TEST_BLOCK_SIZE1+TEST_BLOCK_SIZE3)) + TEST_ERROR + if(fs_stat.serial_sect_count < 2) + TEST_ERROR + + /* Retrieve block #1 from H5FD_MEM_SUPER free-space manager; block #2 still in free-space */ + if(HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1))) + FAIL_STACK_ERROR + if(tmp_addr != addr1) + TEST_ERROR + + /* Verify that the free-space manager for H5FD_MEM_DRAW is there */ + if(!H5F_addr_defined(f->shared->fs_addr[stype])) + TEST_ERROR + + /* Start up H5FD_MEM_DRAW free-space manager */ + if(H5MF_alloc_open(f, H5P_DATASET_XFER_DEFAULT, stype) < 0) + FAIL_STACK_ERROR + + /* Get free-space info */ + if(H5FS_stat_info(f, f->shared->fs_man[stype], &fs_stat) < 0) + FAIL_STACK_ERROR + + /* Verify free-space info */ + if(fs_stat.tot_space < (TEST_BLOCK_SIZE1+TEST_BLOCK_SIZE3)) + TEST_ERROR + if(fs_stat.serial_sect_count < 2) + TEST_ERROR + + /* Retrieve blocks #1 from H5FD_MEM_DRAW free-space manager */ + if(HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1))) + FAIL_STACK_ERROR + if(tmp_addr != saddr1) + TEST_ERROR + + /* Retrieve blocks #3 from H5FD_MEM_DRAW free-space manager */ + if(HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE3))) + FAIL_STACK_ERROR + if(tmp_addr != saddr3) + TEST_ERROR + /* H5FD_MEM_DRAW free-space manager is going away at closing */ + /* works for this one because the freeing of sect_addr is to H5FD_MEM_SUPER fs, not against itself */ + + /* Allocate 4 blocks of type H5FD_MEM_BTREE */ + btype = H5FD_MEM_BTREE; + if(HADDR_UNDEF == (baddr5 = H5MF_alloc(f, btype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE5))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (baddr6 = H5MF_alloc(f, btype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE6))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (baddr7 = H5MF_alloc(f, btype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE7))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (baddr8 = H5MF_alloc(f, btype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE8))) + FAIL_STACK_ERROR + + /* Put block #5 & #7 into H5FD_MEM_BTREE free-space manager */ + if(H5MF_xfree(f, btype, H5P_DATASET_XFER_DEFAULT, baddr5, (hsize_t)TEST_BLOCK_SIZE5) < 0) + FAIL_STACK_ERROR + if(H5MF_xfree(f, btype, H5P_DATASET_XFER_DEFAULT, baddr7, (hsize_t)TEST_BLOCK_SIZE7) < 0) + FAIL_STACK_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* Verify that the free-space manager for H5FD_MEM_DRAW is not there */ + if(H5F_addr_defined(f->shared->fs_addr[stype])) + TEST_ERROR + + /* Verify that the free-space manager for H5FD_MEM_SUPER is there */ + if(!H5F_addr_defined(f->shared->fs_addr[type])) + TEST_ERROR + + /* Start up H5FD_MEM_SUPER free-space manager */ + if(H5MF_alloc_open(f, H5P_DATASET_XFER_DEFAULT, type) < 0) + FAIL_STACK_ERROR + + /* Get free-space info */ + if(H5FS_stat_info(f, f->shared->fs_man[type], &fs_stat) < 0) + FAIL_STACK_ERROR + + /* Verify free-space info */ + if(fs_stat.tot_space < (TEST_BLOCK_SIZE3+TEST_BLOCK_SIZE5+TEST_BLOCK_SIZE7)) + TEST_ERROR + + /* Retrieve block #3 from H5FD_MEM_SUPER free-space manager */ + if(HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE3))) + FAIL_STACK_ERROR + if(tmp_addr != addr3) + TEST_ERROR + + /* Retrieve block #7 from H5FD_MEM_BTREE free-space manager */ + if(HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, btype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE7))) + FAIL_STACK_ERROR + if(tmp_addr != baddr7) + TEST_ERROR + + /* There should still be block #5 of H5FD_MEM_BTREE in H5FD_MEM_BTREE free-space manager */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* Verify that the H5FD_MEM_SUPER free-space manager is there */ + if(!H5F_addr_defined(f->shared->fs_addr[type])) + TEST_ERROR + + /* Start up H5FD_MEM_SUPER free-space manager */ + if(H5MF_alloc_open(f, H5P_DATASET_XFER_DEFAULT, type) < 0) + FAIL_STACK_ERROR + + /* Get free-space info */ + if(H5FS_stat_info(f, f->shared->fs_man[type], &fs_stat) < 0) + FAIL_STACK_ERROR + + /* Verify free-space info */ + if(fs_stat.tot_space < TEST_BLOCK_SIZE5) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_fs_split() */ + +/* + * Verify that the file's free-space manager(s) are persistent for a multi-file + */ +static unsigned +test_mf_fs_multi(hid_t fapl_new, hid_t fcpl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5FD_mem_t type, stype, btype, gtype; /* File allocation type */ + H5FS_stat_t fs_stat; /* Information for free-space manager */ + haddr_t addr1, addr2, addr3, addr4; /* File allocation type */ + haddr_t saddr1, saddr2, saddr3, saddr4; /* File address for H5FD_MEM_SUPER */ + haddr_t baddr1, baddr2, baddr3, baddr4; /* File address for H5FD_MEM_DRAW */ + haddr_t gaddr1, gaddr2; /* File address for H5FD_MEM_GHEAP */ + haddr_t tmp_addr; /* Temporary variable for address */ + H5FS_section_info_t *node; /* Free space section node */ + htri_t node_found = FALSE; /* Indicate section is in free-space */ + + TESTING("file's free-space managers are persistent for multi-file"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl_new, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate 4 blocks of type H5FD_MEM_SUPER */ + type = H5FD_MEM_SUPER; + if(HADDR_UNDEF == (addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE2))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE3))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr4 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE4))) + FAIL_STACK_ERROR + + /* Put block #1, #3 into H5FD_MEM_SUPER free-space manager */ + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE1) < 0) + FAIL_STACK_ERROR + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr3, (hsize_t)TEST_BLOCK_SIZE3) < 0) + FAIL_STACK_ERROR + + /* Allocate 4 blocks of type H5FD_MEM_DRAW */ + stype = H5FD_MEM_DRAW; + if(HADDR_UNDEF == (saddr1 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (saddr2 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE2))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (saddr3 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE3))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (saddr4 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE4))) + FAIL_STACK_ERROR + + /* Put block #1, #3 into H5FD_MEM_DRAW free-space manager */ + if(H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr1, (hsize_t)TEST_BLOCK_SIZE1) < 0) + FAIL_STACK_ERROR + if(H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr3, (hsize_t)TEST_BLOCK_SIZE3) < 0) + FAIL_STACK_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* Verify that the H5FD_MEM_SUPER free-space manager is there */ + if(!H5F_addr_defined(f->shared->fs_addr[type])) + TEST_ERROR + + /* Start up H5FD_MEM_SUPER free-space manager */ + if(H5MF_alloc_open(f, H5P_DATASET_XFER_DEFAULT, type) < 0) + FAIL_STACK_ERROR + + /* Get free-space info */ + if(H5FS_stat_info(f, f->shared->fs_man[type], &fs_stat) < 0) + FAIL_STACK_ERROR + + /* Verify free-space info */ + if(fs_stat.tot_space < (TEST_BLOCK_SIZE1+TEST_BLOCK_SIZE3)) + TEST_ERROR + if(fs_stat.serial_sect_count < 2) + TEST_ERROR + + /* Retrieve block #1 from H5FD_MEM_SUPER free-space manager; block #2 still in free-space */ + if(HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1))) + FAIL_STACK_ERROR + if(tmp_addr != addr1) + TEST_ERROR + + /* Verify that the free-space manager for H5FD_MEM_DRAW is there */ + if(!H5F_addr_defined(f->shared->fs_addr[stype])) + TEST_ERROR + + /* Start up H5FD_MEM_DRAW free-space manager */ + if(H5MF_alloc_open(f, H5P_DATASET_XFER_DEFAULT, stype) < 0) + FAIL_STACK_ERROR + + /* Get free-space info */ + if(H5FS_stat_info(f, f->shared->fs_man[stype], &fs_stat) < 0) + FAIL_STACK_ERROR + + /* Verify free-space info */ + if(fs_stat.tot_space < (TEST_BLOCK_SIZE1+TEST_BLOCK_SIZE3)) + TEST_ERROR + if(fs_stat.serial_sect_count < 2) + TEST_ERROR + + /* Retrieve blocks #1 from H5FD_MEM_DRAW free-space manager */ + if(HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1))) + FAIL_STACK_ERROR + if(tmp_addr != saddr1) + TEST_ERROR + + /* Retrieve blocks #3 from H5FD_MEM_DRAW free-space manager */ + if(HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE3))) + FAIL_STACK_ERROR + if(tmp_addr != saddr3) + TEST_ERROR + + /* Allocate 4 blocks of type H5FD_MEM_BTREE */ + btype = H5FD_MEM_BTREE; + if(HADDR_UNDEF == (baddr1 = H5MF_alloc(f, btype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (baddr2 = H5MF_alloc(f, btype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE2))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (baddr3 = H5MF_alloc(f, btype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE3))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (baddr4 = H5MF_alloc(f, btype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE4))) + FAIL_STACK_ERROR + + /* Put block #1 & #3 into H5FD_MEM_BTREE free-space manager */ + if(H5MF_xfree(f, btype, H5P_DATASET_XFER_DEFAULT, baddr1, (hsize_t)TEST_BLOCK_SIZE1) < 0) + FAIL_STACK_ERROR + if(H5MF_xfree(f, btype, H5P_DATASET_XFER_DEFAULT, baddr3, (hsize_t)TEST_BLOCK_SIZE3) < 0) + FAIL_STACK_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* Verify that the free-space manager for H5FD_MEM_SUPER is there */ + if(!H5F_addr_defined(f->shared->fs_addr[type])) + TEST_ERROR + + /* Start up H5FD_MEM_SUPER free-space manager */ + if(H5MF_alloc_open(f, H5P_DATASET_XFER_DEFAULT, type) < 0) + FAIL_STACK_ERROR + + /* Get free-space info */ + if(H5FS_stat_info(f, f->shared->fs_man[type], &fs_stat) < 0) + FAIL_STACK_ERROR + + /* Verify free-space info */ + if(fs_stat.tot_space < TEST_BLOCK_SIZE3) + TEST_ERROR + + /* Retrieve block #3 from H5FD_MEM_SUPER free-space manager */ + if(HADDR_UNDEF == (tmp_addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE3))) + FAIL_STACK_ERROR + if(tmp_addr != addr3) + TEST_ERROR + + /* Verify that the free-space manager for H5FD_MEM_DRAW is not there */ + if(H5F_addr_defined(f->shared->fs_addr[stype])) + TEST_ERROR + + /* Verify that the free-space manager for H5FD_MEM_BTREE is there */ + if(!H5F_addr_defined(f->shared->fs_addr[btype])) + TEST_ERROR + + /* Start up H5FD_MEM_BTREE free-space manager */ + if(H5MF_alloc_open(f, H5P_DATASET_XFER_DEFAULT, btype) < 0) + FAIL_STACK_ERROR + + /* Get free-space info */ + if(H5FS_stat_info(f, f->shared->fs_man[btype], &fs_stat) < 0) + FAIL_STACK_ERROR + + /* Verify free-space info */ + if(fs_stat.tot_space < (TEST_BLOCK_SIZE1+TEST_BLOCK_SIZE3)) + TEST_ERROR + if(fs_stat.serial_sect_count < 2) + TEST_ERROR + + /* Allocate 2 blocks of type H5FD_MEM_GHEAP */ + gtype = H5FD_MEM_GHEAP; + if(HADDR_UNDEF == (gaddr2 = H5MF_alloc(f, gtype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE2))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (gaddr1 = H5MF_alloc(f, gtype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1))) + FAIL_STACK_ERROR + + /* Put block #2 into H5FD_MEM_GHEAP free-space manager */ + if(H5MF_xfree(f, gtype, H5P_DATASET_XFER_DEFAULT, gaddr2, (hsize_t)TEST_BLOCK_SIZE2) < 0) + FAIL_STACK_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* If H5FD_MEM_SUPER is there, should not find block #1 & #3 */ + if(H5F_addr_defined(f->shared->fs_addr[type])) { + /* Start up H5FD_MEM_SUPER free-space manager */ + if(H5MF_alloc_open(f, H5P_DATASET_XFER_DEFAULT, type) < 0) + FAIL_STACK_ERROR + + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], + (hsize_t)TEST_BLOCK_SIZE1, (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + if(node_found) TEST_ERROR + + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], + (hsize_t)TEST_BLOCK_SIZE3, (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + if(node_found) TEST_ERROR + } + + /* Verify that the H5FD_MEM_GHEAP free-space manager is there */ + if(!H5F_addr_defined(f->shared->fs_addr[gtype])) + TEST_ERROR + + /* Start up H5FD_MEM_GHEAP free-space manager */ + if(H5MF_alloc_open(f, H5P_DATASET_XFER_DEFAULT, gtype) < 0) + FAIL_STACK_ERROR + + /* Get free-space info */ + if(H5FS_stat_info(f, f->shared->fs_man[gtype], &fs_stat) < 0) + FAIL_STACK_ERROR + + /* Verify free-space info */ + if(fs_stat.tot_space < TEST_BLOCK_SIZE2) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_fs_multi() */ + +#define MULTI_SETUP(memb_map, memb_fapl, memb_name, memb_addr, sv) { \ + H5FD_mem_t mt; \ + HDmemset(memb_map, 0, sizeof memb_map); \ + HDmemset(memb_fapl, 0, sizeof memb_fapl); \ + HDmemset(memb_name, 0, sizeof memb_name); \ + HDmemset(memb_addr, 0, sizeof memb_addr); \ + HDmemset(sv, 0, sizeof sv); \ + for (mt = 0; mt < H5FD_MEM_NTYPES; mt++) { \ + memb_map[mt] = H5FD_MEM_SUPER; \ + memb_fapl[mt] = H5P_DEFAULT; \ + } \ + memb_map[H5FD_MEM_BTREE] = H5FD_MEM_BTREE; \ + memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW; \ + memb_map[H5FD_MEM_GHEAP] = H5FD_MEM_GHEAP; \ + memb_map[H5FD_MEM_LHEAP] = H5FD_MEM_LHEAP; \ + sprintf(sv[H5FD_MEM_SUPER], "%%s-%c.h5", 's'); \ + memb_name[H5FD_MEM_SUPER] = sv[H5FD_MEM_SUPER]; \ + memb_addr[H5FD_MEM_SUPER] = 0; \ + sprintf(sv[H5FD_MEM_BTREE], "%%s-%c.h5", 'b'); \ + memb_name[H5FD_MEM_BTREE] = sv[H5FD_MEM_BTREE]; \ + memb_addr[H5FD_MEM_BTREE] = HADDR_MAX/6; \ + sprintf(sv[H5FD_MEM_DRAW], "%%s-%c.h5", 'r'); \ + memb_name[H5FD_MEM_DRAW] = sv[H5FD_MEM_DRAW]; \ + memb_addr[H5FD_MEM_DRAW] = HADDR_MAX/3; \ + sprintf(sv[H5FD_MEM_GHEAP], "%%s-%c.h5", 'g'); \ + memb_name[H5FD_MEM_GHEAP] = sv[H5FD_MEM_GHEAP]; \ + memb_addr[H5FD_MEM_GHEAP] = HADDR_MAX/2; \ + sprintf(sv[H5FD_MEM_LHEAP], "%%s-%c.h5", 'l'); \ + memb_name[H5FD_MEM_LHEAP] = sv[H5FD_MEM_LHEAP]; \ + memb_addr[H5FD_MEM_LHEAP] = HADDR_MAX*2/3; \ + sprintf(sv[H5FD_MEM_OHDR], "%%s-%c.h5", 'o'); \ + memb_name[H5FD_MEM_OHDR] = sv[H5FD_MEM_OHDR]; \ + memb_addr[H5FD_MEM_OHDR] = HADDR_MAX*5/6; \ +} + +/* + * Tests to verify that file's free-space managers are persistent or going away + * for different drivers. + */ +static unsigned +test_mf_fs_drivers(hid_t fapl) +{ + hid_t fcpl; /* file creation property list */ + hid_t fapl_new; /* copy of file access property list */ + hid_t fapl2; /* copy of file access property list */ + hbool_t new_format; /* To use new library format or not */ + unsigned ret = 0; /* return value */ + + H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; /* Memory usage map */ + hid_t memb_fapl[H5FD_MEM_NTYPES]; /* Member access properties */ + char sv[H5FD_MEM_NTYPES][500]; /* Name generators */ + const char *memb_name[H5FD_MEM_NTYPES]; /* Name generators */ + haddr_t memb_addr[H5FD_MEM_NTYPES]; /* Member starting address */ + + /* Create a non-standard file-creation template */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + if(H5Pset_file_space(fcpl, H5F_FILE_SPACE_ALL_PERSIST, (hsize_t)0) < 0) + TEST_ERROR + + /* Copy the file access property list */ + if((fapl2 = H5Pcopy(fapl)) < 0) TEST_ERROR + + /* Set the "use the latest version of the format" bounds for creating objects in the file */ + if(H5Pset_libver_bounds(fapl2, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) + TEST_ERROR + + /* Test with old and new format */ + for(new_format = FALSE; new_format <= TRUE; new_format++) { + + if(new_format) + HDputs("Testing the following tests for free-space managers with new library format..."); + else + HDputs("Testing the following tests for free-space managers with old library format..."); + + /* SEC2 */ + HDputs("Testing free-space manager(s) with sec2 driver"); + + if((fapl_new = H5Pcopy(new_format ? fapl2 : fapl)) < 0) TEST_ERROR + + if(H5Pset_fapl_sec2(fapl_new) < 0) + FAIL_STACK_ERROR + + ret += test_mf_fs_gone(fapl_new, fcpl); + ret += test_mf_fs_persist(fapl_new, fcpl); + + h5_cleanup(FILENAME, fapl_new); + + + /* STDIO */ + HDputs("Testing free-space managers with stdio driver"); + + if((fapl_new = H5Pcopy(new_format?fapl2:fapl)) < 0) + FAIL_STACK_ERROR + if(H5Pset_fapl_stdio(fapl_new) < 0) + FAIL_STACK_ERROR + + ret += test_mf_fs_gone(fapl_new, fcpl); + ret += test_mf_fs_persist(fapl_new, fcpl); + + h5_cleanup(FILENAME, fapl_new); + + /* CORE */ + HDputs("Testing free-space managers with core driver"); + + /* create fapl to be a "core" file */ + if((fapl_new = H5Pcopy(new_format?fapl2:fapl)) < 0) + FAIL_STACK_ERROR + if(H5Pset_fapl_core(fapl_new, (size_t)CORE_INCREMENT, TRUE) < 0) + FAIL_STACK_ERROR + + ret += test_mf_fs_gone(fapl_new, fcpl); + ret += test_mf_fs_persist(fapl_new, fcpl); + + h5_cleanup(FILENAME, fapl_new); + + /* FAMILY */ + HDputs("Testing free-space managers with family driver"); + + if((fapl_new = H5Pcopy(new_format?fapl2:fapl)) < 0) + FAIL_STACK_ERROR + if(H5Pset_fapl_family(fapl_new, (hsize_t)FAMILY_SIZE, H5P_DEFAULT) < 0) + FAIL_STACK_ERROR + + ret += test_mf_fs_persist(fapl_new, fcpl); + + h5_cleanup(FILENAME, fapl_new); + + /* SPLIT */ + HDputs("Testing free-space managers with split driver"); + + if((fapl_new = H5Pcopy(new_format?fapl2:fapl)) < 0) + FAIL_STACK_ERROR + if(H5Pset_fapl_split(fapl_new, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT)<0) + FAIL_STACK_ERROR + + ret += test_mf_fs_persist(fapl_new, fcpl); + ret += test_mf_fs_split(fapl_new, fcpl); + + h5_cleanup(FILENAME, fapl_new); + + /* MULTI */ + HDputs("Testing free-space managers with multi driver"); + + MULTI_SETUP(memb_map, memb_fapl, memb_name, memb_addr, sv) + + if((fapl_new = H5Pcopy(new_format?fapl2:fapl)) < 0) + FAIL_STACK_ERROR + if(H5Pset_fapl_multi(fapl_new, memb_map, memb_fapl, memb_name, memb_addr, TRUE) < 0) + TEST_ERROR; + + ret += test_mf_fs_multi(fapl_new, fcpl); + + h5_cleanup(FILENAME, fapl_new); + + } /* end for new_format */ + + if (H5Pclose(fcpl) < 0) + FAIL_STACK_ERROR + if (H5Pclose(fapl2) < 0) + FAIL_STACK_ERROR + + return(ret); + +error: + return(1); +} /* test_mf_fs_drivers() */ + + +/* + * Verify that file space management performs according to the + * file space strategy and free space threshold as specified. + */ +static unsigned +test_filespace_strategy_threshold(hid_t fapl_new) +{ + hid_t file = -1; /* File ID */ + hid_t fcpl; /* File creation property list template */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5FD_mem_t type; /* File allocation type */ + haddr_t addr1, addr2, addr3, addr4, addr5, addr6; /* File address for H5FD_MEM_SUPER */ + haddr_t tmp_addr; /* Temporary variable for address */ + H5F_file_space_type_t fs_type; /* File space handling strategy */ + hsize_t fs_threshold; /* Free space section threshold */ + hsize_t tot_space, saved_tot_space; /* Total amount of free space */ + hsize_t tot_sect_count, saved_tot_sect_count; /* # of free-space sections */ + + TESTING("file space strategy and threshold"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl_new, filename, sizeof(filename)); + + for(fs_threshold = 0; fs_threshold <= TEST_THRESHOLD10; fs_threshold++) { + + for(fs_type = H5F_FILE_SPACE_ALL_PERSIST; fs_type < H5F_FILE_SPACE_NTYPES; H5_INC_ENUM(H5F_file_space_type_t, fs_type)) { + + /* Create file-creation template */ + if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) + FAIL_STACK_ERROR + + /* Set default file space information */ + if(H5Pset_file_space(fcpl, fs_type, fs_threshold) < 0) + FAIL_STACK_ERROR + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate 6 blocks */ + type = H5FD_MEM_SUPER; + if(HADDR_UNDEF == (addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE2))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE3))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr4 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE4))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr5 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE5))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr6 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE6))) + FAIL_STACK_ERROR + + /* Put block #1, #3, #5 to H5FD_MEM_SUPER free-space manager */ + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE1) < 0) + FAIL_STACK_ERROR + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr3, (hsize_t)TEST_BLOCK_SIZE3) < 0) + FAIL_STACK_ERROR + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr5, (hsize_t)TEST_BLOCK_SIZE5) < 0) + FAIL_STACK_ERROR + + /* Retrieve the total amount of free space and # of free-space sections */ + if(f->shared->fs_man[type] && + H5FS_sect_stats(f->shared->fs_man[type], &saved_tot_space, &saved_tot_sect_count) < 0) + FAIL_STACK_ERROR + + /* H5F_FILE_SPACE_AGGR_VFD and H5F_FILE_SPACE_VFD: should not have free-space manager */ + if(fs_type > H5F_FILE_SPACE_ALL && f->shared->fs_man[type]) + TEST_ERROR + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + switch(fs_type) { + case H5F_FILE_SPACE_ALL_PERSIST: + if(fs_threshold <= TEST_BLOCK_SIZE5) { + if(!H5F_addr_defined(f->shared->fs_addr[type])) + TEST_ERROR + + /* Open the free-space manager */ + if(H5MF_alloc_open(f, H5P_DATASET_XFER_DEFAULT, type) < 0) + FAIL_STACK_ERROR + + /* Retrieve the total amount of free space and # of free-space sections */ + if(H5FS_sect_stats(f->shared->fs_man[type], &tot_space, &tot_sect_count) < 0) + FAIL_STACK_ERROR + + /* Verify that tot_space should be >= saved_tot_space */ + /* Verify that tot_sect_count should be >= saved_tot_sect_count */ + if(tot_space < saved_tot_space || tot_sect_count < saved_tot_sect_count) + TEST_ERROR + + /* Retrieve block #5 from H5FD_MEM_SUPER free-space manager */ + if(HADDR_UNDEF == + (tmp_addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE5))) + FAIL_STACK_ERROR + + /* Should be the same as before */ + if(tmp_addr != addr5) + TEST_ERROR + } else if(H5F_addr_defined(f->shared->fs_addr[type])) + TEST_ERROR + break; + + case H5F_FILE_SPACE_ALL: + case H5F_FILE_SPACE_AGGR_VFD: + case H5F_FILE_SPACE_VFD: + if(H5F_addr_defined(f->shared->fs_addr[type])) + TEST_ERROR + break; + + default: + break; + } /* end switch */ + + /* Closing */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + if(H5Pclose(fcpl) < 0) + FAIL_STACK_ERROR + + } /* end for fs_type */ + } /* end for fs_threshold */ + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_filespace_strategy_threshold() */ + +/* + * Verify section is merged/shrunk away for + * H5F_FILE_SPACE_ALL_PERSIST and H5F_FILE_SPACE_ALL strategy. + */ +static unsigned +test_filespace_gone(hid_t fapl_new) +{ + hid_t file = -1; /* File ID */ + hid_t fcpl; /* File creation propertly list template */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5FD_mem_t type; /* File allocation type */ + haddr_t addr1, addr2, addr3, addr4, addr5, addr6; /* File address for H5FD_MEM_SUPER */ + H5F_file_space_type_t fs_type; /* File space handling strategy */ + hsize_t fs_threshold; /* Free space section threshold */ + frspace_state_t state; /* State of free space manager */ + + TESTING("file space merge/shrink for section size < threshold"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl_new, filename, sizeof(filename)); + + /* Set free-space threshold */ + fs_threshold = TEST_THRESHOLD3; + + for(fs_type = H5F_FILE_SPACE_ALL_PERSIST; fs_type <= H5F_FILE_SPACE_ALL; H5_INC_ENUM(H5F_file_space_type_t, fs_type)) { + /* Create file-creation template */ + if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) + FAIL_STACK_ERROR + + /* Set default file space information */ + if(H5Pset_file_space(fcpl, fs_type, fs_threshold) < 0) + FAIL_STACK_ERROR + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate 6 blocks */ + type = H5FD_MEM_SUPER; + if(HADDR_UNDEF == (addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE2))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE3))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr4 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE4))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr5 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE5))) + FAIL_STACK_ERROR + if(HADDR_UNDEF == (addr6 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE6))) + FAIL_STACK_ERROR + + /* Put block #3, #5 to H5FD_MEM_SUPER free-space manager */ + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr3, (hsize_t)TEST_BLOCK_SIZE3) < 0) + FAIL_STACK_ERROR + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr5, (hsize_t)TEST_BLOCK_SIZE5) < 0) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += TEST_BLOCK_SIZE3 + TEST_BLOCK_SIZE5; + state.tot_sect_count += 2; + state.serial_sect_count += 2; + + if(check_stats(f, f->shared->fs_man[type], &state)) + TEST_ERROR + + /* section #2 is less than threshold but is merged into section #3 */ + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr2, (hsize_t)TEST_BLOCK_SIZE2) < 0) + FAIL_STACK_ERROR + + state.tot_space += TEST_BLOCK_SIZE2; + if(check_stats(f, f->shared->fs_man[type], &state)) + TEST_ERROR + + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr4, (hsize_t)TEST_BLOCK_SIZE4) < 0) + FAIL_STACK_ERROR + + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr6, (hsize_t)TEST_BLOCK_SIZE6) < 0) + FAIL_STACK_ERROR + + /* all sections should be shrunk away except section #1 */ + HDmemset(&state, 0, sizeof(frspace_state_t)); + if(check_stats(f, f->shared->fs_man[type], &state)) + TEST_ERROR + + /* section #1 is less than threshold but is shrunk away */ + if(H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE1) < 0) + FAIL_STACK_ERROR + + /* free-space manager should be empty */ + HDmemset(&state, 0, sizeof(frspace_state_t)); + if(check_stats(f, f->shared->fs_man[type], &state)) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + FAIL_STACK_ERROR + + /* free-space manager should be empty */ + if(H5F_addr_defined(f->shared->fs_addr[type])) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + if(H5Pclose(fcpl) < 0) + FAIL_STACK_ERROR + + } /* end for fs_type */ + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_filespace_gone() */ + +/* + * Tests to verify file space management for different drivers. + */ +static unsigned +test_filespace_drivers(hid_t fapl) +{ + hid_t fapl_new; /* copy of file access property list */ + hid_t fapl2; /* copy of file access property list */ + hbool_t new_format; /* Using library new format or not */ + unsigned ret = 0; /* return value */ + + H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; /* Memory usage map */ + hid_t memb_fapl[H5FD_MEM_NTYPES]; /* Member access properties */ + char sv[H5FD_MEM_NTYPES][500]; /* Name generators */ + const char *memb_name[H5FD_MEM_NTYPES]; /* Name generators */ + haddr_t memb_addr[H5FD_MEM_NTYPES]; /* Member starting address */ + + /* Copy the file access property list */ + if((fapl2 = H5Pcopy(fapl)) < 0) TEST_ERROR + + /* Set the "use the latest version of the format" bounds for creating objects in the file */ + if(H5Pset_libver_bounds(fapl2, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) + TEST_ERROR + + /* Test with old and new format */ + for(new_format = FALSE; new_format <= TRUE; new_format++) { + + if(new_format) + HDputs("Testing the following tests for file space management with new library format..."); + else + HDputs("Testing the following tests for file space management with old library format..."); + + /* SEC2 */ + HDputs("Testing file space management with sec2 driver"); + + if((fapl_new = H5Pcopy(new_format?fapl2:fapl)) < 0) + FAIL_STACK_ERROR + if(H5Pset_fapl_sec2(fapl_new) < 0) + FAIL_STACK_ERROR + + ret += test_filespace_strategy_threshold(fapl_new); + ret += test_filespace_gone(fapl_new); + + h5_cleanup(FILENAME, fapl_new); + + /* STDIO */ + HDputs("Testing file space management with stdio driver"); + + if((fapl_new = H5Pcopy(new_format?fapl2:fapl)) < 0) + FAIL_STACK_ERROR + if(H5Pset_fapl_stdio(fapl_new) < 0) + FAIL_STACK_ERROR + + ret += test_filespace_strategy_threshold(fapl_new); + ret += test_filespace_gone(fapl_new); + + h5_cleanup(FILENAME, fapl_new); + + /* CORE */ + HDputs("Testing file space management with core driver"); + + /* create fapl to be a "core" file */ + if((fapl_new = H5Pcopy(new_format?fapl2:fapl)) < 0) + FAIL_STACK_ERROR + if(H5Pset_fapl_core(fapl_new, (size_t)CORE_INCREMENT, TRUE) < 0) + FAIL_STACK_ERROR + + ret += test_filespace_strategy_threshold(fapl_new); + ret += test_filespace_gone(fapl_new); + + h5_cleanup(FILENAME, fapl_new); + + /* FAMILY */ + HDputs("Testing file space managers with family driver"); + + if((fapl_new = H5Pcopy(new_format?fapl2:fapl)) < 0) + FAIL_STACK_ERROR + if(H5Pset_fapl_family(fapl_new, (hsize_t)FAMILY_SIZE, H5P_DEFAULT) < 0) + FAIL_STACK_ERROR + + ret += test_filespace_strategy_threshold(fapl_new); + ret += test_filespace_gone(fapl_new); + + h5_cleanup(FILENAME, fapl_new); + + + /* SPLIT */ + HDputs("Testing file space managers with split driver"); + + if((fapl_new = H5Pcopy(new_format?fapl2:fapl)) < 0) + FAIL_STACK_ERROR + if(H5Pset_fapl_split(fapl_new, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT)<0) + FAIL_STACK_ERROR + + ret += test_filespace_strategy_threshold(fapl_new); + ret += test_filespace_gone(fapl_new); + + h5_cleanup(FILENAME, fapl_new); + + /* MULTI */ + HDputs("Testing file space managers with multi driver"); + + MULTI_SETUP(memb_map, memb_fapl, memb_name, memb_addr, sv) + + if((fapl_new = H5Pcopy(new_format?fapl2:fapl)) < 0) + TEST_ERROR + if(H5Pset_fapl_multi(fapl_new, memb_map, memb_fapl, memb_name, memb_addr, TRUE) < 0) + TEST_ERROR; + + ret += test_filespace_strategy_threshold(fapl_new); + ret += test_filespace_gone(fapl_new); + + h5_cleanup(FILENAME, fapl_new); + + } /* end for new_format */ + + if (H5Pclose(fapl2) < 0) + FAIL_STACK_ERROR + + return(ret); + +error: + return(1); +} /* test_filespace_drivers() */ + +int +main(void) +{ + hid_t fapl = -1; /* File access property list for data files */ + hid_t new_fapl = -1; /* File access property list for alignment & aggr setting */ + unsigned nerrors = 0; /* Cumulative error count */ + test_type_t curr_test; /* Current test being worked on */ + const char *env_h5_drvr; /* File Driver value from environment */ + + /* Get the VFD to use */ + env_h5_drvr = HDgetenv("HDF5_DRIVER"); + if(env_h5_drvr == NULL) + env_h5_drvr = "nomatch"; + + fapl = h5_fileaccess(); + + /* Make a copy of the FAPL before adjusting the alignment */ + if((new_fapl = H5Pcopy(fapl)) < 0) TEST_ERROR + + /* alignment is not set for the following tests */ + if(H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)1) < 0) + TEST_ERROR + + /* meta/small data is set to 2048 for the following tests */ + if(H5Pset_meta_block_size(fapl, (hsize_t)TEST_BLOCK_SIZE2048) < 0) + TEST_ERROR + if(H5Pset_small_data_block_size(fapl, (hsize_t)TEST_BLOCK_SIZE2048) < 0) + TEST_ERROR + + /* interaction with file allocation */ + nerrors += test_mf_eoa(env_h5_drvr, fapl); + nerrors += test_mf_eoa_shrink(env_h5_drvr, fapl); + nerrors += test_mf_eoa_extend(env_h5_drvr, fapl); + + /* interaction with temporary file space allocation */ + nerrors += test_mf_tmp(env_h5_drvr, fapl); + + /* interaction with free-space manager */ + nerrors += test_mf_fs_start(fapl); + nerrors += test_mf_fs_alloc_free(fapl); + nerrors += test_mf_fs_extend(fapl); + nerrors += test_mf_fs_absorb(env_h5_drvr, fapl); + + /* interaction with meta/sdata aggregator */ + nerrors += test_mf_aggr_alloc1(env_h5_drvr, fapl); + nerrors += test_mf_aggr_alloc2(env_h5_drvr, fapl); + nerrors += test_mf_aggr_alloc3(env_h5_drvr, fapl); + nerrors += test_mf_aggr_alloc4(env_h5_drvr, fapl); + nerrors += test_mf_aggr_alloc5(env_h5_drvr, fapl); + nerrors += test_mf_aggr_alloc6(env_h5_drvr, fapl); + nerrors += test_mf_aggr_alloc7(env_h5_drvr, fapl); + nerrors += test_mf_aggr_extend(env_h5_drvr, fapl); + nerrors += test_mf_aggr_absorb(env_h5_drvr, fapl); + + /* Tests for alignment */ + for(curr_test = TEST_NORMAL; curr_test < TEST_NTESTS; curr_test++) { + + switch(curr_test) { + + case TEST_NORMAL: /* set alignment = 1024 */ + if(H5Pset_alignment(new_fapl, (hsize_t)0, (hsize_t)TEST_ALIGN1024) < 0) + TEST_ERROR + break; + + case TEST_AGGR_SMALL: /* set alignment = 4096 */ + if(H5Pset_alignment(new_fapl, (hsize_t)0, (hsize_t)TEST_ALIGN4096) < 0) + TEST_ERROR + break; + + default: + TEST_ERROR; + break; + } /* end switch */ + + nerrors += test_mf_align_eoa(env_h5_drvr, fapl, new_fapl); + nerrors += test_mf_align_fs(env_h5_drvr, fapl, new_fapl); + nerrors += test_mf_align_alloc1(env_h5_drvr, fapl, new_fapl); + nerrors += test_mf_align_alloc2(env_h5_drvr, fapl, new_fapl); + nerrors += test_mf_align_alloc3(env_h5_drvr, fapl, new_fapl); + nerrors += test_mf_align_alloc4(env_h5_drvr, fapl, new_fapl); + nerrors += test_mf_align_alloc5(env_h5_drvr, fapl, new_fapl); + nerrors += test_mf_align_alloc6(env_h5_drvr, fapl, new_fapl); + } /* end if */ + + /* tests to verify that file's free-space managers are persistent */ + nerrors += test_mf_fs_drivers(fapl); + + /* tests for file space management */ + nerrors += test_filespace_drivers(fapl); + + if (H5Pclose(new_fapl) < 0) + FAIL_STACK_ERROR + h5_cleanup(FILENAME, fapl); + + if(nerrors) + goto error; + puts("All free-space manager tests for file memory passed."); + + return (0); + +error: + puts("*** TESTS FAILED ***"); + H5E_BEGIN_TRY { + H5Pclose(fapl); + } H5E_END_TRY; + return (1); +} /* main() */ + diff --git a/test/tfile.c b/test/tfile.c index 8103881..454f339 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -98,6 +98,35 @@ #define USERBLOCK_SIZE ((hsize_t) 512) +/* Declarations for test_filespace_*() */ +#define FILENAME_LEN 1024 /* length of file name */ +#define CORE_INCREMENT 1024 /* core file */ +#define FAMILY_SIZE 1024 /* family file */ +#define DSETNAME "dset" /* Name of dataset */ +#define NELMTS(X) (sizeof(X)/sizeof(X[0])) /* # of elements */ +#define READ_OLD_BUFSIZE 1024 /* Buffer for holding file data */ +#define FILE5 "tfile5.h5" /* Test file */ +#define TEST_THRESHOLD10 10 /* Free space section threshold */ + +const char *OLD_FILENAME[] = { /* Files created under 1.6 branch and 1.8 branch */ + "filespace_1_6.h5", /* 1.6 HDF5 file */ + "filespace_1_8.h5" /* 1.8 HDF5 file */ +}; +const char *FILESPACE_NAME[] = { + "tfilespace", + NULL +}; + +const char *FILENAME[] = { + "sec2_tfile", + "split_tfile", + "stdio_tfile", + "core_tfile", + "family_tfile", + NULL +}; + + static void create_objects(hid_t, hid_t, hid_t *, hid_t *, hid_t *, hid_t *); static void @@ -2504,6 +2533,675 @@ test_userblock_alignment(void) /**************************************************************** ** +** test_free_sections(): +** This routine does the actual work of checking information for +** free space sections available in a file in various situations. +** +*****************************************************************/ +static void +test_free_sections(hid_t fapl, char *fname) +{ + hid_t file; /* File ID */ + hid_t fcpl; /* File creation property list template */ + hssize_t free_space; /* Amount of free space in file */ + hid_t dspace; /* Dataspace ID */ + hid_t dset; /* Dataset ID */ + hid_t dcpl; /* Dataset creation property list */ + unsigned u; /* Local index variable */ + char name[32]; /* Dataset name */ + hssize_t nsects; /* # of free-space sections */ + hssize_t saved_nsects; /* saved copy for the # of free-space sections */ + int i; /* local index variable */ + hsize_t total; /* sum of the free-space section sizes */ + hsize_t last_size; /* size of last free-space section */ + H5F_sect_info_t *sect_info; /* array to hold the free-space information */ + H5F_sect_info_t *saved_sect_info; /* array to hold the free-space information */ + herr_t ret; /* return value */ + + /* Create file-creation template */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); + + /* Set file space strategy and free space section threshold */ + ret = H5Pset_file_space(fcpl, H5F_FILE_SPACE_ALL_PERSIST, (hsize_t)0); + CHECK(ret, FAIL, "H5Pget_file_space"); + + /* Create the file */ + file = H5Fcreate(fname, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(file, FAIL, "H5Fcreate"); + + /* Create dataspace for datasets */ + dspace = H5Screate(H5S_SCALAR); + CHECK(dspace, FAIL, "H5Screate"); + + /* Create a dataset creation property list */ + dcpl = H5Pcreate(H5P_DATASET_CREATE); + CHECK(dcpl, FAIL, "H5Pcreate"); + + /* Set the space allocation time to early */ + ret = H5Pset_alloc_time(dcpl, H5D_ALLOC_TIME_EARLY); + CHECK(ret, FAIL, "H5Pset_alloc_time"); + + /* Create datasets in file */ + for(u = 0; u < 10; u++) { + sprintf(name, "Dataset %u", u); + dset = H5Dcreate2(file, name, H5T_STD_U32LE, dspace, H5P_DEFAULT, dcpl, H5P_DEFAULT); + CHECK(dset, FAIL, "H5Dcreate2"); + + ret = H5Dclose(dset); + CHECK(ret, FAIL, "H5Dclose"); + } /* end for */ + + /* Close dataspace */ + ret = H5Sclose(dspace); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close dataset creation property list */ + ret = H5Pclose(dcpl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Delete odd-numbered datasets in file */ + for(u = 0; u < 10; u++) { + sprintf(name, "Dataset %u", u); + if(u % 2) { + ret = H5Ldelete(file, name, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + } /* end if */ + } /* end for */ + + /* Close file */ + ret = H5Fclose(file); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file with read-only permission */ + file = H5Fopen(fname, H5F_ACC_RDONLY, fapl); + CHECK_I(file, "H5Fopen"); + + /* Get the amount of free space in the file */ + free_space = H5Fget_freespace(file); + CHECK(free_space, FAIL, "H5Fget_freespace"); + + /* Get the # of free-space sections in the file */ + saved_nsects = H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)0, NULL); + CHECK(saved_nsects, FAIL, "H5Fget_free_sections"); + + /* Allocate storage for the free space section information */ + saved_sect_info = (H5F_sect_info_t *)HDcalloc((size_t)saved_nsects, sizeof(H5F_sect_info_t)); + CHECK(saved_sect_info, NULL, "HDcalloc"); + + /* Should return failure when nsects is 0 with a nonnull sect_info */ + nsects = H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)0, saved_sect_info); + VERIFY(nsects, FAIL, "H5Fget_free_sections"); + + /* Verify the correct # of free-space sections */ + nsects = H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)saved_nsects, saved_sect_info); + VERIFY(nsects, saved_nsects, "H5Fget_free_sections"); + + /* Verify the amount of free-space is correct */ + total = 0; + for(i = 0; i < nsects; i++) + total += saved_sect_info[i].size; + VERIFY(free_space, total, "H5Fget_free_sections"); + + /* save the last section's size */ + last_size = saved_sect_info[nsects-1].size; + + /* Allocate storage for -1 free space section information */ + sect_info = (H5F_sect_info_t *)HDcalloc((size_t)(saved_nsects - 1), sizeof(H5F_sect_info_t)); + CHECK(sect_info, NULL, "HDcalloc"); + + /* Retrieve free space info for -1 sections */ + nsects = H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)(saved_nsects - 1), sect_info); + VERIFY(nsects, saved_nsects, "H5Fget_free_sections"); + + /* Verify the amount of free-space is correct */ + total = 0; + for(i = 0; i < (saved_nsects - 1); i++) { + VERIFY(sect_info[i].addr, saved_sect_info[i].addr, "H5Fget_free_sections"); + VERIFY(sect_info[i].size, saved_sect_info[i].size, "H5Fget_free_sections"); + total += sect_info[i].size; + } + + VERIFY(((hsize_t)free_space - last_size), total, "H5Fget_free_sections"); + HDfree(sect_info); + + /* Allocate storage for +1 free space section information */ + sect_info = (H5F_sect_info_t *)HDcalloc((size_t)(saved_nsects + 1), sizeof(H5F_sect_info_t)); + CHECK(sect_info, NULL, "HDcalloc"); + + /* Retrieve free-space info for +1 sections */ + nsects = H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)(saved_nsects + 1), sect_info); + VERIFY(nsects, saved_nsects, "H5Fget_free_sections"); + + /* Verify free-space info is correct */ + total = 0; + for(i = 0; i < nsects; i++) { + VERIFY(sect_info[i].addr, saved_sect_info[i].addr, "H5Fget_free_sections"); + VERIFY(sect_info[i].size, saved_sect_info[i].size, "H5Fget_free_sections"); + total += sect_info[i].size; + } + + VERIFY(sect_info[nsects].addr, 0, "H5Fget_free_sections"); + VERIFY(sect_info[nsects].size, 0, "H5Fget_free_sections"); + VERIFY(free_space, total, "H5Fget_free_sections"); + HDfree(sect_info); + + /* Verify that there is no free-space section for this type */ + nsects = H5Fget_free_sections(file, H5FD_MEM_BTREE, (size_t)0, NULL); + VERIFY(nsects, 0, "H5Fget_free_sections"); + + /* Close file */ + ret = H5Fclose(file); + CHECK(ret, FAIL, "H5Fclose"); + + ret = H5Pclose(fcpl); + CHECK(fcpl, FAIL, "H5Pclose"); + + HDfree(saved_sect_info); + +} /* end test_free_sections() */ + +/**************************************************************** +** +** test_filespace_sects(): +** This test checks free space section info for +** files created with sec2 and split drivers. +** +*****************************************************************/ +static void +test_filespace_sects(void) +{ + hid_t fapl_sec2; /* File access property id with sec2 driver */ + hid_t fapl_split; /* File access property id with split driver */ + hid_t fapl_core; /* File access property id with core driver */ + hid_t fapl_stdio; /* File access property id with stdio driver */ + hid_t fapl_family; /* File access property id with family driver */ + char filename[FILENAME_LEN]; /* Filename to use */ + herr_t ret; /* Return value */ + + /* SEC2 */ + MESSAGE(5, ("Testing File free space information for a sec2 file\n")); + + fapl_sec2 = H5Pcreate(H5P_FILE_ACCESS); + + ret = H5Pset_fapl_sec2(fapl_sec2); + CHECK(ret, FAIL, "H5Pset_fapl_sec2"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl_sec2, filename, sizeof(filename)); + + /* perform free space information test for file with sec2 driver */ + test_free_sections(fapl_sec2, filename); + + /* close fapl_sec2 and remove the file */ + h5_cleanup(FILENAME, fapl_sec2); + + + /* SPLIT */ + MESSAGE(5, ("Testing File free space information for a split file\n")); + + fapl_split = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl_split, FAIL, "h5_fileaccess"); + + ret = H5Pset_fapl_split(fapl_split, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT); + CHECK(ret, FAIL, "H5Pset_fapl_split"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[1], fapl_split, filename, sizeof(filename)); + + /* perform free space information test for file with split driver */ + test_free_sections(fapl_split, filename); + + /* close fapl and remove the file */ + h5_cleanup(FILENAME, fapl_split); + + + /* STDIO */ + MESSAGE(5, ("Testing File free space information for a stdio file\n")); + + fapl_stdio = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl_stdio, FAIL, "h5_fileaccess"); + + ret = H5Pset_fapl_stdio(fapl_stdio); + CHECK(ret, FAIL, "H5Pset_fapl_split"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[2], fapl_stdio, filename, sizeof(filename)); + + /* perform free space information test for file with stdio driver */ + test_free_sections(fapl_stdio, filename); + + /* close fapl and remove the file */ + h5_cleanup(FILENAME, fapl_split); + + /* CORE */ + MESSAGE(5, ("Testing File free space information for a core file\n")); + + fapl_core = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl_core, FAIL, "h5_fileaccess"); + + ret = H5Pset_fapl_core(fapl_core, (size_t)CORE_INCREMENT, TRUE); + CHECK(ret, FAIL, "H5Pset_fapl_core"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[3], fapl_core, filename, sizeof(filename)); + + /* perform free space information test for file with core driver */ + test_free_sections(fapl_core, filename); + + /* close fapl_ and remove the file */ + h5_cleanup(FILENAME, fapl_core); + + + /* FAMILY */ + MESSAGE(5, ("Testing File free space information for a family file\n")); + + fapl_family = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl_family, FAIL, "h5_fileaccess"); + + ret = H5Pset_fapl_family(fapl_family, (hsize_t)FAMILY_SIZE, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Pset_fapl_family"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[4], fapl_family, filename, sizeof(filename)); + + /* perform free space information test for file with family driver */ + test_free_sections(fapl_family, filename); + + /* close fapl and remove the file */ + h5_cleanup(FILENAME, fapl_family); + +} /* end test_filespace_sects() */ + +/**************************************************************** +** +** test_filespace_info(): +** Verify that the public routines H5Pget/set_file_space() +** retrieve and set the file space strategy and free space +** section threshold as specified. +** +****************************************************************/ +static void +test_filespace_info(void) +{ + hid_t fid1, fid2; /* HDF5 File IDs */ + hid_t fapl, new_fapl; /* File access property */ + hid_t fcpl, fcpl1, fcpl2; /* File creation property */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_file_space_type_t strategy, fs_type, def_type; /* File space handling strategy */ + hsize_t threshold, fs_size, def_size; /* Free space section threshold */ + hbool_t new_format; /* new format or old format */ + herr_t ret; /* return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing File Space Management public routines: H5Pget/set_file_space()\n")); + + fapl = h5_fileaccess(); + h5_fixname(FILESPACE_NAME[0], fapl, filename, sizeof filename); + + new_fapl = H5Pcopy(fapl); + CHECK(new_fapl, FAIL, "H5Pcopy"); + + /* Set the "use the latest version of the format" bounds */ + ret = H5Pset_libver_bounds(new_fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST); + CHECK(ret, FAIL, "H5Pset_libver_bounds"); + + /* Create file-creation template */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); + + /* Get default file space information */ + ret = H5Pget_file_space(fcpl, &def_type, &def_size); + CHECK(ret, FAIL, "H5Pget_file_space"); + + /* Test with old & new format groups */ + for(new_format = FALSE; new_format <= TRUE; new_format++) { + hid_t my_fapl; + + /* Set the FAPL for the type of format */ + if(new_format) { + MESSAGE(5, ("Testing with new group format\n")); + my_fapl = new_fapl; + } /* end if */ + else { + MESSAGE(5, ("Testing with old group format\n")); + my_fapl = fapl; + } /* end else */ + + /* Test with different sized free space section threshold */ + for(fs_size = 0; fs_size <= TEST_THRESHOLD10; fs_size++) { + + /* Test with different file space handling strategies */ + for(fs_type = 0; fs_type < H5F_FILE_SPACE_NTYPES; H5_INC_ENUM(H5F_file_space_type_t, fs_type)) { + + /* Get a copy of the default file creation property */ + fcpl1 = H5Pcopy(fcpl); + CHECK(fcpl1, FAIL, "H5Pcopy"); + + /* Set file space strategy and free space section threshold */ + ret = H5Pset_file_space(fcpl1, fs_type, fs_size); + CHECK(ret, FAIL, "H5Pget_file_space"); + + /* Get the file space info from the creation property */ + ret = H5Pget_file_space(fcpl1, &strategy, &threshold); + CHECK(ret, FAIL, "H5Pget_file_space"); + + /* A 0 value for strategy retains existing strategy in use */ + VERIFY(strategy, (H5F_file_space_type_t)(fs_type ? fs_type : def_type), "H5Pget_file_space"); + /* A 0 value for threshold retains existing threshold in use */ + VERIFY(threshold, (hsize_t)(fs_size ? fs_size : def_size), "H5Pget_file_space"); + + /* Create the file with the specified file space info */ + fid1 = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl1, my_fapl); + CHECK(ret, FAIL, "H5Fcreate"); + + /* Close the file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file */ + fid2 = H5Fopen(filename, H5F_ACC_RDWR, my_fapl); + CHECK(ret, FAIL, "H5Fopen"); + + /* Get the file's creation property */ + fcpl2 = H5Fget_create_plist(fid2); + CHECK(fcpl2, FAIL, "H5Fget_create_plist"); + + strategy = threshold = 0; + + /* Get the file space info from the creation property list */ + ret = H5Pget_file_space(fcpl2, &strategy, &threshold); + CHECK(ret, FAIL, "H5Pget_file_space"); + + VERIFY(strategy, (H5F_file_space_type_t)(fs_type ? fs_type : def_type), "H5Pget_file_space"); + VERIFY(threshold, (hsize_t)(fs_size ? fs_size : def_size), "H5Pget_file_space"); + + /* Close the file */ + ret = H5Fclose(fid2); + CHECK(ret, FAIL, "H5Fclose"); + + /* Release file-creation template */ + ret = H5Pclose(fcpl1); + CHECK(ret, FAIL, "H5Pclose"); + ret = H5Pclose(fcpl2); + CHECK(ret, FAIL, "H5Pclose"); + } /* end for file space strategy type */ + } /* end for free space threshold */ + + h5_cleanup(FILESPACE_NAME, my_fapl); + + } /* end for new/old format */ + + /* Close the file creation property list */ + ret = H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); +} /* test_filespace_info() */ + +/**************************************************************** +** +** test_filespace_compatible(): +** Verify that the branch with file space management enhancement +** can open, read and modify 1.6 HDF5 file and 1.8 HDF5 file. +** Also verify the correct file space strategy/threshold in use +** and the amount of free space. +** +****************************************************************/ +static void +test_filespace_compatible(void) +{ + int fd_old = (-1), fd_new = (-1); /* File descriptors for copying data */ + hid_t fid; /* File id */ + hid_t fcpl; /* File creation property list template */ + hid_t did; /* Dataset id */ + int check[100]; /* Temporary buffer for verifying dataset data */ + int rdbuf[100]; /* Temporary buffer for reading in dataset data */ + uint8_t buf[READ_OLD_BUFSIZE]; /* temporary buffer for reading */ + ssize_t nread; /* Number of bytes read in */ + char *srcdir = HDgetenv("srcdir"); /* where the src code is located */ + char filename[FILENAME_LEN] = ""; /* old test file name */ + unsigned i, j; /* Local index variable */ + hssize_t free_space; /* Amount of free space in the file */ + hsize_t threshold; /* Free space section threshold */ + H5F_file_space_type_t strategy; /* File space handling strategy */ + herr_t ret; /* Return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing File space compatibility for 1.6 and 1.8 files\n")); + + for(j = 0; j < NELMTS(OLD_FILENAME); j++) { + + /* Generate correct name for test file by prepending the source path */ + if(srcdir && ((HDstrlen(srcdir) + HDstrlen(OLD_FILENAME[j]) + 1) < sizeof(filename))) { + HDstrcpy(filename, srcdir); + HDstrcat(filename, "/"); + } + HDstrcat(filename, OLD_FILENAME[j]); + + /* Copy old file into test file */ + fd_old = HDopen(filename, O_RDONLY, 0666); + CHECK(fd_old, FAIL, "HDopen"); + fd_new = HDopen(FILE5, O_RDWR|O_CREAT|O_TRUNC, 0666); + CHECK(fd_new, FAIL, "HDopen"); + + /* Copy data */ + while((nread = HDread(fd_old, buf, (size_t)READ_OLD_BUFSIZE)) > 0) + HDwrite(fd_new, buf, (size_t)nread); + + /* Close the files */ + ret = HDclose(fd_old); + CHECK(ret, FAIL, "HDclose"); + ret = HDclose(fd_new); + CHECK(ret, FAIL, "HDclose"); + + /* Open the test file */ + fid = H5Fopen(FILE5, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fopen"); + + /* There should not be any free space in the file */ + free_space = H5Fget_freespace(fid); + CHECK(free_space, FAIL, "H5Fget_freespace"); + VERIFY(free_space, (hssize_t)0, "H5Fget_freespace"); + + /* Get the file's file creation property list */ + /* Retrieve the file space handling stretegy and threshold */ + fcpl = H5Fget_create_plist(fid); + CHECK(fcpl, FAIL, "H5Fget_create_plist"); + ret = H5Pget_file_space(fcpl, &strategy, &threshold); + CHECK(ret, FAIL, "H5Pget_file_space"); + + /* File space handling strategy should be H5F_FILE_SPACE_ALL = 2 */ + /* Free space section threshold should be 1 */ + VERIFY(strategy, 2, "H5Pget_file_space"); + VERIFY(threshold, 1, "H5Pget_file_space"); + + /* Generate raw data */ + for(i = 0; i < 100; i++) + check[i] = (int)i; + + /* Open and read the dataset */ + did = H5Dopen2(fid, DSETNAME, H5P_DEFAULT); + CHECK(did, FAIL, "H5Dopen"); + ret = H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdbuf); + CHECK(ret, FAIL, "H5Dread"); + + /* Verify the data read is correct */ + for(i = 0; i < 100; i++) + VERIFY(rdbuf[i], check[i], "test_compatible"); + + /* Close the dataset */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + + /* Remove the dataset */ + ret = H5Ldelete(fid, DSETNAME, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-Open the file */ + fid = H5Fopen(FILE5, H5F_ACC_RDONLY, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fopen"); + + /* The dataset should not be there */ + did = H5Dopen2(fid, DSETNAME, H5P_DEFAULT); + VERIFY(did, FAIL, "H5Dopen"); + + /* There should not be any free space in the file */ + free_space = H5Fget_freespace(fid); + CHECK(free_space, FAIL, "H5Fget_freespace"); + VERIFY(free_space, (hssize_t)0, "H5Fget_freespace"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + } /* end for */ +} /* test_filespace_compatible */ + +/**************************************************************** +** +** test_deprec(): +** Test deprecated functionality. +** +****************************************************************/ +#ifndef H5_NO_DEPRECATED_SYMBOLS +static void +test_deprec(void) +{ + hid_t file; /* File IDs for old & new files */ + hid_t fcpl; /* File creation property list */ + unsigned super; /* Superblock version # */ + unsigned freelist; /* Free list version # */ + unsigned stab; /* Symbol table entry version # */ + unsigned shhdr; /* Shared object header version # */ + H5F_info1_t finfo; /* global information about file */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing deprecated routines\n")); + + /* Creating a file with the default file creation property list should + * create a version 0 superblock + */ + + /* Create file with default file creation property list */ + file= H5Fcreate(FILE1, H5F_ACC_TRUNC , H5P_DEFAULT, H5P_DEFAULT); + CHECK(file, FAIL, "H5Fcreate"); + + /* Get the file's version information */ + ret = H5Fget_info1(file, &finfo); + CHECK(ret, FAIL, "H5Fget_info1"); + VERIFY(finfo.super_ext_size, 0,"H5Fget_info1"); + VERIFY(finfo.sohm.hdr_size, 0,"H5Fget_info1"); + VERIFY(finfo.sohm.msgs_info.index_size, 0,"H5Fget_info1"); + VERIFY(finfo.sohm.msgs_info.heap_size, 0,"H5Fget_info1"); + + /* Get the file's dataset creation property list */ + fcpl = H5Fget_create_plist(file); + CHECK(fcpl, FAIL, "H5Fget_create_plist"); + + /* Get the file's version information */ + ret=H5Pget_version(fcpl, &super, &freelist, &stab, &shhdr); + CHECK(ret, FAIL, "H5Pget_version"); + VERIFY(super,0,"H5Pget_version"); + VERIFY(freelist,0,"H5Pget_version"); + VERIFY(stab,0,"H5Pget_version"); + VERIFY(shhdr,0,"H5Pget_version"); + + /* Close FCPL */ + ret=H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret=H5Fclose(file); + CHECK(ret, FAIL, "H5Fclose"); + + + /* Create a file creation property list */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); + + /* Set a property in the FCPL that will push the superblock version up */ + ret = H5Pset_file_space(fcpl, H5F_FILE_SPACE_VFD, 0); + CHECK(ret, FAIL, "H5Pset_file_space"); + + /* Creating a file with the non-default file creation property list should + * create a version 2 superblock + */ + + /* Create file with custom file creation property list */ + file= H5Fcreate(FILE1, H5F_ACC_TRUNC , fcpl, H5P_DEFAULT); + CHECK(file, FAIL, "H5Fcreate"); + + /* Close FCPL */ + ret=H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Get the file's version information */ + ret = H5Fget_info1(file, &finfo); + CHECK(ret, FAIL, "H5Fget_info1"); + VERIFY(finfo.super_ext_size, 40,"H5Fget_info1"); + VERIFY(finfo.sohm.hdr_size, 0,"H5Fget_info1"); + VERIFY(finfo.sohm.msgs_info.index_size, 0,"H5Fget_info1"); + VERIFY(finfo.sohm.msgs_info.heap_size, 0,"H5Fget_info1"); + + /* Get the file's dataset creation property list */ + fcpl = H5Fget_create_plist(file); + CHECK(fcpl, FAIL, "H5Fget_create_plist"); + + /* Get the file's version information */ + ret=H5Pget_version(fcpl, &super, &freelist, &stab, &shhdr); + CHECK(ret, FAIL, "H5Pget_version"); + VERIFY(super,2,"H5Pget_version"); + VERIFY(freelist,0,"H5Pget_version"); + VERIFY(stab,0,"H5Pget_version"); + VERIFY(shhdr,0,"H5Pget_version"); + + /* Close FCPL */ + ret=H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret=H5Fclose(file); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file */ + file = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); + CHECK(file, FAIL, "H5Fcreate"); + + /* Get the file's version information */ + ret = H5Fget_info1(file, &finfo); + CHECK(ret, FAIL, "H5Fget_info1"); + VERIFY(finfo.super_ext_size, 40,"H5Fget_info1"); + VERIFY(finfo.sohm.hdr_size, 0,"H5Fget_info1"); + VERIFY(finfo.sohm.msgs_info.index_size, 0,"H5Fget_info1"); + VERIFY(finfo.sohm.msgs_info.heap_size, 0,"H5Fget_info1"); + + /* Get the file's creation property list */ + fcpl = H5Fget_create_plist(file); + CHECK(fcpl, FAIL, "H5Fget_create_plist"); + + /* Get the file's version information */ + ret=H5Pget_version(fcpl, &super, &freelist, &stab, &shhdr); + CHECK(ret, FAIL, "H5Pget_version"); + VERIFY(super,2,"H5Pget_version"); + VERIFY(freelist,0,"H5Pget_version"); + VERIFY(stab,0,"H5Pget_version"); + VERIFY(shhdr,0,"H5Pget_version"); + + /* Close FCPL */ + ret=H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret=H5Fclose(file); + CHECK(ret, FAIL, "H5Fclose"); +} /* test_deprec */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + +/**************************************************************** +** ** test_file(): Main low-level file I/O test routine. ** ****************************************************************/ @@ -2537,6 +3235,12 @@ test_file(void) test_cached_stab_info(); /* Tests that files are created with cached stab info in the superblock */ test_rw_noupdate(); /* Test to ensure that RW permissions don't write the file unless dirtied */ test_userblock_alignment(); /* Tests that files created with a userblock and alignment interact properly */ + test_filespace_sects(); /* Test file free space section information */ + test_filespace_info(); /* Test file creation public routines:H5Pget/set_file_space */ + test_filespace_compatible();/* Test compatibility for file space management */ +#ifndef H5_NO_DEPRECATED_SYMBOLS + test_deprec(); /* Test deprecated routines */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ } /* test_file() */ @@ -2562,5 +3266,6 @@ cleanup_file(void) HDremove(FILE2); HDremove(FILE3); HDremove(FILE4); + HDremove(FILE5); } diff --git a/test/tmisc.c b/test/tmisc.c index b646a69..41128a2 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -1797,11 +1797,10 @@ test_misc11(void) unsigned sym_ik; /* Symbol table B-tree initial 'K' value */ unsigned istore_ik; /* Indexed storage B-tree initial 'K' value */ unsigned sym_lk; /* Symbol table B-tree leaf 'K' value */ - unsigned super; /* Superblock version # */ - unsigned freelist; /* Free list version # */ - unsigned stab; /* Symbol table entry version # */ - unsigned shhdr; /* Shared object header version # */ unsigned nindexes; /* Shared message number of indexes */ + H5F_info2_t finfo; /* global information about file */ + H5F_file_space_type_t strategy; /* File/free space strategy */ + hsize_t threshold; /* Free-space section threshold */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ @@ -1815,21 +1814,12 @@ test_misc11(void) file= H5Fcreate(MISC11_FILE, H5F_ACC_TRUNC , H5P_DEFAULT, H5P_DEFAULT); CHECK(file, FAIL, "H5Fcreate"); - /* Get the file's dataset creation property list */ - fcpl = H5Fget_create_plist(file); - CHECK(fcpl, FAIL, "H5Fget_create_plist"); - /* Get the file's version information */ - ret=H5Pget_version(fcpl, &super, &freelist, &stab, &shhdr); - CHECK(ret, FAIL, "H5Pget_version"); - VERIFY(super,0,"H5Pget_version"); - VERIFY(freelist,0,"H5Pget_version"); - VERIFY(stab,0,"H5Pget_version"); - VERIFY(shhdr,0,"H5Pget_version"); - - /* Close FCPL */ - ret=H5Pclose(fcpl); - CHECK(ret, FAIL, "H5Pclose"); + ret = H5Fget_info2(file, &finfo); + CHECK(ret, FAIL, "H5Fget_info2"); + VERIFY(finfo.super.version, 0,"H5Fget_info2"); + VERIFY(finfo.free.version, 0,"H5Fget_info2"); + VERIFY(finfo.sohm.version, 0,"H5Fget_info2"); /* Close file */ ret=H5Fclose(file); @@ -1856,6 +1846,9 @@ test_misc11(void) ret=H5Pset_shared_mesg_nindexes(fcpl,MISC11_NINDEXES); CHECK(ret, FAIL, "H5Pset_shared_mesg"); + ret = H5Pset_file_space(fcpl, H5F_FILE_SPACE_VFD, 0); + CHECK(ret, FAIL, "H5Pset_file_space"); + /* Creating a file with the non-default file creation property list should * create a version 1 superblock */ @@ -1868,21 +1861,12 @@ test_misc11(void) ret=H5Pclose(fcpl); CHECK(ret, FAIL, "H5Pclose"); - /* Get the file's dataset creation property list */ - fcpl = H5Fget_create_plist(file); - CHECK(fcpl, FAIL, "H5Fget_create_plist"); - /* Get the file's version information */ - ret=H5Pget_version(fcpl, &super, &freelist, &stab, &shhdr); - CHECK(ret, FAIL, "H5Pget_version"); - VERIFY(super,2,"H5Pget_version"); - VERIFY(freelist,0,"H5Pget_version"); - VERIFY(stab,0,"H5Pget_version"); - VERIFY(shhdr,0,"H5Pget_version"); - - /* Close FCPL */ - ret=H5Pclose(fcpl); - CHECK(ret, FAIL, "H5Pclose"); + ret = H5Fget_info2(file, &finfo); + CHECK(ret, FAIL, "H5Fget_info2"); + VERIFY(finfo.super.version, 2,"H5Fget_info2"); + VERIFY(finfo.free.version, 0,"H5Fget_info2"); + VERIFY(finfo.sohm.version, 0,"H5Fget_info2"); /* Close file */ ret=H5Fclose(file); @@ -1892,17 +1876,16 @@ test_misc11(void) file = H5Fopen(MISC11_FILE, H5F_ACC_RDONLY, H5P_DEFAULT); CHECK(file, FAIL, "H5Fcreate"); - /* Get the file's dataset creation property list */ + /* Get the file's creation property list */ fcpl = H5Fget_create_plist(file); CHECK(fcpl, FAIL, "H5Fget_create_plist"); /* Get the file's version information */ - ret=H5Pget_version(fcpl, &super, &freelist, &stab, &shhdr); - CHECK(ret, FAIL, "H5Pget_version"); - VERIFY(super,2,"H5Pget_version"); - VERIFY(freelist,0,"H5Pget_version"); - VERIFY(stab,0,"H5Pget_version"); - VERIFY(shhdr,0,"H5Pget_version"); + ret = H5Fget_info2(file, &finfo); + CHECK(ret, FAIL, "H5Fget_info2"); + VERIFY(finfo.super.version, 2,"H5Fget_info2"); + VERIFY(finfo.free.version, 0,"H5Fget_info2"); + VERIFY(finfo.sohm.version, 0,"H5Fget_info2"); /* Retrieve all the property values & check them */ ret=H5Pget_userblock(fcpl,&userblock); @@ -1927,6 +1910,11 @@ test_misc11(void) CHECK(ret, FAIL, "H5Pget_shared_mesg_nindexes"); VERIFY(nindexes, MISC11_NINDEXES, "H5Pget_shared_mesg_nindexes"); + ret = H5Pget_file_space(fcpl, &strategy, &threshold); + CHECK(ret, FAIL, "H5Pget_file_space"); + VERIFY(strategy, 4, "H5Pget_file_space"); + VERIFY(threshold, 1, "H5Pget_file_space"); + /* Close file */ ret=H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); @@ -5162,7 +5150,6 @@ test_misc(void) test_misc27(); /* Test opening file with object that has bad # of object header messages */ test_misc28(); /* Test that chunks are cached appropriately */ - } /* test_misc() */ diff --git a/tools/h5dump/h5dump.c b/tools/h5dump/h5dump.c index 43b2813..a437619 100644 --- a/tools/h5dump/h5dump.c +++ b/tools/h5dump/h5dump.c @@ -3067,22 +3067,22 @@ dump_fcpl(hid_t fid) hsize_t userblock; /* userblock size retrieved from FCPL */ size_t off_size; /* size of offsets in the file */ size_t len_size; /* size of lengths in the file */ - unsigned super; /* superblock version # */ - unsigned freelist; /* free list version # */ - unsigned stab; /* symbol table entry version # */ - unsigned shhdr; /* shared object header version # */ hid_t fdriver; /* file driver */ char dname[32]; /* buffer to store driver name */ unsigned sym_lk; /* symbol table B-tree leaf 'K' value */ unsigned sym_ik; /* symbol table B-tree internal 'K' value */ unsigned istore_ik; /* indexed storage B-tree internal 'K' value */ + H5F_file_space_type_t fs_strategy; /* file space strategy */ + hsize_t fs_threshold; /* free-space section threshold */ + H5F_info2_t finfo; /* file information */ fcpl=H5Fget_create_plist(fid); - H5Pget_version(fcpl, &super, &freelist, &stab, &shhdr); + H5Fget_info2(fid, &finfo); H5Pget_userblock(fcpl,&userblock); H5Pget_sizes(fcpl,&off_size,&len_size); H5Pget_sym_k(fcpl,&sym_ik,&sym_lk); H5Pget_istore_k(fcpl,&istore_ik); + H5Pget_file_space(fcpl, &fs_strategy, &fs_threshold); H5Pclose(fcpl); fapl=h5_fileaccess(); fdriver=H5Pget_driver(fapl); @@ -3094,13 +3094,13 @@ dump_fcpl(hid_t fid) */ printf("%s %s\n",SUPER_BLOCK, BEGIN); indentation(indent + COL); - printf("%s %u\n","SUPERBLOCK_VERSION", super); + printf("%s %u\n","SUPERBLOCK_VERSION", finfo.super.version); indentation(indent + COL); - printf("%s %u\n","FREELIST_VERSION", freelist); + printf("%s %u\n","FREELIST_VERSION", finfo.free.version); indentation(indent + COL); - printf("%s %u\n","SYMBOLTABLE_VERSION", stab); + printf("%s %u\n","SYMBOLTABLE_VERSION", 0); /* Retain this for backward compatibility, for now (QAK) */ indentation(indent + COL); - printf("%s %u\n","OBJECTHEADER_VERSION", shhdr); + printf("%s %u\n","OBJECTHEADER_VERSION", finfo.sohm.version); indentation(indent + COL); HDfprintf(stdout,"%s %Hd\n","OFFSET_SIZE", (long long)off_size); indentation(indent + COL); @@ -3141,6 +3141,21 @@ dump_fcpl(hid_t fid) printf("%s %s\n","FILE_DRIVER", dname);*/ indentation(indent + COL); printf("%s %u\n","ISTORE_K", istore_ik); + + indentation(indent + COL); + if(fs_strategy == H5F_FILE_SPACE_ALL_PERSIST) + printf("%s %s\n", "FILE_SPACE_STRATEGY", "H5F_FILE_SPACE_ALL_PERSIST"); + else if(fs_strategy == H5F_FILE_SPACE_ALL) + printf("%s %s\n", "FILE_SPACE_STRATEGY", "H5F_FILE_SPACE_ALL"); + else if(fs_strategy == H5F_FILE_SPACE_AGGR_VFD) + printf("%s %s\n", "FILE_SPACE_STRATEGY", "H5F_FILE_SPACE_AGGR_VFD"); + else if(fs_strategy == H5F_FILE_SPACE_VFD) + printf("%s %s\n", "FILE_SPACE_STRATEGY", "H5F_FILE_SPACE_VFD"); + else + printf("%s %s\n", "FILE_SPACE_STRATEGY", "Unknown strategy"); + indentation(indent + COL); + HDfprintf(stdout, "%s %Hu\n","FREE_SPACE_THRESHOLD", fs_threshold); + printf("%s\n",END); /*------------------------------------------------------------------------- diff --git a/tools/h5dump/h5dumpgentest.c b/tools/h5dump/h5dumpgentest.c index b8ed41d..2ddc0bf 100644 --- a/tools/h5dump/h5dumpgentest.c +++ b/tools/h5dump/h5dumpgentest.c @@ -93,6 +93,7 @@ #define FILE63 "textlinkfar.h5" #define FILE64 "tarray8.h5" #define FILE65 "tattrreg.h5" +#define FILE66 "file_space.h5" @@ -244,6 +245,10 @@ typedef struct s1_t { #define F64_ARRAY_BUF_LEN (4*1024) #define F64_DIM1 (F64_ARRAY_BUF_LEN / sizeof(int) + 1) +/* File 65 macros */ +#define STRATEGY H5F_FILE_SPACE_AGGR_VFD /* File space handling strategy */ +#define THRESHOLD10 10 /* Free space section threshold */ + static void gent_group(void) { @@ -6443,7 +6448,32 @@ gent_extlinks(void) H5Fclose(far_fid); } +/*------------------------------------------------------------------------- + * Function: gent_fs_strategy_threshold + * + * Purpose: Generate a file with non-default file space strategy and + * non-default free-space section threshold. + *------------------------------------------------------------------------- + */ +static void +gent_fs_strategy_threshold(void) +{ + hid_t fid; /* File id */ + hid_t fcpl; /* File creation property */ + + /* Create file-creation template */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + + /* Set file space information */ + H5Pset_file_space(fcpl, STRATEGY, THRESHOLD10); + /* Create the file with the specified strategy and threshold */ + fid = H5Fcreate(FILE66, H5F_ACC_TRUNC, fcpl, H5P_DEFAULT); + + /* close */ + H5Fclose(fid); + H5Pclose(fcpl); +} /*------------------------------------------------------------------------- * Function: main @@ -6516,7 +6546,7 @@ int main(void) gent_attr_creation_order(); gent_fpformat(); gent_extlinks(); - + gent_fs_strategy_threshold(); return 0; } diff --git a/tools/h5dump/testh5dump.sh.in b/tools/h5dump/testh5dump.sh.in index 3ffff50..9dcb562 100644 --- a/tools/h5dump/testh5dump.sh.in +++ b/tools/h5dump/testh5dump.sh.in @@ -340,6 +340,7 @@ TOOLTEST tnofilename.ddl # tests for super block TOOLTEST tboot1.ddl -H -B -d dset tfcontents1.h5 TOOLTEST tboot2.ddl -B tfcontents2.h5 +TOOLTEST file_space.ddl -B file_space.h5 # test -p with a non existing dataset TOOLTEST tperror.ddl -p -d bogus tfcontents1.h5 diff --git a/tools/h5repack/h5repack.c b/tools/h5repack/h5repack.c index d8a503c..e6b95a0 100644 --- a/tools/h5repack/h5repack.c +++ b/tools/h5repack/h5repack.c @@ -90,8 +90,8 @@ int h5repack(const char* infile, *------------------------------------------------------------------------- */ -int h5repack_init (pack_opt_t *options, - int verbose) +int +h5repack_init(pack_opt_t *options, int verbose, H5F_file_space_type_t strategy, hsize_t threshold) { int k, n; memset(options,0,sizeof(pack_opt_t)); @@ -106,6 +106,9 @@ int h5repack_init (pack_opt_t *options, options->filter_g[n].cd_values[k] = 0; } + options->fs_strategy = strategy; + options->fs_threshold = threshold; + return (options_table_init(&(options->op_tbl))); } diff --git a/tools/h5repack/h5repack.h b/tools/h5repack/h5repack.h index cb3d75a..16f438c 100644 --- a/tools/h5repack/h5repack.h +++ b/tools/h5repack/h5repack.h @@ -112,6 +112,8 @@ typedef struct { hsize_t ublock_size; /* user block size */ hsize_t threshold; /* alignment threshold for H5Pset_alignment */ hsize_t alignment ; /* alignment for H5Pset_alignment */ + H5F_file_space_type_t fs_strategy; /* File space handling strategy */ + hsize_t fs_threshold; /* Free space section threshold */ } pack_opt_t; @@ -125,14 +127,13 @@ typedef struct { extern "C" { #endif -int h5repack (const char* infile, const char* outfile, pack_opt_t *options); -int h5repack_addfilter (const char* str, pack_opt_t *options); -int h5repack_addlayout (const char* str, pack_opt_t *options); -int h5repack_init (pack_opt_t *options, int verbose); -int h5repack_end (pack_opt_t *options); -int h5repack_verify (const char *fname,pack_opt_t *options); -int h5repack_cmp_pl (const char *fname1, - const char *fname2); +int h5repack(const char* infile, const char* outfile, pack_opt_t *options); +int h5repack_addfilter(const char* str, pack_opt_t *options); +int h5repack_addlayout(const char* str, pack_opt_t *options); +int h5repack_init(pack_opt_t *options, int verbose, H5F_file_space_type_t strategy, hsize_t threshold); +int h5repack_end(pack_opt_t *options); +int h5repack_verify(const char *in_fname, const char *out_fname, pack_opt_t *options); +int h5repack_cmp_pl(const char *fname1, const char *fname2); #ifdef __cplusplus diff --git a/tools/h5repack/h5repack_copy.c b/tools/h5repack/h5repack_copy.c index 0fb8fc8..77c03d2 100644 --- a/tools/h5repack/h5repack_copy.c +++ b/tools/h5repack/h5repack_copy.c @@ -104,7 +104,7 @@ int copy_objects(const char* fnamein, goto out; } - /* get user block size */ + /* get user block size and file space strategy/threshold */ { hid_t fcpl_in; /* file creation property list ID for input file */ @@ -120,6 +120,24 @@ int copy_objects(const char* fnamein, goto out; } + if(!options->fs_strategy) + { + if(H5Pget_file_space(fcpl_in, &options->fs_strategy, NULL) < 0) + { + error_msg(progname, "failed to retrieve file space strategy\n"); + goto out; + } + } + + if(!options->fs_threshold) + { + if(H5Pget_file_space(fcpl_in, NULL, &options->fs_threshold) < 0) + { + error_msg(progname, "failed to retrieve file space threshold\n"); + goto out; + } + } + if(H5Pclose(fcpl_in) < 0) { error_msg(progname, "failed to close property list\n"); @@ -316,6 +334,32 @@ int copy_objects(const char* fnamein, } + /* either use the FCPL already created or create a new one */ + if(fcpl != H5P_DEFAULT) + { + /* set file space strategy and free space threshold */ + if(H5Pset_file_space(fcpl, options->fs_strategy, options->fs_threshold) < 0) + { + error_msg(progname, "failed to set file space strategy & threshold\n"); + goto out; + } + } + else + { + /* create a file creation property list */ + if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) + { + error_msg(progname, "fail to create a file creation property list\n"); + goto out; + } + + /* set file space strategy and free space threshold */ + if(H5Pset_file_space(fcpl, options->fs_strategy, options->fs_threshold) < 0) + { + error_msg(progname, "failed to set file space strategy & threshold \n"); + goto out; + } + } /*------------------------------------------------------------------------- * create the output file diff --git a/tools/h5repack/h5repack_main.c b/tools/h5repack/h5repack_main.c index 63aba1f..b6e645a3 100644 --- a/tools/h5repack/h5repack_main.c +++ b/tools/h5repack/h5repack_main.c @@ -38,7 +38,7 @@ const char *outfile = NULL; * Command-line options: The user can specify short or long-named * parameters. */ -static const char *s_opts = "hVvf:l:m:e:nLc:d:s:u:b:t:a:i:o:"; +static const char *s_opts = "hVvf:l:m:e:nLc:d:s:u:b:t:a:i:o:S:T:"; static struct long_options l_opts[] = { { "help", no_arg, 'h' }, { "version", no_arg, 'V' }, @@ -58,6 +58,8 @@ static struct long_options l_opts[] = { { "alignment", require_arg, 'a' }, { "infile", require_arg, 'i' }, /* -i for backward compability */ { "outfile", require_arg, 'o' }, /* -o for backward compability */ + { "fs_strategy", require_arg, 'S' }, + { "fs_threshold", require_arg, 'T' }, { NULL, 0, '\0' } }; @@ -104,7 +106,7 @@ int main(int argc, const char **argv) int ret=-1; /* initialize options */ - h5repack_init (&options,0); + h5repack_init (&options, 0, 0, (hsize_t)0); parse_command_line(argc, argv, &options); @@ -180,6 +182,8 @@ static void usage(const char *prog) printf(" -a A, --alignment=A Alignment value for H5Pset_alignment\n"); printf(" -f FILT, --filter=FILT Filter type\n"); printf(" -l LAYT, --layout=LAYT Layout type\n"); + printf(" -S STRGY, --fs_strategy=STRGY File-space-handling strategy\n"); + printf(" -T THRD, --fs_threshold=THRD Free-space section threshold\n"); printf("\n"); @@ -193,7 +197,18 @@ static void usage(const char *prog) printf(" a power of 2 (1024 default)\n"); printf(" F - is the shared object header message type, any of . If F is not specified, S applies to all messages\n"); - + printf("\n"); + printf(" STRGY is an integer value listed below:\n"); + printf(" 1: Use persistent free-space managers, aggregators and virtual file driver for allocation\n"); + printf(" 2: Use non-persistent free-space managers, aggregators and virtual file driver for allocation\n"); + printf(" 3: Use aggregators and virtual file driver for allocation\n"); + printf(" 4: Use virtual file driver for allocation\n"); + printf(" A value of 0 retains the existing file-space-handling strategy used in the library.\n"); + printf(" The library default is 2.\n"); + printf("\n"); + printf(" THRD is the minimum size of free-space sections to track by the free-space managers.\n"); + printf(" A value of 0 retains the existing free-space section threshold used in the library.\n"); + printf(" The library default is 1.\n"); printf("\n"); printf(" FILT - is a string with the format:\n"); @@ -429,6 +444,15 @@ void parse_command_line(int argc, const char **argv, pack_opt_t* options) } break; + case 'S': + + options->fs_strategy = atol( opt_arg ); + break; + + case 'T': + + options->fs_threshold = (hsize_t)atol( opt_arg ); + break; } /* switch */ diff --git a/tools/h5repack/h5repack_verify.c b/tools/h5repack/h5repack_verify.c index 83985c9..fe94148 100644 --- a/tools/h5repack/h5repack_verify.c +++ b/tools/h5repack/h5repack_verify.c @@ -44,20 +44,25 @@ static int verify_filters(hid_t pid, hid_t tid, int nfilters, filter_info_t *fil *------------------------------------------------------------------------- */ -int h5repack_verify(const char *fname, - pack_opt_t *options) +int +h5repack_verify(const char *in_fname, const char *out_fname, pack_opt_t *options) { - hid_t fid; /* file ID */ - hid_t did; /* dataset ID */ - hid_t pid; /* dataset creation property list ID */ - hid_t sid; /* space ID */ - hid_t tid; /* type ID */ + hid_t fidin; /* file ID for input file*/ + hid_t fidout; /* file ID for output file*/ + hid_t did; /* dataset ID */ + hid_t pid; /* dataset creation property list ID */ + hid_t sid; /* space ID */ + hid_t tid; /* type ID */ unsigned int i; trav_table_t *travt = NULL; int ok = 1; + hid_t fcpl_in; /* file creation property for input file */ + hid_t fcpl_out; /* file creation property for output file */ + H5F_file_space_type_t in_strat, out_strat; /* file space handling strategy for in/output file */ + hsize_t in_thresh, out_thresh; /* free space section threshold for in/output file */ - /* open the file */ - if((fid = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0 ) + /* open the output file */ + if((fidout = H5Fopen(out_fname, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0 ) return -1; for(i = 0; i < options->op_tbl->nelems; i++) @@ -69,7 +74,7 @@ int h5repack_verify(const char *fname, * open *------------------------------------------------------------------------- */ - if((did = H5Dopen2(fid, name, H5P_DEFAULT)) < 0) + if((did = H5Dopen2(fidout, name, H5P_DEFAULT)) < 0) goto error; if((sid = H5Dget_space(did)) < 0) goto error; @@ -121,7 +126,7 @@ int h5repack_verify(const char *fname, trav_table_init(&travt); /* get the list of objects in the file */ - if(h5trav_gettable(fid, travt) < 0) + if(h5trav_gettable(fidout, travt) < 0) goto error; for(i = 0; i < travt->nobjs; i++) @@ -135,7 +140,7 @@ int h5repack_verify(const char *fname, * open *------------------------------------------------------------------------- */ - if((did = H5Dopen2(fid, name, H5P_DEFAULT)) < 0) + if((did = H5Dopen2(fidout, name, H5P_DEFAULT)) < 0) goto error; if((sid = H5Dget_space(did)) < 0) goto error; @@ -191,21 +196,95 @@ int h5repack_verify(const char *fname, } /*------------------------------------------------------------------------- - * close + * Verify that file space strategy and free space threshold + * are set as expected *------------------------------------------------------------------------- */ - if (H5Fclose(fid) < 0) - return -1; + /* open the input file */ + if((fidin = H5Fopen(in_fname, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0 ) + goto error; + + /* Get file creation property list for input file */ + if((fcpl_in = H5Fget_create_plist(fidin)) < 0) { + error_msg(progname, "failed to retrieve file creation property list\n"); + goto error; + } + + /* Get file space management info for input file */ + if(H5Pget_file_space(fcpl_in, &in_strat, &in_thresh) < 0) { + error_msg(progname, "failed to retrieve file space strategy & threshold\n"); + goto error; + } + + /* Output file is already opened */ + /* Get file creation property list for output file */ + if((fcpl_out = H5Fget_create_plist(fidout)) < 0) { + error_msg(progname, "failed to retrieve file creation property list\n"); + goto error; + } + + /* Get file space management info for output file */ + if(H5Pget_file_space(fcpl_out, &out_strat, &out_thresh) < 0) { + error_msg(progname, "failed to retrieve file space strategy & threshold\n"); + goto error; + } + + /* + * If the strategy option is not set, + * file space handling strategy should be the same for both + * input & output files. + * If the strategy option is set, + * the output file's file space handling strategy should be the same + * as what is set via the strategy option + */ + if(!options->fs_strategy && out_strat != in_strat) { + error_msg(progname, "file space strategy not set as unexpected\n"); + goto error; + + } else if(options->fs_strategy && out_strat!= options->fs_strategy) { + error_msg(progname, "file space strategy not set as unexpectec\n"); + goto error; + } + + /* + * If the threshold option is not set, + * the free space section threshold should be the same for both + * input & output files. + * If the threshold option is set, + * the output file's free space section threshold should be the same + * as what is set via the threshold option. + */ + if(!options->fs_threshold && out_thresh != in_thresh) { + error_msg(progname, "free space threshold not set as unexpected\n"); + goto error; + + } else if(options->fs_threshold && out_thresh != options->fs_threshold) { + error_msg(progname, "free space threshold not set as unexpectec\n"); + goto error; + } + + /* Closing */ + if (H5Pclose(fcpl_in) < 0) + goto error; + if (H5Pclose(fcpl_out) < 0) + goto error; + if (H5Fclose(fidin) < 0) + goto error; + if (H5Fclose(fidout) < 0) + goto error; return ok; error: H5E_BEGIN_TRY { + H5Pclose(fcpl_in); + H5Pclose(fcpl_out); H5Pclose(pid); H5Sclose(sid); H5Dclose(did); - H5Fclose(fid); + H5Fclose(fidin); + H5Fclose(fidout); if (travt) trav_table_free(travt); } H5E_END_TRY; diff --git a/tools/h5repack/h5repacktst.c b/tools/h5repack/h5repacktst.c index 7ac339a..e36a8dc 100644 --- a/tools/h5repack/h5repacktst.c +++ b/tools/h5repack/h5repacktst.c @@ -152,6 +152,8 @@ int main (void) { pack_opt_t pack_options; diff_opt_t diff_options; + hsize_t fs_size = 0; /* free space section threshold */ + H5F_file_space_type_t fs_type = H5F_FILE_SPACE_DEFAULT; /* file space handling strategy */ #if defined (H5_HAVE_FILTER_SZIP) int szip_can_encode = 0; #endif @@ -184,13 +186,15 @@ int main (void) */ TESTING(" copy of datasets (fill values)"); - if (h5repack_init (&pack_options, 0) < 0) + + /* fs_type = 0; fs_size = 0 */ + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack(FNAME0,FNAME0OUT,&pack_options) < 0) GOERROR; if (h5diff(FNAME0,FNAME0OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME0OUT,&pack_options)<=0) + if (h5repack_verify(FNAME0, FNAME0OUT,&pack_options)<=0) GOERROR; if (h5repack_cmp_pl(FNAME0,FNAME0OUT)<=0) GOERROR; @@ -204,13 +208,13 @@ int main (void) *------------------------------------------------------------------------- */ TESTING(" copy of datasets (all datatypes)"); - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack(FNAME1,FNAME1OUT,&pack_options) < 0) GOERROR; if (h5diff(FNAME1,FNAME1OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME1OUT,&pack_options)<=0) + if (h5repack_verify(FNAME1, FNAME1OUT,&pack_options)<=0) GOERROR; if (h5repack_cmp_pl(FNAME1,FNAME1OUT)<=0) GOERROR; @@ -224,13 +228,13 @@ int main (void) *------------------------------------------------------------------------- */ TESTING(" copy of datasets (attributes)"); - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack(FNAME2,FNAME2OUT,&pack_options) < 0) GOERROR; if (h5diff(FNAME2,FNAME2OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME2OUT,&pack_options)<=0) + if (h5repack_verify(FNAME2, FNAME2OUT,&pack_options)<=0) GOERROR; if (h5repack_cmp_pl(FNAME2,FNAME2OUT)<=0) GOERROR; @@ -243,13 +247,13 @@ int main (void) *------------------------------------------------------------------------- */ TESTING(" copy of datasets (hardlinks)"); - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack(FNAME3,FNAME3OUT,&pack_options) < 0) GOERROR; if (h5diff(FNAME3,FNAME3OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME3OUT,&pack_options)<=0) + if (h5repack_verify(FNAME3, FNAME3OUT,&pack_options)<=0) GOERROR; if (h5repack_cmp_pl(FNAME3,FNAME3OUT)<=0) GOERROR; @@ -263,13 +267,13 @@ int main (void) *------------------------------------------------------------------------- */ TESTING(" copy of allocation early file"); - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack(FNAME5,FNAME5OUT,&pack_options) < 0) GOERROR; if (h5diff(FNAME5,FNAME5OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME5OUT,&pack_options)<=0) + if (h5repack_verify(FNAME5, FNAME5OUT, &pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -293,7 +297,7 @@ int main (void) *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("dset1:GZIP=9",&pack_options) < 0) GOERROR; @@ -303,7 +307,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -321,7 +325,7 @@ int main (void) #ifdef H5_HAVE_FILTER_DEFLATE - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("GZIP=1",&pack_options) < 0) GOERROR; @@ -331,7 +335,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -359,7 +363,7 @@ int main (void) */ if (szip_can_encode) { - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("dset2:SZIP=8,EC",&pack_options) < 0) GOERROR; @@ -369,7 +373,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -391,7 +395,7 @@ int main (void) #if defined (H5_HAVE_FILTER_SZIP) if (szip_can_encode) { - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("SZIP=8,NN",&pack_options) < 0) GOERROR; @@ -399,7 +403,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -422,7 +426,7 @@ int main (void) *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("dset1:SHUF",&pack_options) < 0) GOERROR; @@ -432,7 +436,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -451,7 +455,8 @@ int main (void) #ifdef H5_HAVE_FILTER_SHUFFLE - if (h5repack_init (&pack_options, 0) < 0) + /* fs_type = H5F_FILE_SPACE_ALL_PERSIST; fs_size = 1 */ + if (h5repack_init (&pack_options, 0, H5_INC_ENUM(H5F_file_space_type_t, fs_type), ++fs_size) < 0) GOERROR; if (h5repack_addfilter("SHUF",&pack_options) < 0) GOERROR; @@ -461,7 +466,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -480,7 +485,7 @@ int main (void) *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("dset1:FLET",&pack_options) < 0) GOERROR; @@ -490,7 +495,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -510,7 +515,7 @@ int main (void) #ifdef H5_HAVE_FILTER_FLETCHER32 - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("FLET",&pack_options) < 0) GOERROR; @@ -520,7 +525,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -538,7 +543,7 @@ int main (void) *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addlayout("dset1:CHUNK 20x10",&pack_options) < 0) GOERROR; @@ -569,7 +574,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -584,7 +589,7 @@ int main (void) *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addlayout("dset1:CHUNK=20x10",&pack_options) < 0) GOERROR; @@ -592,7 +597,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -604,7 +609,7 @@ int main (void) */ TESTING(" adding layout chunked to all"); - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addlayout("CHUNK=20x10",&pack_options) < 0) GOERROR; @@ -612,7 +617,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -625,7 +630,7 @@ int main (void) * test an individual object option *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addlayout("dset1:CONTI",&pack_options) < 0) GOERROR; @@ -633,7 +638,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -646,7 +651,7 @@ int main (void) * test all objects option *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addlayout("CONTI",&pack_options) < 0) GOERROR; @@ -654,7 +659,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -663,7 +668,7 @@ int main (void) * do the same test for a file with filters (chunked) *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addlayout("CONTI",&pack_options) < 0) GOERROR; @@ -671,7 +676,7 @@ int main (void) GOERROR; if (h5diff(FNAME8,FNAME8OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME8OUT,&pack_options)<=0) + if (h5repack_verify(FNAME8, FNAME8OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -685,7 +690,7 @@ int main (void) *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addlayout("dset1:COMPA",&pack_options) < 0) GOERROR; @@ -693,7 +698,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -706,7 +711,8 @@ int main (void) *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + /* fs_type = H5F_FILE_SPACE_ALL; fs_size = 2 */ + if (h5repack_init (&pack_options, 0, H5_INC_ENUM(H5F_file_space_type_t, fs_type), ++fs_size) < 0) GOERROR; if (h5repack_addlayout("COMPA",&pack_options) < 0) GOERROR; @@ -714,7 +720,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -728,7 +734,7 @@ int main (void) * layout compact to contiguous conversion *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addlayout("dset_compact:CONTI",&pack_options) < 0) GOERROR; @@ -736,7 +742,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -748,7 +754,7 @@ int main (void) * layout compact to chunk conversion *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addlayout("dset_compact:CHUNK=2x5",&pack_options) < 0) GOERROR; @@ -756,7 +762,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -768,7 +774,7 @@ int main (void) * layout compact to compact conversion *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addlayout("dset_compact:COMPA",&pack_options) < 0) GOERROR; @@ -776,7 +782,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -787,7 +793,7 @@ int main (void) * layout contiguous to compact conversion *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addlayout("dset_contiguous:COMPA",&pack_options) < 0) GOERROR; @@ -795,7 +801,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -806,7 +812,7 @@ int main (void) * layout contiguous to chunk conversion *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addlayout("dset_contiguous:CHUNK=3x6",&pack_options) < 0) GOERROR; @@ -814,7 +820,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -826,7 +832,7 @@ int main (void) * layout contiguous to contiguous conversion *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addlayout("dset_contiguous:CONTI",&pack_options) < 0) GOERROR; @@ -834,7 +840,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -845,7 +851,7 @@ int main (void) * layout chunked to compact conversion *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addlayout("dset_chunk:COMPA",&pack_options) < 0) GOERROR; @@ -853,7 +859,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -865,7 +871,7 @@ int main (void) * layout chunked to contiguous conversion *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addlayout("dset_chunk:CONTI",&pack_options) < 0) GOERROR; @@ -873,7 +879,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -884,7 +890,7 @@ int main (void) * layout chunked to chunked conversion *------------------------------------------------------------------------- */ - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addlayout("dset_chunk:CHUNK=18x13",&pack_options) < 0) GOERROR; @@ -892,7 +898,7 @@ int main (void) GOERROR; if (h5diff(FNAME4,FNAME4OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME4OUT,&pack_options)<=0) + if (h5repack_verify(FNAME4, FNAME4OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -914,13 +920,14 @@ int main (void) #if defined (H5_HAVE_FILTER_SZIP) if (szip_can_encode) { - if (h5repack_init (&pack_options, 0) < 0) + /* fs_type = H5F_FILE_SPACE_AGGR_VFD; fs_size = 3 */ + if (h5repack_init (&pack_options, 0, H5_INC_ENUM(H5F_file_space_type_t, fs_type), ++fs_size) < 0) GOERROR; if (h5repack(FNAME7,FNAME7OUT,&pack_options) < 0) GOERROR; if (h5diff(FNAME7,FNAME7OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME7OUT,&pack_options)<=0) + if (h5repack_verify(FNAME7, FNAME7OUT,&pack_options)<=0) GOERROR; if (h5repack_cmp_pl(FNAME7,FNAME7OUT)<=0) GOERROR; @@ -939,7 +946,7 @@ int main (void) #if defined (H5_HAVE_FILTER_SZIP) if (szip_can_encode) { - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("dset_szip:NONE",&pack_options) < 0) GOERROR; @@ -947,7 +954,7 @@ int main (void) GOERROR; if (h5diff(FNAME7,FNAME7OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME7OUT,&pack_options)<=0) + if (h5repack_verify(FNAME7, FNAME7OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -964,13 +971,13 @@ int main (void) TESTING(" copy of deflate filter"); #ifdef H5_HAVE_FILTER_DEFLATE - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack(FNAME8,FNAME8OUT,&pack_options) < 0) GOERROR; if (h5diff(FNAME8,FNAME8OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME8OUT,&pack_options)<=0) + if (h5repack_verify(FNAME8, FNAME8OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -984,7 +991,7 @@ int main (void) TESTING(" removing deflate filter"); #ifdef H5_HAVE_FILTER_DEFLATE - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, ++fs_size) < 0) GOERROR; if (h5repack_addfilter("dset_deflate:NONE",&pack_options) < 0) GOERROR; @@ -992,7 +999,7 @@ int main (void) GOERROR; if (h5diff(FNAME8,FNAME8OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME8OUT,&pack_options)<=0) + if (h5repack_verify(FNAME8, FNAME8OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1007,13 +1014,13 @@ int main (void) TESTING(" copy of shuffle filter"); #ifdef H5_HAVE_FILTER_SHUFFLE - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack(FNAME9,FNAME9OUT,&pack_options) < 0) GOERROR; if (h5diff(FNAME9,FNAME9OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME9OUT,&pack_options)<=0) + if (h5repack_verify(FNAME9, FNAME9OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1026,7 +1033,7 @@ int main (void) TESTING(" removing shuffle filter"); #ifdef H5_HAVE_FILTER_SHUFFLE - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("dset_shuffle:NONE",&pack_options) < 0) GOERROR; @@ -1034,7 +1041,7 @@ int main (void) GOERROR; if (h5diff(FNAME9,FNAME9OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME9OUT,&pack_options)<=0) + if (h5repack_verify(FNAME9, FNAME9OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1047,13 +1054,13 @@ int main (void) TESTING(" copy of fletcher filter"); #ifdef H5_HAVE_FILTER_FLETCHER32 - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack(FNAME10,FNAME10OUT,&pack_options) < 0) GOERROR; if (h5diff(FNAME10,FNAME10OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME10OUT,&pack_options)<=0) + if (h5repack_verify(FNAME10, FNAME10OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1066,7 +1073,7 @@ int main (void) TESTING(" removing fletcher filter"); #ifdef H5_HAVE_FILTER_FLETCHER32 - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("dset_fletcher32:NONE",&pack_options) < 0) GOERROR; @@ -1074,7 +1081,7 @@ int main (void) GOERROR; if (h5diff(FNAME10,FNAME10OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME10OUT,&pack_options)<=0) + if (h5repack_verify(FNAME10, FNAME10OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1088,13 +1095,13 @@ int main (void) TESTING(" copy of nbit filter"); #ifdef H5_HAVE_FILTER_NBIT - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack(FNAME12,FNAME12OUT,&pack_options) < 0) GOERROR; if (h5diff(FNAME12,FNAME12OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME12OUT,&pack_options)<=0) + if (h5repack_verify(FNAME12, FNAME12OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1107,7 +1114,7 @@ int main (void) TESTING(" removing nbit filter"); #ifdef H5_HAVE_FILTER_NBIT - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("dset_nbit:NONE",&pack_options) < 0) GOERROR; @@ -1115,7 +1122,7 @@ int main (void) GOERROR; if (h5diff(FNAME12,FNAME12OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME12OUT,&pack_options)<=0) + if (h5repack_verify(FNAME12, FNAME12OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1129,7 +1136,7 @@ int main (void) TESTING(" adding nbit filter"); #ifdef H5_HAVE_FILTER_NBIT - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("dset_int31:NBIT",&pack_options) < 0) GOERROR; @@ -1137,7 +1144,7 @@ int main (void) GOERROR; if (h5diff(FNAME12,FNAME12OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME12OUT,&pack_options)<=0) + if (h5repack_verify(FNAME12, FNAME12OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1151,13 +1158,13 @@ int main (void) TESTING(" copy of scaleoffset filter"); #ifdef H5_HAVE_FILTER_SCALEOFFSET - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack(FNAME13,FNAME13OUT,&pack_options) < 0) GOERROR; if (h5diff(FNAME13,FNAME13OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME13OUT,&pack_options)<=0) + if (h5repack_verify(FNAME13, FNAME13OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1170,7 +1177,7 @@ int main (void) TESTING(" removing scaleoffset filter"); #ifdef H5_HAVE_FILTER_SCALEOFFSET - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("dset_scaleoffset:NONE",&pack_options) < 0) GOERROR; @@ -1178,7 +1185,7 @@ int main (void) GOERROR; if (h5diff(FNAME13,FNAME13OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME13OUT,&pack_options)<=0) + if (h5repack_verify(FNAME13, FNAME13OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1192,7 +1199,7 @@ int main (void) TESTING(" adding scaleoffset filter"); #ifdef H5_HAVE_FILTER_SCALEOFFSET - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("dset_none:SOFF=31,IN",&pack_options) < 0) GOERROR; @@ -1200,7 +1207,7 @@ int main (void) GOERROR; if (h5diff(FNAME13,FNAME13OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME13OUT,&pack_options)<=0) + if (h5repack_verify(FNAME13, FNAME13OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1230,7 +1237,8 @@ int main (void) && defined (H5_HAVE_FILTER_FLETCHER32) && defined (H5_HAVE_FILTER_SHUFFLE) if (szip_can_encode) { - if (h5repack_init (&pack_options, 0) < 0) + /* fs_type = H5F_FILE_SPACE_VFD; fs_size = 4 */ + if (h5repack_init (&pack_options, 0, H5_INC_ENUM(H5F_file_space_type_t, fs_type), ++fs_size) < 0) GOERROR; if (h5repack_addfilter("dset_deflate:SZIP=8,NN",&pack_options) < 0) GOERROR; @@ -1238,7 +1246,7 @@ int main (void) GOERROR; if (h5diff(FNAME11,FNAME11OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME11OUT,&pack_options)<=0) + if (h5repack_verify(FNAME11, FNAME11OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1258,7 +1266,7 @@ int main (void) && defined (H5_HAVE_FILTER_FLETCHER32) && defined (H5_HAVE_FILTER_SHUFFLE) if (szip_can_encode) { - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("dset_szip:GZIP=1",&pack_options) < 0) GOERROR; @@ -1266,7 +1274,7 @@ int main (void) GOERROR; if (h5diff(FNAME11,FNAME11OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME11OUT,&pack_options)<=0) + if (h5repack_verify(FNAME11, FNAME11OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1290,7 +1298,7 @@ int main (void) #if defined (H5_HAVE_FILTER_SZIP) && defined (H5_HAVE_FILTER_DEFLATE) \ && defined (H5_HAVE_FILTER_FLETCHER32) && defined (H5_HAVE_FILTER_SHUFFLE) - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("NONE",&pack_options) < 0) GOERROR; @@ -1298,7 +1306,7 @@ int main (void) GOERROR; if (h5diff(FNAME11,FNAME11OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME11OUT,&pack_options)<=0) + if (h5repack_verify(FNAME11, FNAME11OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1313,13 +1321,14 @@ int main (void) *------------------------------------------------------------------------- */ TESTING(" big file"); - if (h5repack_init (&pack_options, 0) < 0) + + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack(FNAME14,FNAME14OUT,&pack_options) < 0) GOERROR; if (h5diff(FNAME14,FNAME14OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME14OUT,&pack_options)<=0) + if (h5repack_verify(FNAME14, FNAME14OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1330,13 +1339,13 @@ int main (void) *------------------------------------------------------------------------- */ TESTING(" external datasets"); - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack(FNAME15,FNAME15OUT,&pack_options) < 0) GOERROR; if (h5diff(FNAME15,FNAME15OUT,NULL,NULL,&diff_options) > 0) GOERROR; - if (h5repack_verify(FNAME15OUT,&pack_options)<=0) + if (h5repack_verify(FNAME15, FNAME15OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1347,13 +1356,13 @@ int main (void) *------------------------------------------------------------------------- */ TESTING(" file with userblock"); - if(h5repack_init(&pack_options, 0) < 0) + if(h5repack_init(&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if(h5repack(FNAME16, FNAME16OUT, &pack_options) < 0) GOERROR; if(h5diff(FNAME16, FNAME16OUT, NULL, NULL, &diff_options) > 0) GOERROR; - if(h5repack_verify(FNAME16OUT, &pack_options) <= 0) + if(h5repack_verify(FNAME16, FNAME16OUT, &pack_options) <= 0) GOERROR; if(verify_userblock(FNAME16OUT) < 0) GOERROR; @@ -1366,7 +1375,7 @@ int main (void) *------------------------------------------------------------------------- */ TESTING(" latest file format options"); - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; pack_options.latest=1; pack_options.grp_compact=10; @@ -1380,7 +1389,7 @@ int main (void) GOERROR; if (h5diff(FNAME1,FNAME1OUT,NULL,NULL,&diff_options) > 0) GOERROR; - if (h5repack_verify(FNAME1OUT,&pack_options)<=0) + if (h5repack_verify(FNAME1, FNAME1OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1396,7 +1405,7 @@ int main (void) #if defined (H5_HAVE_FILTER_DEFLATE) && defined (H5_HAVE_FILTER_SHUFFLE) - if (h5repack_init (&pack_options, 0) < 0) + if (h5repack_init (&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if (h5repack_addfilter("GZIP=1",&pack_options) < 0) GOERROR; @@ -1406,7 +1415,7 @@ int main (void) GOERROR; if (h5diff(FNAME11,FNAME11OUT,NULL,NULL,&diff_options) >0) GOERROR; - if (h5repack_verify(FNAME11OUT,&pack_options)<=0) + if (h5repack_verify(FNAME11, FNAME11OUT,&pack_options)<=0) GOERROR; if (h5repack_end (&pack_options) < 0) GOERROR; @@ -1425,7 +1434,7 @@ int main (void) #ifdef H5_HAVE_FILTER_DEFLATE - if(h5repack_init(&pack_options, 0) < 0) + if(h5repack_init(&pack_options, 0, fs_type, fs_size) < 0) GOERROR; /* add the options for a user block size and user block filename */ @@ -1436,7 +1445,7 @@ int main (void) GOERROR; if(h5diff(FNAME8, FNAME8OUT, NULL, NULL, &diff_options) > 0) GOERROR; - if(h5repack_verify(FNAME8OUT, &pack_options) <= 0) + if(h5repack_verify(FNAME8, FNAME8OUT, &pack_options) <= 0) GOERROR; if(verify_userblock(FNAME8OUT) < 0) GOERROR; @@ -1458,7 +1467,7 @@ int main (void) #ifdef H5_HAVE_FILTER_DEFLATE - if(h5repack_init(&pack_options, 0) < 0) + if(h5repack_init(&pack_options, 0, fs_type, fs_size) < 0) GOERROR; /* add the options for aligment */ @@ -1469,7 +1478,7 @@ int main (void) GOERROR; if(h5diff(FNAME8, FNAME8OUT, NULL, NULL, &diff_options) > 0) GOERROR; - if(h5repack_verify(FNAME8OUT, &pack_options) <= 0) + if(h5repack_verify(FNAME8, FNAME8OUT, &pack_options) <= 0) GOERROR; /* verify aligment */ @@ -1512,14 +1521,14 @@ int main (void) */ TESTING(" file with committed datatypes"); - if(h5repack_init(&pack_options, 0) < 0) + if(h5repack_init(&pack_options, 0, fs_type, fs_size) < 0) GOERROR; if(h5repack(FNAME17, FNAME17OUT, &pack_options) < 0) GOERROR; if(h5diff(FNAME17, FNAME17OUT, NULL, NULL, &diff_options) > 0) GOERROR; - if(h5repack_verify(FNAME17OUT, &pack_options) <= 0) + if(h5repack_verify(FNAME17, FNAME17OUT, &pack_options) <= 0) GOERROR; if(h5repack_end(&pack_options) < 0) GOERROR; diff --git a/tools/h5stat/h5stat.c b/tools/h5stat/h5stat.c index f5537e1..30ad0a1 100644 --- a/tools/h5stat/h5stat.c +++ b/tools/h5stat/h5stat.c @@ -26,6 +26,7 @@ #define SIZE_SMALL_GROUPS 10 #define SIZE_SMALL_ATTRS 10 #define SIZE_SMALL_DSETS 10 +#define SIZE_SMALL_SECTS 10 #define H5_NFILTERS_IMPL 8 /* Number of currently implemented filters + one to accommodate for user-define filters + one @@ -48,7 +49,7 @@ typedef struct ohdr_info_t { /* Info to pass to the iteration functions */ typedef struct iter_t { hid_t fid; /* File ID */ - + hsize_t filesize; /* Size of the file */ unsigned long uniq_groups; /* Number of unique groups */ unsigned long uniq_dsets; /* Number of unique datasets */ unsigned long uniq_dtypes; /* Number of unique named datatypes */ @@ -79,6 +80,7 @@ typedef struct iter_t { unsigned long *dset_dim_bins; /* Pointer to array of bins for dataset dimensions */ ohdr_info_t dset_ohdr_info; /* Object header information for datasets */ hsize_t dset_storage_size; /* Size of raw data for datasets */ + hsize_t dset_external_storage_size; /* Size of raw data for datasets with external storage */ ohdr_info_t dtype_ohdr_info; /* Object header information for datatypes */ hsize_t groups_btree_storage_size; /* btree size for group */ hsize_t groups_heap_storage_size; /* heap size for group */ @@ -87,8 +89,16 @@ typedef struct iter_t { hsize_t SM_hdr_storage_size; /* header size for SOHM table (1.8) */ hsize_t SM_index_storage_size; /* index (btree & list) size for SOHM table (1.8) */ hsize_t SM_heap_storage_size; /* fractal heap size for SOHM table (1.8) */ + hsize_t super_size; /* superblock size */ hsize_t super_ext_size; /* superblock extension size */ + hsize_t ublk_size; /* user block size (if exists) */ + hsize_t free_space; /* amount of freespace in the file */ + hsize_t free_hdr; /* free space manager header in the file */ + unsigned long num_small_sects[SIZE_SMALL_SECTS]; /* Size of small free-space sections */ + unsigned sect_nbins; /* Number of bins for free-space section sizes */ + unsigned long *sect_bins; /* Pointer to array of bins for free-space section sizes */ hsize_t datasets_index_storage_size;/* meta size for chunked dataset's indexing type */ + hsize_t datasets_heap_storage_size; /* heap size for dataset with external storage */ unsigned long nexternal; /* Number of external files for a dataset */ int local; /* Flag to indicate iteration over the object*/ } iter_t; @@ -104,6 +114,8 @@ static int display_dset = FALSE; static int display_dtype_metadata = FALSE; static int display_object = FALSE; static int display_attr = FALSE; +static int display_free_sections = FALSE; +static int display_summary = FALSE; /* a structure for handling the order command-line parameters come in */ struct handler_t { @@ -111,7 +123,7 @@ struct handler_t { }; -static const char *s_opts ="ADdFfhGgTO:V"; +static const char *s_opts ="ADdFfhGgsSTO:V"; static struct long_options l_opts[] = { {"help", no_arg, 'h'}, {"hel", no_arg, 'h'}, @@ -179,6 +191,20 @@ static struct long_options l_opts[] = { { "att", no_arg, 'A' }, { "at", no_arg, 'A' }, { "a", no_arg, 'A' }, + { "freespace", no_arg, 's' }, + { "freespac", no_arg, 's' }, + { "freespa", no_arg, 's' }, + { "freesp", no_arg, 's' }, + { "frees", no_arg, 's' }, + { "free", no_arg, 's' }, + { "fre", no_arg, 's' }, + { "fr", no_arg, 's' }, + { "summary", no_arg, 'S' }, + { "summar", no_arg, 'S' }, + { "summa", no_arg, 'S' }, + { "summ", no_arg, 'S' }, + { "sum", no_arg, 'S' }, + { "su", no_arg, 'S' }, { NULL, 0, '\0' } }; @@ -206,7 +232,8 @@ static void usage(const char *prog) fprintf(stdout, " -D, --dsetmetadata Print dataset metadata\n"); fprintf(stdout, " -T, --dtypemetadata Print datatype metadata\n"); fprintf(stdout, " -A, --attribute Print attribute information\n"); - fprintf(stdout, "\n"); + fprintf(stdout, " -s, --freespace Print free-space information\n"); + fprintf(stdout, " -S, --Summary Print summary of storage information\n"); } @@ -415,6 +442,7 @@ dataset_stats(iter_t *iter, const char *name, const H5O_info_t *oi) /* Update dataset metadata info */ iter->datasets_index_storage_size += oi->meta_size.obj.index_size; + iter->datasets_heap_storage_size += oi->meta_size.obj.heap_size; /* Update attribute metadata info */ ret = attribute_stats(iter, oi); @@ -422,7 +450,32 @@ dataset_stats(iter_t *iter, const char *name, const H5O_info_t *oi) /* Get storage info */ storage = H5Dget_storage_size(did); - iter->dset_storage_size += storage; + + /* Gather layout statistics */ + dcpl = H5Dget_create_plist(did); + assert(dcpl > 0); + + lout = H5Pget_layout(dcpl); + assert(lout >= 0); + + /* Object header's total size for H5D_COMPACT layout includes raw data size */ + /* "storage" also includes H5D_COMPACT raw data size */ + if(lout == H5D_COMPACT) + iter->dset_ohdr_info.total_size -= storage; + + /* Track the layout type for dataset */ + (iter->dset_layouts[lout])++; + + /* Get the number of external files for the dataset */ + num_ext = H5Pget_external_count(dcpl); + assert (num_ext >= 0); + + /* Accumulate raw data size accordingly */ + if(num_ext) { + iter->nexternal += (unsigned long)num_ext; + iter->dset_external_storage_size += (unsigned long)storage; + } else + iter->dset_storage_size += storage; /* Gather dataspace statistics */ sid = H5Dget_space(did); @@ -505,22 +558,6 @@ dataset_stats(iter_t *iter, const char *name, const H5O_info_t *oi) ret = H5Tclose(tid); assert(ret >= 0); - /* Gather layout statistics */ - dcpl = H5Dget_create_plist(did); - assert(dcpl > 0); - - lout = H5Pget_layout(dcpl); - assert(lout >= 0); - - /* Track the layout type for dataset */ - (iter->dset_layouts[lout])++; - - num_ext = H5Pget_external_count(dcpl); - assert (num_ext >= 0); - - if(num_ext) - iter->nexternal += (unsigned long)num_ext; - /* Track different filters */ if((nfltr = H5Pget_nfilters(dcpl)) >= 0) { if(nfltr == 0) @@ -653,6 +690,66 @@ lnk_stats(const char UNUSED *path, const H5L_info_t *li, void *_iter) return 0; } /* end lnk_stats() */ +/*------------------------------------------------------------------------- + * Function: freespace_stats + * + * Purpose: Gather statistics for free space sections in the file + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Vailin Choi; July 7th, 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +freespace_stats(hid_t fid, iter_t *iter) +{ + H5F_sect_info_t *sect_info = NULL; /* Free space sections */ + ssize_t nsects; /* Number of free space sections */ + size_t u; /* Local index variable */ + + /* Query section information */ + if((nsects = H5Fget_free_sections(fid, H5FD_MEM_DEFAULT, 0, NULL)) < 0) + return(FAIL); + else if(nsects) { + if(NULL == (sect_info = (H5F_sect_info_t *)calloc((size_t)nsects, sizeof(H5F_sect_info_t)))) + return(FAIL); + nsects = H5Fget_free_sections(fid, H5FD_MEM_DEFAULT, (size_t)nsects, sect_info); + assert(nsects); + } /* end else-if */ + + for(u = 0; u < (size_t)nsects; u++) { + unsigned bin; /* "bin" the number of objects falls in */ + + if(sect_info[u].size < SIZE_SMALL_SECTS) + (iter->num_small_sects[(size_t)sect_info[u].size])++; + + /* Add section size to proper bin */ + bin = ceil_log10((unsigned long)sect_info[u].size); + if(bin >= iter->sect_nbins) { + /* Allocate more storage for section info */ + iter->sect_bins = (unsigned long *)realloc(iter->sect_bins, (bin + 1) * sizeof(unsigned long)); + assert(iter->sect_bins); + + /* Initialize counts for intermediate bins */ + while(iter->sect_nbins < bin) + iter->sect_bins[iter->sect_nbins++] = 0; + iter->sect_nbins++; + + /* Initialize count for this bin */ + iter->sect_bins[bin] = 1; + } /* end if */ + else + (iter->sect_bins[bin])++; + } /* end for */ + + if(sect_info) + free(sect_info); + + return 0; +} /* end freespace_stats() */ + /*------------------------------------------------------------------------- * Function: parse_command_line @@ -718,6 +815,16 @@ parse_command_line(int argc, const char *argv[]) display_dset = TRUE; break; + case 's': + display_all = FALSE; + display_free_sections = TRUE; + break; + + case 'S': + display_all = FALSE; + display_summary = TRUE; + break; + case 'h': usage(progname); leave(EXIT_SUCCESS); @@ -829,15 +936,20 @@ print_file_info(const iter_t *iter) static herr_t print_file_metadata(const iter_t *iter) { - printf("Object header size: (total/unused)\n"); - HDfprintf(stdout, "\tGroups: %Hu/%Hu\n", iter->group_ohdr_info.total_size, - iter->group_ohdr_info.free_size); - HDfprintf(stdout, "\tDatasets: %Hu/%Hu\n", iter->dset_ohdr_info.total_size, - iter->dset_ohdr_info.free_size); - HDfprintf(stdout, "\tDatatypes: %Hu/%Hu\n", iter->dtype_ohdr_info.total_size, - iter->dtype_ohdr_info.free_size); - - printf("Storage information:\n"); + printf("Storage information (in bytes):\n"); + HDfprintf(stdout, "\tSuperblock: %Hu\n", iter->super_size); + HDfprintf(stdout, "\tSuperblock extension: %Hu\n", iter->super_ext_size); + HDfprintf(stdout, "\tUser block: %Hu\n", iter->ublk_size); + + HDfprintf(stdout, "\tObject headers: (total/unused)\n"); + HDfprintf(stdout, "\t\tGroups: %Hu/%Hu\n", iter->group_ohdr_info.total_size, + iter->group_ohdr_info.free_size); + HDfprintf(stdout, "\t\tDatasets(exclude compact data): %Hu/%Hu\n", + iter->dset_ohdr_info.total_size, + iter->dset_ohdr_info.free_size); + HDfprintf(stdout, "\t\tDatatypes: %Hu/%Hu\n", iter->dtype_ohdr_info.total_size, + iter->dtype_ohdr_info.free_size); + HDfprintf(stdout, "\tGroups:\n"); HDfprintf(stdout, "\t\tB-tree/List: %Hu\n", iter->groups_btree_storage_size); HDfprintf(stdout, "\t\tHeap: %Hu\n", iter->groups_heap_storage_size); @@ -847,14 +959,19 @@ print_file_metadata(const iter_t *iter) HDfprintf(stdout, "\t\tHeap: %Hu\n", iter->attrs_heap_storage_size); HDfprintf(stdout, "\tChunked datasets:\n"); - HDfprintf(stdout, "\t\tB-tree: %Hu\n", iter->datasets_index_storage_size); + HDfprintf(stdout, "\t\tIndex: %Hu\n", iter->datasets_index_storage_size); + + HDfprintf(stdout, "\tDatasets:\n"); + HDfprintf(stdout, "\t\tHeap: %Hu\n", iter->datasets_heap_storage_size); HDfprintf(stdout, "\tShared Messages:\n"); HDfprintf(stdout, "\t\tHeader: %Hu\n", iter->SM_hdr_storage_size); HDfprintf(stdout, "\t\tB-tree/List: %Hu\n", iter->SM_index_storage_size); HDfprintf(stdout, "\t\tHeap: %Hu\n", iter->SM_heap_storage_size); - HDfprintf(stdout, "\tSuperblock extension: %Hu\n", iter->super_ext_size); + HDfprintf(stdout, "\tFree-space managers:\n"); + HDfprintf(stdout, "\t\tHeader: %Hu\n", iter->free_hdr); + HDfprintf(stdout, "\t\tAmount of free space: %Hu\n", iter->free_space); return 0; } @@ -1035,6 +1152,7 @@ print_dataset_info(const iter_t *iter) printf("Dataset storage information:\n"); HDfprintf(stdout, "\tTotal raw data size: %Hu\n", iter->dset_storage_size); + HDfprintf(stdout, "\tTotal external raw data size: %Hu\n", iter->dset_external_storage_size); printf("Dataset layout information:\n"); for(u = 0; u < H5D_NLAYOUTS; u++) @@ -1075,6 +1193,116 @@ print_dataset_info(const iter_t *iter) /*------------------------------------------------------------------------- + * Function: print_freespace_info + * + * Purpose: Prints information about free space in the file + * + * Return: Success: 0 + * + * Failure: Never fails + * + * Programmer: Vailin Choi; July 7th, 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +print_freespace_info(const iter_t *iter) +{ + unsigned long power; /* Temporary "power" for bins */ + unsigned long total; /* Total count for various statistics */ + unsigned u; /* Local index variable */ + + printf("Small size free-space sections (< %u bytes):\n", (unsigned)SIZE_SMALL_SECTS); + total = 0; + for(u = 0; u < SIZE_SMALL_SECTS; u++) { + if(iter->num_small_sects[u] > 0) { + printf("\t# of sections of size %u: %lu\n", u, iter->num_small_sects[u]); + total += iter->num_small_sects[u]; + } /* end if */ + } /* end for */ + printf("\tTotal # of small size sections: %lu\n", total); + + printf("Free-space section bins:\n"); + + total = 0; + power = 1; + for(u = 1; u < iter->sect_nbins; u++) { + if(iter->sect_bins[u] > 0) { + printf("\t# of sections of size %lu - %lu: %lu\n", power, (power * 10) - 1, + iter->sect_bins[u]); + total += iter->sect_bins[u]; + } /* end if */ + power *= 10; + } /* end for */ + printf("\tTotal # of sections: %lu\n", total); + + return 0; +} /* print_freespace_info() */ + +/*------------------------------------------------------------------------- + * Function: print_storage_summary + * + * Purpose: Prints summary of the storage information in the file + * + * Return: Success: 0 + * + * Failure: Never fails + * + * Programmer: Vailin Choi; August 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +print_storage_summary(const iter_t *iter) +{ + hsize_t total_meta = 0; + hsize_t unaccount = 0; + float percent = 0.0; + + printf("Summary of storage information:\n"); + total_meta = + iter->super_size + iter->super_ext_size + iter->ublk_size + + iter->group_ohdr_info.total_size + + iter->dset_ohdr_info.total_size + + iter->dtype_ohdr_info.total_size + + iter->groups_btree_storage_size + + iter->groups_heap_storage_size + + iter->attrs_btree_storage_size + + iter->attrs_heap_storage_size + + iter->datasets_index_storage_size + + iter->datasets_heap_storage_size + + iter->SM_hdr_storage_size + + iter->SM_index_storage_size + + iter->SM_heap_storage_size + + iter->free_hdr; + + HDfprintf(stdout, " File metadata: %Hu bytes\n", total_meta); + HDfprintf(stdout, " Raw data: %Hu bytes\n", iter->dset_storage_size); + + percent = ((float)iter->free_space / (float)iter->filesize) * 100; + HDfprintf(stdout, " Amount/Percent of tracked free space: %Hu bytes/%3.1f%\n", + iter->free_space, percent); + + if(iter->filesize < (total_meta+iter->dset_storage_size+iter->free_space)) { + unaccount = (total_meta + iter->dset_storage_size + iter->free_space) - iter->filesize; + HDfprintf(stdout, " ??? File has %Hu more bytes accounted for that its size! ???\n", unaccount); + } + else { + unaccount = iter->filesize - (total_meta + iter->dset_storage_size + iter->free_space); + HDfprintf(stdout, " Unaccounted space: %Hu bytes\n", unaccount); + } + + HDfprintf(stdout, "Total space: %Hu bytes\n", + total_meta+iter->dset_storage_size+iter->free_space+unaccount); + + if(iter->nexternal) + HDfprintf(stdout, "External raw data: %Hu bytes\n", iter->dset_external_storage_size); + + return 0; +} /* print_storage_summary() */ + + +/*------------------------------------------------------------------------- * Function: print_file_statistics * * Purpose: Prints file statistics @@ -1098,6 +1326,7 @@ print_file_statistics(const iter_t *iter) display_dset = TRUE; display_dtype_metadata = TRUE; display_attr = TRUE; + display_free_sections = TRUE; } if(display_file) print_file_info(iter); @@ -1105,6 +1334,8 @@ print_file_statistics(const iter_t *iter) if(display_group) print_group_info(iter); if(display_dset) print_dataset_info(iter); if(display_attr) print_attr_info(iter); + if(display_free_sections) print_freespace_info(iter); + if(display_summary) print_storage_summary(iter); } @@ -1163,8 +1394,9 @@ main(int argc, const char *argv[]) iter_t iter; const char *fname = NULL; hid_t fid; + hid_t fcpl; struct handler_t *hand; - H5F_info_t finfo; + H5F_info2_t finfo; /* Disable error reporting */ H5Eset_auto2(H5E_DEFAULT, NULL, NULL); @@ -1190,16 +1422,33 @@ main(int argc, const char *argv[]) /* Initialize iter structure */ iter_init(&iter, fid); - /* Get storge info for SOHM's btree/list/heap and superblock extension */ - if(H5Fget_info(fid, &finfo) < 0) - warn_msg(progname, "Unable to retrieve SOHM info\n"); + if(H5Fget_filesize(fid, &iter.filesize) < 0) + warn_msg(progname, "Unable to retrieve file size\n"); + assert(iter.filesize >= 0); + + /* Get storge info for file-level structures */ + if(H5Fget_info2(fid, &finfo) < 0) + warn_msg(progname, "Unable to retrieve file info\n"); else { - iter.super_ext_size = finfo.super_ext_size; + iter.super_size = finfo.super.super_size; + iter.super_ext_size = finfo.super.super_ext_size; iter.SM_hdr_storage_size = finfo.sohm.hdr_size; iter.SM_index_storage_size = finfo.sohm.msgs_info.index_size; iter.SM_heap_storage_size = finfo.sohm.msgs_info.heap_size; + iter.free_space = finfo.free.tot_space; + iter.free_hdr = finfo.free.meta_size; } /* end else */ + if((fcpl = H5Fget_create_plist(fid)) < 0) + warn_msg(progname, "Unable to retrieve file creation property\n"); + + if(H5Pget_userblock(fcpl, &iter.ublk_size) < 0) + warn_msg(progname, "Unable to retrieve userblock size\n"); + + /* get information for free-space sections */ + if(freespace_stats(fid, &iter) < 0) + warn_msg(progname, "Unable to retrieve freespace info\n"); + /* Walk the objects or all file */ if(display_object) { unsigned u; diff --git a/tools/h5stat/h5stat_gentest.c b/tools/h5stat/h5stat_gentest.c index 3f933f2..e0ad3e2 100644 --- a/tools/h5stat/h5stat_gentest.c +++ b/tools/h5stat/h5stat_gentest.c @@ -40,18 +40,30 @@ */ static void gen_file(void) { - int ret, i; - hid_t fapl, gid; - hid_t file, type_id, space_id, attr_id, dset_id; - char name[30]; - char attrname[30]; + hid_t fcpl; /* File creation property */ + hid_t fapl; /* File access property */ + hid_t file; /* File id */ + hid_t gid; /* Group id */ + hid_t type_id; /* Datatype id */ + hid_t space_id; /* Dataspace id */ + hid_t attr_id; /* Attribute id */ + hid_t dset_id; /* Dataset id */ + char name[30]; /* Group name */ + char attrname[30]; /* Attribute name */ + int ret; /* Return value */ + int i; /* Local index variable */ fapl = H5Pcreate(H5P_FILE_ACCESS); ret = H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST); assert(ret >= 0); + /* Set file space handling strategy */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + ret = H5Pset_file_space(fcpl, H5F_FILE_SPACE_ALL_PERSIST, 0); + assert(ret >= 0); + /* Create dataset */ - file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + file = H5Fcreate(FILE, H5F_ACC_TRUNC, fcpl, fapl); for(i = 1; i <= NUM_GRPS; i++) { sprintf(name, "%s%d", GROUP_NAME,i); gid = H5Gcreate2(file, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); diff --git a/tools/h5stat/testfiles/h5stat_filters-F.ddl b/tools/h5stat/testfiles/h5stat_filters-F.ddl index 6bc6cc2..78c7c5a 100644 --- a/tools/h5stat/testfiles/h5stat_filters-F.ddl +++ b/tools/h5stat/testfiles/h5stat_filters-F.ddl @@ -2,11 +2,14 @@ Expected output for 'h5stat -F h5stat_filters.h5' ############################# Filename: h5stat_filters.h5 -Object header size: (total/unused) - Groups: 48/8 - Datasets: 4936/1344 - Datatypes: 80/0 -Storage information: +Storage information (in bytes): + Superblock: 96 + Superblock extension: 0 + User block: 0 + Object headers: (total/unused) + Groups: 48/8 + Datasets(exclude compact data): 4136/1344 + Datatypes: 80/0 Groups: B-tree/List: 1200 Heap: 288 @@ -14,9 +17,13 @@ Storage information: B-tree/List: 0 Heap: 0 Chunked datasets: - B-tree: 31392 + Index: 31392 + Datasets: + Heap: 72 Shared Messages: Header: 0 B-tree/List: 0 Heap: 0 - Superblock extension: 0 + Free-space managers: + Header: 0 + Amount of free space: 0 diff --git a/tools/h5stat/testfiles/h5stat_filters-d.ddl b/tools/h5stat/testfiles/h5stat_filters-d.ddl index 42d0de3..3cc9071 100644 --- a/tools/h5stat/testfiles/h5stat_filters-d.ddl +++ b/tools/h5stat/testfiles/h5stat_filters-d.ddl @@ -15,7 +15,8 @@ Dataset dimension information: # of datasets of size 100 - 999: 1 Total # of datasets: 1 Dataset storage information: - Total raw data size: 9059 + Total raw data size: 8659 + Total external raw data size: 400 Dataset layout information: Dataset layout counts[COMPACT]: 1 Dataset layout counts[CONTIG]: 2 diff --git a/tools/h5stat/testfiles/h5stat_filters-dT.ddl b/tools/h5stat/testfiles/h5stat_filters-dT.ddl index 2edcf7e..ae9121d 100644 --- a/tools/h5stat/testfiles/h5stat_filters-dT.ddl +++ b/tools/h5stat/testfiles/h5stat_filters-dT.ddl @@ -15,7 +15,8 @@ Dataset dimension information: # of datasets of size 100 - 999: 1 Total # of datasets: 1 Dataset storage information: - Total raw data size: 9059 + Total raw data size: 8659 + Total external raw data size: 400 Dataset layout information: Dataset layout counts[COMPACT]: 1 Dataset layout counts[CONTIG]: 2 diff --git a/tools/h5stat/testfiles/h5stat_filters.ddl b/tools/h5stat/testfiles/h5stat_filters.ddl index f9adebd..6ce04fe 100644 --- a/tools/h5stat/testfiles/h5stat_filters.ddl +++ b/tools/h5stat/testfiles/h5stat_filters.ddl @@ -10,11 +10,14 @@ File information # of unique other: 0 Max. # of links to object: 1 Max. # of objects in group: 16 -Object header size: (total/unused) - Groups: 48/8 - Datasets: 4936/1344 - Datatypes: 80/0 -Storage information: +Storage information (in bytes): + Superblock: 96 + Superblock extension: 0 + User block: 0 + Object headers: (total/unused) + Groups: 48/8 + Datasets(exclude compact data): 4136/1344 + Datatypes: 80/0 Groups: B-tree/List: 1200 Heap: 288 @@ -22,12 +25,16 @@ Storage information: B-tree/List: 0 Heap: 0 Chunked datasets: - B-tree: 31392 + Index: 31392 + Datasets: + Heap: 72 Shared Messages: Header: 0 B-tree/List: 0 Heap: 0 - Superblock extension: 0 + Free-space managers: + Header: 0 + Amount of free space: 0 Small groups: Total # of small groups: 0 Group bins: @@ -46,7 +53,8 @@ Dataset dimension information: # of datasets of size 100 - 999: 1 Total # of datasets: 1 Dataset storage information: - Total raw data size: 9059 + Total raw data size: 8659 + Total external raw data size: 400 Dataset layout information: Dataset layout counts[COMPACT]: 1 Dataset layout counts[CONTIG]: 2 @@ -76,3 +84,7 @@ Small # of attributes: Attribute bins: Total # of objects with attributes: 0 Max. # of attributes to objects: 0 +Small size free-space sections (< 10 bytes): + Total # of small size sections: 0 +Free-space section bins: + Total # of sections: 0 diff --git a/tools/h5stat/testfiles/h5stat_help1.ddl b/tools/h5stat/testfiles/h5stat_help1.ddl index 0a86b4c..5808c49 100644 --- a/tools/h5stat/testfiles/h5stat_help1.ddl +++ b/tools/h5stat/testfiles/h5stat_help1.ddl @@ -14,4 +14,5 @@ Usage: h5stat [OPTIONS] file -D, --dsetmetadata Print dataset metadata -T, --dtypemetadata Print datatype metadata -A, --attribute Print attribute information - + -s, --freespace Print free-space information + -S, --Summary Print summary of storage information diff --git a/tools/h5stat/testfiles/h5stat_help2.ddl b/tools/h5stat/testfiles/h5stat_help2.ddl index e41eb9e..169787f 100644 --- a/tools/h5stat/testfiles/h5stat_help2.ddl +++ b/tools/h5stat/testfiles/h5stat_help2.ddl @@ -14,4 +14,5 @@ Usage: h5stat [OPTIONS] file -D, --dsetmetadata Print dataset metadata -T, --dtypemetadata Print datatype metadata -A, --attribute Print attribute information - + -s, --freespace Print free-space information + -S, --Summary Print summary of storage information diff --git a/tools/h5stat/testfiles/h5stat_newgrat.ddl b/tools/h5stat/testfiles/h5stat_newgrat.ddl index 4f9bcac..877e55a 100644 --- a/tools/h5stat/testfiles/h5stat_newgrat.ddl +++ b/tools/h5stat/testfiles/h5stat_newgrat.ddl @@ -10,24 +10,31 @@ File information # of unique other: 0 Max. # of links to object: 1 Max. # of objects in group: 35001 -Object header size: (total/unused) - Groups: 5145147/3220092 - Datasets: 414/312 - Datatypes: 0/0 -Storage information: +Storage information (in bytes): + Superblock: 48 + Superblock extension: 119 + User block: 0 + Object headers: (total/unused) + Groups: 5145147/3220092 + Datasets(exclude compact data): 414/312 + Datatypes: 0/0 Groups: B-tree/List: 470054 - Heap: 739102 + Heap: 739045 Attributes: B-tree/List: 2598 - Heap: 4442 + Heap: 4431 Chunked datasets: - B-tree: 0 + Index: 0 + Datasets: + Heap: 0 Shared Messages: Header: 0 B-tree/List: 0 Heap: 0 - Superblock extension: 0 + Free-space managers: + Header: 1350 + Amount of free space: 4463 Small groups: # of groups of size 0: 35000 Total # of small groups: 35000 @@ -45,6 +52,7 @@ Dataset dimension information: Total small datasets: 0 Dataset storage information: Total raw data size: 0 + Total external raw data size: 0 Dataset layout information: Dataset layout counts[COMPACT]: 0 Dataset layout counts[CONTIG]: 1 @@ -72,3 +80,15 @@ Attribute bins: # of objects with 100 - 999 attributes: 1 Total # of objects with attributes: 1 Max. # of attributes to objects: 100 +Small size free-space sections (< 10 bytes): + # of sections of size 1: 1 + # of sections of size 2: 12 + # of sections of size 3: 3 + # of sections of size 7: 1 + # of sections of size 8: 2 + Total # of small size sections: 19 +Free-space section bins: + # of sections of size 1 - 9: 19 + # of sections of size 10 - 99: 44 + # of sections of size 100 - 999: 18 + Total # of sections: 81 diff --git a/tools/h5stat/testfiles/h5stat_newgrat.h5 b/tools/h5stat/testfiles/h5stat_newgrat.h5 index 8fa406b..1db0205 100644 Binary files a/tools/h5stat/testfiles/h5stat_newgrat.h5 and b/tools/h5stat/testfiles/h5stat_newgrat.h5 differ diff --git a/tools/h5stat/testfiles/h5stat_tsohm.ddl b/tools/h5stat/testfiles/h5stat_tsohm.ddl index e536c33..a53e40c 100644 --- a/tools/h5stat/testfiles/h5stat_tsohm.ddl +++ b/tools/h5stat/testfiles/h5stat_tsohm.ddl @@ -10,11 +10,14 @@ File information # of unique other: 0 Max. # of links to object: 1 Max. # of objects in group: 3 -Object header size: (total/unused) - Groups: 51/2 - Datasets: 852/447 - Datatypes: 0/0 -Storage information: +Storage information (in bytes): + Superblock: 48 + Superblock extension: 40 + User block: 0 + Object headers: (total/unused) + Groups: 51/2 + Datasets(exclude compact data): 852/447 + Datatypes: 0/0 Groups: B-tree/List: 872 Heap: 120 @@ -22,12 +25,16 @@ Storage information: B-tree/List: 0 Heap: 0 Chunked datasets: - B-tree: 0 + Index: 0 + Datasets: + Heap: 0 Shared Messages: Header: 38 B-tree/List: 550 Heap: 1316 - Superblock extension: 40 + Free-space managers: + Header: 0 + Amount of free space: 0 Small groups: # of groups of size 3: 1 Total # of small groups: 1 @@ -44,6 +51,7 @@ Dataset dimension information: Total small datasets: 0 Dataset storage information: Total raw data size: 0 + Total external raw data size: 0 Dataset layout information: Dataset layout counts[COMPACT]: 0 Dataset layout counts[CONTIG]: 0 @@ -70,3 +78,7 @@ Small # of attributes: Attribute bins: Total # of objects with attributes: 0 Max. # of attributes to objects: 0 +Small size free-space sections (< 10 bytes): + Total # of small size sections: 0 +Free-space section bins: + Total # of sections: 0 diff --git a/tools/testfiles/file_space.ddl b/tools/testfiles/file_space.ddl new file mode 100644 index 0000000..37b3922 --- /dev/null +++ b/tools/testfiles/file_space.ddl @@ -0,0 +1,23 @@ +############################# +Expected output for 'h5dump -B file_space.h5' +############################# +HDF5 "file_space.h5" { +SUPER_BLOCK { + SUPERBLOCK_VERSION 2 + FREELIST_VERSION 0 + SYMBOLTABLE_VERSION 0 + OBJECTHEADER_VERSION 0 + OFFSET_SIZE 8 + LENGTH_SIZE 8 + BTREE_RANK 16 + BTREE_LEAF 4 + ISTORE_K 32 + FILE_SPACE_STRATEGY H5F_FILE_SPACE_AGGR_VFD + FREE_SPACE_THRESHOLD 10 +} +USER_BLOCK { + USERBLOCK_SIZE 0 +} +GROUP "/" { +} +} diff --git a/tools/testfiles/file_space.h5 b/tools/testfiles/file_space.h5 new file mode 100644 index 0000000..48184d3 Binary files /dev/null and b/tools/testfiles/file_space.h5 differ diff --git a/tools/testfiles/tboot1.ddl b/tools/testfiles/tboot1.ddl index 9a7cafc..8ffffc0 100644 --- a/tools/testfiles/tboot1.ddl +++ b/tools/testfiles/tboot1.ddl @@ -12,6 +12,8 @@ SUPER_BLOCK { BTREE_RANK 16 BTREE_LEAF 4 ISTORE_K 32 + FILE_SPACE_STRATEGY H5F_FILE_SPACE_ALL + FREE_SPACE_THRESHOLD 1 } USER_BLOCK { USERBLOCK_SIZE 0 diff --git a/tools/testfiles/tboot2.ddl b/tools/testfiles/tboot2.ddl index d1484ca..51250fe 100644 --- a/tools/testfiles/tboot2.ddl +++ b/tools/testfiles/tboot2.ddl @@ -12,6 +12,8 @@ SUPER_BLOCK { BTREE_RANK 16 BTREE_LEAF 4 ISTORE_K 32 + FILE_SPACE_STRATEGY H5F_FILE_SPACE_ALL + FREE_SPACE_THRESHOLD 1 } USER_BLOCK { USERBLOCK_SIZE 0 -- cgit v0.12