1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /*
15 * Purpose: Test Shared Object Header Messages
16 */
17
18 #include "testhdf5.h"
19
20 /*
21 * This file needs to access private information from the H5F package.
22 * This file also needs to access the file testing code.
23 */
24 #define H5F_FRIEND /* suppress error about including H5Fpkg */
25 #define H5F_TESTING
26 #include "H5Fpkg.h" /* File access */
27
28 /* Default SOHM values */
29 #define DEF_NUM_INDEXES 0
30 const unsigned def_type_flags[H5O_SHMESG_MAX_NINDEXES] = {0,0,0,0,0,0};
31 const unsigned def_minsizes[H5O_SHMESG_MAX_NINDEXES] = {250,250,250,250,250,250};
32 #define DEF_L2B 50
33 #define DEF_B2L 40
34
35 /* Non-default SOHM values for testing */
36 #define TEST_NUM_INDEXES 4
37 const unsigned test_type_flags[H5O_SHMESG_MAX_NINDEXES] =
38 {H5O_SHMESG_FILL_FLAG,
39 H5O_SHMESG_DTYPE_FLAG | H5O_SHMESG_ATTR_FLAG,
40 H5O_SHMESG_SDSPACE_FLAG,
41 H5O_SHMESG_PLINE_FLAG,
42 0, 0};
43 const unsigned test_minsizes[H5O_SHMESG_MAX_NINDEXES] = {0, 2, 40, 100, 3, 1000};
44 #define TEST_L2B 65
45 #define TEST_B2L 64
46
47 #define FILENAME "tsohm.h5"
48 #define FILENAME_SRC "tsohm_src.h5"
49 #define FILENAME_DST "tsohm_dst.h5"
50
51 #define NAME_BUF_SIZE 512
52
53 /* How much overhead counts as "not much" when converting B-trees, etc. */
54 #define OVERHEAD_ALLOWED 1.15F
55
56 #define NUM_DATASETS 10
57 #define NUM_ATTRIBUTES 100
58
59 typedef struct dtype1_struct {
60 int i1;
61 char str[10];
62 int i2;
63 int i3;
64 int i4;
65 int i5;
66 int i6;
67 int i7;
68 int i8;
69 float f1;
70 } dtype1_struct;
71
72 #define DTYPE2_SIZE 1024
73 const char *DSETNAME[] = {
74 "dataset0", "dataset1",
75 "dataset2", "dataset3",
76 "dataset4", "dataset5",
77 "dataset6", "dataset7",
78 "dataset8", "dataset9",
79 "dataset10", "dataset11",
80 NULL
81 };
82 const char *EXTRA_DSETNAME[] = {
83 "ex_dataset0", "ex_dataset1",
84 "ex_dataset2", "ex_dataset3",
85 "ex_dataset4", "ex_dataset5",
86 "ex_dataset6", "ex_dataset7",
87 "ex_dataset8", "ex_dataset9",
88 "ex_dataset10", "ex_dataset11",
89 "ex_dataset12", "ex_dataset13",
90 "ex_dataset14", "ex_dataset15",
91 "ex_dataset16", "ex_dataset17",
92 "ex_dataset18", "ex_dataset19",
93 NULL
94 };
95 #define SOHM_HELPER_NUM_EX_DSETS 20
96 typedef struct complex_t {
97 double re;
98 double im;
99 } complex_t;
100 #define ENUM_NUM_MEMBS 20
101 const char *ENUM_NAME[] = {
102 "enum_member0", "enum_member1",
103 "enum_member2", "enum_member3",
104 "enum_member4", "enum_member5",
105 "enum_member6", "enum_member7",
106 "enum_member8", "enum_member9",
107 "enum_member10", "enum_member11",
108 "enum_member12", "enum_member13",
109 "enum_member14", "enum_member15",
110 "enum_member16", "enum_member17",
111 "enum_member18", "enum_member19",
112 NULL
113 };
114 const int ENUM_VAL[] = {
115 0, 13,
116 -500, 63,
117 64, -64,
118 65, 2048,
119 1, 2,
120 -1, 7,
121 130, -5000,
122 630, 640,
123 -640, 650,
124 20480, 10,
125 -1001, -10
126 };
127 #define SIZE2_RANK1 6
128 #define SIZE2_RANK2 10
129 #define SIZE2_DIMS {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
130
131 #define LONG_STRING "00 index. A long string used for testing. To create new strings, set the first two characters to be some ASCII number other than 00, such as 01."
132
133 /* Struct returned from size2_helper function */
134 typedef struct size2_helper_struct {
135 h5_stat_size_t empty_size;
136 h5_stat_size_t first_dset;
137 h5_stat_size_t second_dset;
138 h5_stat_size_t dsets1;
139 h5_stat_size_t dsets2;
140 h5_stat_size_t interleaved;
141 h5_stat_size_t attrs1;
142 h5_stat_size_t attrs2;
143 } size2_helper_struct;
144
145 /* Number of distinct messages for the sohm_delete test */
146 #define DELETE_NUM_MESGS 7
147 #define HALF_DELETE_NUM_MESGS 3
148 #define DELETE_DIMS {1,1,1,1,1,1,1}
149 #define DELETE_MIN_MESG_SIZE 10
150 #define DELETE_MAX_MESG_SIZE 60
151
152
153 /* Number of dimensions in extend_dset test */
154 #define EXTEND_NDIMS 2
155
156 /* Dimensions for external_dtype test */
157 #define NX 10
158 #define NY 10
159
160 /* Helper function prototypes */
161 static hid_t make_dtype_1(void);
162 static hid_t make_dtype_2(void);
163 static hid_t close_reopen_file(hid_t file, const char* filename, hid_t fapl_id);
164 static void test_sohm_attrs(void);
165 #ifdef NOT_NOW
166 static void size2_dump_struct(const char *name, size2_helper_struct *sizes);
167 #endif /* NOT_NOW */
168 static void size2_verify(void);
169 static void test_sohm_delete(void);
170 static void test_sohm_delete_revert(void);
171 static void test_sohm_extlink(void);
172
173
174
175 /****************************************************************
176 **
177 ** verify_fcpl_values(): Verifies that FCPL is set as expected.
178 **
179 ****************************************************************/
180 static void
verify_fcpl_values(hid_t fcpl_id,const unsigned nindexes_expected,const unsigned * flags_expected,const unsigned * minsizes_expected,unsigned l2b,unsigned b2l)181 verify_fcpl_values(hid_t fcpl_id, const unsigned nindexes_expected, const unsigned *flags_expected, const unsigned *minsizes_expected, unsigned l2b, unsigned b2l)
182 {
183 unsigned nindexes_actual;
184 unsigned list_size;
185 unsigned btree_size;
186 unsigned x;
187 herr_t ret;
188
189 /* Number of indexes */
190 ret = H5Pget_shared_mesg_nindexes(fcpl_id, &nindexes_actual);
191 CHECK_I(ret, "H5Pget_shared_mesg_nindexes");
192 VERIFY(nindexes_actual, nindexes_expected, "H5Pget_shared_mesg_nindexes");
193
194 /* Index flags and minsizes */
195 for(x=0; x<nindexes_actual; ++x) {
196 unsigned flags_i;
197 unsigned min_mesg_size;
198 ret = H5Pget_shared_mesg_index(fcpl_id, x, &flags_i, &min_mesg_size);
199 CHECK_I(ret, "H5Pget_shared_mesg_index");
200 VERIFY(flags_i, flags_expected[x], "H5Pget_shared_mesg_index");
201 VERIFY(min_mesg_size, minsizes_expected[x], "H5Pget_shared_mesg_index");
202 }
203
204 /* List-to-btree and btree-to-list values */
205 ret = H5Pget_shared_mesg_phase_change(fcpl_id, &list_size, &btree_size);
206 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
207 VERIFY(list_size, l2b, "H5Pset_shared_mesg_phase_change");
208 VERIFY(btree_size, b2l, "H5Pset_shared_mesg_phase_change");
209 } /* verify_fcpl_values */
210
211
212 /****************************************************************
213 **
214 ** test_sohm_fcpl(): Test File Creation Property Lists.
215 **
216 ****************************************************************/
217 static void
test_sohm_fcpl(void)218 test_sohm_fcpl(void)
219 {
220 hid_t fid = -1;
221 hid_t fcpl_id = -1;
222 hid_t fcpl2_id = -1;
223 unsigned x;
224 herr_t ret;
225
226 MESSAGE(5, ("Testing File Creation Properties for Shared Messages\n"));
227
228 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
229 CHECK_I(fcpl_id, "H5Pcreate");
230
231 verify_fcpl_values(fcpl_id, DEF_NUM_INDEXES, def_type_flags, def_minsizes, DEF_L2B, DEF_B2L);
232
233 /* Create a file with this fcpl and make sure that all the values can be
234 * retrieved.
235 */
236 fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
237 CHECK_I(fid, "H5Fcreate");
238
239 fcpl2_id = H5Fget_create_plist(fid);
240 CHECK_I(fcpl2_id, "H5Fcreate");
241
242 verify_fcpl_values(fcpl2_id, DEF_NUM_INDEXES, def_type_flags, def_minsizes, DEF_L2B, DEF_B2L);
243
244 ret = H5Pclose(fcpl2_id);
245 CHECK_I(ret, "H5Pclose");
246
247 /* Close and re-open the file. Make sure that fcpl values are still
248 * correct.
249 */
250 ret = H5Fclose(fid);
251 CHECK_I(ret, "H5Fclose");
252 fid = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
253 CHECK_I(fid, "H5Fopen");
254
255 fcpl2_id = H5Fget_create_plist(fid);
256 CHECK_I(ret, "H5Fcreate");
257
258 verify_fcpl_values(fcpl2_id, DEF_NUM_INDEXES, def_type_flags, def_minsizes, DEF_L2B, DEF_B2L);
259
260 /* Clean up */
261 ret = H5Pclose(fcpl2_id);
262 CHECK_I(ret, "H5Pclose");
263 ret = H5Pclose(fcpl_id);
264 CHECK_I(ret, "H5Pclose");
265 ret = H5Fclose(fid);
266 CHECK_I(ret, "H5Fclose");
267
268
269 /* Start over with a non-default fcpl */
270 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
271 CHECK_I(fcpl_id, "H5Pcreate");
272
273 /* Set up index values */
274 ret = H5Pset_shared_mesg_nindexes(fcpl_id, TEST_NUM_INDEXES);
275 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
276 for(x = 0; x < TEST_NUM_INDEXES; ++x) {
277 ret = H5Pset_shared_mesg_index(fcpl_id, x, test_type_flags[x], test_minsizes[x]);
278 CHECK_I(ret, "H5Pset_shared_mesg_index");
279 } /* end for */
280
281 ret = H5Pset_shared_mesg_phase_change(fcpl_id, TEST_L2B, TEST_B2L);
282 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
283
284 verify_fcpl_values(fcpl_id, TEST_NUM_INDEXES, test_type_flags, test_minsizes, TEST_L2B, TEST_B2L);
285
286 /* Use the fcpl to create a file and get it back again */
287 fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
288 CHECK_I(fid, "H5Fcreate");
289 fcpl2_id = H5Fget_create_plist(fid);
290 CHECK_I(fcpl2_id, "H5Fcreate");
291
292 verify_fcpl_values(fcpl2_id, TEST_NUM_INDEXES, test_type_flags, test_minsizes, TEST_L2B, TEST_B2L);
293
294 ret = H5Pclose(fcpl2_id);
295 CHECK_I(ret, "H5Pclose");
296
297 /* Close and re-open the file. Make sure that fcpl values are still
298 * correct.
299 */
300 ret = H5Fclose(fid);
301 CHECK_I(ret, "H5Fclose");
302 fid = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
303 CHECK_I(fid, "H5Fopen");
304
305 fcpl2_id = H5Fget_create_plist(fid);
306 CHECK_I(ret, "H5Fcreate");
307
308 verify_fcpl_values(fcpl2_id, TEST_NUM_INDEXES, test_type_flags, test_minsizes, TEST_L2B, TEST_B2L);
309
310 /* Clean up */
311 ret = H5Pclose(fcpl2_id);
312 CHECK_I(ret, "H5Pclose");
313 ret = H5Fclose(fid);
314 CHECK_I(ret, "H5Fclose");
315
316 /* Actually, the list max can be exactly 1 greater than the
317 * btree min, but no more.
318 * Reset the second index.
319 */
320 ret = H5Pset_shared_mesg_index(fcpl_id, 1, test_type_flags[1], 15);
321 CHECK_I(ret, "H5Pset_shared_mesg_index");
322 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 10, 11);
323 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
324 fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
325 CHECK_I(fid, "H5Fcreate");
326 ret = H5Fclose(fid);
327 CHECK_I(ret, "H5Fclose");
328
329 /* Test edge cases:
330 * H5O_SHMESG_MAX_NINDEXES and H5O_SHMESG_MAX_LIST_SIZE should be valid
331 * values.
332 * Creating a file with uninitialized indexes should work. (TODO: not implemented?)
333 */
334 ret = H5Pset_shared_mesg_nindexes(fcpl_id, H5O_SHMESG_MAX_NINDEXES);
335 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
336 ret = H5Pset_shared_mesg_phase_change(fcpl_id, H5O_SHMESG_MAX_LIST_SIZE, H5O_SHMESG_MAX_LIST_SIZE);
337 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
338 fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
339 CHECK_I(fid, "H5Fcreate");
340
341 /* Clean up */
342 ret = H5Pclose(fcpl_id);
343 CHECK_I(ret, "H5Pclose");
344 ret = H5Fclose(fid);
345 CHECK_I(ret, "H5Fclose");
346 } /* test_sohm_fcpl */
347
348
349 /****************************************************************
350 **
351 ** test_sohm_fcpl_errors(): Test bogus FCPL settings for SOHMs
352 **
353 ****************************************************************/
354 static void
test_sohm_fcpl_errors(void)355 test_sohm_fcpl_errors(void)
356 {
357 hid_t fcpl_id = -1;
358 hid_t fid = -1;
359 unsigned x;
360 herr_t ret;
361
362 MESSAGE(5, ("Testing bogus file creation properties for shared messages\n"));
363
364 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
365 CHECK_I(fcpl_id, "H5Pcreate");
366
367 /* Set up index values */
368 ret = H5Pset_shared_mesg_nindexes(fcpl_id, TEST_NUM_INDEXES);
369 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
370 for(x = 0; x < TEST_NUM_INDEXES; ++x) {
371 ret = H5Pset_shared_mesg_index(fcpl_id, x, test_type_flags[x], test_minsizes[x]);
372 CHECK_I(ret, "H5Pset_shared_mesg_index");
373 }
374
375 ret = H5Pset_shared_mesg_phase_change(fcpl_id, TEST_L2B, TEST_B2L);
376 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
377
378 verify_fcpl_values(fcpl_id, TEST_NUM_INDEXES, test_type_flags, test_minsizes, TEST_L2B, TEST_B2L);
379
380 H5E_BEGIN_TRY {
381 /* Trying to create too many indexes should fail */
382 ret = H5Pset_shared_mesg_nindexes(fcpl_id, H5O_SHMESG_MAX_NINDEXES + 1);
383 VERIFY(ret, -1, "H5Pset_shared_mesg_nindexes");
384
385 /* Trying to set index to an index higher than the current number
386 * of indexes should fail.
387 */
388 ret = H5Pset_shared_mesg_index(fcpl_id, H5O_SHMESG_MAX_NINDEXES, 0, 15);
389 VERIFY(ret, -1, "H5Pset_shared_mesg_index");
390 ret = H5Pset_shared_mesg_index(fcpl_id, TEST_NUM_INDEXES, 0, 15);
391 VERIFY(ret, -1, "H5Pset_shared_mesg_index");
392
393 /* Setting an unknown flag (all flags + 1) should fail */
394 ret = H5Pset_shared_mesg_index(fcpl_id, 1, H5O_SHMESG_ALL_FLAG + 1, 15);
395 VERIFY(ret, -1, "H5Pset_shared_mesg_index");
396
397 /* Try setting two different indexes to hold fill messages. They
398 * should hold even very small messages for testing, even though we
399 * wouldn't really want to share such tiny messages in the real world.
400 */
401 ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_SHMESG_FILL_FLAG, 15);
402 CHECK_I(ret, "H5Pset_shared_mesg_index");
403 ret = H5Pset_shared_mesg_index(fcpl_id, 1, H5O_SHMESG_FILL_FLAG, 15);
404 CHECK_I(ret, "H5Pset_shared_mesg_index");
405 fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
406 VERIFY(fid, -1, "H5Fcreate");
407 ret = H5Pset_shared_mesg_index(fcpl_id, 1, H5O_SHMESG_DTYPE_FLAG | H5O_SHMESG_FILL_FLAG, 15);
408 CHECK_I(ret, "H5Pset_shared_mesg_index");
409 fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
410 VERIFY(fid, -1, "H5Fcreate");
411
412 /* Test list/btree cutoffs. We can set these to any positive value,
413 * but if the list max is less than the btree min we'll get an error
414 * when the file is created.
415 */
416 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 10, 12);
417 VERIFY(ret, -1, "H5Pset_shared_mesg_phase_change");
418 /* Setting them to extremely large values should also fail */
419 ret = H5Pset_shared_mesg_phase_change(fcpl_id, H5O_SHMESG_MAX_LIST_SIZE + 1, 0);
420 VERIFY(ret, -1, "H5Pset_shared_mesg_phase_change");
421 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 10, H5O_SHMESG_MAX_LIST_SIZE + 10);
422 VERIFY(ret, -1, "H5Pset_shared_mesg_phase_change");
423 ret = H5Pset_shared_mesg_phase_change(fcpl_id, H5O_SHMESG_MAX_LIST_SIZE, H5O_SHMESG_MAX_LIST_SIZE+1);
424 VERIFY(ret, -1, "H5Pset_shared_mesg_phase_change");
425 } H5E_END_TRY
426 } /* test_sohm_fcpl_errors */
427
428
429 /*-------------------------------------------------------------------------
430 * Function: make_dtype_1
431 *
432 * Purpose: Creates a complicated datatype for use in testing
433 * shared object header messages. The important thing is that
434 * the datatypes must take a lot of space to store on disk.
435 *
436 * Return: Success: datatype ID (should be closed by calling function)
437 * Failure: negative
438 *
439 * Programmer: James Laird
440 * Saturday, August 26, 2006
441 *
442 *-------------------------------------------------------------------------
443 */
444 static hid_t
make_dtype_1(void)445 make_dtype_1(void)
446 {
447 hid_t dtype1_id = -1;
448 hid_t str_id = -1;
449
450 /* Create compound datatype. */
451 if((dtype1_id = H5Tcreate(H5T_COMPOUND, sizeof(struct dtype1_struct))) < 0) TEST_ERROR
452
453 if(H5Tinsert(dtype1_id, "i1", HOFFSET(dtype1_struct, i1), H5T_NATIVE_INT) < 0) TEST_ERROR
454
455 str_id = H5Tcopy(H5T_C_S1);
456 if(H5Tset_size(str_id, (size_t)10) < 0) TEST_ERROR
457
458 if(H5Tinsert(dtype1_id, "string", HOFFSET(dtype1_struct, str), str_id) < 0) TEST_ERROR
459 if(H5Tinsert(dtype1_id, "i2", HOFFSET(dtype1_struct, i2), H5T_NATIVE_INT) < 0) TEST_ERROR
460 if(H5Tinsert(dtype1_id, "i3", HOFFSET(dtype1_struct, i3), H5T_NATIVE_INT) < 0) TEST_ERROR
461 if(H5Tinsert(dtype1_id, "i4", HOFFSET(dtype1_struct, i4), H5T_NATIVE_INT) < 0) TEST_ERROR
462 if(H5Tinsert(dtype1_id, "i5", HOFFSET(dtype1_struct, i5), H5T_NATIVE_INT) < 0) TEST_ERROR
463 if(H5Tinsert(dtype1_id, "i6", HOFFSET(dtype1_struct, i6), H5T_NATIVE_INT) < 0) TEST_ERROR
464 if(H5Tinsert(dtype1_id, "i7", HOFFSET(dtype1_struct, i7), H5T_NATIVE_INT) < 0) TEST_ERROR
465 if(H5Tinsert(dtype1_id, "i8", HOFFSET(dtype1_struct, i8), H5T_NATIVE_INT) < 0) TEST_ERROR
466 if(H5Tinsert(dtype1_id, "f1", HOFFSET(dtype1_struct, f1), H5T_NATIVE_FLOAT) < 0) TEST_ERROR
467
468 if(H5Tclose(str_id) < 0) TEST_ERROR
469
470 return dtype1_id;
471
472 error:
473 H5E_BEGIN_TRY {
474 H5Tclose(str_id);
475 H5Tclose(dtype1_id);
476 } H5E_END_TRY
477 return -1;
478 } /* make_dtype1 */
479
480
481 /*-------------------------------------------------------------------------
482 * Function: make_dtype_2
483 *
484 * Purpose: Creates complicated datatypes for use in testing
485 * shared object header messages. The important thing is that
486 * the datatypes must take a lot of space to store on disk.
487 *
488 * Return: Success: datatype ID (should be closed by calling function)
489 * Failure: negative
490 *
491 * Programmer: James Laird
492 * Saturday, August 26, 2006
493 *
494 * Modifications:
495 *
496 *-------------------------------------------------------------------------
497 */
498 static hid_t
make_dtype_2(void)499 make_dtype_2(void)
500 {
501 hid_t dtype2_id = -1;
502 hid_t enum_id= -1;
503 hid_t int_id=-1;
504 int x;
505 hsize_t dims[] = {2, 1, 2, 4};
506 size_t size;
507
508 /* Create an int with a strange precision */
509 if((int_id = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
510 if(H5Tset_precision(int_id, (size_t)24) < 0) TEST_ERROR
511
512 /* Create an enumeration using that int */
513 if((enum_id = H5Tenum_create(int_id)) < 0) TEST_ERROR
514
515 for(x = 0; x < ENUM_NUM_MEMBS; x++)
516 if(H5Tenum_insert(enum_id, ENUM_NAME[x], &ENUM_VAL[x]) < 0) TEST_ERROR
517
518 /* Create arrays of arrays of arrays of enums */
519 if((dtype2_id = H5Tarray_create2(enum_id, 3, dims)) < 0) TEST_ERROR
520 if((dtype2_id = H5Tarray_create2(dtype2_id, 4, dims)) < 0) TEST_ERROR
521 if((dtype2_id = H5Tarray_create2(dtype2_id, 2, dims)) < 0) TEST_ERROR
522 if((dtype2_id = H5Tarray_create2(dtype2_id, 1, dims)) < 0) TEST_ERROR
523
524 if(H5Tclose(enum_id) < 0) TEST_ERROR
525 if(H5Tclose(int_id) < 0) TEST_ERROR
526
527 /* Check the datatype size. If this is different than the #defined
528 * size then the fills values will have the wrong size.
529 */
530 size = H5Tget_size(dtype2_id);
531 if(size != DTYPE2_SIZE) TEST_ERROR
532
533 return dtype2_id;
534
535 error:
536 H5E_BEGIN_TRY {
537 H5Tclose(dtype2_id);
538 H5Tclose(enum_id);
539 H5Tclose(int_id);
540 } H5E_END_TRY
541 return -1;
542 } /* make_dtype2 */
543
544
545 /*-------------------------------------------------------------------------
546 * Function: close_reopen_file
547 *
548 * Purpose: Closes a file and then reopens it. Used to ensure that
549 * SOHMs are written to and read from disk
550 *
551 * Return: Success: new hid_t for the file
552 * Failure: Negative
553 *
554 * Programmer: James Laird
555 * Wednesday, October 4, 2006
556 *
557 * Modifications:
558 *
559 *-------------------------------------------------------------------------
560 */
561 static hid_t
close_reopen_file(hid_t file,const char * filename,hid_t fapl_id)562 close_reopen_file(hid_t file, const char* filename, hid_t fapl_id)
563 {
564 if (H5Fclose(file) < 0)
565 FAIL_STACK_ERROR
566 file = H5Fopen(filename, H5F_ACC_RDWR, fapl_id);
567 if (file < 0)
568 FAIL_STACK_ERROR
569 return(file);
570
571 error:
572 return -1;
573 } /* close_reopen_file */
574
575
576 /*-------------------------------------------------------------------------
577 * Function: size1_helper
578 *
579 * Purpose: Creates object headers that use a large datatype message.
580 *
581 * Set test_file_closing to TRUE to add file closing and reopening
582 * whenever possible (to test that SOHMs are written correctly
583 * on disk and not just in memory).
584 *
585 * Return: Success: file ID (may not be the same one passed in)
586 * Failure: H5I_INVALID_HID
587 *
588 * Programmer: James Laird
589 * Monday, April 10, 2006
590 *
591 *-------------------------------------------------------------------------
592 */
593 static hid_t
size1_helper(hid_t file,const char * filename,hid_t fapl_id,hbool_t test_file_closing)594 size1_helper(hid_t file, const char *filename, hid_t fapl_id, hbool_t test_file_closing)
595 {
596 dtype1_struct wdata;
597 dtype1_struct rdata;
598 hid_t dtype1_id = H5I_INVALID_HID;
599 hid_t space_id = H5I_INVALID_HID;
600 hid_t dset_id = H5I_INVALID_HID;
601 hsize_t dim1[1];
602 int x;
603
604 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
605 * Macro: TSOHM_S1H_VERIFY_DATA
606 *
607 * Purpose: Encapsulate a common pattern:
608 * Reads the dataset and verifies that [a subset of] the data
609 * are as expected.
610 *
611 * Programmer: Jacob Smith
612 * 2018 November 1
613 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
614 */
615 #define TSOHM_S1H_VERIFY_DATA(dset_id, dtype_id) \
616 { \
617 HDmemset(&rdata, 0, sizeof(rdata)); \
618 if (0 > H5Dread((dset_id), (dtype_id), H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata)) { \
619 H5_FAILED(); AT(); \
620 HDprintf("Can't read data\n"); \
621 goto error; \
622 } \
623 if ((rdata.i1 != wdata.i1) || (rdata.i2 != wdata.i2) || HDstrcmp(rdata.str, wdata.str)) { \
624 H5_FAILED(); AT(); \
625 HDprintf("incorrect read data\n"); \
626 goto error; \
627 } \
628 } /* TSOHM_S1H_VERIFY_DATA() definition */
629
630 /* Closing and re-opening the file takes a long time on systems without
631 * local disks. Don't close and reopen if express testing is enabled.
632 */
633 if(GetTestExpress() > 1)
634 test_file_closing = FALSE;
635
636 /* Intialize wdata */
637 HDmemset(&wdata, 0, sizeof(wdata));
638 wdata.i1 = 11;
639 HDstrcpy(wdata.str, "string");
640 wdata.i2 = 22;
641 wdata.i3 = 33;
642 wdata.i4 = 44;
643 wdata.i5 = 55;
644 wdata.i6 = 66;
645 wdata.i7 = 77;
646 wdata.i8 = 88;
647 wdata.f1 = 0.0F;
648
649 /* Intialize rdata */
650 HDmemset(&rdata, 0, sizeof(rdata));
651
652 dtype1_id = make_dtype_1();
653 if(dtype1_id < 0) TEST_ERROR
654
655 dim1[0] = 1;
656 space_id = H5Screate_simple(1, dim1, NULL);
657 if(space_id < 0) TEST_ERROR
658
659 dset_id = H5Dcreate2(file, DSETNAME[0], dtype1_id, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
660 if(dset_id < 0) FAIL_STACK_ERROR
661
662 /* Test writing and reading */
663 if(H5Dwrite(dset_id, dtype1_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wdata) < 0) FAIL_STACK_ERROR
664 TSOHM_S1H_VERIFY_DATA(dset_id, dtype1_id)
665 if(H5Dclose(dset_id) < 0) FAIL_STACK_ERROR
666
667 if(test_file_closing)
668 if((file = close_reopen_file(file, filename, fapl_id)) < 0) TEST_ERROR
669
670 /* Create 3 more datasets with the same datatype/dataspace */
671 for (x = 1; x < 4; x++) {
672 dset_id = H5Dcreate2(file, DSETNAME[x], dtype1_id, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
673 if (0 > dset_id) FAIL_STACK_ERROR
674 if (x == 3)
675 if(H5Dwrite(dset_id, dtype1_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wdata) < 0) TEST_ERROR
676 if (H5Dclose(dset_id) < 0) FAIL_STACK_ERROR
677
678 if (test_file_closing)
679 if((file = close_reopen_file(file, filename, fapl_id)) < 0) TEST_ERROR
680 }
681
682 if(H5Tclose(dtype1_id) < 0) TEST_ERROR
683
684 /* Make sure the data has been written successfully */
685 dset_id = H5Dopen2(file, DSETNAME[0], H5P_DEFAULT);
686 if(dset_id < 0) TEST_ERROR
687 dtype1_id = H5Dget_type(dset_id);
688 if(dtype1_id < 0) TEST_ERROR
689 TSOHM_S1H_VERIFY_DATA(dset_id, dtype1_id)
690
691 if(H5Dclose(dset_id) < 0) TEST_ERROR
692
693 /* Create several copies of the dataset
694 * this increases the amount of space saved by sharing the datatype message
695 */
696 for(x = 0; x < SOHM_HELPER_NUM_EX_DSETS; x++) {
697 dset_id = H5Dcreate2(file, EXTRA_DSETNAME[x], dtype1_id, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
698 if(dset_id < 0) TEST_ERROR
699 if(H5Dclose(dset_id) < 0) TEST_ERROR
700
701 if(test_file_closing)
702 if((file = close_reopen_file(file, filename, fapl_id)) < 0) TEST_ERROR
703 }
704
705 if(H5Tclose(dtype1_id) < 0) TEST_ERROR
706 if(H5Sclose(space_id) < 0) TEST_ERROR
707
708 /* Ensure that we can still read data back from dataset 3 */
709 dset_id = H5Dopen2(file, DSETNAME[3], H5P_DEFAULT);
710 if(dset_id < 0) TEST_ERROR
711 dtype1_id = H5Dget_type(dset_id);
712 if(dtype1_id < 0) TEST_ERROR
713 TSOHM_S1H_VERIFY_DATA(dset_id, dtype1_id)
714
715 if(H5Dclose(dset_id) < 0) TEST_ERROR
716 if(H5Tclose(dtype1_id) < 0) TEST_ERROR
717
718 return file;
719
720 error:
721 H5E_BEGIN_TRY {
722 H5Sclose(space_id);
723 H5Tclose(dtype1_id);
724 H5Dclose(dset_id);
725 H5Fclose(file);
726 } H5E_END_TRY
727
728 return H5I_INVALID_HID;
729 #undef TSOHM_S1H_VERIFY_DATA /* macro is exclusive to this function */
730 } /* size1_helper */
731
732
733 /*----------------------------------------------------------------------------
734 * Function: getsize_testsize1
735 *
736 * Purpose: Creates a test file, populates it, and returns its file size.
737 * Oject header information from the "first" dataset in the file
738 * is stored in pointer `oinfo`.
739 *
740 * Programmer: Jacob Smith
741 * 2018 November 1
742 *----------------------------------------------------------------------------
743 */
744 static h5_stat_size_t
getsize_testsize1(const char * filename,hid_t fcpl_id,hid_t fapl_id,hbool_t test_file_closing,H5O_info_t * oinfo)745 getsize_testsize1(const char *filename, hid_t fcpl_id, hid_t fapl_id,
746 hbool_t test_file_closing, H5O_info_t *oinfo)
747 {
748 hid_t fid = H5I_INVALID_HID;
749 herr_t ret;
750
751 fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl_id, fapl_id);
752 CHECK(fid, H5I_INVALID_HID, "H5Fcreate");
753
754 /* If test_file_closing is TRUE, you will get back a different ID,
755 * which will need to be closed. The helper will close your passed-in
756 * ID.
757 */
758 fid = size1_helper(fid, filename, fapl_id, test_file_closing);
759 CHECK(fid, H5I_INVALID_HID, "size1_helper");
760
761 ret = H5Oget_info_by_name2(fid, DSETNAME[0], oinfo, H5O_INFO_HDR, H5P_DEFAULT);
762 CHECK(ret, FAIL, "H5Oget_info_by_name");
763
764 ret = H5Fclose(fid);
765 CHECK(ret, FAIL, "H5Fclose");
766
767 return h5_get_file_size(filename, fapl_id);
768 } /* getsize_testsize1() */
769
770
771 /*-------------------------------------------------------------------------
772 * Function: test_sohm_size1
773 *
774 * Purpose: Tests shared object header messages with a large datatype
775 *
776 * Programmer: James Laird
777 * Monday, April 10, 2006
778 *
779 *-------------------------------------------------------------------------
780 */
781 static void
test_sohm_size1(void)782 test_sohm_size1(void)
783 {
784 hid_t file = -1;
785 hid_t fcpl_id = -1;
786 hid_t fapl_id = -1;
787
788 unsigned use_shared = 0;
789 unsigned use_btree = 0;
790 h5_stat_size_t file_sizes[9];
791 unsigned size_index = 0;
792 hsize_t oh_sizes[3];
793 unsigned oh_size_index = 0;
794
795 #if 0 /* TBD: lying comment or bug. See Jira HDFFV-10646 */
796 hsize_t norm_oh_size;
797 #endif /* Jira HDFFV-10646 */
798 hsize_t sohm_oh_size;
799 hsize_t sohm_btree_oh_size;
800 h5_stat_size_t norm_empty_filesize;
801 h5_stat_size_t sohm_empty_filesize;
802 h5_stat_size_t sohm_btree_empty_filesize;
803 h5_stat_size_t norm_final_filesize;
804 h5_stat_size_t sohm_final_filesize;
805 h5_stat_size_t sohm_btree_final_filesize;
806 h5_stat_size_t norm_final_filesize2;
807 h5_stat_size_t sohm_final_filesize2;
808 h5_stat_size_t sohm_btree_final_filesize2;
809
810 H5O_info_t oinfo;
811 unsigned num_indexes = 1;
812 unsigned index_flags = H5O_SHMESG_DTYPE_FLAG;
813 unsigned min_mesg_size = 50;
814 unsigned list_max = 11;
815 unsigned btree_min = 10;
816 herr_t ret;
817
818 MESSAGE(5, ("Testing that shared datatypes save space\n"));
819
820 /* Create a FAPL with "semi" close degree, to detect dangling IDs */
821 fapl_id = H5Pcreate(H5P_FILE_ACCESS);
822 CHECK_I(fapl_id, "H5Pcreate");
823 ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI);
824 CHECK_I(ret, "H5Pset_fclose_degree");
825
826 /* ----------------------------------------
827 * Run operations, accumulating file sizes to compare later.
828 */
829
830 for (use_shared = 0; use_shared < 2; use_shared++) {
831 for (use_btree = 0; use_btree < 2; use_btree++) {
832 hbool_t test_open_close;
833
834 /* cannot use btree indexing without shared messages; skip case */
835 if (use_btree && !use_shared)
836 continue;
837
838 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
839 CHECK_I(fcpl_id, "H5Pcreate");
840
841 if (use_shared) {
842 /* Tests one index holding only datatype messages */
843 ret = H5Pset_shared_mesg_nindexes(fcpl_id, num_indexes);
844 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
845 ret = H5Pset_shared_mesg_index(fcpl_id, 0, index_flags, min_mesg_size);
846 CHECK_I(ret, "H5Pset_shared_mesg_index");
847
848 if (use_btree) {
849 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 0, 0);
850 } else {
851 ret = H5Pset_shared_mesg_phase_change(fcpl_id, list_max, btree_min);
852 }
853 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
854 } else {
855 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 0);
856 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
857 }
858
859 file = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, fapl_id);
860 CHECK_I(file, "H5Fcreate");
861 ret = H5Fclose(file);
862 CHECK_I(ret, "H5Fclose");
863
864 /* size of empty file */
865 file_sizes[size_index++] = h5_get_file_size(FILENAME, fapl_id);
866
867 /* size of populated file, with different populating behaviors */
868 test_open_close = TRUE;
869 file_sizes[size_index++] = getsize_testsize1(FILENAME, fcpl_id, fapl_id, test_open_close, &oinfo);
870 test_open_close = FALSE;
871 file_sizes[size_index++] = getsize_testsize1(FILENAME, fcpl_id, fapl_id, test_open_close, &oinfo);
872 oh_sizes[oh_size_index++] = oinfo.hdr.space.total;
873
874 ret = H5Pclose(fcpl_id);
875 CHECK_I(ret, "H5Pclose");
876 } /* for btree/listed messages */
877 } /* for normal/shared messages */
878
879 ret = H5Pclose(fapl_id);
880 CHECK_I(ret, "H5Pclose");
881
882 /* sanity-check state of arrays */
883 VERIFY(9, size_index, "size_index");
884 VERIFY(3, oh_size_index, "oh_size_index");
885
886 /* ----------------------------------------
887 * Check that all sizes make sense.
888 */
889
890 /* Put result sizes into human-readable symbolic names.
891 * Order dependent on loop execution above.
892 */
893 norm_empty_filesize = file_sizes[0];
894 norm_final_filesize = file_sizes[1];
895 norm_final_filesize2 = file_sizes[2];
896 #if 0 /* TBD: lying comment or bug. See Jira HDFFV-10646 */
897 norm_oh_size = oh_sizes[0];
898 #endif /* Jira HDFFV-10646 */
899
900 sohm_empty_filesize = file_sizes[3];
901 sohm_final_filesize = file_sizes[4];
902 sohm_final_filesize2 = file_sizes[5];
903 sohm_oh_size = oh_sizes[1];
904
905 sohm_btree_empty_filesize = file_sizes[6];
906 sohm_btree_final_filesize = file_sizes[7];
907 sohm_btree_final_filesize2 = file_sizes[8];
908 sohm_btree_oh_size = oh_sizes[2];
909
910 /* How the SOHM messages are stored shouldn't affect the
911 * size of the object header.
912 */
913 VERIFY(sohm_btree_oh_size, sohm_oh_size, "H5Oget_info_by_name");
914
915 #if 0 /* TBD: lying comment or bug. See Jira HDFFV-10646 */
916 /* Object headers in SOHM files should be smaller than normal object
917 * headers.
918 */
919 if (sohm_oh_size >= norm_oh_size)
920 VERIFY(norm_oh_size, 1, "H5Oget_info_by_name");
921 #endif /* Jira HDFFV-10646 */
922
923 /* Both sohm files should be bigger than a normal file when empty.
924 * It's hard to say whether a B-tree with no nodes allocated should be
925 * smaller than a list with SOHM_HELPER_NUM_DTYPES elements.
926 * The sizes here shouldn't really be 1; it's just used to ensure that the
927 * error code triggers.
928 */
929 if(sohm_empty_filesize <= norm_empty_filesize)
930 VERIFY(sohm_empty_filesize, 1, "h5_get_file_size");
931
932 if(sohm_btree_empty_filesize <= norm_empty_filesize)
933 VERIFY(sohm_btree_empty_filesize, 1, "h5_get_file_size");
934
935 /* When full, the sohm btree file should be smaller than the normal file.
936 * The sohm list file should be at least as small, since it doesn't need
937 * the overhead of a B-tree.
938 */
939 if(sohm_btree_final_filesize >= norm_final_filesize)
940 VERIFY(sohm_btree_final_filesize, 1, "h5_get_file_size");
941 if(sohm_final_filesize > sohm_btree_final_filesize)
942 VERIFY(sohm_final_filesize, 1, "h5_get_file_size");
943
944 /* Comparative sizes shouldn't change even if we open and close the file
945 */
946 if(sohm_btree_final_filesize2 >= norm_final_filesize2)
947 VERIFY(sohm_btree_final_filesize2, 1, "h5_get_file_size");
948 if(sohm_final_filesize2 > sohm_btree_final_filesize2)
949 VERIFY(sohm_final_filesize2, 1, "h5_get_file_size");
950
951 } /* test_sohm_size1 */
952
953
954 /*---------------------------------------------------------------------------
955 * Function: test_sohm_size_consistency_open_create
956 *
957 * Purpose: Tests that header size is different depending on file open
958 * procedure?
959 * Uses "size1_helper" for file setup directed to a specific
960 * file handle.
961 *
962 * Programmer: Jacob Smith
963 * 2018 November 1
964 *
965 *---------------------------------------------------------------------------
966 */
967 #if 0 /* TODO: REVEALS BUG TO BE FIXED - SEE JIRA HDFFV-10645 */
968 static void
969 test_sohm_size_consistency_open_create(void)
970 {
971 hid_t file = -1;
972 hid_t fcpl_id = -1;
973 hid_t fapl_id = -1;
974 unsigned use_btree;
975 hsize_t oh_size_open;
976 hsize_t oh_size_create;
977 H5O_info_t oinfo;
978 unsigned num_indexes = 1;
979 unsigned index_flags = H5O_SHMESG_DTYPE_FLAG;
980 unsigned min_mesg_size = 50;
981 unsigned list_max = 11;
982 unsigned btree_min = 10;
983 herr_t ret;
984
985 MESSAGE(5, \
986 ("Testing that header size is consistent between H5Fopen and H5Fcreate\n"));
987
988 /* Create a FAPL with "semi" close degree, to detect dangling IDs */
989 fapl_id = H5Pcreate(H5P_FILE_ACCESS);
990 CHECK_I(fapl_id, "H5Pcreate");
991 ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI);
992 CHECK_I(ret, "H5Pset_fclose_degree");
993
994 for (use_btree = 0; use_btree < 2; use_btree++) {
995 /* Create FCPL with SOHMs enabled
996 */
997 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
998 CHECK_I(fcpl_id, "H5Pcreate");
999 ret = H5Pset_shared_mesg_nindexes(fcpl_id, num_indexes);
1000 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
1001 ret = H5Pset_shared_mesg_index(fcpl_id, 0, index_flags, min_mesg_size);
1002 CHECK_I(ret, "H5Pset_shared_mesg_index");
1003 if (use_btree) {
1004 MESSAGE(5, ("----testing with btree index----\n"));
1005 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 0, 0);
1006 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
1007 } else {
1008 MESSAGE(5, ("----testing with normal index----\n"));
1009 ret = H5Pset_shared_mesg_phase_change(fcpl_id, list_max, btree_min);
1010 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
1011 }
1012
1013 /* Create empty file */
1014 file = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, fapl_id);
1015 CHECK_I(file, "H5Fcreate");
1016 ret = H5Fclose(file);
1017 CHECK_I(ret, "H5Fclose");
1018
1019 /* Test Open/Write
1020 * Add messages to previously-created file */
1021 file = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl_id);
1022 CHECK_I(file, "H5Fopen");
1023 file = size1_helper(file, FILENAME, fapl_id, FALSE);
1024 CHECK_I(file, "size1_helper");
1025
1026 /* Get the size of a dataset object header */
1027 ret = H5Oget_info_by_name2(file, DSETNAME[0], &oinfo, H5O_INFO_HDR, H5P_DEFAULT);
1028 CHECK_I(ret, "H5Oget_info_by_name");
1029 oh_size_open = oinfo.hdr.space.total;
1030
1031 ret = H5Fclose(file);
1032 CHECK_I(ret, "H5Fclose");
1033
1034 /* Test Create/Write
1035 * Add messages to a newly-created file */
1036 file = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, fapl_id);
1037 CHECK_I(file, "H5Fcreate");
1038 file = size1_helper(file, FILENAME, fapl_id, FALSE);
1039 CHECK_I(file, "size1_helper");
1040
1041 /* Get the size of a dataset object header */
1042 ret = H5Oget_info_by_name2(file, DSETNAME[0], &oinfo, H5O_INFO_HDR, H5P_DEFAULT);
1043 CHECK_I(ret, "H5Oget_info_by_name");
1044 oh_size_create = oinfo.hdr.space.total;
1045
1046 ret = H5Fclose(file);
1047 CHECK_I(ret, "H5Fclose");
1048
1049 VERIFY(oh_size_create, oh_size_open, "H5Oget_info_by_name2");
1050
1051 ret = H5Pclose(fcpl_id);
1052 CHECK_I(ret, "H5Pclose");
1053 } /* for normal/btree indexing */
1054
1055 ret = H5Pclose(fapl_id);
1056 CHECK_I(ret, "H5Pclose");
1057 } /* test_sohm_size_consistency_open_create */
1058 #endif /* Jira HDFFV-10645 */
1059
1060
1061 /*-------------------------------------------------------------------------
1062 * Function: sohm_attr_helper
1063 *
1064 * Purpose: Given an fcpl, tests creating attributes with and without
1065 * committed datatypes.
1066 * Verify that an attribute can be written and read back.
1067 * Tests attribute on a Group.
1068 * Tests committed and non-committed datatypes.
1069 * Tests attribute access through `H5Aopen()`.
1070 *
1071 * Programmer: James Laird
1072 * Thursday, November 30, 2006
1073 *
1074 *-------------------------------------------------------------------------
1075 */
1076 static void
sohm_attr_helper(hid_t fcpl_id)1077 sohm_attr_helper(hid_t fcpl_id)
1078 {
1079 hid_t file_id;
1080 hid_t space_id;
1081 hsize_t dims = 2;
1082 int wdata[2] = {7, 42};
1083 int rdata[2];
1084 herr_t ret;
1085 size_t x;
1086 unsigned op_index=0;
1087 #define TSOHM_SAH_OP_COUNT 3
1088 const char *groupnames[TSOHM_SAH_OP_COUNT] = {
1089 "group_for_nothing_special",
1090 "group_for_commited_dtype",
1091 "group_for_commited_dtype_and_other_ID_access",
1092 };
1093
1094 file_id = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
1095 CHECK_I(file_id, "H5Fcreate");
1096
1097 space_id = H5Screate_simple(1, &dims, &dims);
1098 CHECK_I(space_id, "H5Screate_simple");
1099
1100 /* loop:
1101 * 0 - nothing special
1102 * 1 - committed datatype
1103 * 2 - committed datatype, read through second ID
1104 */
1105 for (op_index = 0; op_index < TSOHM_SAH_OP_COUNT; op_index++) {
1106 hid_t type_id = -1;
1107 hid_t group_id = -1;
1108 hid_t attr_id = -1;
1109 hid_t attr_id2 = -1;
1110 hid_t attr_read_id;
1111
1112 /* create group in file with name unique to op_index */
1113 group_id = H5Gcreate2(file_id, groupnames[op_index], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1114 CHECK_I(group_id, "H5Gcreate2");
1115
1116 type_id = H5Tcopy(H5T_NATIVE_INT);
1117 CHECK_I(type_id, "H5Tcopy");
1118
1119 /* Commit the datatype for the latter iterations.
1120 * Only do this ONCE.
1121 */
1122 if (op_index == 1) {
1123 ret = H5Tcommit2(file_id, "datatype", type_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1124 CHECK_I(ret, "H5Tcommit2");
1125 }
1126
1127 attr_id = H5Acreate2(group_id, "attribute", type_id, space_id, H5P_DEFAULT, H5P_DEFAULT);
1128 CHECK_I(attr_id, "H5Acreate2");
1129
1130 if (op_index == 2) {
1131 /* Open the attribute to get another handle */
1132 attr_id2 = H5Aopen(group_id, "attribute", H5P_DEFAULT);
1133 CHECK_I(attr_id2, "H5Aopen");
1134 }
1135
1136 ret = H5Awrite(attr_id, H5T_NATIVE_INT, wdata);
1137 CHECK_I(ret, "H5Awrite");
1138
1139 ret = H5Gclose(group_id);
1140 CHECK_I(ret, "H5Gclose");
1141 ret = H5Tclose(type_id);
1142 CHECK_I(ret, "H5Tclose");
1143
1144 /* Flush the file to force data to be written */
1145 ret = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
1146 CHECK_I(ret, "H5Fflush");
1147
1148 /* Verify */
1149 attr_read_id = (op_index == 2) ? attr_id2 : attr_id;
1150 HDmemset(rdata, 0, sizeof(rdata));
1151 ret = H5Aread(attr_read_id, H5T_NATIVE_INT, rdata);
1152 CHECK_I(ret, "H5Aread");
1153 for(x = 0; x < (size_t)dims; ++x)
1154 VERIFY(rdata[x], wdata[x], "H5Aread");
1155
1156 ret = H5Aclose(attr_id);
1157 CHECK_I(ret, "H5Aclose");
1158 if (attr_id2 > -1 ) {
1159 ret = H5Aclose(attr_id2);
1160 CHECK_I(ret, "H5Aclose");
1161 }
1162 } /* for each attribute operation */
1163
1164 ret = H5Sclose(space_id);
1165 CHECK_I(ret, "H5Sclose");
1166 ret = H5Fclose(file_id);
1167 CHECK_I(ret, "H5Fclose");
1168 #undef TSOHM_SAH_OP_COUNT
1169 } /* sohm_attr_helper */
1170
1171
1172 /*-------------------------------------------------------------------------
1173 * Function: test_sohm_attrs
1174 *
1175 * Purpose: Attributes can be shared and can also contain shared
1176 * datatype and dataspace messages. Committed datatypes
1177 * shouldn't be shared.
1178 *
1179 * Test permutations of this.
1180 *
1181 * Programmer: James Laird
1182 * Thursday, November 30, 2006
1183 *
1184 *-------------------------------------------------------------------------
1185 */
1186 static void
test_sohm_attrs(void)1187 test_sohm_attrs(void)
1188 {
1189 hid_t bad_fid = H5I_INVALID_HID;
1190 hid_t fcpl_id = H5I_INVALID_HID;
1191 unsigned i = 0;
1192 #define TSOHM_TSA_NFLAGS_1 7
1193 unsigned flags1[TSOHM_TSA_NFLAGS_1] = {
1194 H5O_SHMESG_ATTR_FLAG,
1195 H5O_SHMESG_SDSPACE_FLAG,
1196 H5O_SHMESG_DTYPE_FLAG,
1197 H5O_SHMESG_ATTR_FLAG | H5O_SHMESG_SDSPACE_FLAG,
1198 H5O_SHMESG_SDSPACE_FLAG | H5O_SHMESG_DTYPE_FLAG,
1199 H5O_SHMESG_ATTR_FLAG | H5O_SHMESG_DTYPE_FLAG,
1200 H5O_SHMESG_ATTR_FLAG | H5O_SHMESG_SDSPACE_FLAG | H5O_SHMESG_DTYPE_FLAG,
1201 };
1202 #define TSOHM_TSA_NFLAGS_2 6
1203 unsigned flags2[TSOHM_TSA_NFLAGS_2][2] = {
1204 { H5O_SHMESG_ATTR_FLAG,
1205 H5O_SHMESG_SDSPACE_FLAG | H5O_SHMESG_DTYPE_FLAG,
1206 },
1207 { H5O_SHMESG_SDSPACE_FLAG,
1208 H5O_SHMESG_ATTR_FLAG | H5O_SHMESG_DTYPE_FLAG,
1209 },
1210 { H5O_SHMESG_DTYPE_FLAG,
1211 H5O_SHMESG_ATTR_FLAG | H5O_SHMESG_SDSPACE_FLAG,
1212 },
1213 { H5O_SHMESG_SDSPACE_FLAG | H5O_SHMESG_DTYPE_FLAG,
1214 H5O_SHMESG_ATTR_FLAG,
1215 },
1216 { H5O_SHMESG_ATTR_FLAG | H5O_SHMESG_DTYPE_FLAG,
1217 H5O_SHMESG_SDSPACE_FLAG,
1218 },
1219 { H5O_SHMESG_ATTR_FLAG | H5O_SHMESG_SDSPACE_FLAG,
1220 H5O_SHMESG_DTYPE_FLAG,
1221 },
1222 };
1223 #define TSOHM_TSA_NFLAGS_3 5
1224 unsigned flags3[TSOHM_TSA_NFLAGS_3][3] = {
1225 { H5O_SHMESG_ATTR_FLAG,
1226 H5O_SHMESG_SDSPACE_FLAG,
1227 H5O_SHMESG_DTYPE_FLAG,
1228 },
1229 { H5O_SHMESG_DTYPE_FLAG,
1230 H5O_SHMESG_ATTR_FLAG,
1231 H5O_SHMESG_SDSPACE_FLAG,
1232 },
1233 { H5O_SHMESG_SDSPACE_FLAG,
1234 H5O_SHMESG_DTYPE_FLAG,
1235 H5O_SHMESG_ATTR_FLAG,
1236 },
1237 { 0, /* first index does not hold a shared message type? */
1238 H5O_SHMESG_SDSPACE_FLAG | H5O_SHMESG_DTYPE_FLAG,
1239 H5O_SHMESG_ATTR_FLAG,
1240 },
1241 { 0, /* missing SDSPACE flag */
1242 H5O_SHMESG_DTYPE_FLAG,
1243 H5O_SHMESG_ATTR_FLAG,
1244 },
1245 };
1246 herr_t ret;
1247
1248 MESSAGE(5, ("Testing that shared messages work with attributes\n"));
1249
1250 /* No shared messages
1251 */
1252 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
1253 CHECK_I(fcpl_id, "H5Pcreate");
1254 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 0);
1255 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
1256
1257 sohm_attr_helper(fcpl_id);
1258
1259 ret = H5Pclose(fcpl_id);
1260 CHECK_I(ret, "H5Pclose");
1261
1262 /* One shared message index
1263 */
1264 for (i=0; i < TSOHM_TSA_NFLAGS_1; i++) {
1265 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
1266 CHECK_I(fcpl_id, "H5Pcreate");
1267 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 1);
1268 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
1269 ret = H5Pset_shared_mesg_index(fcpl_id, 0, flags1[i], 2);
1270 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
1271
1272 sohm_attr_helper(fcpl_id);
1273
1274 ret = H5Pclose(fcpl_id);
1275 CHECK_I(ret, "H5Pclose");
1276 }
1277
1278 /* two shared message indices
1279 */
1280 for (i=0; i < TSOHM_TSA_NFLAGS_2; i++) {
1281 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
1282 CHECK_I(fcpl_id, "H5Pcreate");
1283 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 2);
1284 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
1285 ret = H5Pset_shared_mesg_index(fcpl_id, 0, flags2[i][0], 2);
1286 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
1287 ret = H5Pset_shared_mesg_index(fcpl_id, 1, flags2[i][1], 2);
1288 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
1289
1290 sohm_attr_helper(fcpl_id);
1291
1292 ret = H5Pclose(fcpl_id);
1293 CHECK_I(ret, "H5Pclose");
1294 }
1295
1296 /* duplicate flags in separate indices causes problems
1297 */
1298 H5E_BEGIN_TRY {
1299 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
1300 CHECK_I(fcpl_id, "H5Pcreate");
1301 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 2);
1302 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
1303 ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_SHMESG_ATTR_FLAG, 2);
1304 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
1305 ret = H5Pset_shared_mesg_index(fcpl_id, 1, H5O_SHMESG_ATTR_FLAG, 2);
1306 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
1307
1308 bad_fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
1309 VERIFY(bad_fid, H5I_INVALID_HID, "H5Fcreate");
1310
1311 ret = H5Pclose(fcpl_id);
1312 CHECK_I(ret, "H5Pclose");
1313 } H5E_END_TRY;
1314
1315 /* three shared message indices
1316 */
1317 for (i=0; i < TSOHM_TSA_NFLAGS_3; i++) {
1318 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
1319 CHECK_I(fcpl_id, "H5Pcreate");
1320 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 3);
1321 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
1322 ret = H5Pset_shared_mesg_index(fcpl_id, 0, flags3[i][0], 2);
1323 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
1324 ret = H5Pset_shared_mesg_index(fcpl_id, 1, flags3[i][1], 2);
1325 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
1326 ret = H5Pset_shared_mesg_index(fcpl_id, 2, flags3[i][2], 2);
1327 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
1328
1329 sohm_attr_helper(fcpl_id);
1330
1331 ret = H5Pclose(fcpl_id);
1332 CHECK_I(ret, "H5Pclose");
1333 }
1334
1335 #undef TSOHM_TSA_NFLAGS_1
1336 #undef TSOHM_TSA_NFLAGS_2
1337 #undef TSOHM_TSA_NFLAGS_3
1338
1339 } /* test_sohm_attrs */
1340
1341
1342 /*-------------------------------------------------------------------------
1343 * Function: size2_verify_plist1
1344 *
1345 * Purpose: Verify that the property list passed in is in fact the
1346 * same property list used as dcpl1_id in the size2 helper
1347 * function. This ensures that the filters can be read.
1348 *
1349 * Programmer: James Laird
1350 * Wednesday, November 22, 2006
1351 *
1352 *-------------------------------------------------------------------------
1353 */
1354 static void
size2_verify_plist1(hid_t plist)1355 size2_verify_plist1(hid_t plist)
1356 {
1357 size_t cd_nelmts;
1358 unsigned int cd_value;
1359 char name[NAME_BUF_SIZE];
1360 H5Z_filter_t filter;
1361 hid_t dtype1_id;
1362 dtype1_struct fill1;
1363 dtype1_struct fill1_correct;
1364 herr_t ret;
1365
1366 /* Hardcoded to correspond to dcpl1_id created in size2_helper */
1367 /* Check filters */
1368 cd_nelmts = 1;
1369 filter = H5Pget_filter2(plist, 0, NULL, &cd_nelmts, &cd_value, (size_t)NAME_BUF_SIZE, name, NULL);
1370 CHECK_I(filter, "H5Pget_filter2");
1371 VERIFY(filter, H5Z_FILTER_SHUFFLE, "H5Pget_filter2");
1372
1373 cd_nelmts = 1;
1374 filter = H5Pget_filter2(plist, 1, NULL, &cd_nelmts, &cd_value, (size_t)NAME_BUF_SIZE, name, NULL);
1375 CHECK_I(filter, "H5Pget_filter2");
1376 VERIFY(filter, H5Z_FILTER_DEFLATE, "H5Pget_filter2");
1377 VERIFY(cd_value, 1, "H5Pget_filter2");
1378
1379 cd_nelmts = 1;
1380 filter = H5Pget_filter2(plist, 2, NULL, &cd_nelmts, &cd_value, (size_t)NAME_BUF_SIZE, name, NULL);
1381 CHECK_I(filter, "H5Pget_filter2");
1382 VERIFY(filter, H5Z_FILTER_SHUFFLE, "H5Pget_filter2");
1383
1384 cd_nelmts = 1;
1385 filter = H5Pget_filter2(plist, 3, NULL, &cd_nelmts, &cd_value, (size_t)NAME_BUF_SIZE, name, NULL);
1386 CHECK_I(filter, "H5Pget_filter2");
1387 VERIFY(filter, H5Z_FILTER_FLETCHER32, "H5Pget_filter2");
1388
1389
1390 /* Check fill value */
1391 dtype1_id=make_dtype_1();
1392 CHECK_I(dtype1_id, "make_dtype_1");
1393 HDmemset(&fill1_correct, '1', sizeof(fill1_correct));
1394
1395 ret = H5Pget_fill_value(plist, dtype1_id, &fill1);
1396 CHECK_I(ret, "H5Pget_fill_value");
1397
1398 ret = HDmemcmp(&fill1, &fill1_correct, sizeof(fill1_correct));
1399 VERIFY(ret, 0, "memcmp");
1400
1401 ret = H5Tclose(dtype1_id);
1402 CHECK_I(ret, "H5Tclose");
1403 } /* size2_verify_plist1 */
1404
1405
1406 /*-------------------------------------------------------------------------
1407 * Function: size2_verify_plist2
1408 *
1409 * Purpose: Verify that the property list passed in is in fact the
1410 * same property list used as dcpl2_id in the size2 helper
1411 * function. This ensures that the filters can be read.
1412 *
1413 * Programmer: James Laird
1414 * Wednesday, November 22, 2006
1415 *
1416 *-------------------------------------------------------------------------
1417 */
1418 static void
size2_verify_plist2(hid_t plist)1419 size2_verify_plist2(hid_t plist)
1420 {
1421 size_t cd_nelmts;
1422 unsigned int cd_value;
1423 char name[NAME_BUF_SIZE];
1424 H5Z_filter_t filter;
1425 hid_t dtype2_id;
1426 char fill2[DTYPE2_SIZE];
1427 char fill2_correct[DTYPE2_SIZE];
1428 herr_t ret;
1429
1430 /* Hardcoded to correspond to dcpl1_id created in size2_helper */
1431 /* Check filters */
1432 cd_nelmts = 1;
1433 filter = H5Pget_filter2(plist, 0, NULL, &cd_nelmts, &cd_value, (size_t)NAME_BUF_SIZE, name, NULL);
1434 CHECK_I(filter, "H5Pget_filter2");
1435 VERIFY(filter, H5Z_FILTER_DEFLATE, "H5Pget_filter2");
1436 VERIFY(cd_value, 1, "H5Pget_filter2");
1437
1438 cd_nelmts = 1;
1439 filter = H5Pget_filter2(plist, 1, NULL, &cd_nelmts, &cd_value, (size_t)NAME_BUF_SIZE, name, NULL);
1440 CHECK_I(filter, "H5Pget_filter2");
1441 VERIFY(filter, H5Z_FILTER_DEFLATE, "H5Pget_filter2");
1442 VERIFY(cd_value, 2, "H5Pget_filter2");
1443
1444 cd_nelmts = 1;
1445 filter = H5Pget_filter2(plist, 2, NULL, &cd_nelmts, &cd_value, (size_t)NAME_BUF_SIZE, name, NULL);
1446 CHECK_I(filter, "H5Pget_filter2");
1447 VERIFY(filter, H5Z_FILTER_DEFLATE, "H5Pget_filter2");
1448 VERIFY(cd_value, 2, "H5Pget_filter2");
1449
1450 cd_nelmts = 1;
1451 filter = H5Pget_filter2(plist, 3, NULL, &cd_nelmts, &cd_value, (size_t)NAME_BUF_SIZE, name, NULL);
1452 CHECK_I(filter, "H5Pget_filter2");
1453 VERIFY(filter, H5Z_FILTER_DEFLATE, "H5Pget_filter2");
1454 VERIFY(cd_value, 1, "H5Pget_filter2");
1455
1456 cd_nelmts = 1;
1457 filter = H5Pget_filter2(plist, 4, NULL, &cd_nelmts, &cd_value, (size_t)NAME_BUF_SIZE, name, NULL);
1458 CHECK_I(filter, "H5Pget_filter2");
1459 VERIFY(filter, H5Z_FILTER_DEFLATE, "H5Pget_filter2");
1460 VERIFY(cd_value, 5, "H5Pget_filter2");
1461
1462
1463 /* Check fill value */
1464 dtype2_id = make_dtype_2();
1465 CHECK_I(dtype2_id, "make_dtype_2");
1466 HDmemset(&fill2_correct, '2', (size_t)DTYPE2_SIZE);
1467
1468 ret = H5Pget_fill_value(plist, dtype2_id, &fill2);
1469 CHECK_I(ret, "H5Pget_fill_value");
1470
1471 ret = HDmemcmp(&fill2, &fill2_correct, (size_t)DTYPE2_SIZE);
1472 VERIFY(ret, 0, "memcmp");
1473
1474 ret = H5Tclose(dtype2_id);
1475 CHECK_I(ret, "H5Tclose");
1476 } /* size2_verify_plist2 */
1477
1478 #ifdef NOT_NOW
1479
1480 /*-------------------------------------------------------------------------
1481 * Function: size2_dump_struct
1482 *
1483 * Purpose: A debugging function to print the contents of a
1484 * size2_helper_struct (which holds the various sizes for a
1485 * given file during the size2_helper function).
1486 *
1487 * Programmer: James Laird
1488 * Friday, January 26, 2007
1489 *
1490 * Modifications:
1491 *
1492 *-------------------------------------------------------------------------
1493 */
1494 static void
size2_dump_struct(const char * name,size2_helper_struct * sizes)1495 size2_dump_struct(const char *name, size2_helper_struct *sizes)
1496 {
1497 HDputs(name);
1498 HDprintf(" empty size: %llu\n", (unsigned long long)sizes->empty_size);
1499 HDprintf(" first dataset: %llu \tdelta: %llu\n", (unsigned long long)sizes->first_dset, (unsigned long long)(sizes->first_dset - sizes->empty_size));
1500 HDprintf("second dataset: %llu \tdelta: %llu\n", (unsigned long long)sizes->second_dset, (unsigned long long)(sizes->second_dset - sizes->first_dset));
1501 HDprintf(" dsets 1: %llu \tdelta: %llu\n", (unsigned long long)sizes->dsets1, (unsigned long long)(sizes->dsets1 - sizes->second_dset));
1502 HDprintf(" dsets 2: %llu \tdelta: %llu\n", (unsigned long long)sizes->dsets2, (unsigned long long)(sizes->dsets2 - sizes->dsets1));
1503 HDprintf(" interleaved: %llu \tdelta: %llu\n", (unsigned long long)sizes->interleaved, (unsigned long long)(sizes->interleaved - sizes->dsets2));
1504 HDprintf(" attributes: %llu \tdelta: %llu\n", (unsigned long long)sizes->attrs1, (unsigned long long)(sizes->attrs1 - sizes->interleaved));
1505 HDprintf(" attributes 2: %llu \tdelta: %llu\n", (unsigned long long)sizes->attrs2, (unsigned long long)(sizes->attrs2 - sizes->attrs1));
1506 } /* size2_dump_struct */
1507 #endif /* NOT_NOW */
1508
1509
1510 /*-------------------------------------------------------------------------
1511 * Function: size2_helper
1512 *
1513 * Purpose: A helper functon for test_sohm_size2.
1514 *
1515 * Creates a file using the given fcpl, then creates lots
1516 * of different kinds of messages within the file and
1517 * returns the size of the file for comparison.
1518 *
1519 * If test_file_closing is not zero, closes and re-opens
1520 * the file after every write.
1521 *
1522 * Doesn't close the property list. Prints an error message
1523 * if there's a failure, but doesn't alter its return value.
1524 *
1525 * Programmer: James Laird
1526 * Friday, November 17, 2006
1527 *
1528 * Modifications:
1529 *
1530 *-------------------------------------------------------------------------
1531 */
1532 static int
size2_helper(hid_t fcpl_id,int test_file_closing,size2_helper_struct * ret_sizes)1533 size2_helper(hid_t fcpl_id, int test_file_closing, size2_helper_struct *ret_sizes)
1534 {
1535 hid_t file_id = -1;
1536 hid_t dtype1_id = -1;
1537 hid_t dtype2_id = -1;
1538 hid_t dspace1_id = -1;
1539 hid_t dspace2_id = -1;
1540 hid_t dcpl1_id = -1;
1541 hid_t dcpl2_id = -1;
1542 hid_t dset_id = -1;
1543 hid_t attr_type_id = -1;
1544 hid_t attr_space_id = -1;
1545 hid_t attr_id = -1;
1546 hid_t group_id = -1;
1547 char attr_string1[NAME_BUF_SIZE];
1548 char attr_string2[NAME_BUF_SIZE];
1549 char attr_name[NAME_BUF_SIZE];
1550 int x;
1551 herr_t ret;
1552
1553 /* Constants used in this function */
1554 const int rank1 = SIZE2_RANK1;
1555 const int rank2 = SIZE2_RANK2;
1556 const hsize_t dims[SIZE2_RANK2] = SIZE2_DIMS;
1557 dtype1_struct fill1;
1558 char fill2[DTYPE2_SIZE];
1559
1560 /* Closing and re-opening the file takes a long time on systems without
1561 * local disks. Don't close and reopen if express testing is enabled.
1562 */
1563 if(GetTestExpress() > 1)
1564 test_file_closing = 0;
1565
1566 /* Create a file and get its size */
1567 file_id = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
1568 CHECK_I(file_id, "H5Fcreate");
1569
1570 ret = H5Fclose(file_id);
1571 CHECK_I(ret, "H5Fclose");
1572
1573 /* Get the file size */
1574 ret_sizes->empty_size = h5_get_file_size(FILENAME, H5P_DEFAULT);
1575
1576 /* Re-open the file and set up messages to write */
1577 file_id = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
1578 CHECK_I(file_id, "H5Fopen");
1579
1580 /* Create two large datatype messages */
1581 dtype1_id = make_dtype_1();
1582 CHECK_I(dtype1_id, "make_dtype_1");
1583 dtype2_id = make_dtype_2();
1584 CHECK_I(dtype2_id, "make_dtype_2");
1585
1586 /* Create some large dataspaces */
1587 dspace1_id = H5Screate_simple(rank1, dims, dims);
1588 CHECK_I(dspace1_id, "H5Screate_simple");
1589 dspace2_id = H5Screate_simple(rank2, dims, dims);
1590 CHECK_I(dspace2_id, "H5Screate_simple");
1591
1592 /* fill1 and fill2 are fill values for the two datatypes.
1593 * We'll set them in the DCPL.
1594 */
1595 HDmemset(&fill1, '1', sizeof(dtype1_struct));
1596 HDmemset(&fill2, '2', (size_t)DTYPE2_SIZE);
1597
1598 dcpl1_id = H5Pcreate(H5P_DATASET_CREATE);
1599 CHECK_I(dcpl1_id, "H5Pcreate");
1600 H5Pset_fill_value(dcpl1_id, dtype1_id, &fill1);
1601
1602 dcpl2_id = H5Pcreate(H5P_DATASET_CREATE);
1603 CHECK_I(dcpl2_id, "H5Pcreate");
1604 H5Pset_fill_value(dcpl2_id, dtype2_id, &fill2);
1605
1606 /* Filter messages we'll create by setting them in a DCPL. These
1607 * values don't need to make sense, they just need to take up space.
1608 */
1609 ret = H5Pset_chunk(dcpl1_id, rank1, dims);
1610 CHECK_I(ret, "H5Pset_chunk");
1611 ret = H5Pset_shuffle(dcpl1_id);
1612 CHECK_I(ret, "H5Pset_shuffle");
1613 ret = H5Pset_deflate(dcpl1_id, 1);
1614 CHECK_I(ret, "H5Pset_deflate");
1615 ret = H5Pset_shuffle(dcpl1_id);
1616 CHECK_I(ret, "H5Pset_shuffle");
1617 ret = H5Pset_fletcher32(dcpl1_id);
1618 CHECK_I(ret, "H5Pset_fletcher32");
1619 /* Make sure that this property list is what it should be */
1620 size2_verify_plist1(dcpl1_id);
1621
1622 /* Second dcpl */
1623 ret = H5Pset_chunk(dcpl2_id, rank2, dims);
1624 CHECK_I(ret, "H5Pset_chunk");
1625 ret = H5Pset_deflate(dcpl2_id, 1);
1626 CHECK_I(ret, "H5Pset_deflate");
1627 ret = H5Pset_deflate(dcpl2_id, 2);
1628 CHECK_I(ret, "H5Pset_deflate");
1629 ret = H5Pset_deflate(dcpl2_id, 2);
1630 CHECK_I(ret, "H5Pset_deflate");
1631 ret = H5Pset_deflate(dcpl2_id, 1);
1632 CHECK_I(ret, "H5Pset_deflate");
1633 ret = H5Pset_deflate(dcpl2_id, 5);
1634 CHECK_I(ret, "H5Pset_deflate");
1635 /* Make sure that this property list is what it should be */
1636 size2_verify_plist2(dcpl2_id);
1637
1638 /* Set up attribute data */
1639 HDmemset(attr_string1, 0, (size_t)NAME_BUF_SIZE);
1640 HDmemset(attr_string2, 0, (size_t)NAME_BUF_SIZE);
1641 HDstrcpy(attr_string1, LONG_STRING);
1642 HDstrcpy(attr_string2, LONG_STRING);
1643 attr_string2[1] = '1'; /* The second string starts "01 index..." */
1644
1645 /* Set up attribute metadata */
1646 attr_type_id = H5Tcopy(H5T_C_S1);
1647 CHECK_I(attr_type_id, "H5Tcopy");
1648 ret = H5Tset_size(attr_type_id, (size_t)NAME_BUF_SIZE);
1649 CHECK_I(ret, "H5Tset_size");
1650 attr_space_id = H5Screate_simple(1, dims, dims);
1651 CHECK_I(attr_space_id, "H5Screate_simple");
1652
1653 /* Create datasets with a big datatype, dataspace, fill value,
1654 * and filter pipeline.
1655 */
1656 for(x = 0; x < NUM_DATASETS; ++x) {
1657 dset_id = H5Dcreate2(file_id, DSETNAME[x], dtype1_id, dspace1_id, H5P_DEFAULT, dcpl1_id, H5P_DEFAULT);
1658 CHECK_I(dset_id, "H5Dcreate2");
1659
1660 attr_id = H5Acreate2(dset_id, "attr_name", attr_type_id, attr_space_id, H5P_DEFAULT, H5P_DEFAULT);
1661 CHECK_I(attr_id, "H5Acreate2");
1662 ret = H5Awrite(attr_id, attr_type_id, attr_string1);
1663 CHECK_I(ret, "H5Awrite");
1664
1665 ret = H5Aclose(attr_id);
1666 CHECK_I(ret, "H5Aclose");
1667 ret = H5Dclose(dset_id);
1668 CHECK_I(ret, "H5Dclose");
1669
1670 /* Gather extra statistics on first two datasets in file */
1671 if(x < 2) {
1672 ret = H5Fclose(file_id);
1673 CHECK_I(ret, "H5Fclose");
1674
1675 /* Get the file's size now */
1676 if(x == 0)
1677 ret_sizes->first_dset = h5_get_file_size(FILENAME, H5P_DEFAULT);
1678 else
1679 ret_sizes->second_dset = h5_get_file_size(FILENAME, H5P_DEFAULT);
1680
1681 file_id = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
1682 CHECK_I(file_id, "H5Fopen");
1683 } /* end if */
1684 /* Close & reopen file if requested */
1685 else if(test_file_closing) {
1686 file_id = close_reopen_file(file_id, FILENAME, H5P_DEFAULT);
1687 CHECK_I(file_id, "H5Fopen");
1688 } /* end if */
1689 } /* end for */
1690
1691 /* Close file and get its size now */
1692 ret = H5Fclose(file_id);
1693 CHECK_I(ret, "H5Fclose");
1694 ret_sizes->dsets1 = h5_get_file_size(FILENAME, H5P_DEFAULT);
1695
1696
1697 /* Create new group filled with datasets that use all different messages */
1698 file_id = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
1699 CHECK_I(file_id, "H5Fopen");
1700 group_id = H5Gcreate2(file_id, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1701 CHECK_I(group_id, "H5Gcreate2");
1702
1703 /* Create NUM_DATASETS datasets in the new group */
1704 for(x=0; x<NUM_DATASETS; ++x) {
1705 dset_id = H5Dcreate2(group_id, DSETNAME[x], dtype2_id, dspace2_id, H5P_DEFAULT, dcpl2_id, H5P_DEFAULT);
1706 CHECK_I(dset_id, "H5Dcreate2");
1707
1708 attr_id = H5Acreate2(dset_id, "attr_name", attr_type_id, attr_space_id, H5P_DEFAULT, H5P_DEFAULT);
1709 CHECK_I(attr_id, "H5Acreate2");
1710 ret = H5Awrite(attr_id, attr_type_id, attr_string2);
1711 CHECK_I(ret, "H5Awrite");
1712
1713 ret = H5Dclose(dset_id);
1714 CHECK_I(ret, "H5Dclose");
1715 ret = H5Aclose(attr_id);
1716 CHECK_I(ret, "H5Aclose");
1717
1718 /* Close everything & reopen file if requested */
1719 if(test_file_closing) {
1720 ret = H5Gclose(group_id);
1721 CHECK_I(ret, "H5Gclose");
1722 file_id = close_reopen_file(file_id, FILENAME, H5P_DEFAULT);
1723 CHECK_I(file_id, "H5Fopen");
1724 group_id = H5Gopen2(file_id, "group", H5P_DEFAULT);
1725 CHECK_I(group_id, "H5Gopen2");
1726 }
1727 }
1728
1729 /* Close file and get its size now */
1730 ret = H5Gclose(group_id);
1731 CHECK_I(ret, "H5Gclose");
1732 ret = H5Fclose(file_id);
1733 CHECK_I(ret, "H5Fclose");
1734 ret_sizes->dsets2 = h5_get_file_size(FILENAME, H5P_DEFAULT);
1735
1736
1737 /* Create a new group and interleave writes of datasets types 1 and 2. */
1738 file_id = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
1739 CHECK_I(file_id, "H5Fopen");
1740 group_id = H5Gcreate2(file_id, "interleaved group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1741 CHECK_I(group_id, "H5Gcreate2");
1742
1743 /* Create NUM_DATASETS datasets in the new group */
1744 for(x=0; x<NUM_DATASETS; x+=2)
1745 {
1746 dset_id = H5Dcreate2(group_id, DSETNAME[x], dtype1_id, dspace1_id, H5P_DEFAULT, dcpl1_id, H5P_DEFAULT);
1747 CHECK_I(dset_id, "H5Dcreate2");
1748
1749 attr_id = H5Acreate2(dset_id, "attr_name", attr_type_id, attr_space_id, H5P_DEFAULT, H5P_DEFAULT);
1750 CHECK_I(attr_id, "H5Acreate2");
1751 ret = H5Awrite(attr_id, attr_type_id, attr_string1);
1752 CHECK_I(ret, "H5Awrite");
1753
1754 ret = H5Dclose(dset_id);
1755 CHECK_I(ret, "H5Dclose");
1756 ret = H5Aclose(attr_id);
1757 CHECK_I(ret, "H5Aclose");
1758
1759 dset_id = H5Dcreate2(group_id, DSETNAME[x+1], dtype2_id, dspace2_id, H5P_DEFAULT, dcpl2_id, H5P_DEFAULT);
1760 CHECK_I(dset_id, "H5Dcreate2");
1761
1762 attr_id = H5Acreate2(dset_id, "attr_name", attr_type_id, attr_space_id, H5P_DEFAULT, H5P_DEFAULT);
1763 CHECK_I(attr_id, "H5Acreate2");
1764 ret = H5Awrite(attr_id, attr_type_id, attr_string2);
1765 CHECK_I(ret, "H5Awrite");
1766
1767 ret = H5Dclose(dset_id);
1768 CHECK_I(ret, "H5Dclose");
1769 ret = H5Aclose(attr_id);
1770 CHECK_I(ret, "H5Aclose");
1771
1772 /* Close everything & reopen file if requested */
1773 if(test_file_closing) {
1774 ret = H5Gclose(group_id);
1775 CHECK_I(ret, "H5Gclose");
1776 file_id = close_reopen_file(file_id, FILENAME, H5P_DEFAULT);
1777 CHECK_I(file_id, "H5Fopen");
1778 group_id = H5Gopen2(file_id, "interleaved group", H5P_DEFAULT);
1779 CHECK_I(group_id, "H5Gopen2");
1780 }
1781 }
1782
1783 /* Close file and get its size now */
1784 ret = H5Gclose(group_id);
1785 CHECK_I(ret, "H5Gclose");
1786 ret = H5Fclose(file_id);
1787 CHECK_I(ret, "H5Fclose");
1788 ret_sizes->interleaved = h5_get_file_size(FILENAME, H5P_DEFAULT);
1789
1790 /* Create lots of new attribute messages on the group
1791 * (using different strings for the attribute)
1792 */
1793 file_id = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
1794 CHECK_I(file_id, "H5Fopen");
1795 group_id = H5Gopen2(file_id, "group", H5P_DEFAULT);
1796 CHECK_I(group_id, "H5Gopen2");
1797
1798 HDstrcpy(attr_name, "00 index");
1799
1800 for(x = 0; x < NUM_ATTRIBUTES; ++x) {
1801 /* Create a unique name and value for each attribute */
1802 attr_string1[0] = attr_name[0] = (char)((x / 10) + '0');
1803 attr_string1[1] = attr_name[1] = (char)((x % 10) + '0');
1804
1805 /* Create an attribute on the group */
1806 attr_id = H5Acreate2(group_id, attr_name, attr_type_id, attr_space_id, H5P_DEFAULT, H5P_DEFAULT);
1807 CHECK_I(attr_id, "H5Acreate2");
1808 ret = H5Awrite(attr_id, attr_type_id, attr_string1);
1809 CHECK_I(ret, "H5Awrite");
1810
1811 ret = H5Aclose(attr_id);
1812 CHECK_I(ret, "H5Aclose");
1813
1814 /* Close everything & reopen file if requested */
1815 if(test_file_closing) {
1816 ret = H5Gclose(group_id);
1817 CHECK_I(ret, "H5Gclose");
1818 file_id = close_reopen_file(file_id, FILENAME, H5P_DEFAULT);
1819 CHECK_I(file_id, "H5Fopen");
1820 group_id = H5Gopen2(file_id, "group", H5P_DEFAULT);
1821 CHECK_I(group_id, "H5Gopen2");
1822 }
1823 }
1824
1825 /* Close file and get its size now */
1826 ret = H5Gclose(group_id);
1827 CHECK_I(ret, "H5Gclose");
1828 ret = H5Fclose(file_id);
1829 CHECK_I(ret, "H5Fclose");
1830 ret_sizes->attrs1 = h5_get_file_size(FILENAME, H5P_DEFAULT);
1831
1832
1833 /* Create all of the attributes again on the other group */
1834 file_id = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
1835 CHECK_I(file_id, "H5Fopen");
1836 group_id = H5Gopen2(file_id, "interleaved group", H5P_DEFAULT);
1837 CHECK_I(group_id, "H5Gopen2");
1838
1839 for(x=0; x<NUM_ATTRIBUTES; ++x)
1840 {
1841 /* Create the same name and value for each attribute as before */
1842 attr_string1[0] = attr_name[0] = (char)((x / 10) + '0');
1843 attr_string1[1] = attr_name[1] = (char)((x % 10) + '0');
1844
1845 /* Create an attribute on the group */
1846 attr_id = H5Acreate2(group_id, attr_name, attr_type_id, attr_space_id, H5P_DEFAULT, H5P_DEFAULT);
1847 CHECK_I(attr_id, "H5Acreate2");
1848 ret = H5Awrite(attr_id, attr_type_id, attr_string1);
1849 CHECK_I(ret, "H5Awrite");
1850
1851 ret = H5Aclose(attr_id);
1852 CHECK_I(ret, "H5Aclose");
1853
1854 /* Close everything & reopen file if requested */
1855 if(test_file_closing) {
1856 ret = H5Gclose(group_id);
1857 CHECK_I(ret, "H5Gclose");
1858 file_id = close_reopen_file(file_id, FILENAME, H5P_DEFAULT);
1859 CHECK_I(file_id, "H5Fopen");
1860 group_id = H5Gopen2(file_id, "interleaved group", H5P_DEFAULT);
1861 CHECK_I(group_id, "H5Gopen2");
1862 }
1863 }
1864 /* Close file and get its size now */
1865 ret = H5Gclose(group_id);
1866 CHECK_I(ret, "H5Gclose");
1867 ret = H5Fclose(file_id);
1868 CHECK_I(ret, "H5Fclose");
1869 ret_sizes->attrs2 = h5_get_file_size(FILENAME, H5P_DEFAULT);
1870
1871
1872 /* Close everything */
1873 ret = H5Sclose(attr_space_id);
1874 CHECK_I(ret, "H5Sclose");
1875 ret = H5Tclose(attr_type_id);
1876 CHECK_I(ret, "H5Sclose");
1877 ret = H5Tclose(dtype1_id);
1878 CHECK_I(ret, "H5Tclose");
1879 ret = H5Tclose(dtype2_id);
1880 CHECK_I(ret, "H5Tclose");
1881 ret = H5Sclose(dspace1_id);
1882 CHECK_I(ret, "H5Sclose");
1883 ret = H5Sclose(dspace2_id);
1884 CHECK_I(ret, "H5Sclose");
1885 ret = H5Pclose(dcpl1_id);
1886 CHECK_I(ret, "H5Pclose");
1887 ret = H5Pclose(dcpl2_id);
1888 CHECK_I(ret, "H5Pclose");
1889
1890 return 0;
1891 } /* size2_helper */
1892
1893
1894 /*-------------------------------------------------------------------------
1895 * Function: size2_verify
1896 *
1897 * Purpose: A helper functon to verify the file created by size2_helper.
1898 *
1899 * Runs various tests (not exhaustive) to ensure that the
1900 * file FILENAME actually has the structure that size2_helper
1901 * should have created.
1902 *
1903 * Programmer: James Laird
1904 * Friday, November 17, 2006
1905 *
1906 *-------------------------------------------------------------------------
1907 */
1908 static void
size2_verify(void)1909 size2_verify(void)
1910 {
1911 hid_t file_id = -1;
1912 hid_t dset_id=-1;
1913 hid_t plist_id=-1;
1914 hid_t space_id=-1;
1915 hid_t group1_id, group2_id;
1916 hid_t attr1_id, attr2_id;
1917 hid_t attr_type_id;
1918 int x, y;
1919 herr_t ret;
1920 char attr_string[NAME_BUF_SIZE];
1921 char attr_correct_string[NAME_BUF_SIZE];
1922 char attr_name[NAME_BUF_SIZE];
1923 int ndims;
1924 hsize_t dims[SIZE2_RANK2];
1925 hsize_t correct_dims[SIZE2_RANK2] = SIZE2_DIMS;
1926
1927 file_id = H5Fopen(FILENAME, H5F_ACC_RDONLY, H5P_DEFAULT);
1928 CHECK_I(file_id, "H5Fopen");
1929
1930
1931 /* Verify property lists and dataspaces */
1932
1933 /* Get property lists from first batch of datasets */
1934 for(x = 0; x < NUM_DATASETS; ++x) {
1935 dset_id = H5Dopen2(file_id, DSETNAME[x], H5P_DEFAULT);
1936 CHECK_I(dset_id, "H5Dopen2");
1937 plist_id = H5Dget_create_plist(dset_id);
1938 CHECK_I(plist_id, "H5Dget_create_plist");
1939 size2_verify_plist1(plist_id);
1940 ret = H5Pclose(plist_id);
1941 CHECK_I(ret, "H5Pclose");
1942
1943 space_id = H5Dget_space(dset_id);
1944 CHECK_I(space_id, "H5Dget_space");
1945 ndims = H5Sget_simple_extent_dims(space_id, dims, NULL);
1946 CHECK_I(ndims, "H5Sget_simple_extent_dims");
1947 VERIFY(ndims, SIZE2_RANK1, "H5Sget_simple_extent_dims");
1948 for(y = 0; y < ndims; ++y)
1949 VERIFY(dims[y], correct_dims[y], "H5Sget_simple_extent_dims");
1950
1951 ret = H5Sclose(space_id);
1952 CHECK_I(ret, "H5Sclose");
1953
1954 ret = H5Dclose(dset_id);
1955 CHECK_I(ret, "H5Dclose");
1956 }
1957
1958 /* Get property lists from second batch of datasets */
1959 group1_id = H5Gopen2(file_id, "group", H5P_DEFAULT);
1960 CHECK_I(group1_id, "H5Gopen2");
1961 for(x = 0; x < NUM_DATASETS; ++x) {
1962 dset_id = H5Dopen2(group1_id, DSETNAME[x], H5P_DEFAULT);
1963 CHECK_I(dset_id, "H5Dopen2");
1964 plist_id = H5Dget_create_plist(dset_id);
1965 CHECK_I(plist_id, "H5Dget_create_plist");
1966 size2_verify_plist2(plist_id);
1967 ret = H5Pclose(plist_id);
1968 CHECK_I(ret, "H5Pclose");
1969
1970 space_id = H5Dget_space(dset_id);
1971 CHECK_I(space_id, "H5Dget_space");
1972 ndims = H5Sget_simple_extent_dims(space_id, dims, NULL);
1973 CHECK_I(ndims, "H5Sget_simple_extent_dims");
1974 VERIFY(ndims, SIZE2_RANK2, "H5Sget_simple_extent_dims");
1975 for(y = 0; y < ndims; ++y)
1976 VERIFY(dims[y], correct_dims[y], "H5Sget_simple_extent_dims");
1977
1978 ret = H5Sclose(space_id);
1979 CHECK_I(ret, "H5Sclose");
1980
1981 ret = H5Dclose(dset_id);
1982 CHECK_I(ret, "H5Dclose");
1983 } /* end for */
1984 ret = H5Gclose(group1_id);
1985 CHECK_I(ret, "H5Gclose");
1986
1987 /* Get property lists from interleaved group of datasets */
1988 group1_id = H5Gopen2(file_id, "interleaved group", H5P_DEFAULT);
1989 CHECK_I(group1_id, "H5Gopen2");
1990 for(x = 0; x < NUM_DATASETS; x += 2) {
1991 /* First "type 1" dataset */
1992 dset_id = H5Dopen2(group1_id, DSETNAME[x], H5P_DEFAULT);
1993 CHECK_I(dset_id, "H5Dopen2");
1994 plist_id = H5Dget_create_plist(dset_id);
1995 CHECK_I(plist_id, "H5Dget_create_plist");
1996 size2_verify_plist1(plist_id);
1997 ret = H5Pclose(plist_id);
1998 CHECK_I(ret, "H5Pclose");
1999
2000 space_id = H5Dget_space(dset_id);
2001 CHECK_I(space_id, "H5Dget_space");
2002 ndims = H5Sget_simple_extent_dims(space_id, dims, NULL);
2003 CHECK_I(ndims, "H5Sget_simple_extent_dims");
2004 VERIFY(ndims, SIZE2_RANK1, "H5Sget_simple_extent_dims");
2005 for(y = 0; y < ndims; ++y)
2006 VERIFY(dims[y], correct_dims[y], "H5Sget_simple_extent_dims");
2007
2008 ret = H5Sclose(space_id);
2009 CHECK_I(ret, "H5Sclose");
2010
2011 ret = H5Dclose(dset_id);
2012 CHECK_I(ret, "H5Dclose");
2013
2014 /* Second "type 2" dataset */
2015 dset_id = H5Dopen2(group1_id, DSETNAME[x + 1], H5P_DEFAULT);
2016 CHECK_I(dset_id, "H5Dopen2");
2017 plist_id = H5Dget_create_plist(dset_id);
2018 CHECK_I(plist_id, "H5Dget_create_plist");
2019 size2_verify_plist2(plist_id);
2020 ret = H5Pclose(plist_id);
2021 CHECK_I(ret, "H5Pclose");
2022
2023 space_id = H5Dget_space(dset_id);
2024 CHECK_I(space_id, "H5Dget_space");
2025 ndims = H5Sget_simple_extent_dims(space_id, dims, NULL);
2026 CHECK_I(ndims, "H5Sget_simple_extent_dims");
2027 VERIFY(ndims, SIZE2_RANK2, "H5Sget_simple_extent_dims");
2028 for(y = 0; y < ndims; ++y)
2029 VERIFY(dims[y], correct_dims[y], "H5Sget_simple_extent_dims");
2030
2031 ret = H5Sclose(space_id);
2032 CHECK_I(ret, "H5Sclose");
2033
2034 ret = H5Dclose(dset_id);
2035 CHECK_I(ret, "H5Dclose");
2036 } /* end for */
2037 ret = H5Gclose(group1_id);
2038 CHECK_I(ret, "H5Gclose");
2039
2040
2041 /* Verify attributes */
2042
2043 /* Create attribute data type */
2044 attr_type_id = H5Tcopy(H5T_C_S1);
2045 CHECK_I(attr_type_id, "H5Tcopy");
2046 ret = H5Tset_size(attr_type_id, (size_t)NAME_BUF_SIZE);
2047 CHECK_I(ret, "H5Tset_size");
2048
2049 /* Read attributes on both groups and verify that they are correct */
2050 group1_id = H5Gopen2(file_id, "group", H5P_DEFAULT);
2051 CHECK_I(group1_id, "H5Gopen2");
2052 group2_id = H5Gopen2(file_id, "interleaved group", H5P_DEFAULT);
2053 CHECK_I(group2_id, "H5Gopen2");
2054
2055 HDmemset(attr_string, 0, (size_t)NAME_BUF_SIZE);
2056 HDmemset(attr_correct_string, 0, (size_t)NAME_BUF_SIZE);
2057 HDstrcpy(attr_correct_string, LONG_STRING);
2058 HDstrcpy(attr_name, "00 index");
2059
2060 for(x = 0; x < NUM_ATTRIBUTES; ++x) {
2061 /* Create the name and correct value for each attribute */
2062 attr_correct_string[0] = attr_name[0] = (char)((x / 10) + '0');
2063 attr_correct_string[1] = attr_name[1] = (char)((x % 10) + '0');
2064
2065 attr1_id = H5Aopen(group1_id, attr_name, H5P_DEFAULT);
2066 CHECK_I(attr1_id, "H5Aopen");
2067 attr2_id = H5Aopen(group2_id, attr_name, H5P_DEFAULT);
2068 CHECK_I(attr2_id, "H5Aopen");
2069
2070 ret = H5Aread(attr1_id, attr_type_id, attr_string);
2071 CHECK_I(ret, "H5Aread");
2072 VERIFY_STR(attr_string, attr_correct_string, "H5Aread");
2073 ret = H5Aread(attr2_id, attr_type_id, attr_string);
2074 CHECK_I(ret, "H5Aread");
2075 VERIFY_STR(attr_string, attr_correct_string, "H5Aread");
2076
2077 ret = H5Aclose(attr1_id);
2078 CHECK_I(attr1_id, "H5Aclose");
2079 ret = H5Aclose(attr2_id);
2080 CHECK_I(attr2_id, "H5Aclose");
2081 }
2082
2083 /* Close everything */
2084 ret = H5Tclose(attr_type_id);
2085 CHECK_I(ret, "H5Tclose");
2086 ret = H5Gclose(group1_id);
2087 CHECK_I(ret, "H5Gclose");
2088 ret = H5Gclose(group2_id);
2089 CHECK_I(ret, "H5Gclose");
2090 ret = H5Fclose(file_id);
2091 CHECK_I(ret, "H5Fclose");
2092 } /* size2_verify */
2093
2094
2095 /*-------------------------------------------------------------------------
2096 * Function: test_sohm_size2
2097 *
2098 * Purpose: Tests shared object header messages using size2_helper to
2099 * create different kinds of big messages.
2100 *
2101 * If close_reopen is set, closes and reopens the HDF5 file
2102 * repeatedly while writing.
2103 *
2104 * This test works by first creating FCPLs with various
2105 * parameters, then creating a standard file that includes
2106 * every kind of message that can be shared using the helper
2107 * function size2_helper. The test measures the size of the
2108 * file at various points. Once all of the files have been
2109 * generated, the test compares the measured sizes of the files.
2110 *
2111 *
2112 * Programmer: James Laird
2113 * Friday, November 17, 2006
2114 *
2115 *-------------------------------------------------------------------------
2116 */
2117 static void
test_sohm_size2(int close_reopen)2118 test_sohm_size2(int close_reopen)
2119 {
2120 hid_t fcpl_id = -1;
2121 /* Sizes for file with no shared messages at all */
2122 size2_helper_struct norm_sizes;
2123 /* Sizes for files with all messages in one index */
2124 size2_helper_struct list_index_med, list_index_big;
2125 size2_helper_struct btree_index, list_index_small;
2126 /* Sizes for files with messages in three different indexes */
2127 size2_helper_struct mult_index_med, mult_index_btree;
2128 /* Sizes for files that don't share all kinds of messages */
2129 size2_helper_struct share_some_med, share_some_btree;
2130 /* Sizes for files that share different sizes of messages */
2131 size2_helper_struct share_some_toobig_index, share_tiny_index, type_space_index;
2132 herr_t ret;
2133
2134 if(close_reopen == 0)
2135 MESSAGE(5, ("Testing that shared object header messages save space\n"))
2136 else
2137 MESSAGE(5, ("Testing that shared messages save space when file is closed and reopened\n"))
2138
2139 /* Create an fcpl with SOHMs disabled */
2140 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
2141 CHECK_I(fcpl_id, "H5Pcreate");
2142
2143 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 0);
2144 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
2145
2146 /* Get the file size & verify its contents */
2147 size2_helper(fcpl_id, close_reopen, &norm_sizes);
2148 size2_verify();
2149
2150 ret = H5Pclose(fcpl_id);
2151 CHECK_I(ret, "H5Pclose");
2152
2153
2154 /* Create an fcpl with one big index */
2155 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
2156 CHECK_I(fcpl_id, "H5Pcreate");
2157
2158 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 1);
2159 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
2160 ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_SHMESG_ALL_FLAG, 20);
2161 CHECK_I(ret, "H5Pset_shared_mesg_index");
2162
2163 /* Set the indexes to use a medium-sized list */
2164 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 30, 25);
2165 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
2166
2167 /* Get the file size & verify its contents */
2168 size2_helper(fcpl_id, close_reopen, &list_index_med);
2169 size2_verify();
2170
2171
2172 /* Try making the list really big */
2173 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 1000, 900);
2174 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
2175
2176 /* Get the file size & verify its contents */
2177 size2_helper(fcpl_id, close_reopen, &list_index_big);
2178 size2_verify();
2179
2180
2181 /* Use a B-tree instead of a list */
2182 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 0, 0);
2183 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
2184
2185 /* Get the file size & verify its contents */
2186 size2_helper(fcpl_id, close_reopen, &btree_index);
2187 size2_verify();
2188
2189
2190 /* Use such a small list that it'll become a B-tree */
2191 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 10, 0);
2192 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
2193
2194 /* Get the file size & verify its contents */
2195 size2_helper(fcpl_id, close_reopen, &list_index_small);
2196 size2_verify();
2197
2198 ret = H5Pclose(fcpl_id);
2199 CHECK_I(ret, "H5Pclose");
2200
2201
2202 /* Create a new property list that puts messages in different indexes. */
2203 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
2204 CHECK_I(fcpl_id, "H5Pcreate");
2205
2206 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 3);
2207 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
2208 ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_SHMESG_SDSPACE_FLAG | H5O_SHMESG_DTYPE_FLAG, 20);
2209 CHECK_I(ret, "H5Pset_shared_mesg_index");
2210 ret = H5Pset_shared_mesg_index(fcpl_id, 1, H5O_SHMESG_FILL_FLAG | H5O_SHMESG_PLINE_FLAG, 20);
2211 CHECK_I(ret, "H5Pset_shared_mesg_index");
2212 ret = H5Pset_shared_mesg_index(fcpl_id, 2, H5O_SHMESG_ATTR_FLAG, 20);
2213 CHECK_I(ret, "H5Pset_shared_mesg_index");
2214
2215 /* Use lists that are the same size as the "medium" list on the previous
2216 * run.
2217 */
2218 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 30, 25);
2219 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
2220
2221 /* Get the file size & verify its contents */
2222 size2_helper(fcpl_id, close_reopen, &mult_index_med);
2223 size2_verify();
2224
2225
2226 /* Use all B-trees */
2227 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 0, 0);
2228 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
2229
2230 /* Get the file size & verify its contents */
2231 size2_helper(fcpl_id, close_reopen, &mult_index_btree);
2232 size2_verify();
2233
2234
2235 /* Edit the same property list (this should work) and don't share all messages.
2236 */
2237 ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_SHMESG_PLINE_FLAG, 20);
2238 CHECK_I(ret, "H5Pset_shared_mesg_index");
2239 ret = H5Pset_shared_mesg_index(fcpl_id, 1, H5O_SHMESG_DTYPE_FLAG | H5O_SHMESG_FILL_FLAG, 100000);
2240 CHECK_I(ret, "H5Pset_shared_mesg_index");
2241 ret = H5Pset_shared_mesg_index(fcpl_id, 2, H5O_SHMESG_ATTR_FLAG | H5O_SHMESG_SDSPACE_FLAG, 20);
2242 CHECK_I(ret, "H5Pset_shared_mesg_index");
2243
2244 /* Use "normal-sized" lists. */
2245 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 30, 25);
2246 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
2247
2248 /* Get the file size & verify its contents */
2249 size2_helper(fcpl_id, close_reopen, &share_some_med);
2250 size2_verify();
2251
2252 /* Use btrees. */
2253 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 0, 0);
2254 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
2255
2256 /* Get the file size & verify its contents */
2257 size2_helper(fcpl_id, close_reopen, &share_some_btree);
2258 size2_verify();
2259
2260
2261 /* Change the second index to hold only gigantic messages. Result should
2262 * be the same as the previous file.
2263 */
2264 ret = H5Pset_shared_mesg_index(fcpl_id, 1, H5O_SHMESG_DTYPE_FLAG | H5O_SHMESG_FILL_FLAG, 100000);
2265 CHECK_I(ret, "H5Pset_shared_mesg_index");
2266
2267 /* Get the file size & verify its contents */
2268 size2_helper(fcpl_id, close_reopen, &share_some_toobig_index);
2269 size2_verify();
2270
2271
2272 /* Share even tiny dataspace and datatype messages. This should result in
2273 * attribute datatypes being shared. Make this one use "really big" lists.
2274 * It turns out that attribute dataspaces are just big enough that it saves
2275 * some space to share them, while sharing datatypes creates as much overhead
2276 * as one gains from sharing them.
2277 */
2278 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 1);
2279 ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_SHMESG_DTYPE_FLAG | H5O_SHMESG_SDSPACE_FLAG, 1);
2280 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 1000, 900);
2281
2282 /* Get the file size & verify its contents */
2283 size2_helper(fcpl_id, close_reopen, &share_tiny_index);
2284 size2_verify();
2285
2286 /* Create the same file but don't share the really tiny messages */
2287 ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_SHMESG_DTYPE_FLAG | H5O_SHMESG_SDSPACE_FLAG, 100);
2288 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 1000, 900);
2289
2290 /* Get the file size & verify its contents */
2291 size2_helper(fcpl_id, close_reopen, &type_space_index);
2292 size2_verify();
2293
2294 ret = H5Pclose(fcpl_id);
2295 CHECK_I(ret, "H5Pclose");
2296
2297
2298
2299 /* Check that all sizes make sense. There is lots of room for inexact
2300 * results here since so many different factors contribute to file size.
2301 */
2302
2303
2304 /* Check sizes of all files created using a single index first */
2305
2306 /* The empty size of each file with shared messages enabled should be the
2307 * same and should be bigger than a normal file.
2308 */
2309 if(norm_sizes.empty_size > list_index_med.empty_size)
2310 VERIFY(norm_sizes.empty_size, 1, "h5_get_file_size");
2311 if(list_index_med.empty_size != list_index_big.empty_size)
2312 VERIFY(list_index_med.empty_size, list_index_big.empty_size, "h5_get_file_size");
2313 if(list_index_med.empty_size != btree_index.empty_size)
2314 VERIFY(list_index_med.empty_size, btree_index.empty_size, "h5_get_file_size");
2315 if(list_index_med.empty_size != list_index_small.empty_size)
2316 VERIFY(list_index_med.empty_size, list_index_small.empty_size, "h5_get_file_size");
2317 /* The files with indexes shouldn't be that much bigger than an
2318 * empty file.
2319 */
2320 if(list_index_med.empty_size > (h5_stat_size_t)((float)norm_sizes.empty_size * OVERHEAD_ALLOWED))
2321 VERIFY(0, 1, "h5_get_file_size");
2322
2323
2324 /* Once one dataset has been created (with one of every kind of message),
2325 * the normal file should still be smallest. The very small list
2326 * btree_convert should be smaller than the B-tree since it has no
2327 * extra overhead. The small list should also be smaller than the B-tree.
2328 * The very large list should be much larger than anything else.
2329 */
2330 if(norm_sizes.first_dset >= list_index_small.first_dset)
2331 VERIFY(norm_sizes.first_dset, 1, "h5_get_file_size");
2332 if(list_index_small.first_dset >= btree_index.first_dset)
2333 VERIFY(list_index_small.first_dset, 1, "h5_get_file_size");
2334 if(list_index_med.first_dset >= btree_index.first_dset)
2335 VERIFY(btree_index.first_dset, 1, "h5_get_file_size");
2336 if(btree_index.first_dset >= list_index_big.first_dset)
2337 VERIFY(list_index_med.first_dset, 1, "h5_get_file_size");
2338
2339
2340 /* Once a few copies of the same dataset have been created, the
2341 * very small list shouldn't have become a B-tree yet, so it should
2342 * be the smallest file. A larger list should be next, followed
2343 * by a B-tree, followed by a normal file, followed by a
2344 * list that is too large.
2345 */
2346 if(list_index_small.dsets1 >= list_index_med.dsets1)
2347 VERIFY(btree_index.dsets1, 1, "h5_get_file_size");
2348 if(list_index_med.dsets1 >= btree_index.dsets1)
2349 VERIFY(list_index_med.dsets1, 1, "h5_get_file_size");
2350 if(btree_index.dsets1 >= norm_sizes.dsets1)
2351 VERIFY(btree_index.dsets1, 1, "h5_get_file_size");
2352 if(norm_sizes.dsets1 >= list_index_big.dsets1)
2353 VERIFY(list_index_big.dsets1, 1, "h5_get_file_size");
2354
2355 /* The size gain should have been the same for each of the lists;
2356 * their overhead is fixed. The B-tree should have gained at least
2357 * as much, and the normal file more than that.
2358 */
2359 if((list_index_small.dsets1 - list_index_small.first_dset) !=
2360 (list_index_med.dsets1 - list_index_med.first_dset))
2361 VERIFY(0, 1, "h5_get_file_size");
2362 if((list_index_med.dsets1 - list_index_med.first_dset) !=
2363 (list_index_big.dsets1 - list_index_big.first_dset))
2364 VERIFY(0, 1, "h5_get_file_size");
2365 if((list_index_big.dsets1 - list_index_big.first_dset) >
2366 (btree_index.dsets1 - btree_index.first_dset))
2367 VERIFY(0, 1, "h5_get_file_size");
2368 if((btree_index.dsets1 - btree_index.first_dset) >=
2369 (norm_sizes.dsets1 - norm_sizes.first_dset))
2370 VERIFY(0, 1, "h5_get_file_size");
2371
2372
2373 /* Once another kind of each message has been written, the very small list
2374 * should convert into a B-tree. Now the list should be smallest, then
2375 * the B-trees (although the converted B-tree file may be a little bigger),
2376 * then the normal file. The largest list may or may not be bigger than
2377 * the normal file.
2378 */
2379 if(list_index_med.dsets2 >= btree_index.dsets2)
2380 VERIFY(list_index_med.dsets2, 1, "h5_get_file_size");
2381 if(btree_index.dsets2 > (h5_stat_size_t)((float)list_index_small.dsets2 * OVERHEAD_ALLOWED))
2382 VERIFY(btree_index.dsets2, list_index_small.dsets2, "h5_get_file_size");
2383 if(list_index_small.dsets2 >= norm_sizes.dsets2)
2384 VERIFY(btree_index.dsets2, 1, "h5_get_file_size");
2385 /* If the small list (now a B-tree) is bigger than the existing B-tree,
2386 * it shouldn't be much bigger.
2387 * It seems that the small lists tends to be pretty big anyway. Allow
2388 * for it to have twice as much overhead.
2389 */
2390 if(list_index_small.dsets2 > (h5_stat_size_t)((float)btree_index.dsets2 * OVERHEAD_ALLOWED * OVERHEAD_ALLOWED))
2391 VERIFY(0, 1, "h5_get_file_size");
2392 /* The lists should have grown the least since they share messages and
2393 * have no extra overhead. The normal file should have grown more than
2394 * either the lists or the B-tree. The B-tree may not have grown more
2395 * than the lists, depending on whether it needed to split nodes or not.
2396 */
2397 if((list_index_med.dsets2 - list_index_med.dsets1) !=
2398 (list_index_big.dsets2 - list_index_big.dsets1))
2399 VERIFY(0, 1, "h5_get_file_size");
2400 if((list_index_big.dsets2 - list_index_big.dsets1) >
2401 (btree_index.dsets2 - btree_index.dsets1))
2402 VERIFY(0, 1, "h5_get_file_size");
2403 if((btree_index.dsets2 - btree_index.dsets1) >=
2404 (norm_sizes.dsets2 - norm_sizes.dsets1))
2405 VERIFY(0, 1, "h5_get_file_size");
2406
2407
2408 /* Interleaving the writes should have no effect on how the messages are
2409 * shared. No new messages should be written to the indexes, so the
2410 * sohm files will only get a little bit bigger.
2411 */
2412 if(list_index_med.interleaved >= btree_index.interleaved)
2413 VERIFY(0, 1, "h5_get_file_size");
2414 if(btree_index.interleaved > (h5_stat_size_t)((float)list_index_small.interleaved * OVERHEAD_ALLOWED))
2415 VERIFY(btree_index.interleaved, list_index_small.interleaved, "h5_get_file_size");
2416 if(list_index_small.interleaved >= norm_sizes.interleaved)
2417 VERIFY(0, 1, "h5_get_file_size");
2418 /* The lists should still have grown the same amount. The converted
2419 * B-tree shouldn't have grown more than the index that was originally
2420 * a B-tree (although it might have grown less if there was extra free
2421 * space within the file).
2422 */
2423 if((list_index_med.interleaved - list_index_med.dsets2) !=
2424 (list_index_big.interleaved - list_index_big.dsets2))
2425 VERIFY(0, 1, "h5_get_file_size");
2426 if((list_index_big.interleaved - list_index_big.dsets2) >
2427 (btree_index.interleaved - btree_index.dsets2))
2428 VERIFY(0, 1, "h5_get_file_size");
2429 if((list_index_small.interleaved - list_index_small.dsets2) >
2430 (btree_index.interleaved - btree_index.dsets2))
2431 VERIFY(0, 1, "h5_get_file_size");
2432 if((btree_index.interleaved - btree_index.dsets2) >=
2433 (norm_sizes.interleaved - norm_sizes.dsets2))
2434 VERIFY(0, 1, "h5_get_file_size");
2435
2436 /* After many attributes have been written, both the small and medium lists
2437 * should have become B-trees and be about the same size as the index
2438 * that started as a B-tree.
2439 * Add in OVERHEAD_ALLOWED as a fudge factor here, since the allocation
2440 * of file space can be hard to predict.
2441 */
2442 if(btree_index.attrs1 > (h5_stat_size_t)((float)list_index_small.attrs1 * OVERHEAD_ALLOWED))
2443 VERIFY(btree_index.attrs1, list_index_small.attrs1, "h5_get_file_size");
2444 if(btree_index.attrs1 > (h5_stat_size_t)((float)list_index_med.attrs1 * OVERHEAD_ALLOWED))
2445 VERIFY(0, 1, "h5_get_file_size");
2446 if(list_index_med.attrs1 > (h5_stat_size_t)((float)btree_index.attrs1 * OVERHEAD_ALLOWED))
2447 VERIFY(0, 1, "h5_get_file_size");
2448 if(list_index_small.attrs1 > (h5_stat_size_t)((float)btree_index.attrs1 * OVERHEAD_ALLOWED))
2449 VERIFY(0, 1, "h5_get_file_size");
2450 /* Neither of the converted lists should be too much bigger than
2451 * the index that was originally a B-tree.
2452 */
2453 if(list_index_small.attrs1 > (h5_stat_size_t)((float)btree_index.attrs1 * OVERHEAD_ALLOWED))
2454 VERIFY(0, 1, "h5_get_file_size");
2455 if(list_index_med.attrs1 > (h5_stat_size_t)((float)btree_index.attrs1 * OVERHEAD_ALLOWED))
2456 VERIFY(0, 1, "h5_get_file_size");
2457 /* The "normal" file should have had less overhead, so should gain less
2458 * size than any of the other indexes since none of these attribute
2459 * messages could be shared. The large list should have gained
2460 * less overhead than the B-tree indexes.
2461 */
2462 if((norm_sizes.attrs1 - norm_sizes.interleaved) >=
2463 (list_index_big.attrs1 - list_index_big.interleaved))
2464 VERIFY(0, 1, "h5_get_file_size");
2465 if((list_index_big.attrs1 - list_index_big.interleaved) >=
2466 (list_index_small.attrs1 - list_index_small.interleaved))
2467 VERIFY(0, 1, "h5_get_file_size");
2468
2469 /* Give it some overhead (for checkin to move messages into continuation message) */
2470 if((list_index_small.attrs1 - list_index_small.interleaved) >
2471 (h5_stat_size_t)((float)(btree_index.attrs1 - btree_index.interleaved) * OVERHEAD_ALLOWED))
2472 VERIFY(0, 1, "h5_get_file_size");
2473
2474
2475 /* Writing another copy of each attribute shouldn't change the ordering
2476 * of sizes. The big list index is still too big to be smaller than a
2477 * normal file. The B-tree indexes should all be about the same size.
2478 */
2479 if(btree_index.attrs2 > (h5_stat_size_t)((float)list_index_small.attrs2 * OVERHEAD_ALLOWED))
2480 VERIFY(btree_index.attrs2, list_index_small.attrs2, "h5_get_file_size");
2481 if(list_index_small.attrs2 > (h5_stat_size_t)((float)btree_index.attrs2 * OVERHEAD_ALLOWED))
2482 VERIFY(0, 1, "h5_get_file_size");
2483 if(btree_index.attrs2 > (h5_stat_size_t)((float)list_index_med.attrs2 * OVERHEAD_ALLOWED))
2484 VERIFY(0, 1, "h5_get_file_size");
2485 if(list_index_med.attrs2 > (h5_stat_size_t)((float)btree_index.attrs2 * OVERHEAD_ALLOWED))
2486 VERIFY(0, 1, "h5_get_file_size");
2487 if(list_index_med.attrs2 >= norm_sizes.attrs2)
2488 VERIFY(0, 1, "h5_get_file_size");
2489 if(list_index_big.attrs2 >= norm_sizes.attrs2)
2490 VERIFY(0, 1, "h5_get_file_size");
2491 /* All of the B-tree indexes should have gained about the same amount
2492 * of space; at least as much as the list index and less than a normal
2493 * file.
2494 */
2495 if((list_index_small.attrs2 - list_index_small.attrs1) >
2496 (btree_index.attrs2 - btree_index.attrs1))
2497 VERIFY(0, 1, "h5_get_file_size");
2498 if((list_index_med.attrs2 - list_index_med.attrs1) >
2499 (btree_index.attrs2 - btree_index.attrs1))
2500 VERIFY(0, 1, "h5_get_file_size");
2501 if((list_index_big.attrs2 - list_index_big.attrs1) >
2502 (list_index_med.attrs2 - list_index_med.attrs1))
2503 VERIFY(0, 1, "h5_get_file_size");
2504 if((btree_index.attrs2 - btree_index.attrs1) >=
2505 (norm_sizes.attrs2 - norm_sizes.attrs1))
2506 VERIFY(0, 1, "h5_get_file_size");
2507
2508 /* Done checking the first few files that use a single index. */
2509
2510
2511 /* Start comparing other kinds of files with these "standard"
2512 * one-index files
2513 */
2514
2515 /* Check files with multiple indexes. */
2516 /* These files should be larger when first created than one-index
2517 * files.
2518 */
2519 if(mult_index_med.empty_size <= list_index_med.empty_size)
2520 VERIFY(0, 1, "h5_get_file_size");
2521 if(mult_index_btree.empty_size != mult_index_med.empty_size)
2522 VERIFY(0, 1, "h5_get_file_size");
2523
2524 /* When the first dataset is written, they should grow quite a bit as
2525 * many different indexes must be created.
2526 */
2527 if((mult_index_med.first_dset - mult_index_med.empty_size) <=
2528 (list_index_med.first_dset - list_index_med.empty_size))
2529 VERIFY(0, 1, "h5_get_file_size");
2530 if((mult_index_btree.first_dset - mult_index_btree.empty_size) <=
2531 (btree_index.first_dset - btree_index.empty_size))
2532 VERIFY(0, 1, "h5_get_file_size");
2533
2534 /* When the second dataset is written, they should grow less as
2535 * some extra heap space is allocated, but no more indices.
2536 */
2537 if((mult_index_med.second_dset - mult_index_med.first_dset) >
2538 (mult_index_med.first_dset - mult_index_med.empty_size))
2539 VERIFY(0, 1, "h5_get_file_size");
2540 if((list_index_med.second_dset - list_index_med.first_dset) >
2541 (list_index_med.first_dset - list_index_med.empty_size))
2542 VERIFY(0, 1, "h5_get_file_size");
2543 if((mult_index_btree.second_dset - mult_index_btree.first_dset) >
2544 (mult_index_btree.first_dset - mult_index_btree.empty_size))
2545 VERIFY(0, 1, "h5_get_file_size");
2546 if((btree_index.second_dset - btree_index.first_dset) >
2547 (btree_index.first_dset - btree_index.empty_size))
2548 VERIFY(0, 1, "h5_get_file_size");
2549
2550 /* And the size delta for the second dataset is less in files with only
2551 * one index.
2552 */
2553 if((mult_index_med.second_dset - mult_index_med.first_dset) <=
2554 (list_index_med.second_dset - list_index_med.first_dset))
2555 VERIFY(0, 1, "h5_get_file_size");
2556 if((mult_index_btree.first_dset - mult_index_btree.empty_size) <=
2557 (btree_index.first_dset - btree_index.empty_size))
2558 VERIFY(0, 1, "h5_get_file_size");
2559
2560 /* Once that initial overhead is out of the way and the lists/btrees
2561 * have been created, files with more than one index should grow at
2562 * the same rate or slightly faster than files with just one index
2563 * and one heap.
2564 */
2565 if((mult_index_med.dsets1 - mult_index_med.second_dset) !=
2566 (list_index_med.dsets1 - list_index_med.second_dset))
2567 VERIFY((mult_index_med.dsets1 - mult_index_med.second_dset), (list_index_med.dsets1 - list_index_med.second_dset), "h5_get_file_size");
2568 if((mult_index_btree.dsets1 - mult_index_btree.second_dset) !=
2569 (btree_index.dsets1 - btree_index.second_dset))
2570 VERIFY((mult_index_btree.dsets1 - mult_index_btree.second_dset), (btree_index.dsets1 - btree_index.second_dset), "h5_get_file_size");
2571
2572 if((mult_index_med.dsets2 - mult_index_med.dsets1) >
2573 (h5_stat_size_t)((float)(list_index_med.dsets2 - list_index_med.dsets1) * OVERHEAD_ALLOWED))
2574 VERIFY(0, 1, "h5_get_file_size");
2575 if((mult_index_btree.dsets2 - mult_index_btree.dsets1) >
2576 (h5_stat_size_t)((float)(btree_index.dsets2 - btree_index.dsets1) * OVERHEAD_ALLOWED))
2577 VERIFY(0, 1, "h5_get_file_size");
2578
2579 if((mult_index_med.interleaved - mult_index_med.dsets2) >
2580 (h5_stat_size_t)((float)(list_index_med.interleaved - list_index_med.dsets2) * OVERHEAD_ALLOWED))
2581 VERIFY(0, 1, "h5_get_file_size");
2582 if((mult_index_btree.interleaved - mult_index_btree.dsets2) >
2583 (h5_stat_size_t)((float)(btree_index.interleaved - btree_index.dsets2) * OVERHEAD_ALLOWED))
2584 VERIFY(0, 1, "h5_get_file_size");
2585
2586 /* When all the attributes are added, only the index holding attributes
2587 * will become a B-tree. Skip the interleaved to attrs1 interval when
2588 * this happens because it's hard to predict exactly how much space this
2589 * will take.
2590 */
2591 if((mult_index_med.attrs2 - mult_index_med.attrs1) >
2592 (h5_stat_size_t)((float)(list_index_med.attrs2 - list_index_med.attrs1) * OVERHEAD_ALLOWED))
2593 VERIFY(0, 1, "h5_get_file_size");
2594 if((mult_index_btree.attrs2 - mult_index_btree.attrs1) >
2595 (h5_stat_size_t)((float)(btree_index.attrs2 - btree_index.attrs1) * OVERHEAD_ALLOWED))
2596 VERIFY(0, 1, "h5_get_file_size");
2597
2598 /* The final file size for both of the multiple index files should be
2599 * smaller than a normal file but bigger than any of the one-index files.
2600 */
2601 if(mult_index_med.attrs2 >= norm_sizes.attrs2)
2602 VERIFY(0, 1, "h5_get_file_size");
2603 if(mult_index_btree.attrs2 >= norm_sizes.attrs2)
2604 VERIFY(0, 1, "h5_get_file_size");
2605 if((h5_stat_size_t)((float)mult_index_med.attrs2 * OVERHEAD_ALLOWED) < btree_index.attrs2)
2606 VERIFY(0, 1, "h5_get_file_size");
2607 if((h5_stat_size_t)((float)mult_index_btree.attrs2 * OVERHEAD_ALLOWED) < btree_index.attrs2)
2608 VERIFY(0, 1, "h5_get_file_size");
2609
2610
2611 /* Check files that don't share all messages. */
2612 /* These files have three indexes like the files above, so they should be
2613 * the same size when created.
2614 */
2615 if(share_some_med.empty_size != mult_index_med.empty_size)
2616 VERIFY(0, 1, "h5_get_file_size");
2617 if(share_some_med.empty_size != share_some_btree.empty_size)
2618 VERIFY(0, 1, "h5_get_file_size");
2619
2620 /* When the first dataset is created, they should be not quite as big
2621 * as equivalent files that share all messages (since shared messages
2622 * have a little bit of overhead).
2623 */
2624 if(share_some_med.first_dset >= mult_index_med.first_dset)
2625 VERIFY(0, 1, "h5_get_file_size");
2626 if(share_some_btree.first_dset >= mult_index_btree.first_dset)
2627 VERIFY(0, 1, "h5_get_file_size");
2628
2629 /* The files that share some should have a growth rate in between
2630 * files that share all messages and normal files
2631 */
2632 if((share_some_med.interleaved - share_some_med.first_dset) <=
2633 (mult_index_med.interleaved - mult_index_med.first_dset))
2634 VERIFY(0, 1, "h5_get_file_size");
2635 if((share_some_med.interleaved - share_some_med.first_dset) >=
2636 (norm_sizes.interleaved - norm_sizes.first_dset))
2637 VERIFY(0, 1, "h5_get_file_size");
2638 if((share_some_btree.interleaved - share_some_btree.first_dset) <=
2639 (mult_index_btree.interleaved - mult_index_btree.first_dset))
2640 VERIFY(0, 1, "h5_get_file_size");
2641 if((share_some_btree.interleaved - share_some_btree.first_dset) >=
2642 (norm_sizes.interleaved - norm_sizes.first_dset))
2643 VERIFY(0, 1, "h5_get_file_size");
2644
2645
2646 /* Check the file that only stored gigantic messages in its second
2647 * index. Since no messages were that big, it should be identical
2648 * to the file with an empty index.
2649 */
2650 if(share_some_btree.empty_size != share_some_toobig_index.empty_size)
2651 VERIFY(0, 1, "h5_get_file_size");
2652 if(share_some_btree.first_dset != share_some_toobig_index.first_dset)
2653 VERIFY(0, 1, "h5_get_file_size");
2654 if(share_some_btree.dsets1 != share_some_toobig_index.dsets1)
2655 VERIFY(0, 1, "h5_get_file_size");
2656 if(share_some_btree.dsets2 != share_some_toobig_index.dsets2)
2657 VERIFY(0, 1, "h5_get_file_size");
2658 if(share_some_btree.interleaved != share_some_toobig_index.interleaved)
2659 VERIFY(0, 1, "h5_get_file_size");
2660 if(share_some_btree.attrs1 != share_some_toobig_index.attrs1)
2661 VERIFY(0, 1, "h5_get_file_size");
2662 if(share_some_btree.attrs2 != share_some_toobig_index.attrs2)
2663 VERIFY(0, 1, "h5_get_file_size");
2664
2665
2666 /* Check the file that shares even very tiny messages. Once messages
2667 * are written to it, it should gain a little space from sharing the
2668 * messages and lose a little space to overhead so that it's just slightly
2669 * smaller than a file that doesn't share tiny messages.
2670 * If the overhead increases or the size of messages decreases, these
2671 * numbers may be off.
2672 */
2673 if(share_tiny_index.empty_size != type_space_index.empty_size)
2674 VERIFY(share_tiny_index.empty_size, type_space_index.empty_size, "h5_get_file_size");
2675
2676 if(share_tiny_index.first_dset >= (h5_stat_size_t)((float)type_space_index.first_dset * OVERHEAD_ALLOWED))
2677 VERIFY(share_tiny_index.first_dset, type_space_index.first_dset, "h5_get_file_size");
2678 if(share_tiny_index.first_dset < type_space_index.first_dset)
2679 VERIFY(0, 1, "h5_get_file_size");
2680
2681 if(share_tiny_index.second_dset >= type_space_index.second_dset)
2682 VERIFY(share_tiny_index.second_dset, type_space_index.second_dset, "h5_get_file_size");
2683 if((h5_stat_size_t)((float)share_tiny_index.second_dset * OVERHEAD_ALLOWED) < type_space_index.second_dset)
2684 VERIFY(0, 1, "h5_get_file_size");
2685
2686 if(share_tiny_index.dsets1 >= type_space_index.dsets1)
2687 VERIFY(0, 1, "h5_get_file_size");
2688 if((h5_stat_size_t)((float)share_tiny_index.dsets1 * OVERHEAD_ALLOWED) < type_space_index.dsets1)
2689 VERIFY(0, 1, "h5_get_file_size");
2690
2691 if(share_tiny_index.dsets2 >= type_space_index.dsets2)
2692 VERIFY(0, 1, "h5_get_file_size");
2693 if((h5_stat_size_t)((float)share_tiny_index.dsets2 * OVERHEAD_ALLOWED) < type_space_index.dsets2)
2694 VERIFY(0, 1, "h5_get_file_size");
2695
2696 if(share_tiny_index.interleaved >= type_space_index.interleaved)
2697 VERIFY(0, 1, "h5_get_file_size");
2698 if((h5_stat_size_t)((float)share_tiny_index.interleaved * OVERHEAD_ALLOWED) < type_space_index.interleaved)
2699 VERIFY(0, 1, "h5_get_file_size");
2700
2701 if(share_tiny_index.attrs1 >= type_space_index.attrs1)
2702 VERIFY(0, 1, "h5_get_file_size");
2703 if((h5_stat_size_t)((float)share_tiny_index.attrs1 * OVERHEAD_ALLOWED) < type_space_index.attrs1)
2704 VERIFY(0, 1, "h5_get_file_size");
2705
2706 if(share_tiny_index.attrs2 >= type_space_index.attrs2)
2707 VERIFY(0, 1, "h5_get_file_size");
2708 if((h5_stat_size_t)((float)share_tiny_index.attrs2 * OVERHEAD_ALLOWED) < type_space_index.attrs2)
2709 VERIFY(0, 1, "h5_get_file_size");
2710 } /* test_sohm_size2 */
2711
2712
2713 /*-------------------------------------------------------------------------
2714 * Function: delete_helper_write
2715 *
2716 * Purpose: Creates a dataset and attribute in file FILE_ID using value X
2717 * in the DSPACE_ID and DCPL_ID arrays.
2718 *
2719 * Programmer: James Laird
2720 * Tuesday, December 19, 2006
2721 *
2722 * Modifications:
2723 *
2724 *-------------------------------------------------------------------------
2725 */
2726 static void
delete_helper_write(hid_t file_id,hid_t * dspace_id,hid_t * dcpl_id,int x)2727 delete_helper_write(hid_t file_id, hid_t *dspace_id, hid_t *dcpl_id, int x)
2728 {
2729 hid_t dset_id = -1;
2730 hid_t attr_id = -1;
2731 char wdata;
2732 herr_t ret;
2733
2734 dset_id = H5Dcreate2(file_id, DSETNAME[x], H5T_NATIVE_CHAR, dspace_id[x], H5P_DEFAULT, dcpl_id[x], H5P_DEFAULT);
2735 CHECK_I(dset_id, "H5Dcreate2");
2736 wdata = (char)(x + 'a');
2737 ret = H5Dwrite(dset_id, H5T_NATIVE_CHAR, dspace_id[x], dspace_id[x], H5P_DEFAULT, &wdata);
2738 CHECK_I(ret, "H5Dwrite");
2739
2740 attr_id = H5Acreate2(dset_id, "attr_name", H5T_NATIVE_CHAR, dspace_id[x], H5P_DEFAULT, H5P_DEFAULT);
2741 CHECK_I(attr_id, "H5Acreate2");
2742 ret = H5Awrite(attr_id, H5T_NATIVE_CHAR, &wdata);
2743 CHECK_I(ret, "H5Awrite");
2744
2745 ret = H5Aclose(attr_id);
2746 CHECK_I(ret, "H5Aclose");
2747 ret = H5Dclose(dset_id);
2748 CHECK_I(ret, "H5Dclose");
2749 } /* delete_helper_write */
2750
2751
2752 /*-------------------------------------------------------------------------
2753 * Function: delete_helper_read
2754 *
2755 * Purpose: Checks the value of the dataset and attribute created by
2756 * delete_helper_write.
2757 *
2758 * Programmer: James Laird
2759 * Tuesday, December 19, 2006
2760 *
2761 * Modifications:
2762 *
2763 *-------------------------------------------------------------------------
2764 */
2765 static void
delete_helper_read(hid_t file_id,hid_t * dspace_id,int x)2766 delete_helper_read(hid_t file_id, hid_t *dspace_id, int x)
2767 {
2768 hid_t dset_id = -1;
2769 hid_t attr_id = -1;
2770 char rdata;
2771 herr_t ret;
2772
2773 dset_id = H5Dopen2(file_id, DSETNAME[x], H5P_DEFAULT);
2774 CHECK_I(dset_id, "H5Dopen2");
2775 rdata = '\0';
2776 ret = H5Dread(dset_id, H5T_NATIVE_CHAR, dspace_id[x], dspace_id[x], H5P_DEFAULT, &rdata);
2777 CHECK_I(ret, "H5Dread");
2778 VERIFY(rdata, (x + 'a'), "H5Dread");
2779
2780 attr_id = H5Aopen(dset_id, "attr_name", H5P_DEFAULT);
2781 CHECK_I(attr_id, "H5Aopen");
2782 rdata = '\0';
2783 ret = H5Aread(attr_id, H5T_NATIVE_CHAR, &rdata);
2784 CHECK_I(ret, "H5Dread");
2785 VERIFY(rdata, (x + 'a'), "H5Dread");
2786
2787 ret = H5Aclose(attr_id);
2788 CHECK_I(ret, "H5Aclose");
2789 ret = H5Dclose(dset_id);
2790 CHECK_I(ret, "H5Dclose");
2791 } /* delete_helper_read */
2792
2793
2794 /*-------------------------------------------------------------------------
2795 * Function: delete_helper
2796 *
2797 * Purpose: Creates some shared messages, deletes them, and creates some
2798 * more messages. The second batch of messages should use the
2799 * space freed by the first batch, so should be about the same
2800 * size as a file that never had the first batch of messages
2801 * created.
2802 *
2803 * FCPL_ID is the file creation property list to use.
2804 * DSPACE_ID and DCPL_ID are arrays of different dataspaces
2805 * and property lists with filter pipelines used to create the
2806 * messages.
2807 *
2808 * Programmer: James Laird
2809 * Tuesday, December 19, 2006
2810 *
2811 * Modifications:
2812 *
2813 *-------------------------------------------------------------------------
2814 */
2815 static void
delete_helper(hid_t fcpl_id,hid_t * dspace_id,hid_t * dcpl_id)2816 delete_helper(hid_t fcpl_id, hid_t *dspace_id, hid_t *dcpl_id)
2817 {
2818 hid_t file_id=-1;
2819 int x;
2820 h5_stat_size_t norm_filesize;
2821 h5_stat_size_t deleted_filesize;
2822 herr_t ret;
2823
2824 /* Get the size of a "normal" file with no deleted messages */
2825 file_id = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
2826 CHECK_I(file_id, "H5Fcreate");
2827
2828 /* Create batch of messages in the file starting at message 2 */
2829 for(x=HALF_DELETE_NUM_MESGS; x<DELETE_NUM_MESGS; ++x) {
2830 delete_helper_write(file_id, dspace_id, dcpl_id, x);
2831 }
2832
2833 /* Check that messages can be read */
2834 for(x=HALF_DELETE_NUM_MESGS; x<DELETE_NUM_MESGS; ++x) {
2835 delete_helper_read(file_id, dspace_id, x);
2836 }
2837
2838 /* Close file and get filesize */
2839 ret = H5Fclose(file_id);
2840 CHECK_I(ret, "H5Fclose");
2841 norm_filesize = h5_get_file_size(FILENAME, H5P_DEFAULT);
2842
2843 /* Create a new file with messages 0 to (HALF_DELETE_NUM_MESGS - 1) */
2844 file_id = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
2845 CHECK_I(file_id, "H5Fcreate");
2846
2847 for(x=0; x<HALF_DELETE_NUM_MESGS; ++x) {
2848 delete_helper_write(file_id, dspace_id, dcpl_id, x);
2849 }
2850
2851 /* Verify each dataset, then delete it (which should delete
2852 * its shared messages as well
2853 */
2854 for(x=0; x<HALF_DELETE_NUM_MESGS; ++x) {
2855 delete_helper_read(file_id, dspace_id, x);
2856 ret = H5Ldelete(file_id, DSETNAME[x], H5P_DEFAULT);
2857 CHECK_I(ret, "H5Ldelete");
2858 }
2859
2860 /* The file is now empty. Write and verify the second batch of messages
2861 * again.
2862 */
2863 for(x=HALF_DELETE_NUM_MESGS; x<DELETE_NUM_MESGS; ++x) {
2864 delete_helper_write(file_id, dspace_id, dcpl_id, x);
2865 }
2866 for(x=HALF_DELETE_NUM_MESGS; x<DELETE_NUM_MESGS; ++x) {
2867 delete_helper_read(file_id, dspace_id, x);
2868 }
2869
2870 /* Close file and get filesize */
2871 ret = H5Fclose(file_id);
2872 CHECK_I(ret, "H5Fclose");
2873 deleted_filesize = h5_get_file_size(FILENAME, H5P_DEFAULT);
2874
2875 /* The two filesizes should be almost the same */
2876 if(norm_filesize > (h5_stat_size_t)((float)deleted_filesize * OVERHEAD_ALLOWED))
2877 VERIFY(norm_filesize, deleted_filesize, "h5_get_file_size");
2878 if(deleted_filesize > (h5_stat_size_t)((float)norm_filesize * OVERHEAD_ALLOWED))
2879 VERIFY(deleted_filesize, norm_filesize, "h5_get_file_size");
2880 } /* delete_helper */
2881
2882
2883 /*-------------------------------------------------------------------------
2884 * Function: test_sohm_delete
2885 *
2886 * Purpose: Tests shared object header message deletion.
2887 *
2888 * Creates lots of shared messages, then ensures that they
2889 * can be deleted without corrupting the remaining messages.
2890 * Also checks that indexes convert from B-trees back into
2891 * lists.
2892 *
2893 * Programmer: James Laird
2894 * Tuesday, December 19, 2006
2895 *
2896 * Modifications:
2897 *
2898 *-------------------------------------------------------------------------
2899 */
2900 static void
test_sohm_delete(void)2901 test_sohm_delete(void)
2902 {
2903 hid_t fcpl_id;
2904 /* We'll use dataspaces and filter pipelines for this test.
2905 * Create a number of distinct messages of each type.
2906 */
2907 hid_t dspace_id[DELETE_NUM_MESGS] = {0};
2908 hid_t dcpl_id[DELETE_NUM_MESGS] = {0};
2909 unsigned u;
2910 int x;
2911 hsize_t dims[] = DELETE_DIMS;
2912 herr_t ret;
2913
2914 MESSAGE(5, ("Testing deletion of SOHMs\n"));
2915
2916 /* Create a number of different dataspaces.
2917 * For simplicity, each dataspace has only one element.
2918 */
2919 for(u = 0; u < DELETE_NUM_MESGS; ++u) {
2920 dspace_id[u] = H5Screate_simple((int)(u + 1), dims, dims);
2921 CHECK_I(dspace_id[u], "H5Screate_simple");
2922 } /* end for */
2923
2924 /* Create a number of different filter pipelines. */
2925 dcpl_id[0] = H5Pcreate(H5P_DATASET_CREATE);
2926 CHECK_I(dcpl_id[0], "H5Pcreate");
2927
2928 ret = H5Pset_chunk(dcpl_id[0], 1, dims);
2929 CHECK_I(ret, "H5Pset_chunk");
2930 ret = H5Pset_shuffle(dcpl_id[0]);
2931 CHECK_I(ret, "H5Pset_shuffle");
2932
2933 for(u = 1; u < DELETE_NUM_MESGS; u += 2) {
2934 dcpl_id[u] = H5Pcopy(dcpl_id[u - 1]);
2935 CHECK_I(dcpl_id[u], "H5Pcopy");
2936 ret = H5Pset_chunk(dcpl_id[u], (int)(u + 1), dims);
2937 CHECK_I(ret, "H5Pset_chunk");
2938 ret = H5Pset_deflate(dcpl_id[u], 1);
2939 CHECK_I(ret, "H5Pset_deflate");
2940
2941 dcpl_id[u + 1] = H5Pcopy(dcpl_id[u]);
2942 CHECK_I(dcpl_id[u + 1], "H5Pcopy");
2943 ret = H5Pset_chunk(dcpl_id[u + 1], (int)(u + 2), dims);
2944 CHECK_I(ret, "H5Pset_chunk");
2945 ret = H5Pset_shuffle(dcpl_id[u + 1]);
2946 CHECK_I(ret, "H5Pset_shuffle");
2947 } /* end for */
2948
2949 /* Create an fcpl where all messages are shared in the same index */
2950 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
2951 CHECK_I(fcpl_id, "H5Pcreate");
2952 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 1);
2953 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
2954 ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_SHMESG_ALL_FLAG, 16);
2955 CHECK_I(ret, "H5Pset_shared_mesg_index");
2956
2957
2958 /* Use big list indexes */
2959 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 4 * DELETE_NUM_MESGS, 0);
2960 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
2961
2962 /* Test that messages can be created and deleted properly */
2963 delete_helper(fcpl_id, dspace_id, dcpl_id);
2964
2965 /* Use B-tree indexes */
2966 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 0, 0);
2967 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
2968
2969 delete_helper(fcpl_id, dspace_id, dcpl_id);
2970
2971
2972 /* Use small list indexes that will convert from lists to B-trees and back */
2973 ret = H5Pset_shared_mesg_phase_change(fcpl_id, HALF_DELETE_NUM_MESGS, HALF_DELETE_NUM_MESGS - 1);
2974 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
2975
2976 delete_helper(fcpl_id, dspace_id, dcpl_id);
2977
2978
2979 /* Use two indexes */
2980 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 2);
2981 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
2982 ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_SHMESG_SDSPACE_FLAG | H5O_SHMESG_ATTR_FLAG, 16);
2983 CHECK_I(ret, "H5Pset_shared_mesg_index");
2984 ret = H5Pset_shared_mesg_index(fcpl_id, 1, H5O_SHMESG_DTYPE_FLAG, 16);
2985 CHECK_I(ret, "H5Pset_shared_mesg_index");
2986
2987 /* Use big list indexes */
2988 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 5000, 0);
2989 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
2990
2991
2992 /* Use B-tree indexes */
2993 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 0, 0);
2994 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
2995
2996 delete_helper(fcpl_id, dspace_id, dcpl_id);
2997
2998
2999 /* Set phase change values so that one index converts to a B-tree and one doesn't */
3000 ret = H5Pset_shared_mesg_phase_change(fcpl_id, HALF_DELETE_NUM_MESGS + 1, 0);
3001 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
3002
3003 delete_helper(fcpl_id, dspace_id, dcpl_id);
3004
3005
3006 /* Test with varying message sizes (ideally, so some messages are too
3007 * small to be written but some are big enough that they are still written
3008 */
3009 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 1);
3010 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
3011 for(u = DELETE_MIN_MESG_SIZE; u <= DELETE_MAX_MESG_SIZE; u += 10) {
3012 ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_SHMESG_ALL_FLAG, u);
3013 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
3014 delete_helper(fcpl_id, dspace_id, dcpl_id);
3015 } /* end for */
3016
3017 /* Cleanup */
3018 ret = H5Pclose(fcpl_id);
3019 CHECK_I(ret, "H5Pclose");
3020
3021 for(x = DELETE_NUM_MESGS - 1; x >= 0; --x) {
3022 ret = H5Sclose(dspace_id[x]);
3023 CHECK_I(ret, "H5Sclose");
3024 ret = H5Pclose(dcpl_id[x]);
3025 CHECK_I(ret, "H5Pclose");
3026 } /* end for */
3027 } /* test_sohm_delete */
3028
3029
3030 /*-------------------------------------------------------------------------
3031 * Function: verify_dset_create_and_delete_does_not_grow_file
3032 *
3033 * Purpose: Tests that shared object header message deletion returns
3034 * the file to its previous state using the supplied FCPL.
3035 *
3036 * Creates a file according to the supplied FCPL,
3037 * then creates datasets and deletes them.
3038 * Done in two passes: once with one dataset, once with two.
3039 *
3040 * Programmer: James Laird
3041 * Wednesday, January 3, 2007
3042 *
3043 * Modifications:
3044 *
3045 *-------------------------------------------------------------------------
3046 */
3047 static int
verify_dset_create_and_delete_does_not_grow_file(hid_t fcpl_id)3048 verify_dset_create_and_delete_does_not_grow_file(hid_t fcpl_id)
3049 {
3050 hid_t file_id;
3051 hid_t dspace_id;
3052 hid_t dset_id;
3053 hsize_t dims[1] = {1};
3054 h5_stat_size_t initial_filesize, deleted_filesize;
3055 int old_nerrs; /* Number of errors when entering this routine */
3056 herr_t ret;
3057
3058 /* Retrieve the current # of reported errors */
3059 old_nerrs = GetTestNumErrs();
3060
3061 /* Create a dataspace for later */
3062 dspace_id = H5Screate_simple(1, dims, dims);
3063 CHECK_I(dspace_id, "H5Screate_simple");
3064
3065 /* Create a file using the FCPL supplied*/
3066 file_id = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
3067 CHECK_I(file_id, "H5Fcreate");
3068
3069 /* Close the file and get its size */
3070 ret = H5Fclose(file_id);
3071 CHECK_I(ret, "H5Fclose");
3072 initial_filesize = h5_get_file_size(FILENAME, H5P_DEFAULT);
3073
3074
3075 /* Re-create the file and create a dataset in it */
3076 file_id = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
3077 CHECK_I(file_id, "H5Fcreate");
3078
3079 dset_id = H5Dcreate2(file_id, "dset", H5T_NATIVE_SHORT, dspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
3080 CHECK_I(dset_id, "H5Dcreate2");
3081
3082 /* Close the dataset and delete it */
3083 ret = H5Dclose(dset_id);
3084 CHECK_I(ret, "H5Dclose");
3085 ret = H5Ldelete(file_id, "dset", H5P_DEFAULT);
3086 CHECK_I(ret, "H5Ldelete");
3087
3088 /* Close the file and get its size */
3089 ret = H5Fclose(file_id);
3090 CHECK_I(ret, "H5Fclose");
3091 deleted_filesize = h5_get_file_size(FILENAME, H5P_DEFAULT);
3092
3093 VERIFY(deleted_filesize, initial_filesize, "h5_get_file_size");
3094
3095
3096 /* Repeat, creating two datasets in the file */
3097 file_id = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
3098 CHECK_I(file_id, "H5Fcreate");
3099
3100 /* Create and close the first dataset */
3101 dset_id = H5Dcreate2(file_id, "dset", H5T_NATIVE_SHORT, dspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
3102 CHECK_I(dset_id, "H5Dcreate2");
3103 ret = H5Dclose(dset_id);
3104 CHECK_I(ret, "H5Dclose");
3105
3106 /* Create and close the second. These messages should be shared */
3107 dset_id = H5Dcreate2(file_id, "dset2", H5T_NATIVE_SHORT, dspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
3108 CHECK_I(dset_id, "H5Dcreate2");
3109 ret = H5Dclose(dset_id);
3110 CHECK_I(ret, "H5Dclose");
3111
3112 /* Delete both datasets */
3113 ret = H5Ldelete(file_id, "dset", H5P_DEFAULT);
3114 CHECK_I(ret, "H5Ldelete");
3115 ret = H5Ldelete(file_id, "dset2", H5P_DEFAULT);
3116 CHECK_I(ret, "H5Ldelete");
3117
3118 /* Close the file and get its size */
3119 ret = H5Fclose(file_id);
3120 CHECK_I(ret, "H5Fclose");
3121 deleted_filesize = h5_get_file_size(FILENAME, H5P_DEFAULT);
3122
3123 VERIFY(deleted_filesize, initial_filesize, "h5_get_file_size");
3124
3125
3126 /* Cleanup */
3127 ret = H5Sclose(dspace_id);
3128 CHECK_I(ret, "H5Sclose");
3129
3130 /* Retrieve current # of errors */
3131 if(old_nerrs == GetTestNumErrs())
3132 return(0);
3133 else
3134 return(-1);
3135 } /* verify_dset_create_and_delete_does_not_grow_file */
3136
3137
3138 /*-------------------------------------------------------------------------
3139 * Function: test_sohm_delete_revert
3140 *
3141 * Purpose: Verifies that creation and deletion of datasets with shared
3142 * message headers will not increase file size.
3143 *
3144 * Programmer: James Laird
3145 * Wednesday, January 3, 2007
3146 *
3147 * Modifications:
3148 *
3149 *-------------------------------------------------------------------------
3150 */
3151 static void
test_sohm_delete_revert(void)3152 test_sohm_delete_revert(void)
3153 {
3154 hid_t fcpl_id;
3155 herr_t ret;
3156
3157 MESSAGE(5, ("Testing that file reverts to original size on SOHM deletion\n"));
3158
3159 /* Create an fcpl with messages in two indexes */
3160 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
3161 CHECK_I(fcpl_id, "H5Pcreate");
3162 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 2);
3163 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
3164 ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_SHMESG_DTYPE_FLAG, 10);
3165 CHECK_I(ret, "H5Pset_shared_mesg_index");
3166 ret = H5Pset_shared_mesg_index(fcpl_id, 1, H5O_SHMESG_SDSPACE_FLAG, 10);
3167 CHECK_I(ret, "H5Pset_shared_mesg_index");
3168
3169 /* Call the helper function to test this FCPL. */
3170 ret = verify_dset_create_and_delete_does_not_grow_file(fcpl_id);
3171 CHECK_I(ret, "verify_dset_create_and_delete_does_not_grow_file");
3172
3173 /* Try using B-trees */
3174 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 0, 0);
3175 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
3176 ret = verify_dset_create_and_delete_does_not_grow_file(fcpl_id);
3177 CHECK_I(ret, "verify_dset_create_and_delete_does_not_grow_file");
3178
3179
3180 /* Try sharing all messages */
3181 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 1);
3182 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
3183 ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_SHMESG_ALL_FLAG, 10);
3184 CHECK_I(ret, "H5Pset_shared_mesg_index");
3185 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 10, 5);
3186 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
3187
3188 ret = verify_dset_create_and_delete_does_not_grow_file(fcpl_id);
3189 CHECK_I(ret, "verify_dset_create_and_delete_does_not_grow_file");
3190
3191 /* Try using B-trees */
3192 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 0, 0);
3193 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
3194 ret = verify_dset_create_and_delete_does_not_grow_file(fcpl_id);
3195 CHECK_I(ret, "verify_dset_create_and_delete_does_not_grow_file");
3196
3197 /* There should be at least two messages in the test (datatype and
3198 * dataspace). Use an index that will transition from a list to
3199 * a B-tree and back.
3200 */
3201 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 1, 2);
3202 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
3203 ret = verify_dset_create_and_delete_does_not_grow_file(fcpl_id);
3204 CHECK_I(ret, "verify_dset_create_and_delete_does_not_grow_file");
3205
3206
3207 /* Try with shared messages enabled, but when messages are too big
3208 * to be shared.
3209 */
3210 ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_SHMESG_ALL_FLAG, 35);
3211 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
3212 ret = verify_dset_create_and_delete_does_not_grow_file(fcpl_id);
3213 CHECK_I(ret, "verify_dset_create_and_delete_does_not_grow_file");
3214
3215 ret = H5Pclose(fcpl_id);
3216 CHECK_I(ret, "H5Pclose");
3217 } /* test_sohm_delete_revert */
3218
3219
3220 /*-------------------------------------------------------------------------
3221 * Function: verify_dset_create_and_open_through_extlink_with_sohm
3222 *
3223 * Purpose: Tests that a dataset created through an external link can
3224 * be opened (that shared messages were created or not and
3225 * were shared in the right file).
3226 *
3227 * Programmer: James Laird
3228 * Friday, December 22, 2006
3229 *
3230 * Modifications:
3231 *
3232 *-------------------------------------------------------------------------
3233 */
3234 static void
verify_dset_create_and_open_through_extlink_with_sohm(hid_t src_fcpl_id,hid_t dst_fcpl_id)3235 verify_dset_create_and_open_through_extlink_with_sohm(hid_t src_fcpl_id, hid_t dst_fcpl_id)
3236 {
3237 hid_t src_file_id = -1;
3238 hid_t dst_file_id = -1;
3239 hid_t space_id = -1;
3240 hid_t dset_id = -1;
3241 hsize_t dims[] = {1, 1};
3242 herr_t ret;
3243
3244 /* Create files */
3245 src_file_id = H5Fcreate(FILENAME_SRC, H5F_ACC_TRUNC, src_fcpl_id, H5P_DEFAULT);
3246 CHECK_I(src_file_id, "H5Fcreate");
3247 dst_file_id = H5Fcreate(FILENAME_DST, H5F_ACC_TRUNC, dst_fcpl_id, H5P_DEFAULT);
3248 CHECK_I(dst_file_id, "H5Fcreate");
3249
3250 /* Create an external link from the source file to the destination file */
3251 ret = H5Lcreate_external(FILENAME_DST, "/", src_file_id, "ext_link", H5P_DEFAULT, H5P_DEFAULT);
3252 CHECK_I(ret, "H5Lcreate_external");
3253
3254 /* Create a dataset through the external link */
3255 space_id = H5Screate_simple(2, dims, dims);
3256 CHECK_I(space_id, "H5Screate_simple");
3257 dset_id = H5Dcreate2(src_file_id, "ext_link/dataset", H5T_NATIVE_FLOAT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
3258 CHECK_I(dset_id, "H5Dcreate2");
3259
3260 /* Close the dataset and both files to make sure everything gets flushed
3261 * out of memory
3262 */
3263 ret = H5Sclose(space_id);
3264 CHECK_I(ret, "H5Sclose");
3265 ret = H5Dclose(dset_id);
3266 CHECK_I(ret, "H5Dclose");
3267 ret = H5Fclose(src_file_id);
3268 CHECK_I(ret, "H5Fclose");
3269 ret = H5Fclose(dst_file_id);
3270 CHECK_I(ret, "H5Fclose");
3271
3272 /* Ensure that the dataset can be opened. If the messages were written in
3273 * the wrong file, it'll be impossible to read the dataset's object
3274 * header.
3275 */
3276 dst_file_id = H5Fopen(FILENAME_DST, H5F_ACC_RDONLY, H5P_DEFAULT);
3277 CHECK_I(dst_file_id, "H5Fopen");
3278 dset_id = H5Dopen2(dst_file_id, "dataset", H5P_DEFAULT);
3279 CHECK_I(dset_id, "H5Dopen2");
3280
3281 /* Cleanup */
3282 ret = H5Dclose(dset_id);
3283 CHECK_I(ret, "H5Dclose");
3284 ret = H5Fclose(dst_file_id);
3285 CHECK_I(ret, "H5Fclose");
3286 } /* verify_dset_create_and_open_through_extlink_with_sohm */
3287
3288
3289 /*-------------------------------------------------------------------------
3290 * Function: test_sohm_extlink
3291 *
3292 * Purpose: Test creating SOHMs through external links (to make sure that
3293 * they're created in the correct file).
3294 *
3295 * Programmer: James Laird
3296 * Friday, December 22, 2006
3297 *
3298 * Modifications:
3299 *
3300 *-------------------------------------------------------------------------
3301 */
3302 static void
test_sohm_extlink(void)3303 test_sohm_extlink(void)
3304 {
3305 hid_t fcpl_id = -1;
3306 herr_t ret;
3307
3308 MESSAGE(5, ("Testing SOHM creation through external links\n"));
3309
3310 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
3311 CHECK_I(fcpl_id, "H5Pcreate");
3312 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 1);
3313 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
3314 ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_SHMESG_ALL_FLAG, 16);
3315 CHECK_I(ret, "H5Pset_shared_mesg_index");
3316
3317 verify_dset_create_and_open_through_extlink_with_sohm(fcpl_id, H5P_DEFAULT);
3318 verify_dset_create_and_open_through_extlink_with_sohm(H5P_DEFAULT, fcpl_id);
3319 verify_dset_create_and_open_through_extlink_with_sohm(fcpl_id, fcpl_id);
3320
3321 ret = H5Pclose(fcpl_id);
3322 CHECK_I(ret, "H5Pclose");
3323 } /* test_sohm_extlink */
3324
3325
3326 /*-------------------------------------------------------------------------
3327 * Function: verify_dataset_extension
3328 *
3329 * Purpose: Tests extending a dataset's dataspace when sharing is
3330 * enabled.
3331 *
3332 * If close_reopen is TRUE, closes and reopens the file to
3333 * ensure that data is correctly written to disk.
3334 *
3335 * Programmer: James Laird
3336 * Wednesday, January 10, 2007
3337 *
3338 * Modifications:
3339 *
3340 *-------------------------------------------------------------------------
3341 */
3342 static int
verify_dataset_extension(hid_t fcpl_id,hbool_t close_reopen)3343 verify_dataset_extension(hid_t fcpl_id, hbool_t close_reopen)
3344 {
3345 hid_t file_id = -1;
3346 hid_t orig_space_id = -1;
3347 hid_t space1_id, space2_id, space3_id;
3348 hid_t dcpl_id = -1;
3349 hid_t dset1_id, dset2_id, dset3_id;
3350 hsize_t dims1[] = {1, 2};
3351 hsize_t max_dims[] = {H5S_UNLIMITED, 2};
3352 hsize_t dims2[] = {5, 2};
3353 hsize_t out_dims[2];
3354 hsize_t out_maxdims[2];
3355 int x;
3356 int old_nerrs; /* Number of errors when entering this routine */
3357 herr_t ret;
3358
3359 hsize_t *space_dims[3];
3360
3361 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3362 * Macro: TSOHM_VDE_VERIFY_SPACES
3363 *
3364 * Purpose: Encapsulate a common pattern
3365 * Open, read-verify, and close the dataspaces for datasets 1-3
3366 *
3367 * Programmer: Jacob Smith
3368 * 2018 November 5
3369 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3370 */
3371 #define TSOHM_VDE_VERIFY_SPACES(dims) \
3372 { \
3373 /* Open dataspaces \
3374 */ \
3375 space1_id = H5Dget_space(dset1_id); \
3376 CHECK_I(space1_id, "H5Dget_space"); \
3377 space2_id = H5Dget_space(dset2_id); \
3378 CHECK_I(space2_id, "H5Dget_space"); \
3379 space3_id = H5Dget_space(dset3_id); \
3380 CHECK_I(space3_id, "H5Dget_space"); \
3381 /* Verify dataspaces \
3382 */ \
3383 ret = H5Sget_simple_extent_dims(space1_id, out_dims, out_maxdims); \
3384 CHECK_I(ret, "H5Sget_simple_extent_dims"); \
3385 for(x=0; x<EXTEND_NDIMS; ++x) { \
3386 VERIFY(out_dims[x], (dims)[0][x], "H5Sget_simple_extent_dims"); \
3387 VERIFY(out_maxdims[x], max_dims[x], "H5Sget_simple_extent_dims"); \
3388 } \
3389 ret = H5Sget_simple_extent_dims(space2_id, out_dims, out_maxdims); \
3390 CHECK_I(ret, "H5Sget_simple_extent_dims"); \
3391 for(x=0; x<EXTEND_NDIMS; ++x) { \
3392 VERIFY(out_dims[x], (dims)[1][x], "H5Sget_simple_extent_dims"); \
3393 VERIFY(out_maxdims[x], max_dims[x], "H5Sget_simple_extent_dims"); \
3394 } \
3395 ret = H5Sget_simple_extent_dims(space3_id, out_dims, out_maxdims); \
3396 CHECK_I(ret, "H5Sget_simple_extent_dims"); \
3397 for(x=0; x<EXTEND_NDIMS; ++x) { \
3398 VERIFY(out_dims[x], (dims)[2][x], "H5Sget_simple_extent_dims"); \
3399 VERIFY(out_maxdims[x], max_dims[x], "H5Sget_simple_extent_dims"); \
3400 } \
3401 /* Close dataspaces \
3402 */ \
3403 CHECK_I(H5Sclose(space1_id), "H5Sclose"); \
3404 CHECK_I(H5Sclose(space2_id), "H5Sclose"); \
3405 CHECK_I(H5Sclose(space3_id), "H5Sclose"); \
3406 } /* define TSOHM_VDE_VERIFY_SPACES */
3407
3408 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3409 * Macro: TSOHM_VDE_CLOSE_REOPEN_FILE_AND_DSETS()
3410 *
3411 * Purpose: Encapsulate a common pattern
3412 * Wrapper to close and reopen file and datasets:
3413 * + "dataset" (dset_id)
3414 * + if n > 1 then include "dataset2" (dset_id2)
3415 * + if n > 2 then include "dataset3" (dset_id3)
3416 * + file (file_id)
3417 *
3418 * Programmer: Jacob Smith
3419 * 2018 November 5
3420 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3421 */
3422 #define TSOHM_VDE_CLOSE_REOPEN_FILE_AND_DSETS(n) \
3423 { \
3424 CHECK_I(H5Dclose(dset1_id), "H5Dclose"); \
3425 if ((n) > 1) \
3426 CHECK_I(H5Dclose(dset2_id), "H5Dclose"); \
3427 if ((n) > 2) \
3428 CHECK_I(H5Dclose(dset3_id), "H5Dclose"); \
3429 CHECK_I(H5Fclose(file_id), "H5Fclose"); \
3430 \
3431 file_id = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT); \
3432 CHECK_I(file_id, "H5Fopen"); \
3433 dset1_id = H5Dopen2(file_id, "dataset", H5P_DEFAULT); \
3434 CHECK_I(dset1_id, "H5Dopen2"); \
3435 if ((n) > 1) { \
3436 dset2_id = H5Dopen2(file_id, "dataset2", H5P_DEFAULT); \
3437 CHECK_I(dset2_id, "H5Dopen2"); \
3438 } \
3439 if ((n) > 2) { \
3440 dset3_id = H5Dopen2(file_id, "dataset3", H5P_DEFAULT); \
3441 CHECK_I(dset3_id, "H5Dopen2"); \
3442 } \
3443 } /* define TSOHM_VDE_CLOSE_REOPEN_FILE_AND_DSETS */
3444
3445 /* Remember the current # of reported errors */
3446 old_nerrs = GetTestNumErrs();
3447
3448 file_id = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
3449 CHECK_I(file_id, "H5Fcreate");
3450
3451 /* Create property list with chunking */
3452 dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
3453 CHECK_I(dcpl_id, "H5Pcreate");
3454 ret = H5Pset_chunk(dcpl_id, 2, dims1);
3455 CHECK_I(ret, "H5Pset_chunk");
3456
3457 /* Create a dataspace and a dataset*/
3458 orig_space_id = H5Screate_simple(EXTEND_NDIMS, dims1, max_dims);
3459 CHECK_I(orig_space_id, "H5Screate_simple");
3460 dset1_id = H5Dcreate2(file_id, "dataset", H5T_NATIVE_LONG, orig_space_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT);
3461 CHECK_I(dset1_id, "H5Dcreate2");
3462 if(close_reopen)
3463 TSOHM_VDE_CLOSE_REOPEN_FILE_AND_DSETS(1);
3464
3465 /* Create another dataset starting with the same dataspace */
3466 dset2_id = H5Dcreate2(file_id, "dataset2", H5T_NATIVE_LONG, orig_space_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT);
3467 CHECK_I(dset2_id, "H5Dcreate2");
3468 if (close_reopen)
3469 TSOHM_VDE_CLOSE_REOPEN_FILE_AND_DSETS(2);
3470
3471 /* Create a third dataset with the same dataspace */
3472 dset3_id = H5Dcreate2(file_id, "dataset3", H5T_NATIVE_LONG, orig_space_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT);
3473 CHECK_I(dset3_id, "H5Dcreate2");
3474 if (close_reopen)
3475 TSOHM_VDE_CLOSE_REOPEN_FILE_AND_DSETS(3);
3476
3477 /* Extend the first dataset */
3478 ret = H5Dset_extent(dset1_id, dims2);
3479 CHECK_I(ret, "H5Dset_extent");
3480 if (close_reopen)
3481 TSOHM_VDE_CLOSE_REOPEN_FILE_AND_DSETS(3);
3482
3483 space_dims[0] = dims2;
3484 space_dims[1] = dims1;
3485 space_dims[2] = dims1;
3486 TSOHM_VDE_VERIFY_SPACES(space_dims);
3487
3488 /* Extend the second dataset */
3489 ret = H5Dset_extent(dset2_id, dims2);
3490 CHECK_I(ret, "H5Dset_extent");
3491 if(close_reopen)
3492 TSOHM_VDE_CLOSE_REOPEN_FILE_AND_DSETS(3);
3493
3494 space_dims[1] = dims2;
3495 TSOHM_VDE_VERIFY_SPACES(space_dims);
3496
3497 /* Extend the third dataset */
3498 ret = H5Dset_extent(dset3_id, dims2);
3499 CHECK_I(ret, "H5Dset_extent");
3500 if(close_reopen)
3501 TSOHM_VDE_CLOSE_REOPEN_FILE_AND_DSETS(3);
3502
3503 space_dims[2] = dims2;
3504 TSOHM_VDE_VERIFY_SPACES(space_dims);
3505
3506 /* Close the datasets and file */
3507 ret = H5Dclose(dset1_id);
3508 CHECK_I(ret, "H5Dclose");
3509 ret = H5Dclose(dset2_id);
3510 CHECK_I(ret, "H5Dclose");
3511 ret = H5Dclose(dset3_id);
3512 CHECK_I(ret, "H5Dclose");
3513 ret = H5Fclose(file_id);
3514 CHECK_I(ret, "H5Fclose");
3515
3516
3517
3518 /* Change the order in which datasets are extended to ensure that there
3519 * are no problems if a dataspace goes from being shared to not being
3520 * shared or vice versa.
3521 */
3522 file_id = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
3523 CHECK_I(file_id, "H5Fcreate");
3524 dset1_id = H5Dcreate2(file_id, "dataset", H5T_NATIVE_LONG, orig_space_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT);
3525 CHECK_I(dset1_id, "H5Dcreate2");
3526 if (close_reopen)
3527 TSOHM_VDE_CLOSE_REOPEN_FILE_AND_DSETS(1);
3528
3529 /* Extend the first dataset */
3530 ret = H5Dset_extent(dset1_id, dims2);
3531 CHECK_I(ret, "H5Dset_extent");
3532 if (close_reopen)
3533 TSOHM_VDE_CLOSE_REOPEN_FILE_AND_DSETS(1);
3534
3535 /* Create the second dataset. Its dataspace will be unshared and then
3536 * become shared when extended.
3537 */
3538 dset2_id = H5Dcreate2(file_id, "dataset2", H5T_NATIVE_LONG, orig_space_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT);
3539 CHECK_I(dset2_id, "H5Dcreate2");
3540 if (close_reopen)
3541 TSOHM_VDE_CLOSE_REOPEN_FILE_AND_DSETS(2);
3542
3543 /* Extend the second dataset */
3544 ret = H5Dset_extent(dset2_id, dims2);
3545 CHECK_I(ret, "H5Dset_extent");
3546 if (close_reopen)
3547 TSOHM_VDE_CLOSE_REOPEN_FILE_AND_DSETS(2);
3548
3549 /* Create the third dataset. Its dataspace will be unshared and then
3550 * become shared when extended.
3551 */
3552 dset3_id = H5Dcreate2(file_id, "dataset3", H5T_NATIVE_LONG, orig_space_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT);
3553 CHECK_I(dset3_id, "H5Dcreate2");
3554 if(close_reopen)
3555 TSOHM_VDE_CLOSE_REOPEN_FILE_AND_DSETS(3);
3556
3557 /* Extend the third dataset */
3558 ret = H5Dset_extent(dset3_id, dims2);
3559 CHECK_I(ret, "H5Dset_extent");
3560 if(close_reopen)
3561 TSOHM_VDE_CLOSE_REOPEN_FILE_AND_DSETS(3);
3562
3563 TSOHM_VDE_VERIFY_SPACES(space_dims);
3564
3565 /* Close the datasets and file */
3566 ret = H5Dclose(dset1_id);
3567 CHECK_I(ret, "H5Dclose");
3568 ret = H5Dclose(dset2_id);
3569 CHECK_I(ret, "H5Dclose");
3570 ret = H5Dclose(dset3_id);
3571 CHECK_I(ret, "H5Dclose");
3572 ret = H5Fclose(file_id);
3573 CHECK_I(ret, "H5Fclose");
3574
3575 /* Cleanup */
3576 ret = H5Sclose(orig_space_id);
3577 CHECK_I(ret, "H5Sclose");
3578 ret = H5Pclose(dcpl_id);
3579 CHECK_I(ret, "H5Pclose");
3580
3581 /* Complain if this test generated errors */
3582 if(old_nerrs == GetTestNumErrs())
3583 return(0);
3584 else
3585 return(-1);
3586 /* macros are exclusive to this function */
3587 #undef TSOHM_VDE_CLOSE_REOPEN_FILE_AND_DSETS
3588 #undef TSOHM_VDE_VERIFY_SPACES
3589 } /* verify_dataset_extension */
3590
3591
3592 /*-------------------------------------------------------------------------
3593 * Function: test_sohm_extend_dset
3594 *
3595 * Purpose: Test extended shared dataspaces. An extended dataset's
3596 * dataspace will change, possibly confusing the shared message
3597 * code.
3598 *
3599 * Programmer: James Laird
3600 * Wednesday, January 10, 2007
3601 *
3602 * Modifications:
3603 *
3604 *-------------------------------------------------------------------------
3605 */
3606 static void
test_sohm_extend_dset(void)3607 test_sohm_extend_dset(void)
3608 {
3609 hid_t fcpl_id = -1;
3610 herr_t ret;
3611
3612 MESSAGE(5, ("Testing extending shared dataspaces\n"));
3613
3614 fcpl_id = H5Pcreate(H5P_FILE_CREATE);
3615 CHECK_I(fcpl_id, "H5Pcreate");
3616
3617 /* Test extending datasets with different FCPLs */
3618 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 1);
3619 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
3620
3621 /* No shared messages */
3622 ret = verify_dataset_extension(fcpl_id, FALSE);
3623 CHECK_I(ret, "verify_dataset_extension");
3624 ret = verify_dataset_extension(fcpl_id, TRUE);
3625 CHECK_I(ret, "verify_dataset_extension");
3626
3627
3628 /* Only dataspaces */
3629 ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_SHMESG_SDSPACE_FLAG, 16);
3630 CHECK_I(ret, "H5Pset_shared_mesg_index");
3631
3632 ret = verify_dataset_extension(fcpl_id, FALSE);
3633 CHECK_I(ret, "verify_dataset_extension");
3634 ret = verify_dataset_extension(fcpl_id, TRUE);
3635 CHECK_I(ret, "verify_dataset_extension");
3636
3637 /* All messages */
3638 ret = H5Pset_shared_mesg_nindexes(fcpl_id, 1);
3639 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
3640 ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_SHMESG_ALL_FLAG, 16);
3641 CHECK_I(ret, "H5Pset_shared_mesg_index");
3642
3643 ret = verify_dataset_extension(fcpl_id, FALSE);
3644 CHECK_I(ret, "verify_dataset_extension");
3645 ret = verify_dataset_extension(fcpl_id, TRUE);
3646 CHECK_I(ret, "verify_dataset_extension");
3647
3648
3649 /* All messages in lists */
3650 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 100, 50);
3651 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
3652
3653 ret = verify_dataset_extension(fcpl_id, FALSE);
3654 CHECK_I(ret, "verify_dataset_extension");
3655 ret = verify_dataset_extension(fcpl_id, TRUE);
3656 CHECK_I(ret, "verify_dataset_extension");
3657
3658
3659 /* All messages in lists converted to B-trees */
3660 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 1, 0);
3661 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
3662
3663 ret = verify_dataset_extension(fcpl_id, FALSE);
3664 CHECK_I(ret, "verify_dataset_extension");
3665 ret = verify_dataset_extension(fcpl_id, TRUE);
3666 CHECK_I(ret, "verify_dataset_extension");
3667
3668
3669 /* All messages in B-trees */
3670 ret = H5Pset_shared_mesg_phase_change(fcpl_id, 0, 0);
3671 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
3672
3673 ret = verify_dataset_extension(fcpl_id, FALSE);
3674 CHECK_I(ret, "verify_dataset_extension");
3675 ret = verify_dataset_extension(fcpl_id, TRUE);
3676 CHECK_I(ret, "verify_dataset_extension");
3677
3678 ret = H5Pclose(fcpl_id);
3679 CHECK_I(ret, "H5Pclose");
3680 } /* test_sohm_extend_dset */
3681
3682
3683 /*-------------------------------------------------------------------------
3684 * Function: test_sohm_external_dtype
3685 *
3686 * Purpose: When a datatype is a SOHM type in one file, test that the
3687 * second file using the same datatype actually save it in
3688 * the file, too.
3689 *
3690 * Programmer: Raymond Lu
3691 * 13 October, 2008
3692 *
3693 * Modifications:
3694 *
3695 *-------------------------------------------------------------------------
3696 */
3697 static void
test_sohm_external_dtype(void)3698 test_sohm_external_dtype(void)
3699 {
3700 typedef struct s1_t {
3701 int a;
3702 int b;
3703 } s1_t;
3704 s1_t *s_ptr, *orig;
3705 hid_t fcpl, file1, file2;
3706 hid_t dataset1, dataset2;
3707 hid_t s1_tid, dset1_tid, dset2_tid, space;
3708 hsize_t dims[2] = {NX, NY};
3709 H5T_class_t dtype_class;
3710 size_t dmsg_count;
3711 unsigned x, i;
3712 herr_t ret;
3713
3714 MESSAGE(5, ("Testing shared external datatype\n"));
3715
3716 fcpl = H5Pcreate(H5P_FILE_CREATE);
3717 CHECK_I(fcpl, "H5Pcreate");
3718 ret = H5Pset_shared_mesg_nindexes(fcpl, TEST_NUM_INDEXES);
3719 CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
3720 for(x=0; x<TEST_NUM_INDEXES; ++x) {
3721 ret = H5Pset_shared_mesg_index(fcpl, x, test_type_flags[x], test_minsizes[x]);
3722 CHECK_I(ret, "H5Pset_shared_mesg_index");
3723 }
3724 ret = H5Pset_shared_mesg_phase_change(fcpl, TEST_L2B, TEST_B2L);
3725 CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
3726
3727 space = H5Screate_simple(2, dims, NULL);
3728 CHECK_I(space, "H5Screate_simple");
3729
3730 s1_tid = H5Tcreate(H5T_COMPOUND, sizeof(s1_t));
3731 CHECK_I(s1_tid, "H5Tcreate");
3732 ret = H5Tinsert(s1_tid, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT);
3733 CHECK_I(ret, "H5Tinsert");
3734 ret = H5Tinsert (s1_tid, "b", HOFFSET(s1_t,b), H5T_NATIVE_INT);
3735 CHECK_I(ret, "H5Tinsert");
3736
3737 /* Set up dataset in first file */
3738 file1 = H5Fcreate(FILENAME_SRC, H5F_ACC_TRUNC, fcpl, H5P_DEFAULT);
3739 CHECK_I(file1, "H5Fcreate");
3740
3741 /* Check on datatype storage status. It should be zero now. */
3742 ret = H5F_get_sohm_mesg_count_test(file1, H5O_DTYPE_ID, &dmsg_count);
3743 CHECK(ret, FAIL, "H5F_get_sohm_mesg_count_test");
3744 VERIFY(dmsg_count, 0, "H5F_get_sohm_mesg_count_test");
3745
3746 dataset1 = H5Dcreate2(file1, "dataset_1", s1_tid, space, H5P_DEFAULT, H5P_DEFAULT,
3747 H5P_DEFAULT);
3748 CHECK_I(dataset1, "H5Dcreate2");
3749
3750 /* Check on datatype storage status. It should be 1 now. */
3751 ret = H5F_get_sohm_mesg_count_test(file1, H5O_DTYPE_ID, &dmsg_count);
3752 CHECK(ret, FAIL, "H5F_get_sohm_mesg_count_test");
3753 VERIFY(dmsg_count, 1, "H5F_get_sohm_mesg_count_test");
3754
3755 dset1_tid = H5Dget_type(dataset1);
3756 CHECK_I(dset1_tid, "H5Dget_type");
3757
3758 /* Allocate space and initialize data */
3759 orig = (s1_t*)HDmalloc(NX * NY * sizeof(s1_t));
3760 if (orig == NULL)
3761 CHECK_I(-1, "HDmalloc");
3762 for(i=0; i<NX*NY; i++) {
3763 s_ptr = (s1_t*)orig + i;
3764 s_ptr->a = (int)(i * 3 + 1);
3765 s_ptr->b = (int)(i * 3 + 2);
3766 }
3767
3768 ret = H5Dwrite(dataset1, s1_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, orig);
3769 CHECK_I(ret, "H5Dwrite");
3770 ret = H5Dclose(dataset1);
3771 CHECK_I(ret, "H5Dclose");
3772
3773 /* Create dataset in second file using datatype from dataset in the first file */
3774 file2 = H5Fcreate(FILENAME_DST, H5F_ACC_TRUNC, fcpl, H5P_DEFAULT);
3775 CHECK_I(file2, "H5Fcreate");
3776
3777 /* Check on datatype storage status. It should be zero now. */
3778 ret = H5F_get_sohm_mesg_count_test(file2, H5O_DTYPE_ID, &dmsg_count);
3779 CHECK(ret, FAIL, "H5F_get_sohm_mesg_count_test");
3780 VERIFY(dmsg_count, 0, "H5F_get_sohm_mesg_count_test");
3781
3782 dataset2 = H5Dcreate2(file2, "dataset_2", dset1_tid, space, H5P_DEFAULT, H5P_DEFAULT,
3783 H5P_DEFAULT);
3784 CHECK_I(dataset2, "H5Dcreate2");
3785
3786 /* Check on datatype storage status. It should be 1 now. */
3787 ret = H5F_get_sohm_mesg_count_test(file2, H5O_DTYPE_ID, &dmsg_count);
3788 CHECK(ret, FAIL, "H5F_get_sohm_mesg_count_test");
3789 VERIFY(dmsg_count, 1, "H5F_get_sohm_mesg_count_test");
3790
3791 ret = H5Dwrite(dataset2, s1_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, orig);
3792 CHECK_I(ret, "H5Dwrite");
3793
3794 /* Close references to the first file */
3795 ret = H5Dclose(dataset2);
3796 CHECK_I(ret, "H5Dclose");
3797 ret = H5Tclose(dset1_tid);
3798 CHECK_I(ret, "H5Tclose");
3799 ret = H5Fclose(file1);
3800 CHECK_I(ret, "H5Fclose");
3801
3802 /* Verify that datatype details are still accessible by second file */
3803 dataset2 = H5Dopen2(file2, "dataset_2", H5P_DEFAULT);
3804 CHECK_I(dataset2, "H5Dopen2");
3805
3806 dset2_tid = H5Dget_type(dataset2);
3807 CHECK_I(dset2_tid, "H5Dget_type");
3808
3809 dtype_class = H5Tget_class(dset2_tid);
3810 VERIFY(dtype_class, H5T_COMPOUND, "H5Tget_class");
3811
3812 /* Cleanup */
3813 ret = H5Tclose(dset2_tid);
3814 CHECK_I(ret, "H5Tclose");
3815 ret = H5Dclose(dataset2);
3816 CHECK_I(ret, "H5Dclose");
3817 ret = H5Sclose(space);
3818 CHECK_I(ret, "H5Sclose");
3819 ret = H5Tclose(s1_tid);
3820 CHECK_I(ret, "H5Tclose");
3821 ret = H5Pclose(fcpl);
3822 CHECK_I(ret, "H5Pclose");
3823 ret = H5Fclose(file2);
3824 CHECK_I(ret, "H5Fclose");
3825 HDfree(orig);
3826 } /* test_sohm_external_dtype */
3827
3828
3829 /****************************************************************
3830 **
3831 ** test_sohm(): Main Shared Object Header Message testing routine.
3832 **
3833 ****************************************************************/
3834 void
test_sohm(void)3835 test_sohm(void)
3836 {
3837 MESSAGE(5, ("Testing Shared Object Header Messages\n"));
3838
3839 test_sohm_fcpl(); /* Test SOHMs and file creation plists */
3840 test_sohm_fcpl_errors(); /* Bogus H5P* calls for SOHMs */
3841 test_sohm_size1(); /* Tests the sizes of files with one SOHM */
3842 #if 0 /* TODO: REVEALS BUG TO BE FIXED - SEE JIRA HDFFV-10645 */
3843 test_sohm_size_consistency_open_create();
3844 #endif /* Jira HDFFV-10645 */
3845 test_sohm_attrs(); /* Tests shared messages in attributes */
3846 test_sohm_size2(0); /* Tests the sizes of files with multiple SOHMs */
3847 test_sohm_size2(1); /* Tests the sizes of files with multiple
3848 * SOHMs, closing and reopening file after
3849 * each write. */
3850 test_sohm_delete(); /* Test deleting shared messages */
3851 test_sohm_delete_revert(); /* Test that a file with SOHMs becomes an
3852 * empty file again when they are deleted. */
3853 test_sohm_extlink(); /* Test SOHMs when external links are used */
3854
3855 test_sohm_extend_dset(); /* Test extending shared datasets */
3856 test_sohm_external_dtype(); /* Test using datatype in another file */
3857 } /* test_sohm */
3858
3859
3860 /*-------------------------------------------------------------------------
3861 * Function: cleanup_sohm
3862 *
3863 * Purpose: Cleanup temporary test files
3864 *
3865 * Return: none
3866 *
3867 * Programmer: James Laird
3868 * October 9, 2006
3869 *
3870 * Modifications:
3871 *
3872 *-------------------------------------------------------------------------
3873 */
3874 void
cleanup_sohm(void)3875 cleanup_sohm(void)
3876 {
3877 HDremove(FILENAME);
3878 HDremove(FILENAME_SRC);
3879 HDremove(FILENAME_DST);
3880 } /* cleanup_sohm */
3881
3882