diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2003-08-28 16:02:21 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2003-08-28 16:02:21 (GMT) |
commit | a3888a3b007e818f4178b053606c8d1b46f0fa1b (patch) | |
tree | 315bb1018c4d2bc20b01e9ad7ff82f8d008e7537 /src/H5F.c | |
parent | b89fbdd877c687edb489d02f5f286a33e9af251f (diff) | |
download | hdf5-a3888a3b007e818f4178b053606c8d1b46f0fa1b.zip hdf5-a3888a3b007e818f4178b053606c8d1b46f0fa1b.tar.gz hdf5-a3888a3b007e818f4178b053606c8d1b46f0fa1b.tar.bz2 |
[svn-r7426] 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.c | 55 |
1 files changed, 50 insertions, 5 deletions
@@ -4196,7 +4196,7 @@ H5F_addr_decode(const H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*o *------------------------------------------------------------------------- */ herr_t -H5F_sieve_overlap_clear(const H5F_t *f, haddr_t addr, hsize_t size) +H5F_sieve_overlap_clear(const H5F_t *f, hid_t dxpl_id, haddr_t addr, hsize_t size) { herr_t ret_value=SUCCEED; /* Return value */ @@ -4207,10 +4207,55 @@ H5F_sieve_overlap_clear(const 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: |