diff options
-rw-r--r-- | hl/src/H5DS.c | 377 | ||||
-rw-r--r-- | hl/src/H5DS.h | 10 | ||||
-rw-r--r-- | hl/test/test_ds.c | 208 |
3 files changed, 565 insertions, 30 deletions
diff --git a/hl/src/H5DS.c b/hl/src/H5DS.c index ba410ec..232109f 100644 --- a/hl/src/H5DS.c +++ b/hl/src/H5DS.c @@ -118,11 +118,14 @@ herr_t H5DSattach_scale(hid_t did, hsize_t *dims; /* dimension of the "REFERENCE_LIST" array */ ds_list_t dsl; /* attribute data in the DS pointing to the dataset */ ds_list_t *dsbuf; /* array of attribute data in the DS pointing to the dataset */ - hobj_ref_t ref; /* reference to the DS */ + hobj_ref_t ref_to_ds; /* reference to the DS */ + hobj_ref_t ref_j; /* iterator reference */ hvl_t *buf; /* VL buffer to store in the attribute */ + hid_t dsid_j; /* DS dataset ID in DIMENSION_LIST */ H5G_stat_t sb1, sb2; H5I_type_t it1, it2; int i, len; + int found_ds=0; /*------------------------------------------------------------------------- * parameter checking @@ -183,7 +186,7 @@ herr_t H5DSattach_scale(hid_t did, *------------------------------------------------------------------------- */ /* create a reference for the >>DS<< dataset */ - if (H5Rcreate(&ref,dsid,".",H5R_OBJECT,-1)<0) + if (H5Rcreate(&ref_to_ds,dsid,".",H5R_OBJECT,-1)<0) goto out; /* create a reference for the >>data<< dataset */ @@ -235,7 +238,7 @@ herr_t H5DSattach_scale(hid_t did, /* store the REF information in the index of the dataset that has the DS */ buf[idx].len = 1; buf[idx].p = malloc( 1 * sizeof(hobj_ref_t)); - ((hobj_ref_t *)buf[idx].p)[0] = ref; + ((hobj_ref_t *)buf[idx].p)[0] = ref_to_ds; /* write the attribute with the reference */ if (H5Awrite(aid,tid,buf)<0) @@ -285,20 +288,53 @@ herr_t H5DSattach_scale(hid_t did, if (H5Aread(aid,tid,buf)<0) goto out; - /* we are adding one more DS to this dimension */ - if ( buf[idx].len > 0 ) + /* check to avoid inserting duplicates. it is not FAIL, just do nothing */ + /* iterate all the REFs in this dimension IDX */ + for (i=0; i<(int)buf[idx].len; i++) { - buf[idx].len++; - len = buf[idx].len; - buf[idx].p = realloc( buf[idx].p, len * sizeof(hobj_ref_t)); - ((hobj_ref_t *)buf[idx].p)[ len-1 ] = ref; + /* get the reference */ + ref_j = ((hobj_ref_t *)buf[idx].p)[i]; + + /* get the scale id for this REF */ + if ((dsid_j = H5Rdereference(did,H5R_OBJECT,&ref_j))<0) + goto out; + + /* get info for DS in the parameter list */ + if (H5Gget_objinfo(dsid,".",TRUE,&sb1)<0) + goto out; + + /* get info for this DS */ + if (H5Gget_objinfo(dsid_j,".",TRUE,&sb2)<0) + goto out; + + /* same object, so this DS scale is already in this DIM IDX */ + if (sb1.fileno==sb2.fileno && sb1.objno==sb2.objno) + { + found_ds = 1; + } + + /* close the dereferenced dataset */ + if (H5Dclose(dsid_j)<0) + goto out; } - else + + if (found_ds==0) { - /* store the REF information in the index of the dataset that has the DS */ - buf[idx].len = 1; - buf[idx].p = malloc( 1 * sizeof(hobj_ref_t)); - ((hobj_ref_t *)buf[idx].p)[0] = ref; + /* we are adding one more DS to this dimension */ + if ( buf[idx].len > 0 ) + { + buf[idx].len++; + len = buf[idx].len; + buf[idx].p = realloc( buf[idx].p, len * sizeof(hobj_ref_t)); + ((hobj_ref_t *)buf[idx].p)[ len-1 ] = ref_to_ds; + } + else + { + /* store the REF information in the index of the dataset that has the DS */ + buf[idx].len = 1; + buf[idx].p = malloc( 1 * sizeof(hobj_ref_t)); + ((hobj_ref_t *)buf[idx].p)[0] = ref_to_ds; + } } /* write the attribute with the new references */ @@ -461,7 +497,7 @@ herr_t H5DSattach_scale(hid_t did, if (dsbuf) free(dsbuf); - } /* has_dimlist */ + } /* has_reflist */ /*------------------------------------------------------------------------- * write the standard attributes for a Dimension Scale dataset @@ -623,7 +659,7 @@ herr_t H5DSdetach_scale(hid_t did, /* reset */ if ( buf[idx].len > 0 ) { - for(j=0; j<buf[idx].len; j++) + for (j=0; j<buf[idx].len; j++) { /* get the reference */ ref = ((hobj_ref_t *)buf[idx].p)[j]; @@ -658,9 +694,6 @@ herr_t H5DSdetach_scale(hid_t did, } /* j */ } /* if */ - if (found_ds == 0) - goto out; - /* write the attribute */ if (H5Awrite(aid,tid,buf)<0) goto out; @@ -677,6 +710,10 @@ herr_t H5DSdetach_scale(hid_t did, if (buf) free(buf); + /* the scale must be present */ + if (found_ds == 0) + goto out; + /*------------------------------------------------------------------------- * the "REFERENCE_LIST" array exists, update *------------------------------------------------------------------------- @@ -732,9 +769,6 @@ herr_t H5DSdetach_scale(hid_t did, goto out; } /* i */ - if (found_dset == 0) - goto out; - /* update on disk */ if (H5Awrite(aid,tid,dsbuf)<0) goto out; @@ -748,6 +782,10 @@ herr_t H5DSdetach_scale(hid_t did, goto out; if (dsbuf) free(dsbuf); + + /* the pointed dataset must exist */ + if (found_dset == 0) + goto out; return SUCCESS; @@ -1495,3 +1533,298 @@ out: return FAIL; } + + +/*------------------------------------------------------------------------- + * private functions + *------------------------------------------------------------------------- + */ + + +/*------------------------------------------------------------------------- + * Function: H5DS_is_attached + * + * Purpose: Checks if the dataset named DNAME has a pointer in the REFERENCE_LIST + * attribute and the the dataset named DSNAME (scale ) has a pointer in the + * DIMENSION_LIST attribute + * + * Return: + * 1: both the DS and the dataset pointers match + * 0: one of them or both do not match + * FAIL (-1): error + * + * Programmer: pvn@ncsa.uiuc.edu + * + * Date: February 18, 2005 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +htri_t H5DS_is_attached(hid_t loc_id, + const char *dname, + const char *dsname, + unsigned int idx) +{ + int has_dimlist; + int has_reflist; + hssize_t nelmts; + hid_t did; /* dataset ID */ + hid_t dsid; /* scale dataset ID */ + hid_t sid; /* space ID */ + hid_t tid; /* attribute type ID */ + hid_t aid; /* attribute ID */ + int rank; /* rank of dataset */ + ds_list_t *dsbuf; /* array of attribute data in the DS pointing to the dataset */ + hobj_ref_t ref; /* reference to the DS */ + hvl_t *buf; /* VL buffer to store in the attribute */ + hid_t dsid_j; /* DS dataset ID in DIMENSION_LIST */ + H5G_stat_t sb1, sb2, sb3, sb4; + H5I_type_t it1, it2; + int i; + int found_dset=0, found_ds=0; + + /* get the dataset id */ + if ((did = H5Dopen(loc_id,dname))<0) + return FAIL; + + /* get the DS dataset id */ + if ((dsid = H5Dopen(loc_id,dsname))<0) + return FAIL; + +/*------------------------------------------------------------------------- + * parameter checking + *------------------------------------------------------------------------- + */ + /* the dataset cannot be a DS dataset */ + if ((H5DSis_scale(did))==1) + return FAIL; + + /* get info for the dataset in the parameter list */ + if (H5Gget_objinfo(did,".",TRUE,&sb1)<0) + return FAIL; + + /* get info for the scale in the parameter list */ + if (H5Gget_objinfo(dsid,".",TRUE,&sb2)<0) + return FAIL; + + /* same object, not valid */ + if (sb1.fileno==sb2.fileno && sb1.objno==sb2.objno) + return FAIL; + + /* get ID type */ + if ((it1 = H5Iget_type(did))<0) + return FAIL; + if ((it2 = H5Iget_type(dsid))<0) + return FAIL; + + if (H5I_DATASET!=it1 || H5I_DATASET!=it2) + return FAIL; + +/*------------------------------------------------------------------------- + * get space + *------------------------------------------------------------------------- + */ + + /* get dataset space */ + if ((sid = H5Dget_space(did))<0) + goto out; + + /* get rank */ + if ((rank=H5Sget_simple_extent_ndims(sid))<0) + goto out; + + /* close dataset space */ + if (H5Sclose(sid)<0) + goto out; + + /* parameter range checking */ + if (idx>(unsigned)rank-1) + goto out; + + /* try to find the attribute "DIMENSION_LIST" on the >>data<< dataset */ + if ((has_dimlist = H5LT_find_attribute(did,DIMENSION_LIST))<0) + return FAIL; + +/*------------------------------------------------------------------------- + * open "DIMENSION_LIST" + *------------------------------------------------------------------------- + */ + + if ( has_dimlist == 1 ) + { + if ((aid = H5Aopen_name(did,DIMENSION_LIST))<0) + goto out; + + if ((tid = H5Aget_type(aid))<0) + goto out; + + if ((sid = H5Aget_space(aid))<0) + goto out; + + /* allocate and initialize the VL */ + buf = (hvl_t*)malloc((size_t)rank * sizeof(hvl_t)); + + if (buf == NULL) + goto out; + + /* read */ + if (H5Aread(aid,tid,buf)<0) + goto out; + + /* iterate all the REFs in this dimension IDX */ + for (i=0; i<(int)buf[idx].len; i++) + { + /* get the reference */ + ref = ((hobj_ref_t *)buf[idx].p)[i]; + + /* get the scale id for this REF */ + if ((dsid_j = H5Rdereference(did,H5R_OBJECT,&ref))<0) + goto out; + + /* get info for DS in the parameter list */ + if (H5Gget_objinfo(dsid,".",TRUE,&sb1)<0) + goto out; + + /* get info for this DS */ + if (H5Gget_objinfo(dsid_j,".",TRUE,&sb2)<0) + goto out; + + /* same object */ + if (sb1.fileno==sb2.fileno && sb1.objno==sb2.objno) + { + found_ds = 1; + } + + /* close the dereferenced dataset */ + if (H5Dclose(dsid_j)<0) + goto out; + + } + + + /* close */ + if (H5Dvlen_reclaim(tid,sid,H5P_DEFAULT,buf)<0) + goto out; + if (H5Sclose(sid)<0) + goto out; + if (H5Tclose(tid)<0) + goto out; + if (H5Aclose(aid)<0) + goto out; + if (buf) + free(buf); + } /* has_dimlist */ + +/*------------------------------------------------------------------------- + * info on the >>DS<< dataset + *------------------------------------------------------------------------- + */ + + /* try to find the attribute "REFERENCE_LIST" on the >>DS<< dataset */ + if ((has_reflist = H5LT_find_attribute(dsid,REFERENCE_LIST))<0) + goto out; + +/*------------------------------------------------------------------------- + * open "REFERENCE_LIST" + *------------------------------------------------------------------------- + */ + + if ( has_reflist == 1 ) + { + if ((aid = H5Aopen_name(dsid,REFERENCE_LIST))<0) + goto out; + + if ((tid = H5Aget_type(aid))<0) + goto out; + + /* get and save the old reference(s) */ + if ((sid = H5Aget_space(aid))<0) + goto out; + + if ((nelmts = H5Sget_simple_extent_npoints(sid))<0) + goto out; + + dsbuf = malloc((size_t)nelmts * sizeof(ds_list_t)); + + if (dsbuf == NULL) + goto out; + + if (H5Aread(aid,tid,dsbuf)<0) + goto out; + +/*------------------------------------------------------------------------- + * iterate + *------------------------------------------------------------------------- + */ + + for(i=0; i<nelmts; i++) + { + /* get the reference */ + ref = dsbuf[i].ref; + + /* the reference was not deleted */ + if (ref) + { + /* get the DS id */ + if ((dsid_j = H5Rdereference(did,H5R_OBJECT,&ref))<0) + goto out; + + /* get info for dataset in the parameter list */ + if (H5Gget_objinfo(did,".",TRUE,&sb3)<0) + goto out; + + /* get info for this DS */ + if (H5Gget_objinfo(dsid_j,".",TRUE,&sb4)<0) + goto out; + + /* same object */ + if (sb3.fileno==sb4.fileno && sb3.objno==sb4.objno && (int)idx==dsbuf[i].dim_idx) { + found_dset=1; + } /* if */ + + /* close the dereferenced dataset */ + if (H5Dclose(dsid_j)<0) + goto out; + } /* if */ + } /* i */ + + + /* close */ + if (H5Sclose(sid)<0) + goto out; + if (H5Tclose(tid)<0) + goto out; + if (H5Aclose(aid)<0) + goto out; + if (dsbuf) + free(dsbuf); + } /* has_reflist */ + + /* close the dataset */ + if (H5Dclose(did)<0) + goto out; + + /* close the scale */ + if (H5Dclose(dsid)<0) + goto out; + + if (found_ds && found_dset) + return 1; + else + return 0; + +/* error zone, gracefully close */ +out: + H5E_BEGIN_TRY { + H5Sclose(sid); + H5Aclose(aid); + H5Tclose(tid); + H5Dclose(did); + H5Dclose(dsid); + } H5E_END_TRY; + return FAIL; +}
\ No newline at end of file diff --git a/hl/src/H5DS.h b/hl/src/H5DS.h index 6089e67..b179a19 100644 --- a/hl/src/H5DS.h +++ b/hl/src/H5DS.h @@ -75,6 +75,16 @@ herr_t H5DSiterate_scales(hid_t did, void *visitor_data); +/*------------------------------------------------------------------------- + * private functions + *------------------------------------------------------------------------- + */ +htri_t H5DS_is_attached(hid_t loc_id, + const char *dname, + const char *dsname, + unsigned int idx); + + #ifdef __cplusplus } #endif diff --git a/hl/test/test_ds.c b/hl/test/test_ds.c index 4197c60..b591a2f 100644 --- a/hl/test/test_ds.c +++ b/hl/test/test_ds.c @@ -31,12 +31,15 @@ static int test_errors(void); #define DIM_DATA 12 #define DIM1_SIZE 3 #define DIM2_SIZE 4 +#define DIM0 0 +#define DIM1 1 + /*------------------------------------------------------------------------- * the main program *------------------------------------------------------------------------- */ - +#if 1 int main(void) { int nerrors=0; @@ -142,7 +145,7 @@ static int test_simple(void) goto out; /*------------------------------------------------------------------------- - * attach the "ds1" dimension scale to "dset_a" + * attach the "ds_a_1" dimension scale to "dset_a" *------------------------------------------------------------------------- */ @@ -247,6 +250,15 @@ static int test_simple(void) if (H5Dclose(did)) goto out; + if (H5DS_is_attached(fid,"dset_a","ds_a_1",DIM0)<=0) + goto out; + if (H5DS_is_attached(fid,"dset_a","ds_a_2",DIM1)<=0) + goto out; + if (H5DS_is_attached(fid,"dset_a","ds_a_21",DIM1)<=0) + goto out; + if (H5DS_is_attached(fid,"dset_a","ds_a_22",DIM1)<=0) + goto out; + PASSED(); @@ -888,7 +900,8 @@ static int test_errors(void) hid_t dsid; /* scale ID */ hid_t gid; /* group ID */ hid_t sid; /* space ID */ - hid_t sidds; + hid_t sidds; /* space ID */ + int nscales; /* number of scales in DIM IDX */ printf("Testing error conditions\n"); @@ -1019,8 +1032,44 @@ static int test_errors(void) if (H5Dclose(did)<0) goto out; + /* verify attach */ + if (H5DS_is_attached(fid,"dset_b","ds_b_1",DIM0)<=0) + goto out; + if (H5DS_is_attached(fid,"dset_b","ds_b_2",DIM1)<=0) + goto out; + + /*------------------------------------------------------------------------- - * attach/attach + * detach + *------------------------------------------------------------------------- + */ + + /* get the dataset id for "dset_b" */ + if ((did = H5Dopen(fid,"dset_b"))<0) + goto out; + + /* get the DS dataset id */ + if ((dsid = H5Dopen(fid,"ds_b_1"))<0) + goto out; + + /* detach the dimension scale to "dset_b" in DIM 0 */ + if (H5DSdetach_scale(did,dsid,DIM0)<0) + goto out; + + /* verify attach, it must return 0 for no attach */ + if (H5DS_is_attached(fid,"dset_b","ds_b_1",DIM0)!=0) + goto out; + + /* close DS id */ + if (H5Dclose(dsid)<0) + goto out; + + /* close dataset ID of "dset_b" */ + if (H5Dclose(did)<0) + goto out; + +/*------------------------------------------------------------------------- + * attach again *------------------------------------------------------------------------- */ @@ -1033,7 +1082,17 @@ static int test_errors(void) goto out; /* attach "ds_b_1" again in DIM 0 */ - if (H5DSattach_scale(did,dsid,0)<0) + if (H5DSattach_scale(did,dsid,DIM0)<0) + goto out; + + /* verify attach, it must return 1 for attach */ + if (H5DS_is_attached(fid,"dset_b","ds_b_1",DIM0)!=1) + goto out; + + /* verify that "ds_b_1" has only 1 scale at DIM0 */ + if (H5DSget_nscales(did,DIM0,&nscales)<0) + goto out; + if (nscales!=1) goto out; /* close DS id */ @@ -1058,11 +1117,21 @@ static int test_errors(void) goto out; /* detach the "ds_b_2" dimension scale to "dset_b" in DIM 1 */ - if (H5DSdetach_scale(did,dsid,1)<0) + if (H5DSdetach_scale(did,dsid,DIM1)<0) goto out; /* detach again, it should fail */ - if (H5DSdetach_scale(did,dsid,1)==SUCCESS) + if (H5DSdetach_scale(did,dsid,DIM1)==SUCCESS) + goto out; + + /* verify attach, it must return 0 for no attach */ + if (H5DS_is_attached(fid,"dset_b","ds_b_2",DIM1)!=0) + goto out; + + /* verify that "ds_b_1" has no scale at DIM1 */ + if (H5DSget_nscales(did,DIM1,&nscales)<0) + goto out; + if (nscales!=0) goto out; /* close DS id */ @@ -1073,6 +1142,57 @@ static int test_errors(void) if (H5Dclose(did)<0) goto out; +/*------------------------------------------------------------------------- + * attach twice + *------------------------------------------------------------------------- + */ + + /* get the dataset id for "dset_b" */ + if ((did = H5Dopen(fid,"dset_b"))<0) + goto out; + + /* get the DS dataset id */ + if ((dsid = H5Dopen(fid,"ds_b_2"))<0) + goto out; + + /* attach "ds_b_2" in DIM 1 */ + if (H5DSattach_scale(did,dsid,DIM1)<0) + goto out; + + /* verify attach, it must return 1 for attach */ + if (H5DS_is_attached(fid,"dset_b","ds_b_2",DIM1)!=1) + goto out; + + /* verify that "ds_b_2" has only 1 scale at DIM1 */ + if (H5DSget_nscales(did,DIM0,&nscales)<0) + goto out; + if (nscales!=1) + goto out; + + /* attach "ds_b_2" again in DIM 1 */ + if (H5DSattach_scale(did,dsid,DIM1)<0) + goto out; + + /* verify attach, it must return 1 for attach */ + if (H5DS_is_attached(fid,"dset_b","ds_b_2",DIM1)!=1) + goto out; + + /* verify that "ds_b_2" has only 1 scale at DIM1 */ + if (H5DSget_nscales(did,DIM0,&nscales)<0) + goto out; + if (nscales!=1) + goto out; + + /* close DS id */ + if (H5Dclose(dsid)<0) + goto out; + + /* close dataset ID of "dset_b" */ + if (H5Dclose(did)<0) + goto out; + + + PASSED(); /* close */ @@ -1314,4 +1434,76 @@ out: H5Sclose(sid); } H5E_END_TRY; return FAIL; -}
\ No newline at end of file +} + + +#else + + + +#include "hdf5.h" + +#define H5FILE_NAME "SDS.h5" +#define DATASETNAME "IntArray" +#define DIMNAME "Dim1" +#define NX 5 /* dataset dimensions */ +#define NY 6 +#define RANK 2 + +int +main (void) +{ + hid_t file, dataset; /* file and dataset handles */ + hid_t datatype, dataspace; /* handles */ + hid_t scale; + hid_t grp; + hsize_t dimsf[2]; /* dataset dimensions */ + herr_t status; + int data[NX][NY]; /* data to write */ + int i, j; + + /* + * Data and output buffer initialization. + */ + for (j = 0; j < NX; j++) { + for (i = 0; i < NY; i++) + data[j][i] = i + j; + } + file = H5Fcreate(H5FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + dimsf[0] = NX; + dimsf[1] = NY; + dataspace = H5Screate_simple(RANK, dimsf, NULL); + + dataset = H5Dcreate(file, DATASETNAME, H5T_NATIVE_INT, dataspace, + H5P_DEFAULT); + + status = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, data); + + scale = H5Dcreate(file, DIMNAME, H5T_NATIVE_INT, dataspace, + H5P_DEFAULT); + + grp = H5Gcreate(file, "/Data", 0); + + status = H5DSset_scale(scale,"foo"); + printf("set scale returns: %d\n", status); + + status = H5DSattach_scale(dataset,scale,0); + printf("attach scale returns: %d\n", status); + status = H5DSattach_scale(dataset,scale,1); + printf("attach scale returns: %d\n", status); + status = H5DSdetach_scale(dataset,scale,0); + printf("detach scale returns: %d\n", status); + + H5Sclose(dataspace); + H5Dclose(dataset); + H5Dclose(scale); + H5Fclose(file); + + return 0; +} + + + +#endif
\ No newline at end of file |