diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2001-07-10 21:19:18 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2001-07-10 21:19:18 (GMT) |
commit | 990fadfbe55353383639f0151990ec375fbe18cb (patch) | |
tree | a07f3b3215057bad7d46cbb9e26a4699b1fc8040 /src | |
parent | 0c1c23245d103927c5d59c67b84526974e6217af (diff) | |
download | hdf5-990fadfbe55353383639f0151990ec375fbe18cb.zip hdf5-990fadfbe55353383639f0151990ec375fbe18cb.tar.gz hdf5-990fadfbe55353383639f0151990ec375fbe18cb.tar.bz2 |
[svn-r4181] Purpose:
Bug Fix, Code Cleanup, Code Optimization, etc.
Description:
Fold in the hyperslab speedups, clean up compile warnings and change a
few things from using 'unsigned' or 'hsize_t' to use 'size_t' instead.
Platforms tested:
FreeBSD 4.3 (hawkwind), Solaris 2.7 (arabica), Irix64 6.5 (modi4)
Diffstat (limited to 'src')
44 files changed, 4682 insertions, 2695 deletions
@@ -123,8 +123,8 @@ static herr_t H5B_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5B_t *b); static H5B_t *H5B_load(H5F_t *f, haddr_t addr, const void *_type, void *udata); static herr_t H5B_decode_key(H5F_t *f, H5B_t *bt, intn idx); static herr_t H5B_decode_keys(H5F_t *f, H5B_t *bt, intn idx); -static hsize_t H5B_nodesize(H5F_t *f, const H5B_class_t *type, - hsize_t *total_nkey_size, size_t sizeof_rkey); +static size_t H5B_nodesize(H5F_t *f, const H5B_class_t *type, + size_t *total_nkey_size, size_t sizeof_rkey); static herr_t H5B_split(H5F_t *f, const H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr, intn idx, const double split_ratios[], void *udata, @@ -191,8 +191,8 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata, { H5B_t *bt = NULL; size_t sizeof_rkey; - hsize_t size; - hsize_t total_native_keysize; + size_t size; + size_t total_native_keysize; size_t offset; intn i; herr_t ret_value = FAIL; @@ -211,7 +211,7 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata, */ sizeof_rkey = (type->get_sizeof_rkey) (f, udata); size = H5B_nodesize(f, type, &total_native_keysize, sizeof_rkey); - if (HADDR_UNDEF==(*addr_p=H5MF_alloc(f, H5FD_MEM_BTREE, size))) { + if (HADDR_UNDEF==(*addr_p=H5MF_alloc(f, H5FD_MEM_BTREE, (hsize_t)size))) { HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree root node"); } @@ -229,8 +229,8 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata, bt->nchildren = 0; if (NULL==(bt->page=H5FL_BLK_ALLOC(page,size,1)) || NULL==(bt->native=H5FL_BLK_ALLOC(native_block,total_native_keysize,0)) || - NULL==(bt->child=H5FL_ARR_ALLOC(haddr_t,(2*H5B_K(f,type)),0)) || - NULL==(bt->key=H5FL_ARR_ALLOC(H5B_key_t,(2*H5B_K(f,type)+1),0))) { + NULL==(bt->child=H5FL_ARR_ALLOC(haddr_t,(size_t)(2*H5B_K(f,type)),0)) || + NULL==(bt->key=H5FL_ARR_ALLOC(H5B_key_t,(size_t)(2*H5B_K(f,type)+1),0))) { HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree root node"); } @@ -271,7 +271,7 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata, done: if (ret_value<0) { - H5MF_xfree(f, H5FD_MEM_BTREE, *addr_p, size); + H5MF_xfree(f, H5FD_MEM_BTREE, *addr_p, (hsize_t)size); if (bt) { H5FL_BLK_FREE (page,bt->page); H5FL_BLK_FREE (native_block,bt->native); @@ -307,8 +307,8 @@ static H5B_t * H5B_load(H5F_t *f, haddr_t addr, const void *_type, void *udata) { const H5B_class_t *type = (const H5B_class_t *) _type; - hsize_t total_nkey_size; - hsize_t size; + size_t total_nkey_size; + size_t size; H5B_t *bt = NULL; intn i; uint8_t *p; @@ -333,12 +333,12 @@ H5B_load(H5F_t *f, haddr_t addr, const void *_type, void *udata) bt->ndirty = 0; if (NULL==(bt->page=H5FL_BLK_ALLOC(page,size,0)) || NULL==(bt->native=H5FL_BLK_ALLOC(native_block,total_nkey_size,0)) || - NULL==(bt->key=H5FL_ARR_ALLOC(H5B_key_t,(2*H5B_K(f,type)+1),0)) || - NULL==(bt->child=H5FL_ARR_ALLOC(haddr_t,(2*H5B_K(f,type)),0))) { + NULL==(bt->key=H5FL_ARR_ALLOC(H5B_key_t,(size_t)(2*H5B_K(f,type)+1),0)) || + NULL==(bt->child=H5FL_ARR_ALLOC(haddr_t,(size_t)(2*H5B_K(f,type)),0))) { HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - if (H5F_block_read(f, H5FD_MEM_BTREE, addr, (hsize_t)size, H5P_DEFAULT, bt->page)<0) { + if (H5F_block_read(f, H5FD_MEM_BTREE, addr, size, H5P_DEFAULT, bt->page)<0) { HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree node"); } @@ -420,7 +420,7 @@ static herr_t H5B_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5B_t *bt) { intn i; - hsize_t size = 0; + size_t size = 0; uint8_t *p = bt->page; FUNC_ENTER(H5B_flush, FAIL); @@ -487,7 +487,7 @@ H5B_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5B_t *bt) if (IS_H5FD_MPIO(f)) H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /* only p0 will write */ #endif /* H5_HAVE_PARALLEL */ - if (H5F_block_write(f, H5FD_MEM_BTREE, addr, (hsize_t)size, H5P_DEFAULT, bt->page)<0) { + if (H5F_block_write(f, H5FD_MEM_BTREE, addr, size, H5P_DEFAULT, bt->page)<0) { HRETURN_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree node to disk"); } @@ -1563,7 +1563,7 @@ H5B_iterate (H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata) * We've reached the left-most leaf. Now follow the right-sibling * pointer from leaf to leaf until we've processed all leaves. */ - if (NULL==(child=H5FL_ARR_ALLOC(haddr_t,(2*H5B_K(f,type)),0)) || + if (NULL==(child=H5FL_ARR_ALLOC(haddr_t,(size_t)(2*H5B_K(f,type)),0)) || NULL==(key=H5MM_malloc((2*H5B_K(f, type)+1)*type->sizeof_nkey))) { HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); @@ -1998,11 +1998,11 @@ H5B_remove(H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata) * *------------------------------------------------------------------------- */ -static hsize_t +static size_t H5B_nodesize(H5F_t *f, const H5B_class_t *type, - hsize_t *total_nkey_size/*out*/, size_t sizeof_rkey) + size_t *total_nkey_size/*out*/, size_t sizeof_rkey) { - hsize_t size; + size_t size; FUNC_ENTER(H5B_nodesize, (size_t) 0); @@ -2052,10 +2052,10 @@ static H5B_t * H5B_copy(H5F_t *f, const H5B_t *old_bt) { H5B_t *ret_value = NULL; - hsize_t total_native_keysize; - hsize_t size; - hsize_t nkeys; - hsize_t u; + size_t total_native_keysize; + size_t size; + size_t nkeys; + size_t u; FUNC_ENTER(H5B_copy, NULL); @@ -2091,13 +2091,9 @@ H5B_copy(H5F_t *f, const H5B_t *old_bt) } /* Copy the other structures */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ HDmemcpy(ret_value->page,old_bt->page,(size_t)size); - assert(total_native_keysize==(hsize_t)((size_t)total_native_keysize)); /*check for overflow*/ HDmemcpy(ret_value->native,old_bt->native,(size_t)total_native_keysize); - assert((sizeof(haddr_t)*nkeys)==(hsize_t)((size_t)(sizeof(haddr_t)*nkeys))); /*check for overflow*/ HDmemcpy(ret_value->child,old_bt->child,(size_t)(sizeof(haddr_t)*nkeys)); - assert((sizeof(H5B_key_t)*(nkeys+1))==(hsize_t)((size_t)(sizeof(H5B_key_t)*(nkeys+1)))); /*check for overflow*/ HDmemcpy(ret_value->key,old_bt->key,(size_t)(sizeof(H5B_key_t)*(nkeys+1))); /* @@ -86,11 +86,12 @@ H5D_xfer_t H5D_xfer_dflt = { 0, /*Don't cache the hyperslab blocks */ #endif /* H5_HAVE_PARALLEL */ 0, /*No limit on hyperslab block size to cache */ + 1024, /*Number of I/O vectors for hyperslabs */ NULL, /*Use malloc() for VL data allocations */ NULL, /*No information needed for malloc() calls */ NULL, /*Use free() for VL data frees */ NULL, /*No information needed for free() calls */ - H5FD_VFD_DEFAULT, /*See H5Pget_driver() */ + H5FD_VFD_DEFAULT, /*See H5Pget_driver() */ NULL, /*No file driver-specific information yet */ #ifdef COALESCE_READS 0, /*coalesce single reads into a read */ @@ -1587,7 +1588,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, herr_t status; /*function return status*/ size_t src_type_size; /*size of source type */ size_t dst_type_size; /*size of destination type*/ - hsize_t target_size; /*desired buffer size */ + size_t target_size; /*desired buffer size */ hsize_t request_nelmts; /*requested strip mine */ H5T_bkg_t need_bkg; /*type of background buf*/ H5S_t *free_this_space=NULL; /*data space to free */ @@ -1774,15 +1775,15 @@ printf("%s: check 1.2, \n",FUNC); /* * This is the general case. Figure out the strip mine size. */ - if ((sconv->f->init)(&(dataset->layout), file_space, &file_iter)<0) { + if ((sconv->f->init)(file_space, &file_iter)<0) { HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information"); } - if ((sconv->m->init)(&(dataset->layout), mem_space, &mem_iter)<0) { + if ((sconv->m->init)(mem_space, &mem_iter)<0) { HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information"); } - if ((sconv->m->init)(&(dataset->layout), mem_space, &bkg_iter)<0) { + if ((sconv->m->init)(mem_space, &bkg_iter)<0) { HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize background selection information"); } @@ -1829,7 +1830,8 @@ printf("%s: check 2.0, src_type_size=%d, dst_type_size=%d, target_size=%d\n",FUN printf("%s: check 3.2, allocating conversion buffer\n",FUNC); #endif /* Allocate temporary buffer */ - if((bkg_buf=H5FL_BLK_ALLOC(bkgr_conv,request_nelmts*dst_type_size,0))==NULL) + H5_CHECK_OVERFLOW((request_nelmts*dst_type_size),hsize_t,size_t); + if((bkg_buf=H5FL_BLK_ALLOC(bkgr_conv,(size_t)(request_nelmts*dst_type_size),0))==NULL) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for background conversion"); } @@ -2035,7 +2037,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, herr_t status; /*function return status*/ size_t src_type_size; /*size of source type */ size_t dst_type_size; /*size of destination type*/ - hsize_t target_size; /*desired buffer size */ + size_t target_size; /*desired buffer size */ hsize_t request_nelmts; /*requested strip mine */ H5T_bkg_t need_bkg; /*type of background buf*/ H5S_t *free_this_space=NULL; /*data space to free */ @@ -2251,15 +2253,15 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, /* * This is the general case. Figure out the strip mine size. */ - if ((sconv->f->init)(&(dataset->layout), file_space, &file_iter)<0) { + if ((sconv->f->init)(file_space, &file_iter)<0) { HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information"); } - if ((sconv->m->init)(&(dataset->layout), mem_space, &mem_iter)<0) { + if ((sconv->m->init)(mem_space, &mem_iter)<0) { HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information"); } - if ((sconv->f->init)(&(dataset->layout), file_space, &bkg_iter)<0) { + if ((sconv->f->init)(file_space, &bkg_iter)<0) { HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information"); } @@ -2300,7 +2302,8 @@ printf("%s: check 2.0, src_type_size=%d, dst_type_size=%d, target_size=%d\n",FUN } if (need_bkg && NULL==(bkg_buf=xfer_parms->bkg_buf)) { /* Allocate temporary buffer */ - if((bkg_buf=H5FL_BLK_ALLOC(bkgr_conv,request_nelmts*dst_type_size,0))==NULL) + H5_CHECK_OVERFLOW((request_nelmts*dst_type_size),hsize_t,size_t); + if((bkg_buf=H5FL_BLK_ALLOC(bkgr_conv,(size_t)(request_nelmts*dst_type_size),0))==NULL) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for background conversion"); } @@ -2650,7 +2653,8 @@ static herr_t H5D_init_storage(H5D_t *dset, const H5S_t *space) { hssize_t npoints, ptsperbuf; - hsize_t size, bufsize=8*1024; + size_t bufsize=8*1024; + size_t size; haddr_t addr; herr_t ret_value = FAIL; void *buf = NULL; diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index e08707e..8c3055f 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -39,82 +39,447 @@ static intn interface_initialize_g = 0; * Thursday, September 28, 2000 * * Modifications: + * Re-written in terms of the new readv call, QAK, 7/7/01 * *------------------------------------------------------------------------- */ herr_t -H5F_contig_read(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, hsize_t size, hid_t dxpl_id, - void *buf/*out*/) +H5F_contig_read(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, + size_t size, hid_t dxpl_id, void *buf/*out*/) { - haddr_t abs_eoa; /* Absolute end of file address */ - haddr_t rel_eoa; /* Relative end of file address */ + hsize_t offset=0; /* Offset for vector call */ FUNC_ENTER(H5F_contig_read, FAIL); /* Check args */ assert(f); - assert(size<SIZET_MAX); + assert(buf); + + if (H5F_contig_readv(f, max_data, type, addr, 1, &size, &offset, dxpl_id, buf)<0) + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "vector read failed"); + + FUNC_LEAVE(SUCCEED); +} /* end H5F_contig_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_contig_write + * + * Purpose: Writes some data from a dataset into a buffer. + * The data is contiguous. The address is relative to the base + * address for the file. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, September 28, 2000 + * + * Modifications: + * Re-written in terms of the new readv call, QAK, 7/7/01 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_contig_write(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, size_t size, + hid_t dxpl_id, const void *buf) +{ + hsize_t offset=0; /* Offset for vector call */ + + FUNC_ENTER(H5F_contig_write, FAIL); + + assert (f); + assert (buf); + + if (H5F_contig_writev(f, max_data, type, addr, 1, &size, &offset, dxpl_id, buf)<0) + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vector write failed"); + + FUNC_LEAVE(SUCCEED); +} /* end H5F_contig_write() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_contig_readv + * + * Purpose: Reads some data vectors from a dataset into a buffer. + * The data is contiguous. The address is the start of the dataset, + * relative to the base address for the file and the offsets and + * sequence lengths are in bytes. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Friday, May 3, 2001 + * + * Notes: + * Offsets in the sequences must be monotonically increasing + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_contig_readv(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr, + size_t nseq, size_t size_arr[], hsize_t offset_arr[], hid_t dxpl_id, + void *_buf/*out*/) +{ + unsigned char *buf=(unsigned char *)_buf; /* Pointer to buffer to fill */ + haddr_t abs_eoa; /* Absolute end of file address */ + haddr_t rel_eoa; /* Relative end of file address */ + haddr_t addr; /* Actual address to read */ + hsize_t max_data; /* Actual maximum size of data to cache */ + size_t size; /* Size of sequence in bytes */ + size_t u; /* Counting variable */ +#ifndef SLOW_WAY + size_t max_seq; /* Maximum sequence to copy */ + haddr_t temp_end; /* Temporary end of buffer variable */ + size_t max_search; /* Maximum number of sequences to search */ + size_t mask; /* Bit mask */ + intn bit_loc; /* Bit location of the leftmost '1' in max_search */ + size_t *size_arr_p; /* Pointer into the size array */ + hsize_t *offset_arr_p; /* Pointer into the offset array */ +#endif /* SLOW_WAY */ + + FUNC_ENTER(H5F_contig_readv, FAIL); + + /* Check args */ + assert(f); assert(buf); /* Check if data sieving is enabled */ if(f->shared->lf->feature_flags&H5FD_FEAT_DATA_SIEVE) { - /* Try reading from the data sieve buffer */ - if(f->shared->sieve_buf) { - haddr_t sieve_start, sieve_end; /* Start & end locations of sieve buffer */ - haddr_t contig_end; /* End locations of block to write */ - hsize_t sieve_size; /* size of sieve buffer */ - - /* Stash local copies of these value */ - sieve_start=f->shared->sieve_loc; - sieve_size=f->shared->sieve_size; - sieve_end=sieve_start+sieve_size; - contig_end=addr+size-1; - - /* If entire read is within the sieve buffer, read it from the buffer */ - if(addr>=sieve_start && contig_end<sieve_end) { - /* Grab the data out of the buffer */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(buf,f->shared->sieve_buf+(addr-sieve_start),(size_t)size); - } /* end if */ - /* Entire request is not within this data sieve buffer */ - else { - /* Check if we can actually hold the I/O request in the sieve buffer */ - if(size>f->shared->sieve_buf_size) { - /* Check for any overlap with the current sieve buffer */ - if((sieve_start>=addr && sieve_start<(contig_end+1)) - || ((sieve_end-1)>=addr && (sieve_end-1)<(contig_end+1))) { - /* Flush the sieve buffer, if it's dirty */ - if(f->shared->sieve_dirty) { - /* Write to file */ - if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "block write failed"); + + /* Outer loop, guarantees working through all the sequences */ + for(u=0; u<nseq; ) { + + /* Try reading from the data sieve buffer */ + if(f->shared->sieve_buf) { + haddr_t sieve_start, sieve_end; /* Start & end locations of sieve buffer */ + haddr_t contig_end; /* End locations of block to write */ + size_t sieve_size; /* size of sieve buffer */ + + /* Stash local copies of these value */ + sieve_start=f->shared->sieve_loc; + sieve_size=f->shared->sieve_size; + sieve_end=sieve_start+sieve_size; + + /* Next-outer loop works through sequences as fast as possible */ + for(; u<nseq; ) { + size=size_arr[u]; + addr=_addr+offset_arr[u]; + + /* Compute end of sequence to retrieve */ + contig_end=addr+size-1; + + /* If entire read is within the sieve buffer, read it from the buffer */ + if(addr>=sieve_start && contig_end<sieve_end) { + unsigned char *base_sieve_buf=f->shared->sieve_buf+(_addr-sieve_start); + unsigned char *temp_sieve_buf; + haddr_t temp_addr=_addr-1; /* Temporary address */ + +#ifdef SLOW_WAY + /* Retrieve all the sequences out of the current sieve buffer */ + while(contig_end<sieve_end) { + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+offset_arr[u]; + + /* Grab the data out of the buffer */ + HDmemcpy(buf,temp_sieve_buf,size_arr[u]); + + /* Increment offset in buffer */ + buf += size_arr[u]; + + /* Increment sequence number, check for finished with sequences */ + if((++u) >= nseq) + break; + + /* Re-compute end of sequence to retrieve */ + contig_end=temp_addr+offset_arr[u]+size_arr[u]; + } /* end while */ +#else /* SLOW_WAY */ + /* Find log2(n) where n is the number of elements to search */ + + /* Set initial parameters */ + mask=(size_t)0xff<<((sizeof(size_t)-1)*8); /* Get a mask for the leftmost byte */ + max_search=((nseq-1)-u)+1; /* Compute 'n' for the log2 */ + assert(max_search>0); /* Sanity check */ + bit_loc=(sizeof(size_t)*8)-1; /* Initial bit location */ + + /* Search for the first byte with a bit set */ + while((max_search & mask)==0) { + mask>>=8; + bit_loc-=8; + } /* end while */ + + /* Switch to searching for a bit */ + mask=1<<bit_loc; + while((max_search & mask)==0) { + mask>>=1; + bit_loc--; + } /* end while */ + + /* location of the leftmost bit, plus 1, is log2(n) */ + max_seq=bit_loc+1; + + /* Don't walk off the array */ + max_seq=MIN(u+max_seq,nseq-1); + + /* Determine if a linear search is faster than a binary search */ + temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq]; + if(temp_end>=sieve_end) { + /* Linear search is faster */ + + /* Set the initial search values */ + max_seq=u; + temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq]; + + /* Search for the first sequence ending greater than the sieve buffer end */ + while(temp_end<sieve_end) { + if(++max_seq>=nseq) + break; + temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq]; + } /* end while */ + + /* Adjust back one element */ + max_seq--; + + } /* end if */ + else { + size_t lo,hi; /* Low and high bounds for binary search */ + uintn found=0; /* Flag to indicate bounds have been found */ + + /* Binary search is faster */ + + /* Find the value 'u' which will be beyond the end of the sieve buffer */ + lo=u; + hi=nseq-1; + max_seq=(lo+hi)/2; + while(!found) { + /* Get the address of the end of sequence for the 'max_seq' position */ + temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq]; + + /* Current high bound is too large */ + if(temp_end>=sieve_end) { + if((lo+1)<hi) { + hi=max_seq; + max_seq=(lo+hi)/2; + } /* end if */ + else { + found=1; + } /* end else */ + } /* end if */ + /* Current low bound is too small */ + else { + if((lo+1)<hi) { + lo=max_seq; + max_seq=(lo+hi+1)/2; + } /* end if */ + else { + found=1; + } /* end else */ + } /* end else */ + } /* end while */ + + /* Check for non-exact match */ + if(lo!=hi) { + temp_end=temp_addr+offset_arr[hi]+size_arr[hi]; + if(temp_end<sieve_end) + max_seq=hi; + else + max_seq=lo; + } /* end if */ + } /* end else */ + + /* Set the pointers to the correct locations in the offset & size arrays */ + size_arr_p=&size_arr[u]; + offset_arr_p=&offset_arr[u]; + +#ifdef NO_DUFFS_DEVICE + /* Retrieve all the sequences out of the current sieve buffer */ + while(u<=max_seq) { + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(buf,temp_sieve_buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + } /* end while */ +#else /* NO_DUFFS_DEVICE */ +{ + size_t seq_count; + + seq_count=(max_seq-u)+1; + switch (seq_count % 4) { + case 0: + do + { + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(buf,temp_sieve_buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + + case 3: + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(buf,temp_sieve_buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + + case 2: + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(buf,temp_sieve_buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + + case 1: + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(buf,temp_sieve_buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + + } while (u<=max_seq); + } /* end switch */ + +} +#endif /* NO_DUFFS_DEVICE */ +#endif /* SLOW_WAY */ + } /* end if */ + /* Entire request is not within this data sieve buffer */ + else { + /* Check if we can actually hold the I/O request in the sieve buffer */ + if(size>f->shared->sieve_buf_size) { + /* Check for any overlap with the current sieve buffer */ + if((sieve_start>=addr && sieve_start<(contig_end+1)) + || ((sieve_end-1)>=addr && (sieve_end-1)<(contig_end+1))) { + /* Flush the sieve buffer, if it's dirty */ + if(f->shared->sieve_dirty) { + /* Write to file */ + if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "block write failed"); + } + + /* Reset sieve buffer dirty flag */ + f->shared->sieve_dirty=0; + } /* end if */ + } /* end if */ + + /* Read directly into the user's buffer */ + if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "block read failed"); + } + } /* end if */ + /* Element size fits within the buffer size */ + else { + /* Flush the sieve buffer if it's dirty */ + if(f->shared->sieve_dirty) { + /* Write to file */ + if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "block write failed"); + } + + /* Reset sieve buffer dirty flag */ + f->shared->sieve_dirty=0; + } /* end if */ + + /* Determine the new sieve buffer size & location */ + f->shared->sieve_loc=addr; + + /* Make certain we don't read off the end of the file */ + if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf))) { + HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, + "unable to determine file size"); + } + + /* Adjust absolute EOA address to relative EOA address */ + rel_eoa=abs_eoa-f->shared->base_addr; + + /* Only need this when resizing sieve buffer */ + max_data=_max_data-offset_arr[u]; + + /* Compute the size of the sieve buffer */ + /* Don't read off the end of the file, don't read past the end of the data element and don't read more than the buffer size */ + f->shared->sieve_size=MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)); + + /* Update local copies of sieve information */ + sieve_start=f->shared->sieve_loc; + sieve_size=f->shared->sieve_size; + sieve_end=sieve_start+sieve_size; + + /* Read the new sieve buffer */ + if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "block read failed"); } /* Reset sieve buffer dirty flag */ f->shared->sieve_dirty=0; - } /* end if */ - } /* end if */ - /* Read directly into the user's buffer */ + /* Grab the data out of the buffer (must be first piece of data in buffer ) */ + HDmemcpy(buf,f->shared->sieve_buf,size); + } /* end else */ + + /* Increment offset in buffer */ + buf += size_arr[u]; + + /* Increment sequence number */ + u++; + } /* end else */ + } /* end for */ + } /* end if */ + /* No data sieve buffer yet, go allocate one */ + else { + /* Set up the buffer parameters */ + size=size_arr[u]; + addr=_addr+offset_arr[u]; + max_data=_max_data-offset_arr[u]; + + /* Check if we can actually hold the I/O request in the sieve buffer */ + if(size>f->shared->sieve_buf_size) { if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed"); } } /* end if */ - /* Element size fits within the buffer size */ else { - /* Flush the sieve buffer if it's dirty */ - if(f->shared->sieve_dirty) { - /* Write to file */ - if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "block write failed"); - } - - /* Reset sieve buffer dirty flag */ - f->shared->sieve_dirty=0; - } /* end if */ + /* Allocate room for the data sieve buffer */ + if (NULL==(f->shared->sieve_buf=H5MM_malloc(f->shared->sieve_buf_size))) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed"); + } /* Determine the new sieve buffer size & location */ f->shared->sieve_loc=addr; @@ -129,7 +494,7 @@ H5F_contig_read(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, hsize rel_eoa=abs_eoa-f->shared->base_addr; /* Compute the size of the sieve buffer */ - f->shared->sieve_size=MIN(rel_eoa-addr,MIN(max_data,f->shared->sieve_buf_size)); + f->shared->sieve_size=MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)); /* Read the new sieve buffer */ if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) { @@ -141,288 +506,521 @@ H5F_contig_read(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, hsize f->shared->sieve_dirty=0; /* Grab the data out of the buffer (must be first piece of data in buffer ) */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(buf,f->shared->sieve_buf,(size_t)size); + HDmemcpy(buf,f->shared->sieve_buf,size); } /* end else */ + + /* Increment offset in buffer */ + buf += size_arr[u]; + + /* Increment sequence number */ + u++; } /* end else */ - } /* end if */ - /* No data sieve buffer yet, go allocate one */ - else { - /* Check if we can actually hold the I/O request in the sieve buffer */ - if(size>f->shared->sieve_buf_size) { - if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "block read failed"); - } - } /* end if */ - else { - /* Allocate room for the data sieve buffer */ - assert(f->shared->sieve_buf_size==(hsize_t)((size_t)f->shared->sieve_buf_size)); /*check for overflow*/ - if (NULL==(f->shared->sieve_buf=H5MM_malloc((size_t)f->shared->sieve_buf_size))) { - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); - } - - /* Determine the new sieve buffer size & location */ - f->shared->sieve_loc=addr; - - /* Make certain we don't read off the end of the file */ - if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf))) { - HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "unable to determine file size"); - } - - /* Adjust absolute EOA address to relative EOA address */ - rel_eoa=abs_eoa-f->shared->base_addr; - - /* Compute the size of the sieve buffer */ - f->shared->sieve_size=MIN(rel_eoa-addr,MIN(max_data,f->shared->sieve_buf_size)); - - /* Read the new sieve buffer */ - if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "block read failed"); - } - - /* Reset sieve buffer dirty flag */ - f->shared->sieve_dirty=0; - - /* Grab the data out of the buffer (must be first piece of data in buffer ) */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(buf,f->shared->sieve_buf,(size_t)size); - } /* end else */ - } /* end else */ + } /* end for */ } /* end if */ else { - if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "block read failed"); - } + /* Work through all the sequences */ + for(u=0; u<nseq; u++) { + size=size_arr[u]; + addr=_addr+offset_arr[u]; + + if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "block read failed"); + } + + /* Increment offset in buffer */ + buf += size_arr[u]; + } /* end for */ } /* end else */ FUNC_LEAVE(SUCCEED); -} /* End H5F_contig_read() */ +} /* end H5F_contig_readv() */ /*------------------------------------------------------------------------- - * Function: H5F_contig_write + * Function: H5F_contig_writev * - * Purpose: Writes some data from a dataset into a buffer. - * The data is contiguous. The address is relative to the base - * address for the file. + * Purpose: Writes some data vectors into a dataset from a buffer. + * The data is contiguous. The address is the start of the dataset, + * relative to the base address for the file and the offsets and + * sequence lengths are in bytes. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * Thursday, September 28, 2000 + * Thursday, July 5, 2001 + * + * Notes: + * Offsets in the sequences must be monotonically increasing * * Modifications: * *------------------------------------------------------------------------- */ herr_t -H5F_contig_write(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, hsize_t size, - hid_t dxpl_id, const void *buf) +H5F_contig_writev(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr, + size_t nseq, size_t size_arr[], hsize_t offset_arr[], hid_t dxpl_id, + const void *_buf) { - haddr_t abs_eoa; /* Absolute end of file address */ - haddr_t rel_eoa; /* Relative end of file address */ - - FUNC_ENTER(H5F_contig_write, FAIL); + const unsigned char *buf=_buf; /* Pointer to buffer to fill */ + haddr_t abs_eoa; /* Absolute end of file address */ + haddr_t rel_eoa; /* Relative end of file address */ + haddr_t addr; /* Actual address to read */ + hsize_t max_data; /* Actual maximum size of data to cache */ + size_t size; /* Size of sequence in bytes */ + size_t u; /* Counting variable */ +#ifndef SLOW_WAY + size_t max_seq; /* Maximum sequence to copy */ + haddr_t temp_end; /* Temporary end of buffer variable */ + size_t max_search; /* Maximum number of sequences to search */ + size_t mask; /* Bit mask */ + intn bit_loc; /* Bit location of the leftmost '1' in max_search */ + size_t *size_arr_p; /* Pointer into the size array */ + hsize_t *offset_arr_p; /* Pointer into the offset array */ +#endif /* SLOW_WAY */ + + FUNC_ENTER(H5F_contig_writev, FAIL); - assert (f); - assert (size<SIZET_MAX); - assert (buf); + /* Check args */ + assert(f); + assert(buf); /* Check if data sieving is enabled */ if(f->shared->lf->feature_flags&H5FD_FEAT_DATA_SIEVE) { - /* Try writing to the data sieve buffer */ - if(f->shared->sieve_buf) { - haddr_t sieve_start, sieve_end; /* Start & end locations of sieve buffer */ - haddr_t contig_end; /* End locations of block to write */ - hsize_t sieve_size; /* size of sieve buffer */ - - /* Stash local copies of these value */ - sieve_start=f->shared->sieve_loc; - sieve_size=f->shared->sieve_size; - sieve_end=sieve_start+sieve_size; - contig_end=addr+size-1; - - /* If entire write is within the sieve buffer, write it to the buffer */ - if(addr>=sieve_start && contig_end<sieve_end) { - /* Grab the data out of the buffer */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(f->shared->sieve_buf+(addr-sieve_start),buf,(size_t)size); - - /* Set sieve buffer dirty flag */ - f->shared->sieve_dirty=1; - } /* end if */ - /* Entire request is not within this data sieve buffer */ - else { - /* Check if we can actually hold the I/O request in the sieve buffer */ - if(size>f->shared->sieve_buf_size) { - /* Check for any overlap with the current sieve buffer */ - if((sieve_start>=addr && sieve_start<(contig_end+1)) - || ((sieve_end-1)>=addr && (sieve_end-1)<(contig_end+1))) { - /* Flush the sieve buffer, if it's dirty */ - if(f->shared->sieve_dirty) { - /* Write to file */ - if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "block write failed"); - } + /* Outer loop, guarantees working through all the sequences */ + for(u=0; u<nseq; ) { - /* Reset sieve buffer dirty flag */ - f->shared->sieve_dirty=0; - } /* end if */ + /* Try writing into the data sieve buffer */ + if(f->shared->sieve_buf) { + haddr_t sieve_start, sieve_end; /* Start & end locations of sieve buffer */ + haddr_t contig_end; /* End locations of block to write */ + size_t sieve_size; /* size of sieve buffer */ - /* Force the sieve buffer to be re-read the next time */ - f->shared->sieve_loc=HADDR_UNDEF; - f->shared->sieve_size=0; - } /* end if */ + /* Stash local copies of these value */ + sieve_start=f->shared->sieve_loc; + sieve_size=f->shared->sieve_size; + sieve_end=sieve_start+sieve_size; + + /* Next-outer loop works through sequences as fast as possible */ + for(; u<nseq; ) { + size=size_arr[u]; + addr=_addr+offset_arr[u]; + + /* Compute end of sequence to retrieve */ + contig_end=addr+size-1; + + /* If entire write is within the sieve buffer, write it to the buffer */ + if(addr>=sieve_start && contig_end<sieve_end) { + unsigned char *base_sieve_buf=f->shared->sieve_buf+(_addr-sieve_start); + unsigned char *temp_sieve_buf; + haddr_t temp_addr=_addr-1; /* Temporary address */ + +#ifdef SLOW_WAY + /* Retrieve all the sequences out of the current sieve buffer */ + while(contig_end<sieve_end) { + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+offset_arr[u]; + + /* Grab the data out of the buffer */ + HDmemcpy(temp_sieve_buf,buf,size_arr[u]); + + /* Increment offset in buffer */ + buf += size_arr[u]; + + /* Increment sequence number, check for finished with sequences */ + if((++u) >= nseq) + break; + + /* Re-compute end of sequence to retrieve */ + contig_end=temp_addr+offset_arr[u]+size_arr[u]; + } /* end while */ +#else /* SLOW_WAY */ + /* Find log2(n) where n is the number of elements to search */ + + /* Set initial parameters */ + mask=(size_t)0xff<<((sizeof(size_t)-1)*8); /* Get a mask for the leftmost byte */ + max_search=((nseq-1)-u)+1; /* Compute 'n' for the log2 */ + assert(max_search>0); /* Sanity check */ + bit_loc=(sizeof(size_t)*8)-1; /* Initial bit location */ + + /* Search for the first byte with a bit set */ + while((max_search & mask)==0) { + mask>>=8; + bit_loc-=8; + } /* end while */ + + /* Switch to searching for a bit */ + mask=1<<bit_loc; + while((max_search & mask)==0) { + mask>>=1; + bit_loc--; + } /* end while */ + + /* location of the leftmost bit, plus 1, is log2(n) */ + max_seq=bit_loc+1; + + /* Don't walk off the array */ + max_seq=MIN(u+max_seq,nseq-1); + + /* Determine if a linear search is faster than a binary search */ + temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq]; + if(temp_end>=sieve_end) { + /* Linear search is faster */ + + /* Set the initial search values */ + max_seq=u; + temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq]; + + /* Search for the first sequence ending greater than the sieve buffer end */ + while(temp_end<sieve_end) { + if(++max_seq>=nseq) + break; + temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq]; + } /* end while */ + + /* Adjust back one element */ + max_seq--; - /* Write directly to the user's buffer */ - if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "block write failed"); - } /* end if */ - } /* end if */ - /* Element size fits within the buffer size */ - else { - /* Check if it is possible to (exactly) prepend or append to existing (dirty) sieve buffer */ - if(((addr+size)==sieve_start || addr==sieve_end) && - (size+sieve_size)<=f->shared->sieve_buf_size && - f->shared->sieve_dirty) { - /* Prepend to existing sieve buffer */ - if((addr+size)==sieve_start) { - /* Move existing sieve information to correct location */ - assert(sieve_size==(hsize_t)((size_t)sieve_size)); /*check for overflow*/ - HDmemmove(f->shared->sieve_buf+size,f->shared->sieve_buf,(size_t)sieve_size); - - /* Copy in new information (must be first in sieve buffer) */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(f->shared->sieve_buf,buf,(size_t)size); - - /* Adjust sieve location */ - f->shared->sieve_loc=addr; - } /* end if */ - /* Append to existing sieve buffer */ else { - /* Copy in new information */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(f->shared->sieve_buf+sieve_size,buf,(size_t)size); + size_t lo,hi; /* Low and high bounds for binary search */ + uintn found=0; /* Flag to indicate bounds have been found */ + + /* Binary search is faster */ + + /* Find the value 'u' which will be beyond the end of the sieve buffer */ + lo=u; + hi=nseq-1; + max_seq=(lo+hi)/2; + while(!found) { + /* Get the address of the end of sequence for the 'max_seq' position */ + temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq]; + + /* Current high bound is too large */ + if(temp_end>=sieve_end) { + if((lo+1)<hi) { + hi=max_seq; + max_seq=(lo+hi)/2; + } /* end if */ + else { + found=1; + } /* end else */ + } /* end if */ + /* Current low bound is too small */ + else { + if((lo+1)<hi) { + lo=max_seq; + max_seq=(lo+hi+1)/2; + } /* end if */ + else { + found=1; + } /* end else */ + } /* end else */ + } /* end while */ + + /* Check for non-exact match */ + if(lo!=hi) { + temp_end=temp_addr+offset_arr[hi]+size_arr[hi]; + if(temp_end<sieve_end) + max_seq=hi; + else + max_seq=lo; + } /* end if */ } /* end else */ - /* Adjust sieve size */ - f->shared->sieve_size += size; - + /* Set the pointers to the correct locations in the offset & size arrays */ + size_arr_p=&size_arr[u]; + offset_arr_p=&offset_arr[u]; + +#ifdef NO_DUFFS_DEVICE + /* Retrieve all the sequences out of the current sieve buffer */ + while(u<=max_seq) { + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(temp_sieve_buf,buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + } /* end while */ +#else /* NO_DUFFS_DEVICE */ +{ + size_t seq_count; + + seq_count=(max_seq-u)+1; + switch (seq_count % 4) { + case 0: + do + { + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(temp_sieve_buf,buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + + case 3: + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(temp_sieve_buf,buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + + case 2: + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(temp_sieve_buf,buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + + case 1: + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(temp_sieve_buf,buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + + } while (u<=max_seq); + } /* end switch */ + +} +#endif /* NO_DUFFS_DEVICE */ +#endif /* SLOW_WAY */ + /* Set sieve buffer dirty flag */ + f->shared->sieve_dirty=1; + } /* end if */ - /* Can't add the new data onto the existing sieve buffer */ + /* Entire request is not within this data sieve buffer */ else { - /* Flush the sieve buffer if it's dirty */ - if(f->shared->sieve_dirty) { - /* Write to file */ - if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "block write failed"); - } /* end if */ + /* Check if we can actually hold the I/O request in the sieve buffer */ + if(size>f->shared->sieve_buf_size) { + /* Check for any overlap with the current sieve buffer */ + if((sieve_start>=addr && sieve_start<(contig_end+1)) + || ((sieve_end-1)>=addr && (sieve_end-1)<(contig_end+1))) { + /* Flush the sieve buffer, if it's dirty */ + if(f->shared->sieve_dirty) { + /* Write to file */ + if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "block write failed"); + } - /* Reset sieve buffer dirty flag */ - f->shared->sieve_dirty=0; - } /* end if */ + /* Reset sieve buffer dirty flag */ + f->shared->sieve_dirty=0; + } /* end if */ - /* Determine the new sieve buffer size & location */ - f->shared->sieve_loc=addr; + /* Force the sieve buffer to be re-read the next time */ + f->shared->sieve_loc=HADDR_UNDEF; + f->shared->sieve_size=0; + } /* end if */ - /* Make certain we don't read off the end of the file */ - if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf))) { - HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "unable to determine file size"); + /* Write directly from the user's buffer */ + if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "block write failed"); + } } /* end if */ + /* Element size fits within the buffer size */ + else { + /* Check if it is possible to (exactly) prepend or append to existing (dirty) sieve buffer */ + if(((addr+size)==sieve_start || addr==sieve_end) && + (size+sieve_size)<=f->shared->sieve_buf_size && + f->shared->sieve_dirty) { + /* Prepend to existing sieve buffer */ + if((addr+size)==sieve_start) { + /* Move existing sieve information to correct location */ + HDmemmove(f->shared->sieve_buf+size,f->shared->sieve_buf,sieve_size); - /* Adjust absolute EOA address to relative EOA address */ - rel_eoa=abs_eoa-f->shared->base_addr; + /* Copy in new information (must be first in sieve buffer) */ + HDmemcpy(f->shared->sieve_buf,buf,size); - /* Compute the size of the sieve buffer */ - f->shared->sieve_size=MIN(rel_eoa-addr,MIN(max_data,f->shared->sieve_buf_size)); + /* Adjust sieve location */ + f->shared->sieve_loc=addr; + + } /* end if */ + /* Append to existing sieve buffer */ + else { + /* Copy in new information */ + HDmemcpy(f->shared->sieve_buf+sieve_size,buf,size); + } /* end else */ + + /* Adjust sieve size */ + f->shared->sieve_size += size; + + /* Update local copies of sieve information */ + sieve_start=f->shared->sieve_loc; + sieve_size=f->shared->sieve_size; + sieve_end=sieve_start+sieve_size; - /* Check if there is any point in reading the data from the file */ - if(f->shared->sieve_size>size) { - /* Read the new sieve buffer */ - if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "block read failed"); } /* end if */ - } /* end if */ + /* Can't add the new data onto the existing sieve buffer */ + else { + /* Flush the sieve buffer if it's dirty */ + if(f->shared->sieve_dirty) { + /* Write to file */ + if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "block write failed"); + } - /* Grab the data out of the buffer (must be first piece of data in buffer) */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(f->shared->sieve_buf,buf,(size_t)size); + /* Reset sieve buffer dirty flag */ + f->shared->sieve_dirty=0; + } /* end if */ - /* Set sieve buffer dirty flag */ - f->shared->sieve_dirty=1; + /* Determine the new sieve buffer size & location */ + f->shared->sieve_loc=addr; + /* Make certain we don't read off the end of the file */ + if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf))) { + HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, + "unable to determine file size"); + } + + /* Adjust absolute EOA address to relative EOA address */ + rel_eoa=abs_eoa-f->shared->base_addr; + + /* Only need this when resizing sieve buffer */ + max_data=_max_data-offset_arr[u]; + + /* Compute the size of the sieve buffer */ + /* Don't read off the end of the file, don't read past the end of the data element and don't read more than the buffer size */ + f->shared->sieve_size=MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)); + + /* Update local copies of sieve information */ + sieve_start=f->shared->sieve_loc; + sieve_size=f->shared->sieve_size; + sieve_end=sieve_start+sieve_size; + + /* Check if there is any point in reading the data from the file */ + if(f->shared->sieve_size>size) { + /* Read the new sieve buffer */ + if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "block read failed"); + } /* end if */ + } /* end if */ + + /* Grab the data out of the buffer (must be first piece of data in buffer ) */ + HDmemcpy(f->shared->sieve_buf,buf,size); + + /* Set sieve buffer dirty flag */ + f->shared->sieve_dirty=1; + + } /* end else */ + } /* end else */ + + /* Increment offset in buffer */ + buf += size_arr[u]; + + /* Increment sequence number */ + u++; } /* end else */ - } /* end else */ - } /* end else */ - } /* end if */ - /* No data sieve buffer yet, go allocate one */ - else { - /* Check if we can actually hold the I/O request in the sieve buffer */ - if(size>f->shared->sieve_buf_size) { - if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "block write failed"); - } + } /* end for */ } /* end if */ + /* No data sieve buffer yet, go allocate one */ else { - /* Allocate room for the data sieve buffer */ - assert(f->shared->sieve_buf_size==(hsize_t)((size_t)f->shared->sieve_buf_size)); /*check for overflow*/ - if (NULL==(f->shared->sieve_buf=H5MM_malloc((size_t)f->shared->sieve_buf_size))) { - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); + /* Set up the buffer parameters */ + size=size_arr[u]; + addr=_addr+offset_arr[u]; + max_data=_max_data-offset_arr[u]; + + /* Check if we can actually hold the I/O request in the sieve buffer */ + if(size>f->shared->sieve_buf_size) { + if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "block write failed"); + } } /* end if */ + else { + /* Allocate room for the data sieve buffer */ + if (NULL==(f->shared->sieve_buf=H5MM_malloc(f->shared->sieve_buf_size))) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed"); + } - /* Determine the new sieve buffer size & location */ - f->shared->sieve_loc=addr; + /* Determine the new sieve buffer size & location */ + f->shared->sieve_loc=addr; - /* Make certain we don't read off the end of the file */ - if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf))) { - HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "unable to determine file size"); - } /* end if */ + /* Make certain we don't read off the end of the file */ + if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf))) { + HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, + "unable to determine file size"); + } - /* Adjust absolute EOA address to relative EOA address */ - rel_eoa=abs_eoa-f->shared->base_addr; + /* Adjust absolute EOA address to relative EOA address */ + rel_eoa=abs_eoa-f->shared->base_addr; - /* Compute the size of the sieve buffer */ - f->shared->sieve_size=MIN(rel_eoa-addr,MIN(max_data,f->shared->sieve_buf_size)); + /* Compute the size of the sieve buffer */ + f->shared->sieve_size=MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)); - /* Check if there is any point in reading the data from the file */ - if(f->shared->sieve_size>size) { - /* Read the new sieve buffer */ - if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "block read failed"); + /* Check if there is any point in reading the data from the file */ + if(f->shared->sieve_size>size) { + /* Read the new sieve buffer */ + if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "block read failed"); + } /* end if */ } /* end if */ - } /* end if */ - /* Grab the data out of the buffer (must be first piece of data in buffer) */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(f->shared->sieve_buf,buf,(size_t)size); + /* Grab the data out of the buffer (must be first piece of data in buffer ) */ + HDmemcpy(f->shared->sieve_buf,buf,size); + + /* Set sieve buffer dirty flag */ + f->shared->sieve_dirty=1; + } /* end else */ - /* Set sieve buffer dirty flag */ - f->shared->sieve_dirty=1; + /* Increment offset in buffer */ + buf += size_arr[u]; + + /* Increment sequence number */ + u++; } /* end else */ - } /* end else */ + } /* end for */ } /* end if */ else { - if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "block write failed"); - } /* end if */ + /* Work through all the sequences */ + for(u=0; u<nseq; u++) { + size=size_arr[u]; + addr=_addr+offset_arr[u]; + + if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "block write failed"); + } + + /* Increment offset in buffer */ + buf += size_arr[u]; + } /* end for */ } /* end else */ FUNC_LEAVE(SUCCEED); -} /* End H5F_contig_write() */ +} /* end H5F_contig_writev() */ + diff --git a/src/H5Distore.c b/src/H5Distore.c index 95e4f46..d37c474 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -96,7 +96,7 @@ typedef struct H5F_rdcc_ent_t { size_t chunk_size; /*size of a chunk */ size_t alloc_size; /*amount allocated for the chunk */ uint8_t *chunk; /*the unfiltered chunk data */ - intn idx; /*index in hash table */ + uintn idx; /*index in hash table */ struct H5F_rdcc_ent_t *next;/*next item in doubly-linked list */ struct H5F_rdcc_ent_t *prev;/*previous item in doubly-linked list */ } H5F_rdcc_ent_t; @@ -906,7 +906,6 @@ H5F_istore_init (H5F_t *f) HDmemset (rdcc, 0, sizeof(H5F_rdcc_t)); if (f->shared->rdcc_nbytes>0 && f->shared->rdcc_nelmts>0) { rdcc->nslots = f->shared->rdcc_nelmts; - assert(rdcc->nslots>=0); rdcc->slot = H5FL_ARR_ALLOC (H5F_rdcc_ent_ptr_t,rdcc->nslots,1); if (NULL==rdcc->slot) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, @@ -1002,7 +1001,7 @@ H5F_istore_flush_entry(H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to allocate chunk"); } - if (H5F_block_write(f, H5FD_MEM_DRAW, udata.addr, (hsize_t)udata.key.nbytes, H5P_DEFAULT, + if (H5F_block_write(f, H5FD_MEM_DRAW, udata.addr, udata.key.nbytes, H5P_DEFAULT, buf)<0) { HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file"); @@ -1070,7 +1069,7 @@ H5F_istore_preempt (H5F_t *f, H5F_rdcc_ent_t *ent) assert(f); assert(ent); assert(!ent->locked); - assert(ent->idx>=0 && ent->idx<rdcc->nslots); + assert(ent->idx<rdcc->nslots); /* Flush */ if (H5F_istore_flush_entry(f, ent, TRUE)<0) { @@ -1093,7 +1092,7 @@ H5F_istore_preempt (H5F_t *f, H5F_rdcc_ent_t *ent) /* Remove from cache */ rdcc->slot[ent->idx] = NULL; - ent->idx = -1; + ent->idx = UINT_MAX; rdcc->nbytes -= ent->chunk_size; --rdcc->nused; @@ -1335,7 +1334,7 @@ static void * H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, const H5O_pline_t *pline, const H5O_fill_t *fill, const hssize_t offset[], hbool_t relax, - intn *idx_hint/*in,out*/) + uintn *idx_hint/*in,out*/) { intn idx=0; /*hash index number */ uintn temp_idx=0; /* temporary index number */ @@ -1422,7 +1421,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, /* * The chunk exists on disk. */ - if (H5F_block_read(f, H5FD_MEM_DRAW, udata.addr, (hsize_t)udata.key.nbytes, H5P_DEFAULT, + if (H5F_block_read(f, H5FD_MEM_DRAW, udata.addr, udata.key.nbytes, H5P_DEFAULT, chunk)<0) { HGOTO_ERROR (H5E_IO, H5E_READERROR, NULL, "unable to read raw data chunk"); @@ -1535,7 +1534,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, * unlock function. */ ent = NULL; - idx = INT_MIN; + idx = UINT_MAX; } else if (found) { /* @@ -1608,7 +1607,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, static herr_t H5F_istore_unlock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, const H5O_pline_t *pline, hbool_t dirty, - const hssize_t offset[], intn *idx_hint, + const hssize_t offset[], uintn *idx_hint, uint8_t *chunk, size_t naccessed) { H5F_rdcc_t *rdcc = &(f->shared->rdcc); @@ -1618,10 +1617,10 @@ H5F_istore_unlock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, FUNC_ENTER (H5F_istore_unlock, FAIL); - if (INT_MIN==*idx_hint) { + if (UINT_MAX==*idx_hint) { /*not in cache*/ } else { - assert(*idx_hint>=0 && *idx_hint<rdcc->nslots); + assert(*idx_hint<rdcc->nslots); assert(rdcc->slot[*idx_hint]); assert(rdcc->slot[*idx_hint]->chunk==chunk); found = *idx_hint; @@ -1714,7 +1713,7 @@ H5F_istore_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, uintn u; size_t naccessed; /*bytes accessed in chnk*/ uint8_t *chunk=NULL; /*ptr to a chunk buffer */ - intn idx_hint=0; /*cache index hint */ + uintn idx_hint=0; /*cache index hint */ FUNC_ENTER(H5F_istore_read, FAIL); @@ -1886,7 +1885,7 @@ H5F_istore_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, hssize_t offset_wrt_chunk[H5O_LAYOUT_NDIMS]; hssize_t sub_offset_m[H5O_LAYOUT_NDIMS]; uint8_t *chunk=NULL; - intn idx_hint=0; + uintn idx_hint=0; size_t chunk_size, naccessed; FUNC_ENTER(H5F_istore_write, FAIL); @@ -2333,7 +2332,7 @@ H5F_istore_allocate(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, uintn u; hssize_t chunk_offset[H5O_LAYOUT_NDIMS]; uint8_t *chunk=NULL; - intn idx_hint=0; + uintn idx_hint=0; size_t chunk_size; #ifdef AKC H5F_istore_ud1_t udata; diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index ebf0f80..3254dde 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -53,22 +53,22 @@ typedef struct H5D_create_t { /* Data transfer property list */ typedef struct H5D_xfer_t { - hsize_t buf_size; /*max temp buffer size */ - void *tconv_buf; /*type conversion buffer or null */ - void *bkg_buf; /*background buffer or null */ + size_t buf_size; /*max temp buffer size */ + void *tconv_buf; /*type conversion buffer or null */ + void *bkg_buf; /*background buffer or null */ H5T_bkg_t need_bkg; /*type of background buffer needed */ - double split_ratios[3];/*B-tree node splitting ratios */ + double split_ratios[3];/*B-tree node splitting ratios */ uintn cache_hyper; /*cache hyperslab blocks during I/O? */ uintn block_limit; /*largest hyperslab block to cache */ + size_t vector_size; /*Max. # of I/O vectors for hyperslabs */ H5MM_allocate_t vlen_alloc; /*VL datatype allocation function */ void *alloc_info; /*VL datatype allocation information */ H5MM_free_t vlen_free; /*VL datatype free function */ void *free_info; /*VL datatype free information */ - hid_t driver_id; /*File driver ID */ - void *driver_info; /*File driver specific information */ + hid_t driver_id; /*File driver ID */ + void *driver_info; /*File driver specific information */ #ifdef COALESCE_READS - uintn gather_reads; /*coalesce single reads into a read */ - /*transaction */ + uintn gather_reads; /*coalesce single reads into a read transaction */ #endif } H5D_xfer_t; diff --git a/src/H5Dseq.c b/src/H5Dseq.c index 3868202..1c05dcf 100644 --- a/src/H5Dseq.c +++ b/src/H5Dseq.c @@ -52,6 +52,7 @@ static intn interface_initialize_g = 0; * Thursday, September 28, 2000 * * Modifications: + * Re-written to use new vector I/O call - QAK, 7/7/01 * *------------------------------------------------------------------------- */ @@ -59,28 +60,118 @@ herr_t H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const H5O_fill_t *fill, const struct H5O_efl_t *efl, const H5S_t *file_space, size_t elmt_size, - hsize_t seq_len, hsize_t file_offset, void *buf/*out*/) + size_t seq_len, hsize_t file_offset, void *buf/*out*/) { + FUNC_ENTER(H5F_seq_read, FAIL); + + /* Check args */ + assert(f); + assert(layout); + assert(buf); + + if (H5F_seq_readv(f, dxpl_id, layout, pline, fill, efl, file_space, elmt_size, 1, &seq_len, &file_offset, buf)<0) + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "vector read failed"); + + FUNC_LEAVE(SUCCEED); +} /* H5F_seq_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_seq_write + * + * Purpose: Writes a sequence of bytes to a file dataset from a buffer in + * in memory. The data is written to file F and the array's size and + * storage information is in LAYOUT. External files are described + * according to the external file list, EFL. The sequence offset is + * FILE_OFFSET in the file (offsets are + * in terms of bytes) and the size of the hyperslab is SEQ_LEN. The + * total size of the file array is implied in the LAYOUT argument. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, October 9, 2000 + * + * Modifications: + * Re-written to use new vector I/O routine - QAK, 7/7/01 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, + const struct H5O_pline_t *pline, const H5O_fill_t *fill, + const struct H5O_efl_t *efl, const H5S_t *file_space, size_t elmt_size, + size_t seq_len, hsize_t file_offset, const void *buf) +{ + FUNC_ENTER(H5F_seq_write, FAIL); + + /* Check args */ + assert(f); + assert(layout); + assert(buf); + + if (H5F_seq_writev(f, dxpl_id, layout, pline, fill, efl, file_space, elmt_size, 1, &seq_len, &file_offset, buf)<0) + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vector write failed"); + + FUNC_LEAVE(SUCCEED); +} /* H5F_seq_write() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_seq_readv + * + * Purpose: Reads in a vector of byte sequences from a file dataset into a + * buffer in in memory. The data is read from file F and the array's size + * and storage information is in LAYOUT. External files are described + * according to the external file list, EFL. The vector of byte sequences + * offsets is in the FILE_OFFSET array into the dataset (offsets are in + * terms of bytes) and the size of each sequence is in the SEQ_LEN array. + * The total size of the file array is implied in the LAYOUT argument. + * Bytes read into BUF are sequentially stored in the buffer, each sequence + * from the vector stored directly after the previous. The number of + * sequences is NSEQ. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Wednesday, May 1, 2001 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, + const struct H5O_pline_t *pline, const H5O_fill_t *fill, + const struct H5O_efl_t *efl, const H5S_t *file_space, size_t elmt_size, + size_t nseq, size_t seq_len_arr[], hsize_t file_offset_arr[], + void *_buf/*out*/) +{ + unsigned char *real_buf=(unsigned char *)_buf; /* Local pointer to buffer to fill */ + unsigned char *buf; /* Local pointer to buffer to fill */ + hsize_t file_offset; /* Offset in dataset */ + hsize_t seq_len; /* Number of bytes to read */ hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */ hssize_t coords[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in dataspace */ hsize_t hslab_size[H5O_LAYOUT_NDIMS]; /* hyperslab size in dataspace*/ hsize_t down_size[H5O_LAYOUT_NDIMS]; /* Cumulative yperslab sizes (in elements) */ hsize_t acc; /* Accumulator for hyperslab sizes (in elements) */ intn ndims; - hsize_t max_data = 0; /*bytes in dataset */ + hsize_t max_data; /*bytes in dataset */ haddr_t addr=0; /*address in file */ uintn u; /*counters */ + size_t v; /*counters */ intn i,j; /*counters */ #ifdef H5_HAVE_PARALLEL H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; #endif - FUNC_ENTER(H5F_seq_read, FAIL); + FUNC_ENTER(H5F_seq_readv, FAIL); /* Check args */ assert(f); assert(layout); - assert(buf); + assert(real_buf); #ifdef H5_HAVE_PARALLEL { @@ -110,30 +201,11 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, "filters are not allowed for contiguous data"); } - /* - * Initialize loop variables. The loop is a multi-dimensional loop - * that counts from SIZE down to zero and IDX is the counter. Each - * element of IDX is treated as a digit with IDX[0] being the least - * significant digit. - */ - if (efl && efl->nused>0) { - addr = 0; - } else { - addr = layout->addr; - /* Compute the size of the dataset in bytes */ - for(u=0, max_data=1; u<layout->ndims; u++) - max_data *= layout->dim[u]; - - /* Adjust the maximum size of the data by the offset into it */ - max_data -= file_offset; - } - addr += file_offset; - - /* - * Now begin to walk through the array, copying data from disk to - * memory. - */ + /* Read directly from file if the dataset is in an external file */ + if (efl && efl->nused>0) { + /* Iterate through the sequence vectors */ + for(v=0; v<nseq; v++) { #ifdef H5_HAVE_PARALLEL if (H5FD_MPIO_COLLECTIVE==xfer_mode) { /* @@ -143,8 +215,8 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, */ unsigned long max, min, temp; - temp = seq_len; - assert(temp==seq_len); /* verify no overflow */ + temp = seq_len_arr[v]; + assert(temp==seq_len_arr[v]); /* verify no overflow */ MPI_Allreduce(&temp, &max, 1, MPI_UNSIGNED_LONG, MPI_MAX, H5FD_mpio_communicator(f->shared->lf)); MPI_Allreduce(&temp, &min, 1, MPI_UNSIGNED_LONG, MPI_MIN, @@ -157,20 +229,26 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, "collective access with unequal number of blocks not supported yet"); } #endif + /* Note: We can't use data sieve buffers for datasets in external files + * because the 'addr' of all external files is set to 0 (above) and + * all datasets in external files would alias to the same set of + * file offsets, totally mixing up the data sieve buffer information. -QAK + */ + if (H5O_efl_read(f, efl, file_offset_arr[v], seq_len_arr[v], real_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "external data read failed"); + } - /* Read directly from file if the dataset is in an external file */ - if (efl && efl->nused>0) { - /* Note: We can't use data sieve buffers for datasets in external files - * because the 'addr' of all external files is set to 0 (above) and - * all datasets in external files would alias to the same set of - * file offsets, totally mixing up the data sieve buffer information. -QAK - */ - if (H5O_efl_read(f, efl, addr, seq_len, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "external data read failed"); - } + /* Increment offset in buffer */ + real_buf += seq_len_arr[v]; + } /* end for */ } else { - if (H5F_contig_read(f, max_data, H5FD_MEM_DRAW, addr, seq_len, dxpl_id, buf)<0) { + /* Compute the size of the dataset in bytes */ + for(u=1, max_data=layout->dim[0]; u<layout->ndims; u++) + max_data *= layout->dim[u]; + + /* Pass along the vector of sequences to read */ + if (H5F_contig_readv(f, max_data, H5FD_MEM_DRAW, layout->addr, nseq, seq_len_arr, file_offset_arr, dxpl_id, real_buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed"); } @@ -178,289 +256,218 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, break; case H5D_CHUNKED: - { - /* - * This method is unable to access external raw data files - */ - if (efl && efl->nused>0) { - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, - "chunking and external files are mutually exclusive"); - } - /* Compute the file offset coordinates and hyperslab size */ - if((ndims=H5S_get_simple_extent_dims(file_space,dset_dims,NULL))<0) - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions"); - -#ifdef QAK - /* The library shouldn't be reading partial elements currently */ - assert(seq_len%elmt_size!=0); - assert(addr%elmt_size!=0); -#endif /* QAK */ - -#ifdef QAK -/* Print out the file offsets & hyperslab sizes */ -{ - static int count=0; - - if(count<1000000) { - printf("%s: elmt_size=%d, addr=%d, seq_len=%d\n",FUNC,(int)elmt_size,(int)addr,(int)seq_len); - printf("%s: file_offset=%d\n",FUNC,(int)file_offset); - count++; - } -} -#endif /* QAK */ - /* Set location in dataset from the file_offset */ - addr=file_offset; - - /* Convert the bytes into elements */ - seq_len/=elmt_size; - addr/=elmt_size; - - /* Build the array of cumulative hyperslab sizes */ - for(acc=1, i=(ndims-1); i>=0; i--) { - down_size[i]=acc; - acc*=dset_dims[i]; -#ifdef QAK -printf("%s: acc=%ld, down_size[%d]=%ld\n",FUNC,(long)acc,i,(long)down_size[i]); -#endif /* QAK */ - } /* end for */ + /* Brute-force, stupid way to implement the vectors, but too complex to do other ways... */ + for(v=0; v<nseq; v++) { + file_offset=file_offset_arr[v]; + seq_len=seq_len_arr[v]; + buf=real_buf; + + { + /* + * This method is unable to access external raw data files + */ + if (efl && efl->nused>0) { + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, + "chunking and external files are mutually exclusive"); + } + /* Compute the file offset coordinates and hyperslab size */ + if((ndims=H5S_get_simple_extent_dims(file_space,dset_dims,NULL))<0) + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions"); + + + /* Set location in dataset from the file_offset */ + addr=file_offset; + + /* Convert the bytes into elements */ + seq_len/=elmt_size; + addr/=elmt_size; + + /* Build the array of cumulative hyperslab sizes */ + for(acc=1, i=(ndims-1); i>=0; i--) { + down_size[i]=acc; + acc*=dset_dims[i]; + } /* end for */ - /* Compute the hyperslab offset from the address given */ - for(i=ndims-1; i>=0; i--) { - coords[i]=addr%dset_dims[i]; - addr/=dset_dims[i]; -#ifdef QAK -printf("%s: addr=%lu, coords[%d]=%ld\n",FUNC,(unsigned long)addr,i,(long)coords[i]); -#endif /* QAK */ - } /* end for */ - coords[ndims]=0; /* No offset for element info */ -#ifdef QAK -printf("%s: addr=%lu, coords[%d]=%ld\n",FUNC,(unsigned long)addr,ndims,(long)coords[ndims]); -#endif /* QAK */ - - /* - * Peel off initial partial hyperslabs until we've got a hyperslab which starts - * at coord[n]==0 for dimensions 1->(ndims-1) (i.e. starting at coordinate - * zero for all dimensions except the slowest changing one - */ - for(i=ndims-1; i>0 && seq_len>=down_size[i]; i--) { - hsize_t partial_size; /* Size of the partial hyperslab in bytes */ - - /* Check if we have a partial hyperslab in this lower dimension */ - if(coords[i]>0) { -#ifdef QAK -printf("%s: Need to get hyperslab, seq_len=%ld, coords[%d]=%ld\n",FUNC,(long)seq_len,i,(long)coords[i]); -#endif /* QAK */ - /* Reset the partial hyperslab size */ - partial_size=1; - - /* Build the partial hyperslab information */ - for(j=0; j<ndims; j++) { - if(i==j) - hslab_size[j]=MIN(seq_len/down_size[i],dset_dims[i]-coords[i]); - else - if(j>i) - hslab_size[j]=dset_dims[j]; - else - hslab_size[j]=1; - partial_size*=hslab_size[j]; -#ifdef QAK -printf("%s: partial_size=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)hslab_size[j]); -#endif /* QAK */ + /* Compute the hyperslab offset from the address given */ + for(i=ndims-1; i>=0; i--) { + coords[i]=addr%dset_dims[i]; + addr/=dset_dims[i]; + } /* end for */ + coords[ndims]=0; /* No offset for element info */ + + /* + * Peel off initial partial hyperslabs until we've got a hyperslab which starts + * at coord[n]==0 for dimensions 1->(ndims-1) (i.e. starting at coordinate + * zero for all dimensions except the slowest changing one + */ + for(i=ndims-1; i>0 && seq_len>=down_size[i]; i--) { + hsize_t partial_size; /* Size of the partial hyperslab in bytes */ + + /* Check if we have a partial hyperslab in this lower dimension */ + if(coords[i]>0) { + /* Reset the partial hyperslab size */ + partial_size=1; + + /* Build the partial hyperslab information */ + for(j=0; j<ndims; j++) { + if(i==j) + hslab_size[j]=MIN(seq_len/down_size[i],dset_dims[i]-coords[i]); + else + if(j>i) + hslab_size[j]=dset_dims[j]; + else + hslab_size[j]=1; + partial_size*=hslab_size[j]; + } /* end for */ + hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ + + /* Read in the partial hyperslab */ + if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, + hslab_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); + } + + /* Increment the buffer offset */ + buf=(unsigned char *)buf+partial_size; + + /* Decrement the length of the sequence to read */ + seq_len-=partial_size; + + /* Correct the coords array */ + coords[i]=0; + coords[i-1]++; + } /* end if */ } /* end for */ - hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ -#ifdef QAK -printf("%s: partial_size=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)hslab_size[ndims]); -#endif /* QAK */ - - /* Read in the partial hyperslab */ - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); - } - /* Increment the buffer offset */ - buf=(unsigned char *)buf+partial_size; + /* Check if there is more than just a partial hyperslab to read */ + if(seq_len>=down_size[0]) { + hsize_t tmp_seq_len; /* Temp. size of the sequence in elements */ + hsize_t full_size; /* Size of the full hyperslab in bytes */ - /* Decrement the length of the sequence to read */ - seq_len-=partial_size; + /* Get the sequence length for computing the hyperslab sizes */ + tmp_seq_len=seq_len; - /* Correct the coords array */ - coords[i]=0; - coords[i-1]++; - } /* end if */ - } /* end for */ -#ifdef QAK -printf("%s: after reading initial partial hyperslabs, seq_len=%lu\n",FUNC,(unsigned long)seq_len); -#endif /* QAK */ - - /* Check if there is more than just a partial hyperslab to read */ - if(seq_len>=down_size[0]) { - hsize_t tmp_seq_len; /* Temp. size of the sequence in elements */ - hsize_t full_size; /* Size of the full hyperslab in bytes */ - - /* Get the sequence length for computing the hyperslab sizes */ - tmp_seq_len=seq_len; - - /* Reset the size of the hyperslab read in */ - full_size=1; - - /* Compute the hyperslab size from the length given */ - for(i=ndims-1; i>=0; i--) { - /* Check if the hyperslab is wider than the width of the dimension */ - if(tmp_seq_len>dset_dims[i]) { - assert(0==coords[i]); - hslab_size[i]=dset_dims[i]; - } /* end if */ - else - hslab_size[i]=tmp_seq_len; + /* Reset the size of the hyperslab read in */ + full_size=1; - /* compute the number of elements read in */ - full_size*=hslab_size[i]; + /* Compute the hyperslab size from the length given */ + for(i=ndims-1; i>=0; i--) { + /* Check if the hyperslab is wider than the width of the dimension */ + if(tmp_seq_len>dset_dims[i]) { + assert(0==coords[i]); + hslab_size[i]=dset_dims[i]; + } /* end if */ + else + hslab_size[i]=tmp_seq_len; - /* Fold the length into the length in the next highest dimension */ - tmp_seq_len/=dset_dims[i]; -#ifdef QAK -printf("%s: tmp_seq_len=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)tmp_seq_len,i,(long)hslab_size[i]); -#endif /* QAK */ + /* compute the number of elements read in */ + full_size*=hslab_size[i]; - /* Make certain the hyperslab sizes don't go less than 1 for dimensions less than 0*/ - assert(tmp_seq_len>=1 || i==0); - } /* end for */ - hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ + /* Fold the length into the length in the next highest dimension */ + tmp_seq_len/=dset_dims[i]; -#ifdef QAK -/* Print out the file offsets & hyperslab sizes */ -{ - static int count=0; - - if(count<1000000) { - printf("%s: elmt_size=%d, addr=%d, full_size=%ld, tmp_seq_len=%ld seq_len=%ld\n",FUNC,(int)elmt_size,(int)addr,(long)full_size,(long)tmp_seq_len,(long)seq_len); - for(i=0; i<ndims; i++) - printf("%s: dset_dims[%d]=%d\n",FUNC,i,(int)dset_dims[i]); - for(i=0; i<=ndims; i++) - printf("%s: coords[%d]=%d, hslab_size[%d]=%d\n",FUNC,i,(int)coords[i],(int)i,(int)hslab_size[i]); - count++; - } -} -#endif /* QAK */ + /* Make certain the hyperslab sizes don't go less than 1 for dimensions less than 0*/ + assert(tmp_seq_len>=1 || i==0); + } /* end for */ + hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ - /* Read the full hyperslab in */ - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); - } + /* Read the full hyperslab in */ + if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, + hslab_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); + } - /* Increment the buffer offset */ - buf=(unsigned char *)buf+full_size; + /* Increment the buffer offset */ + buf=(unsigned char *)buf+full_size; - /* Decrement the sequence length left */ - seq_len-=full_size; + /* Decrement the sequence length left */ + seq_len-=full_size; - /* Increment coordinate of slowest changing dimension */ - coords[0]+=hslab_size[0]; + /* Increment coordinate of slowest changing dimension */ + coords[0]+=hslab_size[0]; - } /* end if */ -#ifdef QAK -printf("%s: after reading 'middle' full hyperslabs, seq_len=%lu\n",FUNC,(unsigned long)seq_len); -#endif /* QAK */ + } /* end if */ - /* - * Peel off final partial hyperslabs until we've finished reading all the data - */ - if(seq_len>0) { - hsize_t partial_size; /* Size of the partial hyperslab in bytes */ + /* + * Peel off final partial hyperslabs until we've finished reading all the data + */ + if(seq_len>0) { + hsize_t partial_size; /* Size of the partial hyperslab in bytes */ + + /* + * Peel off remaining partial hyperslabs, from the next-slowest dimension + * on down to the next-to-fastest changing dimension + */ + for(i=1; i<(ndims-1); i++) { + /* Check if there are enough elements to read in a row in this dimension */ + if(seq_len>=down_size[i]) { + /* Reset the partial hyperslab size */ + partial_size=1; + + /* Build the partial hyperslab information */ + for(j=0; j<ndims; j++) { + if(j<i) + hslab_size[j]=1; + else + if(j==i) + hslab_size[j]=seq_len/down_size[j]; + else + hslab_size[j]=dset_dims[j]; + + partial_size*=hslab_size[j]; + } /* end for */ + hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ + + /* Read in the partial hyperslab */ + if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, + hslab_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); + } + + /* Increment the buffer offset */ + buf=(unsigned char *)buf+partial_size; + + /* Decrement the length of the sequence to read */ + seq_len-=partial_size; + + /* Correct the coords array */ + coords[i]=hslab_size[i]; + } /* end if */ + } /* end for */ - /* - * Peel off remaining partial hyperslabs, from the next-slowest dimension - * on down to the next-to-fastest changing dimension - */ - for(i=1; i<(ndims-1); i++) { - /* Check if there are enough elements to read in a row in this dimension */ - if(seq_len>=down_size[i]) { -#ifdef QAK -printf("%s: seq_len=%ld, down_size[%d]=%ld\n",FUNC,(long)seq_len,i+1,(long)down_size[i+1]); -#endif /* QAK */ - /* Reset the partial hyperslab size */ - partial_size=1; - - /* Build the partial hyperslab information */ - for(j=0; j<ndims; j++) { - if(j<i) - hslab_size[j]=1; - else - if(j==i) - hslab_size[j]=seq_len/down_size[j]; - else - hslab_size[j]=dset_dims[j]; + /* Handle fastest changing dimension if there are any elements left */ + if(seq_len>0) { + assert(seq_len<dset_dims[ndims-1]); - partial_size*=hslab_size[j]; -#ifdef QAK -printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)coords[j],j,(long)hslab_size[j]); -#endif /* QAK */ - } /* end for */ - hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ -#ifdef QAK -printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)coords[ndims],ndims,(long)hslab_size[ndims]); -#endif /* QAK */ + /* Reset the partial hyperslab size */ + partial_size=1; - /* Read in the partial hyperslab */ - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); - } + /* Build the partial hyperslab information */ + for(j=0; j<ndims; j++) { + if(j==(ndims-1)) + hslab_size[j]=seq_len; + else + hslab_size[j]=1; - /* Increment the buffer offset */ - buf=(unsigned char *)buf+partial_size; + partial_size*=hslab_size[j]; + } /* end for */ + hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ - /* Decrement the length of the sequence to read */ - seq_len-=partial_size; + /* Read in the partial hyperslab */ + if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, + hslab_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); + } - /* Correct the coords array */ - coords[i]=hslab_size[i]; + /* Double-check the amount read in */ + assert(seq_len==partial_size); + } /* end if */ } /* end if */ - } /* end for */ -#ifdef QAK -printf("%s: after reading trailing hyperslabs for all but the last dimension, seq_len=%ld\n",FUNC,(long)seq_len); -#endif /* QAK */ - - /* Handle fastest changing dimension if there are any elements left */ - if(seq_len>0) { -#ifdef QAK -printf("%s: i=%d, seq_len=%ld\n",FUNC,ndims-1,(long)seq_len); -#endif /* QAK */ - assert(seq_len<dset_dims[ndims-1]); - - /* Reset the partial hyperslab size */ - partial_size=1; - - /* Build the partial hyperslab information */ - for(j=0; j<ndims; j++) { - if(j==(ndims-1)) - hslab_size[j]=seq_len; - else - hslab_size[j]=1; - - partial_size*=hslab_size[j]; -#ifdef QAK -printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)coords[j],j,(long)hslab_size[j]); -#endif /* QAK */ - } /* end for */ - hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ -#ifdef QAK -printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)coords[ndims],ndims,(long)hslab_size[ndims]); -#endif /* QAK */ - - /* Read in the partial hyperslab */ - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); - } + } + /* Increment offset in buffer */ + real_buf += seq_len_arr[v]; + } /* end for */ - /* Double-check the amount read in */ - assert(seq_len==partial_size); - } /* end if */ - } /* end if */ - } break; default: @@ -469,55 +476,64 @@ printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsign } /* end switch() */ FUNC_LEAVE(SUCCEED); -} /* H5F_seq_read() */ +} /* H5F_seq_readv() */ /*------------------------------------------------------------------------- - * Function: H5F_seq_write + * Function: H5F_seq_writev * - * Purpose: Writes a sequence of bytes to a file dataset from a buffer in - * in memory. The data is written to file F and the array's size and - * storage information is in LAYOUT. External files are described - * according to the external file list, EFL. The sequence offset is - * FILE_OFFSET in the file (offsets are - * in terms of bytes) and the size of the hyperslab is SEQ_LEN. The - * total size of the file array is implied in the LAYOUT argument. + * Purpose: Writes a vector of byte sequences from a buffer in memory into + * a file dataset. The data is written to file F and the array's size + * and storage information is in LAYOUT. External files are described + * according to the external file list, EFL. The vector of byte sequences + * offsets is in the FILE_OFFSET array into the dataset (offsets are in + * terms of bytes) and the size of each sequence is in the SEQ_LEN array. + * The total size of the file array is implied in the LAYOUT argument. + * Bytes written from BUF are sequentially stored in the buffer, each sequence + * from the vector stored directly after the previous. The number of + * sequences is NSEQ. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * Monday, October 9, 2000 + * Friday, July 6, 2001 * * Modifications: * *------------------------------------------------------------------------- */ herr_t -H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, +H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const H5O_fill_t *fill, const struct H5O_efl_t *efl, const H5S_t *file_space, size_t elmt_size, - hsize_t seq_len, hsize_t file_offset, const void *buf) + size_t nseq, size_t seq_len_arr[], hsize_t file_offset_arr[], + const void *_buf) { + const unsigned char *real_buf=(const unsigned char *)_buf; /* Local pointer to buffer to fill */ + const unsigned char *buf; /* Local pointer to buffer to fill */ + hsize_t file_offset; /* Offset in dataset */ + hsize_t seq_len; /* Number of bytes to read */ hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */ hssize_t coords[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in dataspace */ hsize_t hslab_size[H5O_LAYOUT_NDIMS]; /* hyperslab size in dataspace*/ hsize_t down_size[H5O_LAYOUT_NDIMS]; /* Cumulative hyperslab sizes (in elements) */ - hsize_t acc; /* Accumulator for hyperslab sizes (in elements) */ + hsize_t acc; /* Accumulator for hyperslab sizes (in elements) */ intn ndims; - hsize_t max_data = 0; /*bytes in dataset */ + hsize_t max_data; /*bytes in dataset */ haddr_t addr; /*address in file */ uintn u; /*counters */ + size_t v; /*counters */ intn i,j; /*counters */ #ifdef H5_HAVE_PARALLEL H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; #endif - FUNC_ENTER(H5F_seq_write, FAIL); + FUNC_ENTER(H5F_seq_writev, FAIL); /* Check args */ assert(f); assert(layout); - assert(buf); + assert(real_buf); #ifdef H5_HAVE_PARALLEL { @@ -547,30 +563,11 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, "filters are not allowed for contiguous data"); } - /* - * Initialize loop variables. The loop is a multi-dimensional loop - * that counts from SIZE down to zero and IDX is the counter. Each - * element of IDX is treated as a digit with IDX[0] being the least - * significant digit. - */ - if (efl && efl->nused>0) { - addr = 0; - } else { - addr = layout->addr; - /* Compute the size of the dataset in bytes */ - for(u=0, max_data=1; u<layout->ndims; u++) - max_data *= layout->dim[u]; - - /* Adjust the maximum size of the data by the offset into it */ - max_data -= file_offset; - } - addr += file_offset; - - /* - * Now begin to walk through the array, copying data from disk to - * memory. - */ + /* Write directly to file if the dataset is in an external file */ + if (efl && efl->nused>0) { + /* Iterate through the sequence vectors */ + for(v=0; v<nseq; v++) { #ifdef H5_HAVE_PARALLEL if (H5FD_MPIO_COLLECTIVE==xfer_mode) { /* @@ -580,8 +577,8 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, */ unsigned long max, min, temp; - temp = seq_len; - assert(temp==seq_len); /* verify no overflow */ + temp = seq_len_arr[v]; + assert(temp==seq_len_arr[v]); /* verify no overflow */ MPI_Allreduce(&temp, &max, 1, MPI_UNSIGNED_LONG, MPI_MAX, H5FD_mpio_communicator(f->shared->lf)); MPI_Allreduce(&temp, &min, 1, MPI_UNSIGNED_LONG, MPI_MIN, @@ -594,20 +591,26 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, "collective access with unequal number of blocks not supported yet"); } #endif + /* Note: We can't use data sieve buffers for datasets in external files + * because the 'addr' of all external files is set to 0 (above) and + * all datasets in external files would alias to the same set of + * file offsets, totally mixing up the data sieve buffer information. -QAK + */ + if (H5O_efl_write(f, efl, file_offset_arr[v], seq_len_arr[v], real_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "external data write failed"); + } - /* Write directly to file if the dataset is in an external file */ - if (efl && efl->nused>0) { - /* Note: We can't use data sieve buffers for datasets in external files - * because the 'addr' of all external files is set to 0 (above) and - * all datasets in external files would alias to the same set of - * file offsets, totally mixing up the data sieve buffer information. -QAK - */ - if (H5O_efl_write(f, efl, addr, seq_len, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "external data write failed"); - } + /* Increment offset in buffer */ + real_buf += seq_len_arr[v]; + } /* end for */ } else { - if (H5F_contig_write(f, max_data, H5FD_MEM_DRAW, addr, seq_len, dxpl_id, buf)<0) { + /* Compute the size of the dataset in bytes */ + for(u=1, max_data=layout->dim[0]; u<layout->ndims; u++) + max_data *= layout->dim[u]; + + /* Pass along the vector of sequences to write */ + if (H5F_contig_writev(f, max_data, H5FD_MEM_DRAW, layout->addr, nseq, seq_len_arr, file_offset_arr, dxpl_id, real_buf)<0) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed"); } @@ -615,286 +618,217 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, break; case H5D_CHUNKED: - { - /* - * This method is unable to access external raw data files - */ - if (efl && efl->nused>0) { - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, - "chunking and external files are mutually exclusive"); - } - /* Compute the file offset coordinates and hyperslab size */ - if((ndims=H5S_get_simple_extent_dims(file_space,dset_dims,NULL))<0) - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions"); - -#ifdef QAK -/* Print out the file offsets & hyperslab sizes */ -{ - static int count=0; - - if(count<1000000) { - printf("%s: elmt_size=%d, addr=%d, seq_len=%lu\n",FUNC,(int)elmt_size,(int)addr,(unsigned long)seq_len); - printf("%s: file_offset=%d\n",FUNC,(int)file_offset); - count++; - } -} -#endif /* QAK */ -#ifdef QAK - /* The library shouldn't be reading partial elements currently */ - assert((seq_len%elmt_size)!=0); - assert((addr%elmt_size)!=0); -#endif /* QAK */ - - /* Set location in dataset from the file_offset */ - addr=file_offset; - - /* Convert the bytes into elements */ - seq_len/=elmt_size; - addr/=elmt_size; - - /* Build the array of cumulative hyperslab sizes */ - for(acc=1, i=(ndims-1); i>=0; i--) { - down_size[i]=acc; - acc*=dset_dims[i]; -#ifdef QAK -printf("%s: acc=%ld, down_size[%d]=%ld\n",FUNC,(long)acc,i,(long)down_size[i]); -#endif /* QAK */ - } /* end for */ - - /* Compute the hyperslab offset from the address given */ - for(i=ndims-1; i>=0; i--) { - coords[i]=addr%dset_dims[i]; - addr/=dset_dims[i]; -#ifdef QAK -printf("%s: addr=%lu, dset_dims[%d]=%ld, coords[%d]=%ld\n",FUNC,(unsigned long)addr,i,(long)dset_dims[i],i,(long)coords[i]); -#endif /* QAK */ - } /* end for */ - coords[ndims]=0; /* No offset for element info */ -#ifdef QAK -printf("%s: addr=%lu, coords[%d]=%ld\n",FUNC,(unsigned long)addr,ndims,(long)coords[ndims]); -#endif /* QAK */ - - /* - * Peel off initial partial hyperslabs until we've got a hyperslab which starts - * at coord[n]==0 for dimensions 1->(ndims-1) (i.e. starting at coordinate - * zero for all dimensions except the slowest changing one - */ - for(i=ndims-1; i>0 && seq_len>=down_size[i]; i--) { - hsize_t partial_size; /* Size of the partial hyperslab in bytes */ - - /* Check if we have a partial hyperslab in this lower dimension */ - if(coords[i]>0) { -#ifdef QAK -printf("%s: Need to get hyperslab, seq_len=%ld, coords[%d]=%ld\n",FUNC,(long)seq_len,i,(long)coords[i]); -#endif /* QAK */ - /* Reset the partial hyperslab size */ - partial_size=1; - - /* Build the partial hyperslab information */ - for(j=0; j<ndims; j++) { - if(i==j) - hslab_size[j]=MIN(seq_len/down_size[i],dset_dims[i]-coords[i]); - else - if(j>i) - hslab_size[j]=dset_dims[j]; - else - hslab_size[j]=1; - partial_size*=hslab_size[j]; -#ifdef QAK -printf("%s: partial_size=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)hslab_size[j]); -#endif /* QAK */ - } /* end for */ - hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ -#ifdef QAK -printf("%s: partial_size=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)hslab_size[ndims]); -#endif /* QAK */ - - /* Write out the partial hyperslab */ - if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked write failed"); + /* Brute-force, stupid way to implement the vectors, but too complex to do other ways... */ + for(v=0; v<nseq; v++) { + file_offset=file_offset_arr[v]; + seq_len=seq_len_arr[v]; + buf=real_buf; + + { + /* + * This method is unable to access external raw data files + */ + if (efl && efl->nused>0) { + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, + "chunking and external files are mutually exclusive"); } + /* Compute the file offset coordinates and hyperslab size */ + if((ndims=H5S_get_simple_extent_dims(file_space,dset_dims,NULL))<0) + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions"); - /* Increment the buffer offset */ - buf=(const unsigned char *)buf+partial_size; + /* Set location in dataset from the file_offset */ + addr=file_offset; - /* Decrement the length of the sequence to read */ - seq_len-=partial_size; - - /* Correct the coords array */ - coords[i]=0; - coords[i-1]++; - } /* end if */ - } /* end for */ -#ifdef QAK -printf("%s: seq_len=%lu\n",FUNC,(unsigned long)seq_len); -#endif /* QAK */ - - /* Check if there is more than just a partial hyperslab to read */ - if(seq_len>=down_size[0]) { - hsize_t tmp_seq_len; /* Temp. size of the sequence in elements */ - hsize_t full_size; /* Size of the full hyperslab in bytes */ - - /* Get the sequence length for computing the hyperslab sizes */ - tmp_seq_len=seq_len; - - /* Reset the size of the hyperslab read in */ - full_size=1; - - /* Compute the hyperslab size from the length given */ - for(i=ndims-1; i>=0; i--) { - /* Check if the hyperslab is wider than the width of the dimension */ - if(tmp_seq_len>dset_dims[i]) { - assert(0==coords[i]); - hslab_size[i]=dset_dims[i]; - } /* end if */ - else - hslab_size[i]=tmp_seq_len; + /* Convert the bytes into elements */ + seq_len/=elmt_size; + addr/=elmt_size; - /* compute the number of elements read in */ - full_size*=hslab_size[i]; - - /* Fold the length into the length in the next highest dimension */ - tmp_seq_len/=dset_dims[i]; -#ifdef QAK -printf("%s: tmp_seq_len=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)tmp_seq_len,i,(long)hslab_size[i]); -#endif /* QAK */ - - /* Make certain the hyperslab sizes don't go less than 1 for dimensions less than 0*/ - assert(tmp_seq_len>=1 || i==0); - } /* end for */ - hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ - -#ifdef QAK -/* Print out the file offsets & hyperslab sizes */ -{ - static int count=0; - - if(count<1000000) { - printf("%s: elmt_size=%d, addr=%d, full_size=%ld, tmp_seq_len=%ld seq_len=%ld\n",FUNC,(int)elmt_size,(int)addr,(long)full_size,(long)tmp_seq_len,(long)seq_len); - for(i=0; i<ndims; i++) - printf("%s: dset_dims[%d]=%d\n",FUNC,i,(int)dset_dims[i]); - for(i=0; i<=ndims; i++) - printf("%s: coords[%d]=%d, hslab_size[%d]=%d\n",FUNC,i,(int)coords[i],(int)i,(int)hslab_size[i]); - count++; - } -} -#endif /* QAK */ + /* Build the array of cumulative hyperslab sizes */ + for(acc=1, i=(ndims-1); i>=0; i--) { + down_size[i]=acc; + acc*=dset_dims[i]; + } /* end for */ - /* Write the full hyperslab in */ - if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked write failed"); - } + /* Compute the hyperslab offset from the address given */ + for(i=ndims-1; i>=0; i--) { + coords[i]=addr%dset_dims[i]; + addr/=dset_dims[i]; + } /* end for */ + coords[ndims]=0; /* No offset for element info */ + + /* + * Peel off initial partial hyperslabs until we've got a hyperslab which starts + * at coord[n]==0 for dimensions 1->(ndims-1) (i.e. starting at coordinate + * zero for all dimensions except the slowest changing one + */ + for(i=ndims-1; i>0 && seq_len>=down_size[i]; i--) { + hsize_t partial_size; /* Size of the partial hyperslab in bytes */ + + /* Check if we have a partial hyperslab in this lower dimension */ + if(coords[i]>0) { + /* Reset the partial hyperslab size */ + partial_size=1; + + /* Build the partial hyperslab information */ + for(j=0; j<ndims; j++) { + if(i==j) + hslab_size[j]=MIN(seq_len/down_size[i],dset_dims[i]-coords[i]); + else + if(j>i) + hslab_size[j]=dset_dims[j]; + else + hslab_size[j]=1; + partial_size*=hslab_size[j]; + } /* end for */ + hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ + + /* Write out the partial hyperslab */ + if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, + hslab_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); + } + + /* Increment the buffer offset */ + buf=(const unsigned char *)buf+partial_size; + + /* Decrement the length of the sequence to read */ + seq_len-=partial_size; + + /* Correct the coords array */ + coords[i]=0; + coords[i-1]++; + } /* end if */ + } /* end for */ - /* Increment the buffer offset */ - buf=(const unsigned char *)buf+full_size; + /* Check if there is more than just a partial hyperslab to read */ + if(seq_len>=down_size[0]) { + hsize_t tmp_seq_len; /* Temp. size of the sequence in elements */ + hsize_t full_size; /* Size of the full hyperslab in bytes */ - /* Decrement the sequence length left */ - seq_len-=full_size; + /* Get the sequence length for computing the hyperslab sizes */ + tmp_seq_len=seq_len; - /* Increment coordinate of slowest changing dimension */ - coords[0]+=hslab_size[0]; + /* Reset the size of the hyperslab read in */ + full_size=1; - } /* end if */ -#ifdef QAK -printf("%s: seq_len=%lu\n",FUNC,(unsigned long)seq_len); -#endif /* QAK */ + /* Compute the hyperslab size from the length given */ + for(i=ndims-1; i>=0; i--) { + /* Check if the hyperslab is wider than the width of the dimension */ + if(tmp_seq_len>dset_dims[i]) { + assert(0==coords[i]); + hslab_size[i]=dset_dims[i]; + } /* end if */ + else + hslab_size[i]=tmp_seq_len; - /* - * Peel off final partial hyperslabs until we've finished reading all the data - */ - if(seq_len>0) { - hsize_t partial_size; /* Size of the partial hyperslab in bytes */ + /* compute the number of elements read in */ + full_size*=hslab_size[i]; - /* - * Peel off remaining partial hyperslabs, from the next-slowest dimension - * on down to the next-to-fastest changing dimension - */ - for(i=1; i<(ndims-1); i++) { - /* Check if there are enough elements to read in a row in this dimension */ - if(seq_len>=down_size[i]) { -#ifdef QAK -printf("%s: seq_len=%ld, down_size[%d]=%ld\n",FUNC,(long)seq_len,i+1,(long)down_size[i+1]); -#endif /* QAK */ - /* Reset the partial hyperslab size */ - partial_size=1; - - /* Build the partial hyperslab information */ - for(j=0; j<ndims; j++) { - if(j<i) - hslab_size[j]=1; - else - if(j==i) - hslab_size[j]=seq_len/down_size[j]; - else - hslab_size[j]=dset_dims[j]; + /* Fold the length into the length in the next highest dimension */ + tmp_seq_len/=dset_dims[i]; - partial_size*=hslab_size[j]; -#ifdef QAK -printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)coords[j],j,(long)hslab_size[j]); -#endif /* QAK */ + /* Make certain the hyperslab sizes don't go less than 1 for dimensions less than 0*/ + assert(tmp_seq_len>=1 || i==0); } /* end for */ hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ -#ifdef QAK -printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)coords[ndims],ndims,(long)hslab_size[ndims]); -#endif /* QAK */ - /* Write out the partial hyperslab */ + /* Write the full hyperslab in */ if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked write failed"); + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); } /* Increment the buffer offset */ - buf=(const unsigned char *)buf+partial_size; + buf=(const unsigned char *)buf+full_size; + + /* Decrement the sequence length left */ + seq_len-=full_size; - /* Decrement the length of the sequence to read */ - seq_len-=partial_size; + /* Increment coordinate of slowest changing dimension */ + coords[0]+=hslab_size[0]; - /* Correct the coords array */ - coords[i]=hslab_size[i]; } /* end if */ - } /* end for */ - /* Handle fastest changing dimension if there are any elements left */ - if(seq_len>0) { -#ifdef QAK -printf("%s: i=%d, seq_len=%ld\n",FUNC,ndims-1,(long)seq_len); -#endif /* QAK */ - assert(seq_len<dset_dims[ndims-1]); - - /* Reset the partial hyperslab size */ - partial_size=1; - - /* Build the partial hyperslab information */ - for(j=0; j<ndims; j++) { - if(j==(ndims-1)) - hslab_size[j]=seq_len; - else - hslab_size[j]=1; - - partial_size*=hslab_size[j]; -#ifdef QAK -printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)coords[j],j,(long)hslab_size[j]); -#endif /* QAK */ - } /* end for */ - hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ -#ifdef QAK -printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)coords[ndims],ndims,(long)hslab_size[ndims]); -#endif /* QAK */ - - /* Write in the final partial hyperslab */ - if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked write failed"); - } + /* + * Peel off final partial hyperslabs until we've finished reading all the data + */ + if(seq_len>0) { + hsize_t partial_size; /* Size of the partial hyperslab in bytes */ + + /* + * Peel off remaining partial hyperslabs, from the next-slowest dimension + * on down to the next-to-fastest changing dimension + */ + for(i=1; i<(ndims-1); i++) { + /* Check if there are enough elements to read in a row in this dimension */ + if(seq_len>=down_size[i]) { + /* Reset the partial hyperslab size */ + partial_size=1; + + /* Build the partial hyperslab information */ + for(j=0; j<ndims; j++) { + if(j<i) + hslab_size[j]=1; + else + if(j==i) + hslab_size[j]=seq_len/down_size[j]; + else + hslab_size[j]=dset_dims[j]; + + partial_size*=hslab_size[j]; + } /* end for */ + hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ + + /* Write out the partial hyperslab */ + if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, + hslab_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); + } + + /* Increment the buffer offset */ + buf=(const unsigned char *)buf+partial_size; + + /* Decrement the length of the sequence to read */ + seq_len-=partial_size; + + /* Correct the coords array */ + coords[i]=hslab_size[i]; + } /* end if */ + } /* end for */ + + /* Handle fastest changing dimension if there are any elements left */ + if(seq_len>0) { + assert(seq_len<dset_dims[ndims-1]); + + /* Reset the partial hyperslab size */ + partial_size=1; + + /* Build the partial hyperslab information */ + for(j=0; j<ndims; j++) { + if(j==(ndims-1)) + hslab_size[j]=seq_len; + else + hslab_size[j]=1; + + partial_size*=hslab_size[j]; + } /* end for */ + hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ + + /* Write out the final partial hyperslab */ + if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, + hslab_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); + } + + /* Double-check the amount read in */ + assert(seq_len==partial_size); + } /* end if */ + } /* end if */ + } + /* Increment offset in buffer */ + real_buf += seq_len_arr[v]; + } /* end for */ - /* Double-check the amount read in */ - assert(seq_len==partial_size); - } /* end if */ - } /* end if */ - } break; default: @@ -903,5 +837,5 @@ printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsign } /* end switch() */ FUNC_LEAVE(SUCCEED); -} /* H5F_seq_write() */ +} /* H5F_seq_writev() */ @@ -596,7 +596,7 @@ H5F_locate_signature(H5FD_t *file) HRETURN_ERROR(H5E_IO, H5E_CANTINIT, HADDR_UNDEF, "unable to set EOA value for file signature"); } - if (H5FD_read(file, H5FD_MEM_SUPER, H5P_DEFAULT, addr, (hsize_t)H5F_SIGNATURE_LEN, buf)<0) { + if (H5FD_read(file, H5FD_MEM_SUPER, H5P_DEFAULT, addr, H5F_SIGNATURE_LEN, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_CANTINIT, HADDR_UNDEF, "unable to read file signature"); } @@ -956,9 +956,9 @@ H5F_open(const char *name, uintn flags, hid_t fcpl_id, hid_t fapl_id) H5FD_t *lf=NULL; /*file driver part of `shared' */ uint8_t buf[256]; /*temporary I/O buffer */ const uint8_t *p; /*ptr into temp I/O buffer */ - hsize_t fixed_size=24; /*fixed sizeof superblock */ - hsize_t variable_size; /*variable sizeof superblock */ - hsize_t driver_size; /*size of driver info block */ + size_t fixed_size=24; /*fixed sizeof superblock */ + size_t variable_size; /*variable sizeof superblock */ + size_t driver_size; /*size of driver info block */ H5G_entry_t root_ent; /*root symbol table entry */ haddr_t eof; /*end of file address */ haddr_t stored_eoa; /*relative end-of-addr in file */ @@ -1217,7 +1217,7 @@ H5F_open(const char *name, uintn flags, hid_t fcpl_id, hid_t fapl_id) if (H5F_addr_defined(shared->driver_addr)) { haddr_t drv_addr = shared->base_addr + shared->driver_addr; if (H5FD_set_eoa(lf, drv_addr+16)<0 || - H5FD_read(lf, H5FD_MEM_SUPER, H5P_DEFAULT, drv_addr, (hsize_t)16, buf)<0) { + H5FD_read(lf, H5FD_MEM_SUPER, H5P_DEFAULT, drv_addr, 16, buf)<0) { HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read driver information block"); } @@ -1629,7 +1629,7 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate, { uint8_t sbuf[2048], dbuf[2048], *p=NULL; uintn nerrors=0, i; - hsize_t superblock_size, driver_size; + size_t superblock_size, driver_size; char driver_name[9]; FUNC_ENTER(H5F_flush, FAIL); @@ -2565,7 +2565,7 @@ H5F_get_driver_id(H5F_t *f) *------------------------------------------------------------------------- */ herr_t -H5F_block_read(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, hid_t dxpl_id, +H5F_block_read(H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, hid_t dxpl_id, void *buf/*out*/) { haddr_t abs_addr; @@ -2616,7 +2616,7 @@ H5F_block_read(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, hid_t dxpl *------------------------------------------------------------------------- */ herr_t -H5F_block_write(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, +H5F_block_write(H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, hid_t dxpl_id, const void *buf) { haddr_t abs_addr; @@ -1658,18 +1658,24 @@ H5FD_realloc(H5FD_t *file, H5FD_mem_t type, haddr_t old_addr, hsize_t old_size, H5FDfree(file, type, old_addr+old_size, old_size-new_size); } else { /* move memory to new location */ + /* Note! This may fail if sizeof(hsize_t)>sizeof(size_t) and the + * object on disk is too large to read into a memory buffer all at one + * time. This chunk of code would have to be re-written using a loop + * to move pieces of the realloced data through a fixed size buffer, etc. + * -QAK, 6/20/01 + */ if (HADDR_UNDEF==(new_addr=H5FDalloc(file, type, new_size))) { HRETURN_ERROR(H5E_FILE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed"); } - assert(old_size==(hsize_t)((size_t)old_size)); /*check for overflow*/ + H5_CHECK_OVERFLOW(old_size,hsize_t,size_t); if (old_size>sizeof(_buf) && NULL==(buf=H5MM_malloc((size_t)old_size))) { H5FDfree(file, type, new_addr, new_size); HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "memory allocation failed"); } - if (H5FDread(file, type, H5P_DEFAULT, old_addr, old_size, buf)<0 || - H5FDwrite(file, type, H5P_DEFAULT, new_addr, old_size, buf)<0) { + if (H5FDread(file, type, H5P_DEFAULT, old_addr, (size_t)old_size, buf)<0 || + H5FDwrite(file, type, H5P_DEFAULT, new_addr, (size_t)old_size, buf)<0) { H5FDfree(file, type, new_addr, new_size); H5MM_xfree(buf); HRETURN_ERROR(H5E_FILE, H5E_READERROR, HADDR_UNDEF, @@ -1955,7 +1961,7 @@ H5FD_get_eof(H5FD_t *file) *------------------------------------------------------------------------- */ herr_t -H5FDread(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size, +H5FDread(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, void *buf/*out*/) { FUNC_ENTER(H5FDread, FAIL); @@ -2005,7 +2011,7 @@ H5FDread(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t siz *------------------------------------------------------------------------- */ herr_t -H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size, +H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, void *buf/*out*/) { FUNC_ENTER(H5FD_read, FAIL); @@ -2028,8 +2034,8 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t si || (addr<file->accum_loc && (addr+size)>(file->accum_loc+file->accum_size)))) { unsigned char *read_buf=(unsigned char *)buf; /* Pointer to the buffer being read in */ - hsize_t amount_read; /* Amount to read at a time */ - hsize_t read_off; /* Offset to read from */ + size_t amount_read; /* Amount to read at a time */ + haddr_t read_off; /* Offset to read from */ /* Double check that we aren't reading raw data */ assert(type!=H5FD_MEM_DRAW); @@ -2058,8 +2064,7 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t si amount_read=MIN((file->accum_size-read_off),size); /* Copy the data out of the buffer */ - assert(amount_read==(hsize_t)((size_t)amount_read)); /*check for overflow*/ - HDmemcpy(read_buf,file->meta_accum+read_off,(size_t)amount_read); + HDmemcpy(read_buf,file->meta_accum+read_off,amount_read); /* Adjust the buffer, address & size */ read_buf+=amount_read; @@ -2112,7 +2117,7 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t si *------------------------------------------------------------------------- */ herr_t -H5FDwrite(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size, +H5FDwrite(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, const void *buf) { FUNC_ENTER(H5FDwrite, FAIL); @@ -2163,10 +2168,10 @@ H5FDwrite(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t si *------------------------------------------------------------------------- */ herr_t -H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size, +H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, const void *buf) { - hsize_t new_size; /* New size of the accumulator buffer */ + size_t new_size; /* New size of the accumulator buffer */ size_t old_offset; /* Offset of old data within the accumulator buffer */ FUNC_ENTER(H5FD_write, FAIL); @@ -2204,12 +2209,10 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t s } /* end if */ /* Move the existing metadata to the proper location */ - assert(file->accum_size==(hsize_t)((size_t)file->accum_size)); /*check for overflow*/ - HDmemmove(file->meta_accum+size,file->meta_accum,(size_t)file->accum_size); + HDmemmove(file->meta_accum+size,file->meta_accum,file->accum_size); /* Copy the new metadata at the front */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(file->meta_accum,buf,(size_t)size); + HDmemcpy(file->meta_accum,buf,size); /* Set the new size & location of the metadata accumulator */ file->accum_loc=addr; @@ -2231,8 +2234,7 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t s } /* end if */ /* Copy the new metadata to the end */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(file->meta_accum+file->accum_size,buf,(size_t)size); + HDmemcpy(file->meta_accum+file->accum_size,buf,size); /* Set the new size of the metadata accumulator */ file->accum_size=file->accum_size+size; @@ -2243,8 +2245,7 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t s /* Check if the new metadata is entirely within the current accumulator */ else if(addr>=file->accum_loc && (addr+size)<=(file->accum_loc+file->accum_size)) { /* Copy the new metadata to the proper location within the accumulator */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(file->meta_accum+(addr-file->accum_loc),buf,(size_t)size); + HDmemcpy(file->meta_accum+(addr-file->accum_loc),buf,size); /* Mark it as written to */ file->accum_dirty=TRUE; @@ -2268,12 +2269,10 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t s old_offset=(addr+size)-file->accum_loc; /* Move the existing metadata to the proper location */ - assert((file->accum_size-old_offset)==(hsize_t)((size_t)(file->accum_size-old_offset))); /*check for overflow*/ - HDmemmove(file->meta_accum+size,file->meta_accum+old_offset,(size_t)(file->accum_size-old_offset)); + HDmemmove(file->meta_accum+size,file->meta_accum+old_offset,(file->accum_size-old_offset)); /* Copy the new metadata at the front */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(file->meta_accum,buf,(size_t)size); + HDmemcpy(file->meta_accum,buf,size); /* Set the new size & location of the metadata accumulator */ file->accum_loc=addr; @@ -2298,8 +2297,7 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t s } /* end if */ /* Copy the new metadata to the end */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(file->meta_accum+(addr-file->accum_loc),buf,(size_t)size); + HDmemcpy(file->meta_accum+(addr-file->accum_loc),buf,size); /* Set the new size & location of the metadata accumulator */ file->accum_loc=addr; @@ -2333,8 +2331,7 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t s file->accum_loc=addr; file->accum_size=size; file->accum_dirty=TRUE; - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(file->meta_accum,buf,(size_t)size); + HDmemcpy(file->meta_accum,buf,size); } /* end else */ } /* end if */ /* No metadata in the accumulator, grab this piece and keep it */ @@ -2353,8 +2350,7 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t s file->accum_loc=addr; file->accum_size=size; file->accum_dirty=TRUE; - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(file->meta_accum,buf,(size_t)size); + HDmemcpy(file->meta_accum,buf,size); } /* end else */ } /* end if */ else { diff --git a/src/H5FDcore.c b/src/H5FDcore.c index b971237..4d8a77d 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -84,9 +84,9 @@ static haddr_t H5FD_core_get_eoa(H5FD_t *_file); static herr_t H5FD_core_set_eoa(H5FD_t *_file, haddr_t addr); static haddr_t H5FD_core_get_eof(H5FD_t *_file); static herr_t H5FD_core_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, void *buf); + size_t size, void *buf); static herr_t H5FD_core_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, const void *buf); + size_t size, const void *buf); static const H5FD_class_t H5FD_core_g = { "core", /*name */ @@ -577,7 +577,7 @@ H5FD_core_get_eof(H5FD_t *_file) */ static herr_t H5FD_core_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, - hsize_t size, void *buf/*out*/) + size_t size, void *buf/*out*/) { H5FD_core_t *file = (H5FD_core_t*)_file; @@ -596,10 +596,9 @@ H5FD_core_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hadd /* Read the part which is before the EOF marker */ if (addr < file->eof) { - hsize_t nbytes = MIN(size, file->eof-addr); + size_t nbytes = MIN(size, file->eof-addr); - assert(nbytes==(hsize_t)((size_t)nbytes)); /*check for overflow*/ - HDmemcpy(buf, file->mem + addr, (size_t)nbytes); + HDmemcpy(buf, file->mem + addr, nbytes); size -= nbytes; addr += nbytes; buf = (char *)buf + nbytes; @@ -607,8 +606,7 @@ H5FD_core_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hadd /* Read zeros for the part which is after the EOF markers */ if (size > 0) { - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemset(buf, 0, (size_t)size); + HDmemset(buf, 0, size); } FUNC_LEAVE(SUCCEED); @@ -635,7 +633,7 @@ H5FD_core_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hadd */ static herr_t H5FD_core_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, - hsize_t size, const void *buf) + size_t size, const void *buf) { H5FD_core_t *file = (H5FD_core_t*)_file; @@ -660,9 +658,12 @@ H5FD_core_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had unsigned char *x; size_t new_eof = file->increment * ((addr+size)/file->increment); - if ((addr+size) % file->increment) new_eof += file->increment; - if (NULL==file->mem) x = H5MM_malloc(new_eof); - else x = H5MM_realloc(file->mem, new_eof); + if ((addr+size) % file->increment) + new_eof += file->increment; + if (NULL==file->mem) + x = H5MM_malloc(new_eof); + else + x = H5MM_realloc(file->mem, new_eof); if (!x) HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory block"); @@ -671,8 +672,7 @@ H5FD_core_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had } /* Write from BUF to memory */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(file->mem+addr, buf, (size_t)size); + HDmemcpy(file->mem+addr, buf, size); file->dirty = TRUE; FUNC_LEAVE(SUCCEED); diff --git a/src/H5FDdpss.c b/src/H5FDdpss.c index 3fde293..81e3115 100644 --- a/src/H5FDdpss.c +++ b/src/H5FDdpss.c @@ -99,9 +99,9 @@ static haddr_t H5FD_dpss_get_eoa (H5FD_t *_file); static herr_t H5FD_dpss_set_eoa (H5FD_t *_file, haddr_t addr); static haddr_t H5FD_dpss_get_eof (H5FD_t *_file); static herr_t H5FD_dpss_read (H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, void *buf); + size_t size, void *buf); static herr_t H5FD_dpss_write (H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED fapl_id,haddr_t addr, - hsize_t size, const void *buf); + size_t size, const void *buf); /* The Grid Storage I/O driver information */ static const H5FD_class_t H5FD_dpss_g = { @@ -513,7 +513,7 @@ H5FD_dpss_get_eof (H5FD_t *_file) */ static herr_t H5FD_dpss_read (H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t addr, - hsize_t size, void *buf/*out*/) + size_t size, void *buf/*out*/) { H5FD_dpss_t *file = (H5FD_dpss_t *) _file; globus_result_t globus_result; @@ -525,8 +525,8 @@ H5FD_dpss_read (H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t ad FUNC_ENTER (H5FD_dpss_read, FAIL); #ifdef DEBUG - fprintf (stdout, "H5FD_dpss_read: addr 0x%lx, size %ld\n", - (unsigned long int) addr, (unsigned long int) size); + fprintf (stdout, "H5FD_dpss_read: addr 0x%lx, size %u\n", + (unsigned long int) addr, (unsigned) size); #endif /* Check parameters */ @@ -569,7 +569,7 @@ H5FD_dpss_read (H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t ad /* do the (synchronuous) write operation */ globus_result = grid_storage_read (&file->handle, (unsigned char *) buf, - (size_t) addr, (size_t) size, NULL); + (size_t) addr, size, NULL); if (GLOBUS_SUCCESS != globus_result) { PRINT_GLOBUS_ERROR_MSG (globus_result); HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, @@ -598,7 +598,7 @@ H5FD_dpss_read (H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t ad */ static herr_t H5FD_dpss_write (H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t addr, - hsize_t size, const void *buf) + size_t size, const void *buf) { H5FD_dpss_t *file = (H5FD_dpss_t *) _file; globus_result_t globus_result; @@ -606,8 +606,8 @@ H5FD_dpss_write (H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t a FUNC_ENTER (H5FD_dpss_write, FAIL); #ifdef DEBUG - fprintf (stdout, "H5FD_dpss_write: addr 0x%lx, size %ld\n", - (unsigned long int) addr, (unsigned long int) size); + fprintf (stdout, "H5FD_dpss_write: addr 0x%lx, size %u\n", + (unsigned long int) addr, (unsigned) size); #endif /* Check parameters */ @@ -626,7 +626,7 @@ H5FD_dpss_write (H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t a /* do the (synchronuous) write operation */ globus_result = grid_storage_write (&file->handle, (unsigned char *) buf, - (size_t) addr, (size_t) size, NULL); + (size_t) addr, size, NULL); if (GLOBUS_SUCCESS != globus_result) { PRINT_GLOBUS_ERROR_MSG (globus_result); HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c index 1efce47..89828c6 100644 --- a/src/H5FDfamily.c +++ b/src/H5FDfamily.c @@ -77,9 +77,9 @@ static haddr_t H5FD_family_get_eoa(H5FD_t *_file); static herr_t H5FD_family_set_eoa(H5FD_t *_file, haddr_t eoa); static haddr_t H5FD_family_get_eof(H5FD_t *_file); static herr_t H5FD_family_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, - hsize_t size, void *_buf/*out*/); + size_t size, void *_buf/*out*/); static herr_t H5FD_family_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, - hsize_t size, const void *_buf); + size_t size, const void *_buf); static herr_t H5FD_family_flush(H5FD_t *_file); /* The class struct */ @@ -813,7 +813,7 @@ H5FD_family_get_eof(H5FD_t *_file) *------------------------------------------------------------------------- */ static herr_t -H5FD_family_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size, +H5FD_family_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, void *_buf/*out*/) { H5FD_family_t *file = (H5FD_family_t*)_file; @@ -821,7 +821,7 @@ H5FD_family_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hs hid_t memb_dxpl_id = H5P_DEFAULT; int i; haddr_t sub; - hsize_t req; + size_t req; FUNC_ENTER(H5FD_family_read, FAIL); @@ -876,7 +876,7 @@ H5FD_family_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hs *------------------------------------------------------------------------- */ static herr_t -H5FD_family_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size, +H5FD_family_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, const void *_buf) { H5FD_family_t *file = (H5FD_family_t*)_file; @@ -884,7 +884,7 @@ H5FD_family_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, h hid_t memb_dxpl_id = H5P_DEFAULT; int i; haddr_t sub; - hsize_t req; + size_t req; FUNC_ENTER(H5FD_family_write, FAIL); diff --git a/src/H5FDgass.c b/src/H5FDgass.c index 2394329..5b6b79c 100644 --- a/src/H5FDgass.c +++ b/src/H5FDgass.c @@ -89,9 +89,9 @@ static haddr_t H5FD_gass_get_eoa(H5FD_t *_file); static herr_t H5FD_gass_set_eoa(H5FD_t *_file, haddr_t addr); static haddr_t H5FD_gass_get_eof(H5FD_t *_file); static herr_t H5FD_gass_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, void *buf); + size_t size, void *buf); static herr_t H5FD_gass_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, const void *buf); + size_t size, const void *buf); /* GASS I/O-specific file access properties */ typedef struct H5FD_gass_fapl_t { @@ -559,7 +559,7 @@ H5FD_gass_get_eof(H5FD_t *_file) */ static herr_t H5FD_gass_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id/*unused*/, haddr_t addr, - hsize_t size, void *buf/*out*/) + size_t size, void *buf/*out*/) { H5FD_gass_t *file = (H5FD_gass_t*)_file; ssize_t nbytes; @@ -606,7 +606,7 @@ H5FD_gass_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id/*unused*/, h size = 0; } assert(nbytes>=0); - assert((hsize_t)nbytes<=size); + assert(nbytes<=size); size -= (hsize_t)nbytes; addr += (haddr_t)nbytes; buf = (char*)buf + nbytes; @@ -637,7 +637,7 @@ H5FD_gass_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id/*unused*/, h */ static herr_t H5FD_gass_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id/*unused*/, haddr_t addr, - hsize_t size, const void *buf) + size_t size, const void *buf) { H5FD_gass_t *file = (H5FD_gass_t*)_file; ssize_t nbytes; @@ -679,7 +679,7 @@ H5FD_gass_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id/*unused*/, haddr_t HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "gass file write failed"); } assert(nbytes>0); - assert((hsize_t)nbytes<=size); + assert(nbytes<=size); size -= (hsize_t)nbytes; addr += (haddr_t)nbytes; buf = (const char*)buf + nbytes; diff --git a/src/H5FDlog.c b/src/H5FDlog.c index 4c37651..552fd55 100644 --- a/src/H5FDlog.c +++ b/src/H5FDlog.c @@ -174,9 +174,9 @@ static haddr_t H5FD_log_get_eoa(H5FD_t *_file); static herr_t H5FD_log_set_eoa(H5FD_t *_file, haddr_t addr); static haddr_t H5FD_log_get_eof(H5FD_t *_file); static herr_t H5FD_log_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, void *buf); + size_t size, void *buf); static herr_t H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, const void *buf); + size_t size, const void *buf); static herr_t H5FD_log_flush(H5FD_t *_file); /* @@ -825,7 +825,7 @@ H5FD_log_get_eof(H5FD_t *_file) */ static herr_t H5FD_log_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, - hsize_t size, void *buf/*out*/) + size_t size, void *buf/*out*/) { H5FD_log_t *file = (H5FD_log_t*)_file; ssize_t nbytes; @@ -845,7 +845,7 @@ H5FD_log_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr /* Log the I/O information about the read */ if(file->fa.verbosity>=0) { - hsize_t tmp_size=size; + size_t tmp_size=size; haddr_t tmp_addr=addr; assert((addr+size)<file->iosize); @@ -876,8 +876,7 @@ H5FD_log_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr */ while (size>0) { do { - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - nbytes = HDread(file->fd, buf, (size_t)size); + nbytes = HDread(file->fd, buf, size); } while (-1==nbytes && EINTR==errno); if (-1==nbytes) { /* error */ @@ -887,13 +886,12 @@ H5FD_log_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr } if (0==nbytes) { /* end of file but not end of format address space */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemset(buf, 0, (size_t)size); + HDmemset(buf, 0, size); size = 0; } assert(nbytes>=0); - assert((hsize_t)nbytes<=size); - size -= (hsize_t)nbytes; + assert((size_t)nbytes<=size); + size -= nbytes; addr += (haddr_t)nbytes; buf = (char*)buf + nbytes; } @@ -925,7 +923,7 @@ H5FD_log_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr */ static herr_t H5FD_log_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, - hsize_t size, const void *buf) + size_t size, const void *buf) { H5FD_log_t *file = (H5FD_log_t*)_file; ssize_t nbytes; @@ -950,7 +948,7 @@ H5FD_log_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hadd /* Log the I/O information about the write */ if(file->fa.verbosity>=0) { - hsize_t tmp_size=size; + size_t tmp_size=size; haddr_t tmp_addr=addr; assert((addr+size)<file->iosize); @@ -965,7 +963,7 @@ H5FD_log_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hadd if(file->fa.verbosity>0) { /* Check if this is the first write into a "default" section, grabbed by the metadata agregation algorithm */ if(file->flavor[addr]==H5FD_MEM_DEFAULT) - HDmemset(&file->flavor[addr],type,(size_t)size); + HDmemset(&file->flavor[addr],type,size); HDfprintf(file->logfp,"%10a-%10a (%10lu bytes) Written, flavor=%s\n",addr,addr+size-1,(unsigned long)size,flavors[file->flavor[addr]]); } /* end if */ } @@ -985,8 +983,7 @@ H5FD_log_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hadd */ while (size>0) { do { - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - nbytes = HDwrite(file->fd, buf, (size_t)size); + nbytes = HDwrite(file->fd, buf, size); } while (-1==nbytes && EINTR==errno); if (-1==nbytes) { /* error */ @@ -995,8 +992,8 @@ H5FD_log_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hadd HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed"); } assert(nbytes>0); - assert((hsize_t)nbytes<=size); - size -= (hsize_t)nbytes; + assert((size_t)nbytes<=size); + size -= nbytes; addr += (haddr_t)nbytes; buf = (const char*)buf + nbytes; } diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 48d9155..9e0dfca 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -77,9 +77,9 @@ static haddr_t H5FD_mpio_get_eoa(H5FD_t *_file); static herr_t H5FD_mpio_set_eoa(H5FD_t *_file, haddr_t addr); static haddr_t H5FD_mpio_get_eof(H5FD_t *_file); static herr_t H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, void *buf); + size_t size, void *buf); static herr_t H5FD_mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, const void *buf); + size_t size, const void *buf); static herr_t H5FD_mpio_flush(H5FD_t *_file); /* MPIO-specific file access properties */ @@ -1062,7 +1062,7 @@ H5FD_mpio_get_eof(H5FD_t *_file) *------------------------------------------------------------------------- */ static herr_t -H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t addr, hsize_t size, +H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t addr, size_t size, void *buf/*out*/) { H5FD_mpio_t *file = (H5FD_mpio_t*)_file; @@ -1313,7 +1313,7 @@ H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t add */ static herr_t H5FD_mpio_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id/*unused*/, haddr_t addr, - hsize_t size, const void *buf) + size_t size, const void *buf) { H5FD_mpio_t *file = (H5FD_mpio_t*)_file; const H5FD_mpio_dxpl_t *dx=NULL; diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c index 85b5695..bd42869 100644 --- a/src/H5FDmulti.c +++ b/src/H5FDmulti.c @@ -124,9 +124,9 @@ static haddr_t H5FD_multi_alloc(H5FD_t *_file, H5FD_mem_t type, hsize_t size); static herr_t H5FD_multi_free(H5FD_t *_file, H5FD_mem_t type, haddr_t addr, hsize_t size); static herr_t H5FD_multi_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, - hsize_t size, void *_buf/*out*/); + size_t size, void *_buf/*out*/); static herr_t H5FD_multi_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, - hsize_t size, const void *_buf); + size_t size, const void *_buf); static herr_t H5FD_multi_flush(H5FD_t *_file); /* The class struct */ @@ -1574,7 +1574,7 @@ H5FD_multi_free(H5FD_t *_file, H5FD_mem_t type, haddr_t addr, hsize_t size) *------------------------------------------------------------------------- */ static herr_t -H5FD_multi_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size, +H5FD_multi_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, void *_buf/*out*/) { H5FD_multi_t *file = (H5FD_multi_t*)_file; @@ -1629,7 +1629,7 @@ H5FD_multi_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsi *------------------------------------------------------------------------- */ static herr_t -H5FD_multi_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size, +H5FD_multi_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, const void *_buf) { H5FD_multi_t *file = (H5FD_multi_t*)_file; diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index d535535..5ea6a8e 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -34,9 +34,9 @@ __DLL__ haddr_t H5FD_realloc(H5FD_t *file, H5FD_mem_t type, haddr_t old_addr, __DLL__ haddr_t H5FD_get_eoa(H5FD_t *file); __DLL__ herr_t H5FD_set_eoa(H5FD_t *file, haddr_t addr); __DLL__ haddr_t H5FD_get_eof(H5FD_t *file); -__DLL__ herr_t H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size, +__DLL__ herr_t H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, void *buf/*out*/); -__DLL__ herr_t H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size, +__DLL__ herr_t H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, const void *buf); __DLL__ herr_t H5FD_flush(H5FD_t *file); diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h index cdd4679..66358be 100644 --- a/src/H5FDpublic.h +++ b/src/H5FDpublic.h @@ -129,9 +129,9 @@ typedef struct H5FD_class_t { haddr_t (*get_eoa)(H5FD_t *file); herr_t (*set_eoa)(H5FD_t *file, haddr_t addr); haddr_t (*get_eof)(H5FD_t *file); - herr_t (*read)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl, haddr_t addr, hsize_t size, + herr_t (*read)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl, haddr_t addr, size_t size, void *buffer); - herr_t (*write)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl, haddr_t addr, hsize_t size, + herr_t (*write)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl, haddr_t addr, size_t size, const void *buffer); herr_t (*flush)(H5FD_t *file); H5FD_mem_t fl_map[H5FD_MEM_NTYPES]; @@ -164,8 +164,8 @@ struct H5FD_t { /* Metadata accumulator fields */ unsigned char *meta_accum; /* Buffer to hold the accumulated metadata */ haddr_t accum_loc; /* File location (offset) of the accumulated metadata */ - hsize_t accum_size; /* Size of the accumulated metadata buffer used (in bytes) */ - hsize_t accum_buf_size; /* Size of the accumulated metadata buffer allocated (in bytes) */ + size_t accum_size; /* Size of the accumulated metadata buffer used (in bytes) */ + size_t accum_buf_size; /* Size of the accumulated metadata buffer allocated (in bytes) */ unsigned accum_dirty; /* Flag to indicate that the accumulated metadata is dirty */ haddr_t maxaddr; /*for this file, overrides class*/ @@ -192,9 +192,9 @@ __DLL__ haddr_t H5FDrealloc(H5FD_t *file, H5FD_mem_t type, haddr_t addr, __DLL__ haddr_t H5FDget_eoa(H5FD_t *file); __DLL__ herr_t H5FDset_eoa(H5FD_t *file, haddr_t eof); __DLL__ haddr_t H5FDget_eof(H5FD_t *file); -__DLL__ herr_t H5FDread(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size, +__DLL__ herr_t H5FDread(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, void *buf/*out*/); -__DLL__ herr_t H5FDwrite(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size, +__DLL__ herr_t H5FDwrite(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, const void *buf); __DLL__ herr_t H5FDflush(H5FD_t *file); diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c index 14481f3..ff3a2bb 100644 --- a/src/H5FDsec2.c +++ b/src/H5FDsec2.c @@ -140,9 +140,9 @@ static haddr_t H5FD_sec2_get_eoa(H5FD_t *_file); static herr_t H5FD_sec2_set_eoa(H5FD_t *_file, haddr_t addr); static haddr_t H5FD_sec2_get_eof(H5FD_t *_file); static herr_t H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, void *buf); + size_t size, void *buf); static herr_t H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, const void *buf); + size_t size, const void *buf); static herr_t H5FD_sec2_flush(H5FD_t *_file); static const H5FD_class_t H5FD_sec2_g = { @@ -549,7 +549,7 @@ H5FD_sec2_get_eof(H5FD_t *_file) */ static herr_t H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, - hsize_t size, void *buf/*out*/) + size_t size, void *buf/*out*/) { H5FD_sec2_t *file = (H5FD_sec2_t*)_file; ssize_t nbytes; @@ -582,8 +582,7 @@ H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hadd */ while (size>0) { do { - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - nbytes = HDread(file->fd, buf, (size_t)size); + nbytes = HDread(file->fd, buf, size); } while (-1==nbytes && EINTR==errno); if (-1==nbytes) { /* error */ @@ -593,13 +592,12 @@ H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hadd } if (0==nbytes) { /* end of file but not end of format address space */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemset(buf, 0, (size_t)size); + HDmemset(buf, 0, size); size = 0; } assert(nbytes>=0); - assert((hsize_t)nbytes<=size); - size -= (hsize_t)nbytes; + assert((size_t)nbytes<=size); + size -= nbytes; addr += (haddr_t)nbytes; buf = (char*)buf + nbytes; } @@ -631,7 +629,7 @@ H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hadd */ static herr_t H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, - hsize_t size, const void *buf) + size_t size, const void *buf) { H5FD_sec2_t *file = (H5FD_sec2_t*)_file; ssize_t nbytes; @@ -664,8 +662,7 @@ H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had */ while (size>0) { do { - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - nbytes = HDwrite(file->fd, buf, (size_t)size); + nbytes = HDwrite(file->fd, buf, size); } while (-1==nbytes && EINTR==errno); if (-1==nbytes) { /* error */ @@ -674,8 +671,8 @@ H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed"); } assert(nbytes>0); - assert((hsize_t)nbytes<=size); - size -= (hsize_t)nbytes; + assert((size_t)nbytes<=size); + size -= nbytes; addr += (haddr_t)nbytes; buf = (const char*)buf + nbytes; } diff --git a/src/H5FDsrb.c b/src/H5FDsrb.c index 7071d8d..64a3aa5 100644 --- a/src/H5FDsrb.c +++ b/src/H5FDsrb.c @@ -56,9 +56,9 @@ static haddr_t H5FD_srb_get_eoa(H5FD_t *_file); static herr_t H5FD_srb_set_eoa(H5FD_t *_file, haddr_t addr); static haddr_t H5FD_srb_get_eof(H5FD_t *_file); static herr_t H5FD_srb_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, void *buf); + size_t size, void *buf); static herr_t H5FD_srb_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, const void *buf); + size_t size, const void *buf); static herr_t H5FD_srb_flush(H5FD_t *_file); /* The description of a file belonging to this driver. */ @@ -483,7 +483,7 @@ H5FD_srb_get_eof(H5FD_t *_file) */ static herr_t H5FD_srb_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, - hsize_t size, void *buf) + size_t size, void *buf) { H5FD_srb_t *file = (H5FD_srb_t*)_file; ssize_t nbytes; @@ -512,7 +512,7 @@ H5FD_srb_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr */ while(size>0) { if((nbytes=srbFileRead(file->srb_conn, (int)file->fd, (char*)buf, - (int)size))<0) { + size))<0) { file->pos = HADDR_UNDEF; srbFileClose(file->srb_conn, file->fd); clFinish(file->srb_conn); @@ -522,10 +522,10 @@ H5FD_srb_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr if (0==nbytes) { /*end of file but not end of format address space*/ - memset(buf, 0, size); + HDmemset(buf, 0, size); size = 0; } - size -= (hsize_t)nbytes; + size -= nbytes; addr += (haddr_t)nbytes; buf = (char*)buf + nbytes; } @@ -553,7 +553,7 @@ H5FD_srb_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr */ static herr_t H5FD_srb_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, - hsize_t size, const void *buf) + size_t size, const void *buf) { H5FD_srb_t *file = (H5FD_srb_t*)_file; ssize_t nbytes; @@ -578,7 +578,7 @@ H5FD_srb_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hadd while(size>0) { if( (nbytes=srbFileWrite(file->srb_conn, (int)file->fd, (char*)buf, - (int)size)) < 0 ) { + size)) < 0 ) { file->pos = HADDR_UNDEF; srbObjClose(file->srb_conn, file->fd); clFinish(file->srb_conn); @@ -586,7 +586,7 @@ H5FD_srb_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hadd "srb file write failed"); } - size -= (hsize_t)nbytes; + size -= nbytes; addr += (haddr_t)nbytes; buf = (const char*)buf + nbytes; } diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c index 67784b3..07885b4 100644 --- a/src/H5FDstdio.c +++ b/src/H5FDstdio.c @@ -136,9 +136,9 @@ static haddr_t H5FD_stdio_get_eoa(H5FD_t *_file); static herr_t H5FD_stdio_set_eoa(H5FD_t *_file, haddr_t addr); static haddr_t H5FD_stdio_get_eof(H5FD_t *_file); static herr_t H5FD_stdio_read(H5FD_t *lf, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, void *buf); + size_t size, void *buf); static herr_t H5FD_stdio_write(H5FD_t *lf, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, const void *buf); + size_t size, const void *buf); static herr_t H5FD_stdio_flush(H5FD_t *_file); static const H5FD_class_t H5FD_stdio_g = { @@ -589,7 +589,7 @@ H5FD_stdio_get_eof(H5FD_t *_file) *------------------------------------------------------------------------- */ static herr_t -H5FD_stdio_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size, +H5FD_stdio_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, void *buf/*out*/) { size_t n; @@ -615,8 +615,7 @@ H5FD_stdio_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsi if (0 == size) return(0); if ((haddr_t)addr >= file->eof) { - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - memset(buf, 0, (size_t)size); + memset(buf, 0, size); return(0); } @@ -657,15 +656,13 @@ H5FD_stdio_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsi * will advance the file position by N. If N is negative or an error * occurs then the file position is undefined. */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - n = fread(buf, 1, (size_t)size, file->fp); + n = fread(buf, 1, size, file->fp); if (n <= 0 && ferror(file->fp)) { file->op = H5FD_STDIO_OP_UNKNOWN; file->pos = HADDR_UNDEF; H5Epush_ret(func, H5E_IO, H5E_READERROR, "fread failed", -1); } else if (n < size) { - assert((size-n)==(hsize_t)((size_t)(size-n))); /*check for overflow*/ - memset((unsigned char *)buf + n, 0, (size_t)(size - n)); + memset((unsigned char *)buf + n, 0, (size - n)); } /* @@ -702,7 +699,7 @@ H5FD_stdio_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsi */ static herr_t H5FD_stdio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, - hsize_t size, const void *buf) + size_t size, const void *buf) { H5FD_stdio_t *file = (H5FD_stdio_t*)_file; static const char *func="H5FD_stdio_write"; /* Function Name for error reporting */ @@ -750,8 +747,7 @@ H5FD_stdio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, * advanced by the number of bytes read. Otherwise nobody knows where it * is. */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - if (size != fwrite(buf, 1, (size_t)size, file->fp)) { + if (size != fwrite(buf, 1, size, file->fp)) { file->op = H5FD_STDIO_OP_UNKNOWN; file->pos = HADDR_UNDEF; H5Epush_ret(func, H5E_IO, H5E_WRITEERROR, "fwrite failed", -1); diff --git a/src/H5FDstream.c b/src/H5FDstream.c index e734014..b0ee868 100644 --- a/src/H5FDstream.c +++ b/src/H5FDstream.c @@ -161,10 +161,10 @@ static herr_t H5FD_stream_set_eoa (H5FD_t *_stream, haddr_t addr); static haddr_t H5FD_stream_get_eof (H5FD_t *_stream); static herr_t H5FD_stream_read (H5FD_t *_stream, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, void *buf); + size_t size, void *buf); static herr_t H5FD_stream_write (H5FD_t *_stream, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - hsize_t size, const void *buf); + size_t size, const void *buf); /* The Stream VFD's class information structure */ static const H5FD_class_t H5FD_stream_g = @@ -1067,11 +1067,11 @@ static herr_t H5FD_stream_read (H5FD_t *_stream, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, - hsize_t size, + size_t size, void *buf /*out*/) { H5FD_stream_t *stream = (H5FD_stream_t *) _stream; - ssize_t nbytes; + size_t nbytes; FUNC_ENTER (H5FD_stream_read, FAIL); @@ -1095,8 +1095,8 @@ static herr_t H5FD_stream_read (H5FD_t *_stream, /* Read the part which is before the EOF marker */ if (addr < stream->eof) { - nbytes = (ssize_t) MIN (size, stream->eof - addr); - HDmemcpy (buf, stream->mem + addr, (size_t) nbytes); + nbytes = MIN (size, stream->eof - addr); + HDmemcpy (buf, stream->mem + addr, nbytes); size -= nbytes; addr += nbytes; buf = (char *) buf + nbytes; @@ -1105,7 +1105,7 @@ static herr_t H5FD_stream_read (H5FD_t *_stream, /* Read zeros for the part which is after the EOF markers */ if (size > 0) { - HDmemset (buf, 0, (size_t) size); + HDmemset (buf, 0, size); } FUNC_LEAVE (SUCCEED); @@ -1133,12 +1133,11 @@ static herr_t H5FD_stream_write (H5FD_t *_stream, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, - hsize_t size, + size_t size, const void *buf) { H5FD_stream_t *stream = (H5FD_stream_t *) _stream; - FUNC_ENTER (H5FD_stream_write, FAIL); assert (stream && stream->pub.cls); @@ -1189,7 +1188,7 @@ static herr_t H5FD_stream_write (H5FD_t *_stream, } /* Write from BUF to memory */ - HDmemcpy (stream->mem + addr, buf, (size_t) size); + HDmemcpy (stream->mem + addr, buf, size); stream->dirty = TRUE; FUNC_LEAVE (SUCCEED); diff --git a/src/H5Farray.c b/src/H5Farray.c index cde7359..c1922fa 100644 --- a/src/H5Farray.c +++ b/src/H5Farray.c @@ -316,12 +316,14 @@ H5F_arr_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, * file offsets, totally mixing up the data sieve buffer information. -QAK */ if (efl && efl->nused>0) { - if (H5O_efl_read(f, efl, addr, elmt_size, buf)<0) { + H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t); + if (H5O_efl_read(f, efl, addr, (size_t)elmt_size, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "external data read failed"); } } else { - if (H5F_contig_read(f, max_data, H5FD_MEM_DRAW, addr, elmt_size, dxpl_id, buf)<0) { + H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t); + if (H5F_contig_read(f, max_data, H5FD_MEM_DRAW, addr, (size_t)elmt_size, dxpl_id, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed"); } @@ -575,12 +577,14 @@ H5F_arr_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, /* Write to file */ if (efl && efl->nused>0) { - if (H5O_efl_write(f, efl, addr, elmt_size, buf)<0) { + H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t); + if (H5O_efl_write(f, efl, addr, (size_t)elmt_size, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "external data write failed"); } } else { - if (H5F_contig_write(f, max_data, H5FD_MEM_DRAW, addr, elmt_size, dxpl_id, buf)<0) { + H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t); + if (H5F_contig_write(f, max_data, H5FD_MEM_DRAW, addr, (size_t)elmt_size, dxpl_id, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed"); } diff --git a/src/H5Fcontig.c b/src/H5Fcontig.c index e08707e..8c3055f 100644 --- a/src/H5Fcontig.c +++ b/src/H5Fcontig.c @@ -39,82 +39,447 @@ static intn interface_initialize_g = 0; * Thursday, September 28, 2000 * * Modifications: + * Re-written in terms of the new readv call, QAK, 7/7/01 * *------------------------------------------------------------------------- */ herr_t -H5F_contig_read(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, hsize_t size, hid_t dxpl_id, - void *buf/*out*/) +H5F_contig_read(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, + size_t size, hid_t dxpl_id, void *buf/*out*/) { - haddr_t abs_eoa; /* Absolute end of file address */ - haddr_t rel_eoa; /* Relative end of file address */ + hsize_t offset=0; /* Offset for vector call */ FUNC_ENTER(H5F_contig_read, FAIL); /* Check args */ assert(f); - assert(size<SIZET_MAX); + assert(buf); + + if (H5F_contig_readv(f, max_data, type, addr, 1, &size, &offset, dxpl_id, buf)<0) + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "vector read failed"); + + FUNC_LEAVE(SUCCEED); +} /* end H5F_contig_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_contig_write + * + * Purpose: Writes some data from a dataset into a buffer. + * The data is contiguous. The address is relative to the base + * address for the file. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, September 28, 2000 + * + * Modifications: + * Re-written in terms of the new readv call, QAK, 7/7/01 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_contig_write(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, size_t size, + hid_t dxpl_id, const void *buf) +{ + hsize_t offset=0; /* Offset for vector call */ + + FUNC_ENTER(H5F_contig_write, FAIL); + + assert (f); + assert (buf); + + if (H5F_contig_writev(f, max_data, type, addr, 1, &size, &offset, dxpl_id, buf)<0) + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vector write failed"); + + FUNC_LEAVE(SUCCEED); +} /* end H5F_contig_write() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_contig_readv + * + * Purpose: Reads some data vectors from a dataset into a buffer. + * The data is contiguous. The address is the start of the dataset, + * relative to the base address for the file and the offsets and + * sequence lengths are in bytes. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Friday, May 3, 2001 + * + * Notes: + * Offsets in the sequences must be monotonically increasing + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_contig_readv(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr, + size_t nseq, size_t size_arr[], hsize_t offset_arr[], hid_t dxpl_id, + void *_buf/*out*/) +{ + unsigned char *buf=(unsigned char *)_buf; /* Pointer to buffer to fill */ + haddr_t abs_eoa; /* Absolute end of file address */ + haddr_t rel_eoa; /* Relative end of file address */ + haddr_t addr; /* Actual address to read */ + hsize_t max_data; /* Actual maximum size of data to cache */ + size_t size; /* Size of sequence in bytes */ + size_t u; /* Counting variable */ +#ifndef SLOW_WAY + size_t max_seq; /* Maximum sequence to copy */ + haddr_t temp_end; /* Temporary end of buffer variable */ + size_t max_search; /* Maximum number of sequences to search */ + size_t mask; /* Bit mask */ + intn bit_loc; /* Bit location of the leftmost '1' in max_search */ + size_t *size_arr_p; /* Pointer into the size array */ + hsize_t *offset_arr_p; /* Pointer into the offset array */ +#endif /* SLOW_WAY */ + + FUNC_ENTER(H5F_contig_readv, FAIL); + + /* Check args */ + assert(f); assert(buf); /* Check if data sieving is enabled */ if(f->shared->lf->feature_flags&H5FD_FEAT_DATA_SIEVE) { - /* Try reading from the data sieve buffer */ - if(f->shared->sieve_buf) { - haddr_t sieve_start, sieve_end; /* Start & end locations of sieve buffer */ - haddr_t contig_end; /* End locations of block to write */ - hsize_t sieve_size; /* size of sieve buffer */ - - /* Stash local copies of these value */ - sieve_start=f->shared->sieve_loc; - sieve_size=f->shared->sieve_size; - sieve_end=sieve_start+sieve_size; - contig_end=addr+size-1; - - /* If entire read is within the sieve buffer, read it from the buffer */ - if(addr>=sieve_start && contig_end<sieve_end) { - /* Grab the data out of the buffer */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(buf,f->shared->sieve_buf+(addr-sieve_start),(size_t)size); - } /* end if */ - /* Entire request is not within this data sieve buffer */ - else { - /* Check if we can actually hold the I/O request in the sieve buffer */ - if(size>f->shared->sieve_buf_size) { - /* Check for any overlap with the current sieve buffer */ - if((sieve_start>=addr && sieve_start<(contig_end+1)) - || ((sieve_end-1)>=addr && (sieve_end-1)<(contig_end+1))) { - /* Flush the sieve buffer, if it's dirty */ - if(f->shared->sieve_dirty) { - /* Write to file */ - if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "block write failed"); + + /* Outer loop, guarantees working through all the sequences */ + for(u=0; u<nseq; ) { + + /* Try reading from the data sieve buffer */ + if(f->shared->sieve_buf) { + haddr_t sieve_start, sieve_end; /* Start & end locations of sieve buffer */ + haddr_t contig_end; /* End locations of block to write */ + size_t sieve_size; /* size of sieve buffer */ + + /* Stash local copies of these value */ + sieve_start=f->shared->sieve_loc; + sieve_size=f->shared->sieve_size; + sieve_end=sieve_start+sieve_size; + + /* Next-outer loop works through sequences as fast as possible */ + for(; u<nseq; ) { + size=size_arr[u]; + addr=_addr+offset_arr[u]; + + /* Compute end of sequence to retrieve */ + contig_end=addr+size-1; + + /* If entire read is within the sieve buffer, read it from the buffer */ + if(addr>=sieve_start && contig_end<sieve_end) { + unsigned char *base_sieve_buf=f->shared->sieve_buf+(_addr-sieve_start); + unsigned char *temp_sieve_buf; + haddr_t temp_addr=_addr-1; /* Temporary address */ + +#ifdef SLOW_WAY + /* Retrieve all the sequences out of the current sieve buffer */ + while(contig_end<sieve_end) { + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+offset_arr[u]; + + /* Grab the data out of the buffer */ + HDmemcpy(buf,temp_sieve_buf,size_arr[u]); + + /* Increment offset in buffer */ + buf += size_arr[u]; + + /* Increment sequence number, check for finished with sequences */ + if((++u) >= nseq) + break; + + /* Re-compute end of sequence to retrieve */ + contig_end=temp_addr+offset_arr[u]+size_arr[u]; + } /* end while */ +#else /* SLOW_WAY */ + /* Find log2(n) where n is the number of elements to search */ + + /* Set initial parameters */ + mask=(size_t)0xff<<((sizeof(size_t)-1)*8); /* Get a mask for the leftmost byte */ + max_search=((nseq-1)-u)+1; /* Compute 'n' for the log2 */ + assert(max_search>0); /* Sanity check */ + bit_loc=(sizeof(size_t)*8)-1; /* Initial bit location */ + + /* Search for the first byte with a bit set */ + while((max_search & mask)==0) { + mask>>=8; + bit_loc-=8; + } /* end while */ + + /* Switch to searching for a bit */ + mask=1<<bit_loc; + while((max_search & mask)==0) { + mask>>=1; + bit_loc--; + } /* end while */ + + /* location of the leftmost bit, plus 1, is log2(n) */ + max_seq=bit_loc+1; + + /* Don't walk off the array */ + max_seq=MIN(u+max_seq,nseq-1); + + /* Determine if a linear search is faster than a binary search */ + temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq]; + if(temp_end>=sieve_end) { + /* Linear search is faster */ + + /* Set the initial search values */ + max_seq=u; + temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq]; + + /* Search for the first sequence ending greater than the sieve buffer end */ + while(temp_end<sieve_end) { + if(++max_seq>=nseq) + break; + temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq]; + } /* end while */ + + /* Adjust back one element */ + max_seq--; + + } /* end if */ + else { + size_t lo,hi; /* Low and high bounds for binary search */ + uintn found=0; /* Flag to indicate bounds have been found */ + + /* Binary search is faster */ + + /* Find the value 'u' which will be beyond the end of the sieve buffer */ + lo=u; + hi=nseq-1; + max_seq=(lo+hi)/2; + while(!found) { + /* Get the address of the end of sequence for the 'max_seq' position */ + temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq]; + + /* Current high bound is too large */ + if(temp_end>=sieve_end) { + if((lo+1)<hi) { + hi=max_seq; + max_seq=(lo+hi)/2; + } /* end if */ + else { + found=1; + } /* end else */ + } /* end if */ + /* Current low bound is too small */ + else { + if((lo+1)<hi) { + lo=max_seq; + max_seq=(lo+hi+1)/2; + } /* end if */ + else { + found=1; + } /* end else */ + } /* end else */ + } /* end while */ + + /* Check for non-exact match */ + if(lo!=hi) { + temp_end=temp_addr+offset_arr[hi]+size_arr[hi]; + if(temp_end<sieve_end) + max_seq=hi; + else + max_seq=lo; + } /* end if */ + } /* end else */ + + /* Set the pointers to the correct locations in the offset & size arrays */ + size_arr_p=&size_arr[u]; + offset_arr_p=&offset_arr[u]; + +#ifdef NO_DUFFS_DEVICE + /* Retrieve all the sequences out of the current sieve buffer */ + while(u<=max_seq) { + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(buf,temp_sieve_buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + } /* end while */ +#else /* NO_DUFFS_DEVICE */ +{ + size_t seq_count; + + seq_count=(max_seq-u)+1; + switch (seq_count % 4) { + case 0: + do + { + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(buf,temp_sieve_buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + + case 3: + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(buf,temp_sieve_buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + + case 2: + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(buf,temp_sieve_buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + + case 1: + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(buf,temp_sieve_buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + + } while (u<=max_seq); + } /* end switch */ + +} +#endif /* NO_DUFFS_DEVICE */ +#endif /* SLOW_WAY */ + } /* end if */ + /* Entire request is not within this data sieve buffer */ + else { + /* Check if we can actually hold the I/O request in the sieve buffer */ + if(size>f->shared->sieve_buf_size) { + /* Check for any overlap with the current sieve buffer */ + if((sieve_start>=addr && sieve_start<(contig_end+1)) + || ((sieve_end-1)>=addr && (sieve_end-1)<(contig_end+1))) { + /* Flush the sieve buffer, if it's dirty */ + if(f->shared->sieve_dirty) { + /* Write to file */ + if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "block write failed"); + } + + /* Reset sieve buffer dirty flag */ + f->shared->sieve_dirty=0; + } /* end if */ + } /* end if */ + + /* Read directly into the user's buffer */ + if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "block read failed"); + } + } /* end if */ + /* Element size fits within the buffer size */ + else { + /* Flush the sieve buffer if it's dirty */ + if(f->shared->sieve_dirty) { + /* Write to file */ + if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "block write failed"); + } + + /* Reset sieve buffer dirty flag */ + f->shared->sieve_dirty=0; + } /* end if */ + + /* Determine the new sieve buffer size & location */ + f->shared->sieve_loc=addr; + + /* Make certain we don't read off the end of the file */ + if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf))) { + HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, + "unable to determine file size"); + } + + /* Adjust absolute EOA address to relative EOA address */ + rel_eoa=abs_eoa-f->shared->base_addr; + + /* Only need this when resizing sieve buffer */ + max_data=_max_data-offset_arr[u]; + + /* Compute the size of the sieve buffer */ + /* Don't read off the end of the file, don't read past the end of the data element and don't read more than the buffer size */ + f->shared->sieve_size=MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)); + + /* Update local copies of sieve information */ + sieve_start=f->shared->sieve_loc; + sieve_size=f->shared->sieve_size; + sieve_end=sieve_start+sieve_size; + + /* Read the new sieve buffer */ + if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "block read failed"); } /* Reset sieve buffer dirty flag */ f->shared->sieve_dirty=0; - } /* end if */ - } /* end if */ - /* Read directly into the user's buffer */ + /* Grab the data out of the buffer (must be first piece of data in buffer ) */ + HDmemcpy(buf,f->shared->sieve_buf,size); + } /* end else */ + + /* Increment offset in buffer */ + buf += size_arr[u]; + + /* Increment sequence number */ + u++; + } /* end else */ + } /* end for */ + } /* end if */ + /* No data sieve buffer yet, go allocate one */ + else { + /* Set up the buffer parameters */ + size=size_arr[u]; + addr=_addr+offset_arr[u]; + max_data=_max_data-offset_arr[u]; + + /* Check if we can actually hold the I/O request in the sieve buffer */ + if(size>f->shared->sieve_buf_size) { if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed"); } } /* end if */ - /* Element size fits within the buffer size */ else { - /* Flush the sieve buffer if it's dirty */ - if(f->shared->sieve_dirty) { - /* Write to file */ - if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "block write failed"); - } - - /* Reset sieve buffer dirty flag */ - f->shared->sieve_dirty=0; - } /* end if */ + /* Allocate room for the data sieve buffer */ + if (NULL==(f->shared->sieve_buf=H5MM_malloc(f->shared->sieve_buf_size))) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed"); + } /* Determine the new sieve buffer size & location */ f->shared->sieve_loc=addr; @@ -129,7 +494,7 @@ H5F_contig_read(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, hsize rel_eoa=abs_eoa-f->shared->base_addr; /* Compute the size of the sieve buffer */ - f->shared->sieve_size=MIN(rel_eoa-addr,MIN(max_data,f->shared->sieve_buf_size)); + f->shared->sieve_size=MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)); /* Read the new sieve buffer */ if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) { @@ -141,288 +506,521 @@ H5F_contig_read(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, hsize f->shared->sieve_dirty=0; /* Grab the data out of the buffer (must be first piece of data in buffer ) */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(buf,f->shared->sieve_buf,(size_t)size); + HDmemcpy(buf,f->shared->sieve_buf,size); } /* end else */ + + /* Increment offset in buffer */ + buf += size_arr[u]; + + /* Increment sequence number */ + u++; } /* end else */ - } /* end if */ - /* No data sieve buffer yet, go allocate one */ - else { - /* Check if we can actually hold the I/O request in the sieve buffer */ - if(size>f->shared->sieve_buf_size) { - if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "block read failed"); - } - } /* end if */ - else { - /* Allocate room for the data sieve buffer */ - assert(f->shared->sieve_buf_size==(hsize_t)((size_t)f->shared->sieve_buf_size)); /*check for overflow*/ - if (NULL==(f->shared->sieve_buf=H5MM_malloc((size_t)f->shared->sieve_buf_size))) { - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); - } - - /* Determine the new sieve buffer size & location */ - f->shared->sieve_loc=addr; - - /* Make certain we don't read off the end of the file */ - if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf))) { - HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "unable to determine file size"); - } - - /* Adjust absolute EOA address to relative EOA address */ - rel_eoa=abs_eoa-f->shared->base_addr; - - /* Compute the size of the sieve buffer */ - f->shared->sieve_size=MIN(rel_eoa-addr,MIN(max_data,f->shared->sieve_buf_size)); - - /* Read the new sieve buffer */ - if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "block read failed"); - } - - /* Reset sieve buffer dirty flag */ - f->shared->sieve_dirty=0; - - /* Grab the data out of the buffer (must be first piece of data in buffer ) */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(buf,f->shared->sieve_buf,(size_t)size); - } /* end else */ - } /* end else */ + } /* end for */ } /* end if */ else { - if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "block read failed"); - } + /* Work through all the sequences */ + for(u=0; u<nseq; u++) { + size=size_arr[u]; + addr=_addr+offset_arr[u]; + + if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "block read failed"); + } + + /* Increment offset in buffer */ + buf += size_arr[u]; + } /* end for */ } /* end else */ FUNC_LEAVE(SUCCEED); -} /* End H5F_contig_read() */ +} /* end H5F_contig_readv() */ /*------------------------------------------------------------------------- - * Function: H5F_contig_write + * Function: H5F_contig_writev * - * Purpose: Writes some data from a dataset into a buffer. - * The data is contiguous. The address is relative to the base - * address for the file. + * Purpose: Writes some data vectors into a dataset from a buffer. + * The data is contiguous. The address is the start of the dataset, + * relative to the base address for the file and the offsets and + * sequence lengths are in bytes. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * Thursday, September 28, 2000 + * Thursday, July 5, 2001 + * + * Notes: + * Offsets in the sequences must be monotonically increasing * * Modifications: * *------------------------------------------------------------------------- */ herr_t -H5F_contig_write(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, hsize_t size, - hid_t dxpl_id, const void *buf) +H5F_contig_writev(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr, + size_t nseq, size_t size_arr[], hsize_t offset_arr[], hid_t dxpl_id, + const void *_buf) { - haddr_t abs_eoa; /* Absolute end of file address */ - haddr_t rel_eoa; /* Relative end of file address */ - - FUNC_ENTER(H5F_contig_write, FAIL); + const unsigned char *buf=_buf; /* Pointer to buffer to fill */ + haddr_t abs_eoa; /* Absolute end of file address */ + haddr_t rel_eoa; /* Relative end of file address */ + haddr_t addr; /* Actual address to read */ + hsize_t max_data; /* Actual maximum size of data to cache */ + size_t size; /* Size of sequence in bytes */ + size_t u; /* Counting variable */ +#ifndef SLOW_WAY + size_t max_seq; /* Maximum sequence to copy */ + haddr_t temp_end; /* Temporary end of buffer variable */ + size_t max_search; /* Maximum number of sequences to search */ + size_t mask; /* Bit mask */ + intn bit_loc; /* Bit location of the leftmost '1' in max_search */ + size_t *size_arr_p; /* Pointer into the size array */ + hsize_t *offset_arr_p; /* Pointer into the offset array */ +#endif /* SLOW_WAY */ + + FUNC_ENTER(H5F_contig_writev, FAIL); - assert (f); - assert (size<SIZET_MAX); - assert (buf); + /* Check args */ + assert(f); + assert(buf); /* Check if data sieving is enabled */ if(f->shared->lf->feature_flags&H5FD_FEAT_DATA_SIEVE) { - /* Try writing to the data sieve buffer */ - if(f->shared->sieve_buf) { - haddr_t sieve_start, sieve_end; /* Start & end locations of sieve buffer */ - haddr_t contig_end; /* End locations of block to write */ - hsize_t sieve_size; /* size of sieve buffer */ - - /* Stash local copies of these value */ - sieve_start=f->shared->sieve_loc; - sieve_size=f->shared->sieve_size; - sieve_end=sieve_start+sieve_size; - contig_end=addr+size-1; - - /* If entire write is within the sieve buffer, write it to the buffer */ - if(addr>=sieve_start && contig_end<sieve_end) { - /* Grab the data out of the buffer */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(f->shared->sieve_buf+(addr-sieve_start),buf,(size_t)size); - - /* Set sieve buffer dirty flag */ - f->shared->sieve_dirty=1; - } /* end if */ - /* Entire request is not within this data sieve buffer */ - else { - /* Check if we can actually hold the I/O request in the sieve buffer */ - if(size>f->shared->sieve_buf_size) { - /* Check for any overlap with the current sieve buffer */ - if((sieve_start>=addr && sieve_start<(contig_end+1)) - || ((sieve_end-1)>=addr && (sieve_end-1)<(contig_end+1))) { - /* Flush the sieve buffer, if it's dirty */ - if(f->shared->sieve_dirty) { - /* Write to file */ - if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "block write failed"); - } + /* Outer loop, guarantees working through all the sequences */ + for(u=0; u<nseq; ) { - /* Reset sieve buffer dirty flag */ - f->shared->sieve_dirty=0; - } /* end if */ + /* Try writing into the data sieve buffer */ + if(f->shared->sieve_buf) { + haddr_t sieve_start, sieve_end; /* Start & end locations of sieve buffer */ + haddr_t contig_end; /* End locations of block to write */ + size_t sieve_size; /* size of sieve buffer */ - /* Force the sieve buffer to be re-read the next time */ - f->shared->sieve_loc=HADDR_UNDEF; - f->shared->sieve_size=0; - } /* end if */ + /* Stash local copies of these value */ + sieve_start=f->shared->sieve_loc; + sieve_size=f->shared->sieve_size; + sieve_end=sieve_start+sieve_size; + + /* Next-outer loop works through sequences as fast as possible */ + for(; u<nseq; ) { + size=size_arr[u]; + addr=_addr+offset_arr[u]; + + /* Compute end of sequence to retrieve */ + contig_end=addr+size-1; + + /* If entire write is within the sieve buffer, write it to the buffer */ + if(addr>=sieve_start && contig_end<sieve_end) { + unsigned char *base_sieve_buf=f->shared->sieve_buf+(_addr-sieve_start); + unsigned char *temp_sieve_buf; + haddr_t temp_addr=_addr-1; /* Temporary address */ + +#ifdef SLOW_WAY + /* Retrieve all the sequences out of the current sieve buffer */ + while(contig_end<sieve_end) { + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+offset_arr[u]; + + /* Grab the data out of the buffer */ + HDmemcpy(temp_sieve_buf,buf,size_arr[u]); + + /* Increment offset in buffer */ + buf += size_arr[u]; + + /* Increment sequence number, check for finished with sequences */ + if((++u) >= nseq) + break; + + /* Re-compute end of sequence to retrieve */ + contig_end=temp_addr+offset_arr[u]+size_arr[u]; + } /* end while */ +#else /* SLOW_WAY */ + /* Find log2(n) where n is the number of elements to search */ + + /* Set initial parameters */ + mask=(size_t)0xff<<((sizeof(size_t)-1)*8); /* Get a mask for the leftmost byte */ + max_search=((nseq-1)-u)+1; /* Compute 'n' for the log2 */ + assert(max_search>0); /* Sanity check */ + bit_loc=(sizeof(size_t)*8)-1; /* Initial bit location */ + + /* Search for the first byte with a bit set */ + while((max_search & mask)==0) { + mask>>=8; + bit_loc-=8; + } /* end while */ + + /* Switch to searching for a bit */ + mask=1<<bit_loc; + while((max_search & mask)==0) { + mask>>=1; + bit_loc--; + } /* end while */ + + /* location of the leftmost bit, plus 1, is log2(n) */ + max_seq=bit_loc+1; + + /* Don't walk off the array */ + max_seq=MIN(u+max_seq,nseq-1); + + /* Determine if a linear search is faster than a binary search */ + temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq]; + if(temp_end>=sieve_end) { + /* Linear search is faster */ + + /* Set the initial search values */ + max_seq=u; + temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq]; + + /* Search for the first sequence ending greater than the sieve buffer end */ + while(temp_end<sieve_end) { + if(++max_seq>=nseq) + break; + temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq]; + } /* end while */ + + /* Adjust back one element */ + max_seq--; - /* Write directly to the user's buffer */ - if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "block write failed"); - } /* end if */ - } /* end if */ - /* Element size fits within the buffer size */ - else { - /* Check if it is possible to (exactly) prepend or append to existing (dirty) sieve buffer */ - if(((addr+size)==sieve_start || addr==sieve_end) && - (size+sieve_size)<=f->shared->sieve_buf_size && - f->shared->sieve_dirty) { - /* Prepend to existing sieve buffer */ - if((addr+size)==sieve_start) { - /* Move existing sieve information to correct location */ - assert(sieve_size==(hsize_t)((size_t)sieve_size)); /*check for overflow*/ - HDmemmove(f->shared->sieve_buf+size,f->shared->sieve_buf,(size_t)sieve_size); - - /* Copy in new information (must be first in sieve buffer) */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(f->shared->sieve_buf,buf,(size_t)size); - - /* Adjust sieve location */ - f->shared->sieve_loc=addr; - } /* end if */ - /* Append to existing sieve buffer */ else { - /* Copy in new information */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(f->shared->sieve_buf+sieve_size,buf,(size_t)size); + size_t lo,hi; /* Low and high bounds for binary search */ + uintn found=0; /* Flag to indicate bounds have been found */ + + /* Binary search is faster */ + + /* Find the value 'u' which will be beyond the end of the sieve buffer */ + lo=u; + hi=nseq-1; + max_seq=(lo+hi)/2; + while(!found) { + /* Get the address of the end of sequence for the 'max_seq' position */ + temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq]; + + /* Current high bound is too large */ + if(temp_end>=sieve_end) { + if((lo+1)<hi) { + hi=max_seq; + max_seq=(lo+hi)/2; + } /* end if */ + else { + found=1; + } /* end else */ + } /* end if */ + /* Current low bound is too small */ + else { + if((lo+1)<hi) { + lo=max_seq; + max_seq=(lo+hi+1)/2; + } /* end if */ + else { + found=1; + } /* end else */ + } /* end else */ + } /* end while */ + + /* Check for non-exact match */ + if(lo!=hi) { + temp_end=temp_addr+offset_arr[hi]+size_arr[hi]; + if(temp_end<sieve_end) + max_seq=hi; + else + max_seq=lo; + } /* end if */ } /* end else */ - /* Adjust sieve size */ - f->shared->sieve_size += size; - + /* Set the pointers to the correct locations in the offset & size arrays */ + size_arr_p=&size_arr[u]; + offset_arr_p=&offset_arr[u]; + +#ifdef NO_DUFFS_DEVICE + /* Retrieve all the sequences out of the current sieve buffer */ + while(u<=max_seq) { + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(temp_sieve_buf,buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + } /* end while */ +#else /* NO_DUFFS_DEVICE */ +{ + size_t seq_count; + + seq_count=(max_seq-u)+1; + switch (seq_count % 4) { + case 0: + do + { + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(temp_sieve_buf,buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + + case 3: + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(temp_sieve_buf,buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + + case 2: + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(temp_sieve_buf,buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + + case 1: + /* Set the location within the sieve buffer to the correct offset */ + temp_sieve_buf=base_sieve_buf+*offset_arr_p++; + + /* Grab the data out of the buffer */ + HDmemcpy(temp_sieve_buf,buf,*size_arr_p); + + /* Increment offset in buffer */ + buf += *size_arr_p++; + + /* Increment the offset in the array */ + u++; + + } while (u<=max_seq); + } /* end switch */ + +} +#endif /* NO_DUFFS_DEVICE */ +#endif /* SLOW_WAY */ + /* Set sieve buffer dirty flag */ + f->shared->sieve_dirty=1; + } /* end if */ - /* Can't add the new data onto the existing sieve buffer */ + /* Entire request is not within this data sieve buffer */ else { - /* Flush the sieve buffer if it's dirty */ - if(f->shared->sieve_dirty) { - /* Write to file */ - if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "block write failed"); - } /* end if */ + /* Check if we can actually hold the I/O request in the sieve buffer */ + if(size>f->shared->sieve_buf_size) { + /* Check for any overlap with the current sieve buffer */ + if((sieve_start>=addr && sieve_start<(contig_end+1)) + || ((sieve_end-1)>=addr && (sieve_end-1)<(contig_end+1))) { + /* Flush the sieve buffer, if it's dirty */ + if(f->shared->sieve_dirty) { + /* Write to file */ + if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "block write failed"); + } - /* Reset sieve buffer dirty flag */ - f->shared->sieve_dirty=0; - } /* end if */ + /* Reset sieve buffer dirty flag */ + f->shared->sieve_dirty=0; + } /* end if */ - /* Determine the new sieve buffer size & location */ - f->shared->sieve_loc=addr; + /* Force the sieve buffer to be re-read the next time */ + f->shared->sieve_loc=HADDR_UNDEF; + f->shared->sieve_size=0; + } /* end if */ - /* Make certain we don't read off the end of the file */ - if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf))) { - HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "unable to determine file size"); + /* Write directly from the user's buffer */ + if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "block write failed"); + } } /* end if */ + /* Element size fits within the buffer size */ + else { + /* Check if it is possible to (exactly) prepend or append to existing (dirty) sieve buffer */ + if(((addr+size)==sieve_start || addr==sieve_end) && + (size+sieve_size)<=f->shared->sieve_buf_size && + f->shared->sieve_dirty) { + /* Prepend to existing sieve buffer */ + if((addr+size)==sieve_start) { + /* Move existing sieve information to correct location */ + HDmemmove(f->shared->sieve_buf+size,f->shared->sieve_buf,sieve_size); - /* Adjust absolute EOA address to relative EOA address */ - rel_eoa=abs_eoa-f->shared->base_addr; + /* Copy in new information (must be first in sieve buffer) */ + HDmemcpy(f->shared->sieve_buf,buf,size); - /* Compute the size of the sieve buffer */ - f->shared->sieve_size=MIN(rel_eoa-addr,MIN(max_data,f->shared->sieve_buf_size)); + /* Adjust sieve location */ + f->shared->sieve_loc=addr; + + } /* end if */ + /* Append to existing sieve buffer */ + else { + /* Copy in new information */ + HDmemcpy(f->shared->sieve_buf+sieve_size,buf,size); + } /* end else */ + + /* Adjust sieve size */ + f->shared->sieve_size += size; + + /* Update local copies of sieve information */ + sieve_start=f->shared->sieve_loc; + sieve_size=f->shared->sieve_size; + sieve_end=sieve_start+sieve_size; - /* Check if there is any point in reading the data from the file */ - if(f->shared->sieve_size>size) { - /* Read the new sieve buffer */ - if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "block read failed"); } /* end if */ - } /* end if */ + /* Can't add the new data onto the existing sieve buffer */ + else { + /* Flush the sieve buffer if it's dirty */ + if(f->shared->sieve_dirty) { + /* Write to file */ + if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "block write failed"); + } - /* Grab the data out of the buffer (must be first piece of data in buffer) */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(f->shared->sieve_buf,buf,(size_t)size); + /* Reset sieve buffer dirty flag */ + f->shared->sieve_dirty=0; + } /* end if */ - /* Set sieve buffer dirty flag */ - f->shared->sieve_dirty=1; + /* Determine the new sieve buffer size & location */ + f->shared->sieve_loc=addr; + /* Make certain we don't read off the end of the file */ + if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf))) { + HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, + "unable to determine file size"); + } + + /* Adjust absolute EOA address to relative EOA address */ + rel_eoa=abs_eoa-f->shared->base_addr; + + /* Only need this when resizing sieve buffer */ + max_data=_max_data-offset_arr[u]; + + /* Compute the size of the sieve buffer */ + /* Don't read off the end of the file, don't read past the end of the data element and don't read more than the buffer size */ + f->shared->sieve_size=MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)); + + /* Update local copies of sieve information */ + sieve_start=f->shared->sieve_loc; + sieve_size=f->shared->sieve_size; + sieve_end=sieve_start+sieve_size; + + /* Check if there is any point in reading the data from the file */ + if(f->shared->sieve_size>size) { + /* Read the new sieve buffer */ + if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "block read failed"); + } /* end if */ + } /* end if */ + + /* Grab the data out of the buffer (must be first piece of data in buffer ) */ + HDmemcpy(f->shared->sieve_buf,buf,size); + + /* Set sieve buffer dirty flag */ + f->shared->sieve_dirty=1; + + } /* end else */ + } /* end else */ + + /* Increment offset in buffer */ + buf += size_arr[u]; + + /* Increment sequence number */ + u++; } /* end else */ - } /* end else */ - } /* end else */ - } /* end if */ - /* No data sieve buffer yet, go allocate one */ - else { - /* Check if we can actually hold the I/O request in the sieve buffer */ - if(size>f->shared->sieve_buf_size) { - if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "block write failed"); - } + } /* end for */ } /* end if */ + /* No data sieve buffer yet, go allocate one */ else { - /* Allocate room for the data sieve buffer */ - assert(f->shared->sieve_buf_size==(hsize_t)((size_t)f->shared->sieve_buf_size)); /*check for overflow*/ - if (NULL==(f->shared->sieve_buf=H5MM_malloc((size_t)f->shared->sieve_buf_size))) { - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); + /* Set up the buffer parameters */ + size=size_arr[u]; + addr=_addr+offset_arr[u]; + max_data=_max_data-offset_arr[u]; + + /* Check if we can actually hold the I/O request in the sieve buffer */ + if(size>f->shared->sieve_buf_size) { + if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "block write failed"); + } } /* end if */ + else { + /* Allocate room for the data sieve buffer */ + if (NULL==(f->shared->sieve_buf=H5MM_malloc(f->shared->sieve_buf_size))) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed"); + } - /* Determine the new sieve buffer size & location */ - f->shared->sieve_loc=addr; + /* Determine the new sieve buffer size & location */ + f->shared->sieve_loc=addr; - /* Make certain we don't read off the end of the file */ - if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf))) { - HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "unable to determine file size"); - } /* end if */ + /* Make certain we don't read off the end of the file */ + if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf))) { + HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, + "unable to determine file size"); + } - /* Adjust absolute EOA address to relative EOA address */ - rel_eoa=abs_eoa-f->shared->base_addr; + /* Adjust absolute EOA address to relative EOA address */ + rel_eoa=abs_eoa-f->shared->base_addr; - /* Compute the size of the sieve buffer */ - f->shared->sieve_size=MIN(rel_eoa-addr,MIN(max_data,f->shared->sieve_buf_size)); + /* Compute the size of the sieve buffer */ + f->shared->sieve_size=MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)); - /* Check if there is any point in reading the data from the file */ - if(f->shared->sieve_size>size) { - /* Read the new sieve buffer */ - if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "block read failed"); + /* Check if there is any point in reading the data from the file */ + if(f->shared->sieve_size>size) { + /* Read the new sieve buffer */ + if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "block read failed"); + } /* end if */ } /* end if */ - } /* end if */ - /* Grab the data out of the buffer (must be first piece of data in buffer) */ - assert(size==(hsize_t)((size_t)size)); /*check for overflow*/ - HDmemcpy(f->shared->sieve_buf,buf,(size_t)size); + /* Grab the data out of the buffer (must be first piece of data in buffer ) */ + HDmemcpy(f->shared->sieve_buf,buf,size); + + /* Set sieve buffer dirty flag */ + f->shared->sieve_dirty=1; + } /* end else */ - /* Set sieve buffer dirty flag */ - f->shared->sieve_dirty=1; + /* Increment offset in buffer */ + buf += size_arr[u]; + + /* Increment sequence number */ + u++; } /* end else */ - } /* end else */ + } /* end for */ } /* end if */ else { - if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "block write failed"); - } /* end if */ + /* Work through all the sequences */ + for(u=0; u<nseq; u++) { + size=size_arr[u]; + addr=_addr+offset_arr[u]; + + if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "block write failed"); + } + + /* Increment offset in buffer */ + buf += size_arr[u]; + } /* end for */ } /* end else */ FUNC_LEAVE(SUCCEED); -} /* End H5F_contig_write() */ +} /* end H5F_contig_writev() */ + diff --git a/src/H5Fistore.c b/src/H5Fistore.c index 95e4f46..d37c474 100644 --- a/src/H5Fistore.c +++ b/src/H5Fistore.c @@ -96,7 +96,7 @@ typedef struct H5F_rdcc_ent_t { size_t chunk_size; /*size of a chunk */ size_t alloc_size; /*amount allocated for the chunk */ uint8_t *chunk; /*the unfiltered chunk data */ - intn idx; /*index in hash table */ + uintn idx; /*index in hash table */ struct H5F_rdcc_ent_t *next;/*next item in doubly-linked list */ struct H5F_rdcc_ent_t *prev;/*previous item in doubly-linked list */ } H5F_rdcc_ent_t; @@ -906,7 +906,6 @@ H5F_istore_init (H5F_t *f) HDmemset (rdcc, 0, sizeof(H5F_rdcc_t)); if (f->shared->rdcc_nbytes>0 && f->shared->rdcc_nelmts>0) { rdcc->nslots = f->shared->rdcc_nelmts; - assert(rdcc->nslots>=0); rdcc->slot = H5FL_ARR_ALLOC (H5F_rdcc_ent_ptr_t,rdcc->nslots,1); if (NULL==rdcc->slot) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, @@ -1002,7 +1001,7 @@ H5F_istore_flush_entry(H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to allocate chunk"); } - if (H5F_block_write(f, H5FD_MEM_DRAW, udata.addr, (hsize_t)udata.key.nbytes, H5P_DEFAULT, + if (H5F_block_write(f, H5FD_MEM_DRAW, udata.addr, udata.key.nbytes, H5P_DEFAULT, buf)<0) { HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file"); @@ -1070,7 +1069,7 @@ H5F_istore_preempt (H5F_t *f, H5F_rdcc_ent_t *ent) assert(f); assert(ent); assert(!ent->locked); - assert(ent->idx>=0 && ent->idx<rdcc->nslots); + assert(ent->idx<rdcc->nslots); /* Flush */ if (H5F_istore_flush_entry(f, ent, TRUE)<0) { @@ -1093,7 +1092,7 @@ H5F_istore_preempt (H5F_t *f, H5F_rdcc_ent_t *ent) /* Remove from cache */ rdcc->slot[ent->idx] = NULL; - ent->idx = -1; + ent->idx = UINT_MAX; rdcc->nbytes -= ent->chunk_size; --rdcc->nused; @@ -1335,7 +1334,7 @@ static void * H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, const H5O_pline_t *pline, const H5O_fill_t *fill, const hssize_t offset[], hbool_t relax, - intn *idx_hint/*in,out*/) + uintn *idx_hint/*in,out*/) { intn idx=0; /*hash index number */ uintn temp_idx=0; /* temporary index number */ @@ -1422,7 +1421,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, /* * The chunk exists on disk. */ - if (H5F_block_read(f, H5FD_MEM_DRAW, udata.addr, (hsize_t)udata.key.nbytes, H5P_DEFAULT, + if (H5F_block_read(f, H5FD_MEM_DRAW, udata.addr, udata.key.nbytes, H5P_DEFAULT, chunk)<0) { HGOTO_ERROR (H5E_IO, H5E_READERROR, NULL, "unable to read raw data chunk"); @@ -1535,7 +1534,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, * unlock function. */ ent = NULL; - idx = INT_MIN; + idx = UINT_MAX; } else if (found) { /* @@ -1608,7 +1607,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, static herr_t H5F_istore_unlock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, const H5O_pline_t *pline, hbool_t dirty, - const hssize_t offset[], intn *idx_hint, + const hssize_t offset[], uintn *idx_hint, uint8_t *chunk, size_t naccessed) { H5F_rdcc_t *rdcc = &(f->shared->rdcc); @@ -1618,10 +1617,10 @@ H5F_istore_unlock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, FUNC_ENTER (H5F_istore_unlock, FAIL); - if (INT_MIN==*idx_hint) { + if (UINT_MAX==*idx_hint) { /*not in cache*/ } else { - assert(*idx_hint>=0 && *idx_hint<rdcc->nslots); + assert(*idx_hint<rdcc->nslots); assert(rdcc->slot[*idx_hint]); assert(rdcc->slot[*idx_hint]->chunk==chunk); found = *idx_hint; @@ -1714,7 +1713,7 @@ H5F_istore_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, uintn u; size_t naccessed; /*bytes accessed in chnk*/ uint8_t *chunk=NULL; /*ptr to a chunk buffer */ - intn idx_hint=0; /*cache index hint */ + uintn idx_hint=0; /*cache index hint */ FUNC_ENTER(H5F_istore_read, FAIL); @@ -1886,7 +1885,7 @@ H5F_istore_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, hssize_t offset_wrt_chunk[H5O_LAYOUT_NDIMS]; hssize_t sub_offset_m[H5O_LAYOUT_NDIMS]; uint8_t *chunk=NULL; - intn idx_hint=0; + uintn idx_hint=0; size_t chunk_size, naccessed; FUNC_ENTER(H5F_istore_write, FAIL); @@ -2333,7 +2332,7 @@ H5F_istore_allocate(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, uintn u; hssize_t chunk_offset[H5O_LAYOUT_NDIMS]; uint8_t *chunk=NULL; - intn idx_hint=0; + uintn idx_hint=0; size_t chunk_size; #ifdef AKC H5F_istore_ud1_t udata; diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 763a592..ebb667c 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -69,7 +69,7 @@ typedef struct H5F_rdcc_t { uintn nmisses;/* Number of cache misses */ uintn nflushes;/* Number of cache flushes */ size_t nbytes; /* Current cached raw data in bytes */ - intn nslots; /* Number of chunk slots allocated */ + size_t nslots; /* Number of chunk slots allocated */ struct H5F_rdcc_ent_t *head; /* Head of doubly linked list */ struct H5F_rdcc_ent_t *tail; /* Tail of doubly linked list */ intn nused; /* Number of chunk slots in use */ @@ -100,7 +100,7 @@ typedef struct H5F_file_t { /* a H5F_create_t until we pass it back to */ /* H5P_close to release it - QAK */ intn mdc_nelmts; /* Size of meta data cache (elements) */ - intn rdcc_nelmts; /* Size of raw data chunk cache (elmts) */ + size_t rdcc_nelmts; /* Size of raw data chunk cache (elmts) */ size_t rdcc_nbytes; /* Size of raw data chunk cache (bytes) */ double rdcc_w0; /* Preempt read chunks first? [0.0..1.0]*/ hsize_t threshold; /* Threshold for alignment */ @@ -111,11 +111,11 @@ typedef struct H5F_file_t { struct H5HG_heap_t **cwfs; /* Global heap cache */ /* Data Sieve Buffering fields */ - unsigned char *sieve_buf; /* Buffer to hold data sieve buffer */ - haddr_t sieve_loc; /* File location (offset) of the data sieve buffer */ - hsize_t sieve_size; /* Size of the data sieve buffer used (in bytes) */ - hsize_t sieve_buf_size; /* Size of the data sieve buffer allocated (in bytes) */ - unsigned sieve_dirty; /* Flag to indicate that the data sieve buffer is dirty */ + unsigned char *sieve_buf; /* Buffer to hold data sieve buffer */ + haddr_t sieve_loc; /* File location (offset) of the data sieve buffer */ + size_t sieve_size; /* Size of the data sieve buffer used (in bytes) */ + size_t sieve_buf_size; /* Size of the data sieve buffer allocated (in bytes) */ + unsigned sieve_dirty; /* Flag to indicate that the data sieve buffer is dirty */ H5F_rdcc_t rdcc; /* Raw data chunk cache */ } H5F_file_t; @@ -199,10 +199,16 @@ __DLL__ herr_t H5F_istore_allocate (H5F_t *f, hid_t dxpl_id, const struct H5O_fill_t *fill); /* Functions that operate on contiguous storage wrt boot block */ -__DLL__ herr_t H5F_contig_read(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, hsize_t size, - hid_t dxpl_id, void *_buf/*out*/); +__DLL__ herr_t H5F_contig_read(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, + size_t size, hid_t dxpl_id, void *_buf/*out*/); __DLL__ herr_t H5F_contig_write(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, - hsize_t size, hid_t dxpl_id, const void *buf); + size_t size, hid_t dxpl_id, const void *buf); + +/* Functions that operate on contiguous storage wrt boot block */ +__DLL__ herr_t H5F_contig_readv(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, + size_t nseq, size_t size[], hsize_t offset[], hid_t dxpl_id, void *_buf/*out*/); +__DLL__ herr_t H5F_contig_writev(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, + size_t nseq, size_t size[], hsize_t offset[], hid_t dxpl_id, const void *buf); #endif diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index e442b37..7d618996 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -274,13 +274,13 @@ typedef struct H5F_create_t { */ typedef struct H5F_access_t { intn mdc_nelmts; /* Size of meta data cache (elements) */ - intn rdcc_nelmts; /* Size of raw data chunk cache (elmts) */ + size_t rdcc_nelmts; /* Size of raw data chunk cache (elmts) */ size_t rdcc_nbytes; /* Size of raw data chunk cache (bytes) */ double rdcc_w0; /* Preempt read chunks first? [0.0..1.0]*/ hsize_t threshold; /* Threshold for alignment */ hsize_t alignment; /* Alignment */ size_t meta_block_size; /* Minimum metadata allocation block size (when aggregating metadata allocations) */ - hsize_t sieve_buf_size; /* Maximum sieve buffer size (when data sieving is allowed by file driver) */ + size_t sieve_buf_size; /* Maximum sieve buffer size (when data sieving is allowed by file driver) */ uintn gc_ref; /* Garbage-collect references? */ hid_t driver_id; /* File driver ID */ void *driver_info; /* File driver specific information */ @@ -332,23 +332,35 @@ __DLL__ herr_t H5F_arr_write (H5F_t *f, hid_t dxpl_id, const hssize_t file_offset[], const void *_buf); /* Functions that operate on blocks of bytes wrt boot block */ -__DLL__ herr_t H5F_block_read(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, - hid_t dxpl_id, void *buf/*out*/); +__DLL__ herr_t H5F_block_read(H5F_t *f, H5FD_mem_t type, haddr_t addr, + size_t size, hid_t dxpl_id, void *buf/*out*/); __DLL__ herr_t H5F_block_write(H5F_t *f, H5FD_mem_t type, haddr_t addr, - hsize_t size, hid_t dxpl_id, const void *buf); + size_t size, hid_t dxpl_id, const void *buf); /* Functions that operate on byte sequences */ __DLL__ herr_t H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, - const struct H5S_t *file_space, size_t elmt_size, hsize_t seq_len, + const struct H5S_t *file_space, size_t elmt_size, size_t seq_len, hsize_t file_offset, void *_buf/*out*/); __DLL__ herr_t H5F_seq_write (H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, - const struct H5S_t *file_space, size_t elmt_size, hsize_t seq_len, + const struct H5S_t *file_space, size_t elmt_size, size_t seq_len, hsize_t file_offset, const void *_buf); +/* Functions that operate on vectors of byte sequences */ +__DLL__ herr_t H5F_seq_readv(H5F_t *f, hid_t dxpl_id, + const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, + const struct H5S_t *file_space, size_t elmt_size, size_t nseq, + size_t seq_len[], hsize_t file_offset[], void *_buf/*out*/); +__DLL__ herr_t H5F_seq_writev(H5F_t *f, hid_t dxpl_id, + const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, + const struct H5S_t *file_space, size_t elmt_size, size_t nseq, + size_t seq_len[], hsize_t file_offset[], const void *_buf); + /* Functions that operate on indexed storage */ __DLL__ hsize_t H5F_istore_allocated(H5F_t *f, uintn ndims, haddr_t addr); diff --git a/src/H5Fseq.c b/src/H5Fseq.c index 3868202..1c05dcf 100644 --- a/src/H5Fseq.c +++ b/src/H5Fseq.c @@ -52,6 +52,7 @@ static intn interface_initialize_g = 0; * Thursday, September 28, 2000 * * Modifications: + * Re-written to use new vector I/O call - QAK, 7/7/01 * *------------------------------------------------------------------------- */ @@ -59,28 +60,118 @@ herr_t H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const H5O_fill_t *fill, const struct H5O_efl_t *efl, const H5S_t *file_space, size_t elmt_size, - hsize_t seq_len, hsize_t file_offset, void *buf/*out*/) + size_t seq_len, hsize_t file_offset, void *buf/*out*/) { + FUNC_ENTER(H5F_seq_read, FAIL); + + /* Check args */ + assert(f); + assert(layout); + assert(buf); + + if (H5F_seq_readv(f, dxpl_id, layout, pline, fill, efl, file_space, elmt_size, 1, &seq_len, &file_offset, buf)<0) + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "vector read failed"); + + FUNC_LEAVE(SUCCEED); +} /* H5F_seq_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_seq_write + * + * Purpose: Writes a sequence of bytes to a file dataset from a buffer in + * in memory. The data is written to file F and the array's size and + * storage information is in LAYOUT. External files are described + * according to the external file list, EFL. The sequence offset is + * FILE_OFFSET in the file (offsets are + * in terms of bytes) and the size of the hyperslab is SEQ_LEN. The + * total size of the file array is implied in the LAYOUT argument. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, October 9, 2000 + * + * Modifications: + * Re-written to use new vector I/O routine - QAK, 7/7/01 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, + const struct H5O_pline_t *pline, const H5O_fill_t *fill, + const struct H5O_efl_t *efl, const H5S_t *file_space, size_t elmt_size, + size_t seq_len, hsize_t file_offset, const void *buf) +{ + FUNC_ENTER(H5F_seq_write, FAIL); + + /* Check args */ + assert(f); + assert(layout); + assert(buf); + + if (H5F_seq_writev(f, dxpl_id, layout, pline, fill, efl, file_space, elmt_size, 1, &seq_len, &file_offset, buf)<0) + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vector write failed"); + + FUNC_LEAVE(SUCCEED); +} /* H5F_seq_write() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_seq_readv + * + * Purpose: Reads in a vector of byte sequences from a file dataset into a + * buffer in in memory. The data is read from file F and the array's size + * and storage information is in LAYOUT. External files are described + * according to the external file list, EFL. The vector of byte sequences + * offsets is in the FILE_OFFSET array into the dataset (offsets are in + * terms of bytes) and the size of each sequence is in the SEQ_LEN array. + * The total size of the file array is implied in the LAYOUT argument. + * Bytes read into BUF are sequentially stored in the buffer, each sequence + * from the vector stored directly after the previous. The number of + * sequences is NSEQ. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Wednesday, May 1, 2001 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, + const struct H5O_pline_t *pline, const H5O_fill_t *fill, + const struct H5O_efl_t *efl, const H5S_t *file_space, size_t elmt_size, + size_t nseq, size_t seq_len_arr[], hsize_t file_offset_arr[], + void *_buf/*out*/) +{ + unsigned char *real_buf=(unsigned char *)_buf; /* Local pointer to buffer to fill */ + unsigned char *buf; /* Local pointer to buffer to fill */ + hsize_t file_offset; /* Offset in dataset */ + hsize_t seq_len; /* Number of bytes to read */ hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */ hssize_t coords[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in dataspace */ hsize_t hslab_size[H5O_LAYOUT_NDIMS]; /* hyperslab size in dataspace*/ hsize_t down_size[H5O_LAYOUT_NDIMS]; /* Cumulative yperslab sizes (in elements) */ hsize_t acc; /* Accumulator for hyperslab sizes (in elements) */ intn ndims; - hsize_t max_data = 0; /*bytes in dataset */ + hsize_t max_data; /*bytes in dataset */ haddr_t addr=0; /*address in file */ uintn u; /*counters */ + size_t v; /*counters */ intn i,j; /*counters */ #ifdef H5_HAVE_PARALLEL H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; #endif - FUNC_ENTER(H5F_seq_read, FAIL); + FUNC_ENTER(H5F_seq_readv, FAIL); /* Check args */ assert(f); assert(layout); - assert(buf); + assert(real_buf); #ifdef H5_HAVE_PARALLEL { @@ -110,30 +201,11 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, "filters are not allowed for contiguous data"); } - /* - * Initialize loop variables. The loop is a multi-dimensional loop - * that counts from SIZE down to zero and IDX is the counter. Each - * element of IDX is treated as a digit with IDX[0] being the least - * significant digit. - */ - if (efl && efl->nused>0) { - addr = 0; - } else { - addr = layout->addr; - /* Compute the size of the dataset in bytes */ - for(u=0, max_data=1; u<layout->ndims; u++) - max_data *= layout->dim[u]; - - /* Adjust the maximum size of the data by the offset into it */ - max_data -= file_offset; - } - addr += file_offset; - - /* - * Now begin to walk through the array, copying data from disk to - * memory. - */ + /* Read directly from file if the dataset is in an external file */ + if (efl && efl->nused>0) { + /* Iterate through the sequence vectors */ + for(v=0; v<nseq; v++) { #ifdef H5_HAVE_PARALLEL if (H5FD_MPIO_COLLECTIVE==xfer_mode) { /* @@ -143,8 +215,8 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, */ unsigned long max, min, temp; - temp = seq_len; - assert(temp==seq_len); /* verify no overflow */ + temp = seq_len_arr[v]; + assert(temp==seq_len_arr[v]); /* verify no overflow */ MPI_Allreduce(&temp, &max, 1, MPI_UNSIGNED_LONG, MPI_MAX, H5FD_mpio_communicator(f->shared->lf)); MPI_Allreduce(&temp, &min, 1, MPI_UNSIGNED_LONG, MPI_MIN, @@ -157,20 +229,26 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, "collective access with unequal number of blocks not supported yet"); } #endif + /* Note: We can't use data sieve buffers for datasets in external files + * because the 'addr' of all external files is set to 0 (above) and + * all datasets in external files would alias to the same set of + * file offsets, totally mixing up the data sieve buffer information. -QAK + */ + if (H5O_efl_read(f, efl, file_offset_arr[v], seq_len_arr[v], real_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "external data read failed"); + } - /* Read directly from file if the dataset is in an external file */ - if (efl && efl->nused>0) { - /* Note: We can't use data sieve buffers for datasets in external files - * because the 'addr' of all external files is set to 0 (above) and - * all datasets in external files would alias to the same set of - * file offsets, totally mixing up the data sieve buffer information. -QAK - */ - if (H5O_efl_read(f, efl, addr, seq_len, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "external data read failed"); - } + /* Increment offset in buffer */ + real_buf += seq_len_arr[v]; + } /* end for */ } else { - if (H5F_contig_read(f, max_data, H5FD_MEM_DRAW, addr, seq_len, dxpl_id, buf)<0) { + /* Compute the size of the dataset in bytes */ + for(u=1, max_data=layout->dim[0]; u<layout->ndims; u++) + max_data *= layout->dim[u]; + + /* Pass along the vector of sequences to read */ + if (H5F_contig_readv(f, max_data, H5FD_MEM_DRAW, layout->addr, nseq, seq_len_arr, file_offset_arr, dxpl_id, real_buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed"); } @@ -178,289 +256,218 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, break; case H5D_CHUNKED: - { - /* - * This method is unable to access external raw data files - */ - if (efl && efl->nused>0) { - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, - "chunking and external files are mutually exclusive"); - } - /* Compute the file offset coordinates and hyperslab size */ - if((ndims=H5S_get_simple_extent_dims(file_space,dset_dims,NULL))<0) - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions"); - -#ifdef QAK - /* The library shouldn't be reading partial elements currently */ - assert(seq_len%elmt_size!=0); - assert(addr%elmt_size!=0); -#endif /* QAK */ - -#ifdef QAK -/* Print out the file offsets & hyperslab sizes */ -{ - static int count=0; - - if(count<1000000) { - printf("%s: elmt_size=%d, addr=%d, seq_len=%d\n",FUNC,(int)elmt_size,(int)addr,(int)seq_len); - printf("%s: file_offset=%d\n",FUNC,(int)file_offset); - count++; - } -} -#endif /* QAK */ - /* Set location in dataset from the file_offset */ - addr=file_offset; - - /* Convert the bytes into elements */ - seq_len/=elmt_size; - addr/=elmt_size; - - /* Build the array of cumulative hyperslab sizes */ - for(acc=1, i=(ndims-1); i>=0; i--) { - down_size[i]=acc; - acc*=dset_dims[i]; -#ifdef QAK -printf("%s: acc=%ld, down_size[%d]=%ld\n",FUNC,(long)acc,i,(long)down_size[i]); -#endif /* QAK */ - } /* end for */ + /* Brute-force, stupid way to implement the vectors, but too complex to do other ways... */ + for(v=0; v<nseq; v++) { + file_offset=file_offset_arr[v]; + seq_len=seq_len_arr[v]; + buf=real_buf; + + { + /* + * This method is unable to access external raw data files + */ + if (efl && efl->nused>0) { + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, + "chunking and external files are mutually exclusive"); + } + /* Compute the file offset coordinates and hyperslab size */ + if((ndims=H5S_get_simple_extent_dims(file_space,dset_dims,NULL))<0) + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions"); + + + /* Set location in dataset from the file_offset */ + addr=file_offset; + + /* Convert the bytes into elements */ + seq_len/=elmt_size; + addr/=elmt_size; + + /* Build the array of cumulative hyperslab sizes */ + for(acc=1, i=(ndims-1); i>=0; i--) { + down_size[i]=acc; + acc*=dset_dims[i]; + } /* end for */ - /* Compute the hyperslab offset from the address given */ - for(i=ndims-1; i>=0; i--) { - coords[i]=addr%dset_dims[i]; - addr/=dset_dims[i]; -#ifdef QAK -printf("%s: addr=%lu, coords[%d]=%ld\n",FUNC,(unsigned long)addr,i,(long)coords[i]); -#endif /* QAK */ - } /* end for */ - coords[ndims]=0; /* No offset for element info */ -#ifdef QAK -printf("%s: addr=%lu, coords[%d]=%ld\n",FUNC,(unsigned long)addr,ndims,(long)coords[ndims]); -#endif /* QAK */ - - /* - * Peel off initial partial hyperslabs until we've got a hyperslab which starts - * at coord[n]==0 for dimensions 1->(ndims-1) (i.e. starting at coordinate - * zero for all dimensions except the slowest changing one - */ - for(i=ndims-1; i>0 && seq_len>=down_size[i]; i--) { - hsize_t partial_size; /* Size of the partial hyperslab in bytes */ - - /* Check if we have a partial hyperslab in this lower dimension */ - if(coords[i]>0) { -#ifdef QAK -printf("%s: Need to get hyperslab, seq_len=%ld, coords[%d]=%ld\n",FUNC,(long)seq_len,i,(long)coords[i]); -#endif /* QAK */ - /* Reset the partial hyperslab size */ - partial_size=1; - - /* Build the partial hyperslab information */ - for(j=0; j<ndims; j++) { - if(i==j) - hslab_size[j]=MIN(seq_len/down_size[i],dset_dims[i]-coords[i]); - else - if(j>i) - hslab_size[j]=dset_dims[j]; - else - hslab_size[j]=1; - partial_size*=hslab_size[j]; -#ifdef QAK -printf("%s: partial_size=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)hslab_size[j]); -#endif /* QAK */ + /* Compute the hyperslab offset from the address given */ + for(i=ndims-1; i>=0; i--) { + coords[i]=addr%dset_dims[i]; + addr/=dset_dims[i]; + } /* end for */ + coords[ndims]=0; /* No offset for element info */ + + /* + * Peel off initial partial hyperslabs until we've got a hyperslab which starts + * at coord[n]==0 for dimensions 1->(ndims-1) (i.e. starting at coordinate + * zero for all dimensions except the slowest changing one + */ + for(i=ndims-1; i>0 && seq_len>=down_size[i]; i--) { + hsize_t partial_size; /* Size of the partial hyperslab in bytes */ + + /* Check if we have a partial hyperslab in this lower dimension */ + if(coords[i]>0) { + /* Reset the partial hyperslab size */ + partial_size=1; + + /* Build the partial hyperslab information */ + for(j=0; j<ndims; j++) { + if(i==j) + hslab_size[j]=MIN(seq_len/down_size[i],dset_dims[i]-coords[i]); + else + if(j>i) + hslab_size[j]=dset_dims[j]; + else + hslab_size[j]=1; + partial_size*=hslab_size[j]; + } /* end for */ + hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ + + /* Read in the partial hyperslab */ + if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, + hslab_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); + } + + /* Increment the buffer offset */ + buf=(unsigned char *)buf+partial_size; + + /* Decrement the length of the sequence to read */ + seq_len-=partial_size; + + /* Correct the coords array */ + coords[i]=0; + coords[i-1]++; + } /* end if */ } /* end for */ - hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ -#ifdef QAK -printf("%s: partial_size=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)hslab_size[ndims]); -#endif /* QAK */ - - /* Read in the partial hyperslab */ - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); - } - /* Increment the buffer offset */ - buf=(unsigned char *)buf+partial_size; + /* Check if there is more than just a partial hyperslab to read */ + if(seq_len>=down_size[0]) { + hsize_t tmp_seq_len; /* Temp. size of the sequence in elements */ + hsize_t full_size; /* Size of the full hyperslab in bytes */ - /* Decrement the length of the sequence to read */ - seq_len-=partial_size; + /* Get the sequence length for computing the hyperslab sizes */ + tmp_seq_len=seq_len; - /* Correct the coords array */ - coords[i]=0; - coords[i-1]++; - } /* end if */ - } /* end for */ -#ifdef QAK -printf("%s: after reading initial partial hyperslabs, seq_len=%lu\n",FUNC,(unsigned long)seq_len); -#endif /* QAK */ - - /* Check if there is more than just a partial hyperslab to read */ - if(seq_len>=down_size[0]) { - hsize_t tmp_seq_len; /* Temp. size of the sequence in elements */ - hsize_t full_size; /* Size of the full hyperslab in bytes */ - - /* Get the sequence length for computing the hyperslab sizes */ - tmp_seq_len=seq_len; - - /* Reset the size of the hyperslab read in */ - full_size=1; - - /* Compute the hyperslab size from the length given */ - for(i=ndims-1; i>=0; i--) { - /* Check if the hyperslab is wider than the width of the dimension */ - if(tmp_seq_len>dset_dims[i]) { - assert(0==coords[i]); - hslab_size[i]=dset_dims[i]; - } /* end if */ - else - hslab_size[i]=tmp_seq_len; + /* Reset the size of the hyperslab read in */ + full_size=1; - /* compute the number of elements read in */ - full_size*=hslab_size[i]; + /* Compute the hyperslab size from the length given */ + for(i=ndims-1; i>=0; i--) { + /* Check if the hyperslab is wider than the width of the dimension */ + if(tmp_seq_len>dset_dims[i]) { + assert(0==coords[i]); + hslab_size[i]=dset_dims[i]; + } /* end if */ + else + hslab_size[i]=tmp_seq_len; - /* Fold the length into the length in the next highest dimension */ - tmp_seq_len/=dset_dims[i]; -#ifdef QAK -printf("%s: tmp_seq_len=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)tmp_seq_len,i,(long)hslab_size[i]); -#endif /* QAK */ + /* compute the number of elements read in */ + full_size*=hslab_size[i]; - /* Make certain the hyperslab sizes don't go less than 1 for dimensions less than 0*/ - assert(tmp_seq_len>=1 || i==0); - } /* end for */ - hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ + /* Fold the length into the length in the next highest dimension */ + tmp_seq_len/=dset_dims[i]; -#ifdef QAK -/* Print out the file offsets & hyperslab sizes */ -{ - static int count=0; - - if(count<1000000) { - printf("%s: elmt_size=%d, addr=%d, full_size=%ld, tmp_seq_len=%ld seq_len=%ld\n",FUNC,(int)elmt_size,(int)addr,(long)full_size,(long)tmp_seq_len,(long)seq_len); - for(i=0; i<ndims; i++) - printf("%s: dset_dims[%d]=%d\n",FUNC,i,(int)dset_dims[i]); - for(i=0; i<=ndims; i++) - printf("%s: coords[%d]=%d, hslab_size[%d]=%d\n",FUNC,i,(int)coords[i],(int)i,(int)hslab_size[i]); - count++; - } -} -#endif /* QAK */ + /* Make certain the hyperslab sizes don't go less than 1 for dimensions less than 0*/ + assert(tmp_seq_len>=1 || i==0); + } /* end for */ + hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ - /* Read the full hyperslab in */ - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); - } + /* Read the full hyperslab in */ + if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, + hslab_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); + } - /* Increment the buffer offset */ - buf=(unsigned char *)buf+full_size; + /* Increment the buffer offset */ + buf=(unsigned char *)buf+full_size; - /* Decrement the sequence length left */ - seq_len-=full_size; + /* Decrement the sequence length left */ + seq_len-=full_size; - /* Increment coordinate of slowest changing dimension */ - coords[0]+=hslab_size[0]; + /* Increment coordinate of slowest changing dimension */ + coords[0]+=hslab_size[0]; - } /* end if */ -#ifdef QAK -printf("%s: after reading 'middle' full hyperslabs, seq_len=%lu\n",FUNC,(unsigned long)seq_len); -#endif /* QAK */ + } /* end if */ - /* - * Peel off final partial hyperslabs until we've finished reading all the data - */ - if(seq_len>0) { - hsize_t partial_size; /* Size of the partial hyperslab in bytes */ + /* + * Peel off final partial hyperslabs until we've finished reading all the data + */ + if(seq_len>0) { + hsize_t partial_size; /* Size of the partial hyperslab in bytes */ + + /* + * Peel off remaining partial hyperslabs, from the next-slowest dimension + * on down to the next-to-fastest changing dimension + */ + for(i=1; i<(ndims-1); i++) { + /* Check if there are enough elements to read in a row in this dimension */ + if(seq_len>=down_size[i]) { + /* Reset the partial hyperslab size */ + partial_size=1; + + /* Build the partial hyperslab information */ + for(j=0; j<ndims; j++) { + if(j<i) + hslab_size[j]=1; + else + if(j==i) + hslab_size[j]=seq_len/down_size[j]; + else + hslab_size[j]=dset_dims[j]; + + partial_size*=hslab_size[j]; + } /* end for */ + hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ + + /* Read in the partial hyperslab */ + if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, + hslab_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); + } + + /* Increment the buffer offset */ + buf=(unsigned char *)buf+partial_size; + + /* Decrement the length of the sequence to read */ + seq_len-=partial_size; + + /* Correct the coords array */ + coords[i]=hslab_size[i]; + } /* end if */ + } /* end for */ - /* - * Peel off remaining partial hyperslabs, from the next-slowest dimension - * on down to the next-to-fastest changing dimension - */ - for(i=1; i<(ndims-1); i++) { - /* Check if there are enough elements to read in a row in this dimension */ - if(seq_len>=down_size[i]) { -#ifdef QAK -printf("%s: seq_len=%ld, down_size[%d]=%ld\n",FUNC,(long)seq_len,i+1,(long)down_size[i+1]); -#endif /* QAK */ - /* Reset the partial hyperslab size */ - partial_size=1; - - /* Build the partial hyperslab information */ - for(j=0; j<ndims; j++) { - if(j<i) - hslab_size[j]=1; - else - if(j==i) - hslab_size[j]=seq_len/down_size[j]; - else - hslab_size[j]=dset_dims[j]; + /* Handle fastest changing dimension if there are any elements left */ + if(seq_len>0) { + assert(seq_len<dset_dims[ndims-1]); - partial_size*=hslab_size[j]; -#ifdef QAK -printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)coords[j],j,(long)hslab_size[j]); -#endif /* QAK */ - } /* end for */ - hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ -#ifdef QAK -printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)coords[ndims],ndims,(long)hslab_size[ndims]); -#endif /* QAK */ + /* Reset the partial hyperslab size */ + partial_size=1; - /* Read in the partial hyperslab */ - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); - } + /* Build the partial hyperslab information */ + for(j=0; j<ndims; j++) { + if(j==(ndims-1)) + hslab_size[j]=seq_len; + else + hslab_size[j]=1; - /* Increment the buffer offset */ - buf=(unsigned char *)buf+partial_size; + partial_size*=hslab_size[j]; + } /* end for */ + hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ - /* Decrement the length of the sequence to read */ - seq_len-=partial_size; + /* Read in the partial hyperslab */ + if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, + hslab_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); + } - /* Correct the coords array */ - coords[i]=hslab_size[i]; + /* Double-check the amount read in */ + assert(seq_len==partial_size); + } /* end if */ } /* end if */ - } /* end for */ -#ifdef QAK -printf("%s: after reading trailing hyperslabs for all but the last dimension, seq_len=%ld\n",FUNC,(long)seq_len); -#endif /* QAK */ - - /* Handle fastest changing dimension if there are any elements left */ - if(seq_len>0) { -#ifdef QAK -printf("%s: i=%d, seq_len=%ld\n",FUNC,ndims-1,(long)seq_len); -#endif /* QAK */ - assert(seq_len<dset_dims[ndims-1]); - - /* Reset the partial hyperslab size */ - partial_size=1; - - /* Build the partial hyperslab information */ - for(j=0; j<ndims; j++) { - if(j==(ndims-1)) - hslab_size[j]=seq_len; - else - hslab_size[j]=1; - - partial_size*=hslab_size[j]; -#ifdef QAK -printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)coords[j],j,(long)hslab_size[j]); -#endif /* QAK */ - } /* end for */ - hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ -#ifdef QAK -printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)coords[ndims],ndims,(long)hslab_size[ndims]); -#endif /* QAK */ - - /* Read in the partial hyperslab */ - if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); - } + } + /* Increment offset in buffer */ + real_buf += seq_len_arr[v]; + } /* end for */ - /* Double-check the amount read in */ - assert(seq_len==partial_size); - } /* end if */ - } /* end if */ - } break; default: @@ -469,55 +476,64 @@ printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsign } /* end switch() */ FUNC_LEAVE(SUCCEED); -} /* H5F_seq_read() */ +} /* H5F_seq_readv() */ /*------------------------------------------------------------------------- - * Function: H5F_seq_write + * Function: H5F_seq_writev * - * Purpose: Writes a sequence of bytes to a file dataset from a buffer in - * in memory. The data is written to file F and the array's size and - * storage information is in LAYOUT. External files are described - * according to the external file list, EFL. The sequence offset is - * FILE_OFFSET in the file (offsets are - * in terms of bytes) and the size of the hyperslab is SEQ_LEN. The - * total size of the file array is implied in the LAYOUT argument. + * Purpose: Writes a vector of byte sequences from a buffer in memory into + * a file dataset. The data is written to file F and the array's size + * and storage information is in LAYOUT. External files are described + * according to the external file list, EFL. The vector of byte sequences + * offsets is in the FILE_OFFSET array into the dataset (offsets are in + * terms of bytes) and the size of each sequence is in the SEQ_LEN array. + * The total size of the file array is implied in the LAYOUT argument. + * Bytes written from BUF are sequentially stored in the buffer, each sequence + * from the vector stored directly after the previous. The number of + * sequences is NSEQ. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * Monday, October 9, 2000 + * Friday, July 6, 2001 * * Modifications: * *------------------------------------------------------------------------- */ herr_t -H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, +H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const H5O_fill_t *fill, const struct H5O_efl_t *efl, const H5S_t *file_space, size_t elmt_size, - hsize_t seq_len, hsize_t file_offset, const void *buf) + size_t nseq, size_t seq_len_arr[], hsize_t file_offset_arr[], + const void *_buf) { + const unsigned char *real_buf=(const unsigned char *)_buf; /* Local pointer to buffer to fill */ + const unsigned char *buf; /* Local pointer to buffer to fill */ + hsize_t file_offset; /* Offset in dataset */ + hsize_t seq_len; /* Number of bytes to read */ hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */ hssize_t coords[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in dataspace */ hsize_t hslab_size[H5O_LAYOUT_NDIMS]; /* hyperslab size in dataspace*/ hsize_t down_size[H5O_LAYOUT_NDIMS]; /* Cumulative hyperslab sizes (in elements) */ - hsize_t acc; /* Accumulator for hyperslab sizes (in elements) */ + hsize_t acc; /* Accumulator for hyperslab sizes (in elements) */ intn ndims; - hsize_t max_data = 0; /*bytes in dataset */ + hsize_t max_data; /*bytes in dataset */ haddr_t addr; /*address in file */ uintn u; /*counters */ + size_t v; /*counters */ intn i,j; /*counters */ #ifdef H5_HAVE_PARALLEL H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; #endif - FUNC_ENTER(H5F_seq_write, FAIL); + FUNC_ENTER(H5F_seq_writev, FAIL); /* Check args */ assert(f); assert(layout); - assert(buf); + assert(real_buf); #ifdef H5_HAVE_PARALLEL { @@ -547,30 +563,11 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, "filters are not allowed for contiguous data"); } - /* - * Initialize loop variables. The loop is a multi-dimensional loop - * that counts from SIZE down to zero and IDX is the counter. Each - * element of IDX is treated as a digit with IDX[0] being the least - * significant digit. - */ - if (efl && efl->nused>0) { - addr = 0; - } else { - addr = layout->addr; - /* Compute the size of the dataset in bytes */ - for(u=0, max_data=1; u<layout->ndims; u++) - max_data *= layout->dim[u]; - - /* Adjust the maximum size of the data by the offset into it */ - max_data -= file_offset; - } - addr += file_offset; - - /* - * Now begin to walk through the array, copying data from disk to - * memory. - */ + /* Write directly to file if the dataset is in an external file */ + if (efl && efl->nused>0) { + /* Iterate through the sequence vectors */ + for(v=0; v<nseq; v++) { #ifdef H5_HAVE_PARALLEL if (H5FD_MPIO_COLLECTIVE==xfer_mode) { /* @@ -580,8 +577,8 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, */ unsigned long max, min, temp; - temp = seq_len; - assert(temp==seq_len); /* verify no overflow */ + temp = seq_len_arr[v]; + assert(temp==seq_len_arr[v]); /* verify no overflow */ MPI_Allreduce(&temp, &max, 1, MPI_UNSIGNED_LONG, MPI_MAX, H5FD_mpio_communicator(f->shared->lf)); MPI_Allreduce(&temp, &min, 1, MPI_UNSIGNED_LONG, MPI_MIN, @@ -594,20 +591,26 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, "collective access with unequal number of blocks not supported yet"); } #endif + /* Note: We can't use data sieve buffers for datasets in external files + * because the 'addr' of all external files is set to 0 (above) and + * all datasets in external files would alias to the same set of + * file offsets, totally mixing up the data sieve buffer information. -QAK + */ + if (H5O_efl_write(f, efl, file_offset_arr[v], seq_len_arr[v], real_buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "external data write failed"); + } - /* Write directly to file if the dataset is in an external file */ - if (efl && efl->nused>0) { - /* Note: We can't use data sieve buffers for datasets in external files - * because the 'addr' of all external files is set to 0 (above) and - * all datasets in external files would alias to the same set of - * file offsets, totally mixing up the data sieve buffer information. -QAK - */ - if (H5O_efl_write(f, efl, addr, seq_len, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "external data write failed"); - } + /* Increment offset in buffer */ + real_buf += seq_len_arr[v]; + } /* end for */ } else { - if (H5F_contig_write(f, max_data, H5FD_MEM_DRAW, addr, seq_len, dxpl_id, buf)<0) { + /* Compute the size of the dataset in bytes */ + for(u=1, max_data=layout->dim[0]; u<layout->ndims; u++) + max_data *= layout->dim[u]; + + /* Pass along the vector of sequences to write */ + if (H5F_contig_writev(f, max_data, H5FD_MEM_DRAW, layout->addr, nseq, seq_len_arr, file_offset_arr, dxpl_id, real_buf)<0) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed"); } @@ -615,286 +618,217 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, break; case H5D_CHUNKED: - { - /* - * This method is unable to access external raw data files - */ - if (efl && efl->nused>0) { - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, - "chunking and external files are mutually exclusive"); - } - /* Compute the file offset coordinates and hyperslab size */ - if((ndims=H5S_get_simple_extent_dims(file_space,dset_dims,NULL))<0) - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions"); - -#ifdef QAK -/* Print out the file offsets & hyperslab sizes */ -{ - static int count=0; - - if(count<1000000) { - printf("%s: elmt_size=%d, addr=%d, seq_len=%lu\n",FUNC,(int)elmt_size,(int)addr,(unsigned long)seq_len); - printf("%s: file_offset=%d\n",FUNC,(int)file_offset); - count++; - } -} -#endif /* QAK */ -#ifdef QAK - /* The library shouldn't be reading partial elements currently */ - assert((seq_len%elmt_size)!=0); - assert((addr%elmt_size)!=0); -#endif /* QAK */ - - /* Set location in dataset from the file_offset */ - addr=file_offset; - - /* Convert the bytes into elements */ - seq_len/=elmt_size; - addr/=elmt_size; - - /* Build the array of cumulative hyperslab sizes */ - for(acc=1, i=(ndims-1); i>=0; i--) { - down_size[i]=acc; - acc*=dset_dims[i]; -#ifdef QAK -printf("%s: acc=%ld, down_size[%d]=%ld\n",FUNC,(long)acc,i,(long)down_size[i]); -#endif /* QAK */ - } /* end for */ - - /* Compute the hyperslab offset from the address given */ - for(i=ndims-1; i>=0; i--) { - coords[i]=addr%dset_dims[i]; - addr/=dset_dims[i]; -#ifdef QAK -printf("%s: addr=%lu, dset_dims[%d]=%ld, coords[%d]=%ld\n",FUNC,(unsigned long)addr,i,(long)dset_dims[i],i,(long)coords[i]); -#endif /* QAK */ - } /* end for */ - coords[ndims]=0; /* No offset for element info */ -#ifdef QAK -printf("%s: addr=%lu, coords[%d]=%ld\n",FUNC,(unsigned long)addr,ndims,(long)coords[ndims]); -#endif /* QAK */ - - /* - * Peel off initial partial hyperslabs until we've got a hyperslab which starts - * at coord[n]==0 for dimensions 1->(ndims-1) (i.e. starting at coordinate - * zero for all dimensions except the slowest changing one - */ - for(i=ndims-1; i>0 && seq_len>=down_size[i]; i--) { - hsize_t partial_size; /* Size of the partial hyperslab in bytes */ - - /* Check if we have a partial hyperslab in this lower dimension */ - if(coords[i]>0) { -#ifdef QAK -printf("%s: Need to get hyperslab, seq_len=%ld, coords[%d]=%ld\n",FUNC,(long)seq_len,i,(long)coords[i]); -#endif /* QAK */ - /* Reset the partial hyperslab size */ - partial_size=1; - - /* Build the partial hyperslab information */ - for(j=0; j<ndims; j++) { - if(i==j) - hslab_size[j]=MIN(seq_len/down_size[i],dset_dims[i]-coords[i]); - else - if(j>i) - hslab_size[j]=dset_dims[j]; - else - hslab_size[j]=1; - partial_size*=hslab_size[j]; -#ifdef QAK -printf("%s: partial_size=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)hslab_size[j]); -#endif /* QAK */ - } /* end for */ - hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ -#ifdef QAK -printf("%s: partial_size=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)hslab_size[ndims]); -#endif /* QAK */ - - /* Write out the partial hyperslab */ - if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked write failed"); + /* Brute-force, stupid way to implement the vectors, but too complex to do other ways... */ + for(v=0; v<nseq; v++) { + file_offset=file_offset_arr[v]; + seq_len=seq_len_arr[v]; + buf=real_buf; + + { + /* + * This method is unable to access external raw data files + */ + if (efl && efl->nused>0) { + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, + "chunking and external files are mutually exclusive"); } + /* Compute the file offset coordinates and hyperslab size */ + if((ndims=H5S_get_simple_extent_dims(file_space,dset_dims,NULL))<0) + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions"); - /* Increment the buffer offset */ - buf=(const unsigned char *)buf+partial_size; + /* Set location in dataset from the file_offset */ + addr=file_offset; - /* Decrement the length of the sequence to read */ - seq_len-=partial_size; - - /* Correct the coords array */ - coords[i]=0; - coords[i-1]++; - } /* end if */ - } /* end for */ -#ifdef QAK -printf("%s: seq_len=%lu\n",FUNC,(unsigned long)seq_len); -#endif /* QAK */ - - /* Check if there is more than just a partial hyperslab to read */ - if(seq_len>=down_size[0]) { - hsize_t tmp_seq_len; /* Temp. size of the sequence in elements */ - hsize_t full_size; /* Size of the full hyperslab in bytes */ - - /* Get the sequence length for computing the hyperslab sizes */ - tmp_seq_len=seq_len; - - /* Reset the size of the hyperslab read in */ - full_size=1; - - /* Compute the hyperslab size from the length given */ - for(i=ndims-1; i>=0; i--) { - /* Check if the hyperslab is wider than the width of the dimension */ - if(tmp_seq_len>dset_dims[i]) { - assert(0==coords[i]); - hslab_size[i]=dset_dims[i]; - } /* end if */ - else - hslab_size[i]=tmp_seq_len; + /* Convert the bytes into elements */ + seq_len/=elmt_size; + addr/=elmt_size; - /* compute the number of elements read in */ - full_size*=hslab_size[i]; - - /* Fold the length into the length in the next highest dimension */ - tmp_seq_len/=dset_dims[i]; -#ifdef QAK -printf("%s: tmp_seq_len=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)tmp_seq_len,i,(long)hslab_size[i]); -#endif /* QAK */ - - /* Make certain the hyperslab sizes don't go less than 1 for dimensions less than 0*/ - assert(tmp_seq_len>=1 || i==0); - } /* end for */ - hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ - -#ifdef QAK -/* Print out the file offsets & hyperslab sizes */ -{ - static int count=0; - - if(count<1000000) { - printf("%s: elmt_size=%d, addr=%d, full_size=%ld, tmp_seq_len=%ld seq_len=%ld\n",FUNC,(int)elmt_size,(int)addr,(long)full_size,(long)tmp_seq_len,(long)seq_len); - for(i=0; i<ndims; i++) - printf("%s: dset_dims[%d]=%d\n",FUNC,i,(int)dset_dims[i]); - for(i=0; i<=ndims; i++) - printf("%s: coords[%d]=%d, hslab_size[%d]=%d\n",FUNC,i,(int)coords[i],(int)i,(int)hslab_size[i]); - count++; - } -} -#endif /* QAK */ + /* Build the array of cumulative hyperslab sizes */ + for(acc=1, i=(ndims-1); i>=0; i--) { + down_size[i]=acc; + acc*=dset_dims[i]; + } /* end for */ - /* Write the full hyperslab in */ - if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked write failed"); - } + /* Compute the hyperslab offset from the address given */ + for(i=ndims-1; i>=0; i--) { + coords[i]=addr%dset_dims[i]; + addr/=dset_dims[i]; + } /* end for */ + coords[ndims]=0; /* No offset for element info */ + + /* + * Peel off initial partial hyperslabs until we've got a hyperslab which starts + * at coord[n]==0 for dimensions 1->(ndims-1) (i.e. starting at coordinate + * zero for all dimensions except the slowest changing one + */ + for(i=ndims-1; i>0 && seq_len>=down_size[i]; i--) { + hsize_t partial_size; /* Size of the partial hyperslab in bytes */ + + /* Check if we have a partial hyperslab in this lower dimension */ + if(coords[i]>0) { + /* Reset the partial hyperslab size */ + partial_size=1; + + /* Build the partial hyperslab information */ + for(j=0; j<ndims; j++) { + if(i==j) + hslab_size[j]=MIN(seq_len/down_size[i],dset_dims[i]-coords[i]); + else + if(j>i) + hslab_size[j]=dset_dims[j]; + else + hslab_size[j]=1; + partial_size*=hslab_size[j]; + } /* end for */ + hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ + + /* Write out the partial hyperslab */ + if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, + hslab_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); + } + + /* Increment the buffer offset */ + buf=(const unsigned char *)buf+partial_size; + + /* Decrement the length of the sequence to read */ + seq_len-=partial_size; + + /* Correct the coords array */ + coords[i]=0; + coords[i-1]++; + } /* end if */ + } /* end for */ - /* Increment the buffer offset */ - buf=(const unsigned char *)buf+full_size; + /* Check if there is more than just a partial hyperslab to read */ + if(seq_len>=down_size[0]) { + hsize_t tmp_seq_len; /* Temp. size of the sequence in elements */ + hsize_t full_size; /* Size of the full hyperslab in bytes */ - /* Decrement the sequence length left */ - seq_len-=full_size; + /* Get the sequence length for computing the hyperslab sizes */ + tmp_seq_len=seq_len; - /* Increment coordinate of slowest changing dimension */ - coords[0]+=hslab_size[0]; + /* Reset the size of the hyperslab read in */ + full_size=1; - } /* end if */ -#ifdef QAK -printf("%s: seq_len=%lu\n",FUNC,(unsigned long)seq_len); -#endif /* QAK */ + /* Compute the hyperslab size from the length given */ + for(i=ndims-1; i>=0; i--) { + /* Check if the hyperslab is wider than the width of the dimension */ + if(tmp_seq_len>dset_dims[i]) { + assert(0==coords[i]); + hslab_size[i]=dset_dims[i]; + } /* end if */ + else + hslab_size[i]=tmp_seq_len; - /* - * Peel off final partial hyperslabs until we've finished reading all the data - */ - if(seq_len>0) { - hsize_t partial_size; /* Size of the partial hyperslab in bytes */ + /* compute the number of elements read in */ + full_size*=hslab_size[i]; - /* - * Peel off remaining partial hyperslabs, from the next-slowest dimension - * on down to the next-to-fastest changing dimension - */ - for(i=1; i<(ndims-1); i++) { - /* Check if there are enough elements to read in a row in this dimension */ - if(seq_len>=down_size[i]) { -#ifdef QAK -printf("%s: seq_len=%ld, down_size[%d]=%ld\n",FUNC,(long)seq_len,i+1,(long)down_size[i+1]); -#endif /* QAK */ - /* Reset the partial hyperslab size */ - partial_size=1; - - /* Build the partial hyperslab information */ - for(j=0; j<ndims; j++) { - if(j<i) - hslab_size[j]=1; - else - if(j==i) - hslab_size[j]=seq_len/down_size[j]; - else - hslab_size[j]=dset_dims[j]; + /* Fold the length into the length in the next highest dimension */ + tmp_seq_len/=dset_dims[i]; - partial_size*=hslab_size[j]; -#ifdef QAK -printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)coords[j],j,(long)hslab_size[j]); -#endif /* QAK */ + /* Make certain the hyperslab sizes don't go less than 1 for dimensions less than 0*/ + assert(tmp_seq_len>=1 || i==0); } /* end for */ hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ -#ifdef QAK -printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)coords[ndims],ndims,(long)hslab_size[ndims]); -#endif /* QAK */ - /* Write out the partial hyperslab */ + /* Write the full hyperslab in */ if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked write failed"); + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); } /* Increment the buffer offset */ - buf=(const unsigned char *)buf+partial_size; + buf=(const unsigned char *)buf+full_size; + + /* Decrement the sequence length left */ + seq_len-=full_size; - /* Decrement the length of the sequence to read */ - seq_len-=partial_size; + /* Increment coordinate of slowest changing dimension */ + coords[0]+=hslab_size[0]; - /* Correct the coords array */ - coords[i]=hslab_size[i]; } /* end if */ - } /* end for */ - /* Handle fastest changing dimension if there are any elements left */ - if(seq_len>0) { -#ifdef QAK -printf("%s: i=%d, seq_len=%ld\n",FUNC,ndims-1,(long)seq_len); -#endif /* QAK */ - assert(seq_len<dset_dims[ndims-1]); - - /* Reset the partial hyperslab size */ - partial_size=1; - - /* Build the partial hyperslab information */ - for(j=0; j<ndims; j++) { - if(j==(ndims-1)) - hslab_size[j]=seq_len; - else - hslab_size[j]=1; - - partial_size*=hslab_size[j]; -#ifdef QAK -printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)coords[j],j,(long)hslab_size[j]); -#endif /* QAK */ - } /* end for */ - hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ -#ifdef QAK -printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)coords[ndims],ndims,(long)hslab_size[ndims]); -#endif /* QAK */ - - /* Write in the final partial hyperslab */ - if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, - hslab_size, buf)<0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked write failed"); - } + /* + * Peel off final partial hyperslabs until we've finished reading all the data + */ + if(seq_len>0) { + hsize_t partial_size; /* Size of the partial hyperslab in bytes */ + + /* + * Peel off remaining partial hyperslabs, from the next-slowest dimension + * on down to the next-to-fastest changing dimension + */ + for(i=1; i<(ndims-1); i++) { + /* Check if there are enough elements to read in a row in this dimension */ + if(seq_len>=down_size[i]) { + /* Reset the partial hyperslab size */ + partial_size=1; + + /* Build the partial hyperslab information */ + for(j=0; j<ndims; j++) { + if(j<i) + hslab_size[j]=1; + else + if(j==i) + hslab_size[j]=seq_len/down_size[j]; + else + hslab_size[j]=dset_dims[j]; + + partial_size*=hslab_size[j]; + } /* end for */ + hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ + + /* Write out the partial hyperslab */ + if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, + hslab_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); + } + + /* Increment the buffer offset */ + buf=(const unsigned char *)buf+partial_size; + + /* Decrement the length of the sequence to read */ + seq_len-=partial_size; + + /* Correct the coords array */ + coords[i]=hslab_size[i]; + } /* end if */ + } /* end for */ + + /* Handle fastest changing dimension if there are any elements left */ + if(seq_len>0) { + assert(seq_len<dset_dims[ndims-1]); + + /* Reset the partial hyperslab size */ + partial_size=1; + + /* Build the partial hyperslab information */ + for(j=0; j<ndims; j++) { + if(j==(ndims-1)) + hslab_size[j]=seq_len; + else + hslab_size[j]=1; + + partial_size*=hslab_size[j]; + } /* end for */ + hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */ + + /* Write out the final partial hyperslab */ + if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords, + hslab_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed"); + } + + /* Double-check the amount read in */ + assert(seq_len==partial_size); + } /* end if */ + } /* end if */ + } + /* Increment offset in buffer */ + real_buf += seq_len_arr[v]; + } /* end for */ - /* Double-check the amount read in */ - assert(seq_len==partial_size); - } /* end if */ - } /* end if */ - } break; default: @@ -903,5 +837,5 @@ printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsign } /* end switch() */ FUNC_LEAVE(SUCCEED); -} /* H5F_seq_write() */ +} /* H5F_seq_writev() */ diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 3847a46..69777b5 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -373,7 +373,7 @@ H5G_node_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5G_node_t *sym) if (IS_H5FD_MPIO(f)) H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 will write*/ #endif /* H5_HAVE_PARALLEL */ - status = H5F_block_write(f, H5FD_MEM_BTREE, addr, (hsize_t)size, H5P_DEFAULT, buf); + status = H5F_block_write(f, H5FD_MEM_BTREE, addr, size, H5P_DEFAULT, buf); if (status < 0) HRETURN_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "unable to write symbol table node to the file"); @@ -415,7 +415,7 @@ H5G_node_load(H5F_t *f, haddr_t addr, const void UNUSED *_udata1, void UNUSED *_udata2) { H5G_node_t *sym = NULL; - hsize_t size = 0; + size_t size = 0; uint8_t *buf = NULL; const uint8_t *p = NULL; H5G_node_t *ret_value = NULL; /*for error handling */ @@ -51,7 +51,7 @@ struct H5HG_heap_t { hbool_t dirty; /*does heap need to be saved? */ size_t size; /*total size of collection */ uint8_t *chunk; /*the collection, incl. header */ - intn nalloc; /*numb object slots allocated */ + size_t nalloc; /*numb object slots allocated */ H5HG_obj_t *obj; /*array of object descriptions */ }; @@ -257,7 +257,7 @@ H5HG_load (H5F_t *f, haddr_t addr, const void UNUSED *udata1, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - if (H5F_block_read(f, H5FD_MEM_GHEAP, addr, (hsize_t)H5HG_MINSIZE, H5P_DEFAULT, + if (H5F_block_read(f, H5FD_MEM_GHEAP, addr, H5HG_MINSIZE, H5P_DEFAULT, heap->chunk)<0) { HGOTO_ERROR (H5E_HEAP, H5E_READERROR, NULL, "unable to read global heap collection"); @@ -293,7 +293,7 @@ H5HG_load (H5F_t *f, haddr_t addr, const void UNUSED *udata1, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - if (H5F_block_read (f, H5FD_MEM_GHEAP, next_addr, (hsize_t)(heap->size-H5HG_MINSIZE), + if (H5F_block_read (f, H5FD_MEM_GHEAP, next_addr, (heap->size-H5HG_MINSIZE), H5P_DEFAULT, heap->chunk+H5HG_MINSIZE)<0) { HGOTO_ERROR (H5E_HEAP, H5E_READERROR, NULL, "unable to read global heap collection"); @@ -307,7 +307,7 @@ H5HG_load (H5F_t *f, haddr_t addr, const void UNUSED *udata1, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - heap->nalloc = (intn)nalloc; + heap->nalloc = nalloc; while (p<heap->chunk+heap->size) { if (p+H5HG_SIZEOF_OBJHDR(f)>heap->chunk+heap->size) { /* @@ -319,8 +319,9 @@ H5HG_load (H5F_t *f, haddr_t addr, const void UNUSED *udata1, heap->obj[0].begin = p; p += heap->obj[0].size; } else { - intn idx; + uintn idx; uint8_t *begin = p; + UINT16DECODE (p, idx); assert (idx<heap->nalloc); assert (NULL==heap->obj[idx].begin); @@ -418,7 +419,7 @@ H5HG_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5HG_heap_t *heap) assert (heap); if (heap->dirty) { - if (H5F_block_write (f, H5FD_MEM_GHEAP, addr, (hsize_t)(heap->size), + if (H5F_block_write (f, H5FD_MEM_GHEAP, addr, heap->size, H5P_DEFAULT, heap->chunk)<0) { HRETURN_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write global heap collection to file"); @@ -455,7 +456,7 @@ H5HG_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5HG_heap_t *heap) * * Return: Success: The heap object ID of the new object. * - * Failure: Negative + * Failure: 0 * * Programmer: Robb Matzke * Friday, March 27, 1998 @@ -464,14 +465,14 @@ H5HG_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5HG_heap_t *heap) * *------------------------------------------------------------------------- */ -static intn +static uintn H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, int cwfsno, size_t size) { - int idx; + uintn idx; uint8_t *p = NULL; size_t need = H5HG_SIZEOF_OBJHDR(f) + H5HG_ALIGN(size); - FUNC_ENTER (H5HG_alloc, FAIL); + FUNC_ENTER (H5HG_alloc, 0); /* Check args */ assert (heap); @@ -482,7 +483,8 @@ H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, int cwfsno, size_t size) * object. */ for (idx=1; idx<heap->nalloc; idx++) { - if (NULL==heap->obj[idx].begin) break; + if (NULL==heap->obj[idx].begin) + break; } assert (idx < heap->nalloc); @@ -567,7 +569,8 @@ herr_t H5HG_insert (H5F_t *f, size_t size, void *obj, H5HG_t *hobj/*out*/) { size_t need; /*total space needed for object */ - intn cwfsno, idx; + intn cwfsno; + uintn idx; H5HG_heap_t *heap = NULL; FUNC_ENTER (H5HG_insert, FAIL); @@ -845,6 +848,7 @@ H5HG_remove (H5F_t *f, H5HG_t *hobj) H5HG_heap_t *heap = NULL; size_t need; intn i; + uintn u; FUNC_ENTER (H5HG_remove, FAIL); @@ -868,9 +872,9 @@ H5HG_remove (H5F_t *f, H5HG_t *hobj) */ /* Move the new free space to the end of the heap */ - for (i=0; i<heap->nalloc; i++) { - if (heap->obj[i].begin > heap->obj[hobj->idx].begin) { - heap->obj[i].begin -= need; + for (u=0; u<heap->nalloc; u++) { + if (heap->obj[u].begin > heap->obj[hobj->idx].begin) { + heap->obj[u].begin -= need; } } if (NULL==heap->obj[0].begin) { @@ -946,7 +950,7 @@ herr_t H5HG_debug(H5F_t *f, haddr_t addr, FILE *stream, intn indent, intn fwidth) { - int i, nused, maxobj; + uintn u, nused, maxobj; uintn j, k; H5HG_heap_t *h = NULL; char buf[64]; @@ -974,35 +978,35 @@ H5HG_debug(H5F_t *f, haddr_t addr, FILE *stream, intn indent, "Total collection size in file:", (unsigned long)(h->size)); - for (i=1, nused=0, maxobj=-1; i<h->nalloc; i++) { - if (h->obj[i].begin) { + for (u=1, nused=0, maxobj=0; u<h->nalloc; u++) { + if (h->obj[u].begin) { nused++; - if (i>maxobj) maxobj = i; + if (u>maxobj) maxobj = u; } } - fprintf (stream, "%*s%-*s %d/%d/", indent, "", fwidth, + fprintf (stream, "%*s%-*s %u/%u/", indent, "", fwidth, "Objects defined/allocated/max:", nused, h->nalloc); - fprintf (stream, nused?"%d\n":"NA\n", maxobj); + fprintf (stream, nused ? "%u\n": "NA\n", maxobj); fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth, "Free space:", (unsigned long)(h->obj[0].size)); - for (i=1; i<h->nalloc; i++) { - if (h->obj[i].begin) { - sprintf (buf, "Object %d", i); + for (u=1; u<h->nalloc; u++) { + if (h->obj[u].begin) { + sprintf (buf, "Object %u", u); fprintf (stream, "%*s%s\n", indent, "", buf); fprintf (stream, "%*s%-*s %d\n", indent+3, "", MIN(fwidth-3, 0), "Reference count:", - h->obj[i].nrefs); + h->obj[u].nrefs); fprintf (stream, "%*s%-*s %lu/%lu\n", indent+3, "", MIN(fwidth-3, 0), "Size of object body:", - (unsigned long)(h->obj[i].size), - (unsigned long)H5HG_ALIGN(h->obj[i].size)); - size = h->obj[i].size - H5HG_SIZEOF_OBJHDR (f); - p = h->obj[i].begin + H5HG_SIZEOF_OBJHDR (f); + (unsigned long)(h->obj[u].size), + (unsigned long)H5HG_ALIGN(h->obj[u].size)); + size = h->obj[u].size - H5HG_SIZEOF_OBJHDR (f); + p = h->obj[u].begin + H5HG_SIZEOF_OBJHDR (f); for (j=0; j<size; j+=16) { fprintf (stream, "%*s%04d: ", indent+6, "", j); for (k=0; k<16; k++) { diff --git a/src/H5HGprivate.h b/src/H5HGprivate.h index a6d02fa..785c060 100644 --- a/src/H5HGprivate.h +++ b/src/H5HGprivate.h @@ -91,7 +91,7 @@ typedef struct H5HG_t { haddr_t addr; /*address of collection */ - intn idx; /*object ID within collection */ + uintn idx; /*object ID within collection */ } H5HG_t; typedef struct H5HG_heap_t H5HG_heap_t; @@ -219,7 +219,7 @@ H5HL_load(H5F_t *f, haddr_t addr, const void UNUSED *udata1, assert(!udata1); assert(!udata2); - if (H5F_block_read(f, H5FD_MEM_LHEAP, addr, (hsize_t)H5HL_SIZEOF_HDR(f), H5P_DEFAULT, + if (H5F_block_read(f, H5FD_MEM_LHEAP, addr, H5HL_SIZEOF_HDR(f), H5P_DEFAULT, hdr) < 0) { HRETURN_ERROR(H5E_HEAP, H5E_READERROR, NULL, "unable to read heap header"); @@ -259,7 +259,7 @@ H5HL_load(H5F_t *f, haddr_t addr, const void UNUSED *udata1, "memory allocation failed"); } if (heap->disk_alloc && - H5F_block_read(f, H5FD_MEM_LHEAP, heap->addr, (hsize_t)(heap->disk_alloc), + H5F_block_read(f, H5FD_MEM_LHEAP, heap->addr, heap->disk_alloc, H5P_DEFAULT, heap->chunk + H5HL_SIZEOF_HDR(f)) < 0) { HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to read heap data"); @@ -399,7 +399,7 @@ H5HL_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5HL_t *heap) H5FD_mpio_tas_allsame( f->shared->lf, TRUE ); /* only p0 writes */ #endif /* H5_HAVE_PARALLEL */ if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, - (hsize_t)(H5HL_SIZEOF_HDR(f)+heap->disk_alloc), + (H5HL_SIZEOF_HDR(f)+heap->disk_alloc), H5P_DEFAULT, heap->chunk) < 0) { HRETURN_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header and data to file"); @@ -409,7 +409,7 @@ H5HL_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5HL_t *heap) if (IS_H5FD_MPIO(f)) H5FD_mpio_tas_allsame( f->shared->lf, TRUE ); /* only p0 writes */ #endif /* H5_HAVE_PARALLEL */ - if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, (hsize_t)H5HL_SIZEOF_HDR(f), + if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, H5HL_SIZEOF_HDR(f), H5P_DEFAULT, heap->chunk)<0) { HRETURN_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header to file"); @@ -418,7 +418,7 @@ H5HL_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5HL_t *heap) if (IS_H5FD_MPIO(f)) H5FD_mpio_tas_allsame( f->shared->lf, TRUE ); /* only p0 writes */ #endif /* H5_HAVE_PARALLEL */ - if (H5F_block_write(f, H5FD_MEM_LHEAP, heap->addr, (hsize_t)(heap->disk_alloc), + if (H5F_block_write(f, H5FD_MEM_LHEAP, heap->addr, heap->disk_alloc, H5P_DEFAULT, heap->chunk + H5HL_SIZEOF_HDR(f)) < 0) { HRETURN_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, @@ -722,7 +722,7 @@ H5HL_insert(H5F_t *f, haddr_t addr, size_t buf_size, const void *buf) old_size = heap->mem_alloc; heap->mem_alloc += need_more; heap->chunk = H5FL_BLK_REALLOC(heap_chunk,heap->chunk, - (hsize_t)(H5HL_SIZEOF_HDR(f) + heap->mem_alloc)); + (H5HL_SIZEOF_HDR(f) + heap->mem_alloc)); if (NULL==heap->chunk) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "memory allocation failed"); @@ -37,12 +37,12 @@ static herr_t H5O_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5O_t *oh); static H5O_t *H5O_load(H5F_t *f, haddr_t addr, const void *_udata1, void *_udata2); -static intn H5O_find_in_ohdr(H5F_t *f, haddr_t addr, +static uintn H5O_find_in_ohdr(H5F_t *f, haddr_t addr, const H5O_class_t **type_p, intn sequence); -static intn H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, +static uintn H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size); -static intn H5O_alloc_extend_chunk(H5O_t *oh, intn chunkno, size_t size); -static intn H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size); +static uintn H5O_alloc_extend_chunk(H5O_t *oh, uintn chunkno, size_t size); +static uintn H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size); static herr_t H5O_touch_oh(H5F_t *f, H5O_t *oh, hbool_t force); /* H5O inherits cache-like properties from H5AC */ @@ -353,9 +353,11 @@ H5O_load(H5F_t *f, haddr_t addr, const void UNUSED *_udata1, H5O_t *ret_value = NULL; uint8_t buf[16], *p; size_t mesg_size; - hsize_t hdr_size; + size_t hdr_size; uintn id; - intn mesgno, chunkno, curmesg = 0, nmesgs; + intn mesgno; + uintn curmesg = 0, nmesgs; + uintn chunkno; haddr_t chunk_addr; size_t chunk_size; H5O_cont_t *cont = NULL; @@ -415,13 +417,14 @@ H5O_load(H5F_t *f, haddr_t addr, const void UNUSED *_udata1, /* increase chunk array size */ if (oh->nchunks >= oh->alloc_nchunks) { - hsize_t na = oh->alloc_nchunks + H5O_NCHUNKS; + size_t na = oh->alloc_nchunks + H5O_NCHUNKS; H5O_chunk_t *x = H5FL_ARR_REALLOC (H5O_chunk_t, oh->chunk, na); + if (!x) { - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - oh->alloc_nchunks = (intn)na; + oh->alloc_nchunks = na; oh->chunk = x; } @@ -434,7 +437,7 @@ H5O_load(H5F_t *f, haddr_t addr, const void UNUSED *_udata1, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - if (H5F_block_read(f, H5FD_MEM_OHDR, chunk_addr, (hsize_t)chunk_size, H5P_DEFAULT, + if (H5F_block_read(f, H5FD_MEM_OHDR, chunk_addr, chunk_size, H5P_DEFAULT, oh->chunk[chunkno].image) < 0) { HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header data"); @@ -488,6 +491,7 @@ H5O_load(H5F_t *f, haddr_t addr, const void UNUSED *_udata1, curmesg++) { if (H5O_CONT_ID == oh->mesg[curmesg].type->id) { uint8_t *p2 = oh->mesg[curmesg].raw; + cont = (H5O_CONT->decode) (f, p2, NULL); oh->mesg[curmesg].native = cont; chunk_addr = cont->addr; @@ -503,10 +507,10 @@ done: /* * Free resources. */ - int i; + uintn u; - for (i = 0; i < oh->nchunks; i++) - oh->chunk[i].image = H5FL_BLK_FREE(chunk_image,oh->chunk[i].image); + for (u = 0; u < oh->nchunks; u++) + oh->chunk[u].image = H5FL_BLK_FREE(chunk_image,oh->chunk[u].image); oh->chunk = H5FL_ARR_FREE(H5O_chunk_t,oh->chunk); oh->mesg = H5FL_ARR_FREE(H5O_mesg_t,oh->mesg); H5FL_FREE(H5O_t,oh); @@ -542,7 +546,8 @@ static herr_t H5O_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5O_t *oh) { uint8_t buf[16], *p; - intn i, id; + intn id; + uintn u; H5O_cont_t *cont = NULL; herr_t (*encode)(H5F_t*, uint8_t*, const void*) = NULL; uintn combine=0; /* Whether to combine the object header prefix & the first chunk */ @@ -577,125 +582,125 @@ H5O_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5O_t *oh) HDmemset (p, 0, H5O_SIZEOF_HDR(f)-12); /* write the object header prefix */ - /* Check if we can combine the object header prefix & the first chunk into one I/O operation */ - if(oh->chunk[0].dirty && (addr+H5O_SIZEOF_HDR(f))==oh->chunk[0].addr) { - combine=1; - } /* end if */ - else { + + /* Check if we can combine the object header prefix & the first chunk into one I/O operation */ + if(oh->chunk[0].dirty && (addr+H5O_SIZEOF_HDR(f))==oh->chunk[0].addr) { + combine=1; + } /* end if */ + else { #ifdef H5_HAVE_PARALLEL - if (IS_H5FD_MPIO(f)) - H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 will write*/ + if (IS_H5FD_MPIO(f)) + H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 will write*/ #endif /* H5_HAVE_PARALLEL */ - if (H5F_block_write(f, H5FD_MEM_OHDR, addr, (hsize_t)H5O_SIZEOF_HDR(f), - H5P_DEFAULT, buf) < 0) { - HRETURN_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, - "unable to write object header hdr to disk"); - } - } /* end else */ - - /* encode messages */ - for (i = 0; i < oh->nmesgs; i++) { - if (oh->mesg[i].dirty) { - p = oh->mesg[i].raw - H5O_SIZEOF_MSGHDR(f); - - id = oh->mesg[i].type->id; - UINT16ENCODE(p, id); - assert (oh->mesg[i].raw_size<65536); - UINT16ENCODE(p, oh->mesg[i].raw_size); - *p++ = oh->mesg[i].flags; - *p++ = 0; /*reserved*/ - *p++ = 0; /*reserved*/ - *p++ = 0; /*reserved*/ + if (H5F_block_write(f, H5FD_MEM_OHDR, addr, H5O_SIZEOF_HDR(f), + H5P_DEFAULT, buf) < 0) { + HRETURN_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, + "unable to write object header hdr to disk"); + } + } /* end else */ - if (oh->mesg[i].native) { - assert(oh->mesg[i].type->encode); - - /* allocate file space for chunks that have none yet */ - if (H5O_CONT_ID == oh->mesg[i].type->id && - !H5F_addr_defined(((H5O_cont_t *)(oh->mesg[i].native))->addr)) { - cont = (H5O_cont_t *) (oh->mesg[i].native); - assert(cont->chunkno >= 0); - assert(cont->chunkno < oh->nchunks); - assert(!H5F_addr_defined(oh->chunk[cont->chunkno].addr)); - cont->size = oh->chunk[cont->chunkno].size; - if (HADDR_UNDEF==(cont->addr=H5MF_alloc(f, - H5FD_MEM_OHDR, (hsize_t)cont->size))) { - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "unable to allocate space for object header data"); - } - oh->chunk[cont->chunkno].addr = cont->addr; - } + /* encode messages */ + for (u = 0; u < oh->nmesgs; u++) { + if (oh->mesg[u].dirty) { + p = oh->mesg[u].raw - H5O_SIZEOF_MSGHDR(f); + + id = oh->mesg[u].type->id; + UINT16ENCODE(p, id); + assert (oh->mesg[u].raw_size<65536); + UINT16ENCODE(p, oh->mesg[u].raw_size); + *p++ = oh->mesg[u].flags; + *p++ = 0; /*reserved*/ + *p++ = 0; /*reserved*/ + *p++ = 0; /*reserved*/ - /* - * Encode the message. If the message is shared then we - * encode a Shared Object message instead of the object - * which is being shared. - */ - assert(oh->mesg[i].raw >= - oh->chunk[oh->mesg[i].chunkno].image); - assert (oh->mesg[i].raw_size == - H5O_ALIGN (oh->mesg[i].raw_size)); - assert(oh->mesg[i].raw + oh->mesg[i].raw_size <= - oh->chunk[oh->mesg[i].chunkno].image + - oh->chunk[oh->mesg[i].chunkno].size); - if (oh->mesg[i].flags & H5O_FLAG_SHARED) { - encode = H5O_SHARED->encode; - } else { - encode = oh->mesg[i].type->encode; - } - if ((encode)(f, oh->mesg[i].raw, oh->mesg[i].native)<0) { - HRETURN_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, - "unable to encode object header message"); + if (oh->mesg[u].native) { + assert(oh->mesg[u].type->encode); + + /* allocate file space for chunks that have none yet */ + if (H5O_CONT_ID == oh->mesg[u].type->id && + !H5F_addr_defined(((H5O_cont_t *)(oh->mesg[u].native))->addr)) { + cont = (H5O_cont_t *) (oh->mesg[u].native); + assert(cont->chunkno < oh->nchunks); + assert(!H5F_addr_defined(oh->chunk[cont->chunkno].addr)); + cont->size = oh->chunk[cont->chunkno].size; + if (HADDR_UNDEF==(cont->addr=H5MF_alloc(f, + H5FD_MEM_OHDR, (hsize_t)cont->size))) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "unable to allocate space for object header data"); + } + oh->chunk[cont->chunkno].addr = cont->addr; + } + + /* + * Encode the message. If the message is shared then we + * encode a Shared Object message instead of the object + * which is being shared. + */ + assert(oh->mesg[u].raw >= + oh->chunk[oh->mesg[u].chunkno].image); + assert (oh->mesg[u].raw_size == + H5O_ALIGN (oh->mesg[u].raw_size)); + assert(oh->mesg[u].raw + oh->mesg[u].raw_size <= + oh->chunk[oh->mesg[u].chunkno].image + + oh->chunk[oh->mesg[u].chunkno].size); + if (oh->mesg[u].flags & H5O_FLAG_SHARED) { + encode = H5O_SHARED->encode; + } else { + encode = oh->mesg[u].type->encode; + } + if ((encode)(f, oh->mesg[u].raw, oh->mesg[u].native)<0) { + HRETURN_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, + "unable to encode object header message"); + } } - } - oh->mesg[i].dirty = FALSE; - oh->chunk[oh->mesg[i].chunkno].dirty = TRUE; + oh->mesg[u].dirty = FALSE; + oh->chunk[oh->mesg[u].chunkno].dirty = TRUE; } } /* write each chunk to disk */ - for (i = 0; i < oh->nchunks; i++) { - if (oh->chunk[i].dirty) { - assert(H5F_addr_defined(oh->chunk[i].addr)); - if(i==0 && combine) { - /* Allocate space for the combined prefix and first chunk */ - if((p=H5FL_BLK_ALLOC(chunk_image,(H5O_SIZEOF_HDR(f)+oh->chunk[i].size),0))==NULL) - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + for (u = 0; u < oh->nchunks; u++) { + if (oh->chunk[u].dirty) { + assert(H5F_addr_defined(oh->chunk[u].addr)); + if(u==0 && combine) { + /* Allocate space for the combined prefix and first chunk */ + if((p=H5FL_BLK_ALLOC(chunk_image,(H5O_SIZEOF_HDR(f)+oh->chunk[u].size),0))==NULL) + HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - /* Copy in the prefix */ - HDmemcpy(p,buf,H5O_SIZEOF_HDR(f)); + /* Copy in the prefix */ + HDmemcpy(p,buf,H5O_SIZEOF_HDR(f)); - /* Copy in the first chunk */ - HDmemcpy(p+H5O_SIZEOF_HDR(f),oh->chunk[i].image,oh->chunk[i].size); + /* Copy in the first chunk */ + HDmemcpy(p+H5O_SIZEOF_HDR(f),oh->chunk[u].image,oh->chunk[u].size); - /* Write the combined prefix/chunk out */ + /* Write the combined prefix/chunk out */ #ifdef H5_HAVE_PARALLEL - if (IS_H5FD_MPIO(f)) - H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 write*/ + if (IS_H5FD_MPIO(f)) + H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 write*/ #endif /* H5_HAVE_PARALLEL */ - if (H5F_block_write(f, H5FD_MEM_OHDR, addr, - (hsize_t)(H5O_SIZEOF_HDR(f)+oh->chunk[i].size), - H5P_DEFAULT, p) < 0) { - HRETURN_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, - "unable to write object header data to disk"); + if (H5F_block_write(f, H5FD_MEM_OHDR, addr, + (H5O_SIZEOF_HDR(f)+oh->chunk[u].size), + H5P_DEFAULT, p) < 0) { + HRETURN_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, + "unable to write object header data to disk"); + } /* end if */ + + /* Release the memory for the combined prefix/chunk */ + p = H5FL_BLK_FREE(chunk_image,p); } /* end if */ - - /* Release the memory for the combined prefix/chunk */ - p = H5FL_BLK_FREE(chunk_image,p); - } /* end if */ - else { + else { #ifdef H5_HAVE_PARALLEL - if (IS_H5FD_MPIO(f)) - H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 write*/ + if (IS_H5FD_MPIO(f)) + H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 write*/ #endif /* H5_HAVE_PARALLEL */ - if (H5F_block_write(f, H5FD_MEM_OHDR, oh->chunk[i].addr, - (hsize_t)(oh->chunk[i].size), - H5P_DEFAULT, oh->chunk[i].image) < 0) { - HRETURN_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, - "unable to write object header data to disk"); - } /* end if */ - } /* end else */ - oh->chunk[i].dirty = FALSE; + if (H5F_block_write(f, H5FD_MEM_OHDR, oh->chunk[u].addr, + (oh->chunk[u].size), + H5P_DEFAULT, oh->chunk[u].image) < 0) { + HRETURN_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, + "unable to write object header data to disk"); + } /* end if */ + } /* end else */ + oh->chunk[u].dirty = FALSE; } /* end if */ } /* end for */ oh->dirty = FALSE; @@ -703,23 +708,23 @@ H5O_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5O_t *oh) if (destroy) { /* destroy chunks */ - /*the conditional below is because of the microsoft c run time library + /*the conditional below is because of the microsoft c run time library it calls its own version of malloc and free and does checks on the mem. causes problems with this code so i am taking it out for the win32 debug version until i can figure out a way around it*/ /* I commented this back in to use the new free list routines - QAK 3/23/00 */ /* #if !defined(WIN32) && !defined(_DEBUG) */ - for (i = 0; i < oh->nchunks; i++) - oh->chunk[i].image = H5FL_BLK_FREE(chunk_image,oh->chunk[i].image); + for (u = 0; u < oh->nchunks; u++) + oh->chunk[u].image = H5FL_BLK_FREE(chunk_image,oh->chunk[u].image); /* #endif */ oh->chunk = H5FL_ARR_FREE(H5O_chunk_t,oh->chunk); /* destroy messages */ - for (i = 0; i < oh->nmesgs; i++) { - if (oh->mesg[i].flags & H5O_FLAG_SHARED) { - H5O_free(H5O_SHARED, oh->mesg[i].native); + for (u = 0; u < oh->nmesgs; u++) { + if (oh->mesg[u].flags & H5O_FLAG_SHARED) { + H5O_free(H5O_SHARED, oh->mesg[u].native); } else { - H5O_free(oh->mesg[i].type, oh->mesg[i].native); + H5O_free(oh->mesg[u].type, oh->mesg[u].native); } } oh->mesg = H5FL_ARR_FREE(H5O_mesg_t,oh->mesg); @@ -931,7 +936,8 @@ intn H5O_count (H5G_entry_t *ent, const H5O_class_t *type) { H5O_t *oh = NULL; - intn i, acc; + intn acc; + uintn u; FUNC_ENTER (H5O_count, FAIL); @@ -947,8 +953,9 @@ H5O_count (H5G_entry_t *ent, const H5O_class_t *type) "unable to load object header"); } - for (i=acc=0; i<oh->nmesgs; i++) { - if (oh->mesg[i].type==type) acc++; + for (u=acc=0; u<oh->nmesgs; u++) { + if (oh->mesg[u].type==type) + acc++; } FUNC_LEAVE (acc); @@ -979,7 +986,7 @@ htri_t H5O_exists(H5G_entry_t *ent, const H5O_class_t *type, intn sequence) { H5O_t *oh=NULL; - intn i; + uintn u; FUNC_ENTER(H5O_exists, FAIL); assert(ent); @@ -994,9 +1001,11 @@ H5O_exists(H5G_entry_t *ent, const H5O_class_t *type, intn sequence) } /* Scan through the messages looking for the right one */ - for (i=0; i<oh->nmesgs; i++) { - if (type->id!=oh->mesg[i].type->id) continue; - if (--sequence<0) break; + for (u=0; u<oh->nmesgs; u++) { + if (type->id!=oh->mesg[u].type->id) + continue; + if (--sequence<0) + break; } FUNC_LEAVE(sequence<0); @@ -1146,15 +1155,15 @@ H5O_read(H5G_entry_t *ent, const H5O_class_t *type, intn sequence, void *mesg) * The ADDR argument is passed by value. *------------------------------------------------------------------------- */ -static intn +static uintn H5O_find_in_ohdr(H5F_t *f, haddr_t addr, const H5O_class_t **type_p, intn sequence) { H5O_t *oh = NULL; - int i; + uintn u; const H5O_class_t *type = NULL; - FUNC_ENTER(H5O_find_in_ohdr, FAIL); + FUNC_ENTER(H5O_find_in_ohdr, UFAIL); /* Check args */ assert(f); @@ -1163,17 +1172,19 @@ H5O_find_in_ohdr(H5F_t *f, haddr_t addr, const H5O_class_t **type_p, /* Load the object header */ if (NULL == (oh = H5AC_find(f, H5AC_OHDR, addr, NULL, NULL))) { - HRETURN_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, + HRETURN_ERROR(H5E_OHDR, H5E_CANTLOAD, UFAIL, "unable to load object header"); } /* Scan through the messages looking for the right one */ - for (i = 0; i < oh->nmesgs; i++) { - if (*type_p && (*type_p)->id != oh->mesg[i].type->id) continue; - if (--sequence < 0) break; + for (u = 0; u < oh->nmesgs; u++) { + if (*type_p && (*type_p)->id != oh->mesg[u].type->id) + continue; + if (--sequence < 0) + break; } if (sequence >= 0) { - HRETURN_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, + HRETURN_ERROR(H5E_OHDR, H5E_NOTFOUND, UFAIL, "unable to find object header message"); } @@ -1181,16 +1192,16 @@ H5O_find_in_ohdr(H5F_t *f, haddr_t addr, const H5O_class_t **type_p, * Decode the message if necessary. If the message is shared then decode * a shared message, ignoring the message type. */ - if (oh->mesg[i].flags & H5O_FLAG_SHARED) { + if (oh->mesg[u].flags & H5O_FLAG_SHARED) { type = H5O_SHARED; } else { - type = oh->mesg[i].type; + type = oh->mesg[u].type; } - if (NULL == oh->mesg[i].native) { + if (NULL == oh->mesg[u].native) { assert(type->decode); - oh->mesg[i].native = (type->decode) (f, oh->mesg[i].raw, NULL); - if (NULL == oh->mesg[i].native) { - HRETURN_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, + oh->mesg[u].native = (type->decode) (f, oh->mesg[u].raw, NULL); + if (NULL == oh->mesg[u].native) { + HRETURN_ERROR(H5E_OHDR, H5E_CANTDECODE, UFAIL, "unable to decode message"); } } @@ -1199,8 +1210,8 @@ H5O_find_in_ohdr(H5F_t *f, haddr_t addr, const H5O_class_t **type_p, * Return the message type. If this is a shared message then return the * pointed-to type. */ - *type_p = oh->mesg[i].type; - FUNC_LEAVE(i); + *type_p = oh->mesg[u].type; + FUNC_LEAVE(u); } @@ -1246,7 +1257,8 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite, uintn flags, const void *mesg) { H5O_t *oh = NULL; - intn idx, sequence; + intn sequence; + uintn idx; intn ret_value = FAIL; size_t size = 0; H5O_shared_t sh_mesg = {0,{{0,0}}}; @@ -1273,8 +1285,10 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite, /* Count similar messages */ for (idx = 0, sequence = -1; idx < oh->nmesgs; idx++) { - if (type->id != oh->mesg[idx].type->id) continue; - if (++sequence == overwrite) break; + if (type->id != oh->mesg[idx].type->id) + continue; + if (++sequence == overwrite) + break; } /* Was the right message found? */ @@ -1338,7 +1352,7 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite, } } idx = H5O_alloc(ent->file, oh, type, size); - if (idx < 0) { + if (idx == UFAIL) { HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for message"); } @@ -1408,7 +1422,7 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite, static herr_t H5O_touch_oh(H5F_t *f, H5O_t *oh, hbool_t force) { - intn idx; + uintn idx; time_t now = HDtime(NULL); size_t size; @@ -1417,17 +1431,18 @@ H5O_touch_oh(H5F_t *f, H5O_t *oh, hbool_t force) /* Look for existing message */ for (idx=0; idx<oh->nmesgs; idx++) { - if (H5O_MTIME==oh->mesg[idx].type) break; + if (H5O_MTIME==oh->mesg[idx].type) + break; } /* Create a new message */ if (idx==oh->nmesgs) { - if (!force) HRETURN(SUCCEED); /*nothing to do*/ + if (!force) + HRETURN(SUCCEED); /*nothing to do*/ size = (H5O_MTIME->raw_size)(f, &now); - if ((idx=H5O_alloc(f, oh, H5O_MTIME, size))<0) { + if ((idx=H5O_alloc(f, oh, H5O_MTIME, size))==UFAIL) { HRETURN_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, - "unable to allocate space for modification time " - "message"); + "unable to allocate space for modification time message"); } } @@ -1533,7 +1548,8 @@ herr_t H5O_remove(H5G_entry_t *ent, const H5O_class_t *type, intn sequence) { H5O_t *oh = NULL; - intn i, seq, nfailed = 0; + intn seq, nfailed = 0; + uintn u; herr_t ret_value = FAIL; H5O_shared_t *sh_mesg = NULL; @@ -1556,23 +1572,24 @@ H5O_remove(H5G_entry_t *ent, const H5O_class_t *type, intn sequence) "unable to load object header"); } - for (i = seq = 0; i < oh->nmesgs; i++) { - if (type->id != oh->mesg[i].type->id) continue; + for (u = seq = 0; u < oh->nmesgs; u++) { + if (type->id != oh->mesg[u].type->id) + continue; if (seq++ == sequence || H5O_ALL == sequence) { /* * Keep track of how many times we failed trying to remove constant * messages. */ - if (oh->mesg[i].flags & H5O_FLAG_CONSTANT) { + if (oh->mesg[u].flags & H5O_FLAG_CONSTANT) { nfailed++; continue; } - if (oh->mesg[i].flags & H5O_FLAG_SHARED) { - if (NULL==oh->mesg[i].native) { - sh_mesg = (H5O_SHARED->decode)(ent->file, oh->mesg[i].raw, + if (oh->mesg[u].flags & H5O_FLAG_SHARED) { + if (NULL==oh->mesg[u].native) { + sh_mesg = (H5O_SHARED->decode)(ent->file, oh->mesg[u].raw, NULL); - if (NULL==(oh->mesg[i].native = sh_mesg)) { + if (NULL==(oh->mesg[u].native = sh_mesg)) { HGOTO_ERROR (H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode shared message info"); } @@ -1593,10 +1610,10 @@ H5O_remove(H5G_entry_t *ent, const H5O_class_t *type, intn sequence) } /* change message type to nil and zero it */ - oh->mesg[i].type = H5O_NULL; - HDmemset(oh->mesg[i].raw, 0, oh->mesg[i].raw_size); - oh->mesg[i].native = H5O_free (type, oh->mesg[i].native); - oh->mesg[i].dirty = TRUE; + oh->mesg[u].type = H5O_NULL; + HDmemset(oh->mesg[u].raw, 0, oh->mesg[u].raw_size); + oh->mesg[u].native = H5O_free (type, oh->mesg[u].native); + oh->mesg[u].dirty = TRUE; oh->dirty = TRUE; H5O_touch_oh(ent->file, oh, FALSE); } @@ -1646,23 +1663,24 @@ H5O_remove(H5G_entry_t *ent, const H5O_class_t *type, intn sequence) * memory. *------------------------------------------------------------------------- */ -static intn -H5O_alloc_extend_chunk(H5O_t *oh, intn chunkno, size_t size) +static uintn +H5O_alloc_extend_chunk(H5O_t *oh, uintn chunkno, size_t size) { - intn idx, i; + uintn u; + uintn idx; size_t delta, old_size; size_t aligned_size = H5O_ALIGN(size); uint8_t *old_addr; - FUNC_ENTER(H5O_alloc_extend_chunk, FAIL); + FUNC_ENTER(H5O_alloc_extend_chunk, UFAIL); /* check args */ assert(oh); - assert(chunkno >= 0 && chunkno < oh->nchunks); + assert(chunkno < oh->nchunks); assert(size > 0); if (H5F_addr_defined(oh->chunk[chunkno].addr)) { - HRETURN_ERROR(H5E_OHDR, H5E_NOSPACE, FAIL, "chunk is on disk"); + HRETURN_ERROR(H5E_OHDR, H5E_NOSPACE, UFAIL, "chunk is on disk"); } /* try to extend a null message */ @@ -1680,9 +1698,9 @@ H5O_alloc_extend_chunk(H5O_t *oh, intn chunkno, size_t size) /* Be careful not to indroduce garbage */ oh->chunk[chunkno].image = H5FL_BLK_REALLOC(chunk_image,old_addr, - (hsize_t)(oh->chunk[chunkno].size + delta)); + (oh->chunk[chunkno].size + delta)); if (NULL==oh->chunk[chunkno].image) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed"); } HDmemset(oh->chunk[chunkno].image + oh->chunk[chunkno].size, @@ -1691,10 +1709,10 @@ H5O_alloc_extend_chunk(H5O_t *oh, intn chunkno, size_t size) /* adjust raw addresses for messages of this chunk */ if (old_addr != oh->chunk[chunkno].image) { - for (i = 0; i < oh->nmesgs; i++) { - if (oh->mesg[i].chunkno == chunkno) { - oh->mesg[i].raw = oh->chunk[chunkno].image + - (oh->mesg[i].raw - old_addr); + for (u = 0; u < oh->nmesgs; u++) { + if (oh->mesg[u].chunkno == chunkno) { + oh->mesg[u].raw = oh->chunk[chunkno].image + + (oh->mesg[u].raw - old_addr); } } } @@ -1704,13 +1722,14 @@ H5O_alloc_extend_chunk(H5O_t *oh, intn chunkno, size_t size) /* create a new null message */ if (oh->nmesgs >= oh->alloc_nmesgs) { - hsize_t na = oh->alloc_nmesgs + H5O_NMESGS; + size_t na = oh->alloc_nmesgs + H5O_NMESGS; H5O_mesg_t *x = H5FL_ARR_REALLOC (H5O_mesg_t, oh->mesg, na); + if (NULL==x) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed"); } - oh->alloc_nmesgs = (intn)na; + oh->alloc_nmesgs = na; oh->mesg = x; } delta = MAX(H5O_MIN_SIZE, aligned_size+H5O_SIZEOF_MSGHDR(f)); @@ -1729,9 +1748,9 @@ H5O_alloc_extend_chunk(H5O_t *oh, intn chunkno, size_t size) old_size = oh->chunk[chunkno].size; oh->chunk[chunkno].size += delta; oh->chunk[chunkno].image = H5FL_BLK_REALLOC(chunk_image,old_addr, - (hsize_t)oh->chunk[chunkno].size); + oh->chunk[chunkno].size); if (NULL==oh->chunk[chunkno].image) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed"); } HDmemset(oh->chunk[chunkno].image+old_size, 0, @@ -1739,10 +1758,10 @@ H5O_alloc_extend_chunk(H5O_t *oh, intn chunkno, size_t size) /* adjust raw addresses for messages of this chunk */ if (old_addr != oh->chunk[chunkno].image) { - for (i = 0; i < oh->nmesgs; i++) { - if (oh->mesg[i].chunkno == chunkno) { - oh->mesg[i].raw = oh->chunk[chunkno].image + - (oh->mesg[i].raw - old_addr); + for (u = 0; u < oh->nmesgs; u++) { + if (oh->mesg[u].chunkno == chunkno) { + oh->mesg[u].raw = oh->chunk[chunkno].image + + (oh->mesg[u].raw - old_addr); } } } @@ -1777,18 +1796,19 @@ H5O_alloc_extend_chunk(H5O_t *oh, intn chunkno, size_t size) * *------------------------------------------------------------------------- */ -static intn +static uintn H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) { size_t cont_size; /*continuation message size */ intn found_null = (-1); /*best fit null message */ intn found_other = (-1); /*best fit other message */ - intn idx = FAIL; /*message number return value */ + uintn idx; /*message number return value */ uint8_t *p = NULL; /*ptr into new chunk */ H5O_cont_t *cont = NULL; /*native continuation message */ - intn i, chunkno; + intn chunkno; + uintn u; - FUNC_ENTER(H5O_alloc_new_chunk, FAIL); + FUNC_ENTER(H5O_alloc_new_chunk, UFAIL); /* check args */ assert (oh); @@ -1802,23 +1822,23 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) * Don't ever move continuation message from one chunk to another. */ cont_size = H5O_ALIGN (H5F_SIZEOF_ADDR(f) + H5F_SIZEOF_SIZE(f)); - for (i=0; i<oh->nmesgs; i++) { - if (H5O_NULL_ID == oh->mesg[i].type->id) { - if (cont_size == oh->mesg[i].raw_size) { - found_null = i; + for (u=0; u<oh->nmesgs; u++) { + if (H5O_NULL_ID == oh->mesg[u].type->id) { + if (cont_size == oh->mesg[u].raw_size) { + found_null = u; break; - } else if (oh->mesg[i].raw_size >= cont_size && + } else if (oh->mesg[u].raw_size >= cont_size && (found_null < 0 || - (oh->mesg[i].raw_size < + (oh->mesg[u].raw_size < oh->mesg[found_null].raw_size))) { - found_null = i; + found_null = u; } - } else if (H5O_CONT_ID == oh->mesg[i].type->id) { + } else if (H5O_CONT_ID == oh->mesg[u].type->id) { /*don't consider continuation messages */ - } else if (oh->mesg[i].raw_size >= cont_size && + } else if (oh->mesg[u].raw_size >= cont_size && (found_other < 0 || - oh->mesg[i].raw_size < oh->mesg[found_other].raw_size)) { - found_other = i; + oh->mesg[u].raw_size < oh->mesg[found_other].raw_size)) { + found_other = u; } } assert(found_null >= 0 || found_other >= 0); @@ -1843,13 +1863,14 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) * Create the new chunk without giving it a file address. */ if (oh->nchunks >= oh->alloc_nchunks) { - hsize_t na = oh->alloc_nchunks + H5O_NCHUNKS; + size_t na = oh->alloc_nchunks + H5O_NCHUNKS; H5O_chunk_t *x = H5FL_ARR_REALLOC (H5O_chunk_t, oh->chunk, na); + if (!x) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed"); } - oh->alloc_nchunks = (intn)na; + oh->alloc_nchunks = na; oh->chunk = x; } chunkno = oh->nchunks++; @@ -1857,7 +1878,7 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) oh->chunk[chunkno].addr = HADDR_UNDEF; oh->chunk[chunkno].size = size; if (NULL==(oh->chunk[chunkno].image = p = H5FL_BLK_ALLOC(chunk_image,size,1))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed"); } @@ -1867,13 +1888,14 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) */ if (oh->nmesgs + 3 > oh->alloc_nmesgs) { int old_alloc=oh->alloc_nmesgs; - hsize_t na = oh->alloc_nmesgs + MAX (H5O_NMESGS, 3); + size_t na = oh->alloc_nmesgs + MAX (H5O_NMESGS, 3); H5O_mesg_t *x = H5FL_ARR_REALLOC (H5O_mesg_t, oh->mesg, na); + if (!x) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed"); } - oh->alloc_nmesgs = (intn)na; + oh->alloc_nmesgs = na; oh->mesg = x; /* Set new object header info to zeros */ @@ -1885,13 +1907,13 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) * Describe the messages of the new chunk. */ if (found_null < 0) { - found_null = i = oh->nmesgs++; - oh->mesg[i].type = H5O_NULL; - oh->mesg[i].dirty = TRUE; - oh->mesg[i].native = NULL; - oh->mesg[i].raw = oh->mesg[found_other].raw; - oh->mesg[i].raw_size = oh->mesg[found_other].raw_size; - oh->mesg[i].chunkno = oh->mesg[found_other].chunkno; + found_null = u = oh->nmesgs++; + oh->mesg[u].type = H5O_NULL; + oh->mesg[u].dirty = TRUE; + oh->mesg[u].native = NULL; + oh->mesg[u].raw = oh->mesg[found_other].raw; + oh->mesg[u].raw_size = oh->mesg[found_other].raw_size; + oh->mesg[u].chunkno = oh->mesg[found_other].chunkno; oh->mesg[found_other].dirty = TRUE; oh->mesg[found_other].raw = p + H5O_SIZEOF_MSGHDR(f); @@ -1913,16 +1935,16 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) * two null messages. */ if (oh->mesg[found_null].raw_size > cont_size) { - i = oh->nmesgs++; - oh->mesg[i].type = H5O_NULL; - oh->mesg[i].dirty = TRUE; - oh->mesg[i].native = NULL; - oh->mesg[i].raw = oh->mesg[found_null].raw + + u = oh->nmesgs++; + oh->mesg[u].type = H5O_NULL; + oh->mesg[u].dirty = TRUE; + oh->mesg[u].native = NULL; + oh->mesg[u].raw = oh->mesg[found_null].raw + cont_size + H5O_SIZEOF_MSGHDR(f); - oh->mesg[i].raw_size = oh->mesg[found_null].raw_size - + oh->mesg[u].raw_size = oh->mesg[found_null].raw_size - (cont_size + H5O_SIZEOF_MSGHDR(f)); - oh->mesg[i].chunkno = oh->mesg[found_null].chunkno; + oh->mesg[u].chunkno = oh->mesg[found_null].chunkno; oh->mesg[found_null].dirty = TRUE; oh->mesg[found_null].raw_size = cont_size; @@ -1934,7 +1956,7 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) oh->mesg[found_null].type = H5O_CONT; oh->mesg[found_null].dirty = TRUE; if (NULL==(cont = H5MM_calloc(sizeof(H5O_cont_t)))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed"); } cont->addr = HADDR_UNDEF; @@ -1963,15 +1985,15 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) * *------------------------------------------------------------------------- */ -static intn +static uintn H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size) { - intn chunkno; - intn idx; - intn null_idx; + uintn chunkno; + uintn idx; + uintn null_idx; size_t aligned_size = H5O_ALIGN(size); - FUNC_ENTER(H5O_alloc, FAIL); + FUNC_ENTER(H5O_alloc, UFAIL); /* check args */ assert (oh); @@ -2001,7 +2023,7 @@ H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size) * since we can just increase the size of that chunk. */ for (chunkno = 0; chunkno < oh->nchunks; chunkno++) { - if ((idx = H5O_alloc_extend_chunk(oh, chunkno, size)) >= 0) { + if ((idx = H5O_alloc_extend_chunk(oh, chunkno, size)) != UFAIL) { break; } H5E_clear(); @@ -2010,9 +2032,9 @@ H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size) /* * Create a new chunk */ - if (idx < 0) { - if ((idx = H5O_alloc_new_chunk(f, oh, size)) < 0) { - HRETURN_ERROR(H5E_OHDR, H5E_NOSPACE, FAIL, + if (idx == UFAIL) { + if ((idx = H5O_alloc_new_chunk(f, oh, size)) == UFAIL) { + HRETURN_ERROR(H5E_OHDR, H5E_NOSPACE, UFAIL, "unable to create a new object header data chunk"); } } @@ -2024,13 +2046,14 @@ H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size) if (oh->nmesgs >= oh->alloc_nmesgs) { int old_alloc=oh->alloc_nmesgs; - hsize_t na = oh->alloc_nmesgs + H5O_NMESGS; + size_t na = oh->alloc_nmesgs + H5O_NMESGS; H5O_mesg_t *x = H5FL_ARR_REALLOC (H5O_mesg_t, oh->mesg, na); + if (!x) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed"); } - oh->alloc_nmesgs = (intn)na; + oh->alloc_nmesgs = na; oh->mesg = x; /* Set new object header info to zeros */ @@ -2136,7 +2159,7 @@ herr_t H5O_debug(H5F_t *f, haddr_t addr, FILE *stream, intn indent, intn fwidth) { H5O_t *oh = NULL; - intn i, chunkno; + uintn i, chunkno; size_t mesg_total = 0, chunk_total = 0; int *sequence; haddr_t tmp_addr; @@ -2173,12 +2196,12 @@ H5O_debug(H5F_t *f, haddr_t addr, FILE *stream, intn indent, intn fwidth) HDfprintf(stream, "%*s%-*s %d\n", indent, "", fwidth, "Number of links:", (int) (oh->nlink)); - HDfprintf(stream, "%*s%-*s %d (%d)\n", indent, "", fwidth, + HDfprintf(stream, "%*s%-*s %u (%u)\n", indent, "", fwidth, "Number of messages (allocated):", - (int) (oh->nmesgs), (int) (oh->alloc_nmesgs)); - HDfprintf(stream, "%*s%-*s %d (%d)\n", indent, "", fwidth, + (unsigned) (oh->nmesgs), (unsigned) (oh->alloc_nmesgs)); + HDfprintf(stream, "%*s%-*s %u (%u)\n", indent, "", fwidth, "Number of chunks (allocated):", - (int) (oh->nchunks), (int) (oh->alloc_nchunks)); + (unsigned) (oh->nchunks), (unsigned) (oh->alloc_nchunks)); /* debug each chunk */ for (i=0, chunk_total=0; i<oh->nchunks; i++) { @@ -2243,7 +2266,7 @@ H5O_debug(H5F_t *f, haddr_t addr, FILE *stream, intn indent, intn fwidth) "Chunk number:", (int) (oh->mesg[i].chunkno)); chunkno = oh->mesg[i].chunkno; - if (chunkno < 0 || chunkno >= oh->nchunks) { + if (chunkno >= oh->nchunks) { HDfprintf(stream, "*** BAD CHUNK NUMBER\n"); } diff --git a/src/H5Oefl.c b/src/H5Oefl.c index c5ac308..f26e276 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -404,7 +404,7 @@ H5O_efl_total_size (H5O_efl_t *efl) */ herr_t H5O_efl_read (H5F_t UNUSED *f, const H5O_efl_t *efl, haddr_t addr, - hsize_t size, uint8_t *buf) + size_t size, uint8_t *buf) { int i, fd=-1; size_t to_read, cur, skip=0; @@ -489,7 +489,7 @@ H5O_efl_read (H5F_t UNUSED *f, const H5O_efl_t *efl, haddr_t addr, */ herr_t H5O_efl_write (H5F_t UNUSED *f, const H5O_efl_t *efl, haddr_t addr, - hsize_t size, const uint8_t *buf) + size_t size, const uint8_t *buf) { int i, fd=-1; size_t to_write, cur, skip=0; diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 19ba259..9a92bb3 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -89,7 +89,7 @@ typedef struct H5O_mesg_t { void *native; /*native format message */ uint8_t *raw; /*ptr to raw data */ size_t raw_size; /*size with alignment */ - intn chunkno; /*chunk number for this mesg */ + uintn chunkno; /*chunk number for this mesg */ } H5O_mesg_t; typedef struct H5O_chunk_t { @@ -105,11 +105,11 @@ typedef struct H5O_t { hbool_t dirty; /*out of data wrt disk */ intn version; /*version number */ intn nlink; /*link count */ - intn nmesgs; /*number of messages */ - intn alloc_nmesgs; /*number of message slots */ + uintn nmesgs; /*number of messages */ + uintn alloc_nmesgs; /*number of message slots */ H5O_mesg_t *mesg; /*array of messages */ - intn nchunks; /*number of chunks */ - intn alloc_nchunks; /*chunks allocated */ + uintn nchunks; /*number of chunks */ + uintn alloc_nchunks; /*chunks allocated */ H5O_chunk_t *chunk; /*array of chunks */ } H5O_t; @@ -253,7 +253,7 @@ typedef struct H5O_cont_t { size_t size; /*size of continuation block */ /* the following field(s) do not appear on disk */ - intn chunkno; /*chunk this mesg refers to */ + uintn chunkno; /*chunk this mesg refers to */ } H5O_cont_t; /* @@ -297,9 +297,9 @@ __DLL__ herr_t H5O_debug(H5F_t *f, haddr_t addr, FILE * stream, intn indent, /* EFL operators */ __DLL__ hsize_t H5O_efl_total_size(H5O_efl_t *efl); __DLL__ herr_t H5O_efl_read(H5F_t *f, const H5O_efl_t *efl, haddr_t addr, - hsize_t size, uint8_t *buf); + size_t size, uint8_t *buf); __DLL__ herr_t H5O_efl_write(H5F_t *f, const H5O_efl_t *efl, haddr_t addr, - hsize_t size, const uint8_t *buf); + size_t size, const uint8_t *buf); /* Fill value operators */ __DLL__ herr_t H5O_fill_convert(H5O_fill_t *fill, H5T_t *type); @@ -2680,7 +2680,7 @@ H5Pget_xfer(hid_t plist_id, H5D_transfer_t *data_xfer_mode) */ herr_t H5Pset_cache(hid_t plist_id, int mdc_nelmts, - int rdcc_nelmts, size_t rdcc_nbytes, double rdcc_w0) + size_t rdcc_nelmts, size_t rdcc_nbytes, double rdcc_w0) { H5F_access_t *fapl = NULL; @@ -2698,10 +2698,6 @@ H5Pset_cache(hid_t plist_id, int mdc_nelmts, HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "meta data cache size must be non-negative"); } - if (rdcc_nelmts<0) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "raw data chunk cache nelmts must be non-negative"); - } if (rdcc_w0<0.0 || rdcc_w0>1.0) { HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "raw data cache w0 value must be between 0.0 and 1.0 " @@ -2738,7 +2734,7 @@ H5Pset_cache(hid_t plist_id, int mdc_nelmts, */ herr_t H5Pget_cache(hid_t plist_id, int *mdc_nelmts, - int *rdcc_nelmts, size_t *rdcc_nbytes, double *rdcc_w0) + size_t *rdcc_nelmts, size_t *rdcc_nbytes, double *rdcc_w0) { H5F_access_t *fapl = NULL; @@ -2791,7 +2787,7 @@ H5Pget_cache(hid_t plist_id, int *mdc_nelmts, *------------------------------------------------------------------------- */ herr_t -H5Pset_buffer(hid_t plist_id, hsize_t size, void *tconv, void *bkg) +H5Pset_buffer(hid_t plist_id, size_t size, void *tconv, void *bkg) { H5D_xfer_t *plist = NULL; @@ -3772,12 +3768,12 @@ H5Pget_vlen_mem_manager(hid_t plist_id, H5MM_allocate_t *alloc_func/*out*/, *------------------------------------------------------------------------- */ herr_t -H5Pset_meta_block_size(hid_t fapl_id, hsize_t size) +H5Pset_meta_block_size(hid_t fapl_id, size_t size) { H5F_access_t *fapl = NULL; FUNC_ENTER (H5Pset_meta_block_size, FAIL); - H5TRACE2("e","ih",fapl_id,size); + H5TRACE2("e","iz",fapl_id,size); /* Check args */ if (H5P_FILE_ACCESS != H5P_get_class (fapl_id) || @@ -3809,7 +3805,7 @@ H5Pset_meta_block_size(hid_t fapl_id, hsize_t size) *------------------------------------------------------------------------- */ herr_t -H5Pget_meta_block_size(hid_t fapl_id, hsize_t *size/*out*/) +H5Pget_meta_block_size(hid_t fapl_id, size_t *size/*out*/) { H5F_access_t *fapl = NULL; @@ -3856,12 +3852,12 @@ H5Pget_meta_block_size(hid_t fapl_id, hsize_t *size/*out*/) *------------------------------------------------------------------------- */ herr_t -H5Pset_sieve_buf_size(hid_t fapl_id, hsize_t size) +H5Pset_sieve_buf_size(hid_t fapl_id, size_t size) { H5F_access_t *fapl = NULL; FUNC_ENTER (H5Pset_sieve_buf_size, FAIL); - H5TRACE2("e","ih",fapl_id,size); + H5TRACE2("e","iz",fapl_id,size); /* Check args */ if (H5P_FILE_ACCESS != H5P_get_class (fapl_id) || @@ -3893,7 +3889,7 @@ H5Pset_sieve_buf_size(hid_t fapl_id, hsize_t size) *------------------------------------------------------------------------- */ herr_t -H5Pget_sieve_buf_size(hid_t fapl_id, hsize_t *size/*out*/) +H5Pget_sieve_buf_size(hid_t fapl_id, size_t *size/*out*/) { H5F_access_t *fapl = NULL; @@ -3915,6 +3911,93 @@ H5Pget_sieve_buf_size(hid_t fapl_id, hsize_t *size/*out*/) } /* end H5Pget_sieve_buf_size() */ +/*------------------------------------------------------------------------- + * Function: H5Pset_hyper_vector_size + * + * Purpose: Given a dataset transfer property list, set the number of + * "I/O vectors" (offset and length pairs) which are to be + * accumulated in memory before being issued to the lower levels + * of the library for reading or writing the actual data. + * Increasing the number should give better performance, but use + * more memory during hyperslab I/O. The vector size must be + * greater than 1. + * + * The default is to use 1024 vectors for I/O during hyperslab + * reading/writing. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, July 9, 2001 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_hyper_vector_size(hid_t plist_id, size_t vector_size) +{ + H5D_xfer_t *plist = NULL; + + FUNC_ENTER (H5Pset_hyper_vector_size, FAIL); + H5TRACE2("e","iz",plist_id,vector_size); + + /* Check arguments */ + if (H5P_DATASET_XFER != H5P_get_class (plist_id) || + NULL == (plist = H5I_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "not a dataset transfer property list"); + } + + if (vector_size<1) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "vector size too small"); + } + + /* Update property list */ + plist->vector_size = vector_size; + + FUNC_LEAVE (SUCCEED); +} /* end H5Pset_hyper_vector_size() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_hyper_vector_size + * + * Purpose: Reads values previously set with H5Pset_hyper_vector_size(). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, July 9, 2001 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_hyper_vector_size(hid_t plist_id, size_t *vector_size/*out*/) +{ + H5D_xfer_t *plist = NULL; + + FUNC_ENTER (H5Pget_hyper_vector_size, FAIL); + H5TRACE2("e","ix",plist_id,vector_size); + + /* Check arguments */ + if (H5P_DATASET_XFER != H5P_get_class (plist_id) || + NULL == (plist = H5I_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "not a dataset transfer property list"); + } + + /* Return values */ + if (vector_size) + *vector_size = plist->vector_size; + + FUNC_LEAVE (SUCCEED); +} /* end H5Pget_hyper_vector_size() */ + + /*-------------------------------------------------------------------------- NAME H5P_copy_prop diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 6c49956..6dc32bb 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -182,7 +182,7 @@ __DLL__ herr_t H5Pget_xfer(hid_t plist_id, H5D_transfer_t *data_xfer_mode); __DLL__ hid_t H5Pget_driver(hid_t plist_id); #endif /* WANT_H5_V1_2_COMPAT */ __DLL__ void *H5Pget_driver_info(hid_t plist_id); -__DLL__ herr_t H5Pset_buffer(hid_t plist_id, hsize_t size, void *tconv, +__DLL__ herr_t H5Pset_buffer(hid_t plist_id, size_t size, void *tconv, void *bkg); __DLL__ hsize_t H5Pget_buffer(hid_t plist_id, void **tconv/*out*/, void **bkg/*out*/); @@ -198,10 +198,10 @@ __DLL__ H5Z_filter_t H5Pget_filter(hid_t plist_id, int filter, unsigned cd_values[]/*out*/, size_t namelen, char name[]); __DLL__ herr_t H5Pset_deflate(hid_t plist_id, unsigned aggression); -__DLL__ herr_t H5Pset_cache(hid_t plist_id, int mdc_nelmts, int rdcc_nelmts, +__DLL__ herr_t H5Pset_cache(hid_t plist_id, int mdc_nelmts, size_t rdcc_nelmts, size_t rdcc_nbytes, double rdcc_w0); __DLL__ herr_t H5Pget_cache(hid_t plist_id, int *mdc_nelmts/*out*/, - int *rdcc_nelmts/*out*/, + size_t *rdcc_nelmts/*out*/, size_t *rdcc_nbytes/*out*/, double *rdcc_w0); __DLL__ herr_t H5Pset_hyper_cache(hid_t plist_id, unsigned cache, unsigned limit); @@ -227,10 +227,12 @@ __DLL__ herr_t H5Pget_vlen_mem_manager(hid_t plist_id, void **alloc_info, H5MM_free_t *free_func, void **free_info); -__DLL__ herr_t H5Pset_meta_block_size(hid_t fapl_id, hsize_t size); -__DLL__ herr_t H5Pget_meta_block_size(hid_t fapl_id, hsize_t *size/*out*/); -__DLL__ herr_t H5Pset_sieve_buf_size(hid_t fapl_id, hsize_t size); -__DLL__ herr_t H5Pget_sieve_buf_size(hid_t fapl_id, hsize_t *size/*out*/); +__DLL__ herr_t H5Pset_meta_block_size(hid_t fapl_id, size_t size); +__DLL__ herr_t H5Pget_meta_block_size(hid_t fapl_id, size_t *size/*out*/); +__DLL__ herr_t H5Pset_sieve_buf_size(hid_t fapl_id, size_t size); +__DLL__ herr_t H5Pget_sieve_buf_size(hid_t fapl_id, size_t *size/*out*/); +__DLL__ herr_t H5Pset_hyper_vector_size(hid_t fapl_id, size_t size); +__DLL__ herr_t H5Pget_hyper_vector_size(hid_t fapl_id, size_t *size/*out*/); #ifdef __cplusplus } @@ -23,6 +23,10 @@ #include "H5Oprivate.h" /* object headers */ #include "H5Spkg.h" /* Data-space functions */ +/* Local static function prototypes */ +herr_t H5S_set_extent_simple (H5S_t *space, uintn rank, const hsize_t *dims, + const hsize_t *max); + /* Interface initialization */ #define PABLO_MASK H5S_mask #define INTERFACE_INIT H5S_init_interface @@ -1372,7 +1376,7 @@ H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[/*rank*/], } /* Do it */ - if (H5S_set_extent_simple(space, rank, dims, max)<0) { + if (H5S_set_extent_simple(space, (uintn)rank, dims, max)<0) { HRETURN_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set simple extent"); } @@ -1397,13 +1401,13 @@ H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[/*rank*/], *------------------------------------------------------------------------- */ herr_t -H5S_set_extent_simple (H5S_t *space, int rank, const hsize_t *dims, +H5S_set_extent_simple (H5S_t *space, uintn rank, const hsize_t *dims, const hsize_t *max) { FUNC_ENTER(H5S_set_extent_simple, FAIL); /* Check args */ - assert(rank>=0 && rank<=H5S_MAX_RANK); + assert(rank<=H5S_MAX_RANK); assert(0==rank || dims); /* If there was a previous offset for the selection, release it */ @@ -1725,7 +1729,7 @@ H5Screate_simple(int rank, const hsize_t dims[/*rank*/], HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace"); } - if(H5S_set_extent_simple(space,rank,dims,maxdims)<0) { + if(H5S_set_extent_simple(space,(uintn)rank,dims,maxdims)<0) { HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't set dimensions"); } diff --git a/src/H5Sall.c b/src/H5Sall.c index 80abaea..5c8eea8 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -22,8 +22,7 @@ #define INTERFACE_INIT NULL static intn interface_initialize_g = 0; -static herr_t H5S_all_init (const struct H5O_layout_t *layout, - const H5S_t *space, H5S_sel_iter_t *iter); +static herr_t H5S_all_init (const H5S_t *space, H5S_sel_iter_t *iter); static hsize_t H5S_all_favail (const H5S_t *space, const H5S_sel_iter_t *iter, hsize_t max); static hsize_t H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout, @@ -81,13 +80,11 @@ const H5S_mconv_t H5S_ALL_MCONV[1] = {{ *------------------------------------------------------------------------- */ static herr_t -H5S_all_init (const struct H5O_layout_t UNUSED *layout, - const H5S_t *space, H5S_sel_iter_t *sel_iter) +H5S_all_init (const H5S_t *space, H5S_sel_iter_t *sel_iter) { FUNC_ENTER (H5S_all_init, FAIL); /* Check args */ - assert (layout); assert (space && H5S_SEL_ALL==space->select.type); assert (sel_iter); @@ -167,7 +164,7 @@ H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout, H5S_sel_iter_t *file_iter, hsize_t nelmts, hid_t dxpl_id, void *buf/*out*/) { - hsize_t actual_bytes; /* The actual number of bytes to read */ + size_t actual_bytes; /* The actual number of bytes to read */ hsize_t buf_off; /* Dataset offset for copying memory */ FUNC_ENTER (H5S_all_fgath, 0); @@ -228,7 +225,7 @@ H5S_all_fscat (H5F_t *f, const struct H5O_layout_t *layout, const H5S_t *file_space, H5S_sel_iter_t *file_iter, hsize_t nelmts, hid_t dxpl_id, const void *buf) { - hsize_t actual_bytes; /* The actual number of bytes to write */ + size_t actual_bytes; /* The actual number of bytes to write */ hsize_t buf_off; /* Dataset offset for copying memory */ FUNC_ENTER (H5S_all_fscat, FAIL); diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 9ffbdb0..2257263 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -76,8 +76,7 @@ static hsize_t H5S_hyper_fwrite_opt (H5F_t *f, const struct H5O_layout_t *layout const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, hsize_t nelmts, hid_t dxpl_id, const void *_buf); -static herr_t H5S_hyper_init (const struct H5O_layout_t *layout, - const H5S_t *space, H5S_sel_iter_t *iter); +static herr_t H5S_hyper_init (const H5S_t *space, H5S_sel_iter_t *iter); static hsize_t H5S_hyper_favail (const H5S_t *space, const H5S_sel_iter_t *iter, hsize_t max); static hsize_t H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout, @@ -137,8 +136,11 @@ H5FL_DEFINE_STATIC(H5S_hyper_node_t); /* Declare a free list to manage the H5S_hyper_list_t struct */ H5FL_DEFINE_STATIC(H5S_hyper_list_t); +/* Declare a free list to manage arrays of size_t */ +H5FL_ARR_DEFINE_STATIC(size_t,-1); + /* Declare a free list to manage arrays of hsize_t */ -H5FL_ARR_DEFINE_STATIC(hsize_t,H5S_MAX_RANK); +H5FL_ARR_DEFINE_STATIC(hsize_t,-1); typedef H5S_hyper_bound_t *H5S_hyper_bound_ptr_t; /* Declare a free list to manage arrays of H5S_hyper_bound_ptr_t */ @@ -172,8 +174,7 @@ H5FL_BLK_DEFINE_STATIC(hyper_block); *------------------------------------------------------------------------- */ static herr_t -H5S_hyper_init (const struct H5O_layout_t UNUSED *layout, - const H5S_t *space, H5S_sel_iter_t *sel_iter) +H5S_hyper_init (const H5S_t *space, H5S_sel_iter_t *sel_iter) { FUNC_ENTER (H5S_hyper_init, FAIL); @@ -954,8 +955,15 @@ H5S_hyper_fread_opt (H5F_t *f, const struct H5O_layout_t *layout, const H5S_t *file_space, H5S_sel_iter_t *file_iter, hsize_t nelmts, hid_t dxpl_id, void *_buf/*out*/) { + size_t *seq_len_arr=NULL; /* Array of sequence lengths */ + hsize_t *buf_off_arr=NULL; /* Array of dataset offsets */ + size_t nseq=0; /* Number of sequence/offsets stored in the arrays */ + size_t tot_buf_size=0; /* Total number of bytes in buffer */ + hssize_t offset[H5O_LAYOUT_NDIMS]; /* Offset on disk */ hsize_t slab[H5O_LAYOUT_NDIMS]; /* Hyperslab size */ + hssize_t wrap[H5O_LAYOUT_NDIMS]; /* Bytes to wrap around at the end of a row */ + hsize_t skip[H5O_LAYOUT_NDIMS]; /* Bytes to skip between blocks */ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary block count */ hsize_t tmp_block[H5O_LAYOUT_NDIMS]; /* Temporary block offset */ uint8_t *buf=(uint8_t *)_buf; /* Alias for pointer arithmetic */ @@ -966,18 +974,26 @@ H5S_hyper_fread_opt (H5F_t *f, const struct H5O_layout_t *layout, fast_dim_block, fast_dim_count, fast_dim_buf_off; + hsize_t tot_blk_count; /* Total number of blocks left to output */ + size_t act_blk_count; /* Actual number of blocks to output */ intn fast_dim; /* Rank of the fastest changing dimension for the dataspace */ intn temp_dim; /* Temporary rank holder */ hsize_t acc; /* Accumulator */ hsize_t buf_off; /* Current buffer offset for copying memory */ - hsize_t last_buf_off; /* Last buffer offset for copying memory */ - hsize_t buf_size; /* Current size of the buffer to write */ intn i; /* Counters */ uintn u; /* Counters */ intn ndims; /* Number of dimensions of dataset */ - hsize_t actual_read; /* The actual number of elements to read in */ - hsize_t actual_bytes; /* The actual number of bytes to copy */ - hsize_t num_read=0; /* Number of elements read */ + size_t actual_read; /* The actual number of elements to read in */ + size_t actual_bytes; /* The actual number of bytes to copy */ + size_t io_left; /* The number of elements left in I/O operation */ + size_t tot_seq; /* The number of sequences filled */ + hsize_t *buf_off_arr_p; /* Pointer into the buffer offset array */ + size_t seq_count; /* Temporary count of sequences left to process */ +#ifndef NO_DUFFS_DEVICE + size_t duffs_index; /* Counting index for Duff's device */ +#endif /* NO_DUFFS_DEVICE */ + const H5D_xfer_t *xfer_parms;/* Data transfer property list */ + hsize_t ret_value=0; /* Return value */ FUNC_ENTER (H5S_hyper_fread_opt, 0); @@ -995,6 +1011,20 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) printf("%s: file_file->hyp.pos[%d]=%d\n",FUNC,(int)i,(int)file_iter->hyp.pos[i]); #endif /* QAK */ + /* Get the data transfer properties */ + if (H5P_DEFAULT==dxpl_id) { + xfer_parms = &H5D_xfer_dflt; + } else { + xfer_parms = H5I_object(dxpl_id); + assert(xfer_parms); + } /* end else */ + + /* Allocate the vector I/O arrays */ + if((seq_len_arr = H5FL_ARR_ALLOC(size_t,xfer_parms->vector_size,0))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "can't allocate vector I/O array"); + if((buf_off_arr = H5FL_ARR_ALLOC(hsize_t,xfer_parms->vector_size,0))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "can't allocate vector I/O array"); + /* Set the rank of the fastest changing dimension */ fast_dim=file_space->extent.u.simple.rank-1; ndims=file_space->extent.u.simple.rank; @@ -1005,6 +1035,10 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) acc*=file_space->extent.u.simple.size[i]; } /* end for */ + /* Set the number of elements left for I/O */ + assert(nelmts==(hsize_t)((size_t)nelmts)); /*check for overflow*/ + io_left=(size_t)nelmts; + #ifdef QAK printf("%s: fast_dim=%d\n",FUNC,(int)fast_dim); printf("%s: file_space->select.sel_info.hslab.diminfo[%d].start=%d\n",FUNC,(int)fast_dim,(int)file_space->select.sel_info.hslab.diminfo[fast_dim].start); @@ -1054,10 +1088,10 @@ printf("%s: buf_off=%ld, actual_read=%d, actual_bytes=%d\n",FUNC,(long)buf_off,( } /* Increment the offset of the buffer */ - buf+=elmt_size*actual_read; + buf+=actual_bytes; - /* Increment the count read */ - num_read+=actual_read; + /* Decrement the amount left to read */ + io_left-=actual_read; /* Advance the point iterator */ /* If we had enough buffer space to read in the rest of the sequence @@ -1079,9 +1113,9 @@ printf("%s: buf_off=%ld, actual_read=%d, actual_bytes=%d\n",FUNC,(long)buf_off,( * algorithm to compute the offsets and run through as many as possible, * until the buffer fills up. */ - if(num_read<nelmts) { /* Just in case the "remainder" above filled the buffer */ + if(io_left>0) { /* Just in case the "remainder" above filled the buffer */ #ifdef QAK -printf("%s: Check 2.0, ndims=%d, num_read=%d, nelmts=%d\n",FUNC,(int)ndims,(int)num_read,(int)nelmts); +printf("%s: Check 2.0, ndims=%d, io_left=%d, nelmts=%d\n",FUNC,(int)ndims,(int)io_left,(int)nelmts); #endif /* QAK */ /* Compute the arrays to perform I/O on */ /* Copy the location of the point to get */ @@ -1130,10 +1164,6 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) (int)i,(int)file_space->select.sel_info.hslab.diminfo[i].count); #endif /* QAK */ - /* Set the last location & length to invalid numbers */ - last_buf_off=(hsize_t)-1; - buf_size=0; - /* Set the local copy of the diminfo pointer */ tdiminfo=file_space->select.sel_info.hslab.diminfo; @@ -1141,84 +1171,288 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) fast_dim_start=tdiminfo[fast_dim].start; fast_dim_stride=tdiminfo[fast_dim].stride; fast_dim_block=tdiminfo[fast_dim].block; - fast_dim_count=tdiminfo[fast_dim].count; fast_dim_buf_off=slab[fast_dim]*fast_dim_stride; fast_dim_offset=fast_dim_start+file_space->select.offset[fast_dim]; + /* Compute the number of blocks which would fit into the buffer */ + tot_blk_count=io_left/fast_dim_block; + + /* Compute the amount to wrap at the end of each row */ + for(i=0; i<ndims; i++) + wrap[i]=(file_space->extent.u.simple.size[i]-(tdiminfo[i].stride*tdiminfo[i].count))*slab[i]; + + /* Compute the amount to skip between blocks */ + for(i=0; i<ndims; i++) + skip[i]=(tdiminfo[i].stride-tdiminfo[i].block)*slab[i]; + + /* Fill the sequence length array (since they will all be the same for optimized hyperslabs) */ + for(u=0; u<xfer_parms->vector_size; u++) + seq_len_arr[u]=actual_bytes; + /* Read in data until an entire sequence can't be read in any longer */ - while(num_read<nelmts) { - /* Check if we are running out of room in the buffer */ - if((actual_read+num_read)>nelmts) { - actual_read=nelmts-num_read; - actual_bytes=actual_read*elmt_size; - } /* end if */ + while(io_left>0) { + /* Reset copy of number of blocks in fastest dimension */ + fast_dim_count=tdiminfo[fast_dim].count-tmp_count[fast_dim]; + + /* Check if this entire row will fit into buffer */ + if(fast_dim_count<=tot_blk_count) { + + /* Entire row of blocks fits into buffer */ + act_blk_count=fast_dim_count; + + /* Loop over all the blocks in the fastest changing dimension */ + while(fast_dim_count>0) { + /* Gather the sequence */ -#ifdef QAK -printf("%s: num_read=%d\n",FUNC,(int)num_read); -for(i=0; i<file_space->extent.u.simple.rank; i++) - printf("%s: tmp_count[%d]=%d, offset[%d]=%d\n",FUNC,(int)i,(int)tmp_count[i],(int)i,(int)offset[i]); -#endif /* QAK */ + /* Compute the number of sequences to fill */ + tot_seq=MIN(xfer_parms->vector_size-nseq,fast_dim_count); - /* check for the first read */ - if(last_buf_off==(hsize_t)-1) { - last_buf_off=buf_off; - buf_size=actual_bytes; - } /* end if */ - else { - /* Check if we are extending the buffer to read */ - if((last_buf_off+buf_size)==buf_off) { - buf_size+=actual_bytes; - } /* end if */ - /* - * We've moved to another section of the dataset, read in the - * previous piece and change the last position and length to - * the current position and length - */ - else { - /* Read in the sequence */ - if (H5F_seq_read(f, dxpl_id, layout, pline, fill, efl, file_space, - elmt_size, buf_size, last_buf_off, buf/*out*/)<0) { - HRETURN_ERROR(H5E_DATASPACE, H5E_READERROR, 0, "read error"); - } /* end if */ + /* Get a copy of the number of sequences to fill */ + seq_count=tot_seq; + + /* Set the pointer to the correct starting array element */ + buf_off_arr_p=&buf_off_arr[nseq]; + +#ifdef NO_DUFFS_DEVICE + /* Fill up the buffer, or finish up the blocks in this dimension */ + while(seq_count>0) { + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + seq_count--; + } /* end while */ +#else /* NO_DUFFS_DEVICE */ + duffs_index = (seq_count + 7) / 8; + switch (seq_count % 8) { + case 0: + do + { + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + case 7: + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + case 6: + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + case 5: + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + case 4: + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + case 3: + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + case 2: + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + case 1: + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + } while (--duffs_index > 0); + } /* end switch */ +#endif /* NO_DUFFS_DEVICE */ + + /* Increment number of array elements used */ + nseq+=tot_seq; + + /* Increment the total number of bytes contained in arrays */ + tot_buf_size += tot_seq*actual_bytes; + + /* Decrement number of blocks left */ + fast_dim_count -= tot_seq; + + /* If the sequence & offset arrays are full, read them in */ + if(nseq>=xfer_parms->vector_size) { + /* Read in the sequences */ + if (H5F_seq_readv(f, dxpl_id, layout, pline, fill, efl, file_space, + elmt_size, nseq, seq_len_arr, buf_off_arr, buf/*out*/)<0) { + HRETURN_ERROR(H5E_DATASPACE, H5E_READERROR, 0, "read error"); + } /* end if */ - /* Increment the offset of the buffer */ - buf+=buf_size; + /* Increment the offset of the destination buffer */ + buf+=tot_buf_size; - /* Updated the last position and length */ - last_buf_off=buf_off; - buf_size=actual_bytes; + /* Reset the number of bytes & sequences */ + tot_buf_size=0; + nseq=0; + } /* end else */ + } /* end while */ - } /* end else */ - } /* end else */ + /* Decrement number of elements left */ + io_left -= actual_read*act_blk_count; - /* Increment the count read */ - num_read+=actual_read; + /* Decrement number of blocks left */ + tot_blk_count -= act_blk_count; - /* Increment the offset and count for the fastest changing dimension */ + /* Increment information to reflect block just processed */ + offset[fast_dim]=fast_dim_offset; /* reset the offset in the fastest dimension */ + tmp_count[fast_dim]=0; - /* Move to the next block in the current dimension */ - /* Check for partial block read! */ - if(actual_read<fast_dim_block) { - offset[fast_dim]+=actual_read; - buf_off+=actual_bytes; - continue; /* don't bother checking slower dimensions */ + /* Increment offset in destination buffer */ + buf_off += wrap[fast_dim]; } /* end if */ else { - offset[fast_dim]+=fast_dim_stride; /* reset the offset in the fastest dimension */ - buf_off+=fast_dim_buf_off; - tmp_count[fast_dim]++; - } /* end else */ - /* If this block is still in the range of blocks to output for the dimension, break out of loop */ - if(tmp_count[fast_dim]<fast_dim_count) - continue; /* don't bother checking slower dimensions */ - else { - tmp_count[fast_dim]=0; /* reset back to the beginning of the line */ - offset[fast_dim]=fast_dim_offset; + /* Entire row of blocks doesn't fit into buffer */ + act_blk_count=tot_blk_count; + + /* Reduce number of blocks to output */ + fast_dim_count=tot_blk_count; + + /* Loop over all the blocks in the fastest changing dimension */ + while(fast_dim_count>0) { + /* Gather the sequence */ + + /* Compute the number of sequences to fill */ + tot_seq=MIN(xfer_parms->vector_size-nseq,fast_dim_count); + + /* Get a copy of the number of sequences to fill */ + seq_count=tot_seq; + + /* Set the pointer to the correct starting array element */ + buf_off_arr_p=&buf_off_arr[nseq]; + + /* Fill up the buffer, or finish up the blocks in this dimension */ + while(seq_count>0) { + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + seq_count--; + } /* end while */ + + /* Increment number of array elements used */ + nseq+=tot_seq; - /* Re-compute the initial buffer offset */ - for(i=0,buf_off=0; i<ndims; i++) - buf_off+=offset[i]*slab[i]; + /* Increment the total number of bytes contained in arrays */ + tot_buf_size += tot_seq*actual_bytes; + + /* Decrement number of blocks left */ + fast_dim_count -= tot_seq; + + /* If the sequence & offset arrays are full, read them in */ + if(nseq>=xfer_parms->vector_size) { + /* Read in the sequences */ + if (H5F_seq_readv(f, dxpl_id, layout, pline, fill, efl, file_space, + elmt_size, nseq, seq_len_arr, buf_off_arr, buf/*out*/)<0) { + HRETURN_ERROR(H5E_DATASPACE, H5E_READERROR, 0, "read error"); + } /* end if */ + + /* Increment the offset of the destination buffer */ + buf+=tot_buf_size; + + /* Reset the number of bytes & sequences */ + tot_buf_size=0; + nseq=0; + } /* end else */ + } /* end while */ + + /* Decrement number of elements left */ + io_left -= actual_read*act_blk_count; + + /* Decrement number of blocks left */ + tot_blk_count -= act_blk_count; + + /* Increment information to reflect block just processed */ + offset[fast_dim]+=(fast_dim_stride*act_blk_count); /* reset the offset in the fastest dimension */ + tmp_count[fast_dim]+=act_blk_count; + + /* Handle any leftover, partial blocks in this row */ + if(io_left>0) { + actual_read=io_left; + actual_bytes=actual_read*elmt_size; + + /* Gather the sequence */ + + /* Store of length & offset */ + seq_len_arr[nseq]=actual_bytes; + buf_off_arr[nseq]=buf_off; + + /* Increment the total number of bytes contained in arrays */ + tot_buf_size += actual_bytes; + + /* Increment the number of sequences in arrays */ + nseq++; + + /* If the sequence & offset arrays are full, read them in */ + if(nseq>=xfer_parms->vector_size) { + /* Read in the sequences */ + if (H5F_seq_readv(f, dxpl_id, layout, pline, fill, efl, file_space, + elmt_size, nseq, seq_len_arr, buf_off_arr, buf/*out*/)<0) { + HRETURN_ERROR(H5E_DATASPACE, H5E_READERROR, 0, "read error"); + } /* end if */ + + /* Increment the offset of the destination buffer */ + buf+=tot_buf_size; + + /* Reset the number of bytes & sequences */ + tot_buf_size=0; + nseq=0; + } /* end else */ + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + /* Decrement the number of elements left */ + io_left -= actual_read; + + /* Increment buffer correctly */ + offset[fast_dim]+=actual_read; + } /* end if */ + + /* don't bother checking slower dimensions */ + assert(tot_blk_count==0); + assert(io_left==0); + break; } /* end else */ /* Increment the offset and count for the other dimensions */ @@ -1226,7 +1460,6 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) while(temp_dim>=0) { /* Move to the next row in the curent dimension */ offset[temp_dim]++; - buf_off+=slab[temp_dim]; tmp_block[temp_dim]++; /* If this block is still in the range of blocks to output for the dimension, break out of loop */ @@ -1235,7 +1468,7 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) else { /* Move to the next block in the current dimension */ offset[temp_dim]+=(tdiminfo[temp_dim].stride-tdiminfo[temp_dim].block); - buf_off+=(tdiminfo[temp_dim].stride-tdiminfo[temp_dim].block)*slab[temp_dim]; + buf_off += skip[temp_dim]; tmp_block[temp_dim]=0; tmp_count[temp_dim]++; @@ -1243,14 +1476,11 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) if(tmp_count[temp_dim]<tdiminfo[temp_dim].count) break; else { + offset[temp_dim]=tdiminfo[temp_dim].start+file_space->select.offset[temp_dim]; + buf_off += wrap[temp_dim]; tmp_count[temp_dim]=0; /* reset back to the beginning of the line */ tmp_block[temp_dim]=0; - offset[temp_dim]=tdiminfo[temp_dim].start+file_space->select.offset[temp_dim]; - - /* Re-compute the initial buffer offset */ - for(i=0,buf_off=0; i<ndims; i++) - buf_off+=offset[i]*slab[i]; - } + } /* end else */ } /* end else */ /* Decrement dimension count */ @@ -1258,23 +1488,36 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) } /* end while */ } /* end while */ - /* check for the last read */ - if(last_buf_off!=(hsize_t)-1) { + /* Check for any stored sequences which need to be flushed */ + if(nseq>0) { /* Read in the sequence */ - if (H5F_seq_read(f, dxpl_id, layout, pline, fill, efl, file_space, - elmt_size, buf_size, last_buf_off, buf/*out*/)<0) { + if (H5F_seq_readv(f, dxpl_id, layout, pline, fill, efl, file_space, + elmt_size, nseq, seq_len_arr, buf_off_arr, buf/*out*/)<0) { HRETURN_ERROR(H5E_DATASPACE, H5E_READERROR, 0, "read error"); } /* end if */ } /* end if */ + /* Subtract out the selection offset */ + for(i=0; i<ndims; i++) + offset[i] -= file_space->select.offset[i]; + /* Update the iterator with the location we stopped */ HDmemcpy(file_iter->hyp.pos, offset, ndims*sizeof(hssize_t)); } /* end if */ /* Decrement the number of elements left in selection */ - file_iter->hyp.elmt_left-=num_read; + file_iter->hyp.elmt_left -= (nelmts-io_left); - FUNC_LEAVE (num_read); + /* Set the return value */ + ret_value= (nelmts-io_left); + +done: + if(seq_len_arr!=NULL) + H5FL_ARR_FREE(size_t,seq_len_arr); + if(buf_off_arr!=NULL) + H5FL_ARR_FREE(hsize_t,buf_off_arr); + + FUNC_LEAVE (ret_value); } /* H5S_hyper_fread_opt() */ @@ -1543,7 +1786,7 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_io_info_t *io_info) * Failure: 0 * * Programmer: Quincey Koziol - * Tuesday, September 12, 2000 + * Friday, July 6, 2001 * * Modifications: * @@ -1557,37 +1800,52 @@ H5S_hyper_fwrite_opt (H5F_t *f, const struct H5O_layout_t *layout, const H5S_t *file_space, H5S_sel_iter_t *file_iter, hsize_t nelmts, hid_t dxpl_id, const void *_buf) { + size_t *seq_len_arr=NULL; /* Array of sequence lengths */ + hsize_t *buf_off_arr=NULL; /* Array of dataset offsets */ + size_t nseq=0; /* Number of sequence/offsets stored in the arrays */ + size_t tot_buf_size=0; /* Total number of bytes in buffer */ + hssize_t offset[H5O_LAYOUT_NDIMS]; /* Offset on disk */ hsize_t slab[H5O_LAYOUT_NDIMS]; /* Hyperslab size */ + hssize_t wrap[H5O_LAYOUT_NDIMS]; /* Bytes to wrap around at the end of a row */ + hsize_t skip[H5O_LAYOUT_NDIMS]; /* Bytes to skip between blocks */ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary block count */ hsize_t tmp_block[H5O_LAYOUT_NDIMS]; /* Temporary block offset */ - const uint8_t *buf=(const uint8_t *)_buf; /* Alias for pointer arithmetic */ - const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ + const uint8_t *buf=_buf; /* Alias for pointer arithmetic */ + const H5S_hyper_dim_t *tdiminfo; /* Local pointer to diminfo information */ hssize_t fast_dim_start, /* Local copies of fastest changing dimension info */ fast_dim_offset; hsize_t fast_dim_stride, /* Local copies of fastest changing dimension info */ fast_dim_block, fast_dim_count, fast_dim_buf_off; + hsize_t tot_blk_count; /* Total number of blocks left to output */ + size_t act_blk_count; /* Actual number of blocks to output */ intn fast_dim; /* Rank of the fastest changing dimension for the dataspace */ intn temp_dim; /* Temporary rank holder */ hsize_t acc; /* Accumulator */ - hsize_t buf_off; /* Buffer offset for copying memory */ - hsize_t last_buf_off; /* Last buffer offset for copying memory */ - hsize_t buf_size; /* Current size of the buffer to write */ + hsize_t buf_off; /* Current buffer offset for copying memory */ intn i; /* Counters */ - uintn u; /* Counters */ + uintn u; /* Counters */ intn ndims; /* Number of dimensions of dataset */ - hsize_t actual_write; /* The actual number of elements to read in */ - hsize_t actual_bytes; /* The actual number of bytes to copy */ - hsize_t num_write=0; /* Number of elements read */ + size_t actual_write; /* The actual number of elements to write out */ + size_t actual_bytes; /* The actual number of bytes to copy */ + size_t io_left; /* The number of elements left in I/O operation */ + size_t tot_seq; /* The number of sequences filled */ + hsize_t *buf_off_arr_p; /* Pointer into the buffer offset array */ + size_t seq_count; /* Temporary count of sequences left to process */ +#ifndef NO_DUFFS_DEVICE + size_t duffs_index; /* Counting index for Duff's device */ +#endif /* NO_DUFFS_DEVICE */ + const H5D_xfer_t *xfer_parms;/* Data transfer property list */ + hsize_t ret_value=0; /* Return value */ FUNC_ENTER (H5S_hyper_fwrite_opt, 0); #ifdef QAK -printf("%s: Called!\n",FUNC); +printf("%s: Called!, file_iter->hyp.pos[0]==%d\n",FUNC,(int)file_iter->hyp.pos[0]); #endif /* QAK */ - /* Check if this is the first element read in from the hyperslab */ + /* Check if this is the first element written from the hyperslab */ if(file_iter->hyp.pos[0]==(-1)) { for(u=0; u<file_space->extent.u.simple.rank; u++) file_iter->hyp.pos[u]=file_space->select.sel_info.hslab.diminfo[u].start; @@ -1598,6 +1856,20 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) printf("%s: file_file->hyp.pos[%d]=%d\n",FUNC,(int)i,(int)file_iter->hyp.pos[i]); #endif /* QAK */ + /* Get the data transfer properties */ + if (H5P_DEFAULT==dxpl_id) { + xfer_parms = &H5D_xfer_dflt; + } else { + xfer_parms = H5I_object(dxpl_id); + assert(xfer_parms); + } /* end else */ + + /* Allocate the vector I/O arrays */ + if((seq_len_arr = H5FL_ARR_ALLOC(size_t,xfer_parms->vector_size,0))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "can't allocate vector I/O array"); + if((buf_off_arr = H5FL_ARR_ALLOC(hsize_t,xfer_parms->vector_size,0))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "can't allocate vector I/O array"); + /* Set the rank of the fastest changing dimension */ fast_dim=file_space->extent.u.simple.rank-1; ndims=file_space->extent.u.simple.rank; @@ -1608,6 +1880,15 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) acc*=file_space->extent.u.simple.size[i]; } /* end for */ + /* Set the number of elements left for I/O */ + assert(nelmts==(hsize_t)((size_t)nelmts)); /*check for overflow*/ + io_left=(size_t)nelmts; + +#ifdef QAK + printf("%s: fast_dim=%d\n",FUNC,(int)fast_dim); + printf("%s: file_space->select.sel_info.hslab.diminfo[%d].start=%d\n",FUNC,(int)fast_dim,(int)file_space->select.sel_info.hslab.diminfo[fast_dim].start); + printf("%s: file_space->select.sel_info.hslab.diminfo[%d].stride=%d\n",FUNC,(int)fast_dim,(int)file_space->select.sel_info.hslab.diminfo[fast_dim].stride); +#endif /* QAK */ /* Check if we stopped in the middle of a sequence of elements */ if((file_iter->hyp.pos[fast_dim]-file_space->select.sel_info.hslab.diminfo[fast_dim].start)%file_space->select.sel_info.hslab.diminfo[fast_dim].stride!=0 || ((file_iter->hyp.pos[fast_dim]!=file_space->select.sel_info.hslab.diminfo[fast_dim].start) && file_space->select.sel_info.hslab.diminfo[fast_dim].stride==1)) { @@ -1633,22 +1914,29 @@ printf("%s: Check 1.0\n",FUNC); /* Add in the selection offset */ for(i=0; i<ndims; i++) offset[i] += file_space->select.offset[i]; +#ifdef QAK +for(i=0; i<ndims+1; i++) + printf("%s: offset[%d]=%d\n",FUNC,(int)i,(int)offset[i]); +#endif /* QAK */ /* Compute the initial buffer offset */ for(i=0,buf_off=0; i<ndims; i++) buf_off+=offset[i]*slab[i]; +#ifdef QAK +printf("%s: buf_off=%ld, actual_write=%d, actual_bytes=%d\n",FUNC,(long)buf_off,(int)actual_write,(int)actual_bytes); +#endif /* QAK */ - /* Read in the rest of the sequence */ + /* Write out the rest of the sequence */ if (H5F_seq_write(f, dxpl_id, layout, pline, fill, efl, file_space, elmt_size, actual_bytes, buf_off, buf)<0) { HRETURN_ERROR(H5E_DATASPACE, H5E_WRITEERROR, 0, "write error"); } /* Increment the offset of the buffer */ - buf+=elmt_size*actual_write; + buf+=actual_bytes; - /* Increment the count write */ - num_write+=actual_write; + /* Decrement the amount left to write */ + io_left-=actual_write; /* Advance the point iterator */ /* If we had enough buffer space to write out the rest of the sequence @@ -1668,16 +1956,20 @@ printf("%s: Check 1.0\n",FUNC); /* Now that we've cleared the "remainder" of the previous fastest dimension * sequence, we must be at the beginning of a sequence, so use the fancy * algorithm to compute the offsets and run through as many as possible, - * until the buffer fills up. + * until the buffer runs dry. */ - if(num_write<nelmts) { /* Just in case the "remainder" above filled the buffer */ + if(io_left>0) { /* Just in case the "remainder" above emptied the buffer */ #ifdef QAK -printf("%s: Check 2.0\n",FUNC); +printf("%s: Check 2.0, ndims=%d, io_left=%d, nelmts=%d\n",FUNC,(int)ndims,(int)io_left,(int)nelmts); #endif /* QAK */ /* Compute the arrays to perform I/O on */ /* Copy the location of the point to get */ HDmemcpy(offset, file_iter->hyp.pos,ndims*sizeof(hssize_t)); offset[ndims] = 0; +#ifdef QAK +for(i=0; i<ndims+1; i++) + printf("%s: offset[%d]=%d\n",FUNC,(int)i,(int)offset[i]); +#endif /* QAK */ /* Add in the selection offset */ for(i=0; i<ndims; i++) @@ -1688,6 +1980,12 @@ printf("%s: Check 2.0\n",FUNC); tmp_count[i] = (file_iter->hyp.pos[i]-file_space->select.sel_info.hslab.diminfo[i].start)%file_space->select.sel_info.hslab.diminfo[i].stride; tmp_block[i] = (file_iter->hyp.pos[i]-file_space->select.sel_info.hslab.diminfo[i].start)/file_space->select.sel_info.hslab.diminfo[i].stride; } /* end for */ +#ifdef QAK +for(i=0; i<ndims; i++) { + printf("%s: tmp_count[%d]=%d, tmp_block[%d]=%d\n",FUNC,(int)i,(int)tmp_count[i],(int)i,(int)tmp_block[i]); + printf("%s: slab[%d]=%d\n",FUNC,(int)i,(int)slab[i]); +} +#endif /* QAK */ /* Compute the initial buffer offset */ for(i=0,buf_off=0; i<ndims; i++) @@ -1699,7 +1997,10 @@ printf("%s: Check 2.0\n",FUNC); /* Set the number of actual bytes */ actual_bytes=actual_write*elmt_size; #ifdef QAK -printf("%s: actual_write=%d\n",FUNC,(int)actual_write); +printf("%s: buf_off=%ld, actual_write=%d, actual_bytes=%d\n",FUNC,(long)buf_off,(int)actual_write,(int)actual_bytes); +#endif /* QAK */ + +#ifdef QAK for(i=0; i<file_space->extent.u.simple.rank; i++) printf("%s: diminfo: start[%d]=%d, stride[%d]=%d, block[%d]=%d, count[%d]=%d\n",FUNC, (int)i,(int)file_space->select.sel_info.hslab.diminfo[i].start, @@ -1708,10 +2009,6 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) (int)i,(int)file_space->select.sel_info.hslab.diminfo[i].count); #endif /* QAK */ - /* Set the last location & length to invalid numbers */ - last_buf_off=(hsize_t)-1; - buf_size=0; - /* Set the local copy of the diminfo pointer */ tdiminfo=file_space->select.sel_info.hslab.diminfo; @@ -1719,84 +2016,288 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) fast_dim_start=tdiminfo[fast_dim].start; fast_dim_stride=tdiminfo[fast_dim].stride; fast_dim_block=tdiminfo[fast_dim].block; - fast_dim_count=tdiminfo[fast_dim].count; fast_dim_buf_off=slab[fast_dim]*fast_dim_stride; fast_dim_offset=fast_dim_start+file_space->select.offset[fast_dim]; - /* Read in data until an entire sequence can't be written out any longer */ - while(num_write<nelmts) { - /* Check if we are running out of room in the buffer */ - if((actual_write+num_write)>nelmts) { - actual_write=nelmts-num_write; - actual_bytes=actual_write*elmt_size; - } /* end if */ + /* Compute the number of blocks which would fit into the buffer */ + tot_blk_count=io_left/fast_dim_block; -#ifdef QAK -printf("%s: num_write=%d\n",FUNC,(int)num_write); -for(i=0; i<file_space->extent.u.simple.rank; i++) - printf("%s: tmp_count[%d]=%d, offset[%d]=%d\n",FUNC,(int)i,(int)tmp_count[i],(int)i,(int)offset[i]); -#endif /* QAK */ + /* Compute the amount to wrap at the end of each row */ + for(i=0; i<ndims; i++) + wrap[i]=(file_space->extent.u.simple.size[i]-(tdiminfo[i].stride*tdiminfo[i].count))*slab[i]; - /* check for the first write */ - if(last_buf_off==(hsize_t)-1) { - last_buf_off=buf_off; - buf_size=actual_bytes; - } /* end if */ - else { - /* Check if we are extending the buffer to write */ - if((last_buf_off+buf_size)==buf_off) { - buf_size+=actual_bytes; - } /* end if */ - /* - * We've moved to another section of the dataset, write out the - * previous piece and change the last position and length to - * the current position and length - */ - else { - /* Write out the sequence */ - if (H5F_seq_write(f, dxpl_id, layout, pline, fill, efl, file_space, - elmt_size, buf_size, last_buf_off, buf)<0) { - HRETURN_ERROR(H5E_DATASPACE, H5E_WRITEERROR, 0, "write error"); - } /* end if */ + /* Compute the amount to skip between blocks */ + for(i=0; i<ndims; i++) + skip[i]=(tdiminfo[i].stride-tdiminfo[i].block)*slab[i]; + + /* Fill the sequence length array (since they will all be the same for optimized hyperslabs) */ + for(u=0; u<xfer_parms->vector_size; u++) + seq_len_arr[u]=actual_bytes; + + /* Write out data until an entire sequence can't be written any longer */ + while(io_left>0) { + /* Reset copy of number of blocks in fastest dimension */ + fast_dim_count=tdiminfo[fast_dim].count-tmp_count[fast_dim]; - /* Increment the offset of the buffer */ - buf+=buf_size; + /* Check if this entire row will fit into buffer */ + if(fast_dim_count<=tot_blk_count) { + + /* Entire row of blocks fits into buffer */ + act_blk_count=fast_dim_count; + + /* Loop over all the blocks in the fastest changing dimension */ + while(fast_dim_count>0) { + /* Gather the sequence */ - /* Updated the last position and length */ - last_buf_off=buf_off; - buf_size=actual_bytes; + /* Compute the number of sequences to fill */ + tot_seq=MIN(xfer_parms->vector_size-nseq,fast_dim_count); - } /* end else */ - } /* end else */ + /* Get a copy of the number of sequences to fill */ + seq_count=tot_seq; - /* Increment the count write */ - num_write+=actual_write; + /* Set the pointer to the correct starting array element */ + buf_off_arr_p=&buf_off_arr[nseq]; + +#ifdef NO_DUFFS_DEVICE + /* Fill up the buffer, or finish up the blocks in this dimension */ + while(seq_count>0) { + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + seq_count--; + } /* end while */ +#else /* NO_DUFFS_DEVICE */ + duffs_index = (seq_count + 7) / 8; + switch (seq_count % 8) { + case 0: + do + { + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + case 7: + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + case 6: + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + case 5: + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + case 4: + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + case 3: + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + case 2: + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + case 1: + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + } while (--duffs_index > 0); + } /* end switch */ +#endif /* NO_DUFFS_DEVICE */ + + /* Increment number of array elements used */ + nseq+=tot_seq; + + /* Increment the total number of bytes contained in arrays */ + tot_buf_size += tot_seq*actual_bytes; + + /* Decrement number of blocks left */ + fast_dim_count -= tot_seq; + + /* If the sequence & offset arrays are full, write them out */ + if(nseq>=xfer_parms->vector_size) { + /* Write out the sequences */ + if (H5F_seq_writev(f, dxpl_id, layout, pline, fill, efl, file_space, + elmt_size, nseq, seq_len_arr, buf_off_arr, buf)<0) { + HRETURN_ERROR(H5E_DATASPACE, H5E_WRITEERROR, 0, "write error"); + } /* end if */ - /* Increment the offset and count for the fastest changing dimension */ + /* Increment the offset of the destination buffer */ + buf+=tot_buf_size; - /* Move to the next block in the current dimension */ - /* Check for partial block write! */ - if(actual_write<fast_dim_block) { - offset[fast_dim]+=actual_write; - buf_off+=actual_bytes; - continue; /* don't bother checking slower dimensions */ + /* Reset the number of bytes & sequences */ + tot_buf_size=0; + nseq=0; + } /* end else */ + } /* end while */ + + /* Decrement number of elements left */ + io_left -= actual_write*act_blk_count; + + /* Decrement number of blocks left */ + tot_blk_count -= act_blk_count; + + /* Increment information to reflect block just processed */ + offset[fast_dim]=fast_dim_offset; /* reset the offset in the fastest dimension */ + tmp_count[fast_dim]=0; + + /* Increment offset in destination buffer */ + buf_off += wrap[fast_dim]; } /* end if */ else { - offset[fast_dim]+=fast_dim_stride; /* reset the offset in the fastest dimension */ - buf_off+=fast_dim_buf_off; - tmp_count[fast_dim]++; - } /* end else */ - /* If this block is still in the range of blocks to output for the dimension, break out of loop */ - if(tmp_count[fast_dim]<fast_dim_count) - continue; /* don't bother checking slower dimensions */ - else { - tmp_count[fast_dim]=0; /* reset back to the beginning of the line */ - offset[fast_dim]=fast_dim_offset; + /* Entire row of blocks doesn't fit into buffer */ + act_blk_count=tot_blk_count; + + /* Reduce number of blocks to output */ + fast_dim_count=tot_blk_count; + + /* Loop over all the blocks in the fastest changing dimension */ + while(fast_dim_count>0) { + /* Gather the sequence */ + + /* Compute the number of sequences to fill */ + tot_seq=MIN(xfer_parms->vector_size-nseq,fast_dim_count); + + /* Get a copy of the number of sequences to fill */ + seq_count=tot_seq; + + /* Set the pointer to the correct starting array element */ + buf_off_arr_p=&buf_off_arr[nseq]; + + /* Fill up the buffer, or finish up the blocks in this dimension */ + while(seq_count>0) { + /* Store of length & offset */ + /* seq_len_arr[nseq] already has the correct value */ + *buf_off_arr_p++=buf_off; + + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + seq_count--; + } /* end while */ + + /* Increment number of array elements used */ + nseq+=tot_seq; + + /* Increment the total number of bytes contained in arrays */ + tot_buf_size += tot_seq*actual_bytes; + + /* Decrement number of blocks left */ + fast_dim_count -= tot_seq; + + /* If the sequence & offset arrays are full, write them out */ + if(nseq>=xfer_parms->vector_size) { + /* Write out the sequences */ + if (H5F_seq_writev(f, dxpl_id, layout, pline, fill, efl, file_space, + elmt_size, nseq, seq_len_arr, buf_off_arr, buf)<0) { + HRETURN_ERROR(H5E_DATASPACE, H5E_WRITEERROR, 0, "write error"); + } /* end if */ + + /* Increment the offset of the destination buffer */ + buf+=tot_buf_size; + + /* Reset the number of bytes & sequences */ + tot_buf_size=0; + nseq=0; + } /* end else */ + } /* end while */ + + /* Decrement number of elements left */ + io_left -= actual_write*act_blk_count; + + /* Decrement number of blocks left */ + tot_blk_count -= act_blk_count; + + /* Increment information to reflect block just processed */ + offset[fast_dim]+=(fast_dim_stride*act_blk_count); /* reset the offset in the fastest dimension */ + tmp_count[fast_dim]+=act_blk_count; + + /* Handle any leftover, partial blocks in this row */ + if(io_left>0) { + actual_write=io_left; + actual_bytes=actual_write*elmt_size; + + /* Gather the sequence */ + + /* Store of length & offset */ + seq_len_arr[nseq]=actual_bytes; + buf_off_arr[nseq]=buf_off; + + /* Increment the total number of bytes contained in arrays */ + tot_buf_size += actual_bytes; + + /* Increment the number of sequences in arrays */ + nseq++; + + /* If the sequence & offset arrays are full, write them out */ + if(nseq>=xfer_parms->vector_size) { + /* Write out the sequences */ + if (H5F_seq_writev(f, dxpl_id, layout, pline, fill, efl, file_space, + elmt_size, nseq, seq_len_arr, buf_off_arr, buf)<0) { + HRETURN_ERROR(H5E_DATASPACE, H5E_WRITEERROR, 0, "write error"); + } /* end if */ + + /* Increment the offset of the destination buffer */ + buf+=tot_buf_size; + + /* Reset the number of bytes & sequences */ + tot_buf_size=0; + nseq=0; + } /* end else */ - /* Re-compute the initial buffer offset */ - for(i=0,buf_off=0; i<ndims; i++) - buf_off+=offset[i]*slab[i]; + /* Increment the source offset */ + buf_off+=fast_dim_buf_off; + + /* Decrement the number of elements left */ + io_left -= actual_write; + + /* Increment buffer correctly */ + offset[fast_dim]+=actual_write; + } /* end if */ + + /* don't bother checking slower dimensions */ + assert(tot_blk_count==0); + assert(io_left==0); + break; } /* end else */ /* Increment the offset and count for the other dimensions */ @@ -1804,7 +2305,6 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) while(temp_dim>=0) { /* Move to the next row in the curent dimension */ offset[temp_dim]++; - buf_off+=slab[temp_dim]; tmp_block[temp_dim]++; /* If this block is still in the range of blocks to output for the dimension, break out of loop */ @@ -1813,7 +2313,7 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) else { /* Move to the next block in the current dimension */ offset[temp_dim]+=(tdiminfo[temp_dim].stride-tdiminfo[temp_dim].block); - buf_off+=(tdiminfo[temp_dim].stride-tdiminfo[temp_dim].block)*slab[temp_dim]; + buf_off += skip[temp_dim]; tmp_block[temp_dim]=0; tmp_count[temp_dim]++; @@ -1821,14 +2321,11 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) if(tmp_count[temp_dim]<tdiminfo[temp_dim].count) break; else { + offset[temp_dim]=tdiminfo[temp_dim].start+file_space->select.offset[temp_dim]; + buf_off += wrap[temp_dim]; tmp_count[temp_dim]=0; /* reset back to the beginning of the line */ tmp_block[temp_dim]=0; - offset[temp_dim]=tdiminfo[temp_dim].start+file_space->select.offset[temp_dim]; - - /* Re-compute the initial buffer offset */ - for(i=0,buf_off=0; i<ndims; i++) - buf_off+=offset[i]*slab[i]; - } + } /* end else */ } /* end else */ /* Decrement dimension count */ @@ -1836,23 +2333,35 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) } /* end while */ } /* end while */ - /* check for the last write */ - if(last_buf_off!=(hsize_t)-1) { + /* Check for any stored sequences which need to be flushed */ + if(nseq>0) { /* Write out the sequence */ - if (H5F_seq_write(f, dxpl_id, layout, pline, fill, efl, file_space, - elmt_size, buf_size, last_buf_off, buf)<0) { + if (H5F_seq_writev(f, dxpl_id, layout, pline, fill, efl, file_space, + elmt_size, nseq, seq_len_arr, buf_off_arr, buf)<0) { HRETURN_ERROR(H5E_DATASPACE, H5E_WRITEERROR, 0, "write error"); } /* end if */ } /* end if */ + /* Subtract out the selection offset */ + for(i=0; i<ndims; i++) + offset[i] -= file_space->select.offset[i]; + /* Update the iterator with the location we stopped */ HDmemcpy(file_iter->hyp.pos, offset, ndims*sizeof(hssize_t)); } /* end if */ /* Decrement the number of elements left in selection */ - file_iter->hyp.elmt_left-=num_write; + file_iter->hyp.elmt_left -= (nelmts-io_left); - FUNC_LEAVE (num_write); + ret_value= (nelmts-io_left); + +done: + if(seq_len_arr!=NULL) + H5FL_ARR_FREE(size_t,seq_len_arr); + if(buf_off_arr!=NULL) + H5FL_ARR_FREE(hsize_t,buf_off_arr); + + FUNC_LEAVE (ret_value); } /* H5S_hyper_fwrite_opt() */ @@ -2107,8 +2616,10 @@ H5S_hyper_mread_opt (const void *_buf, size_t elmt_size, hsize_t nelmts, void *_tconv_buf/*out*/) { hsize_t mem_size[H5O_LAYOUT_NDIMS]; /* Size of the source buffer */ - hssize_t offset[H5O_LAYOUT_NDIMS]; /* Offset on disk */ hsize_t slab[H5O_LAYOUT_NDIMS]; /* Hyperslab size */ + hssize_t wrap[H5O_LAYOUT_NDIMS]; /* Bytes to wrap around at the end of a row */ + hsize_t skip[H5O_LAYOUT_NDIMS]; /* Bytes to skip between blocks */ + hssize_t offset[H5O_LAYOUT_NDIMS]; /* Offset on disk */ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary block count */ hsize_t tmp_block[H5O_LAYOUT_NDIMS]; /* Temporary block offset */ const uint8_t *src=(const uint8_t *)_buf; /* Alias for pointer arithmetic */ @@ -2118,23 +2629,27 @@ H5S_hyper_mread_opt (const void *_buf, size_t elmt_size, fast_dim_offset; hsize_t fast_dim_stride, /* Local copies of fastest changing dimension info */ fast_dim_block, - fast_dim_count, - fast_dim_buf_off; + fast_dim_count; + hsize_t tot_blk_count; /* Total number of blocks left to output */ + size_t act_blk_count; /* Actual number of blocks to output */ + size_t fast_dim_buf_off; /* Local copy of amount to move fastest dimension buffer offset */ intn fast_dim; /* Rank of the fastest changing dimension for the dataspace */ intn temp_dim; /* Temporary rank holder */ hsize_t acc; /* Accumulator */ - size_t buf_off; /* Buffer offset for copying memory */ intn i; /* Counters */ - uintn u; /* Counters */ + uintn u; /* Counters */ intn ndims; /* Number of dimensions of dataset */ - hsize_t actual_read; /* The actual number of elements to read in */ - hsize_t actual_bytes; /* The actual number of bytes to copy */ - hsize_t num_read=0; /* Number of elements read */ + size_t actual_read; /* The actual number of elements to read in */ + size_t actual_bytes; /* The actual number of bytes to copy */ + size_t io_left; /* The number of elements left in I/O operation */ +#ifndef NO_DUFFS_DEVICE + hsize_t duffs_index; /* Counting index for Duff's device */ +#endif /* NO_DUFFS_DEVICE */ FUNC_ENTER (H5S_hyper_mread_opt, 0); #ifdef QAK -printf("%s: Called!\n",FUNC); +printf("%s: Called!, nelmts=%lu, elmt_size=%d\n",FUNC,(unsigned long)nelmts,(int)elmt_size); #endif /* QAK */ /* Check if this is the first element read in from the hyperslab */ if(mem_iter->hyp.pos[0]==(-1)) { @@ -2147,7 +2662,7 @@ for(u=0; u<mem_space->extent.u.simple.rank; u++) printf("%s: mem_file->hyp.pos[%u]=%d\n",FUNC,(unsigned)u,(int)mem_iter->hyp.pos[u]); #endif /* QAK */ - /* Set the aliases for dimension information */ + /* Set the aliases for a few important dimension ranks */ fast_dim=mem_space->extent.u.simple.rank-1; ndims=mem_space->extent.u.simple.rank; @@ -2165,13 +2680,17 @@ for(i=0; i<ndims; i++) printf("%s: mem_size[%d]=%d, slab[%d]=%d\n",FUNC,(int)i,(int)mem_size[i],(int)i,(int)slab[i]); #endif /* QAK */ + /* Set the number of elements left for I/O */ + assert(nelmts==(hsize_t)((size_t)nelmts)); /*check for overflow*/ + io_left=(size_t)nelmts; + /* Check if we stopped in the middle of a sequence of elements */ if((mem_iter->hyp.pos[fast_dim]-mem_space->select.sel_info.hslab.diminfo[fast_dim].start)%mem_space->select.sel_info.hslab.diminfo[fast_dim].stride!=0 || ((mem_iter->hyp.pos[fast_dim]!=mem_space->select.sel_info.hslab.diminfo[fast_dim].start) && mem_space->select.sel_info.hslab.diminfo[fast_dim].stride==1)) { - size_t leftover; /* The number of elements left over from the last sequence */ + uintn leftover; /* The number of elements left over from the last sequence */ #ifdef QAK -printf("%s: Check 1.0\n",FUNC); +printf("%s: Check 1.0, io_left=%lu\n",FUNC,(unsigned long)io_left); #endif /* QAK */ /* Calculate the number of elements left in the sequence */ if(mem_space->select.sel_info.hslab.diminfo[fast_dim].stride==1) @@ -2179,7 +2698,7 @@ printf("%s: Check 1.0\n",FUNC); else leftover=mem_space->select.sel_info.hslab.diminfo[fast_dim].block-((mem_iter->hyp.pos[fast_dim]-mem_space->select.sel_info.hslab.diminfo[fast_dim].start)%mem_space->select.sel_info.hslab.diminfo[fast_dim].stride); - /* Make certain that we don't read too many */ + /* Make certain that we don't write too many */ actual_read=MIN(leftover,nelmts); actual_bytes=actual_read*elmt_size; @@ -2192,17 +2711,17 @@ printf("%s: Check 1.0\n",FUNC); offset[i] += mem_space->select.offset[i]; /* Compute the initial buffer offset */ - for(i=0,buf_off=0; i<ndims; i++) - buf_off+=offset[i]*slab[i]; + for(i=0,src=_buf; i<ndims; i++) + src+=offset[i]*slab[i]; - assert(actual_bytes==(hsize_t)((size_t)actual_bytes)); /*check for overflow*/ - HDmemcpy(dst,src+buf_off,(size_t)actual_bytes); + /* Scatter out the rest of the sequence */ + HDmemcpy(dst,src,actual_bytes); /* Increment the offset of the buffer */ dst+=actual_bytes; - /* Increment the count read */ - num_read+=actual_read; + /* Decrement the number of elements written out */ + io_left -= actual_read; /* Advance the point iterator */ /* If we had enough buffer space to read in the rest of the sequence @@ -2215,7 +2734,7 @@ printf("%s: Check 1.0\n",FUNC); H5S_hyper_iter_next(mem_space,mem_iter); } /* end if */ else { - mem_iter->hyp.pos[fast_dim]+=actual_read; /* whole sequence not read in, just advance fastest dimension offset */ + mem_iter->hyp.pos[fast_dim]+=actual_read; /* whole sequence not written out, just advance fastest dimension offset */ } /* end if */ } /* end if */ @@ -2224,9 +2743,9 @@ printf("%s: Check 1.0\n",FUNC); * algorithm to compute the offsets and run through as many as possible, * until the buffer fills up. */ - if(num_read<nelmts) { /* Just in case the "remainder" above filled the buffer */ + if(io_left>0) { /* Just in case the "remainder" above filled the buffer */ #ifdef QAK -printf("%s: Check 2.0\n",FUNC); +printf("%s: Check 2.0, io_left=%lu\n",FUNC,(unsigned long)io_left); #endif /* QAK */ /* Compute the arrays to perform I/O on */ /* Copy the location of the point to get */ @@ -2244,21 +2763,21 @@ printf("%s: Check 2.0\n",FUNC); } /* end for */ /* Compute the initial buffer offset */ - for(i=0,buf_off=0; i<ndims; i++) - buf_off+=offset[i]*slab[i]; + for(i=0,src=_buf; i<ndims; i++) + src+=offset[i]*slab[i]; - /* Set the number of elements to read each time */ + /* Set the number of elements to write each time */ actual_read=mem_space->select.sel_info.hslab.diminfo[fast_dim].block; /* Set the number of actual bytes */ actual_bytes=actual_read*elmt_size; #ifdef QAK -printf("%s: buf_off=%u, actual_bytes=%u\n",FUNC,(unsigned)buf_off,(int)actual_bytes); +printf("%s: src=%p, actual_bytes=%u\n",FUNC,src,(int)actual_bytes); #endif /* QAK */ #ifdef QAK printf("%s: actual_read=%d\n",FUNC,(int)actual_read); -for(i=0; i<file_space->extent.u.simple.rank; i++) +for(i=0; i<ndims; i++) printf("%s: diminfo: start[%d]=%d, stride[%d]=%d, block[%d]=%d, count[%d]=%d\n",FUNC, (int)i,(int)mem_space->select.sel_info.hslab.diminfo[i].start, (int)i,(int)mem_space->select.sel_info.hslab.diminfo[i].stride, @@ -2273,59 +2792,203 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) fast_dim_start=tdiminfo[fast_dim].start; fast_dim_stride=tdiminfo[fast_dim].stride; fast_dim_block=tdiminfo[fast_dim].block; - fast_dim_count=tdiminfo[fast_dim].count; fast_dim_buf_off=slab[fast_dim]*fast_dim_stride; fast_dim_offset=fast_dim_start+mem_space->select.offset[fast_dim]; + /* Compute the number of blocks which would fit into the buffer */ + tot_blk_count=io_left/fast_dim_block; + + /* Compute the amount to wrap at the end of each row */ + for(i=0; i<ndims; i++) + wrap[i]=(mem_size[i]-(tdiminfo[i].stride*tdiminfo[i].count))*slab[i]; + + /* Compute the amount to skip between blocks */ + for(i=0; i<ndims; i++) + skip[i]=(tdiminfo[i].stride-tdiminfo[i].block)*slab[i]; + /* Read in data until an entire sequence can't be written out any longer */ - while(num_read<nelmts) { - /* Check if we are running out of room in the buffer */ - if((actual_read+num_read)>nelmts) { - actual_read=nelmts-num_read; - actual_bytes=actual_read*elmt_size; - } /* end if */ + while(io_left>0) { + /* Reset copy of number of blocks in fastest dimension */ + fast_dim_count=tdiminfo[fast_dim].count-tmp_count[fast_dim]; -#ifdef QAK -printf("%s: num_read=%d\n",FUNC,(int)num_read); -for(i=0; i<mem_space->extent.u.simple.rank; i++) - printf("%s: tmp_count[%d]=%d, offset[%d]=%d\n",FUNC,(int)i,(int)tmp_count[i],(int)i,(int)offset[i]); -#endif /* QAK */ + /* Check if this entire row will fit into buffer */ + if(fast_dim_count<=tot_blk_count) { - /* Scatter out the rest of the sequence */ - assert(actual_bytes==(hsize_t)((size_t)actual_bytes)); /*check for overflow*/ - HDmemcpy(dst,src+buf_off,(size_t)actual_bytes); + /* Entire row of blocks fits into buffer */ + act_blk_count=fast_dim_count; - /* Increment the offset of the buffer */ - dst+=actual_bytes; +#ifdef NO_DUFFS_DEVICE + /* Loop over all the blocks in the fastest changing dimension */ + while(fast_dim_count>0) { + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); - /* Increment the count read */ - num_read+=actual_read; + /* Increment the offset of the buffer */ + dst+=actual_bytes; - /* Increment the offset and count for the fastest changing dimension */ + /* Increment information to reflect block just processed */ + src+=fast_dim_buf_off; - /* Move to the next block in the current dimension */ - /* Check for partial block read! */ - if(actual_read<fast_dim_block) { - offset[fast_dim]+=actual_read; - buf_off+=actual_bytes; - continue; /* don't bother checking slower dimensions */ + /* Decrement number of blocks */ + fast_dim_count--; + } /* end while */ +#else /* NO_DUFFS_DEVICE */ + duffs_index = (fast_dim_count + 7) / 8; + switch (fast_dim_count % 8) { + case 0: + do + { + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + dst+=actual_bytes; + + /* Increment information to reflect block just processed */ + src+=fast_dim_buf_off; + + case 7: + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + dst+=actual_bytes; + + /* Increment information to reflect block just processed */ + src+=fast_dim_buf_off; + + case 6: + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + dst+=actual_bytes; + + /* Increment information to reflect block just processed */ + src+=fast_dim_buf_off; + + case 5: + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + dst+=actual_bytes; + + /* Increment information to reflect block just processed */ + src+=fast_dim_buf_off; + + case 4: + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + dst+=actual_bytes; + + /* Increment information to reflect block just processed */ + src+=fast_dim_buf_off; + + case 3: + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + dst+=actual_bytes; + + /* Increment information to reflect block just processed */ + src+=fast_dim_buf_off; + + case 2: + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + dst+=actual_bytes; + + /* Increment information to reflect block just processed */ + src+=fast_dim_buf_off; + + case 1: + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + dst+=actual_bytes; + + /* Increment information to reflect block just processed */ + src+=fast_dim_buf_off; + + } while (--duffs_index > 0); + } /* end switch */ +#endif /* NO_DUFFS_DEVICE */ + + /* Decrement number of elements left */ + io_left -= actual_read*act_blk_count; + + /* Decrement number of blocks left */ + tot_blk_count -= act_blk_count; + + /* Increment information to reflect block just processed */ + offset[fast_dim]=fast_dim_offset; /* reset the offset in the fastest dimension */ + tmp_count[fast_dim]=0; + + /* Increment offset in destination buffer */ + src += wrap[fast_dim]; } /* end if */ else { - offset[fast_dim]+=fast_dim_stride; /* reset the offset in the fastest dimension */ - buf_off+=fast_dim_buf_off; - tmp_count[fast_dim]++; - } /* end else */ - /* If this block is still in the range of blocks to output for the dimension, break out of loop */ - if(tmp_count[fast_dim]<fast_dim_count) - continue; /* don't bother checking slower dimensions */ - else { - tmp_count[fast_dim]=0; /* reset back to the beginning of the line */ - offset[fast_dim]=fast_dim_offset; + /* Entire row of blocks doesn't fit into buffer */ + act_blk_count=tot_blk_count; + + /* Reduce number of blocks to output */ + fast_dim_count=tot_blk_count; + + /* Loop over all the blocks in the fastest changing dimension */ + while(fast_dim_count>0) { + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); - /* Re-compute the initial buffer offset */ - for(i=0,buf_off=0; i<ndims; i++) - buf_off+=offset[i]*slab[i]; + /* Increment the offset of the buffer */ + dst+=actual_bytes; + + /* Increment information to reflect block just processed */ + src+=fast_dim_buf_off; + + /* Decrement number of blocks */ + fast_dim_count--; + } /* end while */ + + /* Decrement number of elements left */ + io_left -= actual_read*act_blk_count; + + /* Decrement number of blocks left */ + tot_blk_count -= act_blk_count; + + /* Increment information to reflect block just processed */ + offset[fast_dim]+=(fast_dim_stride*act_blk_count); /* reset the offset in the fastest dimension */ + tmp_count[fast_dim]+=act_blk_count; + + /* Handle any leftover, partial blocks in this row */ + if(io_left>0) { + actual_read=io_left; + actual_bytes=actual_read*elmt_size; + + /* Scatter out the rest of the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + dst+=actual_bytes; + + /* Decrement the number of elements left */ + io_left -= actual_read; + + /* Increment buffer correctly */ + offset[fast_dim]+=actual_read; + } /* end if */ + + /* don't bother checking slower dimensions */ + assert(tot_blk_count==0); + assert(io_left==0); + break; } /* end else */ /* Increment the offset and count for the other dimensions */ @@ -2333,7 +2996,6 @@ for(i=0; i<mem_space->extent.u.simple.rank; i++) while(temp_dim>=0) { /* Move to the next row in the curent dimension */ offset[temp_dim]++; - buf_off+=slab[temp_dim]; tmp_block[temp_dim]++; /* If this block is still in the range of blocks to output for the dimension, break out of loop */ @@ -2342,7 +3004,7 @@ for(i=0; i<mem_space->extent.u.simple.rank; i++) else { /* Move to the next block in the current dimension */ offset[temp_dim]+=(tdiminfo[temp_dim].stride-tdiminfo[temp_dim].block); - buf_off+=(tdiminfo[temp_dim].stride-tdiminfo[temp_dim].block)*slab[temp_dim]; + src += skip[temp_dim]; tmp_block[temp_dim]=0; tmp_count[temp_dim]++; @@ -2350,14 +3012,11 @@ for(i=0; i<mem_space->extent.u.simple.rank; i++) if(tmp_count[temp_dim]<tdiminfo[temp_dim].count) break; else { + offset[temp_dim]=tdiminfo[temp_dim].start+mem_space->select.offset[temp_dim]; + src += wrap[temp_dim]; tmp_count[temp_dim]=0; /* reset back to the beginning of the line */ tmp_block[temp_dim]=0; - offset[temp_dim]=tdiminfo[temp_dim].start+mem_space->select.offset[temp_dim]; - - /* Re-compute the initial buffer offset */ - for(i=0,buf_off=0; i<ndims; i++) - buf_off+=offset[i]*slab[i]; - } + } /* end else */ } /* end else */ /* Decrement dimension count */ @@ -2365,14 +3024,18 @@ for(i=0; i<mem_space->extent.u.simple.rank; i++) } /* end while */ } /* end while */ + /* Subtract out the selection offset */ + for(i=0; i<ndims; i++) + offset[i] -= mem_space->select.offset[i]; + /* Update the iterator with the location we stopped */ HDmemcpy(mem_iter->hyp.pos, offset, ndims*sizeof(hssize_t)); } /* end if */ /* Decrement the number of elements left in selection */ - mem_iter->hyp.elmt_left-=num_read; + mem_iter->hyp.elmt_left-=(nelmts-io_left); - FUNC_LEAVE (num_read); + FUNC_LEAVE (nelmts-io_left); } /* end H5S_hyper_mread_opt() */ @@ -2623,6 +3286,8 @@ H5S_hyper_mwrite_opt (const void *_tconv_buf, size_t elmt_size, { hsize_t mem_size[H5O_LAYOUT_NDIMS]; /* Size of the source buffer */ hsize_t slab[H5O_LAYOUT_NDIMS]; /* Hyperslab size */ + hssize_t wrap[H5O_LAYOUT_NDIMS]; /* Bytes to wrap around at the end of a row */ + hsize_t skip[H5O_LAYOUT_NDIMS]; /* Bytes to skip between blocks */ hssize_t offset[H5O_LAYOUT_NDIMS]; /* Offset on disk */ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary block count */ hsize_t tmp_block[H5O_LAYOUT_NDIMS]; /* Temporary block offset */ @@ -2633,23 +3298,27 @@ H5S_hyper_mwrite_opt (const void *_tconv_buf, size_t elmt_size, fast_dim_offset; hsize_t fast_dim_stride, /* Local copies of fastest changing dimension info */ fast_dim_block, - fast_dim_count, - fast_dim_buf_off; + fast_dim_count; + hsize_t tot_blk_count; /* Total number of blocks left to output */ + size_t act_blk_count; /* Actual number of blocks to output */ + size_t fast_dim_buf_off; /* Local copy of amount to move fastest dimension buffer offset */ intn fast_dim; /* Rank of the fastest changing dimension for the dataspace */ intn temp_dim; /* Temporary rank holder */ hsize_t acc; /* Accumulator */ - size_t buf_off; /* Buffer offset for copying memory */ intn i; /* Counters */ uintn u; /* Counters */ intn ndims; /* Number of dimensions of dataset */ - hsize_t actual_write; /* The actual number of elements to read in */ - hsize_t actual_bytes; /* The actual number of bytes to copy */ - hsize_t num_write=0; /* Number of elements read */ + size_t actual_write; /* The actual number of elements to read in */ + size_t actual_bytes; /* The actual number of bytes to copy */ + size_t io_left; /* The number of elements left in I/O operation */ +#ifndef NO_DUFFS_DEVICE + hsize_t duffs_index; /* Counting index for Duff's device */ +#endif /* NO_DUFFS_DEVICE */ - FUNC_ENTER (H5S_hyper_fwrite_opt, 0); + FUNC_ENTER (H5S_hyper_mwrite_opt, 0); #ifdef QAK -printf("%s: Called!, elmt_size=%d\n",FUNC,(int)elmt_size); +printf("%s: Called!, nelmts=%lu, elmt_size=%d\n",FUNC,(unsigned long)nelmts,(int)elmt_size); #endif /* QAK */ /* Check if this is the first element read in from the hyperslab */ if(mem_iter->hyp.pos[0]==(-1)) { @@ -2680,13 +3349,17 @@ for(i=0; i<ndims; i++) printf("%s: mem_size[%d]=%d, slab[%d]=%d\n",FUNC,(int)i,(int)mem_size[i],(int)i,(int)slab[i]); #endif /* QAK */ + /* Set the number of elements left for I/O */ + assert(nelmts==(hsize_t)((size_t)nelmts)); /*check for overflow*/ + io_left=(size_t)nelmts; + /* Check if we stopped in the middle of a sequence of elements */ if((mem_iter->hyp.pos[fast_dim]-mem_space->select.sel_info.hslab.diminfo[fast_dim].start)%mem_space->select.sel_info.hslab.diminfo[fast_dim].stride!=0 || ((mem_iter->hyp.pos[fast_dim]!=mem_space->select.sel_info.hslab.diminfo[fast_dim].start) && mem_space->select.sel_info.hslab.diminfo[fast_dim].stride==1)) { uintn leftover; /* The number of elements left over from the last sequence */ #ifdef QAK -printf("%s: Check 1.0\n",FUNC); +printf("%s: Check 1.0, io_left=%lu\n",FUNC,(unsigned long)io_left); #endif /* QAK */ /* Calculate the number of elements left in the sequence */ if(mem_space->select.sel_info.hslab.diminfo[fast_dim].stride==1) @@ -2707,18 +3380,17 @@ printf("%s: Check 1.0\n",FUNC); offset[i] += mem_space->select.offset[i]; /* Compute the initial buffer offset */ - for(i=0,buf_off=0; i<ndims; i++) - buf_off+=offset[i]*slab[i]; + for(i=0,dst=(unsigned char *)_buf; i<ndims; i++) + dst+=offset[i]*slab[i]; /* Scatter out the rest of the sequence */ - assert(actual_bytes==(hsize_t)((size_t)actual_bytes)); /*check for overflow*/ - HDmemcpy(dst+buf_off,src,(size_t)actual_bytes); + HDmemcpy(dst,src,actual_bytes); /* Increment the offset of the buffer */ src+=actual_bytes; - /* Increment the count write */ - num_write+=actual_write; + /* Decrement the number of elements written out */ + io_left -= actual_write; /* Advance the point iterator */ /* If we had enough buffer space to write out the rest of the sequence @@ -2740,9 +3412,9 @@ printf("%s: Check 1.0\n",FUNC); * algorithm to compute the offsets and run through as many as possible, * until the buffer fills up. */ - if(num_write<nelmts) { /* Just in case the "remainder" above filled the buffer */ + if(io_left>0) { /* Just in case the "remainder" above filled the buffer */ #ifdef QAK -printf("%s: Check 2.0\n",FUNC); +printf("%s: Check 2.0, io_left=%lu\n",FUNC,(unsigned long)io_left); #endif /* QAK */ /* Compute the arrays to perform I/O on */ /* Copy the location of the point to get */ @@ -2760,8 +3432,8 @@ printf("%s: Check 2.0\n",FUNC); } /* end for */ /* Compute the initial buffer offset */ - for(i=0,buf_off=0; i<ndims; i++) - buf_off+=offset[i]*slab[i]; + for(i=0,dst=(unsigned char *)_buf; i<ndims; i++) + dst+=offset[i]*slab[i]; /* Set the number of elements to write each time */ actual_write=mem_space->select.sel_info.hslab.diminfo[fast_dim].block; @@ -2769,12 +3441,12 @@ printf("%s: Check 2.0\n",FUNC); /* Set the number of actual bytes */ actual_bytes=actual_write*elmt_size; #ifdef QAK -printf("%s: buf_off=%u, actual_bytes=%u\n",FUNC,(unsigned)buf_off,(int)actual_bytes); +printf("%s: dst=%p, actual_bytes=%u\n",FUNC,dst,(int)actual_bytes); #endif /* QAK */ #ifdef QAK printf("%s: actual_write=%d\n",FUNC,(int)actual_write); -for(i=0; i<file_space->extent.u.simple.rank; i++) +for(i=0; i<ndims; i++) printf("%s: diminfo: start[%d]=%d, stride[%d]=%d, block[%d]=%d, count[%d]=%d\n",FUNC, (int)i,(int)mem_space->select.sel_info.hslab.diminfo[i].start, (int)i,(int)mem_space->select.sel_info.hslab.diminfo[i].stride, @@ -2789,63 +3461,203 @@ for(i=0; i<file_space->extent.u.simple.rank; i++) fast_dim_start=tdiminfo[fast_dim].start; fast_dim_stride=tdiminfo[fast_dim].stride; fast_dim_block=tdiminfo[fast_dim].block; - fast_dim_count=tdiminfo[fast_dim].count; fast_dim_buf_off=slab[fast_dim]*fast_dim_stride; fast_dim_offset=fast_dim_start+mem_space->select.offset[fast_dim]; + /* Compute the number of blocks which would fit into the buffer */ + tot_blk_count=io_left/fast_dim_block; + + /* Compute the amount to wrap at the end of each row */ + for(i=0; i<ndims; i++) + wrap[i]=(mem_size[i]-(tdiminfo[i].stride*tdiminfo[i].count))*slab[i]; + + /* Compute the amount to skip between blocks */ + for(i=0; i<ndims; i++) + skip[i]=(tdiminfo[i].stride-tdiminfo[i].block)*slab[i]; + /* Read in data until an entire sequence can't be written out any longer */ - while(num_write<nelmts) { - /* Check if we are running out of room in the buffer */ - if((actual_write+num_write)>nelmts) { - actual_write=nelmts-num_write; - actual_bytes=actual_write*elmt_size; - } /* end if */ + while(io_left>0) { + /* Reset copy of number of blocks in fastest dimension */ + fast_dim_count=tdiminfo[fast_dim].count-tmp_count[fast_dim]; -#ifdef QAK -printf("%s: num_write=%d\n",FUNC,(int)num_write); -for(i=0; i<mem_space->extent.u.simple.rank; i++) - printf("%s: tmp_count[%d]=%d, offset[%d]=%d\n",FUNC,(int)i,(int)tmp_count[i],(int)i,(int)offset[i]); -#endif /* QAK */ + /* Check if this entire row will fit into buffer */ + if(fast_dim_count<=tot_blk_count) { - /* Scatter out the rest of the sequence */ - assert(actual_bytes==(hsize_t)((size_t)actual_bytes)); /*check for overflow*/ - HDmemcpy(dst+buf_off,src,(size_t)actual_bytes); + /* Entire row of blocks fits into buffer */ + act_blk_count=fast_dim_count; -#ifdef QAK -printf("%s: buf_off=%u, actual_bytes=%u\n",FUNC,(unsigned)buf_off,(int)actual_bytes); -#endif /* QAK */ +#ifdef NO_DUFFS_DEVICE + /* Loop over all the blocks in the fastest changing dimension */ + while(fast_dim_count>0) { + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); - /* Increment the offset of the buffer */ - src+=actual_bytes; + /* Increment the offset of the buffer */ + src+=actual_bytes; - /* Increment the count write */ - num_write+=actual_write; + /* Increment information to reflect block just processed */ + dst+=fast_dim_buf_off; - /* Increment the offset and count for the fastest changing dimension */ + /* Decrement number of blocks */ + fast_dim_count--; + } /* end while */ +#else /* NO_DUFFS_DEVICE */ + duffs_index = (fast_dim_count + 7) / 8; + switch (fast_dim_count % 8) { + case 0: + do + { + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); - /* Move to the next block in the current dimension */ - /* Check for partial block write! */ - if(actual_write<fast_dim_block) { - offset[fast_dim]+=actual_write; - buf_off+=actual_bytes; - continue; /* don't bother checking slower dimensions */ + /* Increment the offset of the buffer */ + src+=actual_bytes; + + /* Increment information to reflect block just processed */ + dst+=fast_dim_buf_off; + + case 7: + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + src+=actual_bytes; + + /* Increment information to reflect block just processed */ + dst+=fast_dim_buf_off; + + case 6: + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + src+=actual_bytes; + + /* Increment information to reflect block just processed */ + dst+=fast_dim_buf_off; + + case 5: + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + src+=actual_bytes; + + /* Increment information to reflect block just processed */ + dst+=fast_dim_buf_off; + + case 4: + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + src+=actual_bytes; + + /* Increment information to reflect block just processed */ + dst+=fast_dim_buf_off; + + case 3: + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + src+=actual_bytes; + + /* Increment information to reflect block just processed */ + dst+=fast_dim_buf_off; + + case 2: + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + src+=actual_bytes; + + /* Increment information to reflect block just processed */ + dst+=fast_dim_buf_off; + + case 1: + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + src+=actual_bytes; + + /* Increment information to reflect block just processed */ + dst+=fast_dim_buf_off; + + } while (--duffs_index > 0); + } /* end switch */ +#endif /* NO_DUFFS_DEVICE */ + + /* Decrement number of elements left */ + io_left -= actual_write*act_blk_count; + + /* Decrement number of blocks left */ + tot_blk_count -= act_blk_count; + + /* Increment information to reflect block just processed */ + offset[fast_dim]=fast_dim_offset; /* reset the offset in the fastest dimension */ + tmp_count[fast_dim]=0; + + /* Increment offset in destination buffer */ + dst += wrap[fast_dim]; } /* end if */ else { - offset[fast_dim]+=fast_dim_stride; /* reset the offset in the fastest dimension */ - buf_off+=fast_dim_buf_off; - tmp_count[fast_dim]++; - } /* end else */ - /* If this block is still in the range of blocks to output for the dimension, break out of loop */ - if(tmp_count[fast_dim]<fast_dim_count) - continue; /* don't bother checking slower dimensions */ - else { - tmp_count[fast_dim]=0; /* reset back to the beginning of the line */ - offset[fast_dim]=fast_dim_offset; + /* Entire row of blocks doesn't fit into buffer */ + act_blk_count=tot_blk_count; + + /* Reduce number of blocks to output */ + fast_dim_count=tot_blk_count; + + /* Loop over all the blocks in the fastest changing dimension */ + while(fast_dim_count>0) { + /* Scatter out the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + src+=actual_bytes; + + /* Increment information to reflect block just processed */ + dst+=fast_dim_buf_off; + + /* Decrement number of blocks */ + fast_dim_count--; + } /* end while */ + + /* Decrement number of elements left */ + io_left -= actual_write*act_blk_count; + + /* Decrement number of blocks left */ + tot_blk_count -= act_blk_count; + + /* Increment information to reflect block just processed */ + offset[fast_dim]+=(fast_dim_stride*act_blk_count); /* reset the offset in the fastest dimension */ + tmp_count[fast_dim]+=act_blk_count; + + /* Handle any leftover, partial blocks in this row */ + if(io_left>0) { + actual_write=io_left; + actual_bytes=actual_write*elmt_size; + + /* Scatter out the rest of the sequence */ + HDmemcpy(dst,src,actual_bytes); + + /* Increment the offset of the buffer */ + src+=actual_bytes; + + /* Decrement the number of elements left */ + io_left -= actual_write; - /* Re-compute the initial buffer offset */ - for(i=0,buf_off=0; i<ndims; i++) - buf_off+=offset[i]*slab[i]; + /* Increment buffer correctly */ + offset[fast_dim]+=actual_write; + } /* end if */ + + /* don't bother checking slower dimensions */ + assert(tot_blk_count==0); + assert(io_left==0); + break; } /* end else */ /* Increment the offset and count for the other dimensions */ @@ -2853,7 +3665,6 @@ printf("%s: buf_off=%u, actual_bytes=%u\n",FUNC,(unsigned)buf_off,(int)actual_by while(temp_dim>=0) { /* Move to the next row in the curent dimension */ offset[temp_dim]++; - buf_off+=slab[temp_dim]; tmp_block[temp_dim]++; /* If this block is still in the range of blocks to output for the dimension, break out of loop */ @@ -2862,7 +3673,7 @@ printf("%s: buf_off=%u, actual_bytes=%u\n",FUNC,(unsigned)buf_off,(int)actual_by else { /* Move to the next block in the current dimension */ offset[temp_dim]+=(tdiminfo[temp_dim].stride-tdiminfo[temp_dim].block); - buf_off+=(tdiminfo[temp_dim].stride-tdiminfo[temp_dim].block)*slab[temp_dim]; + dst += skip[temp_dim]; tmp_block[temp_dim]=0; tmp_count[temp_dim]++; @@ -2870,14 +3681,11 @@ printf("%s: buf_off=%u, actual_bytes=%u\n",FUNC,(unsigned)buf_off,(int)actual_by if(tmp_count[temp_dim]<tdiminfo[temp_dim].count) break; else { + offset[temp_dim]=tdiminfo[temp_dim].start+mem_space->select.offset[temp_dim]; + dst += wrap[temp_dim]; tmp_count[temp_dim]=0; /* reset back to the beginning of the line */ tmp_block[temp_dim]=0; - offset[temp_dim]=tdiminfo[temp_dim].start+mem_space->select.offset[temp_dim]; - - /* Re-compute the initial buffer offset */ - for(i=0,buf_off=0; i<ndims; i++) - buf_off+=offset[i]*slab[i]; - } + } /* end else */ } /* end else */ /* Decrement dimension count */ @@ -2885,14 +3693,18 @@ printf("%s: buf_off=%u, actual_bytes=%u\n",FUNC,(unsigned)buf_off,(int)actual_by } /* end while */ } /* end while */ + /* Subtract out the selection offset */ + for(i=0; i<ndims; i++) + offset[i] -= mem_space->select.offset[i]; + /* Update the iterator with the location we stopped */ HDmemcpy(mem_iter->hyp.pos, offset, ndims*sizeof(hssize_t)); } /* end if */ /* Decrement the number of elements left in selection */ - mem_iter->hyp.elmt_left-=num_write; + mem_iter->hyp.elmt_left-=(nelmts-io_left); - FUNC_LEAVE (num_write); + FUNC_LEAVE (nelmts-io_left); } /* end H5S_hyper_mwrite_opt() */ @@ -5417,7 +6229,7 @@ H5S_hyper_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t assert(H5I_DATATYPE == H5I_get_type(type_id)); /* Initialize the selection iterator */ - if (H5S_hyper_init(NULL, space, &iter)<0) { + if (H5S_hyper_init(space, &iter)<0) { HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection information"); } diff --git a/src/H5Spoint.c b/src/H5Spoint.c index 072a5b7..780daf8 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -23,8 +23,7 @@ #define INTERFACE_INIT NULL static intn interface_initialize_g = 0; -static herr_t H5S_point_init (const struct H5O_layout_t *layout, - const H5S_t *space, H5S_sel_iter_t *iter); +static herr_t H5S_point_init (const H5S_t *space, H5S_sel_iter_t *iter); static hsize_t H5S_point_favail (const H5S_t *space, const H5S_sel_iter_t *iter, hsize_t max); static hsize_t H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout, @@ -86,13 +85,11 @@ const H5S_mconv_t H5S_POINT_MCONV[1] = {{ *------------------------------------------------------------------------- */ static herr_t -H5S_point_init (const struct H5O_layout_t UNUSED *layout, - const H5S_t *space, H5S_sel_iter_t *sel_iter) +H5S_point_init (const H5S_t *space, H5S_sel_iter_t *sel_iter) { FUNC_ENTER (H5S_point_init, FAIL); /* Check args */ - assert (layout); assert (space && H5S_SEL_POINTS==space->select.type); assert (sel_iter); diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 1415229..f1c355d 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -81,8 +81,7 @@ typedef struct H5S_fconv_t { H5S_sel_type type; /* Initialize file element numbering information */ - herr_t (*init)(const struct H5O_layout_t *layout, const H5S_t *space, - H5S_sel_iter_t *iter); + herr_t (*init)(const H5S_t *space, H5S_sel_iter_t *iter); /* Determine optimal number of elements to transfer */ hsize_t (*avail)(const H5S_t *file_space, const H5S_sel_iter_t *file_iter, @@ -111,8 +110,7 @@ typedef struct H5S_mconv_t { H5S_sel_type type; /* Initialize memory element numbering information */ - herr_t (*init)(const struct H5O_layout_t *layout, const H5S_t *space, - H5S_sel_iter_t *iter); + herr_t (*init)(const H5S_t *space, H5S_sel_iter_t *iter); /* Gather elements from app buffer to type conversion buffer */ hsize_t (*gath)(const void *buf, size_t elmt_size, @@ -221,8 +219,6 @@ __DLL__ herr_t H5S_extent_release(H5S_t *space); __DLL__ herr_t H5S_select_release(H5S_t *space); __DLL__ hssize_t H5S_get_select_npoints(const H5S_t *space); __DLL__ intn H5S_extend(H5S_t *space, const hsize_t *size); -__DLL__ herr_t H5S_set_extent_simple(H5S_t *space, int rank, - const hsize_t *dims, const hsize_t *max); __DLL__ htri_t H5S_select_valid(const H5S_t *space); __DLL__ herr_t H5S_debug(H5F_t *f, const void *_mesg, FILE *stream, intn indent, intn fwidth); @@ -7413,7 +7413,7 @@ H5T_print_stats(H5T_path_t UNUSED *path, intn UNUSED *nprint/*in,out*/) *------------------------------------------------------------------------- */ herr_t -H5T_debug(H5T_t *dt, FILE *stream) +H5T_debug(const H5T_t *dt, FILE *stream) { const char *s1="", *s2=""; int i; diff --git a/src/H5Tconv.c b/src/H5Tconv.c index a151db2..070c63b 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -1822,7 +1822,7 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts, size_t src_base_size, dst_base_size;/*source & destination base size*/ size_t src_size, dst_size;/*source & destination total size in bytes*/ void *conv_buf=NULL; /*temporary conversion buffer */ - hsize_t conv_buf_size; /*size of conversion buffer in bytes */ + size_t conv_buf_size; /*size of conversion buffer in bytes */ uint8_t dbuf[64],*dbuf_ptr=dbuf;/*temp destination buffer */ intn direction; /*direction of traversal */ hsize_t elmtno; /*element number counter */ diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 28d505c..cf37304 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -114,7 +114,7 @@ __DLL__ herr_t H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member); __DLL__ herr_t H5T_enum_insert(H5T_t *dt, const char *name, void *value); __DLL__ herr_t H5T_pack(H5T_t *dt); -__DLL__ herr_t H5T_debug(H5T_t *dt, FILE * stream); +__DLL__ herr_t H5T_debug(const H5T_t *dt, FILE * stream); __DLL__ H5G_entry_t *H5T_entof(H5T_t *dt); __DLL__ H5T_path_t *H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name, H5T_conv_t func); |