/*------------------------------------------------------------------------- * Function: gen_extlink_trg * * Purpose: generate target external link objs * * Programmer: Jonathan Kim (March 03, 2010) *------------------------------------------------------------------------*/ static herr_t gen_extlink_trg(hid_t loc_id) { hid_t gid=0, tid=0; int status; herr_t ret = SUCCEED; /*----------------------------------------------------------------------- * Groups *------------------------------------------------------------------------*/ /*-------------- * target file */ gid = H5Gcreate2(loc_id, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); if (gid < 0) { fprintf(stderr, "Error: %s %d> H5Gcreate2 failed.\n", FUNC, __LINE__); ret = FAIL; goto out; } /*-------------- * add dataset */ gent_simple(loc_id); /*-------------------- * add named datatype */ tid = H5Tcopy(H5T_NATIVE_INT); status = H5Tcommit2(loc_id, "datatype", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); if (status < 0) { fprintf(stderr, "Error: %s %d> H5Tcommit2 failed.\n", FUNC, __LINE__); ret = FAIL; goto out; } out: if(gid > 0) H5Gclose(gid); if(tid > 0) H5Tclose(tid); return ret; }
/*------------------------------------------------------------------------- * Function: gent_named_vl * * Purpose: Generate a variable lenght named datatype for a dataset in LOC_ID * *------------------------------------------------------------------------- */ static void gent_named_vl(hid_t loc_id) { hid_t sid, did, tid; hsize_t dims[1] = {2}; hvl_t buf[2]; /* allocate and initialize VL dataset to write */ buf[0].len = 1; buf[0].p = HDmalloc( 1 * sizeof(int)); ((int *)buf[0].p)[0]=1; buf[1].len = 2; buf[1].p = HDmalloc( 2 * sizeof(int)); ((int *)buf[1].p)[0]=2; ((int *)buf[1].p)[1]=3; /* create dataspace */ sid = H5Screate_simple(1, dims, NULL); /* create datatype */ tid = H5Tvlen_create(H5T_NATIVE_INT); /* create named datatype */ H5Tcommit2(loc_id, "vl", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); /* create dataset */ did = H5Dcreate2(loc_id, DATASET_NAMED_VL, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); /* write */ H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf); /* close */ H5Dvlen_reclaim(tid,sid,H5P_DEFAULT,buf); H5Sclose(sid); H5Dclose(did); H5Tclose(tid); }
mhdf_FileHandle mhdf_createFile( const char* filename, int overwrite, const char** elem_type_list, size_t elem_list_len, hid_t id_type, mhdf_Status* status ) { FileHandle* file_ptr; unsigned int flags; unsigned char idx; size_t i; hid_t enum_id, group_id; int rval; API_BEGIN; if (elem_list_len > 255) { mhdf_setFail( status, "Element type list too long." ); return NULL; } mhdf_setOkay( status ); /* Create struct to hold working data */ file_ptr = mhdf_alloc_FileHandle( 0, id_type, status ); if (!file_ptr) return NULL; /* Create the file */ flags = overwrite ? H5F_ACC_TRUNC : H5F_ACC_EXCL; file_ptr->hdf_handle = H5Fcreate( filename, flags, H5P_DEFAULT, H5P_DEFAULT ); if (file_ptr->hdf_handle < 0) { mhdf_setFail( status, "Failed to create file \"%s\"", filename ); free( file_ptr ); return NULL; } /* Create file structure */ if (!make_hdf_group( ROOT_GROUP, file_ptr->hdf_handle, 6, status ) || !make_hdf_group( TAG_GROUP, file_ptr->hdf_handle, 0, status ) || !make_hdf_group( ELEMENT_GROUP, file_ptr->hdf_handle, 8, status ) || !make_hdf_group( NODE_GROUP, file_ptr->hdf_handle, 3, status ) || !make_hdf_group( SET_GROUP, file_ptr->hdf_handle, 5, status ) || !make_hdf_group( NODE_TAG_GROUP, file_ptr->hdf_handle, 0, status ) || !make_hdf_group( SET_TAG_GROUP, file_ptr->hdf_handle, 0, status )) { H5Fclose( file_ptr->hdf_handle ); free( file_ptr ); return NULL; } /* Store the max ID as an attribite on the /tstt/ group */ #if defined(H5Gopen_vers) && H5Gopen_vers > 1 group_id = H5Gopen2( file_ptr->hdf_handle, ROOT_GROUP, H5P_DEFAULT ); #else group_id = H5Gopen( file_ptr->hdf_handle, ROOT_GROUP ); #endif rval = mhdf_create_scalar_attrib( group_id, MAX_ID_ATTRIB, H5T_NATIVE_ULONG, &file_ptr->max_id, status ); H5Gclose( group_id ); if (!rval) { H5Fclose( file_ptr->hdf_handle ); free( file_ptr ); return NULL; } /* Create the type name list in file */ enum_id = H5Tenum_create( H5T_NATIVE_UCHAR ); if (enum_id < 0) { mhdf_setFail( status, "Failed to store elem type list." ); H5Fclose( file_ptr->hdf_handle ); free( file_ptr ); return NULL; } for (i = 0; i < elem_list_len; ++i) { if (!elem_type_list[i] || !*elem_type_list[i]) continue; idx = (unsigned char)i; if ( H5Tenum_insert( enum_id, elem_type_list[i], &idx ) < 0) { mhdf_setFail( status, "Failed to store elem type list." ); H5Fclose( file_ptr->hdf_handle ); free( file_ptr ); return NULL; } } #if defined(H5Tcommit_vers) && H5Tcommit_vers > 1 if (H5Tcommit2( file_ptr->hdf_handle, TYPE_ENUM_PATH, enum_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT ) < 0) #else if (H5Tcommit( file_ptr->hdf_handle, TYPE_ENUM_PATH, enum_id ) < 0) #endif { mhdf_setFail( status, "Failed to store elem type list." ); H5Fclose( file_ptr->hdf_handle ); free( file_ptr ); return NULL; } H5Tclose( enum_id ); API_END_H( 1 ); return file_ptr; }
/*------------------------------------------------------------------------- * Function: test_refresh * * Purpose: This function tests refresh (evict/reload) of individual * objects' metadata from the metadata cache. * * Return: 0 on Success, 1 on Failure * * Programmer: Mike McGreevy * August 17, 2010 * * Modifications: * *------------------------------------------------------------------------- */ herr_t test_refresh(void) { /************************************************************************** * * Test Description: * * This test will build an HDF5 file with several objects in a varying * hierarchical layout. It will then flush the entire file to disk. Then, * an attribute will be added to each object in the file. * * One by one, this process will flush each object to disk, individually. * It will also be coordinating with another process, which will open * the object before it is flushed by this process, and then refresh the * object after it's been flushed, comparing the before and after object * information to ensure that they are as expected. (i.e., most notably, * that an attribute has been added, and is only visible after a * successful call to a H5*refresh function). * * As with the flush case, the implemention is a bit tricky as it's * dealing with signals going back and forth between the two processes * to ensure the timing is correct, but basically, an example: * * Step 1. Dataset is created. * Step 2. Dataset is flushed. * Step 3. Attribute on Dataset is created. * Step 4. Another process opens the dataset and verifies that it does * not see an attribute (as the attribute hasn't been flushed yet). * Step 5. This process flushes the dataset again (with Attribute attached). * Step 6. The other process calls H5Drefresh, which should evict/reload * the object's metadata, and thus pick up the attribute that's * attached to it. Most other before/after object information is * compared for sanity as well. * Step 7. Rinse and Repeat for each object in the file. * **************************************************************************/ /************************************************************************** * Generated Test File will look like this: * * GROUP "/" * DATASET "Dataset1" * GROUP "Group1" { * DATASET "Dataset2" * GROUP "Group2" { * DATATYPE "CommittedDatatype3" * } * } * GROUP "Group3" { * DATASET "Dataset3" * DATATYPE "CommittedDatatype2" * } * DATATYPE "CommittedDatatype1" **************************************************************************/ /* Variables */ hid_t aid,fid,sid,tid1,did,dcpl,fapl = 0; hid_t gid,gid2,gid3,tid2,tid3,did2,did3,status = 0; hsize_t dims[2] = {50,50}; hsize_t cdims[2] = {1,1}; int fillval = 2; /* Testing Message */ HDfprintf(stdout, "Testing individual object refresh behavior:\n"); /* Cleanup any old error or signal files */ CLEANUP_FILES; /* ================ */ /* CREATE TEST FILE */ /* ================ */ /* Create File */ if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) TEST_ERROR; if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) TEST_ERROR; if ((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC|H5F_ACC_SWMR_WRITE, H5P_DEFAULT, fapl)) < 0) TEST_ERROR; /* Create data space and types */ if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR; if ( H5Pset_chunk(dcpl, 2, cdims) < 0 ) TEST_ERROR; if ( H5Pset_fill_value(dcpl, H5T_NATIVE_INT, &fillval) < 0 ) TEST_ERROR; if ((sid = H5Screate_simple(2, dims, dims)) < 0) TEST_ERROR; if ((tid1 = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR; if ((tid2 = H5Tcopy(H5T_NATIVE_CHAR)) < 0) TEST_ERROR; if ((tid3 = H5Tcopy(H5T_NATIVE_LONG)) < 0) TEST_ERROR; /* Create Group1 */ if ((gid = H5Gcreate2(fid, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Create Group2 */ if ((gid2 = H5Gcreate2(gid, "Group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Create Group3 */ if ((gid3 = H5Gcreate2(fid, "Group3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Create Dataset1 */ if ((did = H5Dcreate2(fid, "Dataset1", tid1, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) TEST_ERROR; /* Create Dataset2 */ if ((did2 = H5Dcreate2(gid, "Dataset2", tid3, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Create Dataset3 */ if ((did3 = H5Dcreate2(gid3, "Dataset3", tid2, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Create CommittedDatatype1 */ if ((status = H5Tcommit2(fid, "CommittedDatatype1", tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Create CommittedDatatype2 */ if ((status = H5Tcommit2(gid2, "CommittedDatatype2", tid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Create CommittedDatatype3 */ if ((status = H5Tcommit2(gid3, "CommittedDatatype3", tid3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Flush File to Disk */ if (H5Fflush(fid, H5F_SCOPE_GLOBAL) < 0) TEST_ERROR; /* Create an attribute on each object. These will not immediately hit disk, and thus be unavailable to another process until this process flushes the object and the other process refreshes from disk. */ if ((aid = H5Acreate2(did, "Attribute", tid1, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; if (H5Aclose(aid) < 0) TEST_ERROR; if ((aid = H5Acreate2(did2, "Attribute", tid1, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; if (H5Aclose(aid) < 0) TEST_ERROR; if ((aid = H5Acreate2(did3, "Attribute", tid1, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; if (H5Aclose(aid) < 0) TEST_ERROR; if ((aid = H5Acreate2(gid, "Attribute", tid1, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; if (H5Aclose(aid) < 0) TEST_ERROR; if ((aid = H5Acreate2(gid2, "Attribute", tid1, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; if (H5Aclose(aid) < 0) TEST_ERROR; if ((aid = H5Acreate2(gid3, "Attribute", tid1, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; if (H5Aclose(aid) < 0) TEST_ERROR; if ((aid = H5Acreate2(tid1, "Attribute", tid1, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; if (H5Aclose(aid) < 0) TEST_ERROR; if ((aid = H5Acreate2(tid2, "Attribute", tid1, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; if (H5Aclose(aid) < 0) TEST_ERROR; if ((aid = H5Acreate2(tid3, "Attribute", tid1, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; if (H5Aclose(aid) < 0) TEST_ERROR; /* ================ */ /* Refresh Datasets */ /* ================ */ TESTING("to ensure that H5Drefresh correctly refreshes single datasets"); /* Verify First Dataset can be refreshed with H5Drefresh */ if (start_refresh_verification_process(D1) != 0) TEST_ERROR; if (H5Oflush(did) < 0) TEST_ERROR; if (end_refresh_verification_process() != 0) TEST_ERROR; /* Verify Second Dataset can be refreshed with H5Drefresh */ if (start_refresh_verification_process(D2) != 0) TEST_ERROR; if (H5Oflush(did2) < 0) TEST_ERROR; if (end_refresh_verification_process() != 0) TEST_ERROR; PASSED(); /* ============== */ /* Refresh Groups */ /* ============== */ TESTING("to ensure that H5Grefresh correctly refreshes single groups"); /* Verify First Group can be refreshed with H5Grefresh */ if (start_refresh_verification_process(G1) != 0) TEST_ERROR; if (H5Oflush(gid) < 0) TEST_ERROR; if (end_refresh_verification_process() != 0) TEST_ERROR; /* Verify Second Group can be refreshed with H5Grefresh */ if (start_refresh_verification_process(G2) != 0) TEST_ERROR; if (H5Oflush(gid2) < 0) TEST_ERROR; if (end_refresh_verification_process() != 0) TEST_ERROR; PASSED(); /* ================= */ /* Refresh Datatypes */ /* ================= */ TESTING("to ensure that H5Trefresh correctly refreshes single datatypes"); /* Verify First Committed Datatype can be refreshed with H5Trefresh */ if (start_refresh_verification_process(T1) != 0) TEST_ERROR; if (H5Oflush(tid1) < 0) TEST_ERROR; if (end_refresh_verification_process() != 0) TEST_ERROR; /* Verify Second Committed Datatype can be refreshed with H5Trefresh */ if (start_refresh_verification_process(T2) != 0) TEST_ERROR; if (H5Oflush(tid2) < 0) TEST_ERROR; if (end_refresh_verification_process() != 0) TEST_ERROR; PASSED(); /* =============== */ /* Refresh Objects */ /* =============== */ TESTING("to ensure that H5Orefresh correctly refreshes single objects"); /* Verify Third Dataset can be refreshed with H5Orefresh */ if (start_refresh_verification_process(D3) != 0) TEST_ERROR; if (H5Oflush(did3) < 0) TEST_ERROR; if (end_refresh_verification_process() != 0) TEST_ERROR; /* Verify Third Group can be refreshed with H5Orefresh */ if (start_refresh_verification_process(G3) != 0) TEST_ERROR; if (H5Oflush(gid3) < 0) TEST_ERROR; if (end_refresh_verification_process() != 0) TEST_ERROR; /* Verify Third Committed Datatype can be refreshed with H5Orefresh */ if (start_refresh_verification_process(T3) != 0) TEST_ERROR; if (H5Oflush(tid3) < 0) TEST_ERROR; if (end_refresh_verification_process() != 0) TEST_ERROR; PASSED(); /* ================== */ /* Cleanup and Return */ /* ================== */ /* Close Stuff */ if (H5Pclose(fapl) < 0) TEST_ERROR; if (H5Tclose(tid1) < 0) TEST_ERROR; if (H5Tclose(tid2) < 0) TEST_ERROR; if (H5Tclose(tid3) < 0) TEST_ERROR; if (H5Dclose(did) < 0) TEST_ERROR; if (H5Dclose(did2) < 0) TEST_ERROR; if (H5Dclose(did3) < 0) TEST_ERROR; if (H5Gclose(gid) < 0) TEST_ERROR; if (H5Gclose(gid2) < 0) TEST_ERROR; if (H5Gclose(gid3) < 0) TEST_ERROR; if (H5Sclose(sid) < 0) TEST_ERROR; if (H5Fclose(fid) < 0) TEST_ERROR; /* Delete Test File */ HDremove(FILENAME); if (end_verification() < 0) TEST_ERROR; return SUCCEED; error: /* Return */ return FAIL; } /* test_refresh() */
/*------------------------------------------------------------------------- * Function: test_flush * * Purpose: This function tests flushing individual objects' metadata * from the metadata cache. * * Return: 0 on Success, 1 on Failure * * Programmer: Mike McGreevy * July 1, 2010 * * Modifications: * *------------------------------------------------------------------------- */ herr_t test_flush(void) { /************************************************************************** * * Test Description: * * This test will build an HDF5 file with several objects in a varying * hierarchical layout. It will then attempt to flush the objects * in the file one by one, individually, using the four H5*flush * routines (D,G,T, and O). After each call to either create or flush an * object, a series of verifications will occur on each object in the file. * * Each verification consists of spawning off a new process and determining * if the object can be opened and its information retreived in said * alternate process. It reports the results, which are compared to an * expected value (either that the object can be found on disk, or that it * cannot). * * Note that to spawn a verification, this program sends a signal (by creating * a file on disk) to the test script controlling it, indicating how to * run the verification. * * Implementation is funky, but basically, an example: * * Step 1. Dataset is created. * Step 2. Verify that dataset can't be opened by separate process, as * it should not have been flushed to disk yet. * Step 3. Group is created. * Step 4. Verify that group can't be opened by separate process. * Step 5. H5Gflush is called on the group. * Step 6. Verify that group CAN be opened, but dataset still has * yet to hit disk, and CANNOT be opened. Success! Only the group * was flushed. * **************************************************************************/ /************************************************************************** * Generated Test File will look like this: * * GROUP "/" * DATASET "Dataset1" * GROUP "Group1" { * DATASET "Dataset2" * GROUP "Group2" { * DATATYPE "CommittedDatatype3" * } * } * GROUP "Group3" { * DATASET "Dataset3" * DATATYPE "CommittedDatatype2" * } * DATATYPE "CommittedDatatype1" **************************************************************************/ /* Variables */ hid_t fid,gid,gid2,gid3,sid,tid1,tid2,tid3,did,did2,did3,rid,fapl,status = 0; hsize_t dims[2] = {3,5}; /* Testing Message */ HDfprintf(stdout, "Testing individual object flush behavior:\n"); /* Cleanup any old error or signal files */ CLEANUP_FILES; /* ================ */ /* CREATE TEST FILE */ /* ================ */ /* Create file, open root group - have to use latest file format for SWMR */ if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) TEST_ERROR; if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) TEST_ERROR; if ((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC|H5F_ACC_SWMR_WRITE, H5P_DEFAULT, fapl)) < 0) TEST_ERROR; if ((rid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) TEST_ERROR; /* Create data space and types */ if ((sid = H5Screate_simple(2, dims, dims)) < 0) TEST_ERROR; if ((tid1 = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR; if ((tid2 = H5Tcopy(H5T_NATIVE_CHAR)) < 0) TEST_ERROR; if ((tid3 = H5Tcopy(H5T_NATIVE_LONG)) < 0) TEST_ERROR; /* Create Group1 */ if ((gid = H5Gcreate2(fid, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Create Group2 */ if ((gid2 = H5Gcreate2(gid, "Group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Create Group3 */ if ((gid3 = H5Gcreate2(fid, "Group3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Create Dataset1 */ if ((did = H5Dcreate2(fid, "Dataset1", tid1, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Create Dataset2 */ if ((did2 = H5Dcreate2(gid, "Dataset2", tid3, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Create Dataset3 */ if ((did3 = H5Dcreate2(gid3, "Dataset3", tid2, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Create CommittedDatatype1 */ if ((status = H5Tcommit2(fid, "CommittedDatatype1", tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Create CommittedDatatype2 */ if ((status = H5Tcommit2(gid2, "CommittedDatatype2", tid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Create CommittedDatatype3 */ if ((status = H5Tcommit2(gid3, "CommittedDatatype3", tid3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* ============ */ /* FLUSH GROUPS */ /* ============ */ /* Test */ TESTING("to ensure H5Gflush correctly flushes single groups"); /* First, let's verify that nothing is currently flushed. */ if (run_flush_verification_process(RG, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G1, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G2, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D1, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D2, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T1, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T2, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR; /* Then, flush the root group and verify it's the only thing on disk */ if ((status = H5Gflush(rid)) < 0) TEST_ERROR; if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G1, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G2, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D1, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D2, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T1, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T2, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR; /* Flush Group1 and Verify it is recently flushed, and nothing * else has changed. */ if ((status = H5Gflush(gid)) < 0) TEST_ERROR; if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G2, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D1, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D2, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T1, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T2, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR; /* Flush Group2 and Verify it is recently flushed, and nothing * else has changed. */ if ((status = H5Gflush(gid2)) < 0) TEST_ERROR; if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D1, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D2, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T1, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T2, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR; PASSED(); /* ============== */ /* FLUSH DATASETS */ /* ============== */ /* Test */ TESTING("to ensure H5Dflush correctly flushes single datasets"); /* Flush Dataset1 and verify it's the only thing that hits disk. */ if ((status = H5Dflush(did)) < 0) TEST_ERROR; if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D2, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T1, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T2, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR; /* Flush Dataset2 and verify it's the only thing that hits disk. */ if ((status = H5Dflush(did2)) < 0) TEST_ERROR; if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T1, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T2, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR; PASSED(); /* =============== */ /* FLUSH DATATYPES */ /* =============== */ /* Test */ TESTING("to ensure H5Tflush correctly flushes single datatypes"); /* Flush Datatype 1 and verify it's the only thing that hits disk. */ if ((status = H5Tflush(tid1)) < 0) TEST_ERROR; if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T2, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR; /* Flush Datatype 2 and verify it's the only thing that hits disk. */ if ((status = H5Tflush(tid2)) < 0) TEST_ERROR; if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR; PASSED(); /* ============= */ /* FLUSH OBJECTS */ /* ============= */ /* Test */ TESTING("to ensure H5Oflush correctly flushes single objects"); /* Flush Group3 and verify it's the only thing that hits disk. */ if ((status = H5Oflush(gid3)) < 0) TEST_ERROR; if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G3, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D3, NOT_FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR; /* Flush Dataset3 and verify it's the only thing that hits disk. */ if ((status = H5Oflush(did3)) < 0) TEST_ERROR; if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G3, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D3, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T3, NOT_FLUSHED) != 0) TEST_ERROR; /* Flush CommittedDatatype3 and verify it's the only thing that hits disk. */ if ((status = H5Oflush(tid3)) < 0) TEST_ERROR; if (run_flush_verification_process(RG, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(G3, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(D3, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T1, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T2, FLUSHED) != 0) TEST_ERROR; if (run_flush_verification_process(T3, FLUSHED) != 0) TEST_ERROR; PASSED(); /* ================== */ /* Cleanup and Return */ /* ================== */ if (H5Pclose(fapl) < 0) TEST_ERROR; if (H5Gclose(gid) < 0) TEST_ERROR; if (H5Gclose(gid2) < 0) TEST_ERROR; if (H5Dclose(did) < 0) TEST_ERROR; if (H5Dclose(did2) < 0) TEST_ERROR; if (H5Gclose(rid) < 0) TEST_ERROR; if (H5Fclose(fid) < 0) TEST_ERROR; /* Delete test file */ HDremove(FILENAME); if (end_verification() < 0) TEST_ERROR; return SUCCEED; error: return FAIL; } /* end test_flush */
/* * test_objnames * Tests that UTF-8 can be used for object names in the file. * Tests groups, datasets, named datatypes, and soft links. * Note that this test doesn't actually mark the names as being * in UTF-8. At the time this test was written, that feature * didn't exist in HDF5, and when the character encoding property * was added to links it didn't change how they were stored in the file, * -JML 2/2/2006 */ void test_objnames(hid_t fid, const char* string) { hid_t grp_id, grp1_id, grp2_id, grp3_id; hid_t type_id, dset_id, space_id; char read_buf[MAX_STRING_LENGTH]; char path_buf[MAX_PATH_LENGTH]; hsize_t dims=1; hobj_ref_t obj_ref; herr_t ret; /* Create a group with a UTF-8 name */ grp_id = H5Gcreate2(fid, string, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(grp_id, FAIL, "H5Gcreate2"); /* Set a comment on the group to test that we can access the group * Also test that UTF-8 comments can be read. */ ret = H5Oset_comment_by_name(fid, string, string, H5P_DEFAULT); CHECK(ret, FAIL, "H5Oset_comment_by_name"); ret = H5Oget_comment_by_name(fid, string, read_buf, (size_t)MAX_STRING_LENGTH, H5P_DEFAULT); CHECK(ret, FAIL, "H5Oget_comment_by_name"); ret = H5Gclose(grp_id); CHECK(ret, FAIL, "H5Gclose"); VERIFY(HDstrcmp(string, read_buf), 0, "strcmp"); /* Create a new dataset with a UTF-8 name */ grp1_id = H5Gcreate2(fid, GROUP1_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(grp1_id, FAIL, "H5Gcreate2"); space_id = H5Screate_simple(RANK, &dims, NULL); CHECK(space_id, FAIL, "H5Screate_simple"); dset_id = H5Dcreate2(grp1_id, string, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(dset_id, FAIL, "H5Dcreate2"); /* Make sure that dataset can be opened again */ ret = H5Dclose(dset_id); CHECK(ret, FAIL, "H5Dclose"); ret = H5Sclose(space_id); CHECK(ret, FAIL, "H5Sclose"); dset_id = H5Dopen2(grp1_id, string, H5P_DEFAULT); CHECK(ret, FAIL, "H5Dopen2"); ret = H5Dclose(dset_id); CHECK(ret, FAIL, "H5Dclose"); ret = H5Gclose(grp1_id); CHECK(ret, FAIL, "H5Gclose"); /* Do the same for a named datatype */ grp2_id = H5Gcreate2(fid, GROUP2_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(grp2_id, FAIL, "H5Gcreate2"); type_id = H5Tcreate(H5T_OPAQUE, (size_t)1); CHECK(type_id, FAIL, "H5Tcreate"); ret = H5Tcommit2(grp2_id, string, type_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(type_id, FAIL, "H5Tcommit2"); ret = H5Tclose(type_id); CHECK(type_id, FAIL, "H5Tclose"); type_id = H5Topen2(grp2_id, string, H5P_DEFAULT); CHECK(type_id, FAIL, "H5Topen2"); ret = H5Tclose(type_id); CHECK(type_id, FAIL, "H5Tclose"); /* Don't close the group -- use it to test that object references * can refer to objects named in UTF-8 */ space_id = H5Screate_simple(RANK, &dims, NULL); CHECK(space_id, FAIL, "H5Screate_simple"); dset_id = H5Dcreate2(grp2_id, DSET3_NAME, H5T_STD_REF_OBJ, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Dcreate2"); /* Create reference to named datatype */ ret = H5Rcreate(&obj_ref, grp2_id, string, H5R_OBJECT, -1); CHECK(ret, FAIL, "H5Rcreate"); /* Write selection and read it back*/ ret = H5Dwrite(dset_id, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &obj_ref); CHECK(ret, FAIL, "H5Dwrite"); ret = H5Dread(dset_id, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &obj_ref); CHECK(ret, FAIL, "H5Dread"); /* Ensure that we can open named datatype using object reference */ type_id = H5Rdereference2(dset_id, H5P_DEFAULT, H5R_OBJECT, &obj_ref); CHECK(type_id, FAIL, "H5Rdereference2"); ret = H5Tcommitted(type_id); VERIFY(ret, 1, "H5Tcommitted"); ret = H5Tclose(type_id); CHECK(type_id, FAIL, "H5Tclose"); ret = H5Dclose(dset_id); CHECK(ret, FAIL, "H5Dclose"); ret = H5Sclose(space_id); CHECK(ret, FAIL, "H5Sclose"); ret = H5Gclose(grp2_id); CHECK(ret, FAIL, "H5Gclose"); /* Create "group3". Build a hard link from group3 to group2, which has * a datatype with the UTF-8 name. Create a soft link in group3 * pointing through the hard link to the datatype. Give the soft * link a name in UTF-8. Ensure that the soft link works. */ grp3_id = H5Gcreate2(fid, GROUP3_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(grp3_id, FAIL, "H5Gcreate2"); ret = H5Lcreate_hard(fid, GROUP2_NAME, grp3_id, GROUP2_NAME, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Lcreate_hard"); HDstrcpy(path_buf, GROUP2_NAME); HDstrcat(path_buf, "/"); HDstrcat(path_buf, string); ret = H5Lcreate_hard(grp3_id, path_buf, H5L_SAME_LOC, string, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Lcreate_hard"); /* Open named datatype using soft link */ type_id = H5Topen2(grp3_id, string, H5P_DEFAULT); CHECK(type_id, FAIL, "H5Topen2"); ret = H5Tclose(type_id); CHECK(type_id, FAIL, "H5Tclose"); ret = H5Gclose(grp3_id); CHECK(ret, FAIL, "H5Gclose"); }
/**************************************************************** ** ** test_grp_memb_funcs(): Test group member information ** functionality ** ****************************************************************/ static void test_grp_memb_funcs(hid_t fapl) { hid_t file; /* File ID */ hid_t dataset; /* Dataset ID */ hid_t datatype; /* Common datatype ID */ hid_t filespace; /* Common dataspace ID */ hid_t root_group,grp; /* Root group ID */ int i; /* counting variable */ char name[NAMELEN]; /* temporary name buffer */ char *dnames[NDATASETS+2];/* Names of the datasets created */ char *obj_names[NDATASETS+2];/* Names of the objects in group */ char dataset_name[NAMELEN]; /* dataset name */ ssize_t name_len; /* Length of object's name */ H5G_info_t ginfo; /* Buffer for querying object's info */ herr_t ret = SUCCEED; /* Generic return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing Group Member Information Functionality\n")); /* Create the test file with the datasets */ file = H5Fcreate(DATAFILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); CHECK(file, FAIL, "H5Fcreate"); datatype = H5Tcopy(H5T_NATIVE_INT); CHECK(datatype, FAIL, "H5Tcopy"); filespace = H5Screate(H5S_SCALAR); CHECK(filespace, FAIL, "H5Screate"); for(i = 0; i < NDATASETS; i++) { sprintf(name, "Dataset %d", i); dataset = H5Dcreate2(file, name, datatype, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(dataset, FAIL, "H5Dcreate2"); /* Keep a copy of the dataset names around for later */ dnames[i] = HDstrdup(name); CHECK(dnames[i], NULL, "strdup"); ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); } /* end for */ /* Create a group and named datatype under root group for testing */ grp = H5Gcreate2(file, "grp", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Gcreate2"); dnames[NDATASETS] = HDstrdup("grp"); CHECK(dnames[NDATASETS], NULL, "strdup"); ret = H5Tcommit2(file, "dtype", datatype, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Tcommit2"); dnames[NDATASETS + 1] = HDstrdup("dtype"); CHECK(dnames[NDATASETS], NULL, "strdup"); /* Close everything up */ ret = H5Tclose(datatype); CHECK(ret, FAIL, "H5Tclose"); ret = H5Gclose(grp); CHECK(ret, FAIL, "H5Gclose"); ret = H5Sclose(filespace); CHECK(ret, FAIL, "H5Sclose"); ret = H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); /* Sort the dataset names */ HDqsort(dnames, (size_t)(NDATASETS + 2), sizeof(char *), iter_strcmp); /* Iterate through the datasets in the root group in various ways */ file = H5Fopen(DATAFILE, H5F_ACC_RDONLY, fapl); CHECK(file, FAIL, "H5Fopen"); /* These two functions, H5Oget_info_by_idx and H5Lget_name_by_idx, actually * iterate through B-tree for group members in internal library design. */ root_group = H5Gopen2(file, "/", H5P_DEFAULT); CHECK(root_group, FAIL, "H5Gopen2"); ret = H5Gget_info(root_group, &ginfo); CHECK(ret, FAIL, "H5Gget_info"); VERIFY(ginfo.nlinks, (NDATASETS + 2), "H5Gget_info"); for(i = 0; i < (int)ginfo.nlinks; i++) { H5O_info_t oinfo; /* Object info */ /* Test with NULL for name, to query length */ name_len = H5Lget_name_by_idx(root_group, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, NULL, (size_t)NAMELEN, H5P_DEFAULT); CHECK(name_len, FAIL, "H5Lget_name_by_idx"); ret = (herr_t)H5Lget_name_by_idx(root_group, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, dataset_name, (size_t)(name_len + 1), H5P_DEFAULT); CHECK(ret, FAIL, "H5Lget_name_by_idx"); /* Double-check that the length is the same */ VERIFY(ret, name_len, "H5Lget_name_by_idx"); /* Keep a copy of the dataset names around for later */ obj_names[i] = HDstrdup(dataset_name); CHECK(obj_names[i], NULL, "strdup"); ret = H5Oget_info_by_idx(root_group, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, &oinfo, H5P_DEFAULT); CHECK(ret, FAIL, "H5Oget_info_by_idx"); if(!HDstrcmp(dataset_name, "grp")) VERIFY(oinfo.type, H5O_TYPE_GROUP, "H5Lget_name_by_idx"); if(!HDstrcmp(dataset_name, "dtype")) VERIFY(oinfo.type, H5O_TYPE_NAMED_DATATYPE, "H5Lget_name_by_idx"); if(!HDstrncmp(dataset_name, "Dataset", (size_t)7)) VERIFY(oinfo.type, H5O_TYPE_DATASET, "H5Lget_name_by_idx"); } /* end for */ H5E_BEGIN_TRY { ret = (herr_t)H5Lget_name_by_idx(root_group, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)(NDATASETS+3), dataset_name, (size_t)NAMELEN, H5P_DEFAULT); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Lget_name_by_idx"); /* Sort the dataset names */ HDqsort(obj_names, (size_t)(NDATASETS + 2), sizeof(char *), iter_strcmp); /* Compare object names */ for(i = 0; i< (int)ginfo.nlinks; i++) { ret = HDstrcmp(dnames[i], obj_names[i]); VERIFY(ret, 0, "HDstrcmp"); } /* end for */ ret = H5Gclose(root_group); CHECK(ret, FAIL, "H5Gclose"); ret = H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); /* Free the dataset names */ for(i = 0; i< (NDATASETS + 2); i++) { HDfree(dnames[i]); HDfree(obj_names[i]); } /* end for */ } /* test_grp_memb_funcs() */
/**************************************************************** ** ** test_iter_group_large(): Test group iteration functionality ** for groups with large #'s of objects ** ****************************************************************/ static void test_iter_group_large(hid_t fapl) { hid_t file; /* HDF5 File IDs */ hid_t dataset; /* Dataset ID */ hid_t group; /* Group ID */ hid_t sid; /* Dataspace ID */ hid_t tid; /* Datatype ID */ hsize_t dims[] = {SPACE1_DIM1}; herr_t ret; /* Generic return value */ char gname[20]; /* Temporary group name */ iter_info names[ITER_NGROUPS+2]; /* Names of objects in the root group */ iter_info *curr_name; /* Pointer to the current name in the root group */ int i; /* Compound datatype */ typedef struct s1_t { unsigned int a; unsigned int b; float c; } s1_t; HDmemset(names, 0, sizeof names); /* Output message about test being performed */ MESSAGE(5, ("Testing Large Group Iteration Functionality\n")); /* Create file */ file = H5Fcreate(DATAFILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); CHECK(file, FAIL, "H5Fcreate"); /* Create dataspace for datasets */ sid = H5Screate_simple(SPACE1_RANK, dims, NULL); CHECK(sid, FAIL, "H5Screate_simple"); /* Create a bunch of groups */ for(i = 0; i < ITER_NGROUPS; i++) { sprintf(gname, "Group_%d", i); /* Add the name to the list of objects in the root group */ HDstrcpy(names[i].name, gname); names[i].type = H5O_TYPE_GROUP; /* Create a group */ group = H5Gcreate2(file, gname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(group, FAIL, "H5Gcreate2"); /* Close a group */ ret = H5Gclose(group); CHECK(ret, FAIL, "H5Gclose"); } /* end for */ /* Create a dataset */ dataset = H5Dcreate2(file, "Dataset1", H5T_STD_U32LE, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(dataset, FAIL, "H5Dcreate2"); /* Add the name to the list of objects in the root group */ HDstrcpy(names[ITER_NGROUPS].name, "Dataset1"); names[ITER_NGROUPS].type = H5O_TYPE_DATASET; /* Close Dataset */ ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); /* Close Dataspace */ ret = H5Sclose(sid); CHECK(ret, FAIL, "H5Sclose"); /* Create a datatype */ tid = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); CHECK(tid, FAIL, "H5Tcreate"); /* Insert fields */ ret = H5Tinsert(tid, "a", HOFFSET(s1_t, a), H5T_NATIVE_INT); CHECK(ret, FAIL, "H5Tinsert"); ret = H5Tinsert(tid, "b", HOFFSET(s1_t, b), H5T_NATIVE_INT); CHECK(ret, FAIL, "H5Tinsert"); ret = H5Tinsert(tid, "c", HOFFSET(s1_t, c), H5T_NATIVE_FLOAT); CHECK(ret, FAIL, "H5Tinsert"); /* Save datatype for later */ ret = H5Tcommit2(file, "Datatype1", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Tcommit2"); /* Add the name to the list of objects in the root group */ HDstrcpy(names[ITER_NGROUPS + 1].name, "Datatype1"); names[ITER_NGROUPS + 1].type = H5O_TYPE_NAMED_DATATYPE; /* Close datatype */ ret = H5Tclose(tid); CHECK(ret, FAIL, "H5Tclose"); /* Need to sort the names in the root group, cause that's what the library does */ HDqsort(names, (size_t)(ITER_NGROUPS + 2), sizeof(iter_info), iter_strcmp2); /* Iterate through the file to see members of the root group */ curr_name = &names[0]; ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, NULL, liter_cb2, curr_name); CHECK(ret, FAIL, "H5Literate"); for(i = 1; i < 100; i++) { hsize_t idx = i; curr_name = &names[i]; ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb2, curr_name); CHECK(ret, FAIL, "H5Literate"); } /* end for */ /* Close file */ ret = H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); } /* test_iterate_group_large() */
/**************************************************************** ** ** test_iter_group(): Test group iteration functionality ** ****************************************************************/ static void test_iter_group(hid_t fapl, hbool_t new_format) { hid_t file; /* File ID */ hid_t dataset; /* Dataset ID */ hid_t datatype; /* Common datatype ID */ hid_t filespace; /* Common dataspace ID */ hid_t root_group,grp; /* Root group ID */ int i; /* counting variable */ hsize_t idx; /* Index in the group */ char name[NAMELEN]; /* temporary name buffer */ char *lnames[NDATASETS + 2];/* Names of the links created */ char dataset_name[NAMELEN]; /* dataset name */ iter_info info; /* Custom iteration information */ H5G_info_t ginfo; /* Buffer for querying object's info */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing Group Iteration Functionality\n")); /* Create the test file with the datasets */ file = H5Fcreate(DATAFILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); CHECK(file, FAIL, "H5Fcreate"); /* Test iterating over empty group */ info.command = RET_ZERO; idx = 0; ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info); VERIFY(ret, SUCCEED, "H5Literate"); datatype = H5Tcopy(H5T_NATIVE_INT); CHECK(datatype, FAIL, "H5Tcopy"); filespace=H5Screate(H5S_SCALAR); CHECK(filespace, FAIL, "H5Screate"); for(i=0; i< NDATASETS; i++) { sprintf(name,"Dataset %d",i); dataset = H5Dcreate2(file, name, datatype, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(dataset, FAIL, "H5Dcreate2"); /* Keep a copy of the dataset names around for later */ lnames[i] = HDstrdup(name); CHECK(lnames[i], NULL, "strdup"); ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); } /* end for */ /* Create a group and named datatype under root group for testing */ grp = H5Gcreate2(file, "grp", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Gcreate2"); lnames[NDATASETS] = HDstrdup("grp"); CHECK(lnames[NDATASETS], NULL, "strdup"); ret = H5Tcommit2(file, "dtype", datatype, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Tcommit2"); lnames[NDATASETS + 1] = HDstrdup("dtype"); CHECK(lnames[NDATASETS], NULL, "strdup"); /* Close everything up */ ret = H5Tclose(datatype); CHECK(ret, FAIL, "H5Tclose"); ret = H5Gclose(grp); CHECK(ret, FAIL, "H5Gclose"); ret = H5Sclose(filespace); CHECK(ret, FAIL, "H5Sclose"); ret = H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); /* Sort the dataset names */ HDqsort(lnames, (size_t)(NDATASETS + 2), sizeof(char *), iter_strcmp); /* Iterate through the datasets in the root group in various ways */ file = H5Fopen(DATAFILE, H5F_ACC_RDONLY, fapl); CHECK(file, FAIL, "H5Fopen"); /* These two functions, H5Oget_info_by_idx and H5Lget_name_by_idx, actually * iterate through B-tree for group members in internal library design. */ root_group = H5Gopen2(file, "/", H5P_DEFAULT); CHECK(root_group, FAIL, "H5Gopen2"); ret = H5Gget_info(root_group, &ginfo); CHECK(ret, FAIL, "H5Gget_info"); VERIFY(ginfo.nlinks, (NDATASETS + 2), "H5Gget_info"); for(i = 0; i< (int)ginfo.nlinks; i++) { H5O_info_t oinfo; /* Object info */ ret = (herr_t)H5Lget_name_by_idx(root_group, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, dataset_name, (size_t)NAMELEN, H5P_DEFAULT); CHECK(ret, FAIL, "H5Lget_name_by_idx"); ret = H5Oget_info_by_idx(root_group, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, &oinfo, H5P_DEFAULT); CHECK(ret, FAIL, "H5Oget_info_by_idx"); } /* end for */ H5E_BEGIN_TRY { ret = (herr_t)H5Lget_name_by_idx(root_group, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)(NDATASETS+3), dataset_name, (size_t)NAMELEN, H5P_DEFAULT); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Lget_name_by_idx"); ret = H5Gclose(root_group); CHECK(ret, FAIL, "H5Gclose"); /* These two functions, H5Oget_info_by_idx and H5Lget_name_by_idx, actually * iterate through B-tree for group members in internal library design. * (Same as test above, but with the file ID instead of opening the root group) */ ret = H5Gget_info(file, &ginfo); CHECK(ret, FAIL, "H5Gget_info"); VERIFY(ginfo.nlinks, NDATASETS + 2, "H5Gget_info"); for(i = 0; i< (int)ginfo.nlinks; i++) { H5O_info_t oinfo; /* Object info */ ret = (herr_t)H5Lget_name_by_idx(file, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, dataset_name, (size_t)NAMELEN, H5P_DEFAULT); CHECK(ret, FAIL, "H5Lget_name_by_idx"); ret = H5Oget_info_by_idx(file, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, &oinfo, H5P_DEFAULT); CHECK(ret, FAIL, "H5Oget_info_by_idx"); } /* end for */ H5E_BEGIN_TRY { ret = (herr_t)H5Lget_name_by_idx(file, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)(NDATASETS + 3), dataset_name, (size_t)NAMELEN, H5P_DEFAULT); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Lget_name_by_idx"); /* Test invalid indices for starting iteration */ info.command = RET_ZERO; idx = (hsize_t)-1; H5E_BEGIN_TRY { ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Literate"); /* Test skipping exactly as many entries as in the group */ idx = NDATASETS + 2; H5E_BEGIN_TRY { ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Literate"); /* Test skipping more entries than are in the group */ idx = NDATASETS + 3; H5E_BEGIN_TRY { ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Literate"); /* Test all objects in group, when callback always returns 0 */ info.command = RET_ZERO; idx = 0; if((ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info)) > 0) TestErrPrintf("Group iteration function didn't return zero correctly!\n"); /* Test all objects in group, when callback always returns 1 */ /* This also tests the "restarting" ability, because the index changes */ info.command = RET_TWO; idx = i = 0; while((ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info)) > 0) { /* Verify return value from iterator gets propagated correctly */ VERIFY(ret, 2, "H5Literate"); /* Increment the number of times "2" is returned */ i++; /* Verify that the index is the correct value */ VERIFY(idx, (hsize_t)i, "H5Literate"); if(idx > (NDATASETS + 2)) TestErrPrintf("Group iteration function walked too far!\n"); /* Verify that the correct name is retrieved */ if(HDstrcmp(info.name, lnames[(size_t)(idx - 1)]) != 0) TestErrPrintf("Group iteration function didn't return name correctly for link - lnames[%u] = '%s'!\n", (unsigned)(idx - 1), lnames[(size_t)(idx - 1)]); } /* end while */ VERIFY(ret, -1, "H5Literate"); if(i != (NDATASETS + 2)) TestErrPrintf("%u: Group iteration function didn't perform multiple iterations correctly!\n", __LINE__); /* Test all objects in group, when callback changes return value */ /* This also tests the "restarting" ability, because the index changes */ info.command = new_format ? RET_CHANGE2 : RET_CHANGE; idx = i = 0; while((ret = H5Literate(file, H5_INDEX_NAME, H5_ITER_INC, &idx, liter_cb, &info)) >= 0) { /* Verify return value from iterator gets propagated correctly */ VERIFY(ret, 1, "H5Literate"); /* Increment the number of times "1" is returned */ i++; /* Verify that the index is the correct value */ VERIFY(idx, (hsize_t)(i + 10), "H5Literate"); if(idx > (NDATASETS + 2)) TestErrPrintf("Group iteration function walked too far!\n"); /* Verify that the correct name is retrieved */ if(HDstrcmp(info.name, lnames[(size_t)(idx - 1)]) != 0) TestErrPrintf("Group iteration function didn't return name correctly for link - lnames[%u] = '%s'!\n", (unsigned)(idx - 1), lnames[(size_t)(idx - 1)]); } /* end while */ VERIFY(ret, -1, "H5Literate"); if(i != 42 || idx != 52) TestErrPrintf("%u: Group iteration function didn't perform multiple iterations correctly!\n", __LINE__); ret = H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); /* Free the dataset names */ for(i = 0; i< (NDATASETS + 2); i++) HDfree(lnames[i]); } /* test_iter_group() */
/**************************************************************** ** ** test_vlstring_type(): Test VL string type. ** Tests if VL string is treated as string. ** ****************************************************************/ static void test_vlstring_type(void) { hid_t fid; /* HDF5 File IDs */ hid_t tid_vlstr; H5T_cset_t cset; H5T_str_t pad; htri_t vl_str; /* Whether string is VL */ herr_t ret; /* Output message about test being performed */ MESSAGE(5, ("Testing VL String type\n")); /* Open file */ fid = H5Fopen(DATAFILE, H5F_ACC_RDWR, H5P_DEFAULT); CHECK(fid, FAIL, "H5Fopen"); /* Create a datatype to refer to */ tid_vlstr = H5Tcopy(H5T_C_S1); CHECK(tid_vlstr, FAIL, "H5Tcopy"); /* Change padding and verify it */ ret = H5Tset_strpad(tid_vlstr, H5T_STR_NULLPAD); CHECK(ret, FAIL, "H5Tset_strpad"); pad = H5Tget_strpad(tid_vlstr); VERIFY(pad, H5T_STR_NULLPAD, "H5Tget_strpad"); /* Convert to variable-length string */ ret = H5Tset_size(tid_vlstr, H5T_VARIABLE); CHECK(ret, FAIL, "H5Tset_size"); /* Check if datatype is VL string */ ret = H5Tget_class(tid_vlstr); VERIFY(ret, H5T_STRING, "H5Tget_class"); ret = H5Tis_variable_str(tid_vlstr); VERIFY(ret, TRUE, "H5Tis_variable_str"); /* Verify that the class detects as a string */ vl_str = H5Tdetect_class(tid_vlstr, H5T_STRING); CHECK(vl_str, FAIL, "H5Tdetect_class"); VERIFY(vl_str, TRUE, "H5Tdetect_class"); /* Check default character set and padding */ cset = H5Tget_cset(tid_vlstr); VERIFY(cset, H5T_CSET_ASCII, "H5Tget_cset"); pad = H5Tget_strpad(tid_vlstr); VERIFY(pad, H5T_STR_NULLPAD, "H5Tget_strpad"); /* Commit variable-length string datatype to storage */ ret = H5Tcommit2(fid, VLSTR_TYPE, tid_vlstr, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Tcommit2"); /* Close datatype */ ret = H5Tclose(tid_vlstr); CHECK(ret, FAIL, "H5Tclose"); tid_vlstr = H5Topen2(fid, VLSTR_TYPE, H5P_DEFAULT); CHECK(tid_vlstr, FAIL, "H5Topen2"); ret = H5Tclose(tid_vlstr); CHECK(ret, FAIL, "H5Tclose"); ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); fid = H5Fopen(DATAFILE, H5F_ACC_RDWR, H5P_DEFAULT); CHECK(fid, FAIL, "H5Fopen"); /* Open the variable-length string datatype just created */ tid_vlstr = H5Topen2(fid, VLSTR_TYPE, H5P_DEFAULT); CHECK(tid_vlstr, FAIL, "H5Topen2"); /* Verify character set and padding */ cset = H5Tget_cset(tid_vlstr); VERIFY(cset, H5T_CSET_ASCII, "H5Tget_cset"); pad = H5Tget_strpad(tid_vlstr); VERIFY(pad, H5T_STR_NULLPAD, "H5Tget_strpad"); /* Close datatype and file */ ret = H5Tclose(tid_vlstr); CHECK(ret, FAIL, "H5Tclose"); ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); } /* end test_vlstring_type() */