Files
hdf5/src/H5Fcontig.c
Quincey Koziol b53bfca418 [svn-r2611] Purpose:
Rearrange code
Description:
    The data sieve buffering code for contiguously stored datasets was
    wedged in the H5F_arr_read/H5F_arr_write routines.
Solution:
    Created a new H5Fcontig.c to hold I/O routines for contiguously stored
    datasets (like H5Fistore.c for chunked dataset I/O routines) and moved
    data sieving code into those routines.
Platforms tested:
    Solaris 2.6 (i.e. baldric)
2000-09-28 14:12:43 -05:00

341 lines
15 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Copyright (C) 2000 NCSA
* All rights reserved.
*
* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
* Thursday, September 28, 2000
*
* 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.
*
*/
#include <H5private.h>
#include <H5Eprivate.h>
#include <H5Fprivate.h>
#include <H5FDprivate.h> /*file driver */
#include <H5MMprivate.h>
/* Interface initialization */
#define PABLO_MASK H5Fcontig_mask
static intn interface_initialize_g = 0;
#define INTERFACE_INIT NULL
/*-------------------------------------------------------------------------
* 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:
*
*-------------------------------------------------------------------------
*/
herr_t
H5F_contig_read(H5F_t *f, haddr_t addr, hsize_t size, hid_t dxpl_id,
void *_buf/*out*/)
{
uint8_t *buf = (uint8_t*)_buf; /*cast for arithmetic */
haddr_t eof; /*end of file address */
FUNC_ENTER(H5F_contig_read, FAIL);
/* Check args */
assert(f);
assert(size<SIZET_MAX);
assert(buf);
/* Check if data sieving is enabled */
if(f->shared->lf->feature_flags&H5FD_FEAT_DATA_SIEVE) {
/* Try reading from the data sieve buffer */
if(f->shared->sieve_buf) {
/* If entire read is within the sieve buffer, read it from the buffer */
if((addr>=f->shared->sieve_loc && addr<(f->shared->sieve_loc+f->shared->sieve_size))
&& ((addr+size-1)>=f->shared->sieve_loc && (addr+size-1)<(f->shared->sieve_loc+f->shared->sieve_size))) {
/* Grab the data out of the buffer */
HDmemcpy(buf,f->shared->sieve_buf+(addr-f->shared->sieve_loc),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>f->shared->sieve_buf_size) {
/* Check for any overlap with the current sieve buffer */
if((f->shared->sieve_loc>=addr && f->shared->sieve_loc<(addr+size))
|| ((f->shared->sieve_loc+f->shared->sieve_size-1)>=addr && (f->shared->sieve_loc+f->shared->sieve_size-1)<(addr+size))) {
/* Flush the sieve buffer, if it's dirty */
if(f->shared->sieve_dirty) {
/* Write to file */
if (H5F_block_write(f, H5FD_MEM_DRAW, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) {
HRETURN_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, addr, size, dxpl_id, buf)<0) {
HRETURN_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, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) {
HRETURN_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==(eof=H5FD_get_eof(f->shared->lf))) {
HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL,
"unable to determine file size");
}
f->shared->sieve_size=MIN(eof-addr,f->shared->sieve_buf_size);
/* Read the new sieve buffer */
if (H5F_block_read(f, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) {
HRETURN_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);
} /* end else */
} /* end else */
} /* end if */
/* No data sieve buffer yet, go allocate one */
else {
/* 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, addr, size, dxpl_id, buf)<0) {
HRETURN_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=H5MM_malloc(f->shared->sieve_buf_size))) {
HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
/* 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==(eof=H5FD_get_eof(f->shared->lf))) {
HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL,
"unable to determine file size");
}
f->shared->sieve_size=MIN(eof-addr,f->shared->sieve_buf_size);
/* Read the new sieve buffer */
if (H5F_block_read(f, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) {
HRETURN_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);
} /* end else */
} /* end else */
} /* end if */
else {
if (H5F_block_read(f, addr, size, dxpl_id, buf)<0) {
HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL,
"block read failed");
}
} /* end else */
FUNC_LEAVE(SUCCEED);
} /* End H5F_contig_read() */
/*-------------------------------------------------------------------------
* Function: H5F_contig_write
*
* Purpose: Writes 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:
*
*-------------------------------------------------------------------------
*/
herr_t
H5F_contig_write(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size,
hid_t dxpl_id, const void *buf)
{
haddr_t eof; /*end of file address */
FUNC_ENTER(H5F_block_write, FAIL);
assert (f);
assert (size<SIZET_MAX);
assert (buf);
/* Check if data sieving is enabled */
if(f->shared->lf->feature_flags&H5FD_FEAT_DATA_SIEVE) {
/* Try writing to the data sieve buffer */
if(f->shared->sieve_buf) {
/* If entire write is within the sieve buffer, write it to the buffer */
if((addr>=f->shared->sieve_loc && addr<(f->shared->sieve_loc+f->shared->sieve_size))
&& ((addr+size-1)>=f->shared->sieve_loc && (addr+size-1)<(f->shared->sieve_loc+f->shared->sieve_size))) {
/* Grab the data out of the buffer */
HDmemcpy(f->shared->sieve_buf+(addr-f->shared->sieve_loc),buf,size);
/* Set sieve buffer dirty flag */
f->shared->sieve_dirty=1;
} /* 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((f->shared->sieve_loc>=addr && f->shared->sieve_loc<(addr+size))
|| ((f->shared->sieve_loc+f->shared->sieve_size-1)>=addr && (f->shared->sieve_loc+f->shared->sieve_size-1)<(addr+size))) {
/* Flush the sieve buffer, if it's dirty */
if(f->shared->sieve_dirty) {
/* Write to file */
if (H5F_block_write(f, H5FD_MEM_DRAW, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) {
HRETURN_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, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0) {
HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,
"block write 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, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) {
HRETURN_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==(eof=H5FD_get_eof(f->shared->lf))) {
HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL,
"unable to determine file size");
}
f->shared->sieve_size=MIN(eof-addr,f->shared->sieve_buf_size);
/* Read the new sieve buffer */
if (H5F_block_read(f, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) {
HRETURN_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(f->shared->sieve_buf,buf,size);
/* Set sieve buffer dirty flag */
f->shared->sieve_dirty=1;
} /* end else */
} /* end else */
} /* end if */
/* No data sieve buffer yet, go allocate one */
else {
/* 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) {
HRETURN_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=H5MM_malloc(f->shared->sieve_buf_size))) {
HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
/* 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==(eof=H5FD_get_eof(f->shared->lf))) {
HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL,
"unable to determine file size");
}
f->shared->sieve_size=MIN(eof-addr,f->shared->sieve_buf_size);
/* Read the new sieve buffer */
if (H5F_block_read(f, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0) {
HRETURN_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(f->shared->sieve_buf,buf,size);
/* Set sieve buffer dirty flag */
f->shared->sieve_dirty=1;
} /* end else */
} /* end else */
} /* end if */
else {
if (H5F_block_write(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0) {
HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,
"block write failed");
}
} /* end else */
FUNC_LEAVE(SUCCEED);
} /* End H5F_contig_write() */