summaryrefslogtreecommitdiffstats
path: root/src/H5Dcontig.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Dcontig.c')
-rw-r--r--src/H5Dcontig.c1271
1 files changed, 497 insertions, 774 deletions
diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c
index 2593d83..3a14175 100644
--- a/src/H5Dcontig.c
+++ b/src/H5Dcontig.c
@@ -18,9 +18,8 @@
*
* Purpose:
* Contiguous dataset I/O functions. These routines are similar to
- * the H5F_istore_* routines and really only abstract away dealing
- * with the data sieve buffer from the H5F_arr_read/write and
- * H5F_seg_read/write.
+ * the H5F_istore_* routines and really only an abstract way of dealing
+ * with the data sieve buffer from H5F_seg_read/write.
*/
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
@@ -34,6 +33,7 @@
#include "H5MFprivate.h" /*file memory management */
#include "H5Oprivate.h" /* Object headers */
#include "H5Pprivate.h" /* Property lists */
+#include "H5Sprivate.h" /* Dataspace functions */
#include "H5Vprivate.h" /* Vector and array functions */
/* MPIO, MPIPOSIX, & FPHDF5 drivers needed for special checks */
@@ -41,6 +41,11 @@
#include "H5FDmpio.h"
#include "H5FDmpiposix.h"
+/* Private prototypes */
+static herr_t
+H5F_contig_write(H5F_t *f, hsize_t max_data, haddr_t addr,
+ const size_t size, hid_t dxpl_id, const void *buf);
+
/* Interface initialization */
#define PABLO_MASK H5Fcontig_mask
static int interface_initialize_g = 0;
@@ -57,6 +62,48 @@ H5FL_BLK_DEFINE_STATIC(zero_fill);
/*-------------------------------------------------------------------------
+ * Function: H5F_contig_create
+ *
+ * Purpose: Allocate file space for a contiguously stored dataset
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * April 19, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_contig_create(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout)
+{
+ hsize_t size; /* Size of contiguous block of data */
+ unsigned u; /* Local index variable */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_contig_create, FAIL);
+
+ /* check args */
+ assert(f);
+ assert(layout);
+
+ /* Compute size */
+ size=layout->dim[0];
+ for (u = 1; u < layout->ndims; u++)
+ size *= layout->dim[u];
+ assert (size>0);
+
+ /* Allocate space for the contiguous data */
+ if (HADDR_UNDEF==(layout->addr=H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, size)))
+ HGOTO_ERROR (H5E_IO, H5E_NOSPACE, FAIL, "unable to reserve file space");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5F_contig_create */
+
+
+/*-------------------------------------------------------------------------
* Function: H5F_contig_fill
*
* Purpose: Write fill values to a contiguously stored dataset.
@@ -75,8 +122,7 @@ H5FL_BLK_DEFINE_STATIC(zero_fill);
*/
herr_t
H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist, const struct H5O_efl_t *efl,
- const struct H5S_t *space,
+ struct H5P_genplist_t *dc_plist, const struct H5S_t *space,
const struct H5O_fill_t *fill, size_t elmt_size)
{
hssize_t snpoints; /* Number of points in space (for error checking) */
@@ -84,7 +130,7 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
size_t ptsperbuf; /* Maximum # of points which fit in the buffer */
size_t bufsize=64*1024; /* Size of buffer to write */
size_t size; /* Current # of points to write */
- hsize_t addr; /* Offset in dataset */
+ haddr_t addr; /* Offset of dataset */
void *buf = NULL; /* Buffer for fill value writing */
#ifdef H5_HAVE_PARALLEL
MPI_Comm mpi_comm=MPI_COMM_NULL; /* MPI communicator for file */
@@ -173,8 +219,8 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
* this quite efficiently by making sure we copy the fill value
* in relatively large pieces.
*/
- ptsperbuf = MAX(1, bufsize/elmt_size);
- bufsize = ptsperbuf*elmt_size;
+ ptsperbuf = MAX(1, bufsize/elmt_size);
+ bufsize = ptsperbuf*elmt_size;
/* Fill the buffer with the user's fill value */
if(fill->buf) {
@@ -207,7 +253,7 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
} /* end else */
/* Start at the beginning of the dataset */
- addr = 0;
+ addr = layout->addr;
/* Loop through writing the fill value to the dataset */
while (npoints>0) {
@@ -218,8 +264,7 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
if(using_mpi) {
/* Round-robin write the chunks out from only one process */
if(mpi_round==mpi_rank) {
- if (H5F_seq_write(f, dxpl_id, layout, dc_plist, efl, space,
- elmt_size, size, addr, buf)<0)
+ if (H5F_contig_write(f, size, addr, size, dxpl_id, buf)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to write fill value to dataset");
} /* end if */
++mpi_round;
@@ -230,8 +275,8 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
} /* end if */
else {
#endif /* H5_HAVE_PARALLEL */
- if (H5F_seq_write(f, dxpl_id, layout, dc_plist, efl, space,
- elmt_size, size, addr, buf)<0)
+ H5_CHECK_OVERFLOW(size,size_t,hsize_t);
+ if (H5F_contig_write(f, (hsize_t)size, addr, size, dxpl_id, buf)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to write fill value to dataset");
#ifdef H5_HAVE_PARALLEL
} /* end else */
@@ -314,44 +359,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5F_contig_read
- *
- * Purpose: Reads 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_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*/)
-{
- hsize_t offset=0; /* Offset for vector call */
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5F_contig_read, FAIL);
-
- /* Check args */
- assert(f);
- assert(buf);
-
- if (H5F_contig_readv(f, max_data, type, addr, 1, &size, &offset, dxpl_id, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "vector read failed");
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5F_contig_read() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5F_contig_write
*
* Purpose: Writes some data from a dataset into a buffer.
@@ -364,23 +371,28 @@ done:
* Thursday, September 28, 2000
*
* Modifications:
- * Re-written in terms of the new readv call, QAK, 7/7/01
+ * Re-written in terms of the new writevv call, QAK, 5/7/03
*
*-------------------------------------------------------------------------
*/
-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)
+static herr_t
+H5F_contig_write(H5F_t *f, hsize_t max_data, haddr_t addr,
+ const size_t size, hid_t dxpl_id, const void *buf)
{
- hsize_t offset=0; /* Offset for vector call */
- herr_t ret_value=SUCCEED; /* Return value */
+ hsize_t dset_off=0; /* Offset in dataset */
+ hsize_t mem_off=0; /* Offset in memory */
+ size_t dset_len=size; /* Length in dataset */
+ size_t mem_len=size; /* Length in memory */
+ size_t mem_curr_seq=0; /* "Current sequence" in memory */
+ size_t dset_curr_seq=0; /* "Current sequence" in dataset */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5F_contig_write, FAIL);
assert (f);
assert (buf);
- if (H5F_contig_writev(f, max_data, type, addr, 1, &size, &offset, dxpl_id, buf)<0)
+ if (H5F_contig_writevv(f, max_data, addr, 1, &dset_curr_seq, &dset_len, &dset_off, 1, &mem_curr_seq, &mem_len, &mem_off, dxpl_id, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vector write failed");
done:
@@ -389,7 +401,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5F_contig_readv
+ * Function: H5F_contig_readvv
*
* Purpose: Reads some data vectors from a dataset into a buffer.
* The data is contiguous. The address is the start of the dataset,
@@ -409,9 +421,10 @@ done:
*-------------------------------------------------------------------------
*/
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*/)
+H5F_contig_readvv(H5F_t *f, hsize_t _max_data, haddr_t _addr,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ hid_t dxpl_id, void *_buf)
{
unsigned char *buf=(unsigned char *)_buf; /* Pointer to buffer to fill */
haddr_t abs_eoa; /* Absolute end of file address */
@@ -420,18 +433,10 @@ H5F_contig_readv(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
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 */
- int 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 */
- herr_t ret_value=SUCCEED; /* Return value */
+ size_t v; /* Counting variable */
+ ssize_t ret_value=0; /* Return value */
- FUNC_ENTER_NOAPI(H5F_contig_readv, FAIL);
+ FUNC_ENTER_NOAPI(H5F_contig_readvv, FAIL);
/* Check args */
assert(f);
@@ -439,325 +444,143 @@ H5F_contig_readv(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
/* Check if data sieving is enabled */
if(f->shared->lf->feature_flags&H5FD_FEAT_DATA_SIEVE) {
+ 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 */
+
+ /* Set offsets in sequence lists */
+ u=*dset_curr_seq;
+ v=*mem_curr_seq;
+
+ /* No data sieve buffer yet, go allocate one */
+ if(f->shared->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=_addr+dset_offset_arr[u];
+
+ /* Compute offset in memory */
+ buf = (unsigned char *)_buf + mem_offset_arr[v];
+
+ /* Set up the buffer parameters */
+ max_data=_max_data-dset_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, 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==(f->shared->sieve_buf=H5FL_BLK_MALLOC(sieve_buf,f->shared->sieve_buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation 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 */
- unsigned 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)
- HGOTO_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)
- 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(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)
- HGOTO_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)))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size");
+ /* Determine the new sieve buffer size & location */
+ f->shared->sieve_loc=addr;
- /* Adjust absolute EOA address to relative EOA address */
- rel_eoa=abs_eoa-f->shared->base_addr;
+ /* Make certain we don't read off the end of the file */
+ if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size");
- /* Only need this when resizing sieve buffer */
- max_data=_max_data-offset_arr[u];
+ /* Adjust absolute EOA address to relative EOA address */
+ rel_eoa=abs_eoa-f->shared->base_addr;
- /* 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(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
+ /* Compute the size of the sieve buffer */
+ H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
- /* 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, H5FD_MEM_DRAW, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
- /* 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)
- 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,f->shared->sieve_buf,size);
- /* Reset sieve buffer dirty flag */
- f->shared->sieve_dirty=0;
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
+ } /* end else */
- /* Grab the data out of the buffer (must be first piece of data in buffer ) */
- HDmemcpy(buf,f->shared->sieve_buf,size);
- } /* end else */
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
+ u++;
- /* Increment sequence number */
- u++;
- } /* end else */
- } /* end for */
+ /* Increment number of bytes copied */
+ ret_value+=size;
+ } /* 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;
+
+ /* 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];
+
+ /* Compute offset on disk */
+ addr=_addr+dset_offset_arr[u];
+
+ /* 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=f->shared->sieve_buf+(addr-sieve_start);
+
+ /* Grab the data out of the buffer */
+ HDmemcpy(buf,base_sieve_buf,size);
} /* end if */
- /* No data sieve buffer yet, go allocate one */
+ /* Entire request is not within this data sieve buffer */
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)
+ /* 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)
+ HGOTO_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, 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 {
- /* Allocate room for the data sieve buffer */
- if (NULL==(f->shared->sieve_buf=H5FL_BLK_MALLOC(sieve_buf,f->shared->sieve_buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ /* 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)
+ HGOTO_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;
@@ -769,59 +592,103 @@ H5F_contig_readv(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
/* 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-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(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
+ /* 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)
+ if (H5F_block_read(f, H5FD_MEM_DRAW, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
HGOTO_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 ) */
HDmemcpy(buf,f->shared->sieve_buf,size);
+
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
} /* end else */
+ } /* end else */
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
- /* Increment sequence number */
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
u++;
- } /* end else */
+
+ /* Increment number of bytes copied */
+ ret_value+=size;
} /* end for */
} /* end if */
else {
/* Work through all the sequences */
- for(u=0; u<nseq; u++) {
- size=size_arr[u];
- addr=_addr+offset_arr[u];
+ for(u=*dset_curr_seq, v=*mem_curr_seq; 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];
- if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
+ /* Compute offset on disk */
+ addr=_addr+dset_offset_arr[u];
+
+ /* Compute offset in memory */
+ buf = (unsigned char *)_buf + mem_offset_arr[v];
+
+ /* Write data */
+ if (H5F_block_read(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* 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 for */
} /* end else */
+ /* Update current sequence vectors */
+ *dset_curr_seq=u;
+ *mem_curr_seq=v;
+
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5F_contig_readv() */
+} /* end H5F_contig_readvv() */
/*-------------------------------------------------------------------------
- * Function: H5F_contig_writev
+ * Function: H5F_contig_writevv
*
- * Purpose: Writes some data vectors into a dataset from a buffer.
- * The data is contiguous. The address is the start of the dataset,
+ * Purpose: Writes some data vectors into a dataset from vectors into a
+ * buffer. 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, July 5, 2001
+ * Friday, May 2, 2003
*
* Notes:
* Offsets in the sequences must be monotonically increasing
@@ -830,10 +697,11 @@ done:
*
*-------------------------------------------------------------------------
*/
-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_arr[], hsize_t offset_arr[], hid_t dxpl_id,
- const void *_buf)
+ssize_t
+H5F_contig_writevv(H5F_t *f, hsize_t _max_data, haddr_t _addr,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ hid_t dxpl_id, const void *_buf)
{
const unsigned char *buf=_buf; /* Pointer to buffer to fill */
haddr_t abs_eoa; /* Absolute end of file address */
@@ -842,18 +710,10 @@ H5F_contig_writev(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
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 */
- int 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 */
- herr_t ret_value=SUCCEED; /* Return value */
+ size_t v; /* Counting variable */
+ ssize_t ret_value=0; /* Return value */
- FUNC_ENTER_NOAPI(H5F_contig_writev, FAIL);
+ FUNC_ENTER_NOAPI(H5F_contig_writevv, FAIL);
/* Check args */
assert(f);
@@ -861,421 +721,284 @@ H5F_contig_writev(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
/* Check if data sieving is enabled */
if(f->shared->lf->feature_flags&H5FD_FEAT_DATA_SIEVE) {
+ 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 */
+
+ /* Set offsets in sequence lists */
+ u=*dset_curr_seq;
+ v=*mem_curr_seq;
+
+ /* No data sieve buffer yet, go allocate one */
+ if(f->shared->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=_addr+dset_offset_arr[u];
+
+ /* Compute offset in memory */
+ buf = (const unsigned char *)_buf + mem_offset_arr[v];
+
+ /* Set up the buffer parameters */
+ max_data=_max_data-dset_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, 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==(f->shared->sieve_buf=H5FL_BLK_MALLOC(sieve_buf,f->shared->sieve_buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- /* Outer loop, guarantees working through all the sequences */
- for(u=0; u<nseq; ) {
-
- /* 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 */
-
- /* 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--;
-
- } /* end if */
- else {
- size_t lo,hi; /* Low and high bounds for binary search */
- unsigned 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++;
+ /* Determine the new sieve buffer size & location */
+ f->shared->sieve_loc=addr;
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,*size_arr_p);
+ /* Make certain we don't read off the end of the file */
+ if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size");
- /* Increment offset in buffer */
- buf += *size_arr_p++;
+ /* Adjust absolute EOA address to relative EOA address */
+ rel_eoa=abs_eoa-f->shared->base_addr;
- /* Increment the offset in the array */
- u++;
- } /* end while */
-#else /* NO_DUFFS_DEVICE */
-{
- size_t seq_count;
+ /* Compute the size of the sieve buffer */
+ H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
- 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++;
+ /* 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, H5FD_MEM_DRAW, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
+ } /* end if */
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,*size_arr_p);
+ /* Grab the data out of the buffer (must be first piece of data in buffer ) */
+ HDmemcpy(f->shared->sieve_buf,buf,size);
- /* Increment offset in buffer */
- buf += *size_arr_p++;
+ /* Set sieve buffer dirty flag */
+ f->shared->sieve_dirty=1;
+ } /* end else */
- /* Increment the offset in the array */
- u++;
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
- case 3:
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
+ u++;
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,*size_arr_p);
+ /* Increment number of bytes copied */
+ ret_value+=size;
+ } /* end if */
- /* Increment offset in buffer */
- buf += *size_arr_p++;
+ /* Stash local copies of these value */
+ sieve_start=f->shared->sieve_loc;
+ sieve_size=f->shared->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];
- /* Increment the offset in the array */
- u++;
+ /* Compute offset on disk */
+ addr=_addr+dset_offset_arr[u];
- case 2:
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
+ /* Compute offset in memory */
+ buf = (const unsigned char *)_buf + mem_offset_arr[v];
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,*size_arr_p);
+ /* Compute end of sequence to retrieve */
+ contig_end=addr+size-1;
- /* Increment offset in buffer */
- buf += *size_arr_p++;
+ /* 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);
- /* Increment the offset in the array */
- u++;
+ /* Put the data into the sieve buffer */
+ HDmemcpy(base_sieve_buf,buf,size);
- case 1:
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
+ /* Set sieve buffer dirty flag */
+ f->shared->sieve_dirty=1;
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,*size_arr_p);
+ } /* 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)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
- /* Increment offset in buffer */
- buf += *size_arr_p++;
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
+ } /* end if */
- /* Increment the offset in the array */
- u++;
+ /* Force the sieve buffer to be re-read the next time */
+ f->shared->sieve_loc=HADDR_UNDEF;
+ f->shared->sieve_size=0;
+ } /* end if */
- } while (u<=max_seq);
- } /* end switch */
+ /* 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 */
+ 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);
+
+ /* Copy in new information (must be first in sieve buffer) */
+ HDmemcpy(f->shared->sieve_buf,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 */
-}
-#endif /* NO_DUFFS_DEVICE */
-#endif /* SLOW_WAY */
- /* Set sieve buffer dirty flag */
- f->shared->sieve_dirty=1;
+ /* 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;
} /* end if */
- /* Entire request is not within this data sieve buffer */
+ /* Can't add the new data onto the existing 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)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
-
- /* Reset sieve buffer dirty flag */
- f->shared->sieve_dirty=0;
- } /* end if */
-
- /* Force the sieve buffer to be re-read the next time */
- f->shared->sieve_loc=HADDR_UNDEF;
- f->shared->sieve_size=0;
- } /* end if */
-
- /* Write directly from the user's buffer */
- if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0)
+ /* 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)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
} /* 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);
-
- /* Copy in new information (must be first in sieve buffer) */
- HDmemcpy(f->shared->sieve_buf,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;
-
- } /* 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)
- HGOTO_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)))
- HGOTO_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 */
- H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
-
- /* 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)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
- } /* 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];
+ /* Determine the new sieve buffer size & location */
+ f->shared->sieve_loc=addr;
- /* 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];
+ /* Make certain we don't read off the end of the file */
+ if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size");
- /* 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)
- HGOTO_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=H5FL_BLK_MALLOC(sieve_buf,f->shared->sieve_buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ /* Adjust absolute EOA address to relative EOA address */
+ rel_eoa=abs_eoa-f->shared->base_addr;
- /* Determine the new sieve buffer size & location */
- f->shared->sieve_loc=addr;
+ /* Only need this when resizing sieve buffer */
+ max_data=_max_data-dset_offset_arr[u];
- /* Make certain we don't read off the end of the file */
- if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf)))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file 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(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
- /* Adjust absolute EOA address to relative EOA address */
- rel_eoa=abs_eoa-f->shared->base_addr;
+ /* Update local copies of sieve information */
+ sieve_start=f->shared->sieve_loc;
+ sieve_size=f->shared->sieve_size;
+ sieve_end=sieve_start+sieve_size;
- /* Compute the size of the sieve buffer */
- H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
+ /* 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, H5FD_MEM_DRAW, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
+ } /* end if */
- /* 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)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
- } /* end if */
+ /* Grab the data out of the buffer (must be first piece of data in buffer ) */
+ HDmemcpy(f->shared->sieve_buf,buf,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;
- /* Set sieve buffer dirty flag */
- f->shared->sieve_dirty=1;
+ } /* end else */
} /* end else */
+ } /* end else */
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
- /* Increment sequence number */
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
u++;
- } /* end else */
+
+ /* Increment number of bytes copied */
+ ret_value+=size;
} /* end for */
} /* end if */
else {
/* Work through all the sequences */
- for(u=0; u<nseq; u++) {
- size=size_arr[u];
- addr=_addr+offset_arr[u];
+ for(u=*dset_curr_seq, v=*mem_curr_seq; 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];
- if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0)
+ /* Compute offset on disk */
+ addr=_addr+dset_offset_arr[u];
+
+ /* Compute offset in memory */
+ buf = (const unsigned char *)_buf + mem_offset_arr[v];
+
+ /* Write data */
+ if (H5F_block_write(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* 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 for */
} /* end else */
+ /* Update current sequence vectors */
+ *dset_curr_seq=u;
+ *mem_curr_seq=v;
+
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5F_contig_writev() */
+} /* end H5F_contig_writevv() */