diff options
author | James Laird <jlaird@hdfgroup.org> | 2004-09-28 19:04:19 (GMT) |
---|---|---|
committer | James Laird <jlaird@hdfgroup.org> | 2004-09-28 19:04:19 (GMT) |
commit | 5c0011a71384223791d18028968382db43f08a6f (patch) | |
tree | 113cc1dd6c8d0ecd1996ddb8f0e9f7693f470e95 /test | |
parent | a841ea35292de8097b429f98af48b29f21c97893 (diff) | |
download | hdf5-5c0011a71384223791d18028968382db43f08a6f.zip hdf5-5c0011a71384223791d18028968382db43f08a6f.tar.gz hdf5-5c0011a71384223791d18028968382db43f08a6f.tar.bz2 |
[svn-r9329]
Purpose:
Feature
Description:
Datatypes and groups now use H5FO "file object" code that was previously
only used by datasets. These objects will hold a file open if the file
is closed but they have not yet been closed. If these objects are unlinked
then relinked, they will not be destroyed. If they are opened twice (even
by two different names), both IDs will "see" changes made to the object
using the other ID.
When an object is opened using two different names (e.g., if a dataset was
opened under one name, then mounted and opened under its new name), calling
H5Iget_name() on a given hid_t will return the name used to open that hid_t,
not the current name of the object (this is a feature, and a change from the
previous behavior of datasets).
Solution:
Used H5FO code that was already in place for datasets. Broke H5D_t's, H5T_t's,
and H5G_t's into a "shared" struct and a private struct. The shared structs
(H5D_shared_t, etc.) hold the object's information and are used by all IDs
that point to a given object in the file. The private structs are pointed
to by the hid_t and contain the object's group entry information (including its
name) and a pointer to the shared struct for that object.
This changed the naming of structs throughout the library (e.g., datatype->size
is now datatype->shared->size). I added an updated H5Tinit.c to windows.zip.
Platforms tested:
Visual Studio 7, sleipnir, arabica, verbena
Misc. update:
Diffstat (limited to 'test')
-rw-r--r-- | test/getname.c | 100 | ||||
-rw-r--r-- | test/unlink.c | 149 |
2 files changed, 230 insertions, 19 deletions
diff --git a/test/getname.c b/test/getname.c index 69f741c..29816f0 100644 --- a/test/getname.c +++ b/test/getname.c @@ -65,7 +65,7 @@ int main( void ) hid_t group_id, group2_id, group3_id, group4_id, group5_id, group6_id, group7_id; hid_t dataset_id, dataset2_id; hid_t space_id; - hid_t type_id; + hid_t type_id, type2_id; hsize_t dims[1] = { 5 }; /*buffer to hold name and its size */ @@ -1212,6 +1212,31 @@ int main( void ) PASSED(); + /*------------------------------------------------------------------------- + * Test H5Iget_name with objects that have two names + *------------------------------------------------------------------------- + */ + +TESTING("H5Iget_name with datasets that have two names"); + +/* Open dataset named "d"*/ +if ((dataset_id = H5Dopen( file_id, "/g17/d"))<0) goto out; + +/* Create link to dataset named "link" */ +if (H5Glink2(dataset_id,".",H5G_LINK_HARD,file_id,"/g17/link")<0) goto out; +if ((dataset2_id = H5Dopen( file_id, "/g17/link"))<0) goto out; + +/* Make sure that the two IDs use two different names */ +if(H5Iget_name(dataset_id, name, size)<0) goto out; +if(check_name(name, "/g17/d")!=0) goto out; + +if(H5Iget_name(dataset2_id, name, size)<0) goto out; +if(check_name(name, "/g17/link")!=0) goto out; + +if(H5Dclose(dataset_id)<0) goto out; +if(H5Dclose(dataset2_id)<0) goto out; + +PASSED(); /*------------------------------------------------------------------------- @@ -1418,6 +1443,14 @@ int main( void ) if ((group_id = H5Gcreate( file_id, "/g18", 0 ))<0) goto out; if ((group2_id = H5Gcreate( file_id, "/g18/g2", 0 ))<0) goto out; + /* Also create a dataset and a datatype */ + if ((space_id = H5Screate_simple( 1, dims, NULL ))<0) goto out; + if ((type_id = H5Tcopy(H5T_NATIVE_INT))<0) goto out; + if ((dataset_id = H5Dcreate( file_id, "g18/d2", type_id, space_id, + H5P_DEFAULT ))<0) goto out; + + if (H5Tcommit(file_id, "g18/t2", type_id) <0) goto out; + /* Create second file and group "/g3/g4/g5" in it */ file1_id = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); if ((group3_id = H5Gcreate( file1_id, "/g3", 0 ))<0) goto out; @@ -1427,39 +1460,70 @@ int main( void ) /* Mount first file at "g3/g4" in the second file */ if (H5Fmount(file1_id, "/g3/g4", file_id, H5P_DEFAULT)<0) goto out; - /* Get name for the ID of the first file, should be "/g18/g2" still */ + /* Get name for the group ID in the first file, should be "/g18/g2" still */ if (H5Iget_name( group2_id, name, size )<0) goto out; - - /* Verify */ if (check_name( name, "/g18/g2" )!=0) goto out; - /* Open the mounted group */ - if ((group6_id = H5Gopen( file_id, "/g3/g4/g18/g2" ))<0) goto out; + /* Get name for the dataset ID in the first file, should be "/g18/g2/d2" still */ + if (H5Iget_name( dataset_id, name, size )<0) goto out; + if (check_name( name, "/g18/d2" )!=0) goto out; - /* Get name */ - if (H5Iget_name( group6_id, name, size )<0) goto out; + /* Get name for the datatype ID in the first file, should be "/g18/g2/t2" still */ + if (H5Iget_name( type_id, name, size )<0) goto out; + if (check_name( name, "/g18/t2" )!=0) goto out; - /* Verify */ + /* Open the mounted group, dataset, and datatype through their new names */ + if ((group6_id = H5Gopen( file1_id, "/g3/g4/g18/g2" ))<0) goto out; + if ((dataset2_id = H5Dopen( file1_id, "/g3/g4/g18/d2" ))<0) goto out; + if ((type2_id = H5Topen( file1_id, "/g3/g4/g18/t2" ))<0) goto out; + + /* Verify names */ + if (H5Iget_name( group6_id, name, size )<0) goto out; if (check_name( name, "/g3/g4/g18/g2" )!=0) goto out; + if (H5Iget_name( dataset2_id, name, size )<0) goto out; + if (check_name( name, "/g3/g4/g18/d2" )!=0) goto out; + + if (H5Iget_name( type2_id, name, size )<0) goto out; + if (check_name( name, "/g3/g4/g18/t2" )!=0) goto out; + + /* Verify that old IDs still refer to objects by their old names */ + if (H5Iget_name( group2_id, name, size )<0) goto out; + if (check_name( name, "/g18/g2" )!=0) goto out; + + if (H5Iget_name( dataset_id, name, size )<0) goto out; + if (check_name( name, "/g18/d2" )!=0) goto out; + + if (H5Iget_name( type_id, name, size )<0) goto out; + if (check_name( name, "/g18/t2" )!=0) goto out; + /* Unmount */ if (H5Funmount(file1_id, "/g3/g4")<0) goto out; - /* Get name for the ID of the first file, should be "/g18/g2" still */ + /* Get name for the IDs of the first file, should be unchanged */ if (H5Iget_name( group2_id, name, size )<0) goto out; + if (check_name( name, "/g18/g2" )!=0) goto out; - /* Verify */ - if (check_name( name, "/g18/g2" )!=0) - goto out; + if (H5Iget_name( dataset_id, name, size )<0) goto out; + if (check_name( name, "/g18/d2" )!=0) goto out; + + if (H5Iget_name( type_id, name, size )<0) goto out; + if (check_name( name, "/g18/t2" )!=0) goto out; - /* Get name for the ID of the secondt file, should be "" */ + /* Get name for the IDs of the second file, should be "" */ if (H5Iget_name( group6_id, name, size )<0) goto out; + if (check_name( name, "" )!=0) goto out; - /* Verify */ - if (check_name( name, "" )!=0) - goto out; + if (H5Iget_name( dataset2_id, name, size )<0) goto out; + if (check_name( name, "" )!=0) goto out; - /* Close */ + if (H5Iget_name( type2_id, name, size )<0) goto out; + if (check_name( name, "" )!=0) goto out; + + H5Tclose( type_id ); + H5Tclose( type2_id ); + H5Dclose( dataset_id ); + H5Dclose( dataset2_id ); H5Gclose( group_id ); H5Gclose( group2_id ); H5Gclose( group3_id ); diff --git a/test/unlink.c b/test/unlink.c index 8e6a9ac..0fa7d4f 100644 --- a/test/unlink.c +++ b/test/unlink.c @@ -29,7 +29,9 @@ const char *FILENAME[] = { "lunlink", "filespace", "slashes", - "resurrect", + "resurrect_set", + "resurrect_type", + "resurrect_group", "unlink_chunked", NULL }; @@ -44,6 +46,7 @@ const char *FILENAME[] = { #define DATASET2NAME "dataset2" #define ATTRNAME "attribute" #define TYPENAME "datatype" +#define TYPE2NAME "datatype2" #define FILESPACE_NDIMS 3 #define FILESPACE_DIM0 20 #define FILESPACE_DIM1 20 @@ -1837,6 +1840,9 @@ test_resurrect_dataset(void) /* Unlink the dataset while it's open (will mark it for deletion when closed) */ if(H5Gunlink(f, DATASETNAME)<0) TEST_ERROR; + /* Check that dataset name is NULL */ + if(H5Iget_name(d, NULL, 0) != 0) TEST_ERROR; + /* Re-link the dataset to the group hierarchy (shouldn't get deleted now) */ if(H5Glink2(d, ".", H5G_LINK_HARD, f, DATASET2NAME)<0) TEST_ERROR; @@ -1870,6 +1876,145 @@ error: /*------------------------------------------------------------------------- + * Function: test_resurrect_datatype + * + * Purpose: Tests deleting a datatype while it's still open and then + * "resurrecting" it by creating a link to it again. + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: James Laird + * Wednesday, July 28, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test_resurrect_datatype(void) +{ + hid_t file=-1, type=-1, fapl=-1, loc_id=-1; + char filename[1024]; + + TESTING("Resurrecting datatype after deletion"); + + /* Create file */ + fapl = h5_fileaccess(); + h5_fixname(FILENAME[7], fapl, filename, sizeof filename); + + /* Create the file */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create a named datatype in the file */ + if((type = H5Tcopy (H5T_NATIVE_INT))<0) TEST_ERROR; + if(H5Tcommit (file, TYPENAME, type)<0) TEST_ERROR; + + /* Unlink the datatype while it's open (will mark it for deletion when closed) */ + if(H5Gunlink(file, TYPENAME)<0) TEST_ERROR; + + /* Check that datatype name is NULL */ + if(H5Iget_name(type, NULL, 0) != 0) TEST_ERROR; + + /* Re-link the datatype to the group hierarchy (shouldn't get deleted now) */ + if(H5Glink2(type, ".", H5G_LINK_HARD, file, TYPE2NAME) < 0) TEST_ERROR; + + /* Close things */ + if(H5Tclose(type)<0) TEST_ERROR; + if(H5Fclose(file)<0) TEST_ERROR; + + /* Re-open the file */ + if((file=H5Fopen(filename, H5F_ACC_RDONLY, fapl))<0) TEST_ERROR; + + /* Attempt to open the datatype under the new name */ + if((type=H5Topen(file,TYPE2NAME))<0) TEST_ERROR; + + /* Close things */ + if(H5Tclose(type)<0) TEST_ERROR; + if(H5Fclose(file)<0) TEST_ERROR; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Tclose(type); + H5Fclose(file); + } H5E_END_TRY; + return 1; +} /* end test_resurrect_datatype() */ + + +/*------------------------------------------------------------------------- + * Function: test_resurrect_group + * + * Purpose: Tests deleting a group while it's still open and then + * "resurrecting" it by creating a link to it again. + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: James Laird + * Wednesday, July 28, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test_resurrect_group(void) +{ + hid_t file=-1, group=-1, fapl=-1; + char filename[1024]; + + TESTING("Resurrecting group after deletion"); + + /* Create file */ + fapl = h5_fileaccess(); + h5_fixname(FILENAME[8], fapl, filename, sizeof filename); + + /* Create the file */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create a group in the file */ + if((group = H5Gcreate (file, GROUPNAME, 0))<0) TEST_ERROR; + + /* Unlink the group while it's open (will mark it for deletion when closed) */ + if(H5Gunlink(file, GROUPNAME)<0) TEST_ERROR; + + /* Check that group's name is NULL */ + if(H5Iget_name(group, NULL, 0) != 0) TEST_ERROR; + + /* Re-link the group into the group hierarchy (shouldn't get deleted now) */ + if(H5Glink2(group, ".", H5G_LINK_HARD, file, GROUP2NAME)<0) TEST_ERROR; + + /* Close things */ + if(H5Gclose(group)<0) TEST_ERROR; + if(H5Fclose(file)<0) TEST_ERROR; + + /* Re-open the file */ + if((file=H5Fopen(filename, H5F_ACC_RDONLY, fapl))<0) TEST_ERROR; + + /* Attempt to open the datatype under the new name */ + if((group=H5Gopen(file,GROUP2NAME))<0) TEST_ERROR; + + /* Close things */ + if(H5Gclose(group)<0) TEST_ERROR; + if(H5Fclose(file)<0) TEST_ERROR; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Gclose(group); + H5Fclose(file); + } H5E_END_TRY; + return 1; +} /* end test_resurrect_group() */ + + +/*------------------------------------------------------------------------- * Function: test_unlink_chunked_dataset * * Purpose: Tests deleting a chunked dataset @@ -2035,6 +2180,8 @@ main(void) /* Test "resurrecting" objects */ nerrors += test_resurrect_dataset(); + nerrors += test_resurrect_datatype(); + nerrors += test_resurrect_group(); /* Test unlinking chunked datasets */ nerrors += test_unlink_chunked_dataset(); |