diff options
author | Neil Fortner <nfortne2@hdfgroup.org> | 2009-01-26 19:43:09 (GMT) |
---|---|---|
committer | Neil Fortner <nfortne2@hdfgroup.org> | 2009-01-26 19:43:09 (GMT) |
commit | 1197e992e94d823a1dea02ad91f42299df305dad (patch) | |
tree | 86f492d980329f2050f080f22ca5b80be394d839 | |
parent | 0a9e0279b698c68bf26ea5fcd223b00572720650 (diff) | |
download | hdf5-1197e992e94d823a1dea02ad91f42299df305dad.zip hdf5-1197e992e94d823a1dea02ad91f42299df305dad.tar.gz hdf5-1197e992e94d823a1dea02ad91f42299df305dad.tar.bz2 |
[svn-r16350] Purpose: enhancements the H5Tinsert, H5Tpack
Description: H5Tinsert will now detect when a compound type that was previously
not packed becomes packed due to out of offset order insertion of a member.
H5Tinsert will now attempt to keep members sorted by offset order. This should
improve performance of H5Tinsert in all cases due to the fact that it no longer
needs to check every other member for overlapping, and should improve
performance of H5Tpack and possibly type conversion when compounds are packed
out of order.
Tested: jam, smirom (h5committest)
-rw-r--r-- | src/H5T.c | 21 | ||||
-rw-r--r-- | src/H5Tcompound.c | 146 | ||||
-rw-r--r-- | test/cmpd_dset.c | 251 |
3 files changed, 384 insertions, 34 deletions
@@ -2973,8 +2973,10 @@ H5T_create(H5T_class_t type, size_t size) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); dt->shared->type = type; - if(type==H5T_COMPOUND) + if(type==H5T_COMPOUND) { dt->shared->u.compnd.packed=TRUE; /* Start out packed */ + dt->shared->u.compnd.sorted=H5T_SORT_VALUE; /* Start out sorted by value */ + } /* end if */ else if(type==H5T_OPAQUE) /* Initialize the tag in case it's not set later. A null tag will * cause problems for later operations. */ @@ -3173,13 +3175,16 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method) * name and type fields of each new member with copied values. * That is, H5T_copy() is a deep copy. */ - new_dt->shared->u.compnd.memb = H5MM_malloc(new_dt->shared->u.compnd.nalloc * - sizeof(H5T_cmemb_t)); - if (NULL==new_dt->shared->u.compnd.memb) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - - HDmemcpy(new_dt->shared->u.compnd.memb, old_dt->shared->u.compnd.memb, - new_dt->shared->u.compnd.nmembs * sizeof(H5T_cmemb_t)); + /* Only malloc if space has been allocated for members - NAF */ + if(new_dt->shared->u.compnd.nalloc > 0) { + new_dt->shared->u.compnd.memb = H5MM_malloc(new_dt->shared->u.compnd.nalloc * + sizeof(H5T_cmemb_t)); + if (NULL==new_dt->shared->u.compnd.memb) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + HDmemcpy(new_dt->shared->u.compnd.memb, old_dt->shared->u.compnd.memb, + new_dt->shared->u.compnd.nmembs * sizeof(H5T_cmemb_t)); + } /* end if */ for(i = 0; i < new_dt->shared->u.compnd.nmembs; i++) { unsigned j; diff --git a/src/H5Tcompound.c b/src/H5Tcompound.c index 68de174..02d6bd1 100644 --- a/src/H5Tcompound.c +++ b/src/H5Tcompound.c @@ -45,6 +45,11 @@ /******************/ /* Local Typedefs */ /******************/ +/* "Key" (+ user data) for bsearch callback */ +typedef struct{ + size_t offset; /* Offset of member to be added */ + const H5T_cmemb_t *max_under; /* Member with maximum offset seen that is not above "offset" */ +} H5T_insert_compar_t; /********************/ @@ -416,6 +421,48 @@ done: /*------------------------------------------------------------------------- + * Function: H5T_insert_compar + * + * Purpose: Callback function for bsearch called from H5T_insert. + * Reports whether obj has a lower of higher offset than + * that stored in key. Also keeps track of the highest + * offset seen that is not higher than that in key. + * + * Return: -1 if key < obj + * 0 if key == obj + * 1 if key > obj + * + * Programmer: Neil Fortner + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +H5T_insert_compar(const void *_key, const void *_obj) +{ + H5T_insert_compar_t *key = *(H5T_insert_compar_t * const *)_key; /* User data */ + const H5T_cmemb_t *memb = (const H5T_cmemb_t *)_obj; /* Compound member being examined */ + int ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_insert_compar) + + if(key->offset > memb->offset) { + if(key->max_under == NULL || memb->offset > key->max_under->offset) + key->max_under = memb; + ret_value = 1; + } /* end if */ + else if(key->offset < memb->offset) + ret_value = -1; + else + ret_value = 0; /* Should not happen */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_insert_compar() */ + + +/*------------------------------------------------------------------------- * Function: H5T_insert * * Purpose: Adds a new MEMBER to the compound datatype PARENT. The new @@ -435,6 +482,8 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) { unsigned idx; /* Index of member to insert */ size_t total_size; + H5T_insert_compar_t key; /* Key for bsearch compare function */ + H5T_insert_compar_t *keyptr = &key; /* Pointer to key */ unsigned i; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -451,20 +500,39 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) if(!HDstrcmp(parent->shared->u.compnd.memb[i].name, name)) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member name is not unique") - /* Does the new member overlap any existing member ? */ total_size = member->shared->size; - for(i = 0; i < parent->shared->u.compnd.nmembs; i++) - if((offset <= parent->shared->u.compnd.memb[i].offset && - (offset + total_size) > parent->shared->u.compnd.memb[i].offset) || - (parent->shared->u.compnd.memb[i].offset <= offset && - (parent->shared->u.compnd.memb[i].offset + - parent->shared->u.compnd.memb[i].size) > offset)) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member") /* Does the new member overlap the end of the compound type? */ if((offset + total_size) > parent->shared->size) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member extends past end of compound type") + if(parent->shared->u.compnd.sorted != H5T_SORT_VALUE) + if(H5T_sort_value(parent, NULL) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOMPARE, FAIL, "value sort failed") + + /* Find the position to insert the new member */ + if(parent->shared->u.compnd.nmembs == 0) + idx = 0; + else { + /* Key value (including user data) for compar callback */ + key.offset = offset; + key.max_under = NULL; + + /* Do a binary search on the offsets of the (now sorted) members. We do + * not expect to find an exact match (if we do it is an error), rely on + * the user data in the key to keep track of the closest member below + * the new member. */ + if(NULL != HDbsearch(&keyptr, parent->shared->u.compnd.memb, parent->shared->u.compnd.nmembs, + sizeof(parent->shared->u.compnd.memb[0]), H5T_insert_compar)) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member") + idx = (key.max_under == NULL) ? 0 : (unsigned) (key.max_under - parent->shared->u.compnd.memb + 1); + } /* end else */ + + /* Does the new member overlap any existing member ? */ + if((idx < parent->shared->u.compnd.nmembs && (offset + total_size) > parent->shared->u.compnd.memb[idx].offset) || + (idx && (parent->shared->u.compnd.memb[idx-1].offset + parent->shared->u.compnd.memb[idx-1].size) > offset)) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member") + /* Increase member array if necessary */ if(parent->shared->u.compnd.nmembs >= parent->shared->u.compnd.nalloc) { unsigned na = MAX(1, parent->shared->u.compnd.nalloc * 2); @@ -476,38 +544,68 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) parent->shared->u.compnd.memb = x; } /* end if */ - /* Add member to end of member array */ - idx = parent->shared->u.compnd.nmembs; - parent->shared->u.compnd.memb[idx].name = H5MM_xstrdup(name); - parent->shared->u.compnd.memb[idx].offset = offset; - parent->shared->u.compnd.memb[idx].size = total_size; - parent->shared->u.compnd.memb[idx].type = H5T_copy(member, H5T_COPY_ALL); - - parent->shared->u.compnd.sorted = H5T_SORT_NONE; - parent->shared->u.compnd.nmembs++; - - /* Determine if the compound datatype stayed packed */ + /* Determine if the compound datatype stays packed */ if(parent->shared->u.compnd.packed) { /* Check if the member type is packed */ - if(H5T_is_packed(parent->shared->u.compnd.memb[idx].type) > 0) { + if(H5T_is_packed(member) > 0) { if(idx == 0) { /* If the is the first member, the datatype is not packed * if the first member isn't at offset 0 */ - if(parent->shared->u.compnd.memb[idx].offset > 0) + if(offset > 0) parent->shared->u.compnd.packed = FALSE; } /* end if */ else { /* If the is not the first member, the datatype is not * packed if the new member isn't adjoining the previous member */ - if(parent->shared->u.compnd.memb[idx].offset != (parent->shared->u.compnd.memb[idx - 1].offset + parent->shared->u.compnd.memb[idx - 1].size)) + if(offset != (parent->shared->u.compnd.memb[idx - 1].offset + parent->shared->u.compnd.memb[idx - 1].size)) parent->shared->u.compnd.packed = FALSE; } /* end else */ } /* end if */ else parent->shared->u.compnd.packed = FALSE; } /* end if */ + else + /* Check if inserting this member causes the parent to become packed */ + /* First check if it completely closes a gap */ + /* No need to check if it's being appended to the end */ + if(idx != parent->shared->u.compnd.nmembs + && (offset + total_size) == parent->shared->u.compnd.memb[idx].offset + && (idx == 0 ? offset == 0 : (parent->shared->u.compnd.memb[idx-1].offset + + parent->shared->u.compnd.memb[idx-1].size) == offset) + && H5T_is_packed(member) > 0) { + + /* Start out packed */ + parent->shared->u.compnd.packed = TRUE; + + /* Check if the entire type is now packed */ + if((idx != 0 && parent->shared->u.compnd.memb[0].offset != 0) + || !H5T_is_packed(parent->shared->u.compnd.memb[0].type)) + parent->shared->u.compnd.packed = FALSE; + else + for(i = 1; i < parent->shared->u.compnd.nmembs; i++) + if((i != idx && parent->shared->u.compnd.memb[i].offset + != (parent->shared->u.compnd.memb[i - 1].offset + + parent->shared->u.compnd.memb[i - 1].size)) + || !H5T_is_packed(parent->shared->u.compnd.memb[i].type)) { + parent->shared->u.compnd.packed = FALSE; + break; + } /* end if */ + } /* end if */ + + /* Reshape the memb array to accomodate the new member */ + if(idx != parent->shared->u.compnd.nmembs) + HDmemmove(&parent->shared->u.compnd.memb[idx+1], &parent->shared->u.compnd.memb[idx], + (parent->shared->u.compnd.nmembs - idx) * sizeof(parent->shared->u.compnd.memb[0])); + + /* Add member to member array */ + parent->shared->u.compnd.memb[idx].name = H5MM_xstrdup(name); + parent->shared->u.compnd.memb[idx].offset = offset; + parent->shared->u.compnd.memb[idx].size = total_size; + parent->shared->u.compnd.memb[idx].type = H5T_copy(member, H5T_COPY_ALL); + + parent->shared->u.compnd.nmembs++; /* Set the "force conversion" flag if the field's datatype indicates */ if(member->shared->force_conv == TRUE) @@ -633,11 +731,11 @@ H5T_is_packed(const H5T_t *dt) /* If this is a compound datatype, check if it is packed */ if(dt->shared->type == H5T_COMPOUND) { H5T_compnd_t *compnd = &(dt->shared->u.compnd); /* Convenience pointer to compound info */ - ret_value = (htri_t)(compnd->packed + ret_value = (htri_t)(compnd->packed && compnd->nmembs > 0 && compnd->memb[compnd->nmembs - 1].offset + compnd->memb[compnd->nmembs - 1].size == dt->shared->size); - } + } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_is_packed() */ diff --git a/test/cmpd_dset.c b/test/cmpd_dset.c index c6ba30b..c05844e 100644 --- a/test/cmpd_dset.c +++ b/test/cmpd_dset.c @@ -23,6 +23,7 @@ #define H5T_PACKAGE #include "H5Tpkg.h" /*to turn off hardware conversions*/ +#include "H5Iprivate.h" #include "h5test.h" @@ -120,6 +121,7 @@ typedef struct { #define NX 100u #define NY 2000u +#define PACK_NMEMBS 100 /*------------------------------------------------------------------------- @@ -600,7 +602,7 @@ test_compound (char *filename, hid_t fapl) if ((s8_m_sid = H5Screate_simple (2, h_size, NULL)) < 0) goto error; /* Read the dataset */ - s8 = calloc ((size_t)(h_size[0]*h_size[1]), sizeof(s1_t)); + s8 = (s1_t *) calloc ((size_t)(h_size[0]*h_size[1]), sizeof(s1_t)); assert (s8); if (H5Dread (dataset, s1_tid, s8_m_sid, s8_f_sid, H5P_DEFAULT, s8) < 0) { goto error; @@ -767,7 +769,7 @@ test_compound (char *filename, hid_t fapl) f_offset[1] = NY/3; h_size[0] = 2*NX/3 - f_offset[0]; h_size[1] = 2*NY/3 - f_offset[1]; - s11 = malloc ((size_t)h_size[0]*(size_t)h_size[1]*sizeof(s4_t)); + s11 = (s4_t *) malloc ((size_t)h_size[0]*(size_t)h_size[1]*sizeof(s4_t)); assert (s11); /* Initialize */ @@ -1717,6 +1719,248 @@ error: return 1; } +/* Error macro that outputs the state of the randomly generated variables so the + * failure can be reproduced */ +#define PACK_OOO_ERROR \ +{ \ + int _i; \ + H5_FAILED(); AT(); \ + printf(" Insertion order ="); \ + for(_i=0; _i<PACK_NMEMBS; _i++) \ + printf(" %d", order[_i]); \ + printf("\n Inner compound order = %d, location = %d\n", sub_cmpd_order, order[sub_cmpd_order]); \ + fflush(stdout); \ + goto error; \ +} + + +/*------------------------------------------------------------------------- + * Function: test_pack_ooo + * + * Purpose: Test inserting fields into a compound out of offset order. + * Verifies that the compound + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Neil Fortner + * Thursday, 22 January 2009 + * + * Modifications: + *------------------------------------------------------------------------- + */ +static int +test_pack_ooo(void) +{ + hid_t cmpd, sub_cmpd; /* Datatype IDs */ + H5T_t *dt; /* Datatype pointer */ + unsigned order[PACK_NMEMBS]; /* Order of insertion */ + unsigned free_order[PACK_NMEMBS]; /* Index of remaining free slots in order */ + unsigned num_free; /* Number of free slots in order */ + unsigned sub_cmpd_order; /* Order to insert the inner compound */ + char name[6]; /* Member name */ + unsigned i, j; /* Indices */ + + HDsrand((unsigned) time(NULL)); + + /* Initialize "free_order" array to indicate that all slots in order are + * free */ + for(i=0; i<PACK_NMEMBS; i++) + free_order[i] = i; + + /* Create "order" array */ + for(i=0; i<PACK_NMEMBS; i++) { + /* Generate index into free_order array */ + num_free = PACK_NMEMBS - i; + j = HDrand() % num_free; + + /* Update order array at the randomly generated (but guaranteed to be + * free) location */ + order[free_order[j]] = i; + + /* Reshape free_order to remove j (which is no longer free) */ + if(j < (num_free - 1)) + HDmemmove(&free_order[j], &free_order[j+1], (num_free - j - 1) * sizeof(free_order[0])); + } /* end for */ + + /* Generate order to insert inner compound type */ + sub_cmpd_order = HDrand() % PACK_NMEMBS; + + TESTING("random member insertion with empty compound subtype"); + + /* Create inner compound type. It will be empty for the first run */ + if((sub_cmpd = H5Tcreate(H5T_COMPOUND, 4)) < 0) PACK_OOO_ERROR + + /* Create main compound type, with extra space at the end */ + if((cmpd = H5Tcreate(H5T_COMPOUND, (4 * PACK_NMEMBS) + 1)) < 0) PACK_OOO_ERROR + + /* Insert the compound members in the random order previously generated */ + for(i=0; i<PACK_NMEMBS; i++) { + sprintf(name, "%05d", i); + if(i == sub_cmpd_order) { + if(H5Tinsert(cmpd, name, 4 * order[i], sub_cmpd) < 0) PACK_OOO_ERROR + } else + if(H5Tinsert(cmpd, name, 4 * order[i], H5T_STD_I32BE) < 0) PACK_OOO_ERROR + } /* end for */ + + /* Verify that the compound is not packed */ + if(NULL == (dt = (H5T_t *) H5I_object_verify(cmpd, H5I_DATATYPE))) PACK_OOO_ERROR + if(dt->shared->u.compnd.packed) PACK_OOO_ERROR + + /* Close the main compound */ + if(H5Tclose(cmpd) < 0) PACK_OOO_ERROR + + PASSED(); + + TESTING("random member insertion with full compound subtype"); + + /* Complete the inner compound type */ + if(H5Tinsert(sub_cmpd, "int", 0, H5T_STD_I32LE) < 0) PACK_OOO_ERROR + + /* Recreate main compound type */ + if((cmpd = H5Tcreate(H5T_COMPOUND, (4 * PACK_NMEMBS) + 1)) < 0) PACK_OOO_ERROR + + /* Insert the compound members in the random order previously generated */ + for(i=0; i<PACK_NMEMBS; i++) { + sprintf(name, "%05d", i); + if(i == sub_cmpd_order) { + if(H5Tinsert(cmpd, name, 4 * order[i], sub_cmpd) < 0) PACK_OOO_ERROR + } else + if(H5Tinsert(cmpd, name, 4 * order[i], H5T_STD_I32BE) < 0) PACK_OOO_ERROR + } /* end for */ + + /* Verify that the compound is packed */ + if(NULL == (dt = (H5T_t *) H5I_object_verify(cmpd, H5I_DATATYPE))) PACK_OOO_ERROR + if(!dt->shared->u.compnd.packed) PACK_OOO_ERROR + + /* Close */ + if(H5Tclose(cmpd) < 0) PACK_OOO_ERROR + if(H5Tclose(sub_cmpd) < 0) PACK_OOO_ERROR + + PASSED(); + + /* Change to reverse ordering, insert compound last */ + for(i=0; i<PACK_NMEMBS; i++) + order[i] = PACK_NMEMBS - i - 1; + sub_cmpd_order = PACK_NMEMBS - 1; + + TESTING("reverse member insertion with empty compound subtype"); + + /* Create inner compound type. It will be empty for the first run */ + if((sub_cmpd = H5Tcreate(H5T_COMPOUND, 4)) < 0) TEST_ERROR + + /* Create main compound type, with extra space at the end */ + if((cmpd = H5Tcreate(H5T_COMPOUND, (4 * PACK_NMEMBS) + 1)) < 0) TEST_ERROR + + /* Insert the compound members in the reverse order previously generated */ + for(i=0; i<PACK_NMEMBS; i++) { + sprintf(name, "%05d", i); + if(i == sub_cmpd_order) { + if(H5Tinsert(cmpd, name, 4 * order[i], sub_cmpd) < 0) TEST_ERROR + } else + if(H5Tinsert(cmpd, name, 4 * order[i], H5T_STD_I32BE) < 0) TEST_ERROR + } /* end for */ + + /* Verify that the compound is not packed */ + if(NULL == (dt = (H5T_t *) H5I_object_verify(cmpd, H5I_DATATYPE))) TEST_ERROR + if(dt->shared->u.compnd.packed) TEST_ERROR + + /* Close the main compound */ + if(H5Tclose(cmpd) < 0) TEST_ERROR + + PASSED(); + + TESTING("reverse member insertion with full compound subtype"); + + /* Complete the inner compound type */ + if(H5Tinsert(sub_cmpd, "int", 0, H5T_STD_I32LE) < 0) TEST_ERROR + + /* Recreate main compound type */ + if((cmpd = H5Tcreate(H5T_COMPOUND, (4 * PACK_NMEMBS) + 1)) < 0) TEST_ERROR + + /* Insert the compound members in the reverse order previously generated */ + for(i=0; i<PACK_NMEMBS; i++) { + sprintf(name, "%05d", i); + if(i == sub_cmpd_order) { + if(H5Tinsert(cmpd, name, 4 * order[i], sub_cmpd) < 0) TEST_ERROR + } else + if(H5Tinsert(cmpd, name, 4 * order[i], H5T_STD_I32BE) < 0) TEST_ERROR + } /* end for */ + + /* Verify that the compound is packed */ + if(NULL == (dt = (H5T_t *) H5I_object_verify(cmpd, H5I_DATATYPE))) TEST_ERROR + if(!dt->shared->u.compnd.packed) TEST_ERROR + + /* Close */ + if(H5Tclose(cmpd) < 0) TEST_ERROR + if(H5Tclose(sub_cmpd) < 0) TEST_ERROR + + PASSED(); + + /* Change to forward ordering, insert compound first */ + sub_cmpd_order = 0; + + TESTING("forward member insertion with empty compound subtype"); + + /* Create inner compound type. It will be empty for the first run */ + if((sub_cmpd = H5Tcreate(H5T_COMPOUND, 4)) < 0) TEST_ERROR + + /* Create main compound type, with extra space at the end */ + if((cmpd = H5Tcreate(H5T_COMPOUND, (4 * PACK_NMEMBS) + 1)) < 0) TEST_ERROR + + /* Insert the compound members in forward order */ + for(i=0; i<PACK_NMEMBS; i++) { + sprintf(name, "%05d", i); + if(i == sub_cmpd_order) { + if(H5Tinsert(cmpd, name, 4 * i, sub_cmpd) < 0) TEST_ERROR + } else + if(H5Tinsert(cmpd, name, 4 * i, H5T_STD_I32BE) < 0) TEST_ERROR + } /* end for */ + + /* Verify that the compound is not packed */ + if(NULL == (dt = (H5T_t *) H5I_object_verify(cmpd, H5I_DATATYPE))) TEST_ERROR + if(dt->shared->u.compnd.packed) TEST_ERROR + + /* Close the main compound */ + if(H5Tclose(cmpd) < 0) TEST_ERROR + + PASSED(); + + TESTING("forward member insertion with full compound subtype"); + + /* Complete the inner compound type */ + if(H5Tinsert(sub_cmpd, "int", 0, H5T_STD_I32LE) < 0) TEST_ERROR + + /* Recreate main compound type */ + if((cmpd = H5Tcreate(H5T_COMPOUND, (4 * PACK_NMEMBS) + 1)) < 0) TEST_ERROR + + /* Insert the compound members in forward order */ + for(i=0; i<PACK_NMEMBS; i++) { + sprintf(name, "%05d", i); + if(i == sub_cmpd_order) { + if(H5Tinsert(cmpd, name, 4 * i, sub_cmpd) < 0) TEST_ERROR + } else + if(H5Tinsert(cmpd, name, 4 * i, H5T_STD_I32BE) < 0) TEST_ERROR + } /* end for */ + + /* Verify that the compound is packed */ + if(NULL == (dt = (H5T_t *) H5I_object_verify(cmpd, H5I_DATATYPE))) TEST_ERROR + if(!dt->shared->u.compnd.packed) TEST_ERROR + + /* Close */ + if(H5Tclose(cmpd) < 0) TEST_ERROR + if(H5Tclose(sub_cmpd) < 0) TEST_ERROR + + PASSED(); + + return 0; + +error: + puts("*** DATASET TESTS FAILED ***"); + return 1; +} + /*------------------------------------------------------------------------- * Function: main @@ -1768,6 +2012,9 @@ main (int argc, char *argv[]) h5_fixname(FILENAME[2], fapl_id, fname, sizeof(fname)); nerrors += test_hdf5_dst_subset(fname, fapl_id); + puts("Testing that compound types can be packed out of order:"); + nerrors += test_pack_ooo(); + if (nerrors) { printf("***** %u FAILURE%s! *****\n", nerrors, 1==nerrors?"":"S"); |