From f766b32d07fae4562e95b9166255c35c8f3e467a Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 7 Oct 2003 08:32:32 -0500 Subject: [svn-r7559] Purpose: Add feature Description: Add H5Fget_freespace() routine, to check the amount of free space in a file. This information is only valid until the file is closed currently, however (until we start recording the free space information in the file itself). Platforms tested: FreeBSD 4.9 (sleipnir) h5committest --- fortran/src/H5Ff.c | 23 +++++++++++ fortran/src/H5Fff.f90 | 52 ++++++++++++++++++++++++ fortran/src/H5f90proto.h | 15 ++++--- fortran/test/fortranlib_test.f90 | 9 +++++ fortran/test/tH5F.f90 | 74 ++++++++++++++++++++++++++++++++++ release_docs/RELEASE.txt | 4 +- src/H5F.c | 39 ++++++++++++++++++ src/H5FD.c | 47 ++++++++++++++++++++++ src/H5FDprivate.h | 1 + src/H5Fpublic.h | 1 + test/tfile.c | 85 ++++++++++++++++++++++++++++++++++++++++ 11 files changed, 341 insertions(+), 9 deletions(-) diff --git a/fortran/src/H5Ff.c b/fortran/src/H5Ff.c index fa1e108..e486698 100644 --- a/fortran/src/H5Ff.c +++ b/fortran/src/H5Ff.c @@ -452,3 +452,26 @@ nh5fget_obj_ids_c ( hid_t_f *file_id , int_f *obj_type, int_f *max_objs, hid_t_f if ( H5Fget_obj_ids(c_file_id, c_obj_type, c_max_objs, (hid_t *)obj_ids) < 0 ) ret_value = -1; return ret_value; } +/*---------------------------------------------------------------------------- + * Name: h5fget_freespace_c + * Purpose: Call H5Fget_freespace to get amount of free space within a file + * Inputs: file_id - identifier of the file to query + * Returns: free_space - amount of free space in file + * 0 on success, -1 on failure + * Programmer: Quincey Koziol + * Tuesday, October 7, 2003 + * Modifications: + *---------------------------------------------------------------------------*/ + +int_f +nh5fget_freespace_c ( hid_t_f *file_id , hssize_t_f *free_space) +{ + int ret_value = 0; + hid_t c_file_id; + hssize_t c_free_space; + + c_file_id = (hid_t)*file_id; + if ( (c_free_space=H5Fget_freespace(c_file_id)) < 0 ) ret_value = -1; + *free_space=(hssize_t_f)c_free_space; + return ret_value; +} diff --git a/fortran/src/H5Fff.f90 b/fortran/src/H5Fff.f90 index 90a5a97..24e3945 100644 --- a/fortran/src/H5Fff.f90 +++ b/fortran/src/H5Fff.f90 @@ -802,4 +802,56 @@ hdferr = h5fget_obj_ids_c(file_id, obj_type, max_objs, obj_ids) END SUBROUTINE h5fget_obj_ids_f + +!---------------------------------------------------------------------- +! Name: h5fget_freespace_f +! +! Purpose: Get amount of free space within a file +! +! Inputs: +! file_id - file identifier +! Outputs: +! free_space - amount of free space in file +! hdferr: - error code +! Success: 0 +! Failure: -1 +! Optional parameters: +! NONE +! +! Programmer: Quincey Koziol +! October 7, 2003 +! +! Modifications: +! +! Comment: +!---------------------------------------------------------------------- + + SUBROUTINE h5fget_freespace_f(file_id, free_space, hdferr) +! +!This definition is needed for Windows DLLs +!DEC$if defined(BUILD_HDF5_DLL) +!DEC$attributes dllexport :: h5fget_freespace_f +!DEC$endif +! + + IMPLICIT NONE + INTEGER(HID_T), INTENT(IN) :: file_id ! File identifier + INTEGER(HSSIZE_T), INTENT(OUT) :: free_space + !amount of free space in file + INTEGER, INTENT(OUT) :: hdferr ! Error code + + INTERFACE + INTEGER FUNCTION h5fget_freespace_c(file_id, free_space) + USE H5GLOBAL + !DEC$ IF DEFINED(HDF5F90_WINDOWS) + !MS$ATTRIBUTES C,reference,alias:'_H5FGET_FREESPACE_C':: h5fget_freespace_c + !DEC$ ENDIF + INTEGER(HID_T), INTENT(IN) :: file_id + INTEGER(HSSIZE_T), INTENT(OUT) :: free_space + END FUNCTION h5fget_freespace_c + END INTERFACE + + hdferr = h5fget_freespace_c(file_id, free_space) + + END SUBROUTINE h5fget_freespace_f END MODULE H5F diff --git a/fortran/src/H5f90proto.h b/fortran/src/H5f90proto.h index 85d8779..ad82080 100644 --- a/fortran/src/H5f90proto.h +++ b/fortran/src/H5f90proto.h @@ -39,6 +39,7 @@ H5_DLL int HD5packFstring(char *src, char *dest, int len); # define nh5fget_access_plist_c FNAME(H5FGET_ACCESS_PLIST_C) # define nh5fget_obj_count_c FNAME(H5FGET_OBJ_COUNT_C) # define nh5fget_obj_ids_c FNAME(H5FGET_OBJ_IDS_C) +# define nh5fget_freespace_c FNAME(H5FGET_FREESPACE_C) #else /* !DF_CAPFNAMES */ # define nh5fcreate_c FNAME(h5fcreate_c) # define nh5fflush_c FNAME(h5fflush_c) @@ -52,6 +53,7 @@ H5_DLL int HD5packFstring(char *src, char *dest, int len); # define nh5fget_access_plist_c FNAME(h5fget_access_plist_c) # define nh5fget_obj_count_c FNAME(h5fget_obj_count_c) # define nh5fget_obj_ids_c FNAME(h5fget_obj_ids_c) +# define nh5fget_freespace_c FNAME(h5fget_freespace_c) #endif /* DF_CAPFNAMES */ #endif /* H5Ff90_FNAMES */ @@ -78,6 +80,7 @@ H5_DLL int_f nh5fget_access_plist_c (hid_t_f *file_id, hid_t_f *access_id); H5_DLL int_f nh5fget_obj_count_c (hid_t_f *file_id, int_f *obj_type, int_f *obj_count); H5_DLL int_f nh5fget_obj_ids_c (hid_t_f *file_id, int_f *obj_type, int_f *max_objs, int_f *obj_ids); +H5_DLL int_f nh5fget_freespace_c (hid_t_f *file_id, hssize_t_f *free_space); H5_DLL int_f nh5fflush_c (hid_t_f *obj_id, int_f *scope); /* @@ -677,11 +680,11 @@ H5_DLL int_f nh5tset_cset_c ( hid_t_f *type_id, int_f * cset); H5_DLL int_f nh5tget_strpad_c ( hid_t_f *type_id, int_f * strpad); H5_DLL int_f nh5tset_strpad_c ( hid_t_f *type_id, int_f * strpad); H5_DLL int_f nh5tget_nmembers_c ( hid_t_f *type_id , int_f * num_members); -H5_DLL int_f nh5tget_member_name_c ( hid_t_f *type_id ,int_f* index, _fcd member_name, int_f *namelen); +H5_DLL int_f nh5tget_member_name_c ( hid_t_f *type_id ,int_f* idx, _fcd member_name, int_f *namelen); H5_DLL int_f nh5tget_member_dims_c ( hid_t_f *type_id ,int_f* field_idx, int_f * dims, size_t_f * field_dims, int_f * perm ); H5_DLL int_f nh5tget_member_offset_c ( hid_t_f *type_id ,int_f* member_no, size_t_f* offset); H5_DLL int_f nh5tget_member_type_c ( hid_t_f *type_id ,int_f* field_idx, hid_t_f * datatype); -H5_DLL int_f nh5tget_member_index_c ( hid_t_f *type_id ,_fcd name, int_f* namelen, int_f *index); +H5_DLL int_f nh5tget_member_index_c ( hid_t_f *type_id ,_fcd name, int_f* namelen, int_f *idx); H5_DLL int_f nh5tinsert_c(hid_t_f *type_id, _fcd name, int_f* namelen, size_t_f *offset, hid_t_f * field_id); H5_DLL int_f nh5tpack_c(hid_t_f * type_id); @@ -810,7 +813,6 @@ H5_DLL int_f nh5tis_variable_str_c ( hid_t_f *type_id , int_f *flag ); # define nh5pget_size_c FNAME(H5PGET_SIZE_C) # define nh5pget_nprops_c FNAME(H5PGET_NPROPS_C) # define nh5pget_class_parent_c FNAME(H5PGET_CLASS_PARENT_C) -# define nh5pequal_c FNAME(H5PEQUAL_C) # define nh5pisa_class_c FNAME(H5PISA_CLASS_C) # define nh5pcopy_prop_c FNAME(H5PCOPY_PROP_C) # define nh5premove_c FNAME(H5PREMOVE_C) @@ -917,7 +919,6 @@ H5_DLL int_f nh5tis_variable_str_c ( hid_t_f *type_id , int_f *flag ); # define nh5pget_size_c FNAME(h5pget_size_c) # define nh5pget_nprops_c FNAME(h5pget_nprops_c) # define nh5pget_class_parent_c FNAME(h5pget_class_parent_c) -# define nh5pequal_c FNAME(h5pequal_c) # define nh5pisa_class_c FNAME(h5pisa_class_c) # define nh5pcopy_prop_c FNAME(h5pcopy_prop_c) # define nh5premove_c FNAME(h5premove_c) @@ -1071,7 +1072,6 @@ H5_DLL int_f nh5pset_alloc_time_c(hid_t_f *plist, int_f *flag); H5_DLL int_f nh5pget_alloc_time_c(hid_t_f *plist, int_f *flag); H5_DLL int_f nh5pset_fill_time_c(hid_t_f *plist, int_f *flag); H5_DLL int_f nh5pget_fill_time_c(hid_t_f *plist, int_f *flag); -H5_DLL int_f nh5pget_buffer_c(hid_t_f *plist, hsize_t_f *size); H5_DLL int_f nh5pset_meta_block_size_c(hid_t_f *plist, hsize_t_f *size); H5_DLL int_f nh5pget_meta_block_size_c(hid_t_f *plist, hsize_t_f *size); @@ -1111,7 +1111,6 @@ H5_DLL int_f nh5pexist_c(hid_t_f *prp_id, _fcd name, int_f *name_len); H5_DLL int_f nh5pget_size_c(hid_t_f *prp_id, _fcd name, int_f *name_len, size_t_f *size); H5_DLL int_f nh5pget_nprops_c(hid_t_f *prp_id, size_t_f *nprops); H5_DLL int_f nh5pget_class_parent_c(hid_t_f *prp_id, hid_t_f *parent_id); -H5_DLL int_f nh5pequal_c(hid_t_f *plist1_id, hid_t_f *plist2_id, int_f *c_flag); H5_DLL int_f nh5pisa_class_c(hid_t_f *plist, hid_t_f *pclass); H5_DLL int_f nh5pcopy_prop_c(hid_t_f *dst_id, hid_t_f *src_id, _fcd name, int_f *name_len); H5_DLL int_f nh5premove_c(hid_t_f *plid, _fcd name, int_f *name_len); @@ -1208,9 +1207,9 @@ H5_DLL int_f nh5iget_name_c(hid_t_f *obj_id, _fcd buf, size_t_f *buf_size, size_ #endif #endif -H5_DLL int_f nh5eclear_c(); +H5_DLL int_f nh5eclear_c(void); H5_DLL int_f nh5eprint_c1(_fcd name, int_f* namelen); -H5_DLL int_f nh5eprint_c2(); +H5_DLL int_f nh5eprint_c2(void); H5_DLL int_f nh5eget_major_c(int_f* error_no, _fcd name); H5_DLL int_f nh5eget_minor_c(int_f* error_no, _fcd name); H5_DLL int_f nh5eset_auto_c(int_f* printflag); diff --git a/fortran/test/fortranlib_test.f90 b/fortran/test/fortranlib_test.f90 index f32924e..a244f53 100644 --- a/fortran/test/fortranlib_test.f90 +++ b/fortran/test/fortranlib_test.f90 @@ -26,6 +26,7 @@ INTEGER :: mounting_total_error = 0 INTEGER :: reopen_total_error = 0 INTEGER :: fclose_total_error = 0 + INTEGER :: fspace_total_error = 0 INTEGER :: dataset_total_error = 0 INTEGER :: extend_dataset_total_error = 0 INTEGER :: refobj_total_error = 0 @@ -104,6 +105,14 @@ write(*, fmt = e_format) error_string total_error = total_error + fclose_total_error + error_string = failure + CALL file_space(cleanup, fspace_total_error) + IF (fspace_total_error == 0) error_string = success + write(*, fmt = '(21a)', advance = 'no') ' File free space test' + write(*, fmt = '(49x,a)', advance = 'no') ' ' + write(*, fmt = e_format) error_string + total_error = total_error + fspace_total_error + ! write(*,*) ! write(*,*) '=========================================' diff --git a/fortran/test/tH5F.f90 b/fortran/test/tH5F.f90 index ffd0df9..8dba136 100644 --- a/fortran/test/tH5F.f90 +++ b/fortran/test/tH5F.f90 @@ -669,5 +669,79 @@ END SUBROUTINE file_close +! +! The following subroutine tests h5fget_freespace_f +! + + SUBROUTINE file_space(cleanup, total_error) + USE HDF5 ! This module contains all necessary modules + IMPLICIT NONE + LOGICAL, INTENT(IN) :: cleanup + INTEGER, INTENT(OUT) :: total_error + INTEGER :: error + + ! + CHARACTER(LEN=10), PARAMETER :: filename = "file_space" + CHARACTER(LEN=3), PARAMETER :: grpname = "grp" + CHARACTER(LEN=80) :: fix_filename + + INTEGER(HID_T) :: fid ! File identifiers + INTEGER(HSSIZE_T) :: free_space + INTEGER(HID_T) :: group_id ! Group identifier + + CALL h5eset_auto_f(0, error) + + CALL h5_fixname_f(filename, fix_filename, H5P_DEFAULT_F, error) + if (error .ne. 0) then + write(*,*) "Cannot modify filename" + stop + endif + CALL h5fcreate_f(fix_filename, H5F_ACC_TRUNC_F, fid, error) + CALL check("h5fcreate_f",error,total_error) + + CALL h5fget_freespace_f(fid, free_space, error) + CALL check("h5fget_freespace_f",error,total_error) + if(error .eq.0 .and. free_space .ne. 0) then + total_error = total_error + 1 + write(*,*) "Wrong amount of free space reported, ", free_space + endif + + ! Create group in the file. + CALL h5gcreate_f(fid, grpname, group_id, error) + CALL check("h5gcreate_f",error,total_error) + + ! Close group + CALL h5gclose_f(group_id, error) + CALL check("h5gclose_f", error, total_error) + + ! Check the free space now + CALL h5fget_freespace_f(fid, free_space, error) + CALL check("h5fget_freespace_f",error,total_error) + if(error .eq.0 .and. free_space .ne. 0) then + total_error = total_error + 1 + write(*,*) "Wrong amount of free space reported, ", free_space + endif + + !Unlink the group + CALL h5gunlink_f(fid, grpname, error) + CALL check("h5gunlink_f", error, total_error) + + ! Check the free space now + CALL h5fget_freespace_f(fid, free_space, error) + CALL check("h5fget_freespace_f",error,total_error) + if(error .eq.0 .and. free_space .ne. 976) then + total_error = total_error + 1 + write(*,*) "Wrong amount of free space reported, ", free_space + endif + + CALL h5fclose_f(fid, error) + CALL check("h5fclose_f",error,total_error) + + if(cleanup) CALL h5_cleanup_f(filename, H5P_DEFAULT_F, error) + CALL check("h5_cleanup_f", error, total_error) + RETURN + + END SUBROUTINE file_space + diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index a65f9e3..0ceae39 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -41,7 +41,9 @@ New Features Library: -------- - - Added backward compatbility with v1.6 for new Error API. SLU - + - Added new H5Fget_freespace() routine to query the free space in a + given file. QAK 2003/10/06 + - Added backward compatability with v1.6 for new Error API. SLU - 2003/09/24 - Changed 'objno' field in H5G_stat_t structure from 'unsigned long[2]' to 'haddr_t'. QAK - 2003/08/08 diff --git a/src/H5F.c b/src/H5F.c index a3feb92..4148f62 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -4498,3 +4498,42 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5F_sieve_overlap_clear() */ + +/*------------------------------------------------------------------------- + * Function: H5Fget_freespace + * + * Purpose: Retrieves the amount of free space (of a given type) in the + * file. If TYPE is 'H5FD_MEM_DEFAULT', then the amount of free + * space for all types is returned. + * + * Return: Success: Amount of free space for type + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Oct 6, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hssize_t +H5Fget_freespace(hid_t file_id) +{ + H5F_t *file=NULL; /* File object for file ID */ + hssize_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5Fget_freespace, FAIL) + + /* Check args */ + if(NULL==(file=H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + + /* Go get the actual amount of free space in the file */ + if((ret_value = H5FD_get_freespace(file->shared->lf))<0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fget_freespace() */ + diff --git a/src/H5FD.c b/src/H5FD.c index abc320c..23ad863 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -3372,3 +3372,50 @@ herr_t H5FD_get_vfd_handle(H5FD_t *file, hid_t fapl, void** file_handle) done: FUNC_LEAVE_NOAPI(ret_value) } + + +/*------------------------------------------------------------------------- + * Function: H5FD_get_freespace + * + * Purpose: Retrieve the amount of free space in a file. + * + * Return: Success: Amount of free space in file + * Failure: Negative + * + * Programmer: Quincey Koziol + * Monday, October 6, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hssize_t +H5FD_get_freespace(H5FD_t *file) +{ + H5FD_free_t *free_node; /* Pointer to node on free list */ + H5FD_mem_t type; /* Type of memory */ + hssize_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5FD_get_freespace, FAIL) + + /* check args */ + assert(file); + assert(file->cls); + + /* Initialize return value */ + ret_value=0; + + /* Iterate over all the types of memory, to retrieve amount of free space for each */ + for (type=H5FD_MEM_DEFAULT; typefl[type]; + while(free_node) { + ret_value+=free_node->size; + free_node=free_node->next; + } /* end while */ + } /* end for */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_get_freespace() */ + diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index 2df3072..4f1785c 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -69,5 +69,6 @@ H5_DLL herr_t H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t a H5_DLL herr_t H5FD_flush(H5FD_t *file, hid_t dxpl_id, unsigned closing); H5_DLL herr_t H5FD_get_fileno(const H5FD_t *file, unsigned long *filenum); H5_DLL herr_t H5FD_get_vfd_handle(H5FD_t *file, hid_t fapl, void** file_handle); +H5_DLL hssize_t H5FD_get_freespace(H5FD_t *file); #endif /* !_H5FDprivate_H */ diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index 02fd70b..431f9bc 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -112,6 +112,7 @@ H5_DLL int H5Fget_obj_ids(hid_t file_id, unsigned types, int max_objs, hid_t *ob H5_DLL herr_t H5Fget_vfd_handle(hid_t file_id, hid_t fapl, void** file_handle); H5_DLL herr_t H5Fmount(hid_t loc, const char *name, hid_t child, hid_t plist); H5_DLL herr_t H5Funmount(hid_t loc, const char *name); +H5_DLL hssize_t H5Fget_freespace(hid_t file_id); #ifdef __cplusplus } diff --git a/test/tfile.c b/test/tfile.c index b0f48cf..e76999f 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -972,6 +972,90 @@ test_file_perm(void) /**************************************************************** ** +** test_file_freespace(): low-level file test routine. +** This test checks the free space available in a file in various +** situations. +** +*****************************************************************/ +static void +test_file_freespace(void) +{ + hid_t file; /* File opened with read-write permission */ + 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 */ + herr_t ret; + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Low-Level File Free Space\n")); + + /* Create the file (with read-write permission) */ + file = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(file, FAIL, "H5Fcreate"); + + /* Check that the free space is 0 */ + free_space = H5Fget_freespace(file); + CHECK(free_space, FAIL, "H5Fget_freespace"); + VERIFY(free_space, 0, "H5Fget_freespace"); + + /* 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 = H5Dcreate(file, name, H5T_NATIVE_INT, dspace, dcpl); + CHECK(dset, FAIL, "H5Dcreate"); + + 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"); + + /* Check that there is the right amount of free space in the file */ + free_space = H5Fget_freespace(file); + CHECK(free_space, FAIL, "H5Fget_freespace"); + VERIFY(free_space, 168, "H5Fget_freespace"); + + /* Delete datasets in file */ + for(u=0; u<10; u++) { + sprintf(name,"Dataset %u",u); + ret = H5Gunlink(file, name); + CHECK(ret, FAIL, "H5Gunlink"); + } /* end for */ + + /* Check that there is the right amount of free space in the file */ + free_space = H5Fget_freespace(file); + CHECK(free_space, FAIL, "H5Fget_freespace"); + VERIFY(free_space, 3584, "H5Fget_freespace"); + + /* Close file */ + ret = H5Fclose(file); + CHECK(ret, FAIL, "H5Fclose"); + +} /* end test_file_freespace() */ + +/**************************************************************** +** ** test_file(): Main low-level file I/O test routine. ** ****************************************************************/ @@ -987,6 +1071,7 @@ test_file(void) test_file_close(); /* Test file close behavior */ #endif /* H5_NO_SHARED_WRITING */ test_file_perm(); /* Test file access permissions */ + test_file_freespace(); /* Test file free space information */ } /* test_file() */ -- cgit v0.12