diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2004-08-17 07:30:18 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2004-08-17 07:30:18 (GMT) |
commit | 2d3c6215f26b94e6fa0cb46178ea5c60fa075d66 (patch) | |
tree | 4fc137e84fd1a4ca4925de9b35f61bc40207767b /src/H5Dcontig.c | |
parent | 3646a3f83dc32b46c18fe2bfde9a2acdc70680f4 (diff) | |
download | hdf5-2d3c6215f26b94e6fa0cb46178ea5c60fa075d66.zip hdf5-2d3c6215f26b94e6fa0cb46178ea5c60fa075d66.tar.gz hdf5-2d3c6215f26b94e6fa0cb46178ea5c60fa075d66.tar.bz2 |
[svn-r9101] Purpose:
Bug fix
Description:
1 - Dataset contiguous storage cache information had a bug where it was
possible to try to access invalid cache information if the cache wasn't filled
the first time it attempted to loop through the list of offset/length vectors.
2 - Additionally, the contiguous storage cache information was being used
in certain circumstances from the chunked dataset I/O code path, which was
generally fatal since the chunk storage and contiguous storage information
were stored together in a union.
Solution:
1 - Avoid special case of first trip through loop over offset/length
I/O vectors and always check for the contiguous storage sieve buffer buffer
being NULL.
2 - Change the union containing the chunk and contiguous storage cache
information into a struct, allowing both to be used at the same time.
Platforms tested:
FreeBSD 4.10 (sleipnir)
h5committested
Diffstat (limited to 'src/H5Dcontig.c')
-rw-r--r-- | src/H5Dcontig.c | 530 |
1 files changed, 246 insertions, 284 deletions
diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index 35d5a23..a093b70 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -396,10 +396,7 @@ H5D_contig_readvv(H5F_t *f, hid_t dxpl_id, H5D_t *dset, void *_buf) { 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 */ size_t v; /* Counting variable */ @@ -417,82 +414,20 @@ H5D_contig_readvv(H5F_t *f, hid_t dxpl_id, H5D_t *dset, 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 */ + haddr_t abs_eoa; /* Absolute end of file address */ + haddr_t rel_eoa; /* Relative end of file address */ + hsize_t max_data; /* Actual maximum size of data to cache */ /* Set offsets in sequence lists */ u=*dset_curr_seq; v=*mem_curr_seq; - /* No data sieve buffer yet, go allocate one */ - if(dset->cache.contig.sieve_buf==NULL) { - /* Choose smallest buffer to write */ - if(mem_len_arr[v]<dset_len_arr[u]) - size=mem_len_arr[v]; - else - size=dset_len_arr[u]; - - /* Compute offset on disk */ - addr=dset_addr+dset_offset_arr[u]; - - /* Compute offset in memory */ - buf = (unsigned char *)_buf + mem_offset_arr[v]; - - /* Set up the buffer parameters */ - max_data=dset_size-dset_offset_arr[u]; - - /* Check if we can actually hold the I/O request in the sieve buffer */ - if(size>dset->cache.contig.sieve_buf_size) { - if (H5F_block_read(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0) - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed"); - } /* end if */ - else { - /* Allocate room for the data sieve buffer */ - if (NULL==(dset->cache.contig.sieve_buf=H5FL_BLK_MALLOC(sieve_buf,dset->cache.contig.sieve_buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - - /* Determine the new sieve buffer size & location */ - dset->cache.contig.sieve_loc=addr; - - /* Make certain we don't read off the end of the file */ - if (HADDR_UNDEF==(abs_eoa=H5F_get_eoa(f))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size"); - - /* Adjust absolute EOA address to relative EOA address */ - rel_eoa=abs_eoa-H5F_get_base_addr(f); - - /* Compute the size of the sieve buffer */ - H5_ASSIGN_OVERFLOW(dset->cache.contig.sieve_size,MIN3(rel_eoa-dset->cache.contig.sieve_loc,max_data,dset->cache.contig.sieve_buf_size),hsize_t,size_t); - - /* Read the new sieve buffer */ - if (H5F_block_read(f, H5FD_MEM_DRAW, dset->cache.contig.sieve_loc, dset->cache.contig.sieve_size, dxpl_id, dset->cache.contig.sieve_buf)<0) - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed"); - - /* Grab the data out of the buffer (must be first piece of data in buffer ) */ - HDmemcpy(buf,dset->cache.contig.sieve_buf,size); - - /* Reset sieve buffer dirty flag */ - dset->cache.contig.sieve_dirty=0; - } /* end else */ - - /* Update memory information */ - mem_len_arr[v]-=size; - mem_offset_arr[v]+=size; - if(mem_len_arr[v]==0) - v++; - - /* Update file information */ - dset_len_arr[u]-=size; - dset_offset_arr[u]+=size; - if(dset_len_arr[u]==0) - u++; - - /* Increment number of bytes copied */ - ret_value+=size; - } /* end if */ - /* Stash local copies of these value */ - sieve_start=dset->cache.contig.sieve_loc; - sieve_size=dset->cache.contig.sieve_size; - sieve_end=sieve_start+sieve_size; + if(dset->cache.contig.sieve_buf!=NULL) { + sieve_start=dset->cache.contig.sieve_loc; + sieve_size=dset->cache.contig.sieve_size; + sieve_end=sieve_start+sieve_size; + } /* end if */ /* Works through sequences as fast as possible */ for(; u<dset_max_nseq && v<mem_max_nseq; ) { @@ -508,49 +443,17 @@ H5D_contig_readvv(H5F_t *f, hid_t dxpl_id, H5D_t *dset, /* Compute offset in memory */ buf = (unsigned char *)_buf + mem_offset_arr[v]; - /* 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=dset->cache.contig.sieve_buf+(addr-sieve_start); - - /* Grab the data out of the buffer */ - HDmemcpy(buf,base_sieve_buf,size); - } /* end if */ - /* Entire request is not within this data sieve buffer */ - else { + /* Check if the sieve buffer is allocated yet */ + if(dset->cache.contig.sieve_buf==NULL) { /* Check if we can actually hold the I/O request in the sieve buffer */ if(size>dset->cache.contig.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(dset->cache.contig.sieve_dirty) { - /* Write to file */ - if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, dset->cache.contig.sieve_buf)<0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed"); - - /* Reset sieve buffer dirty flag */ - dset->cache.contig.sieve_dirty=0; - } /* end if */ - } /* end if */ - - /* Read directly into the user's buffer */ if (H5F_block_read(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0) HGOTO_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(dset->cache.contig.sieve_dirty) { - /* Write to file */ - if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, dset->cache.contig.sieve_buf)<0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed"); - - /* Reset sieve buffer dirty flag */ - dset->cache.contig.sieve_dirty=0; - } /* end if */ + /* Allocate room for the data sieve buffer */ + if (NULL==(dset->cache.contig.sieve_buf=H5FL_BLK_MALLOC(sieve_buf,dset->cache.contig.sieve_buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); /* Determine the new sieve buffer size & location */ dset->cache.contig.sieve_loc=addr; @@ -562,18 +465,12 @@ H5D_contig_readvv(H5F_t *f, hid_t dxpl_id, H5D_t *dset, /* Adjust absolute EOA address to relative EOA address */ rel_eoa=abs_eoa-H5F_get_base_addr(f); - /* Only need this when resizing sieve buffer */ + /* Set up the buffer parameters */ max_data=dset_size-dset_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 */ H5_ASSIGN_OVERFLOW(dset->cache.contig.sieve_size,MIN3(rel_eoa-dset->cache.contig.sieve_loc,max_data,dset->cache.contig.sieve_buf_size),hsize_t,size_t); - /* Update local copies of sieve information */ - sieve_start=dset->cache.contig.sieve_loc; - sieve_size=dset->cache.contig.sieve_size; - sieve_end=sieve_start+sieve_size; - /* Read the new sieve buffer */ if (H5F_block_read(f, H5FD_MEM_DRAW, dset->cache.contig.sieve_loc, dset->cache.contig.sieve_size, dxpl_id, dset->cache.contig.sieve_buf)<0) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed"); @@ -583,6 +480,90 @@ H5D_contig_readvv(H5F_t *f, hid_t dxpl_id, H5D_t *dset, /* Reset sieve buffer dirty flag */ dset->cache.contig.sieve_dirty=0; + + /* Stash local copies of these value */ + sieve_start=dset->cache.contig.sieve_loc; + sieve_size=dset->cache.contig.sieve_size; + sieve_end=sieve_start+sieve_size; + } /* end else */ + } /* end if */ + else { + /* 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=dset->cache.contig.sieve_buf+(addr-sieve_start); + + /* Grab the data out of the buffer */ + HDmemcpy(buf,base_sieve_buf,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>dset->cache.contig.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(dset->cache.contig.sieve_dirty) { + /* Write to file */ + if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, dset->cache.contig.sieve_buf)<0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed"); + + /* Reset sieve buffer dirty flag */ + dset->cache.contig.sieve_dirty=0; + } /* end if */ + } /* end if */ + + /* Read directly into the user's buffer */ + if (H5F_block_read(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0) + HGOTO_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(dset->cache.contig.sieve_dirty) { + /* Write to file */ + if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, dset->cache.contig.sieve_buf)<0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed"); + + /* Reset sieve buffer dirty flag */ + dset->cache.contig.sieve_dirty=0; + } /* end if */ + + /* Determine the new sieve buffer size & location */ + dset->cache.contig.sieve_loc=addr; + + /* Make certain we don't read off the end of the file */ + if (HADDR_UNDEF==(abs_eoa=H5F_get_eoa(f))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size"); + + /* Adjust absolute EOA address to relative EOA address */ + rel_eoa=abs_eoa-H5F_get_base_addr(f); + + /* Only need this when resizing sieve buffer */ + max_data=dset_size-dset_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 */ + H5_ASSIGN_OVERFLOW(dset->cache.contig.sieve_size,MIN3(rel_eoa-dset->cache.contig.sieve_loc,max_data,dset->cache.contig.sieve_buf_size),hsize_t,size_t); + + /* Update local copies of sieve information */ + sieve_start=dset->cache.contig.sieve_loc; + sieve_size=dset->cache.contig.sieve_size; + sieve_end=sieve_start+sieve_size; + + /* Read the new sieve buffer */ + if (H5F_block_read(f, H5FD_MEM_DRAW, dset->cache.contig.sieve_loc, dset->cache.contig.sieve_size, dxpl_id, dset->cache.contig.sieve_buf)<0) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed"); + + /* Grab the data out of the buffer (must be first piece of data in buffer ) */ + HDmemcpy(buf,dset->cache.contig.sieve_buf,size); + + /* Reset sieve buffer dirty flag */ + dset->cache.contig.sieve_dirty=0; + } /* end else */ } /* end else */ } /* end else */ @@ -675,10 +656,7 @@ H5D_contig_writevv(H5F_t *f, hid_t dxpl_id, H5D_t *dset, const void *_buf) { 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 */ size_t v; /* Counting variable */ @@ -696,13 +674,23 @@ H5D_contig_writevv(H5F_t *f, hid_t dxpl_id, H5D_t *dset, 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 */ + haddr_t abs_eoa; /* Absolute end of file address */ + haddr_t rel_eoa; /* Relative end of file address */ + hsize_t max_data; /* Actual maximum size of data to cache */ /* Set offsets in sequence lists */ u=*dset_curr_seq; v=*mem_curr_seq; - /* No data sieve buffer yet, go allocate one */ - if(dset->cache.contig.sieve_buf==NULL) { + /* Stash local copies of these values */ + if(dset->cache.contig.sieve_buf!=NULL) { + sieve_start=dset->cache.contig.sieve_loc; + sieve_size=dset->cache.contig.sieve_size; + sieve_end=sieve_start+sieve_size; + } /* end if */ + + /* Works through sequences as fast as possible */ + for(; u<dset_max_nseq && v<mem_max_nseq; ) { /* Choose smallest buffer to write */ if(mem_len_arr[v]<dset_len_arr[u]) size=mem_len_arr[v]; @@ -715,201 +703,175 @@ H5D_contig_writevv(H5F_t *f, hid_t dxpl_id, H5D_t *dset, /* Compute offset in memory */ buf = (const unsigned char *)_buf + mem_offset_arr[v]; - /* Set up the buffer parameters */ - max_data=dset_size-dset_offset_arr[u]; - - /* Check if we can actually hold the I/O request in the sieve buffer */ - if(size>dset->cache.contig.sieve_buf_size) { - if (H5F_block_write(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed"); - } /* end if */ - else { - /* Allocate room for the data sieve buffer */ - if (NULL==(dset->cache.contig.sieve_buf=H5FL_BLK_MALLOC(sieve_buf,dset->cache.contig.sieve_buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - - /* Determine the new sieve buffer size & location */ - dset->cache.contig.sieve_loc=addr; - - /* Make certain we don't read off the end of the file */ - if (HADDR_UNDEF==(abs_eoa=H5F_get_eoa(f))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size"); - - /* Adjust absolute EOA address to relative EOA address */ - rel_eoa=abs_eoa-H5F_get_base_addr(f); - - /* Compute the size of the sieve buffer */ - H5_ASSIGN_OVERFLOW(dset->cache.contig.sieve_size,MIN3(rel_eoa-dset->cache.contig.sieve_loc,max_data,dset->cache.contig.sieve_buf_size),hsize_t,size_t); - - /* Check if there is any point in reading the data from the file */ - if(dset->cache.contig.sieve_size>size) { - /* Read the new sieve buffer */ - if (H5F_block_read(f, H5FD_MEM_DRAW, dset->cache.contig.sieve_loc, dset->cache.contig.sieve_size, dxpl_id, dset->cache.contig.sieve_buf)<0) - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed"); + /* No data sieve buffer yet, go allocate one */ + if(dset->cache.contig.sieve_buf==NULL) { + /* Check if we can actually hold the I/O request in the sieve buffer */ + if(size>dset->cache.contig.sieve_buf_size) { + if (H5F_block_write(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed"); } /* end if */ + else { + /* Allocate room for the data sieve buffer */ + if (NULL==(dset->cache.contig.sieve_buf=H5FL_BLK_MALLOC(sieve_buf,dset->cache.contig.sieve_buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - /* Grab the data out of the buffer (must be first piece of data in buffer ) */ - HDmemcpy(dset->cache.contig.sieve_buf,buf,size); - - /* Set sieve buffer dirty flag */ - dset->cache.contig.sieve_dirty=1; - } /* end else */ - - /* Update memory information */ - mem_len_arr[v]-=size; - mem_offset_arr[v]+=size; - if(mem_len_arr[v]==0) - v++; - - /* Update file information */ - dset_len_arr[u]-=size; - dset_offset_arr[u]+=size; - if(dset_len_arr[u]==0) - u++; - - /* Increment number of bytes copied */ - ret_value+=size; - } /* end if */ + /* Determine the new sieve buffer size & location */ + dset->cache.contig.sieve_loc=addr; - /* Stash local copies of these value */ - sieve_start=dset->cache.contig.sieve_loc; - sieve_size=dset->cache.contig.sieve_size; - sieve_end=sieve_start+sieve_size; - - /* Works through sequences as fast as possible */ - for(; u<dset_max_nseq && v<mem_max_nseq; ) { - /* Choose smallest buffer to write */ - if(mem_len_arr[v]<dset_len_arr[u]) - size=mem_len_arr[v]; - else - size=dset_len_arr[u]; + /* Make certain we don't read off the end of the file */ + if (HADDR_UNDEF==(abs_eoa=H5F_get_eoa(f))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size"); - /* Compute offset on disk */ - addr=dset_addr+dset_offset_arr[u]; + /* Adjust absolute EOA address to relative EOA address */ + rel_eoa=abs_eoa-H5F_get_base_addr(f); - /* Compute offset in memory */ - buf = (const unsigned char *)_buf + mem_offset_arr[v]; + /* Set up the buffer parameters */ + max_data=dset_size-dset_offset_arr[u]; - /* Compute end of sequence to retrieve */ - contig_end=addr+size-1; + /* Compute the size of the sieve buffer */ + H5_ASSIGN_OVERFLOW(dset->cache.contig.sieve_size,MIN3(rel_eoa-dset->cache.contig.sieve_loc,max_data,dset->cache.contig.sieve_buf_size),hsize_t,size_t); - /* 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=dset->cache.contig.sieve_buf+(addr-sieve_start); + /* Check if there is any point in reading the data from the file */ + if(dset->cache.contig.sieve_size>size) { + /* Read the new sieve buffer */ + if (H5F_block_read(f, H5FD_MEM_DRAW, dset->cache.contig.sieve_loc, dset->cache.contig.sieve_size, dxpl_id, dset->cache.contig.sieve_buf)<0) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed"); + } /* end if */ - /* Put the data into the sieve buffer */ - HDmemcpy(base_sieve_buf,buf,size); + /* Grab the data out of the buffer (must be first piece of data in buffer ) */ + HDmemcpy(dset->cache.contig.sieve_buf,buf,size); - /* Set sieve buffer dirty flag */ - dset->cache.contig.sieve_dirty=1; + /* Set sieve buffer dirty flag */ + dset->cache.contig.sieve_dirty=1; + /* Stash local copies of these values */ + sieve_start=dset->cache.contig.sieve_loc; + sieve_size=dset->cache.contig.sieve_size; + sieve_end=sieve_start+sieve_size; + } /* end else */ } /* 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>dset->cache.contig.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(dset->cache.contig.sieve_dirty) { - /* Write to file */ - if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, dset->cache.contig.sieve_buf)<0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed"); + /* Compute end of sequence to retrieve */ + contig_end=addr+size-1; - /* Reset sieve buffer dirty flag */ - dset->cache.contig.sieve_dirty=0; - } /* end if */ + /* 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=dset->cache.contig.sieve_buf+(addr-sieve_start); - /* Force the sieve buffer to be re-read the next time */ - dset->cache.contig.sieve_loc=HADDR_UNDEF; - dset->cache.contig.sieve_size=0; - } /* end if */ + /* Put the data into the sieve buffer */ + HDmemcpy(base_sieve_buf,buf,size); + + /* Set sieve buffer dirty flag */ + dset->cache.contig.sieve_dirty=1; - /* Write directly from the user's buffer */ - if (H5F_block_write(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed"); } /* end if */ - /* Element size fits within the buffer size */ + /* Entire request is not within this data sieve buffer */ 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)<=dset->cache.contig.sieve_buf_size && - dset->cache.contig.sieve_dirty) { - /* Prepend to existing sieve buffer */ - if((addr+size)==sieve_start) { - /* Move existing sieve information to correct location */ - HDmemmove(dset->cache.contig.sieve_buf+size,dset->cache.contig.sieve_buf,sieve_size); - - /* Copy in new information (must be first in sieve buffer) */ - HDmemcpy(dset->cache.contig.sieve_buf,buf,size); - - /* Adjust sieve location */ - dset->cache.contig.sieve_loc=addr; - + /* Check if we can actually hold the I/O request in the sieve buffer */ + if(size>dset->cache.contig.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(dset->cache.contig.sieve_dirty) { + /* Write to file */ + if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, dset->cache.contig.sieve_buf)<0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed"); + + /* Reset sieve buffer dirty flag */ + dset->cache.contig.sieve_dirty=0; + } /* end if */ + + /* Force the sieve buffer to be re-read the next time */ + dset->cache.contig.sieve_loc=HADDR_UNDEF; + dset->cache.contig.sieve_size=0; } /* end if */ - /* Append to existing sieve buffer */ - else { - /* Copy in new information */ - HDmemcpy(dset->cache.contig.sieve_buf+sieve_size,buf,size); - } /* end else */ - - /* Adjust sieve size */ - dset->cache.contig.sieve_size += size; - - /* Update local copies of sieve information */ - sieve_start=dset->cache.contig.sieve_loc; - sieve_size=dset->cache.contig.sieve_size; - sieve_end=sieve_start+sieve_size; + /* Write directly from the user's buffer */ + if (H5F_block_write(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed"); } /* end if */ - /* Can't add the new data onto the existing sieve buffer */ + /* Element size fits within the buffer size */ else { - /* Flush the sieve buffer if it's dirty */ - if(dset->cache.contig.sieve_dirty) { - /* Write to file */ - if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, dset->cache.contig.sieve_buf)<0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed"); + /* 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)<=dset->cache.contig.sieve_buf_size && + dset->cache.contig.sieve_dirty) { + /* Prepend to existing sieve buffer */ + if((addr+size)==sieve_start) { + /* Move existing sieve information to correct location */ + HDmemmove(dset->cache.contig.sieve_buf+size,dset->cache.contig.sieve_buf,sieve_size); + + /* Copy in new information (must be first in sieve buffer) */ + HDmemcpy(dset->cache.contig.sieve_buf,buf,size); + + /* Adjust sieve location */ + dset->cache.contig.sieve_loc=addr; + + } /* end if */ + /* Append to existing sieve buffer */ + else { + /* Copy in new information */ + HDmemcpy(dset->cache.contig.sieve_buf+sieve_size,buf,size); + } /* end else */ + + /* Adjust sieve size */ + dset->cache.contig.sieve_size += size; + + /* Update local copies of sieve information */ + sieve_start=dset->cache.contig.sieve_loc; + sieve_size=dset->cache.contig.sieve_size; + sieve_end=sieve_start+sieve_size; - /* Reset sieve buffer dirty flag */ - dset->cache.contig.sieve_dirty=0; } /* end if */ + /* Can't add the new data onto the existing sieve buffer */ + else { + /* Flush the sieve buffer if it's dirty */ + if(dset->cache.contig.sieve_dirty) { + /* Write to file */ + if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, dset->cache.contig.sieve_buf)<0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed"); - /* Determine the new sieve buffer size & location */ - dset->cache.contig.sieve_loc=addr; + /* Reset sieve buffer dirty flag */ + dset->cache.contig.sieve_dirty=0; + } /* end if */ - /* Make certain we don't read off the end of the file */ - if (HADDR_UNDEF==(abs_eoa=H5F_get_eoa(f))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size"); + /* Determine the new sieve buffer size & location */ + dset->cache.contig.sieve_loc=addr; - /* Adjust absolute EOA address to relative EOA address */ - rel_eoa=abs_eoa-H5F_get_base_addr(f); + /* Make certain we don't read off the end of the file */ + if (HADDR_UNDEF==(abs_eoa=H5F_get_eoa(f))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size"); - /* Only need this when resizing sieve buffer */ - max_data=dset_size-dset_offset_arr[u]; + /* Adjust absolute EOA address to relative EOA address */ + rel_eoa=abs_eoa-H5F_get_base_addr(f); - /* 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 */ - H5_ASSIGN_OVERFLOW(dset->cache.contig.sieve_size,MIN3(rel_eoa-dset->cache.contig.sieve_loc,max_data,dset->cache.contig.sieve_buf_size),hsize_t,size_t); + /* Only need this when resizing sieve buffer */ + max_data=dset_size-dset_offset_arr[u]; - /* Update local copies of sieve information */ - sieve_start=dset->cache.contig.sieve_loc; - sieve_size=dset->cache.contig.sieve_size; - sieve_end=sieve_start+sieve_size; + /* 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 */ + H5_ASSIGN_OVERFLOW(dset->cache.contig.sieve_size,MIN3(rel_eoa-dset->cache.contig.sieve_loc,max_data,dset->cache.contig.sieve_buf_size),hsize_t,size_t); - /* Check if there is any point in reading the data from the file */ - if(dset->cache.contig.sieve_size>size) { - /* Read the new sieve buffer */ - if (H5F_block_read(f, H5FD_MEM_DRAW, dset->cache.contig.sieve_loc, dset->cache.contig.sieve_size, dxpl_id, dset->cache.contig.sieve_buf)<0) - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed"); - } /* end if */ + /* Update local copies of sieve information */ + sieve_start=dset->cache.contig.sieve_loc; + sieve_size=dset->cache.contig.sieve_size; + sieve_end=sieve_start+sieve_size; - /* Grab the data out of the buffer (must be first piece of data in buffer ) */ - HDmemcpy(dset->cache.contig.sieve_buf,buf,size); + /* Check if there is any point in reading the data from the file */ + if(dset->cache.contig.sieve_size>size) { + /* Read the new sieve buffer */ + if (H5F_block_read(f, H5FD_MEM_DRAW, dset->cache.contig.sieve_loc, dset->cache.contig.sieve_size, dxpl_id, dset->cache.contig.sieve_buf)<0) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed"); + } /* end if */ - /* Set sieve buffer dirty flag */ - dset->cache.contig.sieve_dirty=1; + /* Grab the data out of the buffer (must be first piece of data in buffer ) */ + HDmemcpy(dset->cache.contig.sieve_buf,buf,size); + + /* Set sieve buffer dirty flag */ + dset->cache.contig.sieve_dirty=1; + } /* end else */ } /* end else */ } /* end else */ } /* end else */ |