summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST1
-rw-r--r--doc/html/H5.format.html69
-rw-r--r--src/H5D.c33
-rw-r--r--src/H5Distore.c30
-rw-r--r--src/H5Dprivate.h1
-rw-r--r--src/H5E.c2
-rw-r--r--src/H5Epublic.h2
-rw-r--r--src/H5Farray.c23
-rw-r--r--src/H5Fistore.c30
-rw-r--r--src/H5Fprivate.h14
-rw-r--r--src/H5O.c2
-rw-r--r--src/H5Ofill.c328
-rw-r--r--src/H5Omtime.c4
-rw-r--r--src/H5Oprivate.h16
-rw-r--r--src/H5P.c212
-rw-r--r--src/H5Ppublic.h2
-rw-r--r--src/H5Sall.c25
-rw-r--r--src/H5Shyper.c70
-rw-r--r--src/H5Spoint.c26
-rw-r--r--src/H5Sprivate.h2
-rw-r--r--src/H5Tconv.c4
-rw-r--r--src/H5V.c6
-rw-r--r--src/Makefile.in2
-rw-r--r--test/istore.c14
-rw-r--r--test/overhead.c356
25 files changed, 1158 insertions, 116 deletions
diff --git a/MANIFEST b/MANIFEST
index 36eb740..86ae68f 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -235,6 +235,7 @@
./src/H5Ocont.c
./src/H5Odtype.c
./src/H5Oefl.c
+./src/H5Ofill.c
./src/H5Olayout.c
./src/H5Omtime.c
./src/H5Oname.c
diff --git a/doc/html/H5.format.html b/doc/html/H5.format.html
index 86d591c..9902bca 100644
--- a/doc/html/H5.format.html
+++ b/doc/html/H5.format.html
@@ -1,7 +1,7 @@
<html>
<head>
<title>
- HDF5 Draft Disk-Format Specification
+ HDF5 Disk-Format Specification
</title>
</head>
<body>
@@ -40,8 +40,8 @@
Name: Data-Space</a>
<li><a href="#DataTypeMessage"> <!-- 0x0003 -->
Name: Data-Type</a>
- <li><a href="#ReservedMessage_0004"> <!-- 0x0004 -->
- Name: Reserved - not assigned yet</a>
+ <li><a href="#FillValueMessage"> <!-- 0x0004 -->
+ Name: Data Storage - Fill Value</a>
<li><a href="#ReservedMessage_0005"> <!-- 0x0005 -->
Name: Reserved - not assigned yet</a>
<li><a href="#CompactDataStorageMessage"> <!-- 0x0006 -->
@@ -2268,15 +2268,64 @@
</center>
<p>Data type examples are <a href="Datatypes.html">here</a>.
-
+
<hr>
- <h3><a name="ReservedMessage_0004">Name: Reserved - Not Assigned
- Yet</a></h3>
- <b>Type:</b> 0x0004<BR>
- <b>Length:</b> N/A<BR>
- <b>Status:</b> N/A<BR>
+ <h3><a name="FillValueMessage">Name: Data Storage - Fill Value</a></h3>
+ <b>Type:</b> 0x0004<br>
+ <b>Length:</b> varies<br>
+ <b>Status:</b> Optional, may not be repeated.<br>
+
+ <p>The fill value message stores a single data point value which
+ is returned to the application when an uninitialized data point
+ is read from the dataset. The fill value is interpretted with
+ the same data type as the dataset. If no fill value message is
+ present then a fill value of all zero is assumed.
+
+ <p>
+ <center>
+ <table border cellpadding=4 width="80%">
+ <caption align=top>
+ <b>Fill Value Message</b>
+ </caption>
+
+ <tr align=center>
+ <th width="25%">byte</th>
+ <th width="25%">byte</th>
+ <th width="25%">byte</th>
+ <th width="25%">byte</th>
+ </tr>
+
+ <tr align=center>
+ <td colspan=4>Size (4 bytes)</td>
+ </tr>
+
+ <tr align=center>
+ <td colspan=4><br>Fill Value<br><br></td>
+ </tr>
+ </table>
+ </center>
+
+ <p>
+ <center>
+ <table align=center width="80%">
+ <tr>
+ <th width="30%">Field Name</th>
+ <th width="70%">Description</th>
+ </tr>
+ <tr valign=top>
+ <td>Size (4 bytes)</td>
+ <td>This is the size of the Fill Value field in bytes.</td>
+ </tr>
+
+ <tr valign=top>
+ <td>Fill Value</td>
+ <td>The fill value. The bytes of the fill value are
+ interpreted using the same data type as for the dataset.</td>
+ </tr>
+ </table>
+ </center>
<hr>
<h3><a name="ReservedMessage_0005">Name: Reserved - Not Assigned
@@ -3353,7 +3402,7 @@ data-type.
<address><a href="mailto:koziol@ncsa.uiuc.edu">Quincey Koziol</a></address>
<address><a href="mailto:matzke@llnl.gov">Robb Matzke</a></address>
<!-- hhmts start -->
-Last modified: Fri Aug 7 11:04:44 EDT 1998
+Last modified: Thu Oct 1 10:09:54 EDT 1998
<!-- hhmts end -->
</body>
</html>
diff --git a/src/H5D.c b/src/H5D.c
index e4c9c2c..a4d21dd 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -56,6 +56,9 @@ const H5D_create_t H5D_create_dflt = {
1, 1, 1, 1, 1, 1, 1, 1, /*...produce fewer, but larger I/O......*/
1, 1, 1, 1, 1, 1, 1, 1}, /*...requests. */
+ /* Fill value */
+ {NULL, 0, NULL}, /* No fill value */
+
/* External file list */
{H5F_ADDR_UNDEF, /* External file list heap address */
0, /*...slots allocated */
@@ -531,6 +534,14 @@ H5Dget_create_plist(hid_t dset_id)
"unable to copy the creation property list");
}
+ /* Copy the dataset type into the fill value message */
+ if (!copied_parms->fill.type &&
+ NULL==(copied_parms->fill.type=H5T_copy(dset->type,
+ H5T_COPY_TRANSIENT))) {
+ HRETURN_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to copy dataset data type for fill value");
+ }
+
/* Create an atom */
if ((ret_value=H5I_register ((H5I_group_t)(H5_TEMPLATE_0+
H5P_DATASET_CREATE),
@@ -944,6 +955,17 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
"unable to create dataset object header");
}
+ /* Convert the fill value to the dataset type and write the message */
+ if (H5O_fill_convert(&(new_dset->create_parms->fill), new_dset->type)<0) {
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL,
+ "unable to convert fill value to dataset type");
+ }
+ if (H5O_modify(&(new_dset->ent), H5O_FILL, 0, H5O_FLAG_CONSTANT,
+ &(new_dset->create_parms->fill))<0) {
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL,
+ "unable to update fill value header message");
+ }
+
/* 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 ||
@@ -1105,6 +1127,14 @@ H5D_open(H5G_entry_t *loc, const char *name)
"unable to read data space info from dataset header");
}
+ /* Get the optional fill value message */
+ if (NULL==H5O_read(&(dataset->ent), H5O_FILL, 0,
+ &(dataset->create_parms->fill))) {
+ H5E_clear();
+ HDmemset(&(dataset->create_parms->fill), 0,
+ sizeof(dataset->create_parms->fill));
+ }
+
/* Get the optional filters message */
if (NULL==H5O_read (&(dataset->ent), H5O_PLINE, 0,
&(dataset->create_parms->pline))) {
@@ -1513,6 +1543,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
#endif
n = (sconv->f->gath)(dataset->ent.file, &(dataset->layout),
&(dataset->create_parms->pline),
+ &(dataset->create_parms->fill),
&(dataset->create_parms->efl), src_type_size,
file_space, &file_iter, smine_nelmts,
xfer_parms, tconv_buf/*out*/);
@@ -1913,6 +1944,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
#endif
n = (sconv->f->gath)(dataset->ent.file, &(dataset->layout),
&(dataset->create_parms->pline),
+ &(dataset->create_parms->fill),
&(dataset->create_parms->efl), dst_type_size,
file_space, &bkg_iter, smine_nelmts,
xfer_parms, bkg_buf/*out*/);
@@ -1955,6 +1987,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
#endif
status = (sconv->f->scat)(dataset->ent.file, &(dataset->layout),
&(dataset->create_parms->pline),
+ &(dataset->create_parms->fill),
&(dataset->create_parms->efl), dst_type_size,
file_space, &file_iter, smine_nelmts,
xfer_parms, tconv_buf);
diff --git a/src/H5Distore.c b/src/H5Distore.c
index 88399fd..ebfb004 100644
--- a/src/H5Distore.c
+++ b/src/H5Distore.c
@@ -1170,8 +1170,8 @@ H5F_istore_prune (H5F_t *f, size_t size)
static void *
H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout,
const double split_ratios[], const H5O_pline_t *pline,
- const hssize_t offset[], hbool_t relax,
- intn *idx_hint/*in,out*/)
+ const H5O_fill_t *fill, const hssize_t offset[],
+ hbool_t relax, intn *idx_hint/*in,out*/)
{
uintn idx; /*hash index number */
hbool_t found = FALSE; /*already in cache? */
@@ -1268,9 +1268,20 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout,
"data pipeline read failed");
}
rdcc->nmisses++;
+ } else if (fill && fill->buf) {
+ /*
+ * The chunk doesn't exist in the file. Replicate the fill
+ * value throughout the chunk.
+ */
+ assert(0==chunk_size % fill->size);
+ H5V_array_fill(chunk, fill->buf, fill->size,
+ chunk_size/fill->size);
+ rdcc->ninits++;
+
} else {
/*
- * The chunk doesn't exist in the file. Assume all zeros.
+ * The chunk doesn't exist in the file and no fill value was
+ * specified. Assume all zeros.
*/
HDmemset (chunk, 0, chunk_size);
rdcc->ninits++;
@@ -1510,8 +1521,8 @@ H5F_istore_unlock (H5F_t *f, const H5O_layout_t *layout,
*/
herr_t
H5F_istore_read(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout,
- const H5O_pline_t *pline, const hssize_t offset_f[],
- const hsize_t size[], void *buf)
+ const H5O_pline_t *pline, const H5O_fill_t *fill,
+ const hssize_t offset_f[], const hsize_t size[], void *buf)
{
hssize_t offset_m[H5O_LAYOUT_NDIMS];
hsize_t size_m[H5O_LAYOUT_NDIMS];
@@ -1635,7 +1646,7 @@ H5F_istore_read(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout,
* the chunk.
*/
if (NULL==(chunk=H5F_istore_lock (f, layout, xfer->split_ratios,
- pline, chunk_offset,
+ pline, fill, chunk_offset,
FALSE, &idx_hint))) {
HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL,
"unable to read raw data chunk");
@@ -1682,8 +1693,9 @@ H5F_istore_read(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout,
*/
herr_t
H5F_istore_write(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout,
- const H5O_pline_t *pline, const hssize_t offset_f[],
- const hsize_t size[], const void *buf)
+ const H5O_pline_t *pline, const H5O_fill_t *fill,
+ const hssize_t offset_f[], const hsize_t size[],
+ const void *buf)
{
hssize_t offset_m[H5O_LAYOUT_NDIMS];
hsize_t size_m[H5O_LAYOUT_NDIMS];
@@ -1811,7 +1823,7 @@ H5F_istore_write(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout,
* chunk.
*/
if (NULL==(chunk=H5F_istore_lock (f, layout, xfer->split_ratios,
- pline, chunk_offset,
+ pline, fill, chunk_offset,
naccessed==chunk_size,
&idx_hint))) {
HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL,
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index c647cf0..2f65c7a 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -45,6 +45,7 @@ typedef struct H5D_create_t {
H5D_layout_t layout; /*storage layout */
intn chunk_ndims; /*chunk dimensionality */
hsize_t chunk_size[32]; /*chunk size if chunked storage */
+ H5O_fill_t fill; /*fill value */
H5O_efl_t efl; /*external file list */
H5O_pline_t pline; /*data filter pipeline */
} H5D_create_t;
diff --git a/src/H5E.c b/src/H5E.c
index f3961fd..da16fb5 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -53,7 +53,7 @@ static const H5E_major_mesg_t H5E_major_mesg_g[] = {
{H5E_DATASPACE, "Dataspace interface"},
{H5E_DATASET, "Dataset interface"},
{H5E_STORAGE, "Data storage layer"},
- {H5E_TEMPLATE, "Property list interface"},
+ {H5E_PLIST, "Property list interface"},
{H5E_ATTR, "Attribute layer"},
{H5E_PLINE, "Data filters layer"},
{H5E_EFL, "External file list"},
diff --git a/src/H5Epublic.h b/src/H5Epublic.h
index 6415b60..a31317f 100644
--- a/src/H5Epublic.h
+++ b/src/H5Epublic.h
@@ -70,7 +70,7 @@ typedef enum H5E_major_t {
H5E_DATASPACE, /*Dataspace */
H5E_DATASET, /*Dataset */
H5E_STORAGE, /*data storage */
- H5E_TEMPLATE, /*Property lists */
+ H5E_PLIST, /*Property lists */
H5E_ATTR, /*Attribute */
H5E_PLINE, /*Data filters */
H5E_EFL, /*External file list */
diff --git a/src/H5Farray.c b/src/H5Farray.c
index b3ebcff..2a2cd1c 100644
--- a/src/H5Farray.c
+++ b/src/H5Farray.c
@@ -119,10 +119,10 @@ H5F_arr_create (H5F_t *f, struct H5O_layout_t *layout/*in,out*/)
herr_t
H5F_arr_read (H5F_t *f, const H5D_xfer_t *xfer,
const struct H5O_layout_t *layout,
- const struct H5O_pline_t *pline, const struct H5O_efl_t *efl,
- const hsize_t _hslab_size[], const hsize_t mem_size[],
- const hssize_t mem_offset[], const hssize_t file_offset[],
- void *_buf/*out*/)
+ const struct H5O_pline_t *pline, const H5O_fill_t *fill,
+ const struct H5O_efl_t *efl, const hsize_t _hslab_size[],
+ const hsize_t mem_size[], const hssize_t mem_offset[],
+ const hssize_t file_offset[], void *_buf/*out*/)
{
uint8 *buf = (uint8 *)_buf; /*cast for arithmetic */
hssize_t file_stride[H5O_LAYOUT_NDIMS]; /*strides through file */
@@ -292,8 +292,8 @@ H5F_arr_read (H5F_t *f, const H5D_xfer_t *xfer,
"unable to copy into a proper hyperslab");
}
}
- if (H5F_istore_read (f, xfer, layout, pline, file_offset, hslab_size,
- buf)<0) {
+ if (H5F_istore_read (f, xfer, layout, pline, fill, file_offset,
+ hslab_size, buf)<0) {
HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
}
break;
@@ -344,9 +344,10 @@ herr_t
H5F_arr_write (H5F_t *f, const H5D_xfer_t *xfer,
const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
- const struct H5O_efl_t *efl, const hsize_t _hslab_size[],
- const hsize_t mem_size[], const hssize_t mem_offset[],
- const hssize_t file_offset[], const void *_buf)
+ const struct H5O_fill_t *fill, const struct H5O_efl_t *efl,
+ const hsize_t _hslab_size[], const hsize_t mem_size[],
+ const hssize_t mem_offset[], const hssize_t file_offset[],
+ const void *_buf)
{
const uint8 *buf = (const uint8 *)_buf; /*cast for arithmetic */
hssize_t file_stride[H5O_LAYOUT_NDIMS]; /*strides through file */
@@ -522,8 +523,8 @@ H5F_arr_write (H5F_t *f, const H5D_xfer_t *xfer,
"unable to copy from a proper hyperslab");
}
}
- if (H5F_istore_write (f, xfer, layout, pline, file_offset, hslab_size,
- buf)<0) {
+ if (H5F_istore_write (f, xfer, layout, pline, fill, file_offset,
+ hslab_size, buf)<0) {
HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL,
"chunked write failed");
}
diff --git a/src/H5Fistore.c b/src/H5Fistore.c
index 88399fd..ebfb004 100644
--- a/src/H5Fistore.c
+++ b/src/H5Fistore.c
@@ -1170,8 +1170,8 @@ H5F_istore_prune (H5F_t *f, size_t size)
static void *
H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout,
const double split_ratios[], const H5O_pline_t *pline,
- const hssize_t offset[], hbool_t relax,
- intn *idx_hint/*in,out*/)
+ const H5O_fill_t *fill, const hssize_t offset[],
+ hbool_t relax, intn *idx_hint/*in,out*/)
{
uintn idx; /*hash index number */
hbool_t found = FALSE; /*already in cache? */
@@ -1268,9 +1268,20 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout,
"data pipeline read failed");
}
rdcc->nmisses++;
+ } else if (fill && fill->buf) {
+ /*
+ * The chunk doesn't exist in the file. Replicate the fill
+ * value throughout the chunk.
+ */
+ assert(0==chunk_size % fill->size);
+ H5V_array_fill(chunk, fill->buf, fill->size,
+ chunk_size/fill->size);
+ rdcc->ninits++;
+
} else {
/*
- * The chunk doesn't exist in the file. Assume all zeros.
+ * The chunk doesn't exist in the file and no fill value was
+ * specified. Assume all zeros.
*/
HDmemset (chunk, 0, chunk_size);
rdcc->ninits++;
@@ -1510,8 +1521,8 @@ H5F_istore_unlock (H5F_t *f, const H5O_layout_t *layout,
*/
herr_t
H5F_istore_read(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout,
- const H5O_pline_t *pline, const hssize_t offset_f[],
- const hsize_t size[], void *buf)
+ const H5O_pline_t *pline, const H5O_fill_t *fill,
+ const hssize_t offset_f[], const hsize_t size[], void *buf)
{
hssize_t offset_m[H5O_LAYOUT_NDIMS];
hsize_t size_m[H5O_LAYOUT_NDIMS];
@@ -1635,7 +1646,7 @@ H5F_istore_read(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout,
* the chunk.
*/
if (NULL==(chunk=H5F_istore_lock (f, layout, xfer->split_ratios,
- pline, chunk_offset,
+ pline, fill, chunk_offset,
FALSE, &idx_hint))) {
HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL,
"unable to read raw data chunk");
@@ -1682,8 +1693,9 @@ H5F_istore_read(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout,
*/
herr_t
H5F_istore_write(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout,
- const H5O_pline_t *pline, const hssize_t offset_f[],
- const hsize_t size[], const void *buf)
+ const H5O_pline_t *pline, const H5O_fill_t *fill,
+ const hssize_t offset_f[], const hsize_t size[],
+ const void *buf)
{
hssize_t offset_m[H5O_LAYOUT_NDIMS];
hsize_t size_m[H5O_LAYOUT_NDIMS];
@@ -1811,7 +1823,7 @@ H5F_istore_write(H5F_t *f, const H5D_xfer_t *xfer, const H5O_layout_t *layout,
* chunk.
*/
if (NULL==(chunk=H5F_istore_lock (f, layout, xfer->split_ratios,
- pline, chunk_offset,
+ pline, fill, chunk_offset,
naccessed==chunk_size,
&idx_hint))) {
HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL,
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 9513689..ca787f7 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -503,10 +503,12 @@ typedef struct H5F_t {
case 2: UINT16DECODE(p,l); break; \
}
-struct H5O_layout_t; /*forward decl for prototype arguments */
-struct H5O_efl_t; /*forward decl for prototype arguments */
-struct H5O_pline_t; /*forward decl for prototype arguments */
-struct H5D_xfer_t; /*forward decl for prototype arguments */
+/* Forward declarations for prototypes arguments */
+struct H5O_layout_t;
+struct H5O_efl_t;
+struct H5O_pline_t;
+struct H5D_xfer_t;
+struct H5O_fill_t;
/* library variables */
extern const H5F_create_t H5F_create_dflt;
@@ -533,12 +535,14 @@ herr_t H5F_arr_create(H5F_t *f, struct H5O_layout_t *layout /*in,out*/);
herr_t H5F_arr_read (H5F_t *f, const struct H5D_xfer_t *xfer,
const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
+ const struct H5O_fill_t *fill,
const struct H5O_efl_t *efl, const hsize_t _hslab_size[],
const hsize_t mem_size[], const hssize_t mem_offset[],
const hssize_t file_offset[], void *_buf/*out*/);
herr_t H5F_arr_write (H5F_t *f, const struct H5D_xfer_t *xfer,
const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
+ const struct H5O_fill_t *fill,
const struct H5O_efl_t *efl, const hsize_t _hslab_size[],
const hsize_t mem_size[], const hssize_t mem_offset[],
const hssize_t file_offset[], const void *_buf);
@@ -552,11 +556,13 @@ herr_t H5F_istore_create(H5F_t *f, struct H5O_layout_t *layout /*in,out*/);
herr_t H5F_istore_read(H5F_t *f, const struct H5D_xfer_t *xfer,
const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
+ const struct H5O_fill_t *fill,
const hssize_t offset[], const hsize_t size[],
void *buf /*out */ );
herr_t H5F_istore_write(H5F_t *f, const struct H5D_xfer_t *xfer,
const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
+ const struct H5O_fill_t *fill,
const hssize_t offset[], const hsize_t size[],
const void *buf);
herr_t H5F_istore_allocate (H5F_t *f,
diff --git a/src/H5O.c b/src/H5O.c
index 69d4d5f..233d7f5 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -55,7 +55,7 @@ static const H5O_class_t *const message_type_g[] = {
H5O_SDSPACE, /*0x0001 Simple Dimensionality */
NULL, /*0x0002 Data space (fiber bundle?) */
H5O_DTYPE, /*0x0003 Data Type */
- NULL, /*0x0004 Not assigned */
+ H5O_FILL, /*0x0004 Data storage -- fill value */
NULL, /*0x0005 Not assigned */
NULL, /*0x0006 Data storage -- compact object */
H5O_EFL, /*0x0007 Data storage -- external data files */
diff --git a/src/H5Ofill.c b/src/H5Ofill.c
new file mode 100644
index 0000000..1328307
--- /dev/null
+++ b/src/H5Ofill.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 1998 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Robb Matzke <matzke@llnl.gov>
+ * Wednesday, September 30, 1998
+ *
+ * Purpose: The fill message indicates a bit pattern to use for
+ * uninitialized data points of a dataset.
+ */
+#include <H5private.h>
+#include <H5Eprivate.h>
+#include <H5MMprivate.h>
+#include <H5Oprivate.h>
+
+#define PABLO_MASK H5O_fill_mask
+
+static void *H5O_fill_decode(H5F_t *f, const uint8 *p, H5O_shared_t *sh);
+static herr_t H5O_fill_encode(H5F_t *f, uint8 *p, const void *_mesg);
+static void *H5O_fill_copy(const void *_mesg, void *_dest);
+static size_t H5O_fill_size(H5F_t *f, const void *_mesg);
+static herr_t H5O_fill_reset(void *_mesg);
+static herr_t H5O_fill_debug(H5F_t *f, const void *_mesg, FILE *stream,
+ intn indent, intn fwidth);
+
+/* This message derives from H5O */
+const H5O_class_t H5O_FILL[1] = {{
+ H5O_FILL_ID, /*message id number */
+ "fill", /*message name for debugging */
+ sizeof(H5O_fill_t), /*native message size */
+ H5O_fill_decode, /*decode message */
+ H5O_fill_encode, /*encode message */
+ H5O_fill_copy, /*copy the native value */
+ H5O_fill_size, /*raw message size */
+ H5O_fill_reset, /*free internal memory */
+ NULL, /*get share method */
+ NULL, /*set share method */
+ H5O_fill_debug, /*debug the message */
+}};
+
+/* Interface initialization */
+static hbool_t interface_initialize_g = FALSE;
+#define INTERFACE_INIT NULL
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_fill_decode
+ *
+ * Purpose: Decode a fill value message.
+ *
+ * Return: Success: Ptr to new message in native struct.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, September 30, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_fill_decode(H5F_t *f, const uint8 *p, H5O_shared_t *sh)
+{
+ H5O_fill_t *mesg=NULL;
+ void *ret_value = NULL;
+
+ FUNC_ENTER(H5O_fill_decode, NULL);
+ assert(f);
+ assert(p);
+ assert(!sh);
+
+ if (NULL==(mesg=H5MM_calloc(sizeof(H5O_fill_t)))) {
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed for fill value message");
+ }
+ UINT32DECODE(p, mesg->size);
+ if (NULL==(mesg->buf=H5MM_malloc(mesg->size))) {
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed for fill value");
+ }
+ HDmemcpy(mesg->buf, p, mesg->size);
+ ret_value = (void*)mesg;
+
+ done:
+ if (!ret_value && mesg) {
+ H5MM_xfree(mesg->buf);
+ H5MM_xfree(mesg);
+ }
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_fill_encode
+ *
+ * Purpose: Encode a fill value message.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, October 1, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_fill_encode(H5F_t *f, uint8 *p, const void *_mesg)
+{
+ const H5O_fill_t *mesg = (const H5O_fill_t *)_mesg;
+
+ FUNC_ENTER(H5O_fill_encode, FAIL);
+ assert(f);
+ assert(p);
+ assert(mesg && NULL==mesg->type);
+
+ UINT32ENCODE(p, mesg->size);
+ HDmemcpy(p, mesg->buf, mesg->size);
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_fill_copy
+ *
+ * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if
+ * necessary.
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, October 1, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_fill_copy(const void *_mesg, void *_dest)
+{
+ const H5O_fill_t *mesg = (const H5O_fill_t *)_mesg;
+ H5O_fill_t *dest = (H5O_fill_t *)_dest;
+ void *ret_value = NULL;
+
+ FUNC_ENTER(H5O_fill_copy, NULL);
+ assert(mesg);
+
+ if (!dest && NULL==(dest=H5MM_calloc(sizeof(H5O_fill_t)))) {
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed for fill message");
+ }
+ if (mesg->type &&
+ NULL==(dest->type=H5T_copy(mesg->type, H5T_COPY_TRANSIENT))) {
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL,
+ "unable to copy fill value data type");
+ }
+ if (mesg->buf) {
+ if (NULL==(dest->buf=H5MM_malloc(mesg->size))) {
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed for fill value");
+ }
+ dest->size = mesg->size;
+ HDmemcpy(dest->buf, mesg->buf, mesg->size);
+ }
+ ret_value = dest;
+
+ done:
+ if (!ret_value && dest) {
+ H5MM_xfree(dest->buf);
+ if (dest->type) H5T_close(dest->type);
+ if (!_dest) H5MM_xfree(dest);
+ }
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_fill_size
+ *
+ * Purpose: Returns the size of the raw message in bytes not counting the
+ * message type or size fields, but only the data fields. This
+ * function doesn't take into account alignment.
+ *
+ * Return: Success: Message data size in bytes w/o alignment.
+ *
+ * Failure: 0
+ *
+ * Programmer: Robb Matzke
+ * Thursday, October 1, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5O_fill_size(H5F_t *f, const void *_mesg)
+{
+ const H5O_fill_t *mesg = (const H5O_fill_t *)_mesg;
+
+ FUNC_ENTER(H5O_fill_size, 0);
+ assert(f);
+ assert(mesg);
+
+ FUNC_LEAVE(4+mesg->size);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_fill_reset
+ *
+ * Purpose: Resets a message to an initial state
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, October 1, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_fill_reset(void *_mesg)
+{
+ H5O_fill_t *mesg = (H5O_fill_t *)_mesg;
+
+ FUNC_ENTER(H5O_fill_reset, FAIL);
+ assert(mesg);
+
+ mesg->buf = H5MM_xfree(mesg->buf);
+ mesg->size = 0;
+ if (mesg->type) {
+ H5T_close(mesg->type);
+ mesg->type = NULL;
+ }
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_fill_debug
+ *
+ * Purpose: Prints debugging info for the message.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, October 1, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_fill_debug(H5F_t *f, const void *_mesg, FILE *stream, intn indent,
+ intn fwidth)
+{
+ const H5O_fill_t *mesg = (const H5O_fill_t *)_mesg;
+
+ FUNC_ENTER(H5O_fill_debug, FAIL);
+ assert(f);
+ assert(mesg);
+ assert(stream);
+ assert(indent>=0);
+ assert(fwidth>=0);
+
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "Bytes:", mesg->size);
+ fprintf(stream, "%*s%-*s ", indent, "", fwidth, "Data type:");
+ if (mesg->type) {
+ H5T_debug(mesg->type, stream);
+ fprintf(stream, "\n");
+ } else {
+ fprintf(stream, "<dataset type>\n");
+ }
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_fill_convert
+ *
+ * Purpose: Convert a fill value from whatever data type it currently has
+ * to the specified data type.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, October 1, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_fill_convert(H5O_fill_t *fill, H5T_t *dset_type)
+{
+ FUNC_ENTER(H5O_fill_convert, FAIL);
+ assert(fill);
+ assert(dset_type);
+
+ /* No-op cases */
+ if (!fill->buf || !fill->type || 0==H5T_cmp(fill->type, dset_type)) {
+ if (fill->type) H5T_close(fill->type);
+ fill->type = NULL;
+ HRETURN(SUCCEED);
+ }
+
+
+ HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
+ "fill value conversion not supported yet");
+
+ FUNC_LEAVE(SUCCEED);
+}
diff --git a/src/H5Omtime.c b/src/H5Omtime.c
index f144364..8693032 100644
--- a/src/H5Omtime.c
+++ b/src/H5Omtime.c
@@ -18,7 +18,7 @@ static void *H5O_mtime_decode(H5F_t *f, const uint8 *p, H5O_shared_t *sh);
static herr_t H5O_mtime_encode(H5F_t *f, uint8 *p, const void *_mesg);
static void *H5O_mtime_copy(const void *_mesg, void *_dest);
static size_t H5O_mtime_size(H5F_t *f, const void *_mesg);
-static herr_t H5O_mtime_debug(H5F_t *f, const void *_mesg, FILE * stream,
+static herr_t H5O_mtime_debug(H5F_t *f, const void *_mesg, FILE *stream,
intn indent, intn fwidth);
/* This message derives from H5O */
@@ -246,7 +246,7 @@ H5O_mtime_copy(const void *_mesg, void *_dest)
*
* Return: Success: Message data size in bytes w/o alignment.
*
- * Failure: FAIL
+ * Failure: 0
*
* Programmer: Robb Matzke
* matzke@llnl.gov
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 748e619..adc9396 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -133,6 +133,19 @@ extern const H5O_class_t H5O_DTYPE[1];
/* operates on an H5T_t struct */
/*
+ * Fill Value Message.
+ */
+#define H5O_FILL_ID 0x0004
+extern const H5O_class_t H5O_FILL[1];
+
+typedef struct H5O_fill_t {
+ H5T_t *type; /*type. Null implies same as dataset */
+ size_t size; /*number of bytes in the fill value */
+ void *buf; /*the fill value */
+} H5O_fill_t;
+
+
+/*
* External File List Message
*/
#define H5O_EFL_ID 0x0007 /*external file list id */
@@ -281,4 +294,7 @@ herr_t H5O_efl_read (H5F_t *f, const H5O_efl_t *efl, haddr_t *addr,
herr_t H5O_efl_write (H5F_t *f, const H5O_efl_t *efl, haddr_t *addr,
hsize_t size, const uint8 *buf);
+/* Fill value operators */
+herr_t H5O_fill_convert(H5O_fill_t *fill, H5T_t *type);
+
#endif
diff --git a/src/H5P.c b/src/H5P.c
index eb4faeb..1c8d56e 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -346,6 +346,7 @@ H5P_close (H5P_class_t type, void *plist)
break;
case H5P_DATASET_CREATE:
+ H5O_reset(H5O_FILL, &(dc_list->fill));
H5O_reset(H5O_EFL, &(dc_list->efl));
H5O_reset(H5O_PLINE, &(dc_list->pline));
break;
@@ -2086,15 +2087,16 @@ H5Pget_buffer(hid_t plist_id, void **tconv/*out*/, void **bkg/*out*/)
/*-------------------------------------------------------------------------
* Function: H5Pset_hyper_cache
*
- * Purpose: Given a dataset transfer property list, indicate whether to cache
- * the hyperslab blocks during the I/O (which speeds things up) and the
- * maximum size of the hyperslab block to cache. If a block is smaller
- * than to limit, it may still not be cached if no memory is available.
- * Setting the limit to 0 indicates no limitation on the size of block
- * to attempt to cache.
+ * Purpose: Given a dataset transfer property list, indicate whether to
+ * cache the hyperslab blocks during the I/O (which speeds
+ * things up) and the maximum size of the hyperslab block to
+ * cache. If a block is smaller than to limit, it may still not
+ * be cached if no memory is available. Setting the limit to 0
+ * indicates no limitation on the size of block to attempt to
+ * cache.
*
- * The default is to cache blocks with no limit on block size for serial
- * I/O and to not cache blocks for parallel I/O
+ * The default is to cache blocks with no limit on block size
+ * for serial I/O and to not cache blocks for parallel I/O
*
* Return: Success: SUCCEED
*
@@ -2147,7 +2149,8 @@ H5Pset_hyper_cache(hid_t plist_id, unsigned cache, unsigned limit)
*-------------------------------------------------------------------------
*/
herr_t
-H5Pget_hyper_cache(hid_t plist_id, unsigned *cache/*out*/, unsigned *limit/*out*/)
+H5Pget_hyper_cache(hid_t plist_id, unsigned *cache/*out*/,
+ unsigned *limit/*out*/)
{
H5D_xfer_t *plist = NULL;
@@ -2594,7 +2597,6 @@ herr_t
H5Pset_btree_ratios(hid_t plist_id, double left, double middle,
double right)
{
-
H5D_xfer_t *plist = NULL;
FUNC_ENTER(H5Pget_btree_ratios, FAIL);
@@ -2621,6 +2623,186 @@ H5Pset_btree_ratios(hid_t plist_id, double left, double middle,
}
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_fill_value
+ *
+ * Purpose: Set the fill value for a dataset creation property list. The
+ * VALUE is interpretted as being of type TYPE, which need not
+ * be the same type as the dataset but the library must be able
+ * to convert VALUE to the dataset type when the dataset is
+ * created.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, October 1, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value)
+{
+ H5D_create_t *plist = NULL;
+ H5T_t *type = NULL;
+
+ FUNC_ENTER(H5Pset_fill_value, FAIL);
+ H5TRACE3("e","iix",plist_id,type_id,value);
+
+ /* Check arguments */
+ if (H5P_DATASET_CREATE!=H5P_get_class(plist_id) ||
+ NULL==(plist=H5I_object(plist_id))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a dataset creation property list");
+ }
+ if (H5_DATATYPE!=H5I_group(type_id) ||
+ NULL==(type=H5I_object(type_id))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ }
+ if (!value) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no fill value specified");
+ }
+
+ /* Set the fill value */
+ H5O_reset(H5O_FILL, &(plist->fill));
+ if (NULL==(plist->fill.type=H5T_copy(type, H5T_COPY_TRANSIENT))) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to copy data type");
+ }
+ plist->fill.size = H5T_get_size(type);
+ if (NULL==(plist->fill.buf=H5MM_malloc(plist->fill.size))) {
+ HRETURN_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL,
+ "memory allocation failed for fill value");
+ }
+ HDmemcpy(plist->fill.buf, value, plist->fill.size);
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_fill_value
+ *
+ * Purpose: Queries the fill value property of a dataset creation
+ * property list. The fill value is returned through the VALUE
+ * pointer and the memory is allocated by the caller. The fill
+ * value will be converted from its current data type to the
+ * specified TYPE.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, October 1, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/)
+{
+ H5D_create_t *plist = NULL;
+ H5T_t *type = NULL;
+ H5T_cdata_t *cdata = NULL; /*conversion data */
+ H5T_conv_t cfunc = NULL; /*conversion function */
+ void *buf = NULL; /*conversion buffer */
+ void *bkg = NULL; /*conversion buffer */
+ H5_timer_t timer; /*conversion timer */
+ hid_t src_id = -1; /*source data type id */
+ herr_t status;
+ herr_t ret_value = FAIL;
+
+ FUNC_ENTER(H5Pget_fill_value, FAIL);
+ H5TRACE3("e","iix",plist_id,type_id,value);
+
+ /* Check arguments */
+ if (H5P_DATASET_CREATE!=H5P_get_class(plist_id) ||
+ NULL==(plist=H5I_object(plist_id))) {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a dataset creation proprety list");
+ }
+ if (H5_DATATYPE!=H5I_group(type_id) ||
+ NULL==(type=H5I_object(type_id))) {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ }
+ if (!value) {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "no fill value output buffer");
+ }
+
+ /*
+ * If no fill value is defined then return an error. We can't even
+ * return zero because we don't know the data type of the dataset and
+ * data type conversion might not have resulted in zero.
+ */
+ if (NULL==plist->fill.buf) {
+ HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "no fill value defined");
+ }
+
+ /*
+ * Can we convert between the source and destination data types?
+ */
+ if (NULL==(cfunc=H5T_find(plist->fill.type, type, H5T_BKG_NO, &cdata))) {
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to convert between src and dst data types");
+ }
+ src_id = H5I_register(H5_DATATYPE,
+ H5T_copy (plist->fill.type, H5T_COPY_TRANSIENT));
+ if (src_id<0) {
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to copy/register data type");
+ }
+
+ /*
+ * Data type conversions are always done in place, so we need a buffer
+ * other than the fill value buffer that is large enough for both source
+ * and destination. The app-supplied buffer might do okay.
+ */
+ if (H5T_get_size(type)>=H5T_get_size(plist->fill.type)) {
+ buf = value;
+ if (cdata->need_bkg>=H5T_BKG_TEMP &&
+ NULL==(bkg=H5MM_malloc(H5T_get_size(type)))) {
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed for type conversion");
+ }
+ } else {
+ if (NULL==(buf=H5MM_malloc(H5T_get_size(plist->fill.type)))) {
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed for type conversion");
+ }
+ if (cdata->need_bkg>=H5T_BKG_TEMP) bkg = value;
+ }
+ HDmemcpy(buf, plist->fill.buf, H5T_get_size(plist->fill.type));
+
+ /* Do the conversion */
+#ifdef H5T_DEBUG
+ H5T_timer_begin(&timer, cdata);
+#endif
+ cdata->command = H5T_CONV_CONV;
+ status = (cfunc)(src_id, type_id, cdata, 1, buf, bkg);
+#ifdef H5T_DEBUG
+ H5T_timer_end(&timer, cdata, 1);
+#endif
+ if (status<0) {
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "data type conversion failed");
+ }
+ if (buf!=value) HDmemcpy(value, buf, H5T_get_size(type));
+ ret_value = SUCCEED;
+
+ done:
+ if (buf!=value) H5MM_xfree(buf);
+ if (bkg!=value) H5MM_xfree(bkg);
+ if (src_id>=0) H5I_dec_ref(src_id);
+ FUNC_LEAVE(ret_value);
+}
+
+
#ifdef HAVE_PARALLEL
/*-------------------------------------------------------------------------
* Function: H5Pset_mpi
@@ -3015,16 +3197,22 @@ H5P_copy (H5P_class_t type, const void *src)
dc_src = (const H5D_create_t*)src;
dc_dst = (H5D_create_t*)dst;
+ /* Copy the fill value */
+ if (NULL==H5O_copy(H5O_FILL, &(dc_src->fill), &(dc_dst->fill))) {
+ HRETURN_ERROR(H5E_PLIST, H5E_CANTINIT, NULL,
+ "unabe to copy fill value message");
+ }
+
/* Copy the external file list */
HDmemset(&(dc_dst->efl), 0, sizeof(dc_dst->efl));
if (NULL==H5O_copy(H5O_EFL, &(dc_src->efl), &(dc_dst->efl))) {
- HRETURN_ERROR(H5E_TEMPLATE, H5E_CANTINIT, NULL,
+ HRETURN_ERROR(H5E_PLIST, H5E_CANTINIT, NULL,
"unable to copy external file list message");
}
/* Copy the filter pipeline */
if (NULL==H5O_copy(H5O_PLINE, &(dc_src->pline), &(dc_dst->pline))) {
- HRETURN_ERROR(H5E_TEMPLATE, H5E_CANTINIT, NULL,
+ HRETURN_ERROR(H5E_PLIST, H5E_CANTINIT, NULL,
"unable to copy filter pipeline message");
}
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index cc6c4e3..cccd4fd 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -112,6 +112,8 @@ herr_t H5Pset_btree_ratios(hid_t plist_id, double left, double middle,
double right);
herr_t H5Pget_btree_ratios(hid_t plist_id, double *left/*out*/,
double *middle/*out*/, double *right/*out*/);
+herr_t H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value);
+herr_t H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/);
#ifdef HAVE_PARALLEL
herr_t H5Pset_mpi (hid_t plist_id, MPI_Comm comm, MPI_Info info);
diff --git a/src/H5Sall.c b/src/H5Sall.c
index e3ea157..c798a61 100644
--- a/src/H5Sall.c
+++ b/src/H5Sall.c
@@ -24,12 +24,14 @@ static size_t H5S_all_favail (const H5S_t *space, const H5S_sel_iter_t *iter,
size_t max);
static size_t H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
+ const struct H5O_fill_t *fill,
const struct H5O_efl_t *efl, size_t elmt_size,
const H5S_t *file_space,
H5S_sel_iter_t *file_iter, size_t nelmts,
const H5D_xfer_t *xfer_parms, void *buf/*out*/);
static herr_t H5S_all_fscat (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
+ const struct H5O_fill_t *fill,
const struct H5O_efl_t *efl, size_t elmt_size,
const H5S_t *file_space,
H5S_sel_iter_t *file_iter, size_t nelmts,
@@ -167,9 +169,10 @@ H5S_all_favail (const H5S_t *space, const H5S_sel_iter_t *sel_iter, size_t max)
static size_t
H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
- const struct H5O_efl_t *efl, size_t elmt_size,
- const H5S_t *file_space, H5S_sel_iter_t *file_iter,
- size_t nelmts, const H5D_xfer_t *xfer_parms, void *_buf/*out*/)
+ const struct H5O_fill_t *fill, const struct H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space,
+ H5S_sel_iter_t *file_iter, size_t nelmts,
+ const H5D_xfer_t *xfer_parms, void *_buf/*out*/)
{
hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
@@ -222,8 +225,8 @@ H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout,
/*
* Gather from file.
*/
- if (H5F_arr_read (f, xfer_parms, layout, pline, efl, hsize, hsize, zero,
- file_offset, buf/*out*/)<0) {
+ if (H5F_arr_read (f, xfer_parms, layout, pline, fill, efl, hsize, hsize,
+ zero, file_offset, buf/*out*/)<0) {
HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error");
}
@@ -256,10 +259,10 @@ H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout,
*/
static herr_t
H5S_all_fscat (H5F_t *f, const struct H5O_layout_t *layout,
- const struct H5O_pline_t *pline, const struct H5O_efl_t *efl,
- size_t elmt_size, const H5S_t *file_space,
- H5S_sel_iter_t *file_iter, size_t nelmts,
- const H5D_xfer_t *xfer_parms, const void *_buf)
+ const struct H5O_pline_t *pline, const struct H5O_fill_t *fill,
+ const struct H5O_efl_t *efl, size_t elmt_size,
+ const H5S_t *file_space, H5S_sel_iter_t *file_iter,
+ size_t nelmts, const H5D_xfer_t *xfer_parms, const void *_buf)
{
hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of hyperslab */
hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
@@ -308,8 +311,8 @@ H5S_all_fscat (H5F_t *f, const struct H5O_layout_t *layout,
/*
* Scatter to file.
*/
- if (H5F_arr_write (f, xfer_parms, layout, pline, efl, hsize, hsize, zero,
- file_offset, buf)<0) {
+ if (H5F_arr_write (f, xfer_parms, layout, pline, fill, efl, hsize, hsize,
+ zero, file_offset, buf)<0) {
HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error");
}
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 54ee1bd..c27d068 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -26,6 +26,7 @@ typedef struct {
H5F_t *f;
const struct H5O_layout_t *layout;
const struct H5O_pline_t *pline;
+ const struct H5O_fill_t *fill;
const struct H5O_efl_t *efl;
size_t elmt_size;
const H5S_t *space;
@@ -55,12 +56,14 @@ static size_t H5S_hyper_favail (const H5S_t *space, const H5S_sel_iter_t *iter,
size_t max);
static size_t H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
+ const struct H5O_fill_t *fill,
const struct H5O_efl_t *efl, size_t elmt_size,
const H5S_t *file_space,
H5S_sel_iter_t *file_iter, size_t nelmts,
const H5D_xfer_t *xfer_parms, void *buf/*out*/);
static herr_t H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
+ const struct H5O_fill_t *fill,
const struct H5O_efl_t *efl, size_t elmt_size,
const H5S_t *file_space,
H5S_sel_iter_t *file_iter, size_t nelmts,
@@ -425,7 +428,8 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
*-------------------------------------------------------------------------
*/
static herr_t
-H5S_hyper_block_cache (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_info, uintn block_read)
+H5S_hyper_block_cache (H5S_hyper_node_t *node,
+ H5S_hyper_fhyper_info_t *fhyper_info, uintn block_read)
{
hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
@@ -454,8 +458,8 @@ H5S_hyper_block_cache (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_i
if (H5F_arr_read (fhyper_info->f, fhyper_info->xfer_parms,
fhyper_info->layout, fhyper_info->pline,
- fhyper_info->efl, hsize, hsize, zero, file_offset,
- node->cinfo.block/*out*/)<0)
+ fhyper_info->fill, fhyper_info->efl, hsize, hsize,
+ zero, file_offset, node->cinfo.block/*out*/)<0)
HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, FAIL, "read error");
} /* end if */
else {
@@ -501,9 +505,14 @@ H5S_hyper_block_read (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_in
!! NOTE !! This will need to be changed for different dimension
permutations from the standard 'C' ordering!
*/
- HDmemcpy(fhyper_info->dst,node->cinfo.pos,region_size*fhyper_info->elmt_size);
+ HDmemcpy(fhyper_info->dst,
+ node->cinfo.pos,
+ region_size*fhyper_info->elmt_size);
- /* Decrement the number of elements left in block to read & move the offset */
+ /*
+ * Decrement the number of elements left in block to read & move the
+ * offset
+ */
node->cinfo.pos+=region_size*fhyper_info->elmt_size;
node->cinfo.left-=region_size;
@@ -536,7 +545,9 @@ H5S_hyper_block_read (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_in
*-------------------------------------------------------------------------
*/
static herr_t
-H5S_hyper_block_write (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_info, hsize_t region_size)
+H5S_hyper_block_write (H5S_hyper_node_t *node,
+ H5S_hyper_fhyper_info_t *fhyper_info,
+ hsize_t region_size)
{
hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
@@ -552,16 +563,24 @@ H5S_hyper_block_write (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_i
!! NOTE !! This will need to be changed for different dimension
permutations from the standard 'C' ordering!
*/
- HDmemcpy(node->cinfo.pos,fhyper_info->src,region_size*fhyper_info->elmt_size);
+ HDmemcpy(node->cinfo.pos,
+ fhyper_info->src,
+ region_size*fhyper_info->elmt_size);
- /* Decrement the number of elements left in block to read & move the offset */
+ /*
+ * Decrement the number of elements left in block to read & move the
+ * offset
+ */
node->cinfo.pos+=region_size*fhyper_info->elmt_size;
node->cinfo.left-=region_size;
/* If we've read in all the elements from the block, throw it away */
if(node->cinfo.left==0) {
/* Copy the location of the region in the file */
- HDmemcpy(file_offset,node->start,(fhyper_info->space->extent.u.simple.rank * sizeof(hssize_t)));
+ HDmemcpy(file_offset,
+ node->start,
+ (fhyper_info->space->extent.u.simple.rank *
+ sizeof(hssize_t)));
file_offset[fhyper_info->space->extent.u.simple.rank]=0;
/* Set the hyperslab size to write */
@@ -571,8 +590,8 @@ H5S_hyper_block_write (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_i
if (H5F_arr_write (fhyper_info->f, fhyper_info->xfer_parms,
fhyper_info->layout, fhyper_info->pline,
- fhyper_info->efl, hsize, hsize, zero, file_offset,
- node->cinfo.block/*out*/)<0)
+ fhyper_info->fill, fhyper_info->efl, hsize, hsize,
+ zero, file_offset, node->cinfo.block/*out*/)<0)
HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error");
/* Release the temporary buffer */
@@ -650,10 +669,14 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
/* perform I/O on data from regions */
for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) {
/* Compute the size of the region to read */
- region_size=MIN(fhyper_info->nelmts, (regions[i].end-regions[i].start)+1);
+ region_size=MIN(fhyper_info->nelmts,
+ (regions[i].end-regions[i].start)+1);
/* Check if this hyperslab block is cached or could be cached */
- if(!regions[i].node->cinfo.cached && (fhyper_info->xfer_parms->cache_hyper && (fhyper_info->xfer_parms->block_limit==0 || fhyper_info->xfer_parms->block_limit>=(regions[i].node->cinfo.size*fhyper_info->elmt_size)))) {
+ if(!regions[i].node->cinfo.cached &&
+ (fhyper_info->xfer_parms->cache_hyper &&
+ (fhyper_info->xfer_parms->block_limit==0 ||
+ fhyper_info->xfer_parms->block_limit>=(regions[i].node->cinfo.size*fhyper_info->elmt_size)))) {
/* if we aren't cached, attempt to cache the block */
H5S_hyper_block_cache(regions[i].node,fhyper_info,1);
} /* end if */
@@ -691,17 +714,17 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
*/
if (H5F_arr_read (fhyper_info->f, fhyper_info->xfer_parms,
fhyper_info->layout, fhyper_info->pline,
- fhyper_info->efl, hsize, hsize, zero,
- file_offset,
+ fhyper_info->fill, fhyper_info->efl,
+ hsize, hsize, zero, file_offset,
fhyper_info->dst/*out*/)<0) {
HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0,
"read error");
}
#ifdef QAK
- printf("%s: check 2.3, region #%d\n",FUNC,(int)i);
- for(j=0; j<fhyper_info->space->extent.u.simple.rank; j++)
- printf("%s: %d - pos=%d\n",
- FUNC,j,(int)fhyper_info->iter->hyp.pos[j]);
+ printf("%s: check 2.3, region #%d\n",FUNC,(int)i);
+ for(j=0; j<fhyper_info->space->extent.u.simple.rank; j++)
+ printf("%s: %d - pos=%d\n",
+ FUNC,j,(int)fhyper_info->iter->hyp.pos[j]);
#endif /* QAK */
} /* end else */
@@ -789,6 +812,7 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
static size_t
H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
+ const struct H5O_fill_t *fill,
const struct H5O_efl_t *efl, size_t elmt_size,
const H5S_t *file_space, H5S_sel_iter_t *file_iter,
size_t nelmts, const H5D_xfer_t *xfer_parms,
@@ -833,6 +857,7 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout,
fhyper_info.f=f;
fhyper_info.layout=layout;
fhyper_info.pline=pline;
+ fhyper_info.fill=fill;
fhyper_info.efl=efl;
fhyper_info.elmt_size=elmt_size;
fhyper_info.space=file_space;
@@ -961,8 +986,9 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
*/
if (H5F_arr_write (fhyper_info->f, fhyper_info->xfer_parms,
fhyper_info->layout, fhyper_info->pline,
- fhyper_info->efl, hsize, hsize, zero,
- file_offset, fhyper_info->src)<0) {
+ fhyper_info->fill, fhyper_info->efl,
+ hsize, hsize, zero, file_offset,
+ fhyper_info->src)<0) {
HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0,
"write error");
}
@@ -1049,6 +1075,7 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
static herr_t
H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
+ const struct H5O_fill_t *fill,
const struct H5O_efl_t *efl, size_t elmt_size,
const H5S_t *file_space, H5S_sel_iter_t *file_iter,
size_t nelmts, const H5D_xfer_t *xfer_parms,
@@ -1094,6 +1121,7 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout,
fhyper_info.f=f;
fhyper_info.layout=layout;
fhyper_info.pline=pline;
+ fhyper_info.fill=fill;
fhyper_info.efl=efl;
fhyper_info.elmt_size=elmt_size;
fhyper_info.space=file_space;
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index d532fcf..11aa324 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -25,6 +25,7 @@ static size_t H5S_point_favail (const H5S_t *space, const H5S_sel_iter_t *iter,
size_t max);
static size_t H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
+ const struct H5O_fill_t *fill,
const struct H5O_efl_t *efl, size_t elmt_size,
const H5S_t *file_space,
H5S_sel_iter_t *file_iter, size_t nelmts,
@@ -32,6 +33,7 @@ static size_t H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout,
void *buf/*out*/);
static herr_t H5S_point_fscat (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
+ const struct H5O_fill_t *fill,
const struct H5O_efl_t *efl, size_t elmt_size,
const H5S_t *file_space,
H5S_sel_iter_t *file_iter, size_t nelmts,
@@ -265,10 +267,10 @@ H5S_point_favail (const H5S_t __unused__ *space,
static size_t
H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
- const struct H5O_efl_t *efl, size_t elmt_size,
- const H5S_t *file_space, H5S_sel_iter_t *file_iter,
- size_t nelmts, const H5D_xfer_t *xfer_parms,
- void *_buf/*out*/)
+ const struct H5O_fill_t *fill, const struct H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space,
+ H5S_sel_iter_t *file_iter, size_t nelmts,
+ const H5D_xfer_t *xfer_parms, void *_buf/*out*/)
{
hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
@@ -317,8 +319,8 @@ H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout,
file_offset[i] += file_space->select.offset[i];
/* Go read the point */
- if (H5F_arr_read (f, xfer_parms, layout, pline, efl, hsize, hsize,
- zero, file_offset, buf/*out*/)<0) {
+ if (H5F_arr_read (f, xfer_parms, layout, pline, fill, efl, hsize,
+ hsize, zero, file_offset, buf/*out*/)<0) {
HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error");
}
@@ -374,10 +376,10 @@ H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout,
static herr_t
H5S_point_fscat (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
- const struct H5O_efl_t *efl, size_t elmt_size,
- const H5S_t *file_space, H5S_sel_iter_t *file_iter,
- size_t nelmts, const H5D_xfer_t *xfer_parms,
- const void *_buf)
+ const struct H5O_fill_t *fill, const struct H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space,
+ H5S_sel_iter_t *file_iter, size_t nelmts,
+ const H5D_xfer_t *xfer_parms, const void *_buf)
{
hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of hyperslab */
hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
@@ -445,8 +447,8 @@ H5S_point_fscat (H5F_t *f, const struct H5O_layout_t *layout,
}
#endif /* QAK */
/* Go write the point */
- if (H5F_arr_write (f, xfer_parms, layout, pline, efl, hsize, hsize,
- zero, file_offset, buf)<0) {
+ if (H5F_arr_write (f, xfer_parms, layout, pline, fill, efl, hsize,
+ hsize, zero, file_offset, buf)<0) {
HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0, "write error");
}
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index c870a29..c434690 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -191,6 +191,7 @@ typedef struct H5S_fconv_t {
/* Gather elements from disk to type conversion buffer */
size_t (*gath)(H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
+ const struct H5O_fill_t *fill,
const struct H5O_efl_t *efl, size_t elmt_size,
const H5S_t *file_space, H5S_sel_iter_t *file_iter,
size_t nelmts, const struct H5D_xfer_t *xfer_parms,
@@ -199,6 +200,7 @@ typedef struct H5S_fconv_t {
/* Scatter elements from type conversion buffer to disk */
herr_t (*scat)(H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
+ const struct H5O_fill_t *fill,
const struct H5O_efl_t *efl, size_t elmt_size,
const H5S_t *file_space, H5S_sel_iter_t *file_iter,
size_t nelmts, const struct H5D_xfer_t *xfer_parms,
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 0f1d120..76d92c9 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -517,16 +517,18 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
if (src2dst[i]<0) continue;
src_memb = src->u.compnd.memb + i;
dst_memb = dst->u.compnd.memb + src2dst[i];
- offset -= dst_memb->size;
if (dst_memb->size > src_memb->size) {
H5T_conv_t tconv_func = priv->memb_conv[src2dst[i]];
H5T_cdata_t *memb_cdata = priv->memb_cdata[src2dst[i]];
+ offset -= src_memb->size;
memb_cdata->command = H5T_CONV_CONV;
(tconv_func)(priv->src_memb_id[src2dst[i]],
priv->dst_memb_id[src2dst[i]],
memb_cdata, priv->memb_nelmts[i],
buf+offset, bkg+dst_memb->offset);
+ } else {
+ offset -= dst_memb->size;
}
HDmemmove (bkg+dst_memb->offset, buf+offset, dst_memb->size);
}
diff --git a/src/H5V.c b/src/H5V.c
index c4ad0bb..b05b46c 100644
--- a/src/H5V.c
+++ b/src/H5V.c
@@ -643,9 +643,9 @@ H5V_stride_copy2(hsize_t nelmts, hsize_t elmt_size,
/*-------------------------------------------------------------------------
* Function: H5V_array_fill
*
- * Purpose: Fills all bytes of an array with the same value using memset().
- * Increases amount copied by power of two until the halfway point is
- * crossed, then copies the rest in one swoop.
+ * Purpose: Fills all bytes of an array with the same value using
+ * memset(). Increases amount copied by power of two until the
+ * halfway point is crossed, then copies the rest in one swoop.
*
* Return: Success: SUCCEED
*
diff --git a/src/Makefile.in b/src/Makefile.in
index 158b452..750a200 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -17,7 +17,7 @@ LIB=libhdf5.a
LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5E.c H5F.c H5Farray.c H5Fcore.c \
H5Ffamily.c H5Fistore.c H5Flow.c H5Fmpio.c H5Fsec2.c H5Fsplit.c \
H5Fstdio.c H5G.c H5Gent.c H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5I.c H5MF.c \
- H5MM.c H5O.c H5Oattr.c H5Ocomp.c H5Ocont.c H5Odtype.c H5Oefl.c \
+ H5MM.c H5O.c H5Oattr.c H5Ocomp.c H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c \
H5Olayout.c H5Omtime.c H5Oname.c H5Onull.c H5Osdspace.c H5Oshared.c \
H5Ostab.c H5P.c H5R.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Spoint.c \
H5Sselect.c H5T.c H5Tbit.c H5Tconv.c H5Tinit.c H5TB.c H5V.c H5Z.c
diff --git a/test/istore.c b/test/istore.c
index 7e3ef1d..468ee01 100644
--- a/test/istore.c
+++ b/test/istore.c
@@ -319,8 +319,8 @@ test_extend(H5F_t *f, const char *prefix,
memset(buf, (signed)(128+ctr), (size_t)nelmts);
/* Write to disk */
- if (H5F_arr_write(f, &H5D_xfer_dflt, &layout, NULL, NULL, size, size,
- zero, offset, buf)<0) {
+ if (H5F_arr_write(f, &H5D_xfer_dflt, &layout, NULL, NULL, NULL, size,
+ size, zero, offset, buf)<0) {
puts("*FAILED*");
if (!isatty(1)) {
AT();
@@ -330,8 +330,8 @@ test_extend(H5F_t *f, const char *prefix,
}
/* Read from disk */
memset(check, 0xff, (size_t)nelmts);
- if (H5F_arr_read(f, &H5D_xfer_dflt, &layout, NULL, NULL, size, size,
- zero, offset, check)<0) {
+ if (H5F_arr_read(f, &H5D_xfer_dflt, &layout, NULL, NULL, NULL, size,
+ size, zero, offset, check)<0) {
puts("*FAILED*");
if (!isatty(1)) {
AT();
@@ -366,7 +366,7 @@ test_extend(H5F_t *f, const char *prefix,
/* Now read the entire array back out and check it */
memset(buf, 0xff, nx * ny * nz);
- if (H5F_arr_read(f, &H5D_xfer_dflt, &layout, NULL, NULL, whole_size,
+ if (H5F_arr_read(f, &H5D_xfer_dflt, &layout, NULL, NULL, NULL, whole_size,
whole_size, zero, zero, buf)<0) {
puts("*FAILED*");
if (!isatty(1)) {
@@ -490,8 +490,8 @@ test_sparse(H5F_t *f, const char *prefix, size_t nblocks,
memset(buf, (signed)(128+ctr), nx * ny * nz);
/* write to disk */
- if (H5F_arr_write(f, &H5D_xfer_dflt, &layout, NULL, NULL, size, size,
- zero, offset, buf)<0) {
+ if (H5F_arr_write(f, &H5D_xfer_dflt, &layout, NULL, NULL, NULL, size,
+ size, zero, offset, buf)<0) {
puts("*FAILED*");
if (!isatty(1)) {
AT();
diff --git a/test/overhead.c b/test/overhead.c
new file mode 100644
index 0000000..785bfd7
--- /dev/null
+++ b/test/overhead.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 1998 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Robb Matzke <matzke@llnl.gov>
+ * Monday, September 28, 1998
+ *
+ * Purpose: Creates a chunked dataset and measures the storage overhead.
+ */
+#include <ctype.h>
+#include <fcntl.h>
+#include <hdf5.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <H5config.h>
+#ifndef HAVE_ATTRIBUTE
+# undef __attribute__
+# define __attribute__(X) /*void*/
+# define __unused__ /*void*/
+#else
+# define __unused__ __attribute__((unused))
+#endif
+
+#define FILE_NAME_1 "overhead.h5"
+#define FALSE 0
+#define TRUE 1
+
+typedef enum fill_t {
+ FILL_ALL,
+ FILL_FORWARD,
+ FILL_REVERSE,
+ FILL_INWARD,
+ FILL_OUTWARD,
+ FILL_RANDOM
+} fill_t;
+
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Prints a usage message and exits.
+ *
+ * Return: never returns
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, September 30, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+usage(const char *prog)
+{
+ fprintf(stderr, "usage: %s [STYLE|cache] [LEFT [MIDDLE [RIGHT]]]\n",
+ prog);
+ fprintf(stderr, "\
+ STYLE is the order that the dataset is filled and should be one of:\n\
+ forward -- Fill the dataset from lowest address to highest\n\
+ address. This style tests the right split ratio.\n\
+ reverse -- Fill the dataset from highest address to lowest\n\
+ address. This is the reverse order of `forward' and\n\
+ tests the left split ratio.\n\
+ inward -- Fill beginning at both the lowest and highest\n\
+ addresses and work in toward the center of the\n\
+ dataset. This tests the middle split ratio.\n\
+ outward -- Start at the center of the dataset and work outward\n\
+ toward the lowest and highest addresses. This tests\n\
+ both left and right split ratios.\n\
+ random -- Write the chunks of the dataset in random order. This\n\
+ tests all split ratios.\n\
+ If no fill style is specified then all fill styles are tried and a\n\
+ single value is printed for each one.\n\
+\n\
+ If the word `cache' is used instead of a fill style then the raw data\n\
+ cache is enabled. It is not possible to enable the raw data cache when\n\
+ a specific fill style is used because H5Fflush() is called after each\n\
+ chunk is written in order to calculate overhead during the test. If\n\
+ the cache is enabled then chunks are written to disk in different orders\n\
+ than the actual H5Dwrite() calls in the test due to collisions and the\n\
+ resulting B-tree will be split differently.\n\
+\n\
+ LEFT, MIDDLE, and RIGHT are the ratios to use for splitting and should\n\
+ be values between zero and one, inclusive.\n");
+ exit(1);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: cleanup
+ *
+ * Purpose: Removes test files
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Thursday, June 4, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+cleanup (void)
+{
+ if (!getenv ("HDF5_NOCLEANUP")) {
+ remove (FILE_NAME_1);
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: display_error_cb
+ *
+ * Purpose: Displays the error stack after printing "*FAILED*".
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, March 4, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+display_error_cb (void __unused__ *client_data)
+{
+ puts ("*FAILED*");
+ H5Eprint (stdout);
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test
+ *
+ * Purpose: The guts of the test
+ *
+ * Return: Success: 0
+ *
+ * Failure: number of errors
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, September 30, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test(fill_t fill_style, const double splits[],
+ hbool_t verbose, hbool_t use_rdcc)
+{
+ hid_t file, fapl, dcpl, xfer, mspace, fspace, dset;
+ hsize_t ch_size[1] = {1}; /*chunk size */
+ hsize_t cur_size[1] = {1000}; /*current dataset size */
+ hsize_t max_size[1] = {H5S_UNLIMITED}; /*maximum dataset size */
+ hssize_t hs_start[1]; /*hyperslab start offset*/
+ hsize_t hs_count[1] = {1}; /*hyperslab nelmts */
+ int fd; /*h5 file direct */
+ static int *had = NULL; /*for random filling */
+ const char *sname; /*fill style nam */
+ int mdc_nelmts; /*num meta objs to cache*/
+ hsize_t i;
+ int j;
+ struct stat sb;
+
+ if (!had) had = calloc(cur_size[0], sizeof(int));
+ if ((fapl=H5Pcreate(H5P_FILE_ACCESS))<0) goto error;
+ if (!use_rdcc) {
+ if (H5Pget_cache(fapl, &mdc_nelmts, NULL, NULL, NULL)<0) goto error;
+ if (H5Pset_cache(fapl, mdc_nelmts, 0, 0, 0.0)<0) goto error;
+ }
+ if ((file=H5Fcreate(FILE_NAME_1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) {
+ goto error;
+ }
+ if ((dcpl=H5Pcreate(H5P_DATASET_CREATE))<0) goto error;
+ if (H5Pset_chunk(dcpl, 1, ch_size)<0) goto error;
+ if ((xfer=H5Pcreate(H5P_DATASET_XFER))<0) goto error;
+ if (H5Pset_btree_ratios(xfer, splits[0], splits[1], splits[2])<0) {
+ goto error;
+ }
+ if ((fspace=H5Screate_simple(1, cur_size, max_size))<0) goto error;
+ if ((mspace=H5Screate_simple(1, ch_size, ch_size))<0) goto error;
+ if ((dset=H5Dcreate(file, "chunked", H5T_NATIVE_INT,
+ fspace, dcpl))<0) goto error;
+ if ((fd=open(FILE_NAME_1, O_RDONLY))<0) goto error;
+
+ for (i=1; i<=cur_size[0]; i++) {
+
+ /* Decide which chunk to write to */
+ switch (fill_style) {
+ case FILL_FORWARD:
+ hs_start[0] = i-1;
+ break;
+ case FILL_REVERSE:
+ hs_start[0] = cur_size[0]-i;
+ break;
+ case FILL_INWARD:
+ hs_start[0] = i%2 ? i/2 : cur_size[0]-i/2;
+ break;
+ case FILL_OUTWARD:
+ j = (cur_size[0]-i)+1;
+ hs_start[0] = j%2 ? j/2 : cur_size[0]-j/2;
+ break;
+ case FILL_RANDOM:
+ for (j=rand()%cur_size[0]; had[j]; j=(j+1)%cur_size[0]) /*void*/;
+ hs_start[0] = j;
+ had[j] = 1;
+ break;
+ case FILL_ALL:
+ abort();
+ }
+
+ /* Write the chunk */
+ if (H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_start, NULL,
+ hs_count, NULL)<0) goto error;
+ if (H5Dwrite(dset, H5T_NATIVE_INT, mspace, fspace, xfer, &i)<0) {
+ goto error;
+ }
+
+ /* Determine overhead */
+ if (verbose) {
+ if (H5Fflush(file)<0) goto error;
+ if (fstat(fd, &sb)<0) goto error;
+ printf("%4lu %8.3f\n",
+ (unsigned long)i,
+ (double)(sb.st_size-i*sizeof(int))/(double)i);
+ }
+ }
+
+ H5Dclose(dset);
+ H5Sclose(mspace);
+ H5Sclose(fspace);
+ H5Pclose(dcpl);
+ H5Fclose(file);
+
+ if (!verbose) {
+ switch (fill_style) {
+ case FILL_FORWARD:
+ sname = "forward";
+ break;
+ case FILL_REVERSE:
+ sname = "reverse";
+ break;
+ case FILL_INWARD:
+ sname = "inward";
+ break;
+ case FILL_OUTWARD:
+ sname = "outward";
+ break;
+ case FILL_RANDOM:
+ sname = "random";
+ break;
+ case FILL_ALL:
+ abort();
+ }
+ if (fstat(fd, &sb)<0) goto error;
+ printf("%-7s %8.3f\n", sname,
+ (sb.st_size-cur_size[0]*sizeof(int))/(double)cur_size[0]);
+
+ }
+ close(fd);
+ return 0;
+
+ error:
+ H5Dclose(dset);
+ H5Sclose(mspace);
+ H5Sclose(fspace);
+ H5Pclose(dcpl);
+ H5Fclose(file);
+ free(had);
+ close(fd);
+ return 1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose:
+ *
+ * Return: Success: zero
+ *
+ * Failure: non-zero
+ *
+ * Programmer: Robb Matzke
+ * Monday, September 28, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(int argc, char *argv[])
+{
+ hid_t xfer;
+ fill_t fill_style = FILL_ALL;
+ hbool_t use_cache = FALSE;
+ double splits[3];
+ int i, j, nerrors=0;
+
+ /* Default split ratios */
+ H5Eset_auto(display_error_cb, NULL);
+ if ((xfer=H5Pcreate(H5P_DATASET_XFER))<0) goto error;
+ if (H5Pget_btree_ratios(xfer, splits+0, splits+1, splits+2)<0) {
+ goto error;
+ }
+ if (H5Pclose(xfer)<0) goto error;
+
+ /* Parse command-line options */
+ for (i=1, j=0; i<argc; i++) {
+ if (!strcmp(argv[i], "forward")) {
+ fill_style = FILL_FORWARD;
+ } else if (!strcmp(argv[i], "reverse")) {
+ fill_style = FILL_REVERSE;
+ } else if (!strcmp(argv[i], "inward")) {
+ fill_style = FILL_INWARD;
+ } else if (!strcmp(argv[i], "outward")) {
+ fill_style = FILL_OUTWARD;
+ } else if (!strcmp(argv[i], "random")) {
+ fill_style = FILL_RANDOM;
+ } else if (!strcmp(argv[i], "cache")) {
+ use_cache = TRUE;
+ } else if (j<3 && (isdigit(argv[i][0]) || '.'==argv[i][0])) {
+ splits[j++] = strtod(argv[i], NULL);
+ } else {
+ usage(argv[0]);
+ }
+ }
+
+ if (FILL_ALL==fill_style) {
+ printf("%-7s %8s\n", "Style", "Bytes/Chunk");
+ printf("%-7s %8s\n", "-----", "-----------");
+ nerrors += test(FILL_FORWARD, splits, FALSE, use_cache);
+ nerrors += test(FILL_REVERSE, splits, FALSE, use_cache);
+ nerrors += test(FILL_INWARD, splits, FALSE, use_cache);
+ nerrors += test(FILL_OUTWARD, splits, FALSE, use_cache);
+ nerrors += test(FILL_RANDOM, splits, FALSE, use_cache);
+ } else {
+ if (use_cache) usage(argv[0]);
+ nerrors += test(fill_style, splits, TRUE, FALSE);
+ }
+ if (nerrors>0) goto error;
+ cleanup();
+ return 0;
+
+ error:
+ fprintf(stderr, "*** ERRORS DETECTED ***\n");
+ return 1;
+}