diff options
Diffstat (limited to 'tools/h5repack')
-rw-r--r-- | tools/h5repack/h5repack.c | 66 | ||||
-rw-r--r-- | tools/h5repack/h5repack_refs.c | 418 |
2 files changed, 324 insertions, 160 deletions
diff --git a/tools/h5repack/h5repack.c b/tools/h5repack/h5repack.c index 8c46638..1f42eef 100644 --- a/tools/h5repack/h5repack.c +++ b/tools/h5repack/h5repack.c @@ -108,7 +108,7 @@ h5repack_init(pack_opt_t *options, int verbose, H5F_file_space_type_t strategy, return (options_table_init(&(options->op_tbl))); } - + /*------------------------------------------------------------------------- * Function: h5repack_end * @@ -122,7 +122,7 @@ int h5repack_end (pack_opt_t *options) return options_table_free(options->op_tbl); } - + /*------------------------------------------------------------------------- * Function: h5repack_addfilter * @@ -170,7 +170,7 @@ int h5repack_addfilter(const char* str, return 0; } - + /*------------------------------------------------------------------------- * Function: h5repack_addlayout * @@ -236,9 +236,9 @@ int h5repack_addlayout(const char* str, return 0; } -/* Note: The below copy_named_datatype(), named_datatype_free(), copy_attr() - * were located in h5repack_copy.c as static prior to bugfix1726. - * Made shared functions as copy_attr() was needed in h5repack_refs.c. +/* Note: The below copy_named_datatype(), named_datatype_free(), copy_attr() + * were located in h5repack_copy.c as static prior to bugfix1726. + * Made shared functions as copy_attr() was needed in h5repack_refs.c. * However copy_attr() may be obsoleted when H5Acopy is available and put back * others to static in h5repack_copy.c. */ @@ -269,21 +269,21 @@ hid_t copy_named_datatype(hid_t type_in, hid_t fidout, named_dt_t **named_dt_hea if(H5Oget_info(type_in, &oinfo) < 0) goto error; - if(*named_dt_head_p) + if(*named_dt_head_p) { /* Stack already exists, search for the datatype */ while(dt && dt->addr_in != oinfo.addr) dt = dt->next; dt_ret = dt; - } - else + } + else { /* Create the stack */ size_t i; for(i=0; i<travt->nobjs; i++) - if(travt->objs[i].type == H5TRAV_TYPE_NAMED_DATATYPE) + if(travt->objs[i].type == H5TRAV_TYPE_NAMED_DATATYPE) { /* Push onto the stack */ if(NULL == (dt = (named_dt_t *) HDmalloc(sizeof(named_dt_t)))) @@ -296,7 +296,7 @@ hid_t copy_named_datatype(hid_t type_in, hid_t fidout, named_dt_t **named_dt_hea dt->id_out = -1; /* Check if this type is the one requested */ - if(oinfo.addr == dt->addr_in) + if(oinfo.addr == dt->addr_in) { HDassert(!dt_ret); dt_ret = dt; @@ -306,7 +306,7 @@ hid_t copy_named_datatype(hid_t type_in, hid_t fidout, named_dt_t **named_dt_hea /* Handle the case that the requested datatype was not found. This is * possible if the datatype was committed anonymously in the input file. */ - if(!dt_ret) + if(!dt_ret) { /* Push the new datatype onto the stack */ if(NULL == (dt_ret = (named_dt_t *) HDmalloc(sizeof(named_dt_t)))) @@ -321,7 +321,7 @@ hid_t copy_named_datatype(hid_t type_in, hid_t fidout, named_dt_t **named_dt_hea /* If the requested datatype does not yet exist in the output file, copy it * anonymously */ - if(dt_ret->id_out < 0) + if(dt_ret->id_out < 0) { if (options->use_native==1) dt_ret->id_out = h5tools_get_native_type(type_in); @@ -363,7 +363,7 @@ int named_datatype_free(named_dt_t **named_dt_head_p, int ignore_err) { named_dt_t *dt = *named_dt_head_p; - while(dt) + while(dt) { /* Pop the datatype off the stack and free it */ if(H5Tclose(dt->id_out) < 0 && !ignore_err) @@ -416,6 +416,8 @@ int copy_attr(hid_t loc_in, H5O_info_t oinfo; /* object info */ int j; unsigned u; + hbool_t is_ref=0; + H5T_class_t type_class = -1; if(H5Oget_info(loc_in, &oinfo) < 0) goto error; @@ -449,7 +451,7 @@ int copy_attr(hid_t loc_in, /* Copy named dt */ if((wtype_id = copy_named_datatype(ftype_id, fidout, named_dt_head_p, - travt, options)) < 0) + travt, options)) < 0) { H5Fclose(fidout); goto error; @@ -482,15 +484,37 @@ int copy_attr(hid_t loc_in, goto error; /*------------------------------------------------------------------------- - * object references are a special case - * we cannot just copy the buffers, but instead we recreate the reference - * this is done on a second sweep of the file that just copies - * the referenced objects + * object references are a special case. We cannot just copy the buffers, + * but instead we recreate the reference. + * This is done on a second sweep of the file that just copies the referenced + * objects at copy_refs_attr() *------------------------------------------------------------------------- */ + type_class = H5Tget_class(wtype_id); + is_ref = (type_class == H5T_REFERENCE); + if (type_class == H5T_VLEN ||type_class == H5T_ARRAY ) { + hid_t base_type = -1; + base_type = H5Tget_super(ftype_id); + is_ref = (is_ref || (H5Tget_class(base_type)==H5T_REFERENCE)); + H5Tclose(base_type); + } - if(H5T_REFERENCE == H5Tget_class(wtype_id)) { - ; + if (type_class == H5T_COMPOUND) { + int nmembers = H5Tget_nmembers(wtype_id) ; + for (j=0; j<nmembers; j++) { + hid_t mtid = H5Tget_member_type( wtype_id, j ); + H5T_class_t mtclass = H5Tget_class(mtid); + H5Tclose(mtid); + + if (mtclass==H5T_REFERENCE) { + is_ref = 1; + break; + } + } /* for (j=0; i<nmembers; j++) */ + } /* if (type_class == H5T_COMPOUND) */ + + if(is_ref) { + ; /* handled by copy_refs_attr() */ } else { /*------------------------------------------------------------------------- diff --git a/tools/h5repack/h5repack_refs.c b/tools/h5repack/h5repack_refs.c index e84b2ba..9e403f3 100644 --- a/tools/h5repack/h5repack_refs.c +++ b/tools/h5repack/h5repack_refs.c @@ -27,6 +27,8 @@ static const char* MapIdToName(hid_t refobj_id,trav_table_t *travt); static int copy_refs_attr(hid_t loc_in, hid_t loc_out, pack_opt_t *options, trav_table_t *travt, hid_t fidout); +static herr_t update_ref_value(hid_t obj_id, H5R_type_t ref_type, void *ref_in, + hid_t fid_out, void *ref_out, trav_table_t *travt); /*------------------------------------------------------------------------- * Function: do_copy_refobjs @@ -229,7 +231,7 @@ int do_copy_refobjs(hid_t fidin, * dataset region references *------------------------------------------------------------------------- */ - else if(H5Tequal(mtype_id, H5T_STD_REF_DSETREG)) + else if(H5Tequal(mtype_id, H5T_STD_REF_DSETREG)) { hid_t refobj_id; hdset_reg_ref_t *refbuf = NULL; /* input buffer for region references */ @@ -390,7 +392,7 @@ int do_copy_refobjs(hid_t fidin, } /* end switch */ } /* end for */ - /* Finalize (link) the stack of named datatypes (if any) + /* Finalize (link) the stack of named datatypes (if any) * This function is paired with copy_named_datatype() which is called * in copy_attr(), so need to free. */ @@ -429,6 +431,15 @@ error: * * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu * + * Modifier: xcao@hdfgroup.org, 9/12/2011 + * Update values of references(object and region) for the following types: + * 1) References, + * 2) ARRAY of reference, + * 3) VLEN of references. + * 4) COMPOUND of references. + * This function does not handle references in other complicated structures, + * such as references in nested compound datatypes. + * * Date: October, 28, 2003 * *------------------------------------------------------------------------- @@ -448,34 +459,95 @@ static int copy_refs_attr(hid_t loc_in, hid_t mtype_id = -1; /* memory data type ID */ size_t msize; /* memory size of type */ hsize_t nelmts; /* number of elements in dataset */ - int rank; /* rank of dataset */ hsize_t dims[H5S_MAX_RANK];/* dimensions of dataset */ char name[255]; H5O_info_t oinfo; /* Object info */ - int j; - unsigned u; + unsigned u, i, j; + int rank; + H5T_class_t type_class = -1; + hbool_t is_ref=0, is_ref_vlen=0, is_ref_array=0, is_ref_comp=0; + void *refbuf = NULL; + void *buf = NULL; + const char* refname; + int *ref_comp_index = NULL; + size_t *ref_comp_size = NULL; + int ref_comp_field_n = 0; + if(H5Oget_info(loc_in, &oinfo) < 0) goto error; for(u = 0; u < (unsigned)oinfo.num_attrs; u++) { - /*------------------------------------------------------------------------- - * open - *------------------------------------------------------------------------- - */ + is_ref = is_ref_vlen = is_ref_array = is_ref_comp = 0; + /* open attribute */ if((attr_id = H5Aopen_by_idx(loc_in, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error; - /* get name */ - if(H5Aget_name(attr_id, 255, name) < 0) - goto error; - /* get the file datatype */ if((ftype_id = H5Aget_type(attr_id)) < 0) goto error; + type_class = H5Tget_class(ftype_id); + + if((mtype_id = h5tools_get_native_type(ftype_id)) < 0) + goto error; + + if((msize = H5Tget_size(mtype_id)) == 0) + goto error; + + is_ref = (type_class == H5T_REFERENCE); + + if (type_class == H5T_VLEN ) { + hid_t base_type = -1; + base_type = H5Tget_super(ftype_id); + is_ref_vlen = (H5Tget_class(base_type)==H5T_REFERENCE); + msize = H5Tget_size(base_type); + H5Tclose(base_type); + } + + if (type_class == H5T_ARRAY ) { + hid_t base_type = -1; + base_type = H5Tget_super(ftype_id); + is_ref_array = (H5Tget_class(base_type)==H5T_REFERENCE); + msize = H5Tget_size(base_type); + H5Tclose(base_type); + } + + if (type_class == H5T_COMPOUND) { + int nmembers = H5Tget_nmembers(ftype_id) ; + if (nmembers < 1) + goto error; + + ref_comp_index = (int *)HDmalloc(nmembers*sizeof (int)); + ref_comp_size = (size_t *)HDmalloc(nmembers*sizeof(ref_comp_size)); + ref_comp_field_n = 0; + + for (i=0; i<(unsigned)nmembers; i++) { + hid_t mtid = H5Tget_member_type( ftype_id, i ); + if ((H5Tget_class(mtid)==H5T_REFERENCE)) { + ref_comp_index[ref_comp_field_n] = i; + ref_comp_size[ref_comp_field_n] = H5Tget_size(mtid); + ref_comp_field_n++; + } + H5Tclose(mtid); + } + } + + is_ref_comp = (ref_comp_field_n > 0); + + if (!(is_ref || is_ref_vlen || is_ref_array || is_ref_comp)) { + H5Tclose(mtype_id); + H5Tclose(ftype_id); + H5Aclose(attr_id); + continue; + } + + /* get name */ + if(H5Aget_name(attr_id, 255, name) < 0) + goto error; + /* get the dataspace handle */ if((space_id = H5Aget_space(attr_id)) < 0) goto error; @@ -490,35 +562,32 @@ static int copy_refs_attr(hid_t loc_in, *------------------------------------------------------------------------- */ nelmts = 1; - for(j = 0; j < rank; j++) + for(j = 0; j < (unsigned)rank; j++) nelmts *= dims[j]; - if((mtype_id = h5tools_get_native_type(ftype_id)) < 0) - goto error; - - if((msize = H5Tget_size(mtype_id)) == 0) + if (is_ref_array) { + unsigned array_rank = 0; + hsize_t array_size = 1; + hsize_t array_dims[H5S_MAX_RANK]; + hid_t base_type = -1; + base_type = H5Tget_super(ftype_id); + msize = H5Tget_size(base_type); + H5Tclose(base_type); + + array_rank = H5Tget_array_ndims(mtype_id); + H5Tget_array_dims2(mtype_id, array_dims); + for(j = 0; j <array_rank; j++) + array_size *= array_dims[j]; + nelmts *= array_size; + } + + if((attr_out = H5Acreate2(loc_out, name, ftype_id, space_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error; - - /*------------------------------------------------------------------------- - * object references are a special case - * we cannot just copy the buffers, but instead we recreate the reference - *------------------------------------------------------------------------- - */ - if(H5Tequal(mtype_id, H5T_STD_REF_OBJ)) + if (nelmts>0) { - hid_t refobj_id; - hobj_ref_t *refbuf = NULL; - unsigned k; - const char* refname; - hobj_ref_t *buf = NULL; - - /*------------------------------------------------------------------------- - * read input to memory - *------------------------------------------------------------------------- - */ - - if (nelmts) + /* handle object references */ + if((is_ref || is_ref_array) && (H5R_OBJ_REF_BUF_SIZE==msize)) { buf = (hobj_ref_t *)HDmalloc((unsigned)(nelmts * msize)); if(buf == NULL) @@ -536,65 +605,16 @@ static int copy_refs_attr(hid_t loc_in, goto error; } /* end if */ - for(k = 0; k < nelmts; k++) + for(i = 0; i < (unsigned)nelmts; i++) { - H5E_BEGIN_TRY - { - if((refobj_id = H5Rdereference2(attr_id, H5P_DEFAULT, H5R_OBJECT, &buf[k])) < 0) - goto error; - } H5E_END_TRY; - - /* get the name. a valid name could only occur in the - * second traversal of the file - */ - if((refname = MapIdToName(refobj_id, travt)) != NULL) - { - /* create the reference */ - if(H5Rcreate(&refbuf[k], fidout, refname, H5R_OBJECT, -1) < 0) - goto error; - if(options->verbose) - printf("object <%s> reference created to <%s>\n", name, refname); - } - H5Oclose(refobj_id); + if (update_ref_value(attr_id, H5R_OBJECT, &((hobj_ref_t *)buf)[i], fidout, &((hobj_ref_t *)refbuf)[i], travt)<0) + continue; + if(options->verbose) + printf("object <%s> reference created to <%s>\n", name, refname); } /* k */ - } /*nelmts*/ - - /*------------------------------------------------------------------------- - * copy - *------------------------------------------------------------------------- - */ - if((attr_out = H5Acreate2(loc_out, name, ftype_id, space_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) - goto error; - if(nelmts) - if(H5Awrite(attr_out, mtype_id, refbuf) < 0) - goto error; - - if(H5Aclose(attr_out) < 0) - goto error; - - if(refbuf) - HDfree(refbuf); - if(buf) - HDfree(buf); - }/*H5T_STD_REF_OBJ*/ - - /*------------------------------------------------------------------------- - * dataset region references - *------------------------------------------------------------------------- - */ - else if(H5Tequal(mtype_id, H5T_STD_REF_DSETREG)) - { - hid_t refobj_id; - hdset_reg_ref_t *refbuf = NULL; /* input buffer for region references */ - hdset_reg_ref_t *buf = NULL; /* output buffer */ - const char* refname; - unsigned k; - - /*------------------------------------------------------------------------- - * read input to memory - *------------------------------------------------------------------------- - */ - if(nelmts) + }/*H5T_STD_REF_OBJ*/ + /* handle region references */ + else if((is_ref || is_ref_array) && (H5R_DSET_REG_REF_BUF_SIZE == msize)) { buf = (hdset_reg_ref_t *)HDmalloc((unsigned)(nelmts * msize)); if(buf == NULL) @@ -616,56 +636,119 @@ static int copy_refs_attr(hid_t loc_in, goto error; } /* end if */ - for(k = 0; k < nelmts; k++) + for(i = 0; i < (unsigned)nelmts; i++) { - H5E_BEGIN_TRY - { - if((refobj_id = H5Rdereference2(attr_id, H5P_DEFAULT, H5R_DATASET_REGION, &buf[k])) < 0) - continue; - } H5E_END_TRY; - - /* get the name. a valid name could only occur in the - * second traversal of the file - */ - if((refname = MapIdToName(refobj_id, travt)) != NULL) - { - hid_t region_id; /* region id of the referenced dataset */ + if (update_ref_value(attr_id, H5R_DATASET_REGION, &((hdset_reg_ref_t *)buf)[i], fidout, &((hdset_reg_ref_t *)refbuf)[i], travt)<0) + continue; + if(options->verbose) + printf("object <%s> region reference created to <%s>\n", name, refname); + } + } /* H5T_STD_REF_DSETREG */ + else if (is_ref_vlen) { + /* handle VLEN of references */ + + buf = (hvl_t *)HDmalloc((unsigned)(nelmts * sizeof(hvl_t))); + refbuf = buf; /* reuse the read buffer for write */ - if((region_id = H5Rget_region(attr_id, H5R_DATASET_REGION, &buf[k])) < 0) - goto error; + if(buf == NULL) + { + printf( "cannot read into memory\n" ); + goto error; + } /* end if */ - /* create the reference, we need the space_id */ - if(H5Rcreate(&refbuf[k], fidout, refname, H5R_DATASET_REGION, region_id) < 0) - goto error; - if(H5Sclose(region_id) < 0) - goto error; - if(options->verbose) - printf("object <%s> region reference created to <%s>\n", name, refname); - } /* end if */ - H5Oclose(refobj_id); - } /* k */ - } /*nelmts */ + if(H5Aread(attr_id, mtype_id, buf) < 0) + goto error; - /*------------------------------------------------------------------------- - * copy - *------------------------------------------------------------------------- - */ - if((attr_out = H5Acreate2(loc_out, name, ftype_id, space_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) - goto error; - if(nelmts) - { - if(H5Awrite(attr_out, mtype_id, refbuf) < 0) + if (H5R_OBJ_REF_BUF_SIZE==msize) { + hobj_ref_t ref_out; + for (i=0; i<(unsigned)nelmts; i++) { + hobj_ref_t *ptr = (hobj_ref_t *)((hvl_t *)buf)[i].p; + for (j=0; j<((hvl_t *)buf)[i].len; j++ ) { + if (update_ref_value(attr_id, H5R_OBJECT, &(ptr[j]), fidout, &ref_out, travt)<0) + continue; + HDmemcpy(&(ptr[j]), &ref_out, msize); + } + } /* for (i=0; i<nelems; i++) */ + } else if (H5R_DSET_REG_REF_BUF_SIZE == msize) { + + hdset_reg_ref_t ref_out; + for (i=0; i<(unsigned)nelmts; i++) { + hdset_reg_ref_t *ptr = (hdset_reg_ref_t *)((hvl_t *)buf)[i].p; + for (j=0; j<((hvl_t *)buf)[i].len; j++ ) { + if (update_ref_value(attr_id, H5R_DATASET_REGION, &(ptr[j]), fidout, &ref_out, travt)<0) + continue; + HDmemcpy(&(ptr[j]), &ref_out, msize); + } + } /* for (i=0; i<nelems; i++) */ + } + } /* else if (is_ref_vlen) */ + else if (is_ref_comp) { + /* handle ref fields in a compound */ + + buf = HDmalloc((unsigned)(nelmts * msize)); + refbuf = buf; /* reuse the read buffer for write */ + + if(buf == NULL) + { + printf( "cannot read into memory\n" ); goto error; - } + } /* end if */ - if(H5Aclose(attr_out) < 0) - goto error; + if(H5Aread(attr_id, mtype_id, buf) < 0) + goto error; - if(refbuf) - HDfree(refbuf); - if(buf) - HDfree(buf); - } /* H5T_STD_REF_DSETREG */ + for (i=0; i<(unsigned)nelmts; i++) { + for (j=0; j<(unsigned)ref_comp_field_n; j++) { + if (ref_comp_size[j] == H5R_OBJ_REF_BUF_SIZE) { + int idx = i*msize+H5Tget_member_offset( mtype_id, (unsigned)ref_comp_index[j]); + hobj_ref_t ref_out; + if (update_ref_value(attr_id, H5R_OBJECT, (hobj_ref_t *)(buf+idx), fidout, &ref_out, travt)<0) + continue; + HDmemcpy(buf+idx, &ref_out, ref_comp_size[j]); + } /* if */ + else if (ref_comp_size[j] == H5R_DSET_REG_REF_BUF_SIZE) { + int idx = i*msize+H5Tget_member_offset( mtype_id, (unsigned)ref_comp_index[j]); + hdset_reg_ref_t ref_out; + if (update_ref_value(attr_id, H5R_DATASET_REGION, (hdset_reg_ref_t *)(buf+idx), fidout, &ref_out, travt)<0) + continue; + HDmemcpy(buf+idx, &ref_out, ref_comp_size[j]); + } /* else if */ + } /* j */ + } /* i */ + } /* else if (is_ref_comp) */ + + if(H5Awrite(attr_out, mtype_id, refbuf) < 0) + goto error; + + if (is_ref_vlen && buf) + H5Dvlen_reclaim (mtype_id, space_id, H5P_DEFAULT, buf); + } /* if (nelmts) */ + + if (refbuf == buf) + refbuf = NULL; /* set it to NULL to avoid double free since buf and refbuf are the same. */ + + if(buf) { + HDfree(buf); + buf = NULL; + } + + if(refbuf) { + HDfree(refbuf); + refbuf = NULL; + } + + if (ref_comp_index) { + HDfree(ref_comp_index); + ref_comp_index = NULL; + } + + if (ref_comp_size) { + HDfree(ref_comp_size); + ref_comp_size = NULL; + } + + if(H5Aclose(attr_out) < 0) + goto error; /*------------------------------------------------------------------------- * close @@ -679,11 +762,22 @@ static int copy_refs_attr(hid_t loc_in, goto error; if(H5Aclose(attr_id) < 0) goto error; - } /* u */ + } /* for(u = 0; u < (unsigned)oinfo.num_attrs; u++) */ return 0; error: + if(refbuf) + HDfree(refbuf); + if(buf) + HDfree(buf); + + if (ref_comp_index) + HDfree(ref_comp_index); + + if (ref_comp_size) + HDfree(ref_comp_size); + H5E_BEGIN_TRY { H5Tclose(ftype_id); H5Tclose(mtype_id); @@ -710,7 +804,7 @@ MapIdToName(hid_t refobj_id, trav_table_t *travt) /* linear search */ for(u = 0; u < travt->nobjs; u++) { - if(travt->objs[u].type == H5O_TYPE_DATASET || + if(travt->objs[u].type == H5O_TYPE_DATASET || travt->objs[u].type == H5O_TYPE_GROUP || travt->objs[u].type == H5O_TYPE_NAMED_DATATYPE) { H5O_info_t ref_oinfo; /* Stat for the refobj id */ @@ -730,3 +824,49 @@ out: return ret; } +/*------------------------------------------------------------------------- + * Function: Update_Ref_value + * + * Purpose: Update a reference value + * + * Programmer: xcao@hdfgroup.org 9/12/2011 + * + *------------------------------------------------------------------------- + */ +static herr_t update_ref_value(hid_t obj_id, H5R_type_t ref_type, void *ref_in, + hid_t fid_out, void *ref_out, trav_table_t *travt) +{ + herr_t ret = -1; + const char* ref_obj_name; + hid_t space_id=-1, ref_obj_id=-1; + + ref_obj_id = H5Rdereference2(obj_id, H5P_DEFAULT, ref_type, ref_in); + if (ref_obj_id<0) + goto done; + + ref_obj_name = MapIdToName(ref_obj_id, travt); + if (ref_obj_name == NULL) + goto done; + + if (ref_type == H5R_DATASET_REGION) { + space_id = H5Rget_region(obj_id, H5R_DATASET_REGION, ref_in); + if (space_id < 0) + goto done; + } + + ret = H5Rcreate(ref_out, fid_out, ref_obj_name, ref_type, space_id); + + if (ret < 0) + goto done; + + ret = 0; + +done: + H5E_BEGIN_TRY { + H5Sclose(space_id); + H5Oclose(ref_obj_id); + } H5E_END_TRY; + + return ret; +} + |