summaryrefslogtreecommitdiffstats
path: root/src/H5F.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2003-08-28 16:03:34 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2003-08-28 16:03:34 (GMT)
commitb772787079dcac337276ea27dc68a54d9295b9f6 (patch)
tree575440bfdfda93bd74eb50c02d725fff42af33fe /src/H5F.c
parentbe04bab58bf696122a77b3478a223f719d7e3e98 (diff)
downloadhdf5-b772787079dcac337276ea27dc68a54d9295b9f6.zip
hdf5-b772787079dcac337276ea27dc68a54d9295b9f6.tar.gz
hdf5-b772787079dcac337276ea27dc68a54d9295b9f6.tar.bz2
[svn-r7427] Purpose:
Bug fix Description: When datasets are deleted from a file, they are removed from the sieve buffer, but instead of invalidating only the part of the sieve buffer affected, the sieve buffer code would throw away the entire sieve buffer, potentially including other raw data in the buffer that hadn't been written to disk yet. Solution: Improve the sieve buffer clearing code to handle partial invalidations. Platforms tested: FreeBSD 4.8 (sleipnir) h5committest
Diffstat (limited to 'src/H5F.c')
-rw-r--r--src/H5F.c55
1 files changed, 50 insertions, 5 deletions
diff --git a/src/H5F.c b/src/H5F.c
index dba1646..5ac2d6f 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -4224,7 +4224,7 @@ H5F_addr_pack(H5F_t UNUSED *f, haddr_t *addr_p/*out*/,
*-------------------------------------------------------------------------
*/
herr_t
-H5F_sieve_overlap_clear(H5F_t *f, haddr_t addr, hsize_t size)
+H5F_sieve_overlap_clear(H5F_t *f, hid_t dxpl_id, haddr_t addr, hsize_t size)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -4235,10 +4235,55 @@ H5F_sieve_overlap_clear(H5F_t *f, haddr_t addr, hsize_t size)
/* Check for the address range overlapping with the sieve buffer */
if(H5F_addr_overlap(f->shared->sieve_loc,f->shared->sieve_size,addr,size)) {
- /* Reset sieve information */
- f->shared->sieve_loc=HADDR_UNDEF;
- f->shared->sieve_size=0;
- f->shared->sieve_dirty=0;
+ /* Check if only part of the sieve buffer is being invalidated */
+ if(size<f->shared->sieve_size) {
+ /* Check if the portion to invalidate is at the end */
+ if((f->shared->sieve_loc+f->shared->sieve_size)==(addr+size)) {
+ /* Just shorten the buffer */
+ f->shared->sieve_size-=size;
+ } /* end if */
+ /* Check if the portion to invalidate is at the beginning */
+ else if(f->shared->sieve_loc==addr) {
+ /* Advance the start of the sieve buffer (on disk) and shorten the buffer */
+ f->shared->sieve_loc+=size;
+ f->shared->sieve_size-=size;
+
+ /* Move the retained information in the buffer down */
+ HDmemcpy(f->shared->sieve_buf,f->shared->sieve_buf+size,f->shared->sieve_size);
+ } /* end elif */
+ /* Portion to invalidate is in middle */
+ else {
+ size_t invalid_size; /* Portion of sieve buffer to invalidate */
+
+ /* Write out portion at the beginning of the buffer, if buffer is dirty */
+ if(f->shared->sieve_dirty) {
+ size_t start_size; /* Portion of sieve buffer to write */
+
+ /* Compute size of block at beginning of buffer */
+ start_size=(addr-f->shared->sieve_loc);
+
+ /* Write to file */
+ if (H5F_block_write(f, H5FD_MEM_DRAW, f->shared->sieve_loc, start_size, dxpl_id, f->shared->sieve_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+ } /* end if */
+
+ /* Compute size of block to invalidate */
+ invalid_size=((addr+size)-f->shared->sieve_loc);
+
+ /* Advance the start of the sieve buffer (on disk) and shorten the buffer */
+ f->shared->sieve_loc+=invalid_size;
+ f->shared->sieve_size-=invalid_size;
+
+ /* Move the retained information in the buffer down */
+ HDmemcpy(f->shared->sieve_buf,f->shared->sieve_buf+invalid_size,f->shared->sieve_size);
+ } /* end else */
+ } /* end if */
+ else {
+ /* Reset sieve information */
+ f->shared->sieve_loc=HADDR_UNDEF;
+ f->shared->sieve_size=0;
+ f->shared->sieve_dirty=0;
+ } /* end else */
} /* end if */
done: