diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/Makefile.am | 2 | ||||
-rw-r--r-- | test/Makefile.in | 54 | ||||
-rw-r--r-- | test/big.c | 39 | ||||
-rw-r--r-- | test/btree2.c | 82 | ||||
-rw-r--r-- | test/cache.c | 6 | ||||
-rw-r--r-- | test/cache_common.c | 2 | ||||
-rw-r--r-- | test/dsets.c | 8 | ||||
-rw-r--r-- | test/freespace.c | 2805 | ||||
-rw-r--r-- | test/getname.c | 2 | ||||
-rw-r--r-- | test/links.c | 21 | ||||
-rw-r--r-- | test/mf.c | 5386 | ||||
-rwxr-xr-x | test/objcopy.c | 4 | ||||
-rw-r--r-- | test/tfile.c | 22 | ||||
-rw-r--r-- | test/trefer.c | 6 | ||||
-rw-r--r-- | test/tselect.c | 46 | ||||
-rw-r--r-- | test/tskiplist.c | 162 | ||||
-rw-r--r-- | test/vfd.c | 7 |
17 files changed, 8518 insertions, 136 deletions
diff --git a/test/Makefile.am b/test/Makefile.am index d6b6d62..30262a2 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -42,7 +42,7 @@ TEST_PROG=testhdf5 lheap ohdr stab gheap cache cache_api \ fillval mount flush1 flush2 app_ref enum \ set_extent ttsafe \ getname vfd ntypes dangle dtransform reserved cross_read \ - btree2 fheap earray + freespace mf earray btree2 fheap # List programs to be built when testing here. error_test and err_compat are # built at the same time as the other tests, but executed by testerror.sh. diff --git a/test/Makefile.in b/test/Makefile.in index 7503172..930cf54 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -80,8 +80,8 @@ am__EXEEXT_1 = testhdf5$(EXEEXT) lheap$(EXEEXT) ohdr$(EXEEXT) \ app_ref$(EXEEXT) enum$(EXEEXT) set_extent$(EXEEXT) \ ttsafe$(EXEEXT) getname$(EXEEXT) vfd$(EXEEXT) ntypes$(EXEEXT) \ dangle$(EXEEXT) dtransform$(EXEEXT) reserved$(EXEEXT) \ - cross_read$(EXEEXT) btree2$(EXEEXT) fheap$(EXEEXT) \ - earray$(EXEEXT) + cross_read$(EXEEXT) freespace$(EXEEXT) mf$(EXEEXT) \ + earray$(EXEEXT) btree2$(EXEEXT) fheap$(EXEEXT) am__EXEEXT_2 = gen_bad_ohdr$(EXEEXT) gen_bogus$(EXEEXT) \ gen_cross$(EXEEXT) gen_deflate$(EXEEXT) gen_filters$(EXEEXT) \ gen_new_array$(EXEEXT) gen_new_fill$(EXEEXT) \ @@ -182,6 +182,10 @@ flush2_SOURCES = flush2.c flush2_OBJECTS = flush2.$(OBJEXT) flush2_LDADD = $(LDADD) flush2_DEPENDENCIES = libh5test.la $(LIBHDF5) +freespace_SOURCES = freespace.c +freespace_OBJECTS = freespace.$(OBJEXT) +freespace_LDADD = $(LDADD) +freespace_DEPENDENCIES = libh5test.la $(LIBHDF5) gen_bad_ohdr_SOURCES = gen_bad_ohdr.c gen_bad_ohdr_OBJECTS = gen_bad_ohdr.$(OBJEXT) gen_bad_ohdr_LDADD = $(LDADD) @@ -258,6 +262,10 @@ links_SOURCES = links.c links_OBJECTS = links.$(OBJEXT) links_LDADD = $(LDADD) links_DEPENDENCIES = libh5test.la $(LIBHDF5) +mf_SOURCES = mf.c +mf_OBJECTS = mf.$(OBJEXT) +mf_LDADD = $(LDADD) +mf_DEPENDENCIES = libh5test.la $(LIBHDF5) mount_SOURCES = mount.c mount_OBJECTS = mount.$(OBJEXT) mount_LDADD = $(LDADD) @@ -344,26 +352,26 @@ SOURCES = $(libh5test_la_SOURCES) app_ref.c big.c bittests.c btree2.c \ cache.c cache_api.c cmpd_dset.c cross_read.c dangle.c dsets.c \ dt_arith.c dtransform.c dtypes.c earray.c enum.c err_compat.c \ error_test.c extend.c external.c fheap.c fillval.c flush1.c \ - flush2.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 mount.c mtime.c ntypes.c objcopy.c \ - ohdr.c pool.c reserved.c set_extent.c space_overflow.c stab.c \ - $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c \ - vfd.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 $(testhdf5_SOURCES) \ + testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c DIST_SOURCES = $(libh5test_la_SOURCES) app_ref.c big.c bittests.c \ btree2.c cache.c cache_api.c cmpd_dset.c cross_read.c dangle.c \ dsets.c dt_arith.c dtransform.c dtypes.c earray.c enum.c \ err_compat.c error_test.c extend.c external.c fheap.c \ - fillval.c flush1.c flush2.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 mount.c mtime.c \ - ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c \ - space_overflow.c stab.c $(testhdf5_SOURCES) testmeta.c \ - $(ttsafe_SOURCES) unlink.c vfd.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 $(testhdf5_SOURCES) \ + testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -659,7 +667,7 @@ TEST_PROG = testhdf5 lheap ohdr stab gheap cache cache_api \ fillval mount flush1 flush2 app_ref enum \ set_extent ttsafe \ getname vfd ntypes dangle dtransform reserved cross_read \ - btree2 fheap earray + freespace mf earray btree2 fheap # These programs generate test files for the tests. They don't need to be @@ -842,6 +850,9 @@ flush1$(EXEEXT): $(flush1_OBJECTS) $(flush1_DEPENDENCIES) flush2$(EXEEXT): $(flush2_OBJECTS) $(flush2_DEPENDENCIES) @rm -f flush2$(EXEEXT) $(LINK) $(flush2_OBJECTS) $(flush2_LDADD) $(LIBS) +freespace$(EXEEXT): $(freespace_OBJECTS) $(freespace_DEPENDENCIES) + @rm -f freespace$(EXEEXT) + $(LINK) $(freespace_OBJECTS) $(freespace_LDADD) $(LIBS) gen_bad_ohdr$(EXEEXT): $(gen_bad_ohdr_OBJECTS) $(gen_bad_ohdr_DEPENDENCIES) @rm -f gen_bad_ohdr$(EXEEXT) $(LINK) $(gen_bad_ohdr_OBJECTS) $(gen_bad_ohdr_LDADD) $(LIBS) @@ -899,6 +910,9 @@ lheap$(EXEEXT): $(lheap_OBJECTS) $(lheap_DEPENDENCIES) links$(EXEEXT): $(links_OBJECTS) $(links_DEPENDENCIES) @rm -f links$(EXEEXT) $(LINK) $(links_OBJECTS) $(links_LDADD) $(LIBS) +mf$(EXEEXT): $(mf_OBJECTS) $(mf_DEPENDENCIES) + @rm -f mf$(EXEEXT) + $(LINK) $(mf_OBJECTS) $(mf_LDADD) $(LIBS) mount$(EXEEXT): $(mount_OBJECTS) $(mount_DEPENDENCIES) @rm -f mount$(EXEEXT) $(LINK) $(mount_OBJECTS) $(mount_LDADD) $(LIBS) @@ -975,6 +989,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fillval.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flush1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flush2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/freespace.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_bad_ohdr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_bogus.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_cross.Po@am__quote@ @@ -995,6 +1010,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/istore.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lheap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/links.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mount.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mtime.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntypes.Po@am__quote@ @@ -80,8 +80,8 @@ randll(hsize_t limit, int current_index) /* does not overlap with any previous writes */ while(overlap != 0 && tries < MAX_TRIES) { - acc = rand (); - acc *= rand (); + acc = HDrandom(); + acc *= HDrandom(); acc = acc % limit; overlap = 0; @@ -294,11 +294,6 @@ writer (char* filename, hid_t fapl, int wrt_n) * or it will take some time to write a file. * We should create a dataset allocating space late and never writing fill values. * EIP 4/8/03 - - if((d1 = H5Dcreate2(file, "d1", H5T_NATIVE_INT, space1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0 || - (d2 = H5Dcreate2(file, "d2", H5T_NATIVE_INT, space2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { - goto error; - } */ dcpl = H5Pcreate(H5P_DATASET_CREATE); H5Pset_alloc_time(dcpl, H5D_ALLOC_TIME_LATE); @@ -381,14 +376,14 @@ reader(char *filename, hid_t fapl) script = fopen(DNAME, "r"); /* Open HDF5 file */ - if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) goto error; + if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR /* Open the dataset */ - if((d2 = H5Dopen2(file, "d2", H5P_DEFAULT)) < 0) goto error; - if((fspace = H5Dget_space(d2)) < 0) goto error; + if((d2 = H5Dopen2(file, "d2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if((fspace = H5Dget_space(d2)) < 0) FAIL_STACK_ERROR /* Describe `buf' */ - if((mspace = H5Screate_simple(1, hs_size, hs_size)) < 0) goto error; + if((mspace = H5Screate_simple(1, hs_size, hs_size)) < 0) FAIL_STACK_ERROR /* Read each region */ while(fgets(ln, (int)sizeof(ln), script)) { @@ -400,9 +395,9 @@ reader(char *filename, hid_t fapl) fflush(stdout); if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL, - hs_size, NULL) < 0) goto error; + hs_size, NULL) < 0) FAIL_STACK_ERROR if(H5Dread(d2, H5T_NATIVE_INT, mspace, fspace, H5P_DEFAULT, buf) < 0) - goto error; + FAIL_STACK_ERROR /* Check */ for(j = zero = wrong = 0; j < WRT_SIZE; j++) { @@ -423,10 +418,10 @@ reader(char *filename, hid_t fapl) } } - if(H5Dclose(d2) < 0) goto error; - if(H5Sclose(mspace) < 0) goto error; - if(H5Sclose(fspace) < 0) goto error; - if(H5Fclose(file) < 0) goto error; + if(H5Dclose(d2) < 0) FAIL_STACK_ERROR + if(H5Sclose(mspace) < 0) FAIL_STACK_ERROR + if(H5Sclose(fspace) < 0) FAIL_STACK_ERROR + if(H5Fclose(file) < 0) FAIL_STACK_ERROR free(buf); fclose(script); @@ -511,6 +506,7 @@ main (int ac, char **av) hsize_t family_size; hsize_t family_size_def; /* default family file size */ double family_size_def_dbl; /* default family file size */ + unsigned long seed = 0; /* Random # seed */ int cflag=1; /* check file system before test */ char filename[1024]; @@ -547,6 +543,14 @@ main (int ac, char **av) } } + /* Choose random # seed */ + seed = (unsigned long)HDtime(NULL); +#ifdef QAK +/* seed = (unsigned long)1155438845; */ +HDfprintf(stderr, "Random # seed was: %lu\n", seed); +#endif /* QAK */ + HDsrandom(seed); + /* Reset library */ h5_reset(); fapl = h5_fileaccess(); @@ -657,3 +661,4 @@ error: puts("*** TEST FAILED ***"); return 1; } + diff --git a/test/btree2.c b/test/btree2.c index d4347d4..a25a373 100644 --- a/test/btree2.c +++ b/test/btree2.c @@ -76,9 +76,9 @@ iter_cb(const void *_record, void *_op_data) * * Purpose: v2 B-tree find callback * - * Return: Success: 0 + * Return: Success: TRUE/FALSE * - * Failure: 1 + * Failure: FAIL * * Programmer: Quincey Koziol * Thursday, February 24, 2005 @@ -92,9 +92,9 @@ find_cb(const void *_record, void *_op_data) hsize_t *search = (hsize_t *)_op_data; if(*record != *search) - return(-1); + return(FALSE); - return(0); + return(TRUE); } /* end find_cb() */ @@ -261,11 +261,7 @@ test_insert_basic(hid_t fapl) /* Attempt to find record in B-tree with no records */ idx = 0; - H5E_BEGIN_TRY { - ret = H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, NULL); - } H5E_END_TRY; - /* Should fail */ - if(ret != FAIL) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, NULL) != FALSE) TEST_ERROR /* Attempt to index record in B-tree with no records */ @@ -286,29 +282,23 @@ test_insert_basic(hid_t fapl) FAIL_STACK_ERROR /* Attempt to find non-existant record in B-tree with 1 record */ + /* (Should not be found, but not fail) */ idx = 41; - H5E_BEGIN_TRY { - ret = H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx); - } H5E_END_TRY; - /* Should fail */ - if(ret != FAIL) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) != FALSE) TEST_ERROR /* Try again with NULL 'op' */ - H5E_BEGIN_TRY { - ret = H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, NULL, NULL); - } H5E_END_TRY; - /* Should fail */ - if(ret != FAIL) + /* (Should not be found, but not fail) */ + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, NULL, NULL) != FALSE) TEST_ERROR /* Attempt to find existant record in B-tree with 1 record */ idx = 42; - if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx)<0) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) != TRUE) TEST_ERROR /* Try again with NULL 'op' */ - if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, NULL, NULL)<0) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, NULL, NULL) != TRUE) TEST_ERROR /* Attempt to index non-existant record in B-tree with 1 record */ @@ -347,17 +337,14 @@ test_insert_basic(hid_t fapl) FAIL_STACK_ERROR /* Attempt to find non-existant record in level-0 B-tree with several records */ + /* (Should not be found, but not fail) */ idx = 41; - H5E_BEGIN_TRY { - ret = H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx); - } H5E_END_TRY; - /* Should fail */ - if(ret != FAIL) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) != FALSE) TEST_ERROR /* Attempt to find existant record in level-0 B-tree with several record */ idx = 56; - if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx)<0) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) != TRUE) TEST_ERROR /* Attempt to index non-existant record in B-tree with several records */ @@ -521,22 +508,19 @@ test_insert_split_root(hid_t fapl) TEST_ERROR /* Attempt to find non-existant record in level-1 B-tree */ + /* (Should not be found, but not fail) */ idx = INSERT_SPLIT_ROOT_NREC + 10; - H5E_BEGIN_TRY { - ret = H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx); - } H5E_END_TRY; - /* Should fail */ - if(ret != FAIL) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) != FALSE) TEST_ERROR /* Attempt to find existant record in root of level-1 B-tree */ idx = 33; - if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) < 0) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) != TRUE) FAIL_STACK_ERROR /* Attempt to find existant record in leaf of level-1 B-tree */ idx = 56; - if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) < 0) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) != TRUE) FAIL_STACK_ERROR /* Attempt to index non-existant record in level-1 B-tree */ @@ -1286,17 +1270,14 @@ test_insert_make_level2(hid_t fapl) TEST_ERROR /* Attempt to find non-existant record in level-2 B-tree */ + /* (Should not be found, but not fail) */ idx = INSERT_SPLIT_ROOT_NREC * 30; - H5E_BEGIN_TRY { - ret = H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx); - } H5E_END_TRY; - /* Should fail */ - if(ret != FAIL) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) != FALSE) TEST_ERROR /* Attempt to find existant record in root of level-2 B-tree */ idx = 948; - if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) < 0) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) != TRUE) FAIL_STACK_ERROR /* Check with B-tree */ @@ -1308,7 +1289,7 @@ test_insert_make_level2(hid_t fapl) /* Attempt to find existant record in internal node of level-2 B-tree */ idx = 505; - if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) < 0) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) != TRUE) FAIL_STACK_ERROR /* Check with B-tree */ @@ -1320,7 +1301,7 @@ test_insert_make_level2(hid_t fapl) /* Attempt to find existant record in leaf of level-2 B-tree */ idx = 555; - if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) < 0) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) != TRUE) FAIL_STACK_ERROR /* Check with B-tree */ @@ -2838,12 +2819,9 @@ HDfprintf(stderr,"curr_time=%lu\n",(unsigned long)curr_time); TEST_ERROR /* Attempt to find non-existant record in level-4 B-tree */ - idx = INSERT_MANY*2; - H5E_BEGIN_TRY { - ret = H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx); - } H5E_END_TRY; - /* Should fail */ - if(ret != FAIL) + /* (Should not be found, but not fail) */ + idx = INSERT_MANY * 2; + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) != FALSE) TEST_ERROR /* Find random records */ @@ -2852,7 +2830,7 @@ HDfprintf(stderr,"curr_time=%lu\n",(unsigned long)curr_time); idx = (hsize_t)(HDrandom()%INSERT_MANY); /* Attempt to find existant record in root of level-4 B-tree */ - if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) < 0) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &idx, find_cb, &idx) != TRUE) FAIL_STACK_ERROR } /* end for */ @@ -7310,7 +7288,7 @@ test_modify(hid_t fapl) /* Attempt to find modified record */ record = 4331; found = 4331; - if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &record, find_cb, &found) < 0) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &record, find_cb, &found) != TRUE) FAIL_STACK_ERROR if(found != 4331) TEST_ERROR @@ -7354,7 +7332,7 @@ test_modify(hid_t fapl) /* Attempt to find modified record */ record = 5352; found = 5352; - if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &record, find_cb, &found) < 0) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &record, find_cb, &found) != TRUE) STACK_ERROR if(found != 5352) TEST_ERROR @@ -7398,7 +7376,7 @@ test_modify(hid_t fapl) /* Attempt to find modified record */ record = 9448; found = 9448; - if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &record, find_cb, &found) < 0) + if(H5B2_find(f, H5P_DATASET_XFER_DEFAULT, H5B2_TEST, bt2_addr, &record, find_cb, &found) != TRUE) STACK_ERROR if(found != 9448) TEST_ERROR diff --git a/test/cache.c b/test/cache.c index 7de613e..bc89102 100644 --- a/test/cache.c +++ b/test/cache.c @@ -16778,7 +16778,7 @@ check_expunge_entry_errs(void) if ( pass ) { result = H5C_expunge_entry(NULL, -1, -1, cache_ptr, - &(types[0]), entry_ptr->addr); + &(types[0]), entry_ptr->addr, H5AC__NO_FLAGS_SET); if ( result > 0 ) { @@ -16796,7 +16796,7 @@ check_expunge_entry_errs(void) if ( pass ) { result = H5C_expunge_entry(NULL, -1, -1, cache_ptr, - &(types[0]), entry_ptr->addr); + &(types[0]), entry_ptr->addr, H5AC__NO_FLAGS_SET); if ( result > 0 ) { @@ -16814,7 +16814,7 @@ check_expunge_entry_errs(void) if ( pass ) { result = H5C_expunge_entry(NULL, -1, -1, cache_ptr, - &(types[0]), entry_ptr->addr); + &(types[0]), entry_ptr->addr, H5AC__NO_FLAGS_SET); if ( result < 0 ) { diff --git a/test/cache_common.c b/test/cache_common.c index 5eb91dc..c2ce274 100644 --- a/test/cache_common.c +++ b/test/cache_common.c @@ -2302,7 +2302,7 @@ expunge_entry(H5C_t * cache_ptr, HDassert( ! ( entry_ptr->is_pinned ) ); result = H5C_expunge_entry(NULL, -1, -1, cache_ptr, &(types[type]), - entry_ptr->addr); + entry_ptr->addr, H5AC__NO_FLAGS_SET); if ( result < 0 ) { diff --git a/test/dsets.c b/test/dsets.c index b22ec27..1121f76 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -6044,7 +6044,7 @@ test_random_chunks(hid_t fapl) if((m = H5Screate_simple(1, msize, NULL)) < 0) TEST_ERROR; /* Select the random points for writing */ - if(H5Sselect_elements(s, H5S_SELECT_SET, NPOINTS, coord) < 0) TEST_ERROR; + if(H5Sselect_elements(s, H5S_SELECT_SET, NPOINTS, (const hsize_t *)coord) < 0) TEST_ERROR; /* Write into dataset */ if(H5Dwrite(d, H5T_NATIVE_INT, m, s, H5P_DEFAULT, wbuf) < 0) TEST_ERROR; @@ -6069,7 +6069,7 @@ test_random_chunks(hid_t fapl) if((m = H5Screate_simple(1, msize, NULL)) < 0) TEST_ERROR; /* Select the random points for reading */ - if(H5Sselect_elements (s, H5S_SELECT_SET, NPOINTS, coord) < 0) TEST_ERROR; + if(H5Sselect_elements (s, H5S_SELECT_SET, NPOINTS, (const hsize_t *)coord) < 0) TEST_ERROR; /* Read from dataset */ if(H5Dread(d, H5T_NATIVE_INT, m, s, H5P_DEFAULT, rbuf) < 0) TEST_ERROR; @@ -6134,7 +6134,7 @@ test_random_chunks(hid_t fapl) if((m = H5Screate_simple(1, msize, NULL)) < 0) TEST_ERROR; /* Select the random points for writing */ - if(H5Sselect_elements(s, H5S_SELECT_SET, NPOINTS, coord) < 0) TEST_ERROR; + if(H5Sselect_elements(s, H5S_SELECT_SET, NPOINTS, (const hsize_t *)coord) < 0) TEST_ERROR; /* Write into dataset */ if(H5Dwrite(d, H5T_NATIVE_INT, m, s, H5P_DEFAULT, wbuf) < 0) TEST_ERROR; @@ -6159,7 +6159,7 @@ test_random_chunks(hid_t fapl) if((m = H5Screate_simple(1, msize, NULL)) < 0) TEST_ERROR; /* Select the random points for reading */ - if(H5Sselect_elements (s, H5S_SELECT_SET, NPOINTS, coord) < 0) TEST_ERROR; + if(H5Sselect_elements (s, H5S_SELECT_SET, NPOINTS, (const hsize_t *)coord) < 0) TEST_ERROR; /* Read from dataset */ if(H5Dread(d, H5T_NATIVE_INT, m, s, H5P_DEFAULT, rbuf) < 0) TEST_ERROR; diff --git a/test/freespace.c b/test/freespace.c new file mode 100644 index 0000000..c786ebb --- /dev/null +++ b/test/freespace.c @@ -0,0 +1,2805 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* + * Tests for free-space manager + */ +#include "h5test.h" + +#define H5FS_PACKAGE +#define H5FS_TESTING +#include "H5FSpkg.h" /* Free space manager */ + + +/* Other private headers that this test requires */ +#define H5F_PACKAGE +#include "H5Fpkg.h" +#include "H5FLprivate.h" +#include "H5Iprivate.h" +#include "H5Vprivate.h" + +#define FILENAME_LEN 1024 + +#define TEST_FSPACE_CLIENT_ID 2 +#define TEST_FSPACE_SECT_TYPE 0 +#define TEST_FSPACE_SECT_TYPE_NEW 1 +#define TEST_FSPACE_SECT_TYPE_NONE 2 + +#define TEST_FSPACE_SHRINK 80 +#define TEST_FSPACE_EXPAND 120 +#define TEST_MAX_SECT_SIZE (64 * 1024) +#define TEST_MAX_INDEX 32 + +#define TEST_SECT_ADDR60 60 +#define TEST_SECT_ADDR70 70 +#define TEST_SECT_ADDR80 80 +#define TEST_SECT_ADDR100 100 +#define TEST_SECT_ADDR150 150 +#define TEST_SECT_ADDR200 200 +#define TEST_SECT_ADDR300 300 + +#define TEST_SECT_SIZE5 5 +#define TEST_SECT_SIZE10 10 +#define TEST_SECT_SIZE15 15 +#define TEST_SECT_SIZE20 20 +#define TEST_SECT_SIZE30 30 +#define TEST_SECT_SIZE40 40 +#define TEST_SECT_SIZE50 50 +#define TEST_SECT_SIZE80 80 + +#define FSPACE_THRHD_DEF 1 /* Default: no alignment threshold */ +#define FSPACE_ALIGN_DEF 1 /* Default: no alignment */ + +const char *FILENAME[] = { + "frspace", + NULL +}; + +typedef struct frspace_state_t { + hsize_t tot_space; /* Total amount of space tracked */ + hsize_t tot_sect_count; /* Total # of sections tracked */ + hsize_t serial_sect_count; /* # of serializable sections tracked */ + hsize_t ghost_sect_count; /* # of un-serializable sections tracked */ +} frspace_state_t; + +haddr_t g_eoa=0; +static haddr_t TEST_get_eoa(void); +static void TEST_set_eoa(haddr_t); + +/* + * TEST client + */ +typedef struct TEST_free_section_t { + H5FS_section_info_t sect_info; /* Free space section information (must be first in struct) */ +} TEST_free_section_t; + +H5FL_DEFINE(TEST_free_section_t); + + +static herr_t TEST_sect_init_cls(H5FS_section_class_t *, void *); +static herr_t TEST_sect_free(H5FS_section_info_t *_sect); +static herr_t TEST_sect_can_merge(const H5FS_section_info_t *, const H5FS_section_info_t *, void UNUSED *); +static herr_t TEST_sect_merging(H5FS_section_info_t *, H5FS_section_info_t *, void UNUSED *); +static herr_t TEST_sect_can_shrink(const H5FS_section_info_t *, void *); +static herr_t TEST_sect_shrinking(H5FS_section_info_t **, void *); + +H5FS_section_class_t TEST_FSPACE_SECT_CLS[1] = {{ + TEST_FSPACE_SECT_TYPE, /* Section type */ + 0, /* Extra serialized size */ + H5FS_CLS_MERGE_SYM | H5FS_CLS_ADJUST_OK, /* Class flags */ + NULL, /* Class private info */ + + /* Class methods */ + TEST_sect_init_cls, /* Initialize section class */ + NULL, /* Terminate section class */ + + /* Object methods */ + NULL, /* Add section */ + NULL, /* Serialize section */ + NULL, /* Deserialize section */ + TEST_sect_can_merge, /* Can sections merge? */ + TEST_sect_merging, /* Merge sections */ + TEST_sect_can_shrink, /* Can section shrink container?*/ + TEST_sect_shrinking, /* Shrink container w/section */ + TEST_sect_free, /* Free section */ + NULL, /* Check validity of section */ + NULL, /* Split section node for alignment */ + NULL, /* Dump debugging for section */ +}}; + +H5FS_section_class_t TEST_FSPACE_SECT_CLS_NEW[1] = {{ + TEST_FSPACE_SECT_TYPE_NEW, /* Section type */ + 0, /* Extra serialized size */ + H5FS_CLS_MERGE_SYM | H5FS_CLS_ADJUST_OK, /* Class flags */ + NULL, /* Class private info */ + + /* Class methods */ + TEST_sect_init_cls, /* Initialize section class */ + NULL, /* Terminate section class */ + + /* Object methods */ + NULL, /* Add section */ + NULL, /* Serialize section */ + NULL, /* Deserialize section */ + TEST_sect_can_merge, /* Can sections merge? */ + TEST_sect_merging, /* Merge sections */ + NULL, /* Can section shrink container?*/ + NULL, /* Shrink container w/section */ + TEST_sect_free, /* Free section */ + NULL, /* Check validity of section */ + NULL, /* Split section node for alignment */ + NULL, /* Dump debugging for section */ +}}; + +H5FS_section_class_t TEST_FSPACE_SECT_CLS_NOINIT[1] = {{ + TEST_FSPACE_SECT_TYPE_NONE, /* Section type */ + 0, /* Extra serialized size */ + H5FS_CLS_MERGE_SYM | H5FS_CLS_ADJUST_OK, /* Class flags */ + NULL, /* Class private info */ + + /* Class methods */ + NULL, /* Initialize section class */ + NULL, /* Terminate section class */ + + /* Object methods */ + NULL, /* Add section */ + NULL, /* Serialize section */ + NULL, /* Deserialize section */ + TEST_sect_can_merge, /* Can sections merge? */ + TEST_sect_merging, /* Merge sections */ + NULL, /* Can section shrink container?*/ + NULL, /* Shrink container w/section */ + TEST_sect_free, /* Free section */ + NULL, /* Check validity of section */ + NULL, /* Split section node for alignment */ + NULL, /* Dump debugging for section */ +}}; + +const H5FS_section_class_t *test_classes[] = { + TEST_FSPACE_SECT_CLS, + TEST_FSPACE_SECT_CLS_NEW, + TEST_FSPACE_SECT_CLS_NOINIT +}; + + +static void init_cparam(H5FS_create_t *); +static void init_sect_node(TEST_free_section_t *, haddr_t, hsize_t, unsigned, H5FS_section_state_t); +static int check_stats(const H5FS_t *, const frspace_state_t *); + +#define NUM_SECTIONS 1000 + +/* User data for free space section iterator callback */ +typedef struct { + hsize_t tot_size; + hsize_t tot_sect_count; +} TEST_iter_ud_t; + +static herr_t TEST_sects_cb(const H5FS_section_info_t *_sect, void *_udata); + + +/* + * Tests + */ +static int test_fs_create(hid_t); +static int test_fs_sect_add(hid_t); +static int test_fs_sect_merge(hid_t); +static int test_fs_sect_shrink(hid_t); +static int test_fs_sect_find(hid_t); +static int test_fs_sect_change_class(hid_t); +static int test_fs_sect_extend(hid_t); +static int test_fs_sect_iterate(hid_t); + +/* + * free-space section routines for client TEST + */ +static herr_t +TEST_sect_init_cls(H5FS_section_class_t *cls, void *_udata) +{ + herr_t ret_value = SUCCEED; /* Return value */ + unsigned *init_flags; + + /* Check arguments. */ + HDassert(cls); + HDassert(_udata); + + init_flags = (unsigned *)_udata; + cls->flags |= *init_flags; + + return(ret_value); +} /* TEST_sect_init_cls() */ + +/* + * Check if the two sections can be merged: + * true if second section adjoins the first section + */ +static herr_t +TEST_sect_can_merge(const H5FS_section_info_t *_sect1, + const H5FS_section_info_t *_sect2, void UNUSED *_udata) +{ + const TEST_free_section_t *sect1 = (const TEST_free_section_t *)_sect1; + const TEST_free_section_t *sect2 = (const TEST_free_section_t *)_sect2; + htri_t ret_value; /* Return value */ + + /* Check arguments. */ + HDassert(sect1); + HDassert(sect2); + HDassert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */ + HDassert(H5F_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr)); + + /* Check if second section adjoins first section */ + ret_value = H5F_addr_eq(sect1->sect_info.addr + sect1->sect_info.size, sect2->sect_info.addr); + + return(ret_value); +} /* TEST_sect_can_merge() */ + +/* + * Merge the two sections (second section is merged into the first section) + */ +static herr_t +TEST_sect_merging(H5FS_section_info_t *_sect1, H5FS_section_info_t *_sect2, + void UNUSED *_udata) +{ + TEST_free_section_t *sect1 = (TEST_free_section_t *)_sect1; + TEST_free_section_t *sect2 = (TEST_free_section_t *)_sect2; + herr_t ret_value = SUCCEED; /* Return value */ + + /* Check arguments. */ + HDassert(sect1); + HDassert((sect1->sect_info.type == TEST_FSPACE_SECT_TYPE) || + (sect1->sect_info.type == TEST_FSPACE_SECT_TYPE_NEW) || + (sect1->sect_info.type == TEST_FSPACE_SECT_TYPE_NONE)); + HDassert(sect2); + HDassert((sect2->sect_info.type == TEST_FSPACE_SECT_TYPE) || + (sect2->sect_info.type == TEST_FSPACE_SECT_TYPE_NEW) || + (sect2->sect_info.type == TEST_FSPACE_SECT_TYPE_NONE)); + HDassert(H5F_addr_eq(sect1->sect_info.addr + sect1->sect_info.size, sect2->sect_info.addr)); + + /* Add second section's size to first section */ + sect1->sect_info.size += sect2->sect_info.size; + + /* Get rid of second section */ + if(TEST_sect_free((H5FS_section_info_t *)sect2) < 0) + TEST_ERROR +error: + return(ret_value); +} /* TEST_sect_merging() */ + +/* + * Free the section + */ +static herr_t +TEST_sect_free(H5FS_section_info_t *_sect) +{ + TEST_free_section_t *sect = (TEST_free_section_t *)_sect; + + /* Release the section */ + H5FL_FREE(TEST_free_section_t, sect); + + return(0); +} /* TEST_sect_free() */ + +/* + * Determine if the section can be shrunk and set _udata accordingly + * if _udata passed in is NULL, return FALSE + * Otherwise: + * if section's address+size is the end of file, return TRUE + * otherwise return FALSE + */ +static herr_t +TEST_sect_can_shrink(const H5FS_section_info_t *_sect, void *_udata) +{ + unsigned *can_shrink = (unsigned *)_udata; + const TEST_free_section_t *sect = (const TEST_free_section_t *)_sect; + haddr_t end, eoa; + + if (can_shrink == NULL) + return(FALSE); + + end = sect->sect_info.addr + sect->sect_info.size; + eoa = TEST_get_eoa(); + + if (end == eoa) + *can_shrink = TRUE; + else + *can_shrink = FALSE; + return(*can_shrink); + +} /* TEST_sect_can_shrink() */ + +/* + * Shrink the section + */ +static herr_t +TEST_sect_shrinking(H5FS_section_info_t **_sect, void *_udata) +{ + TEST_free_section_t **sect = (TEST_free_section_t **)_sect; + unsigned *can_shrink = (unsigned *)_udata; + + /* address of the section is faked, so, doesn't need to do anything */ + /* just free the section node */ + if (*can_shrink) { + if (TEST_sect_free((H5FS_section_info_t *)*sect) < 0) + TEST_ERROR + *sect = NULL; + return(TRUE); + } + +error: + return(FALSE); +} + + +/* + * iteration callback + */ +static herr_t +TEST_sects_cb(const H5FS_section_info_t *_sect, void *_udata) +{ + const TEST_free_section_t *sect = (const TEST_free_section_t *)_sect; + TEST_iter_ud_t *udata = (TEST_iter_ud_t *)_udata; + herr_t ret_value = SUCCEED; /* Return value */ + + HDassert(sect); + HDassert(udata); + + udata->tot_size += sect->sect_info.size; + udata->tot_sect_count += 1; + + return(ret_value); +} + +/* supporting routine for shrinking */ +static haddr_t +TEST_get_eoa(void) +{ + return(g_eoa); +} + +/* supporting routine for shrinking */ +static void +TEST_set_eoa(haddr_t val) +{ + g_eoa = val; +} + +/* + * Initialize creation parameter structure for TEST client + */ +static void +init_cparam(H5FS_create_t *cparam) +{ + HDmemset(cparam, 0, sizeof(H5FS_create_t)); + + /* Set the free space creation parameters */ + cparam->shrink_percent = TEST_FSPACE_SHRINK; + cparam->expand_percent = TEST_FSPACE_EXPAND; + cparam->max_sect_size = TEST_MAX_SECT_SIZE; + cparam->max_sect_addr = TEST_MAX_INDEX; + +} /* init_cparam() */ + +/* + * Initialize free space section node + */ +static void +init_sect_node(TEST_free_section_t *sect_node, haddr_t addr, hsize_t size, unsigned type, H5FS_section_state_t state) +{ + sect_node->sect_info.addr = addr; + sect_node->sect_info.size = size; + sect_node->sect_info.type = type; + sect_node->sect_info.state = state; +} /* init_sect_node() */ + +/* + * Verify statistics for the free-space manager + */ +static int +check_stats(const H5FS_t *frsp, const frspace_state_t *state) +{ + H5FS_stat_t frspace_stats; /* Statistics about the heap */ + + /* Get statistics for heap and verify they are correct */ + if(H5FS_stat_info(frsp, &frspace_stats) < 0) + FAIL_STACK_ERROR + + if(frspace_stats.tot_space != state->tot_space) { + HDfprintf(stdout, "frspace_stats.tot_space = %Hu, state->tot_space = %Zu\n", + frspace_stats.tot_space, state->tot_space); + TEST_ERROR + } /* end if */ + if(frspace_stats.tot_sect_count != state->tot_sect_count) { + HDfprintf(stdout, "frspace_stats.tot_sect_count = %Hu, state->tot_sect_count = %Hu\n", + frspace_stats.tot_sect_count, state->tot_sect_count); + TEST_ERROR + } /* end if */ + if(frspace_stats.serial_sect_count != state->serial_sect_count) { + HDfprintf(stdout, "frspace_stats.serial_sect_count = %Hu, state->serial_sect_count = %Hu\n", + frspace_stats.serial_sect_count, state->serial_sect_count); + TEST_ERROR + } /* end if */ + if(frspace_stats.ghost_sect_count != state->ghost_sect_count) { + HDfprintf(stdout, "frspace_stats.ghost_sect_count = %Hu, state->ghost_sect_count = %Hu\n", + frspace_stats.ghost_sect_count, state->ghost_sect_count); + TEST_ERROR + } /* end if */ + + /* All tests passed */ + return(0); + +error: + return(1); +} /* check_stats() */ + +/* + * TESTS for free-space manager + */ + +/* + * To verify the creation, close, reopen and deletion of the free-space manager + */ +static int +test_fs_create(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5FS_t *frsp = NULL; /* pointer to free space structure */ + haddr_t fs_addr; /* address of free space */ + h5_stat_size_t file_size, empty_size; /* File size */ + frspace_state_t state; /* State of free space*/ + H5FS_create_t cparam, test_cparam; /* creation parameters */ + size_t nclasses; + unsigned init_flags=0; + + TESTING("the creation/close/reopen/deletion of the free-space manager"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of a file w/empty heap*/ + if((empty_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* initialize creation parameters for free-space manager */ + init_cparam(&cparam); + nclasses = NELMTS(test_classes); + + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + if (frsp->nclasses != nclasses) + TEST_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + if(check_stats(frsp, &state)) + TEST_ERROR + + HDmemset(&test_cparam, 0, sizeof(H5FS_create_t)); + if(H5FS_get_cparam_test(frsp, &test_cparam) < 0) + FAIL_STACK_ERROR + if (H5FS_cmp_cparam_test(&cparam, &test_cparam)) + FAIL_STACK_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* reopen the free-space manager */ + if(NULL == (frsp = H5FS_open(f, H5P_DATASET_XFER_DEFAULT, fs_addr, + nclasses, test_classes, NULL, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + if (frsp->nclasses != nclasses) + TEST_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if(file_size != empty_size) + TEST_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + if(frsp) + H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_fs_create() */ + + +/* + * Test 1: + * Create free-space manager + * Add section A via H5FS_sect_add() with H5FS_ADD_RETURNED_SPACE + * Close the free-space manager + * Result: section A is serialized to the file + * + * Test 2: + * Create free-space manager with H5FS_CLS_GHOST_OBJ section class setting + * Add section A via H5FS_sect_add() with H5FS_ADD_RETURNED_SPACE + * Close the free-space manager + * Result: section A is not serialized to the file + * + * Test 3: + * Add section A via H5FS_sect_add() to allow shrinking with H5FS_ADD_RETURNED_SPACE + * Set EOF to be the ending address of section A + * Result: H5FS_sect_add() will shrink section A + * + * Test 4: + * Add section A via H5FS_sect_add() to allow shrinking with H5FS_ADD_DESERIALIZING + * Set EOF to be the ending address of section A + * Result: H5FS_sect_add() will not shrink section A + * + */ +static int +test_fs_sect_add(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5FS_t *frsp = NULL; /* pointer to free space structure */ + haddr_t fs_addr=HADDR_UNDEF; /* address of free space */ + size_t nclasses; + H5FS_create_t cparam; /* creation parameters */ + frspace_state_t state; /* State of free space*/ + + TEST_free_section_t *sect_node; + unsigned init_flags=0; + h5_stat_size_t file_size=0, tmp_file_size=0, fr_meta_size=0; + unsigned can_shrink=FALSE; + + TESTING("adding a section via H5FS_sect_add() to free-space: test 1"); + + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of a file w/empty heap*/ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + init_cparam(&cparam); + nclasses = NELMTS(test_classes); + + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + if(NULL == (sect_node = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node, (haddr_t)TEST_SECT_ADDR80, (hsize_t)TEST_SECT_SIZE20, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += sect_node->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + fr_meta_size = H5FS_HEADER_SIZE(f) + H5FS_SINFO_PREFIX_SIZE(f); + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of a file w/empty heap*/ + if((tmp_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + if (tmp_file_size <= (file_size+fr_meta_size)) + TEST_ERROR + + PASSED() + + TESTING("adding a section via H5FS_sect_add() to free-space with H5FS_CLS_GHOST_OBJ: test 2"); + + /* Get the size of a file w/empty heap*/ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + init_cparam(&cparam); + nclasses = NELMTS(test_classes); + + init_flags = H5FS_CLS_GHOST_OBJ; + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + /* Create free list section node */ + if(NULL == (sect_node = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node, (haddr_t)TEST_SECT_ADDR80, (hsize_t)TEST_SECT_SIZE20, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node, + 0, NULL)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += sect_node->sect_info.size; + state.tot_sect_count += 1; + state.ghost_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + fr_meta_size = H5FS_HEADER_SIZE(f); + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of a file w/empty heap*/ + if((tmp_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + if (tmp_file_size != (file_size+fr_meta_size)) + TEST_ERROR + + PASSED() + + TESTING("adding a section via H5FS_sect_add() to free-space: test 3"); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of a file w/empty heap*/ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + TEST_set_eoa((haddr_t)TEST_SECT_ADDR150); /* set end of file address for shrinking */ + + init_cparam(&cparam); + nclasses = NELMTS(test_classes); + + init_flags = 0; + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + if(NULL == (sect_node = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + /* + * Add section A + */ + init_sect_node(sect_node, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node, + H5FS_ADD_RETURNED_SPACE, &can_shrink)) + FAIL_STACK_ERROR + + /* nothing in free-space */ + HDmemset(&state, 0, sizeof(frspace_state_t)); + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + TESTING("adding a section via H5FS_sect_add() to free-space: test 4"); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of a file w/empty heap*/ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + TEST_set_eoa((haddr_t)TEST_SECT_ADDR150); /* set end of file address for shrinking */ + + init_cparam(&cparam); + nclasses = NELMTS(test_classes); + + init_flags = 0; + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + if(NULL == (sect_node = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + /* + * Add section A + */ + init_sect_node(sect_node, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node, + H5FS_ADD_DESERIALIZING, &can_shrink)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += sect_node->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + if(H5FS_sect_remove(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node) < 0) + FAIL_STACK_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + if(frsp) + H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_fs_sect_add() */ + + +/* + * To verify the finding of a section with the requested-size from free-space + * + * Test 1: Free-space is empty and is not able to fulfill the requested-size + * Set up: free-space is started up but is empty + * + * Test 2: Add a section and find the section whose size is equal to the requested-size + * Set up: Add section A whose size is less than requested-size + * Add section B whose size is the same as requested-size with addr=b + * Add section C whose size is the same as requested-size with addr=c > b + * Add section D whose size is greater than requested-size + * + * Test 3: Add a section and find the section whose size is > requested-size + * Set up: Add section A whose size is less than requested-size + * Add section B whose size is greater than requested-size + * + * Test 4: Add a section but the section is not able to fulfill the requested-size + * Set up: Add section A whose size is less than requested-size + * + */ +static int +test_fs_sect_find(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5FS_t *frsp = NULL; /* pointer to free space structure */ + haddr_t fs_addr=HADDR_UNDEF; /* address of free space */ + size_t nclasses; + H5FS_create_t cparam; /* creation parameters */ + frspace_state_t state; /* State of free space*/ + + TEST_free_section_t *sect_node1, *sect_node2, *sect_node3, *sect_node4; + TEST_free_section_t *node; + htri_t node_found = FALSE; + unsigned init_flags=0; + + TESTING("H5FS_sect_find(): free-space is empty"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + init_cparam(&cparam); + nclasses = NELMTS(test_classes); + + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + + if(check_stats(frsp, &state)) + TEST_ERROR + + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)TEST_SECT_SIZE30, (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (node_found) TEST_ERROR + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + PASSED() + + TESTING("H5FS_sect_find() a section equal to requested-size from free-space"); + + /* reopen the free-space manager */ + if(NULL == (frsp = H5FS_open(f, H5P_DATASET_XFER_DEFAULT, fs_addr, nclasses, + test_classes, NULL, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + if (frsp->nclasses != nclasses) + TEST_ERROR + + /* + * Add section A + */ + if(NULL == (sect_node1 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += sect_node1->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + + /* + * Add section C + */ + if(NULL == (sect_node3 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node3, (haddr_t)(TEST_SECT_ADDR200), (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node3, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + state.tot_space += sect_node3->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section B + */ + if(NULL == (sect_node2 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node2, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + state.tot_space += sect_node2->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section D + */ + if(NULL == (sect_node4 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node4, (haddr_t)TEST_SECT_ADDR300, (hsize_t)TEST_SECT_SIZE80, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node4, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + state.tot_space += sect_node4->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)TEST_SECT_SIZE50, (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (!node_found) TEST_ERROR + + if ((node->sect_info.addr != TEST_SECT_ADDR100) || (node->sect_info.size != TEST_SECT_SIZE50)) + TEST_ERROR + + if(TEST_sect_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + /* remove sections A, C and D */ + if(H5FS_sect_remove(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1) < 0) + FAIL_STACK_ERROR + if(H5FS_sect_remove(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node3) < 0) + FAIL_STACK_ERROR + if(H5FS_sect_remove(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node4) < 0) + FAIL_STACK_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + PASSED() + + TESTING("H5FS_sect_find() a section greater than requested-size from free-space"); + + /* reopen the free-space manager */ + if(NULL == (frsp = H5FS_open(f, H5P_DATASET_XFER_DEFAULT, fs_addr, nclasses, + test_classes, NULL, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + if (frsp->nclasses != nclasses) + TEST_ERROR + + /* + * Add section A + */ + if(NULL == (sect_node1 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += sect_node1->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section B + */ + if(NULL == (sect_node2 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR200, (hsize_t)TEST_SECT_SIZE80, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node2, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + state.tot_space += sect_node2->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)TEST_SECT_SIZE50, (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (!node_found) TEST_ERROR + if ((node->sect_info.addr != TEST_SECT_ADDR200) || (node->sect_info.size < TEST_SECT_SIZE50)) + TEST_ERROR + + if(TEST_sect_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + /* remove sections A */ + if(H5FS_sect_remove(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1) < 0) + FAIL_STACK_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + PASSED() + + TESTING("H5FS_sect_find(): cannot find a section with requested-size from free-space"); + + /* reopen the free-space manager */ + if(NULL == (frsp = H5FS_open(f, H5P_DATASET_XFER_DEFAULT, fs_addr, nclasses, + test_classes, NULL, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + if (frsp->nclasses != nclasses) + TEST_ERROR + + /* + * Add section A + */ + if(NULL == (sect_node1 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += sect_node1->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)TEST_SECT_SIZE50, (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (node_found) TEST_ERROR + + /* remove sections A */ + if(H5FS_sect_remove(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1) < 0) + FAIL_STACK_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + if(frsp) + H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_fs_sect_find() */ + + +/* + * To verify that sections are merged when adding sections to free-space + * + * Test 1: + * Set up: + * H5FS_CLS_SEPAR_OBJ (cls->flags) is not set + * H5FS_ADD_RETURNED_SPACE is passed to H5FS_sect_add() + * + * Add sections C, B, A & D that can be merged together + * + * Test 2: + * Set up: + * H5FS_CLS_SEPAR_OBJ (cls->flags) is set + * H5FS_ADD_RETURNED_SPACE is passed to H5FS_sect_add() + * + * Add sections A & B that can be merged together but cannot do so because H5FS_CLS_SEPAR_OBJ flag is set + * + * Test 3: + * Set up: + * H5FS_CLS_SEPAR_OBJ (cls->flags) is not set + * H5FS_ADD_RETURNED_SPACE is passed to H5FS_sect_add() + * + * Add 4 sections that adjoin each other as follows: + * section A is of section class type A + * section B is of section class type B + * section C is of section class type B + * section D is of section class type A + * Sections B & C are merged together but not section A nor D because: + * sections B & C are merged because of the same section class type + * section A cannot be merged with the merged section of B & C because of different section class type + * section D cannot be merged with the merged section of B & C because of different section class type + */ +static int +test_fs_sect_merge(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5FS_t *frsp = NULL; /* pointer to free space structure */ + haddr_t fs_addr=HADDR_UNDEF; /* address of free space */ + size_t nclasses; + H5FS_create_t cparam; /* creation parameters */ + frspace_state_t state; /* State of free space*/ + + TEST_free_section_t *sect_node1=NULL, *sect_node2=NULL, *sect_node3=NULL, *sect_node4=NULL; + unsigned init_flags=0; + htri_t node_found = FALSE; + TEST_free_section_t *node; + + TESTING("the merge of sections when H5FS_sect_add() to free-space: test 1"); + + /* + * TEST 1 + */ + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + init_cparam(&cparam); + nclasses = NELMTS(test_classes); + + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + /* + * Add section C + */ + if(NULL == (sect_node1 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += TEST_SECT_SIZE50; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section B + */ + if(NULL == (sect_node2 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node2, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + /* section B & C are merged */ + state.tot_space += TEST_SECT_SIZE30; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section A + */ + if(NULL == (sect_node3 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node3, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE10, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node3, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + /* section A is merged with the merged section of B & C */ + state.tot_space += TEST_SECT_SIZE10; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section D + */ + if(NULL == (sect_node4 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node4, (haddr_t)TEST_SECT_ADDR150, (hsize_t)TEST_SECT_SIZE80, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node4, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + /* section D is merged with the merged section of A & B & C */ + state.tot_space += TEST_SECT_SIZE80; + + if(check_stats(frsp, &state)) + TEST_ERROR + + + /* should be able to find the merged section of A, B, C & D */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)(TEST_SECT_SIZE10+TEST_SECT_SIZE30+TEST_SECT_SIZE50+TEST_SECT_SIZE80), (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (!node_found) TEST_ERROR + if ((node->sect_info.addr != TEST_SECT_ADDR60) || + (node->sect_info.size != (TEST_SECT_SIZE10+TEST_SECT_SIZE30+TEST_SECT_SIZE50+TEST_SECT_SIZE80))) + TEST_ERROR + + if(TEST_sect_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + /* + * TEST 2 + */ + TESTING("the merge of sections when H5FS_sect_add() to free-space: test 2"); + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + init_cparam(&cparam); + nclasses = NELMTS(test_classes); + + init_flags = H5FS_CLS_SEPAR_OBJ; + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + /* + * Add section A + */ + if(NULL == (sect_node1 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += TEST_SECT_SIZE30; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section B + */ + if(NULL == (sect_node2 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node2, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + /* section A & B are not merged because H5FS_CLS_SEPAR_OBJ is set */ + state.tot_space += TEST_SECT_SIZE50; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* should not be able to find the merged section of A & B */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)(TEST_SECT_SIZE30+TEST_SECT_SIZE50), (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (node_found) TEST_ERROR + + /* remove section A from free-space */ + if(H5FS_sect_remove(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1) < 0) + FAIL_STACK_ERROR + /* remove section B from free-space */ + if(H5FS_sect_remove(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node2) < 0) + FAIL_STACK_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + /* + * TEST 3 + */ + TESTING("the merge of sections when H5FS_sect_add() to free-space: test 3"); + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + init_cparam(&cparam); + nclasses = NELMTS(test_classes); + + init_flags = 0; /* reset */ + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + /* + * Add section A + */ + if(NULL == (sect_node1 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE10, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += TEST_SECT_SIZE10; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section B + */ + if(NULL == (sect_node2 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE_NEW, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node2, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + /* sections A & B are not merged because H5FS_CLS_MERGE_SYM is set & section class type is different */ + state.tot_space += TEST_SECT_SIZE30; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section C + */ + if(NULL == (sect_node3 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node3, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE_NEW, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node3, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + /* sections B & C are merged because H5FS_CLS_MERGE_SYM is set & section class type is the same */ + state.tot_space += TEST_SECT_SIZE50; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section D + */ + if(NULL == (sect_node4 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node4, (haddr_t)TEST_SECT_ADDR150, (hsize_t)TEST_SECT_SIZE80, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node4, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + /* + * section D is not merged with the merged section of B & C because + * H5FS_CLS_MERGE_SYM is set and section class type is different + */ + state.tot_space += TEST_SECT_SIZE80; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* should not be able to find a merged section of A, B, C & D */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)(TEST_SECT_SIZE10+TEST_SECT_SIZE30+TEST_SECT_SIZE50+TEST_SECT_SIZE80), (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (node_found) TEST_ERROR + + /* should be able to find the merged section of B & C */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)(TEST_SECT_SIZE30+TEST_SECT_SIZE50), (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (!node_found) TEST_ERROR + + if ((node->sect_info.addr != TEST_SECT_ADDR70) || + (node->sect_info.size != (TEST_SECT_SIZE30+TEST_SECT_SIZE50))) + TEST_ERROR + + if(TEST_sect_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + /* should be able to find section A */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)(TEST_SECT_SIZE10), (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (!node_found) TEST_ERROR + + if ((node->sect_info.addr != TEST_SECT_ADDR60) || (node->sect_info.size != TEST_SECT_SIZE10)) + TEST_ERROR + + if(TEST_sect_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + /* should be able to find section D */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)(TEST_SECT_SIZE80), (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (!node_found) TEST_ERROR + + if ((node->sect_info.addr != TEST_SECT_ADDR150) || (node->sect_info.size != TEST_SECT_SIZE80)) + TEST_ERROR + + if(TEST_sect_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + if(frsp) + H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_fs_sect_merge() */ + +/* + * To verify that sections are shrunk when adding sections to free-space + * + * Test 1: + * Set EOF to be the ending address of section A + * H5FS_CLS_SEPAR_OBJ (cls->flags) is not set when creating free-space manager + * Add section A to allow shrinking but is not shrunk because its section class type + * TEST_FSPACE_SECT_TYPE_NEW does not define "can_shrink" + * Result:section A is not shrunk and section A is still in free-space + * + * Re-add section A to allow shrinking and with section class type TEST_FSPACE_SECT_TYPE + * that defines "can_shrink" + * Result:section A is shrunk and there is nothing in free-space + * + * Test 2: + * Set EOF to be greater than the ending address of section A + * Set H5FS_CLS_SEPAR_OBJ (cls->flags) when creating free-space manager + * + * Add section A to allow shrinking but is not shrunk because it is not at EOF, + * and section A is not on the merge list due to H5FS_CLS_SEPAR_OBJ + * Add section B to allow shrinking and whose ending address is the same as eof. + * Section B is not merged with section A because of H5FS_CLS_SEPAR_OBJ but it is shrunk + * Result: section A is still in free-space + * + * Test 3: + * Set EOF to be greater than the ending address of section A + * H5FS_CLS_SEPAR_OBJ (cls->flags) is not set when creating free-space manager + * + * Add section A to allow shrinking but is not shrunk because it is not at EOF, + * and section A is on the merge list + * Add section B to allow shrinking and whose ending address is the same as eof. + * Section B is merged with section A and then shrunk. + * Result: free-space should be empty + */ +static int +test_fs_sect_shrink(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5FS_t *frsp = NULL; /* pointer to free space structure */ + haddr_t fs_addr=HADDR_UNDEF; /* address of free space */ + size_t nclasses; + H5FS_create_t cparam; /* creation parameters */ + frspace_state_t state; /* State of free space*/ + + TEST_free_section_t *sect_node1=NULL, *sect_node2=NULL; + unsigned init_flags=0; + unsigned can_shrink=FALSE; + htri_t node_found = FALSE; + TEST_free_section_t *node; + + TESTING("shrinking of sections when H5FS_sect_add() to free-space: test 1"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + init_cparam(&cparam); + nclasses = NELMTS(test_classes); + + TEST_set_eoa((haddr_t)TEST_SECT_ADDR150); /* set end of file address for shrinking */ + + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + /* + * Add section A that allow shrinking but its section class type does not define "can_shrink" + */ + if(NULL == (sect_node1 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE_NEW, H5FS_SECT_LIVE); + + can_shrink = FALSE; + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + H5FS_ADD_RETURNED_SPACE, &can_shrink)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += sect_node1->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* section A should still be there in free-space */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)(TEST_SECT_SIZE50), (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (!node_found) TEST_ERROR + + if ((node->sect_info.addr != TEST_SECT_ADDR100) || (node->sect_info.size != TEST_SECT_SIZE50)) + TEST_ERROR + + if(TEST_sect_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + /* + * Re-add section A that allow shrinking and its section class type defines "can_shrink" + */ + if(NULL == (sect_node1 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + can_shrink = FALSE; + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + H5FS_ADD_RETURNED_SPACE, &can_shrink)) + FAIL_STACK_ERROR + + /* should have nothing in free-space */ + HDmemset(&state, 0, sizeof(frspace_state_t)); + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* section A should not be there in free-space */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)(TEST_SECT_SIZE50), (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (node_found) TEST_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + + TESTING("shrinking of sections when H5FS_sect_add() to free-space: test 2"); + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + init_cparam(&cparam); + nclasses = NELMTS(test_classes); + + TEST_set_eoa((haddr_t)TEST_SECT_ADDR150); /* set end of file address for shrinking */ + + /* does not allow merging */ + init_flags = H5FS_CLS_SEPAR_OBJ; + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + /* + * Add section A + */ + if(NULL == (sect_node1 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR80, (hsize_t)TEST_SECT_SIZE20, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + H5FS_ADD_RETURNED_SPACE, &can_shrink)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += sect_node1->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section B + */ + if(NULL == (sect_node2 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node2, + H5FS_ADD_RETURNED_SPACE, &can_shrink)) + FAIL_STACK_ERROR + + /* free-space should be the same since section B is shrunk */ + if(check_stats(frsp, &state)) + TEST_ERROR + + /* section B should not be there in free-space */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)(TEST_SECT_SIZE50), (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (node_found) TEST_ERROR + + if(check_stats(frsp, &state)) + TEST_ERROR + + + /* section A should still be there in free-space */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)(TEST_SECT_SIZE20), (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (!node_found) TEST_ERROR + + if ((node->sect_info.addr != TEST_SECT_ADDR80) || (node->sect_info.size != TEST_SECT_SIZE20)) + TEST_ERROR + + if(TEST_sect_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + TESTING("shrinking of sections when H5FS_sect_add() to free-space: test 3"); + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + init_cparam(&cparam); + nclasses = NELMTS(test_classes); + + TEST_set_eoa((haddr_t)TEST_SECT_ADDR150); /* set end of file address for shrinking */ + + init_flags = 0; /* reset */ + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + /* + * Add section A + */ + if(NULL == (sect_node1 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + H5FS_ADD_RETURNED_SPACE, &can_shrink)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += sect_node1->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section B + */ + if(NULL == (sect_node2 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node2, + H5FS_ADD_RETURNED_SPACE, &can_shrink)) + FAIL_STACK_ERROR + + /* section A & B are merged and then strunk, so there is nothing in free-space */ + HDmemset(&state, 0, sizeof(frspace_state_t)); + if(check_stats(frsp, &state)) + TEST_ERROR + + /* section B should not be there in free-space */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)(TEST_SECT_SIZE50), (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (node_found) TEST_ERROR + + /* section A should not be there in free-space */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)(TEST_SECT_SIZE30), (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (node_found) TEST_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + if(frsp) + H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_sect_shrink() */ + +/* + * To verify a section's class is changed via H5FS_sect_change_class() + * + * Test 1: + * Add section A with TEST_FSPACE_SECT_TYPE class type with H5FS_CLS_GHOST_OBJ setting + * Add section B with TEST_FSPACE_SECT_TYPE_NONE class type without H5FS_CLS_GHOST_OBJ setting + * Change section A's class to the second section's class + * Result: serial_sect_count is incremented by 1; ghost_sect_count is decremented by 1 + * + * Test 2: + * Add section A with TEST_FSPACE_SECT_TYPE class type with H5FS_CLS_SEPAR_OBJ setting + * Add section B with TEST_FSPACE_SECT_TYPE_NONE class type without H5FS_CLS_SEPAR_OBJ setting + * Add section C with TEST_FSPACE_SECT_TYPE_NONE class type without H5FS_CLS_SEPAR_OBJ setting + * Sections B & C are on the merge list + * Change section class of B and C to A's section class + * Result: the merge list should be null and the class of sections B & C should be changed + */ +static int +test_fs_sect_change_class(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5FS_t *frsp = NULL; /* pointer to free space structure */ + haddr_t fs_addr=HADDR_UNDEF; /* address of free space */ + size_t nclasses; + H5FS_create_t cparam; /* creation parameters */ + frspace_state_t state; /* State of free space*/ + + TEST_free_section_t *sect_node1=NULL, *sect_node2=NULL, *sect_node3=NULL; + unsigned init_flags=0; + TEST_free_section_t *node; + htri_t node_found = FALSE; + + TESTING("the change of section class via H5FS_sect_change_class() in free-space: Test 1"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + init_cparam(&cparam); + nclasses = NELMTS(test_classes); + + init_flags = H5FS_CLS_GHOST_OBJ; + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + /* + * Add section A + */ + if(NULL == (sect_node1 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += TEST_SECT_SIZE30; + state.tot_sect_count += 1; + state.ghost_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section B + */ + if(NULL == (sect_node2 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE_NONE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node2, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + state.tot_space += TEST_SECT_SIZE50; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + if (H5FS_sect_change_class(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + TEST_FSPACE_SECT_TYPE_NONE) < 0) + TEST_ERROR + + state.serial_sect_count += 1; + state.ghost_sect_count -=1; + if(check_stats(frsp, &state)) + TEST_ERROR + + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)TEST_SECT_SIZE30, (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (node->sect_info.type != TEST_FSPACE_SECT_TYPE_NONE) + TEST_ERROR + + if(TEST_sect_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + if(H5FS_sect_remove(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node2) < 0) + FAIL_STACK_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + /* + * TEST 2 + */ + TESTING("the merge of sections when H5FS_sect_add() to free-space: test 2"); + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + init_cparam(&cparam); + nclasses = NELMTS(test_classes); + + init_flags = H5FS_CLS_SEPAR_OBJ; + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + /* + * Add section A + */ + if(NULL == (sect_node1 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + /* + * Add section B + */ + if(NULL == (sect_node2 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE_NONE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node2, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + /* + * Add section C + */ + if(NULL == (sect_node3 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node3, (haddr_t)TEST_SECT_ADDR200, (hsize_t)TEST_SECT_SIZE80, TEST_FSPACE_SECT_TYPE_NONE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node3, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + /* change the class of B to A's class */ + if (H5FS_sect_change_class(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node2, + TEST_FSPACE_SECT_TYPE) < 0) + TEST_ERROR + + /* change the class of C to A's class */ + if (H5FS_sect_change_class(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node3, + TEST_FSPACE_SECT_TYPE) < 0) + TEST_ERROR + + /* the merge_list should be empty */ + if (frsp->sinfo->merge_list) + if (H5SL_count(frsp->sinfo->merge_list)) + TEST_ERROR + + /* verify that section B has changed class */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)TEST_SECT_SIZE50, (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (node->sect_info.type != TEST_FSPACE_SECT_TYPE) + TEST_ERROR + + if(TEST_sect_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + /* verify that section C has changed class */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, frsp, + (hsize_t)TEST_SECT_SIZE80, (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + if (node->sect_info.type != TEST_FSPACE_SECT_TYPE) + TEST_ERROR + + if(TEST_sect_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + /* remove section A from free-space */ + if(H5FS_sect_remove(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1) < 0) + FAIL_STACK_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + if(frsp) + H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_sect_change_class() */ + + +/* + * To verify the extension of a block using space from a section in free-space + * + * Test 1: Try to extend the block by requested-size, which is equal to section B's size + * Add section A (addr=70, size=5) + * Add section B (addr=100, size=40) + * Try to extend the block (addr=80, size=20) by 40, which is the same as section B's size + * Result: succeed in extending the block + * + * Test 2: Try to extend the block by requested-size, which is greater than section B's size + * Add section A (addr=70, size=5) + * Add section B (addr=100, size=40) + * Try to extend the block (addr=80, size=20) by 50, which is greater than section B's size + * Result: fail in extending the block + * + * Test 3: Try to extend the block by requested-size, which is less than section B's size + * Add section A (addr=70, size=5) + * Add section B (addr=100, size=40) + * Try to extend the block (addr=80, size=20) by 30, which is less than section B's size + * Result: succeed in extending the block and a section of size=10 is left in free-space + * + * Test 4: Try to extend the block which does not adjoin section B + * Add section A (addr=70, size=5) + * Add section B (addr=100, size=40) + * Try to extend the block (addr=80, size=15) by 40 + * Result: fail in extending the block because: + * the block does not adjoin section B (80+15 != addr of section B (80)) + * even though the requested-size is equal to section B's size + * + */ +static int +test_fs_sect_extend(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5FS_t *frsp = NULL; /* pointer to free space structure */ + haddr_t fs_addr=HADDR_UNDEF; /* address of free space */ + size_t nclasses; + H5FS_create_t cparam; /* creation parameters */ + frspace_state_t state; /* State of free space*/ + + TEST_free_section_t *sect_node1=NULL, *sect_node2=NULL; + unsigned init_flags=0; + + TESTING("a block's extension by requested-size which is = adjoining free section's size: Test 1"); + + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* + * TEST 1 + */ + init_cparam(&cparam); + nclasses = NELMTS(test_classes); + + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + /* + * Add section A + */ + if(NULL == (sect_node1 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE5, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += sect_node1->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section B + */ + if(NULL == (sect_node2 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE40, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node2, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + state.tot_space += sect_node2->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* Extend a block by requested-size */ + if(H5FS_sect_try_extend(f, H5P_DATASET_XFER_DEFAULT, frsp, (haddr_t)TEST_SECT_SIZE80, (hsize_t)TEST_SECT_SIZE20, (hsize_t)TEST_SECT_SIZE40) < 0) + TEST_ERROR + + /* Succeed in extending the block: free space info is decremented accordingly */ + state.tot_space -= sect_node2->sect_info.size; + state.tot_sect_count -= 1; + state.serial_sect_count -= 1; + if(check_stats(frsp, &state)) + TEST_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + PASSED() + + /* + * TEST 2 + */ + TESTING("a block's extension by requested-size which is > adjoining free section's size: Test 2"); + + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + /* + * Add section A + */ + if(NULL == (sect_node1 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE5, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += sect_node1->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section B + */ + if(NULL == (sect_node2 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE40, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node2, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + state.tot_space += sect_node2->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* Extend the block by requested-size */ + if(H5FS_sect_try_extend(f, H5P_DATASET_XFER_DEFAULT, frsp, (haddr_t)TEST_SECT_ADDR80, (hsize_t)TEST_SECT_SIZE20, (hsize_t)TEST_SECT_SIZE50) < 0) + TEST_ERROR + + /* Not able to extend the block: free space info remains the same */ + if(check_stats(frsp, &state)) + TEST_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + PASSED() + + /* + * Test 3 + */ + TESTING("a block's extension by requested-size which is < adjoining free section's size: Test 3"); + + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + /* + * Add section A + */ + if(NULL == (sect_node1 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE5, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += sect_node1->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section B + */ + if(NULL == (sect_node2 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE40, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node2, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + state.tot_space += sect_node2->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* Extend the block by requested-size */ + if(H5FS_sect_try_extend(f, H5P_DATASET_XFER_DEFAULT, frsp, (haddr_t)TEST_SECT_ADDR80, (hsize_t)TEST_SECT_SIZE20, (hsize_t)TEST_SECT_SIZE30) < 0) + TEST_ERROR + + /* Succeed in extending the block: total free space is decreased but other info remains the same */ + state.tot_space -= 30; + if(check_stats(frsp, &state)) + TEST_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + PASSED() + + /* + * TEST 4 + */ + TESTING("a block's extension by requested-size which does not adjoin any free section: Test 4"); + + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + /* + * Add section A + */ + if(NULL == (sect_node1 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE5, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node1, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += sect_node1->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* + * Add section B + */ + if(NULL == (sect_node2 = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE40, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node2, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + + state.tot_space += sect_node2->sect_info.size; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(frsp, &state)) + TEST_ERROR + + /* Extend the block by requested-size */ + if(H5FS_sect_try_extend(f, H5P_DATASET_XFER_DEFAULT, frsp, (haddr_t)TEST_SECT_ADDR80, (hsize_t)TEST_SECT_SIZE15, (hsize_t)TEST_SECT_SIZE40) < 0) + TEST_ERROR + + /* Not able to extend the block: free space manager info remains the same */ + if(check_stats(frsp, &state)) + TEST_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + return(0); + +error: + H5E_BEGIN_TRY { + if(frsp) + H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_sect_extend() */ + + +/* + * To verify the iteration of free-space sections + * + * Create free-space manager with H5FS_CLS_SEPAR_OBJ + * Create a whole bunch of sections + * Iterate through all sections and collect size and count for all sections + * Check info with H5FS_sect_stat() + */ +static int +test_fs_sect_iterate(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5FS_t *frsp = NULL; /* pointer to free space structure */ + haddr_t fs_addr=HADDR_UNDEF; /* address of free space */ + size_t nclasses; + H5FS_create_t cparam; /* creation parameters */ + + TEST_free_section_t *sect_node=NULL; + unsigned init_flags=0, sect_size; + TEST_iter_ud_t udata; + int i; + hsize_t tot_space, nsects; + + TESTING("iteration of sections in the free-space manager"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + init_cparam(&cparam); + nclasses = NELMTS(test_classes); + udata.tot_size = 0; + udata.tot_sect_count = 0; + + init_flags = H5FS_CLS_SEPAR_OBJ; + if(NULL == (frsp = H5FS_create(f, H5P_DATASET_XFER_DEFAULT, &fs_addr, + &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) + FAIL_STACK_ERROR + + if(!H5F_addr_defined(fs_addr)) + TEST_ERROR + + for (i = 1; i <= NUM_SECTIONS; i++) { + if(NULL == (sect_node = H5FL_MALLOC(TEST_free_section_t))) + FAIL_STACK_ERROR + + sect_size = ((i-1) % 9) + 1; + init_sect_node(sect_node, (haddr_t)i*10, (hsize_t)sect_size, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE); + + if(H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, frsp, (H5FS_section_info_t *)sect_node, + H5FS_ADD_RETURNED_SPACE, NULL)) + FAIL_STACK_ERROR + } + + if(H5FS_sect_iterate(f, H5P_DATASET_XFER_DEFAULT, frsp, TEST_sects_cb, &udata) < 0) + TEST_ERROR + + H5FS_sect_stats(frsp, &tot_space, &nsects); + + if (udata.tot_size != tot_space) + TEST_ERROR + if (udata.tot_sect_count != nsects) + TEST_ERROR + + /* Close the free space manager */ + if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) + FAIL_STACK_ERROR + frsp = NULL; + + /* Delete free space manager */ + if(H5FS_delete(f, H5P_DATASET_XFER_DEFAULT, fs_addr) < 0) + FAIL_STACK_ERROR + fs_addr = HADDR_UNDEF; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + if(frsp) + H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_fs_sect_iterate() */ + + +int +main(void) +{ + + hid_t fapl = -1; /* File access property list for data files */ + unsigned nerrors = 0; /* Cumulative error count */ + + fapl = h5_fileaccess(); + + /* make sure alignment is not set for tests to succeed */ + if(H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)1) < 0) + TEST_ERROR + + nerrors += test_fs_create(fapl); + nerrors += test_fs_sect_add(fapl); + nerrors += test_fs_sect_merge(fapl); + nerrors += test_fs_sect_shrink(fapl); + nerrors += test_fs_sect_find(fapl); + nerrors += test_fs_sect_change_class(fapl); + nerrors += test_fs_sect_extend(fapl); + nerrors += test_fs_sect_iterate(fapl); + + if(nerrors) + goto error; + puts("All free-space tests passed."); + +#ifdef OUT + h5_cleanup(FILENAME, fapl); +#endif + return (0); + +error: + puts("*** TESTS FAILED ***"); + H5E_BEGIN_TRY { + H5Pclose(fapl); + } H5E_END_TRY; + return (1); +} /* main() */ diff --git a/test/getname.c b/test/getname.c index 2d19d33..4084f9e 100644 --- a/test/getname.c +++ b/test/getname.c @@ -2725,7 +2725,7 @@ test_reg_ref(hid_t fapl) /* Create a reference to elements selection */ if((status = H5Sselect_none(space_id)) < 0) TEST_ERROR - if((status = H5Sselect_elements(space_id, H5S_SELECT_SET, num_points, coord)) < 0) + if((status = H5Sselect_elements(space_id, H5S_SELECT_SET, num_points, (const hsize_t *)coord)) < 0) TEST_ERROR if((status = H5Rcreate(&ref[1], file_id, REFREG_DSETNAMEV, H5R_DATASET_REGION, space_id)) < 0) TEST_ERROR diff --git a/test/links.c b/test/links.c index 065cb46..03e77f2 100644 --- a/test/links.c +++ b/test/links.c @@ -26,10 +26,11 @@ */ #define H5G_PACKAGE #define H5G_TESTING -#include "H5Gpkg.h" /* Groups */ #include "h5test.h" -#include "H5Lprivate.h" +#include "H5Gpkg.h" /* Groups */ +#include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ /* File for external link test. Created with gen_udlinks.c */ #define LINKED_FILE "be_extlink2.h5" @@ -1762,6 +1763,10 @@ external_link_root(hid_t fapl, hbool_t new_format) if(H5Gclose(gid) < 0) TEST_ERROR if(H5Fclose(fid) < 0) TEST_ERROR + /* Check that all file IDs have been closed */ + if(H5I_nmembers(H5I_FILE) != 0) TEST_ERROR + if(H5F_sfile_assert_num(0) != 0) TEST_ERROR + /* Open first file again with read-only access and check on objects created */ if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR @@ -1782,6 +1787,10 @@ external_link_root(hid_t fapl, hbool_t new_format) /* Close first file */ if(H5Fclose(fid) < 0) TEST_ERROR + /* Check that all file IDs have been closed */ + if(H5I_nmembers(H5I_FILE) != 0) TEST_ERROR + if(H5F_sfile_assert_num(0) != 0) TEST_ERROR + /* Verify that new objects can't be created through a read-only external * link. */ @@ -1795,6 +1804,10 @@ external_link_root(hid_t fapl, hbool_t new_format) /* Close second file again */ if(H5Fclose(fid) < 0) TEST_ERROR + /* Check that all file IDs have been closed */ + if(H5I_nmembers(H5I_FILE) != 0) TEST_ERROR + if(H5F_sfile_assert_num(0) != 0) TEST_ERROR + PASSED(); return 0; @@ -10377,7 +10390,7 @@ open_by_idx_check(hid_t main_group_id, hid_t soft_group_id, hid_t mount_file_id, haddr_t *objno) { char mntname[NAME_BUF_SIZE]; /* Link value */ - hid_t group_id; /* ID of group to test */ + hid_t group_id = (-1); /* ID of group to test */ H5O_info_t oi; /* Buffer for querying object's info */ haddr_t mnt_root_addr; /* Address of root group in file to mount */ hid_t obj_id; /* ID of object opened */ @@ -10845,7 +10858,7 @@ object_info_check(hid_t main_group_id, hid_t soft_group_id, H5_index_t idx_type, H5_iter_order_t order, unsigned max_links, haddr_t *objno) { char objname[NAME_BUF_SIZE]; /* Object name */ - hid_t group_id; /* ID of group to test */ + hid_t group_id = (-1); /* ID of group to test */ H5O_info_t oinfo; /* Buffer for querying object's info */ unsigned u, v; /* Local index variables */ diff --git a/test/mf.c b/test/mf.c new file mode 100644 index 0000000..24f3333 --- /dev/null +++ b/test/mf.c @@ -0,0 +1,5386 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Tests for file memory management consist of 3 parts: + * test_mf_eoa_*() tests for file meomory that interact with file allocation + * 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 + */ + +#include "h5test.h" + +#define H5MF_PACKAGE +#include "H5MFpkg.h" + +#define H5FS_PACKAGE +#include "H5FSpkg.h" + +#define H5F_PACKAGE +#include "H5Fpkg.h" + +#include "H5FLprivate.h" +#include "H5Iprivate.h" +#include "H5Vprivate.h" + +#define FILENAME_LEN 1024 +#define TEST_FSPACE_CLIENT_ID 2 + +#define TEST_BLOCK_SIZE5 5 +#define TEST_BLOCK_SIZE10 10 +#define TEST_BLOCK_SIZE20 20 +#define TEST_BLOCK_SIZE30 30 +#define TEST_BLOCK_SIZE40 40 +#define TEST_BLOCK_SIZE50 50 +#define TEST_BLOCK_SIZE80 80 +#define TEST_BLOCK_SIZE200 200 +#define TEST_BLOCK_SIZE600 600 +#define TEST_BLOCK_SIZE700 700 +#define TEST_BLOCK_SIZE1034 1034 +#define TEST_BLOCK_SIZE1970 1970 +#define TEST_BLOCK_SIZE2058 2058 +#define TEST_BLOCK_SIZE8000 8000 +#define TEST_BLOCK_SIZE2048 2048 +#define TEST_BLOCK_SIZE1024 1024 + +#define TEST_BLOCK_ADDR70 70 +#define TEST_BLOCK_ADDR100 100 + +#define TEST_ALIGN1024 1024 +#define TEST_ALIGN4096 4096 + +const char *FILENAME[] = { + "mf", + NULL +}; + +typedef enum { + TEST_NORMAL, /* size of aggregator is >= alignment size */ + TEST_AGGR_SMALL, /* size of aggregator is smaller than alignment size */ + TEST_NTESTS /* The number of test types, must be last */ +} test_type_t; + +typedef struct frspace_state_t { + hsize_t tot_space; /* Total amount of space tracked */ + hsize_t tot_sect_count; /* Total # of sections tracked */ + hsize_t serial_sect_count; /* # of serializable sections tracked */ + hsize_t ghost_sect_count; /* # of un-serializable sections tracked */ +} frspace_state_t; + + +static int check_stats(const H5FS_t *, const frspace_state_t *); + +/* + * Verify statistics for the free-space manager + */ +static int +check_stats(const H5FS_t *frsp, const frspace_state_t *state) +{ + H5FS_stat_t frspace_stats; /* Statistics about the heap */ + + /* Get statistics for free-space and verify they are correct */ + if(H5FS_stat_info(frsp, &frspace_stats) < 0) + FAIL_STACK_ERROR + + if(frspace_stats.tot_space != state->tot_space) { + HDfprintf(stdout, "frspace_stats.tot_space = %Hu, state->tot_space = %Zu\n", + frspace_stats.tot_space, state->tot_space); + TEST_ERROR + } /* end if */ + if(frspace_stats.tot_sect_count != state->tot_sect_count) { + HDfprintf(stdout, "frspace_stats.tot_sect_count = %Hu, state->tot_sect_count = %Hu\n", + frspace_stats.tot_sect_count, state->tot_sect_count); + TEST_ERROR + } /* end if */ + if(frspace_stats.serial_sect_count != state->serial_sect_count) { + HDfprintf(stdout, "frspace_stats.serial_sect_count = %Hu, state->serial_sect_count = %Hu\n", + frspace_stats.serial_sect_count, state->serial_sect_count); + TEST_ERROR + } /* end if */ + if(frspace_stats.ghost_sect_count != state->ghost_sect_count) { + HDfprintf(stdout, "frspace_stats.ghost_sect_count = %Hu, state->ghost_sect_count = %Hu\n", + frspace_stats.ghost_sect_count, state->ghost_sect_count); + TEST_ERROR + } /* end if */ + + /* All tests passed */ + return(0); + +error: + return(1); +} /* check_stats() */ + + +/* + * To verify that blocks are allocated from file allocation + * + * Set up: + * Turn off using meta/small data aggregator + * There is nothing in free-space manager + * + * Allocate two blocks which should be from file allocation + */ +static int +test_mf_eoa(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + hid_t fapl_new; /* copy of fapl */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size, new_file_size; /* file size */ + H5FD_mem_t type; + haddr_t addr1, addr2; + haddr_t ma_addr=HADDR_UNDEF, new_ma_addr=HADDR_UNDEF; + hsize_t ma_size=0; + + TESTING("H5MM_alloc() of file allocation"); + + /* Set the filename to use for this test */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + if((fapl_new = H5Pcopy(fapl)) < 0) TEST_ERROR + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Turn off using meta/small data aggregator */ + H5Pset_meta_block_size(fapl_new, (hsize_t)0); + H5Pset_small_data_block_size(fapl_new, (hsize_t)0); + + /* Re-open the file with meta/small data setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* nothing should be changed in meta_aggr */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &ma_size); + if (new_ma_addr != ma_addr) + TEST_ERROR + + if (addr1 < (haddr_t)file_size) + TEST_ERROR + + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + /* nothing should be changed in meta_aggr */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &ma_size); + if (new_ma_addr != ma_addr) + TEST_ERROR + + if (addr2 < (haddr_t)file_size) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != (file_size+TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE50)) + TEST_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 = H5I_object(file))) + FAIL_STACK_ERROR + + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr2, (hsize_t)TEST_BLOCK_SIZE50); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != file_size) + TEST_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_eoa() */ + +/* + * To verify that an allocated block from file allocation is shrunk. + * + * Set up: + * Turn off using meta/small data aggregator + * There is nothing in free-space manager + * + * Test 1: Allocate a block of 30 from file allocation + * H5MF_try_shrink() the block by 30 : succeed + * Test 2: Allocate a block of 30 from file allocation + * H5MF_try_shrink() the block by 20 : fail + * Test 3: Allocate a block of 30 from file allocation + * H5MF_try_shrink() the block by 40 : fail + * Test 4: Allocate a block of 30 from file allocation + * H5MF_try_shrink() the block by 20 from the end: succeed + * + */ +static int +test_mf_eoa_shrink(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + hid_t fapl_new; /* copy of fapl */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size, new_file_size; /* file size */ + htri_t status; + H5FD_mem_t type; + haddr_t addr; + haddr_t ma_addr=HADDR_UNDEF, new_ma_addr=HADDR_UNDEF; + hsize_t ma_size=0, new_ma_size=0; + + TESTING("H5MF_try_shrink() of file allocation: test 1"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + if((fapl_new = H5Pcopy(fapl)) < 0) TEST_ERROR + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Turn off using meta/small data aggregator */ + H5Pset_meta_block_size(fapl_new, (hsize_t)0); + H5Pset_small_data_block_size(fapl_new, (hsize_t)0); + + /* Re-open the file with meta/small data setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + type = H5FD_MEM_SUPER; + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + if (addr < (haddr_t)file_size) + TEST_ERROR + + /* nothing should be changed in meta_aggr */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + if (new_ma_addr != ma_addr) TEST_ERROR + if (new_ma_size != ma_size) TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != (file_size+TEST_BLOCK_SIZE30)) + TEST_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 = H5I_object(file))) + FAIL_STACK_ERROR + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + /* should succeed */ + status = H5MF_try_shrink(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)TEST_BLOCK_SIZE30); + if (status <= 0) + TEST_ERROR + + /* nothing should be changed in meta_aggr */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &ma_size); + if (new_ma_addr != ma_addr) TEST_ERROR + if (new_ma_size != ma_size) TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != file_size) + TEST_ERROR + + PASSED() + + TESTING("H5MF_try_shrink() of file allocation: test 2"); + + /* Re-open the file with meta/small data setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + if (addr < (haddr_t)file_size) + TEST_ERROR + + /* should not succeed in shrinking */ + status = H5MF_try_shrink(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)TEST_BLOCK_SIZE30-10); + if (status > 0) + TEST_ERROR + + /* nothing should be changed in meta_aggr */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &ma_size); + if (new_ma_addr != ma_addr) TEST_ERROR + if (new_ma_size != ma_size) TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != (file_size+TEST_BLOCK_SIZE30)) + TEST_ERROR + + PASSED() + + + TESTING("H5MF_try_shrink() of file allocation: test 3"); + + /* Re-open the file with meta/small data setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + /* should not succeed in shrinking */ + status = H5MF_try_shrink(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)TEST_BLOCK_SIZE30+10); + if (status > 0) + TEST_ERROR + + /* nothing should be changed in meta_aggr */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &ma_size); + if (new_ma_addr != ma_addr) TEST_ERROR + if (new_ma_size != ma_size) TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != (file_size+TEST_BLOCK_SIZE30)) + TEST_ERROR + + PASSED() + + TESTING("H5MF_try_shrink() of file allocation: test 4"); + + /* Re-open the file with meta/small data setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + /* should succeed in shrinking */ + status = H5MF_try_shrink(f, type, H5P_DATASET_XFER_DEFAULT, addr+10, (hsize_t)(TEST_BLOCK_SIZE30-10)); + if (status <= 0) + TEST_ERROR + + /* nothing should be changed in meta_aggr */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &ma_size); + if (new_ma_addr != ma_addr) TEST_ERROR + if (new_ma_size != ma_size) TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != (file_size+10)) + TEST_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_eoa_shrink() */ + +/* + * To verify that an allocated block from file allocation is extended. + * + * Set up: + * Turn off using meta/small data aggregator + * There is nothing in free-space manager + * + * Test 1: Allocate a block of 30 + * H5MF_try_extend() the block of size 30 by 50: succeed + * + * Test 2: Allocate a block of 30 + * H5MF_try_extend() the block of size 20 by 50: fail + */ +static int +test_mf_eoa_extend(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + hid_t fapl_new; /* copy of fapl */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size, new_file_size; /* File size */ + H5FD_mem_t type; + haddr_t addr; + htri_t extended; + haddr_t ma_addr=HADDR_UNDEF, new_ma_addr=HADDR_UNDEF; + hsize_t ma_size=0, new_ma_size=0; + + TESTING("H5MF_try_extend() of file allocation: test 1"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + if((fapl_new = H5Pcopy(fapl)) < 0) TEST_ERROR + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of a file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Turn off using meta/small data aggregator */ + H5Pset_meta_block_size(fapl_new, (hsize_t)0); + H5Pset_small_data_block_size(fapl_new, (hsize_t)0); + + /* Re-open the file with meta/small data setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + type = H5FD_MEM_SUPER; + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + if (addr < (haddr_t)file_size) + TEST_ERROR + + /* nothing should be changed in meta_aggr */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + if (new_ma_addr != ma_addr) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != (file_size+TEST_BLOCK_SIZE30)) + TEST_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 = H5I_object(file))) + FAIL_STACK_ERROR + + /* should succeed */ + extended = H5MF_try_extend(f, H5P_DATASET_XFER_DEFAULT, type, (haddr_t)addr, (hsize_t)TEST_BLOCK_SIZE30, (hsize_t)TEST_BLOCK_SIZE50); + + if(extended <= 0) + TEST_ERROR + + /* nothing should be changed in meta_aggr */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + if (new_ma_addr != ma_addr) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != (file_size+TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE50)) + TEST_ERROR + + PASSED() + + TESTING("H5MF_try_extend() of file allocation: test 2"); + + /* Re-open the file with meta/small data setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + type = H5FD_MEM_SUPER; + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + if (addr < (haddr_t)file_size) + TEST_ERROR + + /* nothing should be changed in meta_aggr */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + if (new_ma_addr != ma_addr) + TEST_ERROR + + extended = H5MF_try_extend(f, H5P_DATASET_XFER_DEFAULT, type, (haddr_t)addr, (hsize_t)(TEST_BLOCK_SIZE30-10), (hsize_t)(TEST_BLOCK_SIZE50)); + + /* should not succeed */ + if(extended > 0) + TEST_ERROR + + /* nothing should be changed in meta_aggr */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + if (new_ma_addr != ma_addr) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != file_size+TEST_BLOCK_SIZE30) + TEST_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_eoa_extend() */ + +/* + * To verify that the free-space manager is started up via H5MF_alloc_start() + * + * Set up: + * Turn off using meta/small data aggregator + */ +static int +test_mf_fs_start(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + hid_t fapl_new; /* copy of fapl */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size, new_file_size; /* file size */ + H5FD_mem_t type; + frspace_state_t state; + + + TESTING("H5MF_alloc_start() of free-space manager"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + if((fapl_new = H5Pcopy(fapl)) < 0) TEST_ERROR + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Turn off using meta/small data aggregator */ + H5Pset_meta_block_size(fapl_new, (hsize_t)0); + H5Pset_small_data_block_size(fapl_new, (hsize_t)0); + + /* Re-open the file with meta/small data setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Start up free-space manager */ + type = H5FD_MEM_SUPER; + if(H5MF_alloc_start(f, H5P_DATASET_XFER_DEFAULT, type, TRUE) < 0) + TEST_ERROR + if (f->shared->fs_state[type] != H5F_FS_STATE_OPEN) + TEST_ERROR + if (f->shared->fs_man[type]->client != H5FS_CLIENT_FILE_ID) + TEST_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != file_size) + TEST_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_fs_start() */ + + +/* + * To verify that a block is allocated/freed from/to the free-space manager + * + * Set up: + * Turn off using meta/small data aggregator + * + * Test 1: + * Add section A to free-space manager (addr=70, size=30) + * Allocate a block of size=30 + * The returned space's address should be same as section A's address + * Deallocate the block which will be returned to the free-space manager + * Test 2: + * Add section A to free-space manager (addr=70, size=30) + * Allocate a block of size=20 + * The returned space's address should be same as section A's address + * There should still be space of 10 left in the free-space manager + * Deallocate the block which will be returned to free-space manager + * Test 3: + * Add section A to free-space manager (addr=70, size=30) + * Allocate a block of size=40 + * The free-space manager is unable to fulfill the request + * The block is allocated from file allocation + * Deallocate the block which will be returned to free-space manager + * (the space is shrunk and freed since it is at end of file) + */ +static int +test_mf_fs_alloc_free(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + hid_t fapl_new; /* copy of fapl */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size, new_file_size; /* file size */ + H5FD_mem_t type; + H5MF_free_section_t *sect_node = NULL; + haddr_t addr; + frspace_state_t state; + H5MF_sect_ud_t udata; + H5FS_section_info_t *node; + htri_t node_found = FALSE; + + TESTING("H5MF_alloc()/H5MF_xfree() of free-space manager:test 1"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + if((fapl_new = H5Pcopy(fapl)) < 0) TEST_ERROR + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of a file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Turn off using meta/small data aggregator */ + H5Pset_meta_block_size(fapl_new, (hsize_t)0); + H5Pset_small_data_block_size(fapl_new, (hsize_t)0); + + /* Re-open the file with meta/small data setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + type = H5FD_MEM_SUPER; + if(H5MF_alloc_start(f, H5P_DATASET_XFER_DEFAULT, type, TRUE) < 0) + TEST_ERROR + if (f->shared->fs_state[type] != H5F_FS_STATE_OPEN) + TEST_ERROR + if (f->shared->fs_man[type]->client != H5FS_CLIENT_FILE_ID) + TEST_ERROR + + /* Create section A */ + sect_node = H5MF_sect_simple_new((haddr_t)TEST_BLOCK_ADDR70, (hsize_t)TEST_BLOCK_SIZE30); + + /* Construct user data for callbacks */ + udata.f = f; + udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; + udata.alloc_type = type; + udata.allow_sect_absorb = TRUE; + + /* Add section A to free-space manager */ + if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &udata)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += TEST_BLOCK_SIZE30; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Allocate a block of 30 */ + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Verify that the allocated block is section A in free-space */ + if (addr != TEST_BLOCK_ADDR70) + TEST_ERROR + + state.tot_space -= TEST_BLOCK_SIZE30; + state.tot_sect_count -= 1; + state.serial_sect_count -= 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Free the block to free-space */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)TEST_BLOCK_SIZE30); + + state.tot_space += TEST_BLOCK_SIZE30; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Remove section A from free-space */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], + (hsize_t)TEST_BLOCK_SIZE30, (H5FS_section_info_t **)&node)) < 0) + + /* Free the free-space section node */ + if(H5MF_sect_simple_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != file_size) + TEST_ERROR + + PASSED() + + TESTING("H5MF_alloc()/H5MF_xfree() of free-space manager:test 2"); + + /* Re-open the file with meta/small data setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + type = H5FD_MEM_SUPER; + if(H5MF_alloc_start(f, H5P_DATASET_XFER_DEFAULT, type, TRUE) < 0) + TEST_ERROR + if (f->shared->fs_state[type] != H5F_FS_STATE_OPEN) + TEST_ERROR + if (f->shared->fs_man[type]->client != H5FS_CLIENT_FILE_ID) + TEST_ERROR + + /* Create section A */ + sect_node = H5MF_sect_simple_new((haddr_t)TEST_BLOCK_ADDR70, (hsize_t)TEST_BLOCK_SIZE30); + + /* Construct user data for callbacks */ + udata.f = f; + udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; + udata.alloc_type = type; + udata.allow_sect_absorb = TRUE; + + /* Add section A to free-space manager */ + if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &udata)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += TEST_BLOCK_SIZE30; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Allocate a block of 20 */ + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)(TEST_BLOCK_SIZE20)); + + /* Verify that the allocated block is section A in free-space manager */ + if (addr != TEST_BLOCK_ADDR70) + TEST_ERROR + + /* should still have 1 section of size 10 left in free-space manager */ + state.tot_space -= (TEST_BLOCK_SIZE20); + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Free the block to free-space manager */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)(TEST_BLOCK_SIZE20)); + + /* Still 1 section in free-space because of merging */ + state.tot_space += TEST_BLOCK_SIZE20; + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Remove section A from free-space manager */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], + (hsize_t)TEST_BLOCK_SIZE30, (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + /* Free the free-space section node */ + if(H5MF_sect_simple_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != file_size) + TEST_ERROR + + PASSED() + + TESTING("H5MF_alloc()/H5MF_xfree() of free-space manager:test 3"); + + /* Re-open the file with meta/small data setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + type = H5FD_MEM_SUPER; + if(H5MF_alloc_start(f, H5P_DATASET_XFER_DEFAULT, type, TRUE) < 0) + TEST_ERROR + if (f->shared->fs_state[type] != H5F_FS_STATE_OPEN) + TEST_ERROR + if (f->shared->fs_man[type]->client != H5FS_CLIENT_FILE_ID) + TEST_ERROR + + /* Create section A */ + sect_node = H5MF_sect_simple_new((haddr_t)TEST_BLOCK_ADDR70, (hsize_t)TEST_BLOCK_SIZE30); + + /* Construct user data for callbacks */ + udata.f = f; + udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; + udata.alloc_type = type; + udata.allow_sect_absorb = TRUE; + + /* Add section A to free-space manager */ + if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &udata)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += TEST_BLOCK_SIZE30; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* + * Allocate a block of 40. + * Since free-space manager cannot fulfull the request, + * the block is obtained from file allocation + */ + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)(TEST_BLOCK_SIZE40)); + + /* Verify that the allocated block is not section A in free-space */ + if (addr == TEST_BLOCK_ADDR70) + TEST_ERROR + + /* free-space info should be the same */ + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Remove section A from free-space */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], + (hsize_t)TEST_BLOCK_SIZE30, (H5FS_section_info_t **)&node)) < 0) + FAIL_STACK_ERROR + + /* Free the free-space section node */ + if(H5MF_sect_simple_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Free the block of size 40 to free-space */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)(TEST_BLOCK_SIZE40)); + + /* + * Free-space info is the same. + * The block is returned to free-space. + * It is shrunk and freed because it is at end of file. + */ + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (file_size != file_size) + TEST_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_fs_alloc_free() */ + + +/* + * To verify that a block allocated from the free-space manager can be extended + * + * Set up: + * Turn off using meta/small data aggregator + * + * Test 1: + * Add section A to free-space manager: addr=70, size=30 + * Allocate a block of size 30 from free-space manager + * Add section B to free-space manager: addr=100, size=50 + * Try to extend the allocated block by requested-size=50 + * Succeed: section A adjoins section B (70+30=100 which is section B's address) and + * requested-size (50) is equal to the size of section B + * Test 2: + * Add section A to free-space manager: addr=70, size=30 + * Allocate a block of size 30 from free-space manager + * Add section B to free-space manager: addr=100, size=50 + * Try to extend the allocated block by requested-size=60 + * Fail: section A adjoins section B (70+30=100 which is section B's address) but + * requested-size (60) > size of section B (50) + * + * Test 3: + * Add section A to free-space manager: addr=70, size=30 + * Allocate a block of size 30 from free-space manager + * Add section B to free-space manager: addr=100, size=50 + * Try to extend the allocated block by requested-size=40 + * Succeed: section A adjoins section B (70+30=100 which is section B's address) and + * requested-size (40) < size of section B (50), therefore, + * a section of 10 is left in the free-space manager + * Test 4: + * Add section A to free-space manager: addr=70, size=20 + * Allocate a block of size 20 from free-space manager + * Add section B to free-space manager: addr=100, size=50 + * Try to extend the allocated block by 50 from the free-space_manager: + * Fail: section A does not adjoin section B (70+20 != address of section B) even though + * the requested-size (50) equal to size of section B (50) + */ +static int +test_mf_fs_extend(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + hid_t fapl_new; /* copy of fapl */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size, new_file_size; /* file size */ + H5FD_mem_t type; + H5MF_free_section_t *sect_node1 = NULL, *sect_node2=NULL; + haddr_t addr; + frspace_state_t state; /* State of free space*/ + H5MF_sect_ud_t udata; + H5FS_section_info_t *node; + htri_t node_found = FALSE; + htri_t extended; + + TESTING("H5MF_try_extend() of free-space manager:test 1"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + if((fapl_new = H5Pcopy(fapl)) < 0) TEST_ERROR + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of a file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Turn off using meta/small data aggregator */ + H5Pset_meta_block_size(fapl_new, (hsize_t)0); + H5Pset_small_data_block_size(fapl_new, (hsize_t)0); + + /* Re-open the file with meta/small data setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + type = H5FD_MEM_SUPER; + if(H5MF_alloc_start(f, H5P_DATASET_XFER_DEFAULT, type, TRUE) < 0) + TEST_ERROR + if (f->shared->fs_state[type] != H5F_FS_STATE_OPEN) + TEST_ERROR + if (f->shared->fs_man[type]->client != H5FS_CLIENT_FILE_ID) + TEST_ERROR + + /* Create section A */ + sect_node1 = H5MF_sect_simple_new((haddr_t)TEST_BLOCK_ADDR70, (hsize_t)TEST_BLOCK_SIZE30); + + /* Construct user data for callbacks */ + udata.f = f; + udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; + udata.alloc_type = type; + udata.allow_sect_absorb = TRUE; + + /* Add section A to free-space manager */ + if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &udata)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += TEST_BLOCK_SIZE30; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Allocate a block of 30 */ + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Verify that the allocated block is section A in free-space manager */ + if (addr != TEST_BLOCK_ADDR70) + TEST_ERROR + + state.tot_space -= TEST_BLOCK_SIZE30; + state.tot_sect_count -= 1; + state.serial_sect_count -= 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Create section B */ + sect_node2 = H5MF_sect_simple_new((haddr_t)TEST_BLOCK_ADDR100, (hsize_t)TEST_BLOCK_SIZE50); + + /* Add section B to free-space manager */ + if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, &udata)) + FAIL_STACK_ERROR + + state.tot_space += TEST_BLOCK_SIZE50; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Try to extend the allocated block */ + extended = H5MF_try_extend(f, H5P_DATASET_XFER_DEFAULT, type, (haddr_t)TEST_BLOCK_ADDR70, (hsize_t)TEST_BLOCK_SIZE30, (hsize_t)TEST_BLOCK_SIZE50); + + /* should succeed */ + if(extended <= 0) + TEST_ERROR + + /* Section B is removed from free-space manager */ + state.tot_space -= TEST_BLOCK_SIZE50; + state.tot_sect_count -= 1; + state.serial_sect_count -= 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Free the extended block to free-space manager */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)(TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE50)); + + /* Verify that the extended block is back into free-space */ + state.tot_space += TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE50; + state.tot_sect_count = 1; + state.serial_sect_count = 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Remove the extended block */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], + (hsize_t)(TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE50), (H5FS_section_info_t **)&node)) < 0) + TEST_ERROR + + /* Remove the free-space section node */ + if(H5MF_sect_simple_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != file_size) + TEST_ERROR + + PASSED() + + TESTING("H5MF_try_extend() of free-space manager:test 2"); + + /* Re-open the file with meta/small data setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + type = H5FD_MEM_SUPER; + if(H5MF_alloc_start(f, H5P_DATASET_XFER_DEFAULT, type, TRUE) < 0) + TEST_ERROR + if (f->shared->fs_state[type] != H5F_FS_STATE_OPEN) + TEST_ERROR + if (f->shared->fs_man[type]->client != H5FS_CLIENT_FILE_ID) + TEST_ERROR + + /* Create section A */ + sect_node1 = H5MF_sect_simple_new((haddr_t)TEST_BLOCK_ADDR70, (hsize_t)TEST_BLOCK_SIZE30); + + /* Construct user data for callbacks */ + udata.f = f; + udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; + udata.alloc_type = type; + udata.allow_sect_absorb = TRUE; + + /* Add section A to free-space */ + if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &udata)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += TEST_BLOCK_SIZE30; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Allocate a block of 30 */ + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Verify that the allocated block is section A in free-space manager */ + if (addr != TEST_BLOCK_ADDR70) + TEST_ERROR + + state.tot_space -= TEST_BLOCK_SIZE30; + state.tot_sect_count -= 1; + state.serial_sect_count -= 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Create section B */ + sect_node2 = H5MF_sect_simple_new((haddr_t)TEST_BLOCK_ADDR100, (hsize_t)TEST_BLOCK_SIZE50); + + /* Add section B to free-space manager */ + if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, &udata)) + FAIL_STACK_ERROR + + state.tot_space += TEST_BLOCK_SIZE50; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Try to extend the allocated block */ + extended = H5MF_try_extend(f, H5P_DATASET_XFER_DEFAULT, type, (haddr_t)TEST_BLOCK_ADDR70, (hsize_t)TEST_BLOCK_SIZE30, (hsize_t)(TEST_BLOCK_SIZE50+10)); + + /* Should not be able to extend the allocated block */ + if(extended) + TEST_ERROR + + /* free-space info should remain the same */ + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Free the allocated block A to free-space */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)TEST_BLOCK_SIZE30); + + /* the returned section A is merged with section B in free-space */ + /* rest of the info remains the same */ + state.tot_space += TEST_BLOCK_SIZE30; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Remove the merged sections A & B from free-space */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], + (hsize_t)(TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE50), (H5FS_section_info_t **)&node)) < 0) + TEST_ERROR + + /* Remove the free-space section node */ + if(H5MF_sect_simple_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != file_size) + TEST_ERROR + + PASSED() + + TESTING("H5MF_try_extend() of free-space manager:test 3"); + + /* Re-open the file with meta/small data setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + type = H5FD_MEM_SUPER; + if(H5MF_alloc_start(f, H5P_DATASET_XFER_DEFAULT, type, TRUE) < 0) + TEST_ERROR + if (f->shared->fs_state[type] != H5F_FS_STATE_OPEN) + TEST_ERROR + if (f->shared->fs_man[type]->client != H5FS_CLIENT_FILE_ID) + TEST_ERROR + + /* Create section A */ + sect_node1 = H5MF_sect_simple_new((haddr_t)TEST_BLOCK_ADDR70, (hsize_t)TEST_BLOCK_SIZE30); + + /* Construct user data for callbacks */ + udata.f = f; + udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; + udata.alloc_type = type; + udata.allow_sect_absorb = TRUE; + + /* Add section A to free-space */ + if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &udata)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += TEST_BLOCK_SIZE30; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Allocate a block of 30 */ + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Verify that the allocated block is section A in free-space manager */ + if (addr != TEST_BLOCK_ADDR70) + TEST_ERROR + + state.tot_space -= TEST_BLOCK_SIZE30; + state.tot_sect_count -= 1; + state.serial_sect_count -= 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Create section B */ + sect_node2 = H5MF_sect_simple_new((haddr_t)TEST_BLOCK_ADDR100, (hsize_t)TEST_BLOCK_SIZE50); + + /* Add section B to free-space manager */ + if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, &udata)) + FAIL_STACK_ERROR + + state.tot_space += TEST_BLOCK_SIZE50; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Try to extend the allocated block */ + extended = H5MF_try_extend(f, H5P_DATASET_XFER_DEFAULT, type, (haddr_t)TEST_BLOCK_ADDR70, (hsize_t)TEST_BLOCK_SIZE30, (hsize_t)(TEST_BLOCK_SIZE40)); + + /* Should succeed in extending the allocated block */ + if(extended <=0) + TEST_ERROR + + /* Should have 1 section of size=10 left in free-space manager */ + state.tot_space -= (TEST_BLOCK_SIZE40); + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Free the extended block */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)(TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE40)); + + /* rest info is same, the extended section returned is merged with the section in free-space */ + state.tot_space += (TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE40); + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Remove the merged sections A & B from free-space */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], + (hsize_t)(TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE50), (H5FS_section_info_t **)&node)) < 0) + TEST_ERROR + + /* Remove the free-space section node */ + if(H5MF_sect_simple_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != file_size) + TEST_ERROR + + PASSED() + + TESTING("H5MF_try_extend() of free-space manager:test 4"); + + /* Re-open the file with meta/small data setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl_new)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + type = H5FD_MEM_SUPER; + if(H5MF_alloc_start(f, H5P_DATASET_XFER_DEFAULT, type, TRUE) < 0) + TEST_ERROR + if (f->shared->fs_state[type] != H5F_FS_STATE_OPEN) + TEST_ERROR + if (f->shared->fs_man[type]->client != H5FS_CLIENT_FILE_ID) + TEST_ERROR + + /* Create section A */ + sect_node1 = H5MF_sect_simple_new((haddr_t)TEST_BLOCK_ADDR70, (hsize_t)(TEST_BLOCK_SIZE30-10)); + + /* Construct user data for callbacks */ + udata.f = f; + udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; + udata.alloc_type = type; + udata.allow_sect_absorb = TRUE; + + /* Add section A of size=20 to free-space */ + if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &udata)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += (TEST_BLOCK_SIZE30-10); + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Allocate a block of size=20 */ + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)(TEST_BLOCK_SIZE30-10)); + + /* Verify that the allocated block is section A in free-space manager */ + if (addr != TEST_BLOCK_ADDR70) + TEST_ERROR + + state.tot_space -= (TEST_BLOCK_SIZE30-10); + state.tot_sect_count -= 1; + state.serial_sect_count -= 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Create section B */ + sect_node2 = H5MF_sect_simple_new((haddr_t)TEST_BLOCK_ADDR100, (hsize_t)TEST_BLOCK_SIZE50); + + /* Add section B to free-space manager */ + if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, &udata)) + FAIL_STACK_ERROR + + state.tot_space += TEST_BLOCK_SIZE50; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Try to extend the allocated block */ + extended = H5MF_try_extend(f, H5P_DATASET_XFER_DEFAULT, type, (haddr_t)TEST_BLOCK_ADDR70, (hsize_t)(TEST_BLOCK_SIZE30-10), (hsize_t)TEST_BLOCK_SIZE50); + + /* Should not succeed in extending the allocated block */ + if(extended) + TEST_ERROR + + /* Free-space info should be the same */ + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Free the allocated block */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)(TEST_BLOCK_SIZE30-10)); + + state.tot_space += (TEST_BLOCK_SIZE30-10); + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Remove section A from free-space manger */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], + (hsize_t)(TEST_BLOCK_SIZE30-10), (H5FS_section_info_t **)&node)) < 0) + TEST_ERROR + + /* Remove the free-space section node */ + if(H5MF_sect_simple_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + /* Remove section B from free-space manager */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], + (hsize_t)TEST_BLOCK_SIZE50, (H5FS_section_info_t **)&node)) < 0) + TEST_ERROR + + /* Remove the free-space section node */ + if(H5MF_sect_simple_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != file_size) + TEST_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_fs_extend() */ + +/* + * To verify that an aggregator is absorbed into a section. + * + * Test 1: To aborb the aggregator onto the beginning of the section + * Allocate block A from meta_aggr + * Create a free-space section node with an address that adjoins + * the end of meta_aggr and a size to make the aggregator + * get absorbed into the section. + * The adding of the section to free-space will call H5MF_aggr_absorb(), + * which will absorb meta_aggr to the section: + * section size + remaining size of aggregator is > aggr->alloc_size, + * section is allowed to absorb an aggregator (allow_sect_absorb is true) + * + * Test 2: To absorb the aggregator onto the end of the section + * Allocate block A from meta_aggr + * Allocate block B from sdata_aggr + * Create a free-space section node with an address that adjoins + * the beginning of meta_aggr and a size to make the + * aggregator get absorbed into the section. + * The adding of the section to free-space will call H5MF_aggr_absorb(), + * which will absorb meta_aggr to the section: + * section size + remaining size of aggregator is > aggr->alloc_size, + * section is allowed to absorb an aggregator (allow_sect_absorb is true) + */ +static int +test_mf_fs_absorb(hid_t fapl) +{ + 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; + haddr_t addr, saddr; + haddr_t ma_addr=HADDR_UNDEF; + hsize_t ma_size=0; + H5MF_free_section_t *sect_node=NULL; + H5MF_sect_ud_t udata; + htri_t node_found=FALSE; + H5FS_section_info_t *node; + + TESTING("A free-space section absorbs an aggregator: test 1"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + type = H5FD_MEM_SUPER; + if(H5MF_alloc_start(f, H5P_DATASET_XFER_DEFAULT, type, TRUE) < 0) + TEST_ERROR + if (f->shared->fs_state[type] != H5F_FS_STATE_OPEN) + TEST_ERROR + if (f->shared->fs_man[type]->client != H5FS_CLIENT_FILE_ID) + TEST_ERROR + + /* Allocate a section from meta_aggr */ + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + /* Add a section to free-space that adjoins end of the aggregator */ + sect_node = H5MF_sect_simple_new((haddr_t)(ma_addr+ma_size), (hsize_t)TEST_BLOCK_SIZE2048); + + /* Construct user data for callbacks */ + udata.f = f; + udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; + udata.alloc_type = type; + udata.allow_sect_absorb = TRUE; + + /* When adding, meta_aggr is absorbed onto the beginning of the section */ + if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &udata)) + FAIL_STACK_ERROR + + /* Verify that the section did absorb the aggregator */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], + (hsize_t)TEST_BLOCK_SIZE2048, (H5FS_section_info_t **)&node)) < 0) + TEST_ERROR + + if (node->addr != ma_addr) TEST_ERROR + if (node->size != (ma_size + TEST_BLOCK_SIZE2048)) TEST_ERROR + + /* Remove the free-space section node */ + if(H5MF_sect_simple_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + /* Restore info for aggregator */ + f->shared->meta_aggr.addr = ma_addr; + f->shared->meta_aggr.size = ma_size; + + /* Remove section from meta_aggr */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)TEST_BLOCK_SIZE30); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + TESTING("A free-space section absorbs an aggregator: test 2"); + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + type = H5FD_MEM_SUPER; + if(H5MF_alloc_start(f, H5P_DATASET_XFER_DEFAULT, type, TRUE) < 0) + TEST_ERROR + if (f->shared->fs_state[type] != H5F_FS_STATE_OPEN) + TEST_ERROR + if (f->shared->fs_man[type]->client != H5FS_CLIENT_FILE_ID) + TEST_ERROR + + /* Allocate a section from meta_aggr */ + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + /* Allocate a section from sdata_aggr */ + stype = H5FD_MEM_DRAW; + saddr = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + /* Add a section to free-space that adjoins the beginning of meta_aggr */ + sect_node = H5MF_sect_simple_new((haddr_t)addr, (hsize_t)TEST_BLOCK_SIZE30); + + /* Construct user data for callbacks */ + udata.f = f; + udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; + udata.alloc_type = type; + udata.allow_sect_absorb = TRUE; + + /* When adding, meta_aggr is absorbed onto the end of the section */ + if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &udata)) + FAIL_STACK_ERROR + + /* Verify that the section did absorb the aggregator */ + if((node_found = H5FS_sect_find(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], + (hsize_t)(ma_size+TEST_BLOCK_SIZE30), (H5FS_section_info_t **)&node)) < 0) + TEST_ERROR + + if ((node->addr + TEST_BLOCK_SIZE30) != ma_addr) TEST_ERROR + if (node->size != (ma_size + TEST_BLOCK_SIZE30)) TEST_ERROR + + /* free the free-space section node */ + if(H5MF_sect_simple_free((H5FS_section_info_t *)node) < 0) + TEST_ERROR + + /* restore info to meta_aggr */ + f->shared->meta_aggr.addr = ma_addr; + f->shared->meta_aggr.size = ma_size; + + /* Remove section from meta_aggr */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)TEST_BLOCK_SIZE30); + /* Remove section from sdata_aggr */ + H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr, (hsize_t)TEST_BLOCK_SIZE50); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_fs_absorb() */ + +/* + * To verify that blocks are allocated from the aggregator + * + * Allocate first block (30) from meta_aggr: (nothing in the aggregator) + * request-size is > what is left in meta_aggr and < meta_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is allocated from file allocation + * The first block of 30 is allocated from meta_aggr + * There is space of 2018 left in meta_aggr + * + * Allocate second block (50) from meta_aggr: + * request-size is <= what is left in meta_aggr + * Result: + * The second block of 50 is allocated from meta_aggr + * There is space of 1968 left in meta_aggr + */ +static int +test_mf_aggr_alloc1(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size, new_file_size; /* file size */ + H5FD_mem_t type; + haddr_t addr1, addr2; + haddr_t ma_addr=HADDR_UNDEF; + hsize_t ma_size=0; + + TESTING("H5MF_alloc() of meta/sdata aggregator:test 1"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of a file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate first block from meta_aggr */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if ((addr1+TEST_BLOCK_SIZE30) != ma_addr) + TEST_ERROR + + /* Allocate second block from meta_aggr */ + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if ((addr2+TEST_BLOCK_SIZE50) != ma_addr) + TEST_ERROR + if (ma_size != (TEST_BLOCK_SIZE2048 - (TEST_BLOCK_SIZE30 + TEST_BLOCK_SIZE50))) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != (file_size+TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE50)) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Free the two blocks */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr2, (hsize_t)TEST_BLOCK_SIZE50); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != file_size) + TEST_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_aggr_alloc1() */ + +/* + * To verify that blocks are allocated from the aggregator + * + * Allocate first block (30) from meta_aggr: (nothing in the aggregator) + * request-size is > what is left in meta_aggr and < meta_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is obtained via file allocation + * There is space of 2018 left in meta_aggr + * + * Allocate second block (50) from meta_aggr: + * request-size is <= what is left in meta_aggr + * Result: + * The second block of 50 is allocated from what is left in meta_aggr + * There is space of 1968 left in meta_aggr + * + * Allocate third block (2058) from meta_aggr: + * request-size is > what is left in meta_aggr and is >= meta_aggr->alloc_size + * meta_aggr is at EOA + * Result: + * A block of request-size is extended via file allocation and is merged with meta_aggr + * The block of 2058 is allocated out of meta_aggr + * There is space of 1968 left in meta_aggr + */ +static int +test_mf_aggr_alloc2(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size, new_file_size; /* file size */ + H5FD_mem_t type; + haddr_t addr1, addr2, addr3; + haddr_t ma_addr=HADDR_UNDEF; + hsize_t ma_size=0; + + TESTING("H5MF_alloc() of meta/sdata aggregator:test 2"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of a file */ + if((file_size= h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if ((addr1+TEST_BLOCK_SIZE30) != ma_addr) + TEST_ERROR + + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if ((addr2+TEST_BLOCK_SIZE50) != ma_addr) + TEST_ERROR + + if (ma_size != (TEST_BLOCK_SIZE2048 - (TEST_BLOCK_SIZE30 + TEST_BLOCK_SIZE50))) + TEST_ERROR + + addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE2058); + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if ((addr3+TEST_BLOCK_SIZE2058) != ma_addr) + TEST_ERROR + + if (ma_size != (TEST_BLOCK_SIZE2048 - (TEST_BLOCK_SIZE30 + TEST_BLOCK_SIZE50))) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + /* Unused space is freed from the end of the file */ + if (new_file_size != (file_size+TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE50+TEST_BLOCK_SIZE2058)) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE50+TEST_BLOCK_SIZE2058); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != file_size) + TEST_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_aggr_alloc2() */ + +/* + * To verify that blocks are allocated from the aggregator + * + * Allocate first block (30) from meta_aggr : (nothing in the aggregator) + * request-size is > what is left in meta_aggr and < meta_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is obtained via file allocation + * The first block of 30 is allocated from there + * There is space of 2018 left in meta_aggr + * + * Allocate second block (50) from meta_aggr: + * request-size is <= what is left in meta_aggr + * Result: + * The second block of 50 is allocated from what is left in meta_aggr + * There is space of 1968 left in meta_aggr + * + * Allocate first block (30) from sdata_aggr: (nothing in sdata_aggr) + * request-size is > what is left in other_aggr and is < sdata_aggr->alloc_size + * Result: + * A block of sdata_aggr->alloc_size is obtained via file allocation + * The first block of 30 is allocated from there + * There is space of 2018 left in sdata_aggr + * + * Allocate the third block (2058) from meta_aggr: + * request-size is > what is left in meta_aggr and >= meta_aggr->alloc_size + * sdata_aggr is at EOA but has not used up more than sdata_aggr->alloc_size + * Result: A block of request-size is obtained via file allocation + * The new block's address is returned + * Nothing is changed in meta_aggr and sdata_aggr + * + * Allocate fourth block (50) from meta_aggr: + * request-size is <= what is left in meta_aggr and < meta_aggr->alloc_size + * Result: + * The fourth block of 50 is allocated from what is left in meta_aggr + * There is space of 1968 left in meta_aggr + */ +static int +test_mf_aggr_alloc3(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size, new_file_size; /* file size */ + H5FD_mem_t type, stype; + haddr_t addr1, addr2, addr3, addr4, saddr1; + haddr_t ma_addr=HADDR_UNDEF, new_ma_addr=HADDR_UNDEF; + hsize_t ma_size=0, new_ma_size=0; + haddr_t sdata_addr=HADDR_UNDEF; + hsize_t sdata_size=0; + + TESTING("H5MF_alloc() of meta/sdata aggregator: test 3"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate first block from meta_aggr */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if ((addr1+TEST_BLOCK_SIZE30) != ma_addr) + TEST_ERROR + + /* Allocate second block from meta_aggr */ + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if ((addr2+TEST_BLOCK_SIZE50) != ma_addr) + TEST_ERROR + if (ma_size != (TEST_BLOCK_SIZE2048 - (TEST_BLOCK_SIZE30 + TEST_BLOCK_SIZE50))) + TEST_ERROR + + /* Allocate first block from sdata_aggr */ + stype = H5FD_MEM_DRAW; + saddr1 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if ((saddr1+TEST_BLOCK_SIZE30) != sdata_addr) + TEST_ERROR + if (sdata_size != (TEST_BLOCK_SIZE2048 - TEST_BLOCK_SIZE30)) TEST_ERROR + + /* Allocate third block, which is from file allocation not from meta_aggr */ + addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)(TEST_BLOCK_SIZE2058)); + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + + /* info for meta_aggr shouldn't be changed */ + if (addr3 != (sdata_addr+sdata_size)) TEST_ERROR + if ((addr3+TEST_BLOCK_SIZE2058) == new_ma_addr) TEST_ERROR + if ((new_ma_addr != ma_addr) || (new_ma_size != ma_size)) TEST_ERROR + + /* Allocate fourth block, which should be from meta_aggr */ + addr4 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if ((addr4+TEST_BLOCK_SIZE50) != ma_addr) + TEST_ERROR + if (ma_size != (TEST_BLOCK_SIZE2048 - (TEST_BLOCK_SIZE30 + TEST_BLOCK_SIZE50 + TEST_BLOCK_SIZE50))) + TEST_ERROR + + /* Free all the allocated blocks */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr2, (hsize_t)TEST_BLOCK_SIZE50); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr3, (hsize_t)TEST_BLOCK_SIZE2058); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr4, (hsize_t)TEST_BLOCK_SIZE50); + H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr1, (hsize_t)TEST_BLOCK_SIZE30); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != file_size) + TEST_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_aggr_alloc3() */ + + +/* + * To verify that blocks are allocated from the aggregator + * + * Allocate first block (30) from meta_aggr: (nothing in the aggregator) + * request-size is > what is left in meta_aggr and < meta_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is obtained via file allocation + * There is space of 2018 left in meta_aggr + * The first block of 30 is allocated from there + * + * Allocate first block (30) from sdata_aggr: (nothing in sdata_aggr) + * request-size is > what is left in sdata_aggr and < sdata_aggr->alloc_size + * Result: + * A block of sdata_aggr->alloc_size is obtained via file allocation + * The first block of 30 is allocated from there + * + * Allocate the second block (2018) from sdata_aggr: + * request-size is <= what is left in sdata_aggr and < sdata_aggr->alloc_size + * request-size is < sdata_aggr->alloc_size + * Result: + * The block is allocated from what is left in sdata_aggr (all used up) + * + * Allocate third block (50) from sdata_aggr : + * request-size is > what is left in sdata_aggr and < sdata_aggr->alloc_size + * Result: + * A block of sdata_aggr->alloc_size is extended via file allocation + * The third block of 50 is allocated from there + * There is space of 1998 left in the sdata_aggr + * + * Allocate second block (2058) from meta_aggr: + * request-size is > what is left in meta_aggr and >= meta_aggr->alloc_size + * sdata_aggr is at EOA and has used up more than sdata_aggr->alloc_size + * Result: + * unused spaced in sdata_aggr is freed to free-space and is shrunk + * sdata_aggr is reset to 0 + * A block of request-size is obtained via file allocation + * The new block's address is returned + * The block does not adjoin meta_aggr + * meta_aggr's info is unchanged + */ +static int +test_mf_aggr_alloc4(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size, new_file_size; /* File size */ + H5FD_mem_t type, stype; + haddr_t addr1, addr2, saddr1, saddr2, saddr3; + haddr_t ma_addr=HADDR_UNDEF, new_ma_addr=HADDR_UNDEF, sdata_addr=HADDR_UNDEF; + hsize_t ma_size=0, new_ma_size=0, sdata_size=0; + + TESTING("H5MF_alloc() of meta/sdata aggregator:test 4"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate first block from meta_aggr */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if ((addr1+TEST_BLOCK_SIZE30) != ma_addr) + TEST_ERROR + if (ma_size != (TEST_BLOCK_SIZE2048 - TEST_BLOCK_SIZE30)) + TEST_ERROR + + /* Allocate first block from sdata_aggr */ + stype = H5FD_MEM_DRAW; + saddr1 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if ((saddr1+TEST_BLOCK_SIZE30) != sdata_addr) + TEST_ERROR + + /* Allocate second block from sdata_aggr */ + saddr2 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)(TEST_BLOCK_SIZE2048 - TEST_BLOCK_SIZE30)); + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if (saddr2+(TEST_BLOCK_SIZE2048 - TEST_BLOCK_SIZE30) != sdata_addr) + TEST_ERROR + + /* Allocate third block from sdata_aggr */ + saddr3 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + + if ((saddr3+TEST_BLOCK_SIZE50) != sdata_addr) + TEST_ERROR + if(sdata_size != (TEST_BLOCK_SIZE2048 - TEST_BLOCK_SIZE50)) + TEST_ERROR + + /* Allocate second block of 2058, which is from file allocation, not from meta_aggr */ + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE2058); + + if (addr2 != sdata_addr) + TEST_ERROR + + /* sdata_aggr is reset 0 */ + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if ((sdata_addr != 0) && (sdata_size != 0)) + TEST_ERROR + + /* info is unchanged in meta_aggr */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + if ((new_ma_addr != ma_addr) && (new_ma_size != ma_size)) + TEST_ERROR + + /* Free all the allocated blocks */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr2, (hsize_t)TEST_BLOCK_SIZE2058); + H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr1, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr2, (hsize_t)TEST_BLOCK_SIZE2048 - TEST_BLOCK_SIZE30); + H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr3, (hsize_t)TEST_BLOCK_SIZE50); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != file_size) + TEST_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_aggr_alloc4() */ + +/* + * To verify that blocks are allocated from the aggregator + * + * Allocate first block (30) from meta_aggr: (nothing in the aggregator) + * request-size is > what is left in meta_aggr and < meta_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is obtained via file allocation + * The first block of 30 is allocate from there + * + * Allocate second block (50) from meta_aggr: + * request-size is < what is left in meta_aggr + * Result: + * The second block of 50 is allocated from what is left there + * There is space of 1968 left in the meta_aggr + * + * Allocate third block (1970) from meta_aggr: + * request-size is > what is left in meta_aggr and is < meta_aggr->alloc_size + * Result: A block of meta_aggr->alloc_size is extended via file allocation and is absorbed into the meta_aggr + * The block of 1970 is allocated from there + * There is space of 2046 left in meta_aggr + * + */ +static int +test_mf_aggr_alloc5(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size, new_file_size; /* File size */ + H5FD_mem_t type; + haddr_t addr1, addr2, addr3; + haddr_t ma_addr=HADDR_UNDEF, new_ma_addr=HADDR_UNDEF; + hsize_t ma_size=0, new_ma_size=0; + + TESTING("H5MF_alloc() of meta/sdata aggregator:test 5"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate first block from meta_aggr */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if ((addr1+TEST_BLOCK_SIZE30) != ma_addr) + TEST_ERROR + + /* Allocate second block from meta_aggr */ + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if (addr2+TEST_BLOCK_SIZE50 != ma_addr) + TEST_ERROR + if (ma_size != (TEST_BLOCK_SIZE2048 - (TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE50))) + TEST_ERROR + + /* Allocate third block from meta_aggr */ + addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1970); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + + if (addr3 != ma_addr) TEST_ERROR + if ((addr3+TEST_BLOCK_SIZE1970) != new_ma_addr) TEST_ERROR + if (new_ma_size != (TEST_BLOCK_SIZE2048 - (TEST_BLOCK_SIZE1970 - ma_size))) + TEST_ERROR + + /* Free all the allocated blocks */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr2, (hsize_t)TEST_BLOCK_SIZE50); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr3, (hsize_t)TEST_BLOCK_SIZE1970); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != file_size) + TEST_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_aggr_alloc5() */ + +/* + * To verify that blocks are allocated from the aggregator + * + * Allocate first block (30) from meta_aggr: (nothing in the aggregator) + * request-size is > what is left in meta_aggr and < meta_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is obtained via file allocation + * The first block of 30 is allocated from there + * + * Allocate second block (50) from meta_aggr: + * request-size is <= what is left in meta_aggr + * Result: + * The second block of 50 is allocated from what is left in meta_aggr + * There is space of 1968 left in meta_aggr + * + * Allocate first block (30) from sdata_aggr: (nothing in sdata_aggr) + * request-size is > what is left in sdata_aggr and is < sdata_aggr->alloc_size + * Result: + * A block of sdata_aggr->alloc_size is obtained via file allocation + * The first block of 30 is allocated from there + * There is space of 2018 left in sdata_aggr + * + * Allocate third block (1970) from meta_aggr: + * request-size is > what is left in meta_aggr and < meta_aggr->alloc_size + * sdata_aggr is at EOA but has not used up more than sdata_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is obtained via file allocation. + * The block does not adjoin meta_aggr + * sdata_aggr is untouched + * meta_aggr's unused space of [880, 1968] is freed to free-space + * meta_aggr is updated to point to the new block + */ +static int +test_mf_aggr_alloc6(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size, new_file_size; /* file size */ + H5FD_mem_t type, stype; + haddr_t addr1, addr2, addr3, saddr1; + haddr_t ma_addr=HADDR_UNDEF, new_ma_addr=HADDR_UNDEF, sdata_addr=HADDR_UNDEF; + hsize_t ma_size=0, new_ma_size=0, sdata_size=0; + frspace_state_t state; + + TESTING("H5MF_alloc() of meta/sdata aggregator:test 6"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate first block from meta_aggr */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if ((addr1+TEST_BLOCK_SIZE30) != ma_addr) + TEST_ERROR + + /* Allocate second block from meta_aggr */ + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if (addr2+TEST_BLOCK_SIZE50 != ma_addr) + TEST_ERROR + if (ma_size != (TEST_BLOCK_SIZE2048 - (TEST_BLOCK_SIZE30 + TEST_BLOCK_SIZE50))) + TEST_ERROR + + /* Allocate first block from sdata_aggr */ + stype = H5FD_MEM_DRAW; + saddr1 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if ((saddr1+TEST_BLOCK_SIZE30) != sdata_addr) TEST_ERROR + if (sdata_size != (TEST_BLOCK_SIZE2048 - TEST_BLOCK_SIZE30)) TEST_ERROR + + /* Allocate third block from meta_aggr */ + addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1970); + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + + if ((addr3+TEST_BLOCK_SIZE1970) != new_ma_addr) TEST_ERROR + if (addr3 != (sdata_addr+sdata_size)) TEST_ERROR + + if ((ma_addr+TEST_BLOCK_SIZE1970) == new_ma_addr) TEST_ERROR + if (new_ma_size != (TEST_BLOCK_SIZE2048 - TEST_BLOCK_SIZE1970)) + TEST_ERROR + + /* Verify that meta_aggr's unused space of 1968 is freed to free-space */ + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += (TEST_BLOCK_SIZE2048 - (TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE50)); + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Free all the allocated blocks */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr2, (hsize_t)TEST_BLOCK_SIZE50); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr3, (hsize_t)TEST_BLOCK_SIZE1970); + H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr1, (hsize_t)TEST_BLOCK_SIZE30); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (new_file_size != file_size) + TEST_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_aggr_alloc6() */ + +/* + * To verify that blocks are allocated from the aggregator + * + * Allocate first block (30) from meta_aggr: (nothing in meta_aggr) + * request-size is > what is left in meta_aggr and < meta_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is obtained via file allocation + * The first block of 30 is allocated from there + * + * Allocate second block (50) from meta_aggr: + * request-size is <= what is left in meta_aggr + * Result: + * The second block of 50 is allocated from what is left in the aggregator + * There is space of 1968 left in the meta_aggr + * + * Allocate first block (30) from sdata_aggr: (nothing in sdata_aggr) + * request-size is > what is left in sdata_aggr->size and < sdata_aggr->alloc_size + * Result: + * A block of sdata_aggr->alloc_size is obtained via file allocation + * The first block of 30 is allocate from there + * + * Allocate second block (2018) from sdata_aggr: + * request-size is <= what is left in sdata_aggr and is < sdata_aggr->alloc_size + * Result: + * The second block of 2018 is allocated from what is left in sdata_aggr (all used up) + * + * Allocate third block (50) from sdata_aggr: + * request-size is > what is left in sdata_aggr and < sdata_aggr->alloc_size + * Result: + * A block of sdata_aggr->alloc_size is extended via file allocation + * The third block of 50 is allocated from there + * + * Allocate third block (1970) from meta_aggr: + * request-size is > what is left in meta_aggr and is < meta_aggr->alloc_size + * sdata_aggr is at EOA and has used up more than sdata_aggr->alloc_size + * Result: + * unused space in sdata_aggr is freed to free-space and is shrunk + * sdata_aggr is reset to 0 + * A block of meta_aggr->alloc_size is obtained via file allocation + * The block does not adjoin meta_aggr + * meta_aggr's unused space of [880, 1968] is freed to free-space + * meta_aggr is updated to point to the new block + */ +static int +test_mf_aggr_alloc7(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t empty_size, file_size; + H5FD_mem_t type, stype; + haddr_t addr1, addr2, addr3, saddr1, saddr2, saddr3; + haddr_t ma_addr=HADDR_UNDEF, sdata_addr=HADDR_UNDEF; + hsize_t ma_size=0, sdata_size=0; + frspace_state_t state; + + TESTING("H5MF_alloc() of meta/sdata aggregator:test 7"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((empty_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate the first block from meta_aggr */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if ((addr1+TEST_BLOCK_SIZE30) != ma_addr) + TEST_ERROR + + /* Allocate the second block from meta_aggr */ + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if (addr2+TEST_BLOCK_SIZE50 != ma_addr) + TEST_ERROR + if (ma_size != (TEST_BLOCK_SIZE2048 - (TEST_BLOCK_SIZE30 + TEST_BLOCK_SIZE50))) + TEST_ERROR + + /* Allocate the first block from sdata_aggr */ + stype = H5FD_MEM_DRAW; + saddr1 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if ((saddr1+TEST_BLOCK_SIZE30) != sdata_addr) + TEST_ERROR + + /* Allocate the second block from sdata_aggr */ + saddr2 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE2048 - TEST_BLOCK_SIZE30); + + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if ((saddr2+(TEST_BLOCK_SIZE2048 - TEST_BLOCK_SIZE30)) != sdata_addr) + TEST_ERROR + if (sdata_size != 0) TEST_ERROR + + /* Allocate the third block from sdata_aggr */ + saddr3 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if ((saddr3+TEST_BLOCK_SIZE50) != sdata_addr) + TEST_ERROR + if (sdata_size != (TEST_BLOCK_SIZE2048 - TEST_BLOCK_SIZE50)) + TEST_ERROR + + /* Allocate the third block from meta_aggr */ + addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1970); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if (addr3 != sdata_addr) TEST_ERROR + if ((addr3 + TEST_BLOCK_SIZE1970) != ma_addr) TEST_ERROR + if (ma_size != (TEST_BLOCK_SIZE2048 - TEST_BLOCK_SIZE1970)) TEST_ERROR + + /* sdata_aggr info is reset to 0 */ + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if (sdata_addr != 0) TEST_ERROR + if (sdata_size != 0) TEST_ERROR + + /* Verify that meta_aggr's unused space of 1968 is freed to free-space */ + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += (TEST_BLOCK_SIZE2048 - (TEST_BLOCK_SIZE30 + TEST_BLOCK_SIZE50)); + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Free all the allocated blocks */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr2, (hsize_t)TEST_BLOCK_SIZE50); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr3, (hsize_t)TEST_BLOCK_SIZE1970); + H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr1, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr2, (hsize_t)(TEST_BLOCK_SIZE2048 - TEST_BLOCK_SIZE30)); + H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr3, (hsize_t)TEST_BLOCK_SIZE50); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Verify the file is the correct size */ + if (file_size != empty_size) + TEST_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_aggr_alloc7() */ + +/* + * To verify that a block can be extended from the aggregator + * + * Test 1: Allocate block A from meta_aggr which is at end of file + * Try to extend a block which adjoins the aggregator + * H5MF_try_extend() succeeds: meta_aggr is extended by extended-request and meta_aggr's info is updated + * + * Test 2: Allocate block A from meta_aggr + * Allocate block B from sdata_aggr so that meta_aggr is not at end of file + * Try to extend a block which adjoins meta_aggr and meta_aggr can fulfill the extended-request + * H5MF_try_extend() succeeds: the block is extended into the aggregator + * + * Test 3: Allocate block A from meta_aggr + * Allocate block B from sdata_aggr so that meta_aggr is not at end of file + * Try to extend a block which adjoins meta_aggr but meta_aggr cannot fulfill the extended-request + * H5MF_try_extend() fails + */ +static int +test_mf_aggr_extend(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t empty_size; + H5FD_mem_t type, stype; + haddr_t new_addr, addr, saddr; + haddr_t ma_addr=HADDR_UNDEF, new_ma_addr=HADDR_UNDEF, sdata_addr=HADDR_UNDEF; + hsize_t ma_size=0, new_ma_size=0, sdata_size=0; + htri_t extended; + + TESTING("H5MF_try_extend() of meta/sdata aggregator: test 1"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((empty_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate the first block from meta_aggr */ + type = H5FD_MEM_SUPER; + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if ((addr+TEST_BLOCK_SIZE30) != ma_addr) + TEST_ERROR + + /* Adjust meta_aggr's info info for testing */ + f->shared->meta_aggr.addr = addr; + f->shared->meta_aggr.size = f->shared->meta_aggr.alloc_size; + + new_addr = addr - 10; + + /* Try to extend the block */ + extended = H5MF_try_extend(f, H5P_DATASET_XFER_DEFAULT, type, (haddr_t)new_addr, (hsize_t)10, (hsize_t)(TEST_BLOCK_SIZE50)); + + /* should succeed */ + if(!extended) + TEST_ERROR + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + + if (new_ma_addr != (addr+TEST_BLOCK_SIZE50)) + TEST_ERROR + if (new_ma_size != f->shared->meta_aggr.alloc_size) TEST_ERROR + + /* Restore info for meta_aggr */ + f->shared->meta_aggr.addr = ma_addr; + f->shared->meta_aggr.size = ma_size; + + /* Free the allocated blocks */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, (ma_addr+ma_size), (hsize_t)TEST_BLOCK_SIZE50); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + TESTING("H5MF_try_extend() of meta/sdata aggregator: test 2"); + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate the first block from meta_aggr */ + type = H5FD_MEM_SUPER; + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if ((addr+TEST_BLOCK_SIZE30) != ma_addr) + TEST_ERROR + + /* Allocate the first block from sdata_aggr */ + stype = H5FD_MEM_DRAW; + saddr = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if ((saddr+TEST_BLOCK_SIZE50) != sdata_addr) + TEST_ERROR + + /* Adjust meta_aggr's info info for testing */ + f->shared->meta_aggr.addr = addr; + f->shared->meta_aggr.size = f->shared->meta_aggr.alloc_size; + + new_addr = addr - 10; + + /* should be able to fulfill request from the aggreqator itself */ + extended = H5MF_try_extend(f, H5P_DATASET_XFER_DEFAULT, type, (haddr_t)new_addr, (hsize_t)10, (hsize_t)(TEST_BLOCK_SIZE50)); + + if(!extended) + TEST_ERROR + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + + if (new_ma_addr != (addr+TEST_BLOCK_SIZE50)) + TEST_ERROR + if (new_ma_size != (f->shared->meta_aggr.alloc_size-TEST_BLOCK_SIZE50)) + TEST_ERROR + + /* Restore info for meta_aggr */ + f->shared->meta_aggr.addr = ma_addr; + f->shared->meta_aggr.size = ma_size; + + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr, (hsize_t)TEST_BLOCK_SIZE50); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + TESTING("H5MF_try_extend() of meta/sdata aggregator: test 3"); + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate first block from meta_aggr */ + type = H5FD_MEM_SUPER; + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if ((addr+TEST_BLOCK_SIZE30) != ma_addr) + TEST_ERROR + + /* Allocate first block from sdata_aggr */ + stype = H5FD_MEM_DRAW; + saddr = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if ((saddr+TEST_BLOCK_SIZE50) != sdata_addr) + TEST_ERROR + + /* Adjust meta_aggr's info info for testing */ + f->shared->meta_aggr.addr = addr; + f->shared->meta_aggr.size = 0; + + new_addr = addr - 10; + + /* unable to fulfill request from the aggreqator itself */ + extended = H5MF_try_extend(f, H5P_DATASET_XFER_DEFAULT, type, (haddr_t)new_addr, (hsize_t)10, (hsize_t)(TEST_BLOCK_SIZE50)); + + if(extended) + TEST_ERROR + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + + if (new_ma_addr != addr) TEST_ERROR + if (new_ma_size != 0) TEST_ERROR + + /* restore info for meta_aggr */ + f->shared->meta_aggr.addr = ma_addr; + f->shared->meta_aggr.size = ma_size; + + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr, (hsize_t)TEST_BLOCK_SIZE50); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_aggr_extend() */ + +/* + * To verify that a block is absorbed into an aggregator + * + * MF_try_shrink() only allows blocks to be absorbed into an aggregator + * + * Test 1: H5MF_alloc() block A from meta_aggr + * H5MF_try_shrink() block A should merge it back into meta_aggr + * since block A adjoins the beginning of meta_aggr + * + * Test 2: H5MF_alloc() block A from meta_aggr + * H5MF_alloc() block B from sdata_aggr + * H5MF_try_shrink() block B should merge it onto the end of meta_aggr + * because H5F_FS_MERGE_METADATA|H5F_FS_MERGE_RAWDATA is on for + * sec2 driver's FLMAP_SINGLE + * + * Test 3: H5MF_alloc() block A from meta_aggr + * H5MF_alloc() block B from meta_aggr + * H5MF_alloc() block C from meta_aggr + * H5MF_try_shrink() block B should fail since it does not adjoin the + * beginning nor the end of meta_aggr + */ +static int +test_mf_aggr_absorb(hid_t fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t empty_size; + H5FD_mem_t type, stype; + haddr_t addr1, addr2, addr3, saddr1; + haddr_t ma_addr=HADDR_UNDEF, new_ma_addr=HADDR_UNDEF; + haddr_t sdata_addr=HADDR_UNDEF, new_sdata_addr=HADDR_UNDEF; + hsize_t ma_size=0, new_ma_size=0; + hsize_t sdata_size=0, new_sdata_size=0; + htri_t status; + + TESTING("H5MF_try_shrink() of meta/sdata aggregator: test 1"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((empty_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate block A from meta_aggr */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + ma_addr = new_ma_addr - TEST_BLOCK_SIZE30; + + if ((addr1+TEST_BLOCK_SIZE30) != new_ma_addr) + TEST_ERROR + + /* should succeed */ + if ((status = H5MF_try_shrink(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30)) <= 0) + TEST_ERROR + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + + if (new_ma_addr != ma_addr) TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + TESTING("H5MF_try_shrink() of meta/sdata aggregator: test 2"); + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate block A from meta_aggr */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if ((addr1+TEST_BLOCK_SIZE30) != ma_addr) TEST_ERROR + if (ma_size != (TEST_BLOCK_SIZE2048 - TEST_BLOCK_SIZE30)) TEST_ERROR + + /* Allocate block B from sdata_aggr */ + stype = H5FD_MEM_DRAW; + saddr1 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + + /* should succeed */ + if ((status = H5MF_try_shrink(f, stype, H5P_DATASET_XFER_DEFAULT, saddr1, (hsize_t)TEST_BLOCK_SIZE50)) <= 0) + TEST_ERROR + + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &new_sdata_addr, &new_sdata_size); + if (new_sdata_addr != sdata_addr) TEST_ERROR + if (new_sdata_size != sdata_size) TEST_ERROR + + /* meta_aggr info should be updated because the block is absorbed into the meta_aggr */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + if (new_ma_addr != ma_addr) TEST_ERROR + if (new_ma_size != (ma_size+TEST_BLOCK_SIZE50)) TEST_ERROR + + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + TESTING("H5MF_try_shrink() of meta/sdata aggregator: test 3"); + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Allocate block A from meta_aggr */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if ((addr1+TEST_BLOCK_SIZE30) != ma_addr) + TEST_ERROR + + /* Allocate block B from meta_aggr */ + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if ((addr2+TEST_BLOCK_SIZE50) != ma_addr) + TEST_ERROR + + /* Allocate block C from meta_aggr */ + addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)(TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE50)); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if ((addr3+TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE50) != ma_addr) + TEST_ERROR + + /* should not succeed */ + if ((status = H5MF_try_shrink(f, type, H5P_DATASET_XFER_DEFAULT, addr2, (hsize_t)TEST_BLOCK_SIZE50)) > 0) + TEST_ERROR + + /* aggregator info should be the same as before */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + if (new_ma_addr != ma_addr) TEST_ERROR + + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr2, (hsize_t)TEST_BLOCK_SIZE50); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr3, (hsize_t)(TEST_BLOCK_SIZE30+TEST_BLOCK_SIZE50)); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_aggr_absorb() */ + +/* + * To verify that a block allocated from file allocation is aligned, can be shrunk and extended + * + * Alignment = 1024 or 4096 + * + * Test 1: + * Turn off using meta data aggregator + * Allocate a block of 30 which should be from file allocation + * Result: + * The return address should be aligned + * A fragment [800, 224] or [800, 3296] is freed to free-space + * EOA is 1054 or 4126 + * + * Allocate a block of 50 which should be from file allocation + * Result: + * The return address should be aligned + * A fragment [1054, 994] or [4126, 4066] is freed to free-space + * EOA is 2098 or 8242 + * Test 2: + * Turn off using meta data aggregator + * Allocate a block which should be from file allocation + * The return address should be aligned + * H5MF_try_shrink() the block with aligned address should succeed + * + * Test 3: + * Turn off using meta data aggregator + * Allocate a block which should be from file allocation + * The return address should be aligned + * H5MF_try_extend() the block with aligned address should succeed + */ +static int +test_mf_align_eoa(hid_t fapl, hid_t new_fapl) +{ + hid_t file = -1; /* File ID */ + hid_t fapl1; + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size, new_file_size; + H5FD_mem_t type; + haddr_t addr1, addr2; + haddr_t ma_addr=HADDR_UNDEF; + hsize_t ma_size=0; + htri_t status, extended; + frspace_state_t state; + hsize_t alignment=0, mis_align=0, tmp=0, accum=0; + + TESTING("H5MM_alloc() of file allocation with alignment: test 1"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Turn off using meta/small data aggregator */ + if((fapl1 = H5Pcopy(new_fapl)) < 0) TEST_ERROR + + H5Pset_meta_block_size(fapl1, (hsize_t)0); + H5Pset_small_data_block_size(fapl1, (hsize_t)0); + + /* Create the file to work on (without alignment) */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* get alignment setting */ + if(H5Pget_alignment(fapl1, NULL, &alignment) < 0) + TEST_ERROR + + /* Re-open the file with alignment and meta/sdata setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl1)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* calculate fragment for alignment of block 30 */ + if ((tmp = file_size % alignment)) + mis_align = alignment - tmp; + + accum = mis_align + TEST_BLOCK_SIZE30; + + /* Allocate a block of 30 from file allocation */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Verify that the allocated block is aligned */ + if (addr1 % alignment) TEST_ERROR + + /* there should be nothing in the aggregator */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if (ma_addr || ma_size) TEST_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + } + + /* calculate fragment for alignment of block 50 */ + mis_align = 0; + if ((tmp = (file_size + accum) % alignment)) + mis_align = alignment - tmp; + accum += (mis_align + TEST_BLOCK_SIZE50); + + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + /* Verify that the allocated block is aligned */ + if (addr2 % alignment) TEST_ERROR + + /* there should be nothing in the aggregator */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if (ma_addr || ma_size) TEST_ERROR + + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + } + + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr2, (hsize_t)TEST_BLOCK_SIZE50); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + if (new_file_size != file_size) + TEST_ERROR + + PASSED() + + TESTING("H5MF_try_shrink() of file allocation with alignment: test 2"); + + /* Re-open the file with alignment and meta/sdata setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl1)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* allocate a block of 50 from meta_aggr */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + /* address should be aligned */ + if (addr1 % alignment) TEST_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl1)) < 0) + FAIL_STACK_ERROR + + /* shrink the block */ + status = H5MF_try_shrink(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE50); + if (status <= 0) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + if (new_file_size != (file_size-TEST_BLOCK_SIZE50)) TEST_ERROR + + PASSED() + + TESTING("H5MF_try_extend() of file allocation with alignment: test 3"); + + /* Re-open the file with alignment and meta/sdata setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl1)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* allocate a block of 50 */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + /* address should be aligned */ + if (addr1 % alignment) TEST_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl1)) < 0) + FAIL_STACK_ERROR + + /* try to extend the block */ + extended = H5MF_try_extend(f, H5P_DATASET_XFER_DEFAULT, type, (haddr_t)addr1, (hsize_t)TEST_BLOCK_SIZE50, (hsize_t)TEST_BLOCK_SIZE30); + + if (extended <=0) TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + if((new_file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + if (new_file_size != (file_size+TEST_BLOCK_SIZE30)) TEST_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_align_eoa() */ + +/* + * To verify that a block allocated from the free-space manager is aligned + * + * Alignment = 1024 or 4096 + * + * Test 1: + * Add section A with an aligned address to free-space manager (addr=alignment, size=50) + * Allocate a block of size=50 + * The returned space's address should be same as section A's address + * + * Test 2: + * Add section A to free-space manager (addr=70, size=8000): + * section A is mis-aligned but the size is big enough for allocation with alignment + * Allocate a block of size=600 + * The returned space should be allocated from section A with an aligned address: + * address=alignment size=600 + * There will be 2 sections in free-space: (alignment = 1024 or alignment = 4096) + * the fragment left from aligning section A: [70, 954] or [70, 4026] + * the section left after allocating block A: [1624, 416] or [4696, 3374] + * H5MF_try_extend() the block of size 600 by 200 should succeed: + * the existing fragment left from aligning section A: [70, 954] or [70, 4026] + * the section left after extending block A: [1824, 216] or [4896, 3174] + * + * Test 3: + * Add section A to free-space manager (addr=70, size=700): + * section A is mis-aligned but the size is not big enough for allocation with alignment + * Allocate a block of size=40 + * The free-space manager is unable to fulfill the request + * The block is allocated from file allocation and should be aligned + */ +static int +test_mf_align_fs(hid_t fapl, hid_t new_fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + h5_stat_size_t file_size; + H5F_t *f = NULL; /* Internal file object pointer */ + H5FD_mem_t type; + H5MF_free_section_t *sect_node = NULL; + haddr_t addr; + frspace_state_t state; + H5MF_sect_ud_t udata; + htri_t extended; + hsize_t alignment=0, tmp=0, mis_align=0; + + TESTING("H5MF_alloc() of free-space manager with alignment: test 1"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* get alignment setting */ + if(H5Pget_alignment(new_fapl, NULL, &alignment) < 0) + TEST_ERROR + + /* Re-open the file with alignment setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + type = H5FD_MEM_SUPER; + if(H5MF_alloc_start(f, H5P_DATASET_XFER_DEFAULT, type, TRUE) < 0) + TEST_ERROR + if (f->shared->fs_state[type] != H5F_FS_STATE_OPEN) + TEST_ERROR + if (f->shared->fs_man[type]->client != H5FS_CLIENT_FILE_ID) + TEST_ERROR + + sect_node = H5MF_sect_simple_new((haddr_t)alignment, (hsize_t)TEST_BLOCK_SIZE50); + + /* Construct user data for callbacks */ + udata.f = f; + udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; + udata.alloc_type = type; + udata.allow_sect_absorb = TRUE; + + /* Add section A to free-space manager */ + if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &udata)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += TEST_BLOCK_SIZE50; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Allocate a block of 50 */ + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + /* Verify that the allocated block is section A in free-space */ + if (addr != (haddr_t)alignment) TEST_ERROR + if (addr % alignment) TEST_ERROR + + state.tot_space -= TEST_BLOCK_SIZE50; + state.tot_sect_count -= 1; + state.serial_sect_count -= 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Free the block to free-space */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)TEST_BLOCK_SIZE50); + + state.tot_space += TEST_BLOCK_SIZE50; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + TESTING("H5MF_alloc() of free-space manager with alignment: test 2"); + + + /* Re-open the file with alignment setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + type = H5FD_MEM_SUPER; + if(H5MF_alloc_start(f, H5P_DATASET_XFER_DEFAULT, type, TRUE) < 0) + TEST_ERROR + if (f->shared->fs_state[type] != H5F_FS_STATE_OPEN) + TEST_ERROR + if (f->shared->fs_man[type]->client != H5FS_CLIENT_FILE_ID) + TEST_ERROR + + sect_node = H5MF_sect_simple_new((haddr_t)TEST_BLOCK_ADDR70, (hsize_t)TEST_BLOCK_SIZE8000); + + /* Construct user data for callbacks */ + udata.f = f; + udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; + udata.alloc_type = type; + udata.allow_sect_absorb = TRUE; + + /* Add section A to free-space manager */ + if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &udata)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += TEST_BLOCK_SIZE8000; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Allocate a block of 600 */ + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE600); + + /* Verify that the allocated block is aligned */ + if (addr % alignment) TEST_ERROR + + /* should have 1 more section in free-space */ + state.tot_space -= TEST_BLOCK_SIZE600; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* try to extend the block */ + extended = H5MF_try_extend(f, H5P_DATASET_XFER_DEFAULT, type, (haddr_t)addr, (hsize_t)TEST_BLOCK_SIZE600, (hsize_t)TEST_BLOCK_SIZE200); + + if (extended <=0) TEST_ERROR + + /* space should be decreased by 200, # of sections remain the same */ + state.tot_space -= TEST_BLOCK_SIZE200; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* Free the block to free-space manager */ + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr, (hsize_t)(TEST_BLOCK_SIZE600+TEST_BLOCK_SIZE200)); + + /* only 1 section in free-space because of merging */ + state.tot_space += (TEST_BLOCK_SIZE600+TEST_BLOCK_SIZE200); + state.tot_sect_count = 1; + state.serial_sect_count = 1; + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + TESTING("H5MF_alloc() of free-space manager with alignment: test 3"); + + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file with alignment setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + type = H5FD_MEM_SUPER; + if(H5MF_alloc_start(f, H5P_DATASET_XFER_DEFAULT, type, TRUE) < 0) + TEST_ERROR + if (f->shared->fs_state[type] != H5F_FS_STATE_OPEN) + TEST_ERROR + if (f->shared->fs_man[type]->client != H5FS_CLIENT_FILE_ID) + TEST_ERROR + + sect_node = H5MF_sect_simple_new((haddr_t)TEST_BLOCK_ADDR70, (hsize_t)TEST_BLOCK_SIZE700); + + /* Construct user data for callbacks */ + udata.f = f; + udata.dxpl_id = H5P_DATASET_XFER_DEFAULT; + udata.alloc_type = type; + udata.allow_sect_absorb = TRUE; + + /* Add section A to free-space manager */ + if (H5FS_sect_add(f, H5P_DATASET_XFER_DEFAULT, f->shared->fs_man[type], (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &udata)) + FAIL_STACK_ERROR + + HDmemset(&state, 0, sizeof(frspace_state_t)); + state.tot_space += TEST_BLOCK_SIZE700; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + /* + * Allocate a block of 40 + * Since free-space manager cannot fulfull the request because of alignment, + * the block is obtained from file allocation + */ + addr = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)(TEST_BLOCK_SIZE40)); + + /* Verify that the allocated block is aligned */ + if (addr % alignment) + TEST_ERROR + + /* verify that the allocated block is from file allocation, not section A in free-space */ + if (!(addr >= (haddr_t)file_size)) TEST_ERROR + + /* calculate fragment for alignment of block 40 from file allocation */ + if ((tmp = file_size % alignment)) + mis_align = alignment - tmp; + + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + /* free-space info should be the same */ + if(check_stats(f->shared->fs_man[type], &state)) + 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_align_fs() */ + +/* + * To verify that blocks allocated from the aggregator are aligned + * + * Alignment = 1024 aggr->alloc_size = 2048 + * + * Allocate first block (30) from meta_aggr: (nothing in the aggregator) + * request-size > aggr->size and < aggr->alloc_size + * Result: + * An "aggr->alloc_size" block is allocated from file allocation for the aggregator + * EOA is 3072 + * The first block of 30 is allocated from the aggregator and should be aligned + * Fragment from alignment of file allocation is freed to free-space:[800, 224] + * There is space of 2018 left in meta_aggr + * + * Allocate second block (50) from meta_aggr: + * (request-size + fragment size) <= aggr->size + * Result: + * The second block of 50 is allocated from the aggregator and should be aligned + * Fragment from alignment of aggregator allocation is freed to free-space:[1054, 994] + * There is space of 974 left in meta_aggr + * + * Allocate third block (80) from meta_aggr: + * (request-size + fragment size) > aggr->size + * request-size < meta_aggr->alloc_size + * fragment size < (meta_aggr->alloc_size - request-size) + * meta_aggr is at EOA + * Result: + * A block of "meta_aggr->alloc_size" is extended from file allocation for meta_aggr + * EOA is 5120 + * The third block of 80 is allocated from the aggregator and should be aligned + * Fragment from alignment of aggregator allocation is freed to free-space:[2098, 974] + * There is space of 1968 left in meta_aggr + * + * Allocate fourth block (1970) from meta_aggr: + * (request-size + fragment size) is <= aggr->size + * fragment size > (aggr->alloc_size - request-size) + * meta_aggr is at EOA + * Result: + * A block of aggr->alloc_size + fragment size - (aggr->alloc_size - request-size)) + * is extended from file allocation for meta_aggr + * The third block of 1970 is allocated from the aggregator and should be aligned + * Fragment from alignment of aggregator allocation is freed to free-space:[3152, 944] + * There is space of 1968 left in meta_aggr + * EOA is at 8034 + * + * + * Alignment = 4096 aggr->alloc_size = 2048 + * + * Allocate first block (30) from meta_aggr: (aggregator is empty) + * request-size is > meta_aggr->size and < meta_aggr->alloc_size + * Result: + * A meta_aggr->alloc_size block is allocated from file allocation for the aggregator + * The first block of 30 is allocated from the aggregator and should be aligned + * Fragment from alignment of file allocation is freed to free-space:[800, 3296] + * There is space of 2018 left in meta_aggr + * EOA is at 6144 + * + * Allocate second block (50) from meta_aggr: + * (request-size + fragment size) is > meta_aggr->size + * request-size < meta_aggr->alloc_size + * fragment size > (meta_aggr->alloc_size - request-size) + * meta_aggr is at EOA + * Result: + * A block of meta_aggr->alloc_size + (fragment size - (meta_aggr->alloc_size - request-size)) + * is extended from file allocation for the aggregator + * The second block of 50 is allocated from the aggregator and should be aligned + * Fragment from alignment of aggregator allocation is freed to free-space:[4126, 4066] + * There is space of 2018 left in meta_aggr + * EOA is at 10260 + * + * Allocate third block (80) from meta_aggr: + * (request-size + fragment size) is > meta_aggr->size + * request-size < meta_aggr->alloc_size + * fragment size > (meta_aggr->alloc_size - request-size) + * meta_aggr is at EOA + * Result: + * A block of meta_aggr->alloc_size + (fragment size - (meta_aggr->alloc_size - request-size)) + * is extended from file allocation for the aggregator + * The third block of 80 is allocated from the aggregator and should be aligned + * Fragment from alignment of aggregator allocation is freed to free-space:[8242, 4046] + * There is space of 2018 left in meta_aggr + * EOA is at 14386 + * + * Allocate fourth block (1970) from meta_aggr: + * (request-size + fragment size) > meta_aggr->size + * request-size < meta_aggr->alloc_size + * fragment size > (meta_aggr->alloc_size - request-size) + * meta_aggr is at EOA + * Result: + * A block of meta_aggr->alloc_size + (fragment size - (meta_aggr->alloc_size - request-size)) + * is extended from file allocation for the aggregator + * The fourth block of 1970 is allocated from the aggregator and should be aligned + * Fragment from alignment of aggregator allocation is freed to free-space:[12368, 4016] + * There is space of 2018 left in meta_aggr + * EOA is at 20372 + */ +static int +test_mf_align_alloc1(hid_t fapl, hid_t new_fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size; /* File size */ + + H5FD_mem_t type; + haddr_t addr1, addr2, addr3, addr4; + frspace_state_t state; + haddr_t ma_addr=HADDR_UNDEF; + hsize_t ma_size=0, mis_align=0; + hsize_t alignment=0, tmp=0; + + + TESTING("H5MF_alloc() of meta/sdata aggregator with alignment: test 1"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on (without alignment) */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* get alignment setting */ + if(H5Pget_alignment(new_fapl, NULL, &alignment) < 0) + TEST_ERROR + + /* Re-open the file with alignment setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* calculate fragment for alignment of block 30 */ + if ((tmp = file_size % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 30 from meta_aggr */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Verify that the allocated block is aligned */ + if (addr1 % alignment) TEST_ERROR + + /* fragment for alignment of block 30 is freed to free-space */ + HDmemset(&state, 0, sizeof(frspace_state_t)); + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if ((addr1 + TEST_BLOCK_SIZE30) != ma_addr) + TEST_ERROR + + /* calculate fragment for alignment of block 50 */ + mis_align = 0; + if ((tmp = ma_addr % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 50 from meta_aggr */ + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + /* Verify that the allocated block is aligned */ + if (addr2 % alignment) TEST_ERROR + + /* fragment for alignment of block 50 is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if ((addr2 + TEST_BLOCK_SIZE50) != ma_addr) + TEST_ERROR + + /* calculate fragment for alignment of block 80 */ + mis_align = 0; + if ((tmp = ma_addr % alignment)) + mis_align = alignment - tmp; + + addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE80); + + /* Verify that the allocated block is aligned */ + if (addr3 % alignment) TEST_ERROR + + /* fragment for alignment of block 80 is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if ((addr3 + TEST_BLOCK_SIZE80) != ma_addr) + TEST_ERROR + + /* calculate fragment for alignment of block 1970 */ + mis_align = 0; + if ((tmp = ma_addr % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 1970 from meta_aggr */ + addr4 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1970); + + /* Verify that the allocated block is aligned */ + if (addr4 % alignment) TEST_ERROR + + /* fragment for alignment of block 1970 is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if ((addr4 + TEST_BLOCK_SIZE1970) != ma_addr) + TEST_ERROR + + /* Verify total size of free space after all the allocations */ + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr2, (hsize_t)TEST_BLOCK_SIZE50); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr3, (hsize_t)TEST_BLOCK_SIZE80); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr3, (hsize_t)TEST_BLOCK_SIZE1970); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_align_alloc1() */ + +/* + * To verify that blocks allocated from the aggregator are aligned + * + * Alignment = 1024 aggr->alloc_size = 2048 + * + * Allocate first block (30) from meta_aggr: (meta_aggr is empty) + * request-size is > meta_aggr->size and < meta_aggr->alloc_size + * Result: + * A meta_aggr->alloc_size block is allocated from file allocation for the aggregator + * The first block of 30 is allocated from the aggregator and should be aligned + * Fragment from alignment of file allocation is freed to free-space:[800, 224] + * There is space of 2018 left in meta_aggr + * EOA is 3072 + * + * Allocate second block (50) from meta_aggr: + * (request-size+fragment size) <= aggr->size + * Result: + * The second block of 50 is allocated from the aggregator and should be aligned + * Fragment from alignment of aggregator allocation is freed to free-space:[1054, 994] + * There is space of 974 left in meta_aggr + * + * Allocate first block (30) from sdata_aggr: (sdata_aggr is empty) + * request-size is > sdata_aggr->size and < sdata_aggr->alloc_size + * Result: + * A block of sdata_aggr->alloc_size is obtained via file allocation + * The first block of 30 is allocated from sdata_aggr and should be aligned + * EOA is 5120 + * + * Allocate third block (80) from meta_aggr: + * request-size+fragment size is > meta_aggr->size + * sdata_aggr is at EOA but has not used up more than sdata_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is allocated from file allocation + * The unused space in meta_aggr is freed to free-space [2098, 974] + * meta_aggr is updated to point to the new block + * The third block of 80 is allocated from meta_aggr and should be aligned + * EOA is 7168 + * + * Alignment = 4096 aggr->alloc_size = 2048 + * + * Allocate first block (30) from meta_aggr: (meta_aggr is empty) + * request-size is > aggr->size and < aggr->alloc_size + * Result: + * A meta_aggr->alloc_size block is allocated from file allocation for the aggregator + * The first block of 30 is allocated from the aggregator and should be aligned + * Fragment from alignment of file allocation is freed to free-space:[800, 3296] + * There is space of 2018 left meta_aggr + * EOA is at 6144 + * + * Allocate second block (50) from meta_aggr: + * (request-size + fragment size) > aggr->size + * request-size < aggr->alloc_size + * fragment size > (aggr->alloc_size - request-size) + * Result: + * A block of aggr->alloc_size + (fragment size - (aggr->alloc_size - request-size)) + * is extended from file allocation for the aggregator + * The second block of 50 is allocated from the aggregator and should be aligned + * Fragment from alignment of aggregator allocation is freed to free-space:[4126, 4066] + * There is space of 2018 left in meta_aggr + * EOA is at 10260 + * + * Allocate first block (30) from sdata_aggr: (sdata_aggr is empty) + * request-size is > sdata_aggr->size and < sdata_aggr->alloc_size + * meta_aggr is at EOA and has used up more than meta_aggr->alloc_size + * Result: + * The remaining space in meta_aggr is freed to free-space [8242, 2018] and shrunk since at EOF + * meta_aggr is reset to 0 + * A block of sdata_aggr->alloc_size is obtained via file allocation + * Fragment from alignment of file allocation is freed to free-space: [8242, 4046] + * The first block of 30 is allocated from sdata_aggr and should be aligned + * There is space of 2018 left in sdata_aggr + * EOA is 14336 + * + * Allocate third block (80) from meta_aggr: + * (request-size + fragment size) is > meta_aggr->size + * request-size < meta_aggr->alloc_size + * sdata_aggr is at EOA but has not used up more than sdata_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is allocated from file allocation for the aggregator + * Fragment from alignment of file allocation is freed to free-space:[14336, 2048] + * Since this fragment adjoins sdata_aggr and fulfills "absorb" condition, + * the space left in sdata_aggr is absorbed into the fragment and freed to free-space: [12318, 2018] + * other_aggr is reset to 0 + * The third block of 80 is allocated from the aggregator and should be aligned + * There is space of 1968 left in meta_aggr + * EOA is at 18432 + */ +static int +test_mf_align_alloc2(hid_t fapl, hid_t new_fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size; /* File size */ + H5FD_mem_t type, stype; + haddr_t addr1, addr2, addr3, saddr1; + frspace_state_t state; + haddr_t ma_addr=HADDR_UNDEF, sdata_addr=HADDR_UNDEF; + hsize_t ma_size=0, sdata_size=0, mis_align=0; + hsize_t alignment=0, tmp=0; + + TESTING("H5MF_alloc() of meta/sdata aggregator with alignment: test 2"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on (without alignment) */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* get alignment setting */ + if(H5Pget_alignment(new_fapl, NULL, &alignment) < 0) + TEST_ERROR + + /* Re-open the file with alignment setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* calculate fragment for alignment of block 30 */ + if ((tmp = file_size % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 30 from meta_aggr */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Verify that the allocated block is aligned */ + if (addr1 % alignment) TEST_ERROR + + /* fragment for alignment of block 30 is freed to free-space */ + HDmemset(&state, 0, sizeof(frspace_state_t)); + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if ((addr1 + TEST_BLOCK_SIZE30) != ma_addr) + TEST_ERROR + + /* fragment for alignment of block 50 is freed to free-space */ + mis_align = 0; + if ((tmp = ma_addr % alignment)) + mis_align = alignment - tmp; + + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + /* Verify that the allocated block is aligned */ + if (addr2 % alignment) TEST_ERROR + + /* fragment for alignment of block 50 is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if ((addr2 + TEST_BLOCK_SIZE50) != ma_addr) + TEST_ERROR + + /* + * Calculate fragment for alignment of block 30 in sdata_aggr: + * + * For alignment = 1024, alloc_size = 2048: + * block 30 is allocated from (ma_addr + ma_size), + * which is already aligned + * + * For alignment = 4096, alloc_size = 2048: + * since remaining space in meta_aggr is freed and shrunk, + * block 30 is allocated from ma_addr + */ + mis_align = 0; + if ((alignment == TEST_ALIGN1024) && (tmp = ((ma_addr + ma_size) % alignment))) + mis_align = alignment - tmp; + else if ((alignment == TEST_ALIGN4096) && (tmp = (ma_addr % alignment))) + mis_align = alignment - tmp; + + /* Allocate a block of 30 from sdata_aggr */ + stype = H5FD_MEM_DRAW; + saddr1 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* fragment for alignment of block 30 for sdata_aggr is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + /* Verify that the allocated block is aligned */ + if (saddr1 % alignment) TEST_ERROR + + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if (sdata_addr != (saddr1 + TEST_BLOCK_SIZE30)) TEST_ERROR + + /* + * Calculate fragment for the allocation of block 80 from meta_aggr: + * + * For alignment = 1024, alloc_size = 2048: + * fragment for unused space in meta_aggr is freed to free-space + * For alignment = 4096, alloc_size = 2048: + * fragment from alignment of file allocation absorbs sdata_aggr's remaining space + */ + mis_align = 0; + if ((alignment == TEST_ALIGN1024) && (tmp = (ma_addr % alignment))) + mis_align = alignment - tmp; + else if ((alignment == TEST_ALIGN4096) && (tmp = (sdata_addr % alignment))) + mis_align = alignment - tmp; + + /* Allocate a block of 80 from meta_aggr */ + addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE80); + + /* Verify that the allocated block is aligned */ + if (addr3 % alignment) TEST_ERROR + + /* fragment for alignment of block 80 is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if ((addr3 + TEST_BLOCK_SIZE80) != ma_addr) + TEST_ERROR + + /* Verify total size of free space after all the allocations */ + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr1, (hsize_t)TEST_BLOCK_SIZE30); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr2, (hsize_t)TEST_BLOCK_SIZE50); + H5MF_xfree(f, type, H5P_DATASET_XFER_DEFAULT, addr3, (hsize_t)TEST_BLOCK_SIZE80); + H5MF_xfree(f, stype, H5P_DATASET_XFER_DEFAULT, saddr1, (hsize_t)TEST_BLOCK_SIZE30); + + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_align_alloc2() */ + +/* + * To verify that blocks allocated from the aggregator are aligned + * + * Alignment = 1024 aggr->alloc_size = 2048 + * + * Allocate first block (30) from meta_aggr: (meta_aggr is empty) + * request-size is > meta_aggr->size and < meta_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is allocated from file allocation for the aggregator + * Fragment from alignment of file allocation is freed to free-space:[800, 224] + * The first block of 30 is allocated from the aggregator and should be aligned + * There is space of 2018 left in meta_aggr + * EOA is 3072 + * + * Allocate second block (50) from meta_aggr: + * (request-size+fragment size) is <= aggr->size + * Result: + * The second block of 50 is allocated from the aggregator and should be aligned + * Fragment from alignment of aggregator allocation is freed to free-space:[1054, 994] + * There is space of 974 left in the aggregator + * + * Allocate first block (30) from other_aggr: (nothing in other_aggr) + * request-size is > what is left in other_aggr->size and < other_aggr->alloc_size + * Result: + * A "other_aggr->alloc_size" block is allocated from file allocation for other_aggr + * The first block of 30 is allocated from other_aggr and should be aligned + * There is space of 2018 left in other_aggr->size + * EOA is 5120 + * + * Allocate second block (50) from sdata_aggr: + * (request-size+fragment size) < sdata_aggr->size + * Result: + * The second block of 50 is allocated from sdata_aggr and should be aligned + * Fragment from alignment of aggregator allocation is freed to free-space:[3102, 994] + * There is space of 974 left in sdata_aggr + * + * Allocate third block (80) from sdata_aggr: + * (request-size+fragment size) is >= sdata_aggr->size + * request-size < sdata_aggr->alloc_size + * sdata_aggr is at EOA + * Result: + * Another block of sdata_aggr->alloc_size is extended from file allocation for sdata_aggr + * The third block of 80 is allocated from sdata_aggr and should be aligned + * Fragment from alignment of aggregator allocation is freed to free-space:[4146, 974] + * There is space of 1968 left in sdata_aggr + * EOA is 7168 + * + * Allocate third block (1034) from meta_aggregator: + * (request-size + alignment) > meta_aggr->size but < meta_aggr->alloc_size + * sdata_aggr is at EOA and has used up more than sdata_aggr->alloc_size + * Result: + * The unused space in sdata_aggr is freed to free-space [5200, 1968] then shrunk + * sdata_aggr is reset to 0 + * A block of meta_aggr->alloc_size is allocated from file allocation + * Fragment from alignment of file allocation is freed to free-space [5200, 944] + * The unused space in meta_aggr is freed to free-space [2098, 974] + * The meta_aggr is updated to point to the new space + * The block of 1034 is allocated from the new block and should be aligned + * There is space of 1014 left in meta_aggr + * EOA is 8192 + * + * Alignment = 4096 aggr->alloc_size = 2048 + * + * Allocate first block (30) from meta_aggr: (meta_aggr is empty) + * request-size is > what is left in aggr->size and < aggr->alloc_size + * Result: + * A meta_aggr->alloc block is allocated from file allocation for the aggregator + * The first block of 30 is allocated from the aggregator and should be aligned + * Fragment from alignment of file allocation is freed to free-space:[800, 3296] + * There is space of 2018 left in meta_aggr + * EOA is at 6144 + * + * Allocate second block (50) from meta_aggr: + * (request-size + fragment size) is > what is left in aggr->size + * request-size < aggr->alloc_size + * fragment size > (aggr->alloc_size - request-size) + * Result: + * A block of aggr->alloc_size + (fragment size - (aggr->alloc_size - request-size)) + * is extended from file allocation for the aggregator + * The second block of 50 is allocated from the aggregator and should be aligned + * Fragment from alignment of aggregator allocation is freed to free-space:[4126, 4066] + * There is space of 2018 left in meta_aggr + * EOA is at 10260 + * + * Allocate first block (30) from sdata_aggr: (sdata_aggr is empty) + * request-size > sdata_aggr->size and < sdata_aggr->alloc_size + * meta_aggr is at EOA and has used up more than meta_aggr->alloc_size + * Result: + * The remaining space in meta_aggr is freed to free-space [8242, 2018] and shrunk + * since at EOF + * meta_aggr is reset to 0 + * A block of sdata_aggr->alloc_size is obtained via file allocation + * Fragment from alignment of file allocation is freed to free-space: [8242, 4046] + * The first block of 30 is allocated from sdata_aggr and should be aligned + * There is space of 2018 left in sdata_aggr + * EOA is 14336 + * + * Allocate second block (50) from sdata_aggr: + * request-size is > sdata_aggr->size + * request-size < sdata_aggr->alloc_size + * fragment size > (sdata_aggr->alloc_size - request-size) + * Result: + * A block of sdata_aggr->alloc_size + (fragment size - (sdata_aggr->alloc_size - request-size)) + * is extended from file allocation for the aggregator + * Fragment from alignment of aggregator allocation is freed to free-space:[12318, 4066] + * The second block of 50 is allocated from the aggregator and should be aligned + * There is space of 2018 left in the sdata_aggr + * EOA is at 18452 + * + * Allocate third block (80) from sdata_aggr: + * request-size + fragment size is > sdata_aggr->size + * request-size < sdata_aggr->alloc_size + * fragment size > (sdata_aggr->alloc_size - request-size) + * Result: + * A block of sdata_aggr->alloc_size + (fragment size - (sdata_aggr->alloc_size - request-size) + * is allocated from file allocation for the aggregator + * Fragment from alignment of aggregator allocation is freed to free-space:[16434, 4046] + * The third block of 80 is allocated from the aggregator and should be aligned + * There is space of 2018 left in the sdata_aggr + * EOA is at 22578 + * + * Allocate third block (1034) from meta_aggregator: + * (request-size + fragment size) is > meta_aggr->size but request-size < meta_aggr->alloc_size + * sdata_aggr is at EOA and has used up more than sdata_aggr->alloc_size + * Result: + * The remaining space in sdata_aggr is freed to free-space [20560, 2018] then shrunk + * sdata_aggr is reset to 0 + * There is nothing in meta_aggr + * A block of meta_aggr->alloc_size is allocated from file allocation + * Fragment from alignment of file allocation is freed to free-space [20560, 4016] + * EOA is 26624 + * The meta_aggr is updated to point to the new space + * The block of 1034 is allocated from the new block and should be aligned + * There is space of 1014 left in meta_aggr + */ +static int +test_mf_align_alloc3(hid_t fapl, hid_t new_fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size; + H5FD_mem_t type, stype; + haddr_t addr1, addr2, addr3; + haddr_t saddr1, saddr2, saddr3; + frspace_state_t state; + haddr_t ma_addr=HADDR_UNDEF, sdata_addr=HADDR_UNDEF; + hsize_t ma_size=0, sdata_size=0, mis_align=0; + hsize_t alignment=0, tmp=0; + + + TESTING("H5MF_alloc() of meta/sdata aggregator with alignment: test 3"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on (without alignment) */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* get alignment setting */ + if(H5Pget_alignment(new_fapl, NULL, &alignment) < 0) + TEST_ERROR + + /* Re-open the file with alignment setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* calculate fragment for alignment of block 30 */ + if ((tmp = file_size % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 30 from meta_aggr */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Verify that the allocated block is aligned */ + if (addr1 % alignment) TEST_ERROR + + /* fragment for alignment of block 30 is freed to free-space */ + HDmemset(&state, 0, sizeof(frspace_state_t)); + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if ((addr1 + TEST_BLOCK_SIZE30) != ma_addr) + TEST_ERROR + + /* calculate fragment for alignment of block 50 */ + mis_align = 0; + if ((tmp = ma_addr % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 50 from meta_aggr */ + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + /* Verify that the allocated block is aligned */ + if (addr2 % alignment) TEST_ERROR + + /* fragment for alignment of block 50 is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if ((addr2 + TEST_BLOCK_SIZE50) != ma_addr) + TEST_ERROR + + /* + * Calculate fragment for alignment of block 30 in sdata_aggr: + * + * For alignment = 1024, alloc_size = 2048: + * block 30 is allocated from (ma_addr + ma_size), + * which is already aligned + * + * For alignment = 4096, alloc_size = 2048: + * since remaining space in meta_aggr is freed and shrunk, + * block 30 is allocated from ma_addr + */ + mis_align = 0; + if ((alignment == TEST_ALIGN1024) && (tmp = ((ma_addr + ma_size) % alignment))) + mis_align = alignment - tmp; + else if ((alignment == TEST_ALIGN4096) && (tmp = ma_addr % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 30 from sdata_aggr */ + stype = H5FD_MEM_DRAW; + saddr1 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Verify that the allocated block is aligned */ + if (saddr1 % alignment) TEST_ERROR + + /* fragment for alignment of block 30 for sdata_aggr is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if (sdata_addr != (saddr1+TEST_BLOCK_SIZE30)) TEST_ERROR + + /* calculate fragment for alignment of block 50 in sdata_aggr */ + mis_align = 0; + if ((tmp = sdata_addr % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 50 from sdata_aggr */ + saddr2 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + /* Verify that the allocated block is aligned */ + if (saddr2 % alignment) TEST_ERROR + + /* fragment for alignment of block 50 for sdata_aggr is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if (sdata_addr != (saddr2 + TEST_BLOCK_SIZE50)) TEST_ERROR + + /* calculate fragment for alignment of block 80 in sdata_aggr */ + mis_align = 0; + if ((tmp = sdata_addr % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 80 from sdata_aggr */ + saddr3 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE80); + + /* Verify that the allocated block is aligned */ + if (saddr3 % alignment) TEST_ERROR + + /* fragment for alignment of block 80 for sdata_aggr is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if ((saddr3 + TEST_BLOCK_SIZE80) != sdata_addr) + TEST_ERROR + + /* calculate fragment for alignment of block 1034 */ + mis_align = 0; + if ((tmp = sdata_addr % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 1034 for meta_aggr */ + addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE1034); + + /* Verify that the allocated block is aligned */ + if (addr3 % alignment) TEST_ERROR + + /* fragment for alignment of block 1034 for meta_aggr is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + /* calculate unused space in meta_aggr that is freed to free-space after block 1034 */ + mis_align = 0; + if ((alignment == TEST_ALIGN1024) && (tmp = (ma_addr % alignment))) + mis_align = alignment - tmp; + + /* fragment for unused space in meta_aggr after block 1034 is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if ((addr3 + TEST_BLOCK_SIZE1034) != ma_addr) + TEST_ERROR + + /* Verify total size of free space after all allocations */ + if(check_stats(f->shared->fs_man[type], &state)) + 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_align_alloc3() */ + + +/* + * To verify that blocks allocated from the aggregator are aligned + * + * Alignment = 4096 aggr->alloc_size = 2048 + * + * Allocate first block (30) from meta_aggr: (meta_aggr is empty) + * request-size > meta_aggr->size and < meta_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is allocated from file allocation + * Fragment from alignment of file allocation is freed to free-space:[800, 224] + * The first block of 30 is allocated from meta_aggr and should be aligned + * There is space of 2018 left in meta_aggr + * EOA is 3072 + * + * Allocate second block (2058) from meta_aggr: + * (request-size+fragment) is > meta_aggr->size and request-size is > meta_aggr->alloc_size + * meta_aggr is at EOA + * Result: + * The second block of 2058 + fragment is extended and merged together with meta_aggr + * The block of 2058 is allocated out of the aggregator + * Fragment from alignment of aggregator allocation is freed to free-space:[1054, 994] + * There is space of 2018 (same as before) left in meta_aggr + * EOA is 6124 + * + * Allocate third block (5) from meta_aggr: + * request-size+fragment < meta_aggr->size + * Result: + * A block of 5 is allocated from the aggregator + * Fragment from alignment of aggregator allocation is freed to free-space:[4106, 1014] + * There is space of 999 left in meta_aggr + * + * Alignment = 4096 aggr->alloc_size = 2048 + * + * Allocate first block (30) from meta_aggr: (meta_aggr is empty) + * request-size is > meta_aggr->size and < meta_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is allocated from file allocation + * Fragment from alignment of file allocation is freed to free-space:[800, 3296] + * The first block of 30 is allocated from meta_aggr and should be aligned + * There is space of 2018 left in meta_aggr + * EOA is 6144 + * + * Allocate second block (2058) from meta_aggr: + * (request-size+fragment) is > meta_aggr->size and request-size is > meta_aggr->alloc_size + * meta_aggr is at EOA + * Result: + * The second block of 2058 + fragment is extended and merged together with meta_aggr + * The block of 2058 is allocated out of the aggregator + * Fragment from alignment of aggregator allocation is freed to free-space:[4126, 4066] + * There is space of 2018 (same as before) left in meta_aggr + * EOA is 12268 + * + * Allocate third block (5) from meta_aggr: + * request-size+fragment is > meta_aggr->size + * request-size < meta_aggr->alloc_size + * fragment < (meta_aggr->alloc_size - request-size) + * meta_aggr is at EOA + * Result: + * A block of meta_aggr->alloc_size is extended from file allocation for the aggregator + * A block of 5 is allocated from the aggregator + * Fragment from alignment of aggregator allocation is freed to free-space:[10250, 2038] + * There is space of 2023 left in meta_aggr + * + */ +static int +test_mf_align_alloc4(hid_t fapl, hid_t new_fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size; + H5FD_mem_t type; + haddr_t addr1, addr2, addr3; + frspace_state_t state; + haddr_t ma_addr=HADDR_UNDEF; + hsize_t ma_size=0, saved_ma_size=0; + hsize_t alignment=0, mis_align=0, tmp=0; + + + TESTING("H5MF_alloc() of meta/sdata aggregator with alignment: test 4"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on (without alignment) */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file with alignment setting and meta/sdata setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* get alignment setting */ + if(H5Pget_alignment(new_fapl, NULL, &alignment) < 0) + TEST_ERROR + + /* calculate fragment for alignment of block 30 */ + if ((tmp = file_size % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 30 from meta_aggr */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Verify that the allocated block is aligned */ + if (addr1 % alignment) TEST_ERROR + + /* fragment for alignment of block 30 is freed to free-space */ + HDmemset(&state, 0, sizeof(frspace_state_t)); + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + saved_ma_size = ma_size; + if ((addr1+TEST_BLOCK_SIZE30) != ma_addr) TEST_ERROR + + /* calculate fragment for alignment of block 2058 */ + mis_align = 0; + if ((tmp = ma_addr % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 2058 from meta_aggr */ + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE2058); + + /* Verify that the allocated block is aligned */ + if (addr2 % alignment) TEST_ERROR + + /* fragment for alignment of block 2058 is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if ((addr2 + TEST_BLOCK_SIZE2058) != ma_addr) TEST_ERROR + + /* meta_aggr->size remains the same */ + if (ma_size != saved_ma_size) TEST_ERROR + + /* calculate fragment for alignment of block 5 from meta_aggr */ + mis_align = 0; + if ((tmp = ma_addr % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 5 from meta_aggr */ + addr3 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE5); + + /* fragment for alignment of block 5 is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + /* Verify that the allocated block is aligned */ + if (addr3 % alignment) TEST_ERROR + + /* Verify total size of free space after all allocations */ + if(check_stats(f->shared->fs_man[type], &state)) + 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_align_alloc4() */ + +/* + * To verify that blocks allocated from the aggregator are aligned + * + * Alignment = 1024 aggr->alloc_size = 2048 + * + * Allocate first block (30) from meta_aggr: (meta_aggr is empty) + * request-size > meta_aggr->size and < meta_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is allocated from file allocation + * Fragment from alignment of file allocation is freed to free-space:[800, 224] + * The first block of 30 is allocated from meta_aggr and should be aligned + * There is space of 2018 left in meta_aggr + * EOA is 3072 + * + * Allocate first block (30) from sdata_aggr: (nothing in the aggregator) + * A block of sdata_aggr->alloc_size is allocated from file allocation + * The first block of 30 is allocated from the aggregator and should be aligned + * There is space of 2018 left in sdata_aggr + * EOA is 5120 + * + * Allocate second block (2058) from meta_aggr: + * (request-size + fragment size) > meta_aggr->size and > meta_aggr->alloc_size + * sdata_aggr is at EOA but has not used up sdata_aggr->alloc_size + * Result: + * A block of 2058 is allocated from file allocation + * EOA is 7178 + * Nothing is changed in meta_aggr and sdata_aggr + * + * Alignment = 4096 aggr->alloc_size = 2048 + * + * Allocate first block (30) from meta_aggr: (meta_aggr is empty) + * request-size is > meta_aggr->size and < meta_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is allocated from file allocation + * Fragment from alignment of file allocation is freed to free-space:[800, 3296] + * The first block of 30 is allocated from meta_aggr and should be aligned + * There is space of 2018 left in meta_aggr + * EOA is 6144 + * + * Allocate first block (30) from sdata_aggr: (meta_aggr is empty) + * meta_aggr is at EOA but has not used up more than meta_aggr->alloc_size + * Result: + * A block of sdata_aggr->alloc_size is allocated from file allocation + * Fragment from alignment of file allocation is freed to free-space:[6144, 2048] + * This fragment adjoins meta_aggr and fulfills "absorb" condition, + * the remaining space left in meta_aggr is absorbed into the fragment and + * freed to free-space: [4126, 2018] + * meta_aggr is reset to 0 + * The first block of 30 is allocated from the aggregator and should be aligned + * There is space of 2018 left in sdata_aggr + * EOA is 10240 + * + * Allocate second block (2058) from meta_aggr: + * request-size + fragment size is > meta_aggr->size + * request_size is > meta_aggr->alloc_size + * sdata_aggr is at EOA but has not used up more than sdata_aggr->alloc_size + * Result: + * A block of 2058 is allocated from file allocation + * Fragment from alignment of file allocation is freed to free-space:[10240, 2048] + * This fragment adjoins sdata_aggr and fulfills "absorb" condition, + * the remaining space left in sdata_aggr is absorbed into the fragment and + * freed to free-space: [8222, 2018] + * sdata_aggr is reset to 0 + * EOA is 14346 + * meta_aggr and sdata_aggr are all 0 + */ +static int +test_mf_align_alloc5(hid_t fapl, hid_t new_fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size; + H5FD_mem_t type, stype; + haddr_t addr1, addr2, saddr1; + frspace_state_t state; + haddr_t ma_addr=HADDR_UNDEF, new_ma_addr=HADDR_UNDEF; + haddr_t sdata_addr=HADDR_UNDEF, new_sdata_addr=HADDR_UNDEF; + hsize_t ma_size=0, new_ma_size=0, sdata_size=0, new_sdata_size=0; + hsize_t alignment=0, mis_align=0, tmp=0; + + + TESTING("H5MF_alloc() of meta/sdata aggregator with alignment: test 5"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on (without alignment) */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file with alignment setting and meta/sdata setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* get alignment setting */ + if(H5Pget_alignment(new_fapl, NULL, &alignment) < 0) + TEST_ERROR + + /* calculate fragment for alignment of block 30 */ + if ((tmp = file_size % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 30 from meta_aggr */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Verify that the allocated block is aligned */ + if (addr1 % alignment) TEST_ERROR + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + + if ((addr1 + TEST_BLOCK_SIZE30) != ma_addr) TEST_ERROR + + /* fragment for alignment of block 30 is freed to free-space */ + HDmemset(&state, 0, sizeof(frspace_state_t)); + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + /* calculate fragment for alignment of block 30 from sdata_aggr */ + mis_align = 0; + if ((alignment == TEST_ALIGN1024) && (tmp = (ma_addr + ma_size) % alignment)) + mis_align = alignment - tmp; + else if ((alignment == TEST_ALIGN4096) && (tmp = (ma_addr % alignment))) + mis_align = alignment - tmp; + + /* Allocate a block of 30 from sdata_aggr */ + stype = H5FD_MEM_DRAW; + saddr1 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Verify that the allocated block is aligned */ + if (saddr1 % alignment) TEST_ERROR + + /* fragment of alignment for block 30 in sdata_aggr is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if ((saddr1+TEST_BLOCK_SIZE30) != sdata_addr) TEST_ERROR + + /* calculate fragment for alignment of block 2058 from meta_aggr */ + mis_align = 0; + if ((alignment == TEST_ALIGN1024) && (tmp = (sdata_addr + sdata_size) % alignment)) + mis_align = alignment - tmp; + else if ((alignment == TEST_ALIGN4096) && (tmp = (sdata_addr % alignment))) + mis_align = alignment - tmp; + + /* Allocate a block of 2058 from meta_aggr */ + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE2058); + + /* Verify that the allocated block is aligned */ + if (addr2 % alignment) TEST_ERROR + + /* fragment for alignment of block 2058 is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + /* Verify total size of free space after all allocations */ + if(check_stats(f->shared->fs_man[type], &state)) + TEST_ERROR + + /* nothing is changed in meta_aggr */ + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + if (alignment == TEST_ALIGN1024 && (new_ma_addr != ma_addr || new_ma_size != ma_size)) + TEST_ERROR + else if (alignment == TEST_ALIGN4096 && (new_ma_addr != 0 || new_ma_size != 0)) + TEST_ERROR + + /* nothing is changed in sdata_aggr */ + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &new_sdata_addr, &new_sdata_size); + if (alignment == TEST_ALIGN1024 && (new_sdata_addr != sdata_addr || new_sdata_size != sdata_size)) + TEST_ERROR + else if (alignment == TEST_ALIGN4096 && ((new_sdata_addr != 0 || new_sdata_size != 0))) + 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_align_alloc5() */ + + +/* + * To verify that blocks allocated from the aggregator are aligned + * + * Alignment = 1024 aggr->alloc_size = 2048 + * + * Allocate first block (30) from meta_aggr: (meta_aggr is empty) + * request-size is > meta_aggr->size and < meta_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is allocated from file allocation + * Fragment from alignment of file allocation is freed to free-space:[800, 224] + * The first block of 30 is allocated from the aggregator and should be aligned + * There is space of 2018 left in meta_aggr->size + * EOA is 3072 + * + * Allocate first block (30) from sdata_aggr: (sdata_aggr is empty) + * request_size > sdata_aggr->size and < sdata_aggr->alloc_size + * Result: + * A block of sdata_aggr->alloc_size is allocated from file allocation + * The first block of 30 is allocated from the aggregator and should be aligned + * There is space of 2018 left in sdata_aggr + * EOA is 5120 + * + * Allocate second block (50) from sdata_aggr: + * (request-size+fragment size) <= sdata_aggr->size + * Result: + * The second block of 50 is allocated from sdata_aggr and should be aligned + * Fragment from alignment of aggregator allocation is freed to free-space:[3102, 994] + * There is space of 974 left in sdata_aggr + * + * Allocate third block (80) from sdata_aggr: + * (request-size+fragment size) > sdata_aggr->size + * request-size < sdata_aggr->alloc_size + * fragment size < (sdata_aggr->alloc_size - request-size) + * Result: + * Another block of sdata_aggr->alloc_size block is extended from file allocation + * for sdata_aggr + * The third block of 80 is allocated from sdata_aggr and should be aligned + * Fragment from alignment of aggregator allocation is freed to free-space:[4146, 974] + * There is space of 1968 left in sdata_aggr + * EOA is 7168 + * + * Allocate second block (2058) from meta_aggr: + * request-size + fragment size is > meta_aggr->size + * request-size is > meta_aggr->alloc_size + * sdata_aggr is at EOA and has used up more than sdata_aggr->alloc_size + * Result: + * The remaining space in sdata_aggr is freed to free-space and shrunk + * sdata_aggr is reset to 0 + * A block of 2058 is allocated from file allocation + * Fragment from alignment of file allocation is freed to free-space:[5200, 944] + * EOA is at 8202 + * meta_aggr is unchanged + * + * Alignment = 4096 aggr->alloc_size = 2048 + * + * Allocate first block (30) from meta_aggr: (meta_aggr is emtpy) + * request-size is > meta_aggr->size and < meta_aggr->alloc_size + * Result: + * A block of meta_aggr->alloc_size is allocated from file allocation + * Fragment from alignment of file allocation is freed to free-space:[800, 3296] + * The first block of 30 is allocated from the aggregator and should be aligned + * There is space of 2018 left in meta_aggr + * EOA is 6144 + * + * Allocate first block (30) from sdata_aggr: (sdata_aggr is empty) + * request_size > sdata_aggr->size and < sdata_aggr->alloc_size + * Result: + * A block of sdata_aggr->alloc_size is allocated from file allocation + * Fragment from alignment of file allocation is freed to free-space: [6144, 2048] + * This fragment adjoins meta_aggr and fulfills "absorb" condition, + * the remaining space left in meta_aggr is absorbed into the fragment and + * freed to free-space:[4126, 2018] + * meta_aggr is reset to 0 + * The first block of 30 is allocated from the aggregator and should be aligned + * There is space of 2018 left in sdata_aggr + * EOA is 5120 + * + * Allocate second block (50) from sdata_aggr: + * (request-size+fragment size) is <= sdata_aggr->size + * request-size < sdata_aggr->alloc_size + * fragment size > (sdata_aggr->alloc_size - request-size) + * Result: + * A block of sdata_aggr->alloc_size + (fragment size - (sdata_aggr->alloc_size - request-size)) + * is extended from file allocation for the aggregator + * The second block of 50 is allocated from sdata_aggr and should be aligned + * Fragment from alignment of aggregator allocation is freed to free-space:[8222, 4066] + * There is space of 2018 left in sdata_aggr + * EOA is at 14356 + * + * Allocate third block (80) from sdata_aggr: + * (request-size+fragment size) is > sdata_aggr->size + * request-size < sdata_aggr->alloc_size + * fragment size > (sdata_aggr->alloc_size - request-size) + * Result: + * A block of sdata_aggr->alloc_size+(fragment size-(sdata_aggr->alloc_size-request-size)) + * is extended from file allocation for sdata_aggr + * The third block of 80 is allocated from sdata_aggr and should be aligned + * Fragment from alignment of aggregator allocation is freed to free-space:[12338, 4046] + * There is space of 2018 left in sdata_aggr + * EOA is 18482 + * + * Allocate second block (2058) from meta_aggr: + * request-size + fragment size is > meta_aggr->size + * request-size is > meta_aggr->alloc_size + * sdata_aggr is at EOA and has used up more than sdata_aggr->alloc_size + * Result: + * The remaining space in sdata_aggr is freed to free-space and shrunk: [16464, 2018] + * sdata_aggr is reset to 0 + * A block of 2058 is allocated from file allocation + * Fragment from alignment of file allocation is freed to free-space:[16464, 4016] + * EOA is at 22538 + * meta_aggr is unchanged + */ +static int +test_mf_align_alloc6(hid_t fapl, hid_t new_fapl) +{ + hid_t file = -1; /* File ID */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + h5_stat_size_t file_size; + H5FD_mem_t type, stype; + haddr_t addr1, addr2; + haddr_t saddr1, saddr2, saddr3; + frspace_state_t state; + haddr_t ma_addr=HADDR_UNDEF, new_ma_addr=HADDR_UNDEF, sdata_addr=HADDR_UNDEF; + hsize_t ma_size=0, new_ma_size=0, sdata_size=0; + hsize_t alignment=0, mis_align=0, tmp=0; + + TESTING("H5MF_alloc() of meta/sdata aggregator with alignment: test 6"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on (without alignment) */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + + /* Close file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) < 0) + TEST_ERROR + + /* Re-open the file with alignment setting and meta/sdata setting */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* get alignment setting */ + if(H5Pget_alignment(new_fapl, NULL, &alignment) < 0) + TEST_ERROR + + /* calculate fragment for alignment of block 30 */ + if ((tmp = file_size % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 30 from meta_aggr */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Verify that the allocated block is aligned */ + if (addr1 % alignment) TEST_ERROR + + /* fragment for alignment of block 30 in meta_aggr is freed to free-space */ + HDmemset(&state, 0, sizeof(frspace_state_t)); + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size); + if ((addr1+TEST_BLOCK_SIZE30) != ma_addr) + TEST_ERROR + + /* calculate fragment for alignment of block 30 in sdata_aggr */ + mis_align = 0; + if ((alignment == TEST_ALIGN1024) && (tmp = (ma_addr + ma_size) % alignment)) + mis_align = alignment - tmp; + else if ((alignment == TEST_ALIGN4096) && (tmp = (ma_addr % alignment))) + mis_align = alignment - tmp; + + /* Allocate a block of 30 from sdata_aggr */ + stype = H5FD_MEM_DRAW; + saddr1 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE30); + + /* Verify that the allocated block is aligned */ + if (saddr1 % alignment) TEST_ERROR + + /* fragment for alignment of block 30 in sdata_aggr is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if (sdata_addr != (saddr1+TEST_BLOCK_SIZE30)) TEST_ERROR + + /* calculate fragment for alignment of block 50 in sdata_aggr */ + mis_align = 0; + if ((tmp = sdata_addr % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 50 from sdata_aggr */ + saddr2 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE50); + + /* Verify that the allocated block is aligned */ + if (saddr2 % alignment) TEST_ERROR + + /* fragment for alignment of block 50 in sdata_aggr is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if (sdata_addr != (saddr2+TEST_BLOCK_SIZE50)) TEST_ERROR + + /* calculate fragment for alignment of block 80 in sdata_aggr */ + mis_align = 0; + if ((tmp = sdata_addr % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 80 from sdata_aggr */ + saddr3 = H5MF_alloc(f, stype, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE80); + + /* Verify that the allocated block is aligned */ + if (saddr3 % alignment) TEST_ERROR + + /* fragment for alignment of block 80 in sdata_aggr is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + if (sdata_addr != (saddr3+TEST_BLOCK_SIZE80)) TEST_ERROR + + /* calculate fragment for alignment of block 2058 */ + /* remaining space in sdata_aggr is freed and shrunk */ + mis_align = 0; + if ((tmp = sdata_addr % alignment)) + mis_align = alignment - tmp; + + /* Allocate a block of 2058 from meta_aggr */ + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)TEST_BLOCK_SIZE2058); + + /* Verify that the allocated block is aligned */ + if (addr2 % alignment) TEST_ERROR + + /* fragment for alignment of block 2058 is freed to free-space */ + if (mis_align) { + state.tot_space += mis_align; + state.tot_sect_count += 1; + state.serial_sect_count += 1; + } + + H5MF_aggr_query(f, &(f->shared->meta_aggr), &new_ma_addr, &new_ma_size); + H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sdata_addr, &sdata_size); + + if (alignment == TEST_ALIGN1024 && (new_ma_addr != ma_addr || new_ma_size != ma_size)) + TEST_ERROR + else if (alignment == TEST_ALIGN4096 && (new_ma_addr != 0 || new_ma_size != 0)) + TEST_ERROR + + if (sdata_addr != 0 || sdata_size != 0) + TEST_ERROR + + if(check_stats(f->shared->fs_man[type], &state)) + 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_align_alloc6() */ + + +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; + + fapl = h5_fileaccess(); + 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 + + nerrors += test_mf_eoa(fapl); + nerrors += test_mf_eoa_shrink(fapl); + nerrors += test_mf_eoa_extend(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(fapl); + + /* interaction with meta/sdata aggregator */ + nerrors += test_mf_aggr_alloc1(fapl); + nerrors += test_mf_aggr_alloc2(fapl); + nerrors += test_mf_aggr_alloc3(fapl); + nerrors += test_mf_aggr_alloc4(fapl); + nerrors += test_mf_aggr_alloc5(fapl); + nerrors += test_mf_aggr_alloc6(fapl); + nerrors += test_mf_aggr_alloc7(fapl); + nerrors += test_mf_aggr_extend(fapl); + nerrors += test_mf_aggr_absorb(fapl); + + /* interaction with file allocation */ + nerrors += test_mf_eoa(fapl); + nerrors += test_mf_eoa_shrink(fapl); + nerrors += test_mf_eoa_extend(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(fapl); + + /* interaction with meta/sdata aggregator */ + nerrors += test_mf_aggr_alloc1(fapl); + nerrors += test_mf_aggr_alloc2(fapl); + nerrors += test_mf_aggr_alloc3(fapl); + nerrors += test_mf_aggr_alloc4(fapl); + nerrors += test_mf_aggr_alloc5(fapl); + nerrors += test_mf_aggr_alloc6(fapl); + nerrors += test_mf_aggr_alloc7(fapl); + nerrors += test_mf_aggr_extend(fapl); + nerrors += test_mf_aggr_absorb(fapl); + + /* + * tests for alignment + */ + + /* set meta/sdata block size = 2048 */ + if(H5Pset_meta_block_size(new_fapl, (hsize_t)TEST_BLOCK_SIZE2048) < 0) + TEST_ERROR + if(H5Pset_small_data_block_size(new_fapl, (hsize_t)TEST_BLOCK_SIZE2048) < 0) + TEST_ERROR + + 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; + } /* end switch */ + + nerrors += test_mf_align_eoa(fapl, new_fapl); + nerrors += test_mf_align_fs(fapl, new_fapl); + nerrors += test_mf_align_alloc1(fapl, new_fapl); + nerrors += test_mf_align_alloc2(fapl, new_fapl); + nerrors += test_mf_align_alloc3(fapl, new_fapl); + nerrors += test_mf_align_alloc4(fapl, new_fapl); + nerrors += test_mf_align_alloc5(fapl, new_fapl); + nerrors += test_mf_align_alloc6(fapl, new_fapl); + } + + if(nerrors) + goto error; + puts("All free-space manager tests for file memory passed."); + + h5_cleanup(FILENAME, fapl); + + return (0); + +error: + puts("*** TESTS FAILED ***"); + H5E_BEGIN_TRY { + H5Pclose(fapl); + } H5E_END_TRY; + return (1); +} /* main() */ diff --git a/test/objcopy.c b/test/objcopy.c index 653da96..86a0d30 100755 --- a/test/objcopy.c +++ b/test/objcopy.c @@ -325,7 +325,7 @@ attach_reg_ref_attr(hid_t file_id, hid_t loc_id) /* create reg_ref of point selection */ if(H5Sselect_none(space_id) < 0) TEST_ERROR - if(H5Sselect_elements(space_id, H5S_SELECT_SET, num_points, coord) < 0) TEST_ERROR + if(H5Sselect_elements(space_id, H5S_SELECT_SET, num_points, (const hsize_t *)coord) < 0) TEST_ERROR if(H5Rcreate(&ref[1], file_id, dsetnamev, H5R_DATASET_REGION, space_id) < 0) TEST_ERROR /* create reg_ref attribute */ @@ -408,7 +408,7 @@ create_reg_ref_dataset(hid_t file_id, hid_t loc_id) if(H5Sselect_hyperslab(space_id,H5S_SELECT_SET,start,NULL,count,NULL) < 0) TEST_ERROR if(H5Rcreate(&ref[0], file_id, dsetnamev, H5R_DATASET_REGION, space_id) < 0) TEST_ERROR if(H5Sselect_none(space_id) < 0) TEST_ERROR - if(H5Sselect_elements(space_id, H5S_SELECT_SET, num_points, coord) < 0) TEST_ERROR + if(H5Sselect_elements(space_id, H5S_SELECT_SET, num_points, (const hsize_t *)coord) < 0) TEST_ERROR if(H5Rcreate(&ref[1], file_id, dsetnamev, H5R_DATASET_REGION, space_id) < 0) TEST_ERROR if(H5Dwrite(dsetr_id, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT,ref) < 0) TEST_ERROR if(H5Dclose(dsetr_id) < 0) TEST_ERROR diff --git a/test/tfile.c b/test/tfile.c index ff8aa2b..b5f024c 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -1191,6 +1191,8 @@ static void test_file_freespace(void) { hid_t file; /* File opened with read-write permission */ + h5_stat_size_t empty_filesize; /* Size of file when empty */ + h5_stat_size_t mod_filesize; /* Size of file after being modified */ hssize_t free_space; /* Amount of free space in file */ hid_t dspace; /* Dataspace ID */ hid_t dset; /* Dataset ID */ @@ -1202,10 +1204,20 @@ test_file_freespace(void) /* Output message about test being performed */ MESSAGE(5, ("Testing Low-Level File Free Space\n")); - /* Create the file (with read-write permission) */ + /* Create an "empty" file */ file = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(file, FAIL, "H5Fcreate"); + ret = H5Fclose(file); + CHECK_I(ret, "H5Fclose"); + + /* Get the "empty" file size */ + empty_filesize = h5_get_file_size(FILE1); + + /* Re-open the file (with read-write permission) */ + file = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK_I(file, "H5Fopen"); + /* Check that the free space is 0 */ free_space = H5Fget_freespace(file); CHECK(free_space, FAIL, "H5Fget_freespace"); @@ -1244,7 +1256,7 @@ test_file_freespace(void) /* 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, 2376, "H5Fget_freespace"); + VERIFY(free_space, 2008, "H5Fget_freespace"); /* Delete datasets in file */ for(u = 0; u < 10; u++) { @@ -1261,6 +1273,12 @@ test_file_freespace(void) /* Close file */ ret = H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); + + /* Get the file size after modifications*/ + mod_filesize = h5_get_file_size(FILE1); + + /* Check that the file reverted to empty size */ + VERIFY(mod_filesize, empty_filesize, "H5Fget_freespace"); } /* end test_file_freespace() */ /**************************************************************** diff --git a/test/trefer.c b/test/trefer.c index f8e2287..bf9692f 100644 --- a/test/trefer.c +++ b/test/trefer.c @@ -407,7 +407,7 @@ test_reference_region(void) coord1[7][0] = 9; coord1[7][1] = 0; coord1[8][0] = 7; coord1[8][1] = 1; coord1[9][0] = 3; coord1[9][1] = 3; - ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, coord1); + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); CHECK(ret, FAIL, "H5Sselect_elements"); ret = (int)H5Sget_select_npoints(sid2); @@ -679,7 +679,7 @@ test_reference_region_1D(void) coord1[7][0] = 89; coord1[8][0] = 97; coord1[9][0] = 03; - ret = H5Sselect_elements(sid3, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, coord1); + ret = H5Sselect_elements(sid3, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); CHECK(ret, FAIL, "H5Sselect_elements"); ret = (int)H5Sget_select_npoints(sid3); @@ -1264,7 +1264,7 @@ test_reference_compat(void) coord1[7][0] = 9; coord1[7][1] = 0; coord1[8][0] = 7; coord1[8][1] = 1; coord1[9][0] = 3; coord1[9][1] = 3; - ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, coord1); + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); CHECK(ret, FAIL, "H5Sselect_elements"); /* Create second dataset region */ diff --git a/test/tselect.c b/test/tselect.c index 0ac5e60..6d8f1bd 100644 --- a/test/tselect.c +++ b/test/tselect.c @@ -447,7 +447,7 @@ test_select_point(hid_t xfer_plist) coord1[7][0]=1; coord1[7][1]= 0; coord1[7][2]= 4; coord1[8][0]=2; coord1[8][1]= 1; coord1[8][2]= 6; coord1[9][0]=0; coord1[9][1]= 3; coord1[9][2]= 8; - ret = H5Sselect_elements(sid1, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, coord1); + ret = H5Sselect_elements(sid1, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); CHECK(ret, FAIL, "H5Sselect_elements"); /* Verify correct elements selected */ @@ -472,7 +472,7 @@ test_select_point(hid_t xfer_plist) coord1[7][0]=1; coord1[7][1]=14; coord1[7][2]= 6; coord1[8][0]=2; coord1[8][1]= 2; coord1[8][2]= 5; coord1[9][0]=0; coord1[9][1]= 6; coord1[9][2]=13; - ret = H5Sselect_elements(sid1, H5S_SELECT_APPEND, (size_t)POINT1_NPOINTS, coord1); + ret = H5Sselect_elements(sid1, H5S_SELECT_APPEND, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); CHECK(ret, FAIL, "H5Sselect_elements"); /* Verify correct elements selected */ @@ -497,7 +497,7 @@ test_select_point(hid_t xfer_plist) coord2[7][0]=29; coord2[7][1]= 4; coord2[8][0]= 8; coord2[8][1]= 8; coord2[9][0]=19; coord2[9][1]=17; - ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, coord2); + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord2); CHECK(ret, FAIL, "H5Sselect_elements"); /* Verify correct elements selected */ @@ -526,7 +526,7 @@ test_select_point(hid_t xfer_plist) coord2[7][0]=12; coord2[7][1]= 2; coord2[8][0]=21; coord2[8][1]=12; coord2[9][0]= 9; coord2[9][1]=18; - ret = H5Sselect_elements(sid2, H5S_SELECT_PREPEND, (size_t)POINT1_NPOINTS, coord2); + ret = H5Sselect_elements(sid2, H5S_SELECT_PREPEND, (size_t)POINT1_NPOINTS, (const hsize_t *)coord2); CHECK(ret, FAIL, "H5Sselect_elements"); /* Verify correct elements selected */ @@ -568,7 +568,7 @@ test_select_point(hid_t xfer_plist) coord3[7][0]= 1; coord3[7][1]=22; coord3[8][0]=12; coord3[8][1]=21; coord3[9][0]=11; coord3[9][1]= 6; - ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, coord3); + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord3); CHECK(ret, FAIL, "H5Sselect_elements"); /* Verify correct elements selected */ @@ -592,7 +592,7 @@ test_select_point(hid_t xfer_plist) coord3[7][0]= 9; coord3[7][1]=16; coord3[8][0]=12; coord3[8][1]=22; coord3[9][0]=13; coord3[9][1]= 9; - ret = H5Sselect_elements(sid2, H5S_SELECT_APPEND, (size_t)POINT1_NPOINTS, coord3); + ret = H5Sselect_elements(sid2, H5S_SELECT_APPEND, (size_t)POINT1_NPOINTS, (const hsize_t *)coord3); CHECK(ret, FAIL, "H5Sselect_elements"); /* Verify correct elements selected */ @@ -945,7 +945,7 @@ test_select_combo(void) coord1[7][0]=1; coord1[7][1]= 0; coord1[7][2]= 4; coord1[8][0]=2; coord1[8][1]= 1; coord1[8][2]= 6; coord1[9][0]=0; coord1[9][1]= 3; coord1[9][2]= 8; - ret = H5Sselect_elements(sid1, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, coord1); + ret = H5Sselect_elements(sid1, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); CHECK(ret, FAIL, "H5Sselect_elements"); /* Select 1x10 hyperslab for writing memory dataset */ @@ -1780,7 +1780,7 @@ test_select_point_copy(void) coord1[7][0]=1; coord1[7][1]= 0; coord1[7][2]= 4; coord1[8][0]=2; coord1[8][1]= 1; coord1[8][2]= 6; coord1[9][0]=0; coord1[9][1]= 3; coord1[9][2]= 8; - ret = H5Sselect_elements(sid1, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, coord1); + ret = H5Sselect_elements(sid1, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); CHECK(ret, FAIL, "H5Sselect_elements"); /* Select sequence of ten points for write dataset */ @@ -1794,7 +1794,7 @@ test_select_point_copy(void) coord2[7][0]=29; coord2[7][1]= 4; coord2[8][0]= 8; coord2[8][1]= 8; coord2[9][0]=19; coord2[9][1]=17; - ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, coord2); + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord2); CHECK(ret, FAIL, "H5Sselect_elements"); /* Make a copy of the dataspace to write */ @@ -1838,7 +1838,7 @@ test_select_point_copy(void) coord3[7][0]= 1; coord3[7][1]=22; coord3[8][0]=12; coord3[8][1]=21; coord3[9][0]=11; coord3[9][1]= 6; - ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, coord3); + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord3); CHECK(ret, FAIL, "H5Sselect_elements"); /* Make a copy of the dataspace to read */ @@ -2227,7 +2227,7 @@ test_select_point_offset(void) coord1[7][0]=1; coord1[7][1]= 0; coord1[7][2]= 4; coord1[8][0]=2; coord1[8][1]= 1; coord1[8][2]= 6; coord1[9][0]=0; coord1[9][1]= 3; coord1[9][2]= 8; - ret = H5Sselect_elements(sid1, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, coord1); + ret = H5Sselect_elements(sid1, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); CHECK(ret, FAIL, "H5Sselect_elements"); /* Check a valid offset */ @@ -2262,7 +2262,7 @@ test_select_point_offset(void) coord2[7][0]=23; coord2[7][1]= 4; coord2[8][0]= 8; coord2[8][1]= 8; coord2[9][0]=19; coord2[9][1]=17; - ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, coord2); + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord2); CHECK(ret, FAIL, "H5Sselect_elements"); /* Choose a valid offset for the memory dataspace */ @@ -2298,7 +2298,7 @@ test_select_point_offset(void) coord3[7][0]= 1; coord3[7][1]=22; coord3[8][0]=12; coord3[8][1]=21; coord3[9][0]=11; coord3[9][1]= 6; - ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, coord3); + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord3); CHECK(ret, FAIL, "H5Sselect_elements"); /* Read selection from disk */ @@ -4248,7 +4248,7 @@ test_select_point_chunk(void) points[6][1]=1; points[7][0]=6; /* In same chunk as point #3, but "earlier" in chunk */ points[7][1]=6; - ret = H5Sselect_elements(pnt1_space, H5S_SELECT_SET, (size_t)SPACE7_NPOINTS, points); + ret = H5Sselect_elements(pnt1_space, H5S_SELECT_SET, (size_t)SPACE7_NPOINTS, (const hsize_t *)points); CHECK(ret, FAIL, "H5Sselect_elements"); /* Create 1st hyperslab selection */ @@ -4284,7 +4284,7 @@ test_select_point_chunk(void) points[6][1]=2; points[7][0]=7; /* In same chunk as point #3, but "earlier" in chunk */ points[7][1]=7; - ret = H5Sselect_elements(pnt2_space, H5S_SELECT_SET, (size_t)SPACE7_NPOINTS, points); + ret = H5Sselect_elements(pnt2_space, H5S_SELECT_SET, (size_t)SPACE7_NPOINTS, (const hsize_t *)points); CHECK(ret, FAIL, "H5Sselect_elements"); /* Create 2nd hyperslab selection */ @@ -5038,7 +5038,7 @@ test_select_fill_point(hssize_t *offset) CHECK(sid1, FAIL, "H5Screate_simple"); /* Select "point" selection */ - ret = H5Sselect_elements(sid1, H5S_SELECT_SET,num_points,points); + ret = H5Sselect_elements(sid1, H5S_SELECT_SET,num_points,(const hsize_t *)points); CHECK(ret, FAIL, "H5Sselect_elements"); if(offset!=NULL) { @@ -5576,7 +5576,7 @@ test_scalar_select(void) /* Select one element in memory with a point selection */ coord1[0]=0; coord1[1]= 2; - ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)1, &coord1); + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)1, (const hsize_t *)&coord1); CHECK(ret, FAIL, "H5Sselect_elements"); /* Write single point to disk */ @@ -5695,7 +5695,7 @@ test_scalar_select2(void) /* Select one element in memory with a point selection */ coord1[0]=0; H5E_BEGIN_TRY { - ret = H5Sselect_elements(sid, H5S_SELECT_SET, (size_t)1, &coord1); + ret = H5Sselect_elements(sid, H5S_SELECT_SET, (size_t)1, (const hsize_t *)&coord1); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Sselect_elements"); @@ -5763,7 +5763,7 @@ test_scalar_select3(void) /* Select one element in file with a point selection */ coord1[0] = 0; coord1[1] = 2; - ret = H5Sselect_elements(sid1, H5S_SELECT_SET, (size_t)1, &coord1); + ret = H5Sselect_elements(sid1, H5S_SELECT_SET, (size_t)1, (const hsize_t *)&coord1); CHECK(ret, FAIL, "H5Sselect_elements"); /* Write single point to disk */ @@ -5924,7 +5924,7 @@ test_shape_same(void) /* Select sequence of ten points for multiple point selection */ coord1[0][0] = 2; coord1[0][1] = 2; - ret = H5Sselect_elements(single_pt_sid, H5S_SELECT_SET, (size_t)1, coord1); + ret = H5Sselect_elements(single_pt_sid, H5S_SELECT_SET, (size_t)1, (const hsize_t *)coord1); CHECK(ret, FAIL, "H5Sselect_elements"); /* Create dataspace for multiple point selection */ @@ -5942,7 +5942,7 @@ test_shape_same(void) coord2[7][0]=1; coord2[7][1]=0; coord2[8][0]=5; coord2[8][1]=1; coord2[9][0]=9; coord2[9][1]=3; - ret = H5Sselect_elements(mult_pt_sid, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, coord2); + ret = H5Sselect_elements(mult_pt_sid, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord2); CHECK(ret, FAIL, "H5Sselect_elements"); /* Create dataspace for single hyperslab selection */ @@ -6623,7 +6623,7 @@ test_shape_same(void) for(v=0; v<2; v++) { coord2[v][0]=u; coord2[v][1]=(v*2)+2; } /* end for */ - ret = H5Sselect_elements(tmp_sid, H5S_SELECT_APPEND, (size_t)2, coord2); + ret = H5Sselect_elements(tmp_sid, H5S_SELECT_APPEND, (size_t)2, (const hsize_t *)coord2); CHECK(ret, FAIL, "H5Sselect_elements"); } /* end for */ @@ -7975,7 +7975,7 @@ test_select_bounds(void) coord[1][0]= 3; coord[1][1]= 96; coord[2][0]= 96; coord[2][1]= 3; coord[3][0]= 96; coord[3][1]= 96; - ret = H5Sselect_elements(sid, H5S_SELECT_SET, (size_t)SPACE11_NPOINTS, coord); + ret = H5Sselect_elements(sid, H5S_SELECT_SET, (size_t)SPACE11_NPOINTS, (const hsize_t *)coord); CHECK(ret, FAIL, "H5Sselect_elements"); /* Get bounds for point selection */ diff --git a/test/tskiplist.c b/test/tskiplist.c index 6f56c39..289df0b 100644 --- a/test/tskiplist.c +++ b/test/tskiplist.c @@ -1165,6 +1165,164 @@ test_skiplist_greater(void) /**************************************************************** ** +** test_skiplist_below(): Test H5SL (skip list) code. +** Tests 'below' operation in skip lists. +** +****************************************************************/ +static void +test_skiplist_below(void) +{ + H5SL_t *slist; /* Skip list created */ + H5SL_node_t *node; /* Skip list node */ + size_t u; /* Local index variable */ + unsigned data[10]={ 10, 20, 15, 5, 50, 30, 31, 32, 80, 90}; + /* unsigned sorted_data[10]={ 5, 10, 15, 20, 30, 31, 32, 50, 80, 90}; */ + unsigned *found_item; /* Item found in skip list */ + unsigned find_item; /* Item to add to skip list */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(7, ("Testing Skip List 'Less' Operation\n")); + + /* Create a skip list */ + slist = H5SL_create(H5SL_TYPE_UNSIGNED, 0.5, (size_t)16); + CHECK(slist, NULL, "H5SL_create"); + + /* Insert objects into the skip list */ + for(u = 0; u < 10; u++) { + ret = H5SL_insert(slist, &data[u], &data[u]); + CHECK(ret, FAIL, "H5SL_insert"); + } /* end for */ + + /* Check for exact match of items in various positions */ + find_item = 20; + node = H5SL_below(slist, &find_item); + CHECK(node, NULL, "H5SL_below"); + found_item = H5SL_item(node); + VERIFY(*found_item, find_item, "H5SL_below"); + find_item = 90; + node = H5SL_below(slist, &find_item); + CHECK(node, NULL, "H5SL_below"); + found_item = H5SL_item(node); + VERIFY(*found_item, find_item, "H5SL_below"); + find_item = 5; + node = H5SL_below(slist, &find_item); + CHECK(node, NULL, "H5SL_below"); + found_item = H5SL_item(node); + VERIFY(*found_item, find_item, "H5SL_below"); + + /* Find item less than a missing key, in various positions */ + find_item = 19; + node = H5SL_below(slist, &find_item); + CHECK(node, NULL, "H5SL_below"); + found_item = H5SL_item(node); + VERIFY(*found_item, 15, "H5SL_below"); + find_item = 89; + node = H5SL_below(slist, &find_item); + CHECK(node, NULL, "H5SL_below"); + found_item = H5SL_item(node); + VERIFY(*found_item, 80, "H5SL_below"); + find_item = 100; + node = H5SL_below(slist, &find_item); + CHECK(node, NULL, "H5SL_below"); + found_item = H5SL_item(node); + VERIFY(*found_item, 90, "H5SL_below"); + find_item = 9; + node = H5SL_below(slist, &find_item); + CHECK(node, NULL, "H5SL_below"); + found_item = H5SL_item(node); + VERIFY(*found_item, 5, "H5SL_below"); + find_item = 4; + node = H5SL_less(slist, &find_item); + VERIFY(node, NULL, "H5SL_below"); + + /* Close the skip list */ + ret = H5SL_close(slist); + CHECK(ret, FAIL, "H5SL_close"); + +} /* end test_skiplist_below() */ + +/**************************************************************** +** +** test_skiplist_above(): Test H5SL (skip list) code. +** Tests 'above' operation in skip lists. +** +****************************************************************/ +static void +test_skiplist_above(void) +{ + H5SL_t *slist; /* Skip list created */ + H5SL_node_t *node; /* Skip list node */ + size_t u; /* Local index variable */ + unsigned data[10]={ 10, 20, 15, 5, 50, 30, 31, 32, 80, 90}; + /* unsigned sorted_data[10]={ 5, 10, 15, 20, 30, 31, 32, 50, 80, 90}; */ + unsigned *found_item; /* Item found in skip list */ + unsigned find_item; /* Item to add to skip list */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(7, ("Testing Skip List 'Greater' Operation\n")); + + /* Create a skip list */ + slist = H5SL_create(H5SL_TYPE_UNSIGNED, 0.5, (size_t)16); + CHECK(slist, NULL, "H5SL_create"); + + /* Insert objects into the skip list */ + for(u = 0; u < 10; u++) { + ret = H5SL_insert(slist, &data[u], &data[u]); + CHECK(ret, FAIL, "H5SL_insert"); + } /* end for */ + + /* Check for exact match of items in various positions */ + find_item = 20; + node = H5SL_above(slist, &find_item); + CHECK(node, NULL, "H5SL_above"); + found_item = H5SL_item(node); + VERIFY(*found_item, find_item, "H5SL_above"); + find_item = 90; + node = H5SL_above(slist, &find_item); + CHECK(node, NULL, "H5SL_above"); + found_item = H5SL_item(node); + VERIFY(*found_item, find_item, "H5SL_above"); + find_item = 5; + node = H5SL_above(slist, &find_item); + CHECK(node, NULL, "H5SL_above"); + found_item = H5SL_item(node); + VERIFY(*found_item, find_item, "H5SL_above"); + + /* Find item greater than a missing key, in various positions */ + find_item = 19; + node = H5SL_above(slist, &find_item); + CHECK(node, NULL, "H5SL_above"); + found_item = H5SL_item(node); + VERIFY(*found_item, 20, "H5SL_above"); + find_item = 89; + node = H5SL_above(slist, &find_item); + CHECK(node, NULL, "H5SL_above"); + found_item = H5SL_item(node); + VERIFY(*found_item, 90, "H5SL_above"); + find_item = 100; + node = H5SL_above(slist, &find_item); + VERIFY(node, NULL, "H5SL_above"); + find_item = 6; + node = H5SL_above(slist, &find_item); + CHECK(node, NULL, "H5SL_above"); + found_item = H5SL_item(node); + VERIFY(*found_item, 10, "H5SL_above"); + find_item = 4; + node = H5SL_above(slist, &find_item); + CHECK(node, NULL, "H5SL_above"); + found_item = H5SL_item(node); + VERIFY(*found_item, 5, "H5SL_above"); + + /* Close the skip list */ + ret = H5SL_close(slist); + CHECK(ret, FAIL, "H5SL_close"); + +} /* end test_skiplist_above() */ + +/**************************************************************** +** ** test_skiplist_remote_first(): Test H5SL (skip list) code. ** Tests 'remove first' operation in skip lists. ** @@ -1240,7 +1398,9 @@ test_skiplist(void) test_skiplist_free(); /* Test 'free' operation */ test_skiplist_less(); /* Test 'less' operation */ test_skiplist_greater(); /* Test 'greater' operation */ - test_skiplist_remove_first(); /* Test 'remove first' operation */ + test_skiplist_below(); /* Test 'below' operation */ + test_skiplist_above(); /* Test 'above' operation */ + test_skiplist_remove_first(); /* Test 'remove first' operation */ } /* end test_skiplist() */ @@ -212,10 +212,11 @@ test_direct(void) if(H5Fget_filesize(file, &file_size) < 0) TEST_ERROR; - /* There is no garantee the size of metadata in file is constant. - * Just try to check if it's reasonable. It's 2KB right now. + /* There is no guarantee of the number of metadata allocations, but it's + * 4 currently and the size of the file should be between 3 & 4 file buffer + * sizes.. */ - if(file_size<1*KB || file_size>4*KB) + if(file_size < (FBSIZE * 3) || file_size >= (FBSIZE * 4)) TEST_ERROR; /* Allocate aligned memory for data set 1. For data set 1, everything is aligned including |