diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2010-04-15 19:57:02 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2010-04-15 19:57:02 (GMT) |
commit | ebd22f7643d53b234b43393d8ede23e0549caa5f (patch) | |
tree | 62b13c6ef0f705822fd925687073df7988bd8288 /src/H5Faccum.c | |
parent | 227a351e4758ffb0af9882b00831ad6cf1acff3b (diff) | |
download | hdf5-ebd22f7643d53b234b43393d8ede23e0549caa5f.zip hdf5-ebd22f7643d53b234b43393d8ede23e0549caa5f.tar.gz hdf5-ebd22f7643d53b234b43393d8ede23e0549caa5f.tar.bz2 |
[svn-r18571] Description:
Bring r18542 from metadata journaling "merging" branch to trunk:
Bring new object header pin/unpin & protect/unprotect routines and
split-out object header chunk proxy changes from metadata_journaling branch to
"merging" branch, along with some other minor tweaks to clean up compiler
warnings, etc.
Also: clean up chunk protect/unprotect calls when allocating or freeing
space in a chunk, optimize metadata accumulator code to avoid some re-reading
of information from the file, refactor H5O_pin/H5O_unpin from way they are done
on the merging branch back to way they were previously done on trunk, other
minor code cleanups, etc.
Tested on
FreeBSD/32 6.3 (duty) in debug mode
FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode
Linux/64-amd64 2.6 (amani) w/Intel compilers, w/default API=1.6.x,
w/C++ & FORTRAN, in production mode
Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN,
w/szip filter, in production mode
Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN,
in production mode
Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in debug mode
Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode
Mac OS X/32 10.6.3 (amazon) in debug mode
Mac OS X/32 10.6.3 (amazon) w/C++ & FORTRAN, w/threadsafe,
in production mode
Diffstat (limited to 'src/H5Faccum.c')
-rw-r--r-- | src/H5Faccum.c | 121 |
1 files changed, 73 insertions, 48 deletions
diff --git a/src/H5Faccum.c b/src/H5Faccum.c index e525a08..426a639 100644 --- a/src/H5Faccum.c +++ b/src/H5Faccum.c @@ -126,68 +126,68 @@ H5F_accum_read(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, /* Check if this information is in the metadata accumulator */ if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && type != H5FD_MEM_DRAW && size < H5F_ACCUM_MAX_SIZE) { - /* Current read overlaps with metadata accumulator */ - if(H5F_addr_overlap(addr, size, f->shared->accum.loc, f->shared->accum.size)) { - unsigned char *read_buf = (unsigned char *)buf; /* Pointer to the buffer being read in */ - size_t amount_read; /* Amount to read at a time */ - hsize_t read_off; /* Offset to read from */ + /* Sanity check */ + HDassert(!f->shared->accum.buf || (f->shared->accum.alloc_size >= f->shared->accum.size)); + + /* Current read adjoins or overlaps with metadata accumulator */ + if(H5F_addr_overlap(addr, size, f->shared->accum.loc, f->shared->accum.size) + || ((addr + size) == f->shared->accum.loc) + || (f->shared->accum.loc + f->shared->accum.size) == addr) { + size_t amount_before; /* Amount to read before current accumulator */ + haddr_t new_addr; /* New address of the accumulator buffer */ + size_t new_size; /* New size of the accumulator buffer */ + + /* Compute new values for accumulator */ + new_addr = MIN(addr, f->shared->accum.loc); + new_size = (size_t)(MAX((addr + size), (f->shared->accum.loc + f->shared->accum.size)) + - new_addr); + + /* Check if we need more buffer space */ + if(new_size > f->shared->accum.size) { + /* Adjust the buffer size, by doubling it */ + f->shared->accum.alloc_size = MAX(f->shared->accum.alloc_size * 2, new_size); + + /* Reallocate the metadata accumulator buffer */ + if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, f->shared->accum.alloc_size))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "unable to allocate metadata accumulator buffer") +#ifdef H5_CLEAR_MEMORY +HDmemset(f->shared->accum.buf + f->shared->accum.size, 0, (f->shared->accum.alloc_size - f->shared->accum.size)); +#endif /* H5_CLEAR_MEMORY */ + } /* end if */ /* Read the part before the metadata accumulator */ if(addr < f->shared->accum.loc) { /* Set the amount to read */ - H5_ASSIGN_OVERFLOW(amount_read, (f->shared->accum.loc - addr), hsize_t, size_t); + H5_ASSIGN_OVERFLOW(amount_before, (f->shared->accum.loc - addr), hsize_t, size_t); + + /* Make room for the metadata to read in */ + HDmemmove(f->shared->accum.buf + amount_before, f->shared->accum.buf, f->shared->accum.size); /* Dispatch to driver */ - if(H5FD_read(f->shared->lf, dxpl_id, type, addr, amount_read, read_buf) < 0) + if(H5FD_read(f->shared->lf, dxpl_id, type, addr, amount_before, f->shared->accum.buf) < 0) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") - - /* Adjust the buffer, address & size */ - read_buf += amount_read; - addr += amount_read; - size -= amount_read; } /* end if */ + else + amount_before = 0; - /* Copy the part overlapping the metadata accumulator */ - if(size > 0 && (addr >= f->shared->accum.loc && addr < (f->shared->accum.loc + f->shared->accum.size))) { - /* Set the offset to "read" from */ - read_off = addr - f->shared->accum.loc; - - /* Set the amount to "read" */ -#ifndef NDEBUG -{ - hsize_t tempamount_read; /* Amount to read at a time */ - - tempamount_read = f->shared->accum.size - read_off; - H5_CHECK_OVERFLOW(tempamount_read, hsize_t, size_t); - amount_read = MIN(size, (size_t)tempamount_read); -} -#else /* NDEBUG */ - amount_read = MIN(size, (size_t)(f->shared->accum.size - read_off)); -#endif /* NDEBUG */ - - /* Copy the data out of the buffer */ - HDmemcpy(read_buf, f->shared->accum.buf + read_off, amount_read); + /* Read the part after the metadata accumulator */ + if((addr + size) > (f->shared->accum.loc + f->shared->accum.size)) { + size_t amount_after; /* Amount to read at a time */ - /* Adjust the buffer, address & size */ - read_buf += amount_read; - addr += amount_read; - size -= amount_read; - } /* end if */ + /* Set the amount to read */ + H5_ASSIGN_OVERFLOW(amount_after, ((addr + size) - (f->shared->accum.loc + f->shared->accum.size)), hsize_t, size_t); - /* Read the part after the metadata accumulator */ - if(size > 0 && addr >= (f->shared->accum.loc + f->shared->accum.size)) { /* Dispatch to driver */ - if(H5FD_read(f->shared->lf, dxpl_id, type, addr, size, read_buf) < 0) + if(H5FD_read(f->shared->lf, dxpl_id, type, (f->shared->accum.loc + f->shared->accum.size), amount_after, (f->shared->accum.buf + f->shared->accum.size + amount_before)) < 0) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") - - /* Adjust the buffer, address & size */ - read_buf += size; - addr += size; - size -= size; } /* end if */ - /* Make certain we've read it all */ - HDassert(size == 0); + /* Copy the data out of the buffer */ + HDmemcpy(buf, f->shared->accum.buf + (addr - new_addr), size); + + /* Adjust the accumulator address & size */ + f->shared->accum.loc = new_addr; + f->shared->accum.size = new_size; } /* end if */ /* Current read doesn't overlap with metadata accumulator, read it from file */ else { @@ -340,6 +340,9 @@ H5F_accum_write(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, /* Check for accumulating metadata */ if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && type != H5FD_MEM_DRAW && size < H5F_ACCUM_MAX_SIZE) { + /* Sanity check */ + HDassert(!f->shared->accum.buf || (f->shared->accum.alloc_size >= f->shared->accum.size)); + /* Check if there is already metadata in the accumulator */ if(f->shared->accum.size > 0) { /* Check if the new metadata adjoins the beginning of the current accumulator */ @@ -433,8 +436,30 @@ H5F_accum_write(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, /* Mark it as written to */ f->shared->accum.dirty = TRUE; } /* end if */ + /* New metadata overlaps both ends of the current accumulator */ else { - HDassert(0 && "New metadata overlapped both beginning and end of existing metadata accumulator!"); + /* Check if we need more buffer space */ + if(size > f->shared->accum.size) { + /* Adjust the buffer size, by doubling it */ + f->shared->accum.alloc_size = MAX(f->shared->accum.alloc_size * 2, size); + + /* Reallocate the metadata accumulator buffer */ + if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, f->shared->accum.alloc_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") +#ifdef H5_CLEAR_MEMORY +HDmemset(f->shared->accum.buf + size, 0, (f->shared->accum.alloc_size - size)); +#endif /* H5_CLEAR_MEMORY */ + } /* end if */ + + /* Copy the new metadata to the buffer */ + HDmemcpy(f->shared->accum.buf, buf, size); + + /* Set the new size & location of the metadata accumulator */ + f->shared->accum.loc = addr; + f->shared->accum.size = size; + + /* Mark it as written to */ + f->shared->accum.dirty = TRUE; } /* end else */ } /* end if */ /* New piece of metadata doesn't adjoin or overlap the existing accumulator */ |