summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2004-08-17 07:30:18 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2004-08-17 07:30:18 (GMT)
commit2d3c6215f26b94e6fa0cb46178ea5c60fa075d66 (patch)
tree4fc137e84fd1a4ca4925de9b35f61bc40207767b /src
parent3646a3f83dc32b46c18fe2bfde9a2acdc70680f4 (diff)
downloadhdf5-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')
-rw-r--r--src/H5D.c35
-rw-r--r--src/H5Dcontig.c530
-rw-r--r--src/H5Distore.c15
-rw-r--r--src/H5Dpkg.h6
4 files changed, 278 insertions, 308 deletions
diff --git a/src/H5D.c b/src/H5D.c
index be85340..434faee 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -2811,14 +2811,16 @@ H5D_close(H5D_t *dataset)
H5D_istore_stats(dataset, FALSE);
#endif /* H5F_ISTORE_DEBUG */
+ /* Free the data sieve buffer, if it's been allocated */
+ if(dataset->cache.contig.sieve_buf) {
+ assert(dataset->layout.type!=H5D_COMPACT); /* We should never have a sieve buffer for compact storage */
+ assert(dataset->cache.contig.sieve_dirty==0); /* The buffer had better be flushed... */
+ dataset->cache.contig.sieve_buf = H5FL_BLK_FREE (sieve_buf,dataset->cache.contig.sieve_buf);
+ } /* end if */
+
/* Free cached information for each kind of dataset */
switch(dataset->layout.type) {
case H5D_CONTIGUOUS:
- /* Free the data sieve buffer, if it's been allocated */
- if(dataset->cache.contig.sieve_buf) {
- assert(dataset->cache.contig.sieve_dirty==0); /* The buffer had better be flushed... */
- dataset->cache.contig.sieve_buf = H5FL_BLK_FREE (sieve_buf,dataset->cache.contig.sieve_buf);
- } /* end if */
break;
case H5D_CHUNKED:
@@ -4035,19 +4037,22 @@ H5D_flush(H5F_t *f, hid_t dxpl_id, unsigned flags)
if(NULL==(dataset=H5I_object_verify(id_list[j], H5I_DATASET)))
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to get dataset object")
+ /* Flush the raw data buffer, if we have a dirty one */
+ if (dataset->cache.contig.sieve_buf && dataset->cache.contig.sieve_dirty) {
+ assert(dataset->layout.type!=H5D_COMPACT);
+
+ /* Write dirty data sieve buffer to file */
+ if (H5F_block_write(f, H5FD_MEM_DRAW, dataset->cache.contig.sieve_loc,
+ dataset->cache.contig.sieve_size, dxpl_id, dataset->cache.contig.sieve_buf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed")
+
+ /* Reset sieve buffer dirty flag */
+ dataset->cache.contig.sieve_dirty=0;
+ } /* end if */
+
/* Flush cached information for each kind of dataset */
switch(dataset->layout.type) {
case H5D_CONTIGUOUS:
- /* flush the raw data buffer, if we have a dirty one */
- if (dataset->cache.contig.sieve_buf && dataset->cache.contig.sieve_dirty) {
- /* Write dirty data sieve buffer to file */
- if (H5F_block_write(f, H5FD_MEM_DRAW, dataset->cache.contig.sieve_loc,
- dataset->cache.contig.sieve_size, dxpl_id, dataset->cache.contig.sieve_buf) < 0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed")
-
- /* Reset sieve buffer dirty flag */
- dataset->cache.contig.sieve_dirty=0;
- } /* end if */
break;
case H5D_CHUNKED:
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 */
diff --git a/src/H5Distore.c b/src/H5Distore.c
index 756f5a1..cbd7a0f 100644
--- a/src/H5Distore.c
+++ b/src/H5Distore.c
@@ -935,7 +935,6 @@ H5D_istore_init (H5F_t *f, H5D_t *dset)
FUNC_ENTER_NOAPI(H5D_istore_init, FAIL);
- HDmemset (rdcc, 0, sizeof(H5D_rdcc_t));
if (H5F_RDCC_NBYTES(f)>0 && H5F_RDCC_NELMTS(f)>0) {
rdcc->nbytes=H5F_RDCC_NBYTES(f);
rdcc->nslots = H5F_RDCC_NELMTS(f);
@@ -1609,7 +1608,7 @@ else
}
assert (found || chunk_size>0);
- if (!found && rdcc->nslots>0 && chunk_size<=dset->cache.chunk.nbytes &&
+ if (!found && rdcc->nslots>0 && chunk_size<=rdcc->nbytes &&
(!ent || !ent->locked)) {
/*
* Add the chunk to the cache only if the slot is not already locked.
@@ -1848,13 +1847,13 @@ H5D_istore_readvv(H5F_t *f, const struct H5D_dxpl_cache_t *dxpl_cache, hid_t dxp
/* Get the address of this chunk on disk */
#ifdef QAK
-HDfprintf(stderr,"%s: chunk_coords={",FUNC);
+HDfprintf(stderr,"%s: store->chunk.offset={",FUNC);
for(u=0; u<dset->layout.u.chunk.ndims; u++)
- HDfprintf(stderr,"%Hd%s",chunk_coords[u],(u<(dset->layout.u.chunk.ndims-1) ? ", " : "}\n"));
+ HDfprintf(stderr,"%Hd%s",store->chunk.offset[u],(u<(dset->layout.u.chunk.ndims-1) ? ", " : "}\n"));
#endif /* QAK */
chunk_addr=H5D_istore_get_addr(f, dxpl_id, &(dset->layout), store->chunk.offset, &udata);
#ifdef QAK
-HDfprintf(stderr,"%s: chunk_addr=%a, chunk_size=%Hu\n",FUNC,chunk_addr,dset->layout.u.chunk.size);
+HDfprintf(stderr,"%s: chunk_addr=%a, chunk_size=%Zu\n",FUNC,chunk_addr,dset->layout.u.chunk.size);
HDfprintf(stderr,"%s: chunk_len_arr[%Zu]=%Zu\n",FUNC,*chunk_curr_seq,chunk_len_arr[*chunk_curr_seq]);
HDfprintf(stderr,"%s: chunk_offset_arr[%Zu]=%Hu\n",FUNC,*chunk_curr_seq,chunk_offset_arr[*chunk_curr_seq]);
HDfprintf(stderr,"%s: mem_len_arr[%Zu]=%Zu\n",FUNC,*mem_curr_seq,mem_len_arr[*mem_curr_seq]);
@@ -1963,13 +1962,13 @@ H5D_istore_writevv(H5F_t *f, const struct H5D_dxpl_cache_t *dxpl_cache,
/* Get the address of this chunk on disk */
#ifdef QAK
-HDfprintf(stderr,"%s: chunk_coords={",FUNC);
+HDfprintf(stderr,"%s: store->chunk.offset={",FUNC);
for(u=0; u<dset->layout.u.chunk.ndims; u++)
- HDfprintf(stderr,"%Hd%s",chunk_coords[u],(u<(dset->layout.u.chunk.ndims-1) ? ", " : "}\n"));
+ HDfprintf(stderr,"%Hd%s",store->chunk.offset[u],(u<(dset->layout.u.chunk.ndims-1) ? ", " : "}\n"));
#endif /* QAK */
chunk_addr=H5D_istore_get_addr(f, dxpl_id, &(dset->layout), store->chunk.offset, &udata);
#ifdef QAK
-HDfprintf(stderr,"%s: chunk_addr=%a, chunk_size=%Hu\n",FUNC,chunk_addr,dset->layout.u.chunk.size);
+HDfprintf(stderr,"%s: chunk_addr=%a, chunk_size=%Zu\n",FUNC,chunk_addr,dset->layout.u.chunk.size);
HDfprintf(stderr,"%s: chunk_len_arr[%Zu]=%Zu\n",FUNC,*chunk_curr_seq,chunk_len_arr[*chunk_curr_seq]);
HDfprintf(stderr,"%s: chunk_offset_arr[%Zu]=%Hu\n",FUNC,*chunk_curr_seq,chunk_offset_arr[*chunk_curr_seq]);
HDfprintf(stderr,"%s: mem_len_arr[%Zu]=%Zu\n",FUNC,*mem_curr_seq,mem_len_arr[*mem_curr_seq]);
diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h
index 30183c3..8b88e92 100644
--- a/src/H5Dpkg.h
+++ b/src/H5Dpkg.h
@@ -93,8 +93,12 @@ struct H5D_t {
H5O_fill_t fill; /* Dataset fill value information */
/* Buffered/cached information for types of raw data storage*/
- union {
+ struct {
H5D_rdcdc_t contig; /* Information about contiguous data */
+ /* (Note that the "contig" cache
+ * information can be used by a chunked
+ * dataset in certain circumstances)
+ */
H5D_rdcc_t chunk; /* Information about chunked data */
}cache;
};