summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5D.c97
-rw-r--r--src/H5F.c2
-rw-r--r--src/H5Fcore.c19
-rw-r--r--src/H5Ffamily.c15
-rw-r--r--src/H5Flow.c66
-rw-r--r--src/H5Fmpio.c29
-rw-r--r--src/H5Fprivate.h21
-rw-r--r--src/H5Fsec2.c5
-rw-r--r--src/H5Fsplit.c90
-rw-r--r--src/H5Fstdio.c5
-rw-r--r--src/H5MF.c155
-rw-r--r--src/H5P.c98
-rw-r--r--src/H5Ppublic.h3
-rw-r--r--src/H5S.c7
-rw-r--r--src/H5Sprivate.h2
15 files changed, 508 insertions, 106 deletions
diff --git a/src/H5D.c b/src/H5D.c
index 92fbccd..10231fc 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -43,7 +43,6 @@ static char RcsId[] = "@(#)$Revision$";
struct H5D_t {
H5G_entry_t ent; /*cached object header stuff */
H5T_t *type; /*datatype of this dataset */
- H5S_t *space; /*dataspace of this dataset */
H5D_create_t *create_parms; /*creation parameters */
H5O_layout_t layout; /*data layout */
};
@@ -343,14 +342,16 @@ H5Dclose(hid_t dataset_id)
* Wednesday, January 28, 1998
*
* Modifications:
- *
+ * Robb Matzke, 9 Jun 1998
+ * The data space is not constant and is no longer cached by the dataset
+ * struct.
*-------------------------------------------------------------------------
*/
hid_t
H5Dget_space (hid_t dataset_id)
{
H5D_t *dataset = NULL;
- H5S_t *copied_space = NULL;
+ H5S_t *space = NULL;
hid_t ret_value = FAIL;
FUNC_ENTER (H5Dget_space, FAIL);
@@ -361,14 +362,15 @@ H5Dget_space (hid_t dataset_id)
HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
}
- /* Copy the data space */
- if (NULL==(copied_space=H5S_copy (dataset->space))) {
+ /* Read the data space message and return a data space object */
+ if (NULL==(space=H5S_read (&(dataset->ent)))) {
HRETURN_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to copy the data space");
+ "unable to load space info from dataset header");
}
/* Create an atom */
- if ((ret_value=H5I_register (H5_DATASPACE, copied_space))<0) {
+ if ((ret_value=H5I_register (H5_DATASPACE, space))<0) {
+ H5S_close (space);
HRETURN_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL,
"unable to register data space");
}
@@ -738,6 +740,8 @@ H5Dextend (hid_t dataset_id, const hsize_t *size)
* Thursday, December 4, 1997
*
* Modifications:
+ * Robb Matzke, 9 Jun 1998
+ * The data space message is no longer cached in the dataset struct.
*
*-------------------------------------------------------------------------
*/
@@ -771,7 +775,6 @@ H5D_create(H5G_t *loc, const char *name, const H5T_t *type, const H5S_t *space,
new_dset = H5MM_xcalloc(1, sizeof(H5D_t));
H5F_addr_undef(&(new_dset->ent.header));
new_dset->type = H5T_copy(type, H5T_COPY_ALL);
- new_dset->space = H5S_copy(space);
new_dset->create_parms = H5P_copy (H5P_DATASET_CREATE, create_parms);
efl = &(new_dset->create_parms->efl);
@@ -852,7 +855,7 @@ H5D_create(H5G_t *loc, const char *name, const H5T_t *type, const H5S_t *space,
/* Update the type and space header messages */
if (H5O_modify(&(new_dset->ent), H5O_DTYPE, 0,
H5O_FLAG_CONSTANT|H5O_FLAG_SHARED, new_dset->type)<0 ||
- H5S_modify(&(new_dset->ent), new_dset->space) < 0) {
+ H5S_modify(&(new_dset->ent), space) < 0) {
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL,
"unable to update type or space header messages");
}
@@ -915,7 +918,6 @@ H5D_create(H5G_t *loc, const char *name, const H5T_t *type, const H5S_t *space,
done:
if (!ret_value && new_dset) {
if (new_dset->type) H5T_close(new_dset->type);
- if (new_dset->space) H5S_close(new_dset->space);
if (new_dset->create_parms) {
H5P_close (H5P_DATASET_CREATE, new_dset->create_parms);
new_dset->create_parms = NULL;
@@ -945,6 +947,8 @@ H5D_create(H5G_t *loc, const char *name, const H5T_t *type, const H5S_t *space,
* Thursday, December 4, 1997
*
* Modifications:
+ * Robb Matzke, 9 Jun 1998
+ * The data space message is no longer cached in the dataset struct.
*
*-------------------------------------------------------------------------
*/
@@ -976,10 +980,9 @@ H5D_open(H5G_t *loc, const char *name)
}
/* Get the type and space */
- if (NULL==(dataset->type=H5O_read(&(dataset->ent), H5O_DTYPE, 0, NULL)) ||
- NULL==(dataset->space=H5S_read(f, &(dataset->ent)))) {
+ if (NULL==(dataset->type=H5O_read(&(dataset->ent), H5O_DTYPE, 0, NULL))) {
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL,
- "unable to load type or space info from dataset header");
+ "unable to load type info from dataset header");
}
/* Get the optional compression message */
@@ -1041,9 +1044,6 @@ H5D_open(H5G_t *loc, const char *name)
if (dataset->type) {
H5T_close(dataset->type);
}
- if (dataset->space) {
- H5S_close(dataset->space);
- }
if (dataset->create_parms) {
H5P_close (H5P_DATASET_CREATE, dataset->create_parms);
}
@@ -1072,6 +1072,8 @@ H5D_open(H5G_t *loc, const char *name)
* Thursday, December 4, 1997
*
* Modifications:
+ * Robb Matzke, 9 Jun 1998
+ * The data space message is no longer cached in the dataset struct.
*
*-------------------------------------------------------------------------
*/
@@ -1086,11 +1088,10 @@ H5D_close(H5D_t *dataset)
assert(dataset && dataset->ent.file);
/*
- * Release dataset type and space - there isn't much we can do if one of
- * these fails, so we just continue.
+ * Release data type and creation property list -- there isn't much we
+ * can do if one of these fails, so we just continue.
*/
free_failed = (H5T_close(dataset->type) < 0 ||
- H5S_close(dataset->space) < 0 ||
H5P_close (H5P_DATASET_CREATE, dataset->create_parms));
/* Close the dataset object */
@@ -1107,8 +1108,8 @@ H5D_close(H5D_t *dataset)
if (free_failed) {
HRETURN_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "couldn't free the type or space, but the dataset was "
- "freed anyway.");
+ "couldn't free the type or creation property list, "
+ "but the dataset was freed anyway.");
}
FUNC_LEAVE(SUCCEED);
}
@@ -1127,6 +1128,8 @@ H5D_close(H5D_t *dataset)
* Thursday, December 4, 1997
*
* Modifications:
+ * Robb Matzke, 9 Jun 1998
+ * The data space is no longer cached in the dataset struct.
*
*-------------------------------------------------------------------------
*/
@@ -1152,6 +1155,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
size_t target_size; /*desired buffer size */
size_t request_nelmts; /*requested strip mine */
H5T_bkg_t need_bkg; /*type of background buf*/
+ H5S_t *free_this_space=NULL; /*data space to free */
#ifdef H5T_DEBUG
H5_timer_t timer;
#endif
@@ -1163,7 +1167,13 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
assert(mem_type);
assert(xfer_parms);
assert(buf);
- if (!file_space) file_space = dataset->space;
+ if (!file_space) {
+ if (NULL==(free_this_space=H5S_read (&(dataset->ent)))) {
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to read data space from dataset header");
+ }
+ file_space = free_this_space;
+ }
if (!mem_space) mem_space = file_space;
nelmts = H5S_get_npoints(mem_space);
@@ -1387,6 +1397,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
if (bkg_buf && NULL==xfer_parms->bkg_buf) {
H5MM_xfree (bkg_buf);
}
+ if (free_this_space) H5S_close (free_this_space);
FUNC_LEAVE(ret_value);
}
@@ -1405,6 +1416,8 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
* Thursday, December 4, 1997
*
* Modifications:
+ * Robb Matzke, 9 Jun 1998
+ * The data space is no longer cached in the dataset struct.
*
*-------------------------------------------------------------------------
*/
@@ -1429,6 +1442,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
size_t target_size; /*desired buffer size */
size_t request_nelmts; /*requested strip mine */
H5T_bkg_t need_bkg; /*type of background buf*/
+ H5S_t *free_this_space=NULL; /*data space to free */
#ifdef H5T_DEBUG
H5_timer_t timer;
#endif
@@ -1440,7 +1454,13 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
assert(mem_type);
assert(xfer_parms);
assert(buf);
- if (!file_space) file_space = dataset->space;
+ if (!file_space) {
+ if (NULL==(free_this_space=H5S_read (&(dataset->ent)))) {
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to read data space from dataset header");
+ }
+ file_space = free_this_space;
+ }
if (!mem_space) mem_space = file_space;
nelmts = H5S_get_npoints(mem_space);
@@ -1666,6 +1686,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
if (bkg_buf && NULL==xfer_parms->bkg_buf) {
H5MM_xfree (bkg_buf);
}
+ if (free_this_space) H5S_close (free_this_space);
FUNC_LEAVE(ret_value);
}
@@ -1689,7 +1710,8 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
herr_t
H5D_extend (H5D_t *dataset, const hsize_t *size)
{
- herr_t changed;
+ herr_t changed, ret_value=FAIL;
+ H5S_t *space = NULL;
FUNC_ENTER (H5D_extend, FAIL);
@@ -1698,26 +1720,33 @@ H5D_extend (H5D_t *dataset, const hsize_t *size)
assert (size);
/*
- * Restrictions on extensions were checked when the dataset was created.
- * All extensions are allowed here since none should be able to muck
- * things up.
+ * NOTE: Restrictions on extensions were checked when the dataset was
+ * created. All extensions are allowed here since none should be
+ * able to muck things up.
*/
- /*void*/
+
/* Increase the size of the data space */
- if ((changed=H5S_extend (dataset->space, size))<0) {
- HRETURN_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to increase size of data space");
+ if (NULL==(space=H5S_read (&(dataset->ent)))) {
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to read data space info from dataset header");
+ }
+ if ((changed=H5S_extend (space, size))<0) {
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to increase size of data space");
}
/* Save the new dataspace in the file if necessary */
if (changed>0 &&
- H5S_modify (&(dataset->ent), dataset->space)<0) {
- HRETURN_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL,
+ H5S_modify (&(dataset->ent), space)<0) {
+ HGOTO_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL,
"unable to update file with new dataspace");
}
+ ret_value = SUCCEED;
- FUNC_LEAVE (SUCCEED);
+ done:
+ H5S_close (space);
+ FUNC_LEAVE (ret_value);
}
diff --git a/src/H5F.c b/src/H5F.c
index c782e53..ad26fc9 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -145,6 +145,8 @@ H5F_init_interface(void)
H5F_access_dflt.mdc_nelmts = H5AC_NSLOTS;
H5F_access_dflt.rdcc_nbytes = 1024*1024; /*1MB*/
H5F_access_dflt.rdcc_w0 = 0.75; /*preempt fully read chunks*/
+ H5F_access_dflt.threshold = 1; /*alignment applies to everything*/
+ H5F_access_dflt.alignment = 1; /*no alignment*/
H5F_access_dflt.driver = H5F_LOW_DFLT;
#if (H5F_LOW_DFLT == H5F_LOW_SEC2)
/* Nothing to initialize */
diff --git a/src/H5Fcore.c b/src/H5Fcore.c
index 99f64fb..c0bfbf7 100644
--- a/src/H5Fcore.c
+++ b/src/H5Fcore.c
@@ -41,13 +41,14 @@ static herr_t H5F_core_write(H5F_low_t *lf, const H5F_access_t *access_parms,
const uint8 *buf);
const H5F_low_class_t H5F_LOW_CORE_g[1] = {{
- H5F_core_access, /* access method */
- H5F_core_open, /* open method */
- H5F_core_close, /* close method */
- H5F_core_read, /* read method */
- H5F_core_write, /* write method */
- NULL, /* flush method */
- NULL, /* extend method */
+ H5F_core_access, /*access method */
+ H5F_core_open, /*open method */
+ H5F_core_close, /*close method */
+ H5F_core_read, /*read method */
+ H5F_core_write, /*write method */
+ NULL, /*flush method */
+ NULL, /*extend method */
+ NULL, /*alloc method */
}};
@@ -186,7 +187,7 @@ H5F_core_close(H5F_low_t *lf, const H5F_access_t __unused__ *access_parms)
*/
static herr_t
H5F_core_read(H5F_low_t *lf, const H5F_access_t __unused__ *access_parms,
- const H5D_transfer_t xfer_mode,
+ const H5D_transfer_t __unused__ xfer_mode,
const haddr_t *addr, size_t size, uint8 *buf)
{
size_t n;
@@ -236,7 +237,7 @@ H5F_core_read(H5F_low_t *lf, const H5F_access_t __unused__ *access_parms,
*/
static herr_t
H5F_core_write(H5F_low_t *lf, const H5F_access_t *access_parms,
- const H5D_transfer_t xfer_mode,
+ const H5D_transfer_t __unused__ xfer_mode,
const haddr_t *addr, size_t size, const uint8 *buf)
{
size_t need_more;
diff --git a/src/H5Ffamily.c b/src/H5Ffamily.c
index e887acc..01b5682 100644
--- a/src/H5Ffamily.c
+++ b/src/H5Ffamily.c
@@ -52,13 +52,14 @@ static herr_t H5F_fam_write(H5F_low_t *lf, const H5F_access_t *access_parms,
static herr_t H5F_fam_flush(H5F_low_t *lf, const H5F_access_t *access_parms);
const H5F_low_class_t H5F_LOW_FAMILY_g[1] = {{
- H5F_fam_access, /* access method */
- H5F_fam_open, /* open method */
- H5F_fam_close, /* close method */
- H5F_fam_read, /* read method */
- H5F_fam_write, /* write method */
- H5F_fam_flush, /* flush method */
- NULL, /* extend method */
+ H5F_fam_access, /*access method */
+ H5F_fam_open, /*open method */
+ H5F_fam_close, /*close method */
+ H5F_fam_read, /*read method */
+ H5F_fam_write, /*write method */
+ H5F_fam_flush, /*flush method */
+ NULL, /*extend method */
+ NULL, /*alloc method */
}};
diff --git a/src/H5Flow.c b/src/H5Flow.c
index 82e1f1a..91fb495 100644
--- a/src/H5Flow.c
+++ b/src/H5Flow.c
@@ -515,6 +515,72 @@ H5F_low_extend(H5F_low_t *lf, const H5F_access_t *access_parms, intn op,
FUNC_LEAVE(SUCCEED);
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_low_alloc
+ *
+ * Purpose: Determines if a free block BLK can satisfy a request for SIZE
+ * bytes of memory from file F. If SIZE >= THRESH then the
+ * memory must be aligned on an ALIGN-byte boundary. Alignment
+ * is wrt the relative file addresses (that is, the size of the
+ * user-defined block at the beginning of the file is subtracted
+ * from the addresses before aligning them).
+ *
+ * Return: Success: Positive if the free block exactly satisfies
+ * the request; zero if the free block
+ * over-satisfies the request. In either case,
+ * ADDR will be the address within the free
+ * block where the request can be satisfied.
+ *
+ * Failure: FAIL with the output value of ADDR
+ * undefined.
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, June 9, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+intn
+H5F_low_alloc (H5F_low_t *lf, intn op, hsize_t alignment, hsize_t threshold,
+ size_t size, H5MF_free_t *blk, haddr_t *addr/*out*/)
+{
+ intn ret_value = FAIL;
+ hsize_t wasted;
+
+ FUNC_ENTER (H5MF_acceptable, FAIL);
+ assert (lf);
+ assert (alignment>0);
+ assert (size>0);
+ assert (blk);
+ assert (addr);
+
+ if (lf->type->alloc) {
+ ret_value = (lf->type->alloc)(lf, op, alignment, threshold, size, blk,
+ addr/*out*/);
+ } else {
+ if (size>=threshold) {
+ wasted = blk->addr.offset % alignment;
+ } else {
+ wasted = 0;
+ }
+ if (0==wasted && size==blk->size) {
+ /* exact match */
+ *addr = blk->addr;
+ ret_value = 1;
+ } else if (blk->size>wasted && blk->size-wasted>=size) {
+ /* over-satisfied */
+ *addr = blk->addr;
+ H5F_addr_inc (addr, wasted);
+ ret_value = 0;
+ }
+ }
+
+ FUNC_LEAVE (ret_value);
+}
+
/*-------------------------------------------------------------------------
* Function: H5F_low_seteof
diff --git a/src/H5Fmpio.c b/src/H5Fmpio.c
index 74a75f4..ceca1b3 100644
--- a/src/H5Fmpio.c
+++ b/src/H5Fmpio.c
@@ -89,14 +89,15 @@ static herr_t H5F_mpio_flush(H5F_low_t *lf, const H5F_access_t *access_parms);
static herr_t H5F_MPIOff_to_haddr(MPI_Offset mpi_off, haddr_t *addr);
static herr_t H5F_haddr_to_MPIOff(haddr_t addr, MPI_Offset *mpi_off);
-const H5F_low_class_t H5F_LOW_MPIO_g[1] = {{
- H5F_mpio_access, /* access method */
- H5F_mpio_open, /* open method */
- H5F_mpio_close, /* close method */
- H5F_mpio_read, /* read method */
- H5F_mpio_write, /* write method */
- H5F_mpio_flush, /* flush method */
- NULL /* extend method */
+const H5F_low_class_t H5F_LOW_MPIO_g[1] = {{
+ H5F_mpio_access, /*access method */
+ H5F_mpio_open, /*open method */
+ H5F_mpio_close, /*close method */
+ H5F_mpio_read, /*read method */
+ H5F_mpio_write, /*write method */
+ H5F_mpio_flush, /*flush method */
+ NULL, /*extend method */
+ NULL, /*alloc method */
}};
ino_t mpio_inode_num = 0; /* fake "inode" number */
@@ -347,7 +348,7 @@ H5F_mpio_open(const char *name, const H5F_access_t *access_parms, uintn flags,
*-------------------------------------------------------------------------
*/
static herr_t
-H5F_mpio_close(H5F_low_t *lf, const H5F_access_t *access_parms)
+H5F_mpio_close(H5F_low_t *lf, const H5F_access_t __unused__ *access_parms)
{
int mpierr;
char mpierrmsg[MPI_MAX_ERROR_STRING];
@@ -404,7 +405,7 @@ H5F_mpio_close(H5F_low_t *lf, const H5F_access_t *access_parms)
*-------------------------------------------------------------------------
*/
static herr_t
-H5F_mpio_read(H5F_low_t *lf, const H5F_access_t *access_parms,
+H5F_mpio_read(H5F_low_t *lf, const H5F_access_t __unused__ *access_parms,
const H5D_transfer_t xfer_mode,
const haddr_t *addr, size_t size, uint8 *buf/*out*/)
{
@@ -448,7 +449,7 @@ H5F_mpio_read(H5F_low_t *lf, const H5F_access_t *access_parms,
break;
default:
- HRETURN_ERROR(H5E_IO, H5E_BADVALUE, NULL, "invalid file access mode");
+ HRETURN_ERROR(H5E_IO, H5E_BADVALUE, FAIL, "invalid file access mode");
}
if (mpierr != MPI_SUCCESS) {
MPI_Error_string( mpierr, mpierrmsg, &msglen );
@@ -528,7 +529,7 @@ H5F_mpio_read(H5F_low_t *lf, const H5F_access_t *access_parms,
*-------------------------------------------------------------------------
*/
static herr_t
-H5F_mpio_write(H5F_low_t *lf, const H5F_access_t *access_parms,
+H5F_mpio_write(H5F_low_t *lf, const H5F_access_t __unused__ *access_parms,
const H5D_transfer_t xfer_mode,
const haddr_t *addr, size_t size, const uint8 *buf)
{
@@ -570,7 +571,7 @@ H5F_mpio_write(H5F_low_t *lf, const H5F_access_t *access_parms,
break;
default:
- HRETURN_ERROR(H5E_IO, H5E_BADVALUE, NULL, "invalid file access mode");
+ HRETURN_ERROR(H5E_IO, H5E_BADVALUE, FAIL, "invalid file access mode");
}
if (mpierr != MPI_SUCCESS) {
MPI_Error_string( mpierr, mpierrmsg, &msglen );
@@ -606,7 +607,7 @@ H5F_mpio_write(H5F_low_t *lf, const H5F_access_t *access_parms,
*-------------------------------------------------------------------------
*/
static herr_t
-H5F_mpio_flush(H5F_low_t *lf, const H5F_access_t *access_parms)
+H5F_mpio_flush(H5F_low_t *lf, const H5F_access_t __unused__ *access_parms)
{
int mpierr;
char mpierrmsg[MPI_MAX_ERROR_STRING];
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 5b0ec5b..dcf5e69 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -242,6 +242,8 @@ typedef struct H5F_access_t {
intn mdc_nelmts; /* Size of meta data cache (nelmts) */
size_t rdcc_nbytes; /* Size of raw data chunk cache (bytes) */
double rdcc_w0; /* Preempt read chunks first? [0.0..1.0]*/
+ hsize_t threshold; /* Threshold for alignment */
+ hsize_t alignment; /* Alignment */
H5F_driver_t driver; /* Low level file driver */
union {
@@ -291,6 +293,13 @@ typedef enum {
H5F_OP_READ /* Last operation was a read */
} H5F_fileop_t;
+/* A free-list entry */
+#define H5MF_NFREE 32 /*size of free block array */
+typedef struct H5MF_free_t {
+ haddr_t addr; /*file address */
+ hsize_t size; /*size of free area */
+} H5MF_free_t;
+
/*
* Define the low-level file interface.
*/
@@ -312,7 +321,10 @@ typedef struct H5F_low_class_t {
const H5F_access_t *access_parms);
herr_t (*extend)(struct H5F_low_t *lf,
const H5F_access_t *access_parms,
- intn op, hsize_t size, haddr_t *addr);
+ intn op, hsize_t size, haddr_t *addr/*out*/);
+ intn (*alloc)(struct H5F_low_t *lf, intn op, hsize_t alignment,
+ hsize_t threshold, size_t size, H5MF_free_t *blk,
+ haddr_t *addr/*out*/);
} H5F_low_class_t;
typedef struct H5F_low_t {
@@ -423,6 +435,8 @@ typedef struct H5F_file_t {
intn ncwfs; /* Num entries on cwfs list */
struct H5HG_heap_t **cwfs; /* Global heap cache */
H5F_rdcc_t rdcc; /* Raw data chunk cache */
+ intn fl_nfree; /*number of free blocks in array */
+ H5MF_free_t fl_free[H5MF_NFREE]; /*free block array */
} H5F_file_t;
/*
@@ -536,8 +550,11 @@ herr_t H5F_block_write(H5F_t *f, const haddr_t *addr, hsize_t size,
/* Functions that operate directly on low-level files */
const H5F_low_class_t *H5F_low_class (H5F_driver_t driver);
herr_t H5F_low_extend(H5F_low_t *lf, const H5F_access_t *access_parms,
- intn op, hsize_t size, haddr_t *addr);
+ intn op, hsize_t size, haddr_t *addr/*out*/);
herr_t H5F_low_seteof(H5F_low_t *lf, const haddr_t *addr);
+intn H5F_low_alloc (H5F_low_t *lf, intn op, hsize_t alignment,
+ hsize_t threshold, size_t size, H5MF_free_t *blk,
+ haddr_t *addr/*out*/);
hbool_t H5F_low_access(const H5F_low_class_t *type, const char *name,
const H5F_access_t *access_parms, int mode,
H5F_search_t *key);
diff --git a/src/H5Fsec2.c b/src/H5Fsec2.c
index b0be347..d61d3a0 100644
--- a/src/H5Fsec2.c
+++ b/src/H5Fsec2.c
@@ -47,6 +47,7 @@ const H5F_low_class_t H5F_LOW_SEC2_g[1] = {{
H5F_sec2_write, /* write method */
NULL, /* flush method */
NULL, /* extend method */
+ NULL, /* alloc method */
}};
@@ -161,7 +162,7 @@ H5F_sec2_close(H5F_low_t *lf, const H5F_access_t __unused__ *access_parms)
*/
static herr_t
H5F_sec2_read(H5F_low_t *lf, const H5F_access_t __unused__ *access_parms,
- const H5D_transfer_t xfer_mode,
+ const H5D_transfer_t __unused__ xfer_mode,
const haddr_t *addr, size_t size, uint8 *buf)
{
ssize_t n;
@@ -268,7 +269,7 @@ H5F_sec2_read(H5F_low_t *lf, const H5F_access_t __unused__ *access_parms,
*/
static herr_t
H5F_sec2_write(H5F_low_t *lf, const H5F_access_t __unused__ *access_parms,
- const H5D_transfer_t xfer_mode,
+ const H5D_transfer_t __unused__ xfer_mode,
const haddr_t *addr, size_t size, const uint8 *buf)
{
uint64 mask;
diff --git a/src/H5Fsplit.c b/src/H5Fsplit.c
index bc57db3..b875023 100644
--- a/src/H5Fsplit.c
+++ b/src/H5Fsplit.c
@@ -43,15 +43,19 @@ static herr_t H5F_split_write(H5F_low_t *lf, const H5F_access_t *access_parms,
static herr_t H5F_split_flush(H5F_low_t *lf, const H5F_access_t *access_parms);
static herr_t H5F_split_extend(H5F_low_t *lf, const H5F_access_t *access_parms,
intn op, hsize_t size, haddr_t *addr/*out*/);
-
-const H5F_low_class_t H5F_LOW_SPLIT_g[1] = {{
- H5F_split_access, /* access method */
- H5F_split_open, /* open method */
- H5F_split_close, /* close method */
- H5F_split_read, /* read method */
- H5F_split_write, /* write method */
- H5F_split_flush, /* flush method */
- H5F_split_extend, /* extend method */
+static intn H5F_split_alloc (H5F_low_t *lf, intn op, hsize_t alignment,
+ hsize_t threshold, size_t size, H5MF_free_t *blk,
+ haddr_t *addr/*out*/);
+
+const H5F_low_class_t H5F_LOW_SPLIT_g[1] = {{
+ H5F_split_access, /*access method */
+ H5F_split_open, /*open method */
+ H5F_split_close, /*close method */
+ H5F_split_read, /*read method */
+ H5F_split_write, /*write method */
+ H5F_split_flush, /*flush method */
+ H5F_split_extend, /*extend method */
+ H5F_split_alloc, /*alloc method */
}};
/*
@@ -451,3 +455,71 @@ H5F_split_extend(H5F_low_t *lf, const H5F_access_t *access_parms, intn op,
FUNC_LEAVE(SUCCEED);
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_split_alloc
+ *
+ * Purpose: Determines if free block BLK in file LF can be used to
+ * satisfy the request for SIZE bytes. This function is
+ * actually the same as H5F_low_alloc() except it returns
+ * failure if the OP is not compatible with the block address,
+ * insuring that meta data is allocated from one half of the
+ * address space and raw data from the other half.
+ *
+ * Return: Success: Positive if the free block satisfies the
+ * request exactly, zero if the free block
+ * over-satisfies the request. The ADDR will
+ * contain the address within the free block
+ * where the request starts.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, June 9, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static intn
+H5F_split_alloc (H5F_low_t *lf, intn op, hsize_t alignment, hsize_t threshold,
+ size_t size, H5MF_free_t *blk, haddr_t *addr/*out*/)
+{
+ intn ret_value = FAIL;
+ hsize_t wasted;
+
+ FUNC_ENTER (H5F_split_alloc, FAIL);
+ assert (lf);
+ assert (alignment>0);
+ assert (size>0);
+ assert (blk);
+ assert (addr);
+
+ switch (op) {
+ case H5MF_META:
+ if (blk->addr.offset & lf->u.split.mask) return FAIL;
+ break;
+ case H5MF_RAW:
+ if (0==(blk->addr.offset & lf->u.split.mask)) return FAIL;
+ break;
+ }
+
+ if (size>=threshold) {
+ wasted = blk->addr.offset % alignment;
+ } else {
+ wasted = 0;
+ }
+ if (0==wasted && size==blk->size) {
+ /* exact match */
+ *addr = blk->addr;
+ ret_value = 1;
+ } else if (blk->size>wasted && blk->size-wasted>=size) {
+ /* over-satisfied */
+ *addr = blk->addr;
+ H5F_addr_inc (addr, wasted);
+ ret_value = 0;
+ }
+
+ FUNC_LEAVE (ret_value);
+}
diff --git a/src/H5Fstdio.c b/src/H5Fstdio.c
index 3ba7653..a472d30 100644
--- a/src/H5Fstdio.c
+++ b/src/H5Fstdio.c
@@ -42,6 +42,7 @@ const H5F_low_class_t H5F_LOW_STDIO_g[1] = {{
H5F_stdio_write, /* write method */
H5F_stdio_flush, /* flush method */
NULL, /* extend method */
+ NULL, /* alloc method */
}};
@@ -186,7 +187,7 @@ H5F_stdio_close(H5F_low_t *lf, const H5F_access_t __unused__ *access_parms)
*/
static herr_t
H5F_stdio_read(H5F_low_t *lf, const H5F_access_t __unused__ *access_parms,
- const H5D_transfer_t xfer_mode,
+ const H5D_transfer_t __unused__ xfer_mode,
const haddr_t *addr, size_t size, uint8 *buf/*out*/)
{
size_t n;
@@ -297,7 +298,7 @@ H5F_stdio_read(H5F_low_t *lf, const H5F_access_t __unused__ *access_parms,
*/
static herr_t
H5F_stdio_write(H5F_low_t *lf, const H5F_access_t __unused__ *access_parms,
- const H5D_transfer_t xfer_mode,
+ const H5D_transfer_t __unused__ xfer_mode,
const haddr_t *addr, size_t size, const uint8 *buf)
{
uint64 mask;
diff --git a/src/H5MF.c b/src/H5MF.c
index a87dc39..6a51ff7 100644
--- a/src/H5MF.c
+++ b/src/H5MF.c
@@ -11,10 +11,13 @@
* Purpose: File memory management functions.
*
* Modifications:
- *
* Robb Matzke, 5 Aug 1997
* Added calls to H5E.
*
+ * Robb Matzke, 8 Jun 1998
+ * Implemented a very simple free list which is not persistent and which
+ * is lossy.
+ *
*-------------------------------------------------------------------------
*/
#include <H5private.h>
@@ -27,6 +30,7 @@
/* Is the interface initialized? */
static intn interface_initialize_g = FALSE;
#define INTERFACE_INIT NULL
+
/*-------------------------------------------------------------------------
* Function: H5MF_alloc
@@ -53,7 +57,12 @@ static intn interface_initialize_g = FALSE;
herr_t
H5MF_alloc(H5F_t *f, intn op, hsize_t size, haddr_t *addr/*out*/)
{
- haddr_t tmp_addr;
+ haddr_t tmp_addr;
+ intn i, found, status;
+ hsize_t n;
+ H5MF_free_t blk;
+ hsize_t thresh = f->shared->access_parms->threshold;
+ hsize_t align = f->shared->access_parms->alignment;
FUNC_ENTER(H5MF_alloc, FAIL);
@@ -63,30 +72,114 @@ H5MF_alloc(H5F_t *f, intn op, hsize_t size, haddr_t *addr/*out*/)
assert(size > 0);
assert(addr);
+#if 0
+ HDfprintf (stderr, "A %Hu\n", size);
+#endif
+
+
/* Fail if we don't have write access */
if (0==(f->intent & H5F_ACC_RDWR)) {
HRETURN_ERROR (H5E_RESOURCE, H5E_CANTINIT, FAIL, "file is read-only");
}
/*
- * Eventually we'll maintain a free list(s) and try to satisfy requests
- * from there. But for now we just allocate more memory from the end of
- * the file.
+ * Try to satisfy the request from the free list. We prefer exact matches
+ * to partial matches, so if we find an exact match then we break out of
+ * the loop immediately, otherwise we keep looking for an exact match.
*/
- if (H5F_low_extend(f->shared->lf, f->shared->access_parms, op,
- size, addr/*out*/) < 0) {
- HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "low level mem management failed");
+ for (i=0, found=-1; i<f->shared->fl_nfree; i++) {
+ if ((status=H5F_low_alloc(f->shared->lf, op, align, thresh, size,
+ f->shared->fl_free+i, addr/*out*/))>0) {
+ /* Exact match found */
+ found = i;
+ break;
+ } else if (0==status) {
+ /* Partial match */
+ found = i;
+ }
}
- /* Convert from absolute to relative */
- addr->offset -= f->shared->base_addr.offset;
-
- /* Did we extend the size of the hdf5 data? */
- tmp_addr = *addr;
- H5F_addr_inc(&tmp_addr, size);
- if (H5F_addr_gt(&tmp_addr, &(f->shared->hdf5_eof))) {
- f->shared->hdf5_eof = tmp_addr;
+
+ if (found>=0 &&
+ (status=H5F_low_alloc (f->shared->lf, op, align, thresh, size,
+ f->shared->fl_free+found, addr/*out*/))>0) {
+ /*
+ * We found an exact match. Remove that block from the free list and
+ * use it to satisfy the request.
+ */
+ --(f->shared->fl_nfree);
+ HDmemmove (f->shared->fl_free+found, f->shared->fl_free+found+1,
+ (f->shared->fl_nfree-found) * sizeof(H5MF_free_t));
+
+ } else if (found>=0 && status==0) {
+ /*
+ * We found a free block which is larger than the requested size.
+ * Return the unused parts of the free block to the free list.
+ */
+ blk = f->shared->fl_free[found];
+ --f->shared->fl_nfree;
+ HDmemmove (f->shared->fl_free+found, f->shared->fl_free+found+1,
+ (f->shared->fl_nfree-found) * sizeof(H5MF_free_t));
+ if (H5F_addr_gt (addr, &(blk.addr))) {
+ /* Free the first part of the free block */
+ n = addr->offset - blk.addr.offset;
+ H5MF_free (f, &(blk.addr), n);
+ blk.addr = *addr;
+ blk.size -= n;
+ }
+
+ if (blk.size > size) {
+ /* Free the second part of the free block */
+ H5F_addr_inc (&(blk.addr), size);
+ blk.size -= size;
+ H5MF_free (f, &(blk.addr), blk.size);
+ }
+
+ } else {
+ /*
+ * No suitable free block was found. Allocate space from the end of
+ * the file. We don't know about alignment at this point, so we
+ * allocate enough space to align the data also.
+ */
+ if (size>=thresh) {
+ blk.size = size + align - 1;
+ } else {
+ blk.size = size;
+ }
+ if (H5F_low_extend(f->shared->lf, f->shared->access_parms, op,
+ blk.size, &(blk.addr)/*out*/) < 0) {
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "low level mem management failed");
+ }
+
+ /* Convert from absolute to relative */
+ blk.addr.offset -= f->shared->base_addr.offset;
+
+ /* Did we extend the size of the hdf5 data? */
+ tmp_addr = blk.addr;
+ H5F_addr_inc(&tmp_addr, blk.size);
+ if (H5F_addr_gt(&tmp_addr, &(f->shared->hdf5_eof))) {
+ f->shared->hdf5_eof = tmp_addr;
+ }
+
+ if ((status=H5F_low_alloc (f->shared->lf, op, align, thresh, size,
+ &blk, addr/*out*/))>0) {
+ /* Exact match */
+ } else if (0==status) {
+ /* Partial match */
+ if (H5F_addr_gt (addr, &(blk.addr))) {
+ n = addr->offset - blk.addr.offset;
+ H5MF_free (f, &(blk.addr), n);
+ blk.addr = *addr;
+ blk.size -= n;
+ }
+ if (blk.size > size) {
+ H5F_addr_inc (&(blk.addr), size);
+ blk.size -= size;
+ H5MF_free (f, &(blk.addr), blk.size);
+ }
+ }
}
+
FUNC_LEAVE(SUCCEED);
}
@@ -111,8 +204,10 @@ H5MF_alloc(H5F_t *f, intn op, hsize_t size, haddr_t *addr/*out*/)
*-------------------------------------------------------------------------
*/
herr_t
-H5MF_free(H5F_t __unused__ *f, const haddr_t *addr, hsize_t size)
+H5MF_free(H5F_t *f, const haddr_t *addr, hsize_t size)
{
+ int i;
+
FUNC_ENTER(H5MF_free, FAIL);
/* check arguments */
@@ -121,11 +216,29 @@ H5MF_free(H5F_t __unused__ *f, const haddr_t *addr, hsize_t size)
HRETURN(SUCCEED);
assert(!H5F_addr_zerop(addr));
+ /*
+ * Insert this free block into the free list without attempting to
+ * combine it with other free blocks. If the list is overfull then
+ * remove the smallest free block.
+ */
+ if (f->shared->fl_nfree>=H5MF_NFREE) {
+ for (i=0; i<H5MF_NFREE; i++) {
+ if (f->shared->fl_free[i].size<size) {
#ifdef H5MF_DEBUG
- fprintf(stderr, "H5MF_free: lost %lu bytes of file storage\n",
- (unsigned long) size);
+ fprintf(stderr, "H5MF_free: lost %lu bytes of file storage\n",
+ (unsigned long) f->shared->fl_free[i].size);
#endif
-
+ f->shared->fl_free[i].addr = *addr;
+ f->shared->fl_free[i].size = size;
+ break;
+ }
+ }
+ } else {
+ i = f->shared->fl_nfree++;
+ f->shared->fl_free[i].addr = *addr;
+ f->shared->fl_free[i].size = size;
+ }
+
FUNC_LEAVE(SUCCEED);
}
diff --git a/src/H5P.c b/src/H5P.c
index aa11f08..095bfa9 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -515,6 +515,102 @@ H5Pget_userblock(hid_t tid, hsize_t *size)
FUNC_LEAVE(SUCCEED);
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_alignment
+ *
+ * Purpose: Sets the alignment properties of a file access property list
+ * so that any file object >= THRESHOLD bytes will be aligned on
+ * an address which is a multiple of ALIGNMENT. The addresses
+ * are relative to the end of the user block; the alignment is
+ * calculated by subtracting the user block size from the
+ * absolute file address and then adjusting the address to be a
+ * multiple of ALIGNMENT.
+ *
+ * Default values for THRESHOLD and ALIGNMENT are one, implying
+ * no alignment. Generally the default values will result in
+ * the best performance for single-process access to the file.
+ * For MPI-IO and other parallel systems, choose an alignment
+ * which is a multiple of the disk block size.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, June 9, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_alignment (hid_t fapl_id, hsize_t threshold, hsize_t alignment)
+{
+ H5F_access_t *fapl = NULL;
+
+ FUNC_ENTER (H5Pset_alignment, FAIL);
+
+ /* Check args */
+ if (H5P_FILE_ACCESS != H5Pget_class (fapl_id) ||
+ NULL == (fapl = H5I_object (fapl_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file access property list");
+ }
+ if (alignment<1) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "alignment must be positive");
+ }
+
+ /* Set values */
+ fapl->threshold = threshold;
+ fapl->alignment = alignment;
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_alignment
+ *
+ * Purpose: Returns the current settings for alignment properties from a
+ * file access property list. The THRESHOLD and/or ALIGNMENT
+ * pointers may be null pointers.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, June 9, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_alignment (hid_t fapl_id, hsize_t *threshold/*out*/,
+ hsize_t *alignment/*out*/)
+{
+ H5F_access_t *fapl = NULL;
+
+ FUNC_ENTER (H5Pget_alignment, FAIL);
+
+ /* Check args */
+ if (H5P_FILE_ACCESS != H5Pget_class (fapl_id) ||
+ NULL == (fapl = H5I_object (fapl_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file access property list");
+ }
+
+ /* Get values */
+ if (threshold) *threshold = fapl->threshold;
+ if (alignment) *alignment = fapl->alignment;
+
+ FUNC_LEAVE (SUCCEED);
+}
+
/*-------------------------------------------------------------------------
* Function: H5Pset_sizes
@@ -2211,8 +2307,6 @@ herr_t
H5Pset_mpi (hid_t tid, MPI_Comm comm, MPI_Info info)
{
H5F_access_t *tmpl = NULL;
- MPI_Comm lcomm;
- int mrc; /* MPI return code */
FUNC_ENTER(H5Pset_mpi, FAIL);
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index 9a3cda2..220073f 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -51,6 +51,9 @@ herr_t H5Pget_version (hid_t tid, int *boot/*out*/, int *freelist/*out*/,
int *stab/*out*/, int *shhdr/*out*/);
herr_t H5Pset_userblock (hid_t tid, hsize_t size);
herr_t H5Pget_userblock (hid_t tid, hsize_t *size);
+herr_t H5Pset_alignment (hid_t fapl_id, hsize_t threshold, hsize_t alignment);
+herr_t H5Pget_alignment (hid_t fapl_id, hsize_t *threshold/*out*/,
+ hsize_t *alignment/*out*/);
herr_t H5Pset_sizes (hid_t tid, size_t sizeof_addr, size_t sizeof_size);
herr_t H5Pget_sizes (hid_t tid, size_t *sizeof_addr/*out*/,
size_t *sizeof_size/*out*/);
diff --git a/src/H5S.c b/src/H5S.c
index 771ccba..0d44675 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -813,18 +813,19 @@ H5S_modify(H5G_entry_t *ent, const H5S_t *ds)
* Tuesday, December 9, 1997
*
* Modifications:
- *
+ * Robb Matzke, 9 Jun 1998
+ * Removed the unused file argument since the file is now part of the
+ * ENT argument.
*-------------------------------------------------------------------------
*/
H5S_t *
-H5S_read(H5F_t __unused__ *f, H5G_entry_t *ent)
+H5S_read(H5G_entry_t *ent)
{
H5S_t *ds = NULL;
FUNC_ENTER(H5S_read, NULL);
/* check args */
- assert(f);
assert(ent);
ds = H5MM_xcalloc(1, sizeof(H5S_t));
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index 06e9d0f..084c282 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -118,7 +118,7 @@ intn H5S_get_ndims (const H5S_t *ds);
intn H5S_get_dims (const H5S_t *ds, hsize_t dims[]/*out*/,
hsize_t max_dims[]/*out*/);
herr_t H5S_modify (H5G_entry_t *ent, const H5S_t *space);
-H5S_t *H5S_read (H5F_t *f, H5G_entry_t *ent);
+H5S_t *H5S_read (H5G_entry_t *ent);
intn H5S_cmp (const H5S_t *ds1, const H5S_t *ds2);
hbool_t H5S_is_simple (const H5S_t *sdim);
uintn H5S_nelem (const H5S_t *space);