summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--c++/test/dsets.cpp33
-rw-r--r--c++/test/tfilter.cpp45
-rw-r--r--src/H5B2private.h1
-rw-r--r--src/H5Dint.c31
-rw-r--r--src/H5Dio.c109
-rw-r--r--src/H5Distore.c283
-rw-r--r--src/H5Dpkg.h6
-rw-r--r--src/H5Dprivate.h2
-rw-r--r--src/H5HFcache.c4
-rw-r--r--src/H5HFhuge.c4
-rw-r--r--src/H5Odtype.c2
-rw-r--r--src/H5Opline.c78
-rw-r--r--src/H5Pdcpl.c2
-rw-r--r--src/H5T.c5
-rw-r--r--src/H5Tcommit.c32
-rw-r--r--src/H5Tprivate.h1
-rw-r--r--src/H5V.c8
-rw-r--r--src/H5Z.c289
-rw-r--r--src/H5Zdeflate.c49
-rw-r--r--src/H5Zdtype_modify.c1316
-rw-r--r--src/H5Zfletcher32.c41
-rw-r--r--src/H5Znbit.c40
-rw-r--r--src/H5Zprivate.h8
-rw-r--r--src/H5Zpublic.h55
-rw-r--r--src/H5Zscaleoffset.c33
-rw-r--r--src/H5Zshuffle.c47
-rw-r--r--src/H5Zszip.c47
-rw-r--r--src/H5vers.txt5
-rw-r--r--src/H5version.h64
-rw-r--r--test/change_dtypes.c91
-rw-r--r--test/cmpd_dset.c443
-rw-r--r--test/dsets.c153
-rw-r--r--tools/h5dump/h5dumpgentest.c83
33 files changed, 3064 insertions, 346 deletions
diff --git a/c++/test/dsets.cpp b/c++/test/dsets.cpp
index 97ba6ca..c921123 100644
--- a/c++/test/dsets.cpp
+++ b/c++/test/dsets.cpp
@@ -59,8 +59,13 @@ const H5std_string DSET_BOGUS_NAME ("bogus");
const int H5Z_FILTER_BOGUS = 305;
// Local prototypes
+#ifndef H5_USE_16_API
+static size_t filter_bogus(unsigned int flags, hsize_t chunk_offset, size_t cd_nelmts,
+ const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf);
+#else
static size_t filter_bogus(unsigned int flags, size_t cd_nelmts,
const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf);
+#endif
/*-------------------------------------------------------------------------
@@ -352,6 +357,7 @@ test_tconv( H5File& file)
} // test_tconv
/* This message derives from H5Z */
+#ifndef H5_USE_16_API
const H5Z_class_t H5Z_BOGUS[1] = {{
H5Z_CLASS_T_VERS, /* H5Z_class_t version number */
H5Z_FILTER_BOGUS, /* Filter id number */
@@ -359,9 +365,23 @@ const H5Z_class_t H5Z_BOGUS[1] = {{
"bogus", /* Filter name for debugging */
NULL, /* The "can apply" callback */
NULL, /* The "set local" callback */
- NULL, /* The "reset local" callback */
+ NULL, /* The "reset local" callback */
+ NULL, /* The "change local" callback */
+ NULL, /* The "evict local" callback */
+ NULL, /* The "delete local" callback */
+ NULL, /* The "close local" callback */
+ (H5Z_func_t)filter_bogus, /* The actual filter function */
+}};
+#else
+const H5Z_class_t H5Z_BOGUS[1] = {{
+ H5Z_CLASS_T_VERS, /* H5Z_class_t version number */
+ H5Z_FILTER_BOGUS, /* Filter id number */
+ "bogus", /* Filter name for debugging */
+ NULL, /* The "can apply" callback */
+ NULL, /* The "set local" callback */
(H5Z_func_t)filter_bogus, /* The actual filter function */
}};
+#endif
/*-------------------------------------------------------------------------
* Function: bogus
@@ -379,14 +399,19 @@ const H5Z_class_t H5Z_BOGUS[1] = {{
*
*-------------------------------------------------------------------------
*/
+#ifndef H5_USE_16_API
static size_t
/*bogus(unsigned int UNUSED flags, size_t UNUSED cd_nelmts,
const unsigned int UNUSED cd_values[], size_t nbytes,
size_t UNUSED *buf_size, void UNUSED **buf)
BMR: removed UNUSED for now until asking Q. or R. to pass compilation*/
-filter_bogus(unsigned int flags, size_t cd_nelmts,
- const unsigned int cd_values[], size_t nbytes,
- size_t *buf_size, void **buf)
+filter_bogus(unsigned int flags, hsize_t chunk_offset, size_t cd_nelmts,
+ const unsigned int cd_values[], size_t nbytes, size_t *buf_size, void **buf)
+#else
+static size_t
+filter_bogus(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[],
+ size_t nbytes, size_t *buf_size, void **buf)
+#endif
{
return nbytes;
}
diff --git a/c++/test/tfilter.cpp b/c++/test/tfilter.cpp
index a667f2a..b88e122 100644
--- a/c++/test/tfilter.cpp
+++ b/c++/test/tfilter.cpp
@@ -57,7 +57,8 @@ static herr_t test_filter_internal(hid_t fid, const char *name, hid_t dcpl,
/* Temporary filter IDs used for testing */
#define H5Z_FILTER_BOGUS 305
-static size_t filter_bogus(unsigned int flags, size_t cd_nelmts,
+#ifndef H5_USE_16_API
+static size_t filter_bogus(unsigned int flags, hsize_t UNUSED chunk_offset, size_t cd_nelmts,
const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf);
/* This message derives from H5Z */
const H5Z_class_t H5Z_BOGUS[1] = {{
@@ -68,6 +69,46 @@ const H5Z_class_t H5Z_BOGUS[1] = {{
NULL, /* The "can apply" callback */
NULL, /* The "set local" callback */
NULL, /* The "reset local" callback */
+ NULL, /* The "change local" callback */
+ NULL, /* The "evict local" callback */
+ NULL, /* The "delete local" callback */
+ NULL, /* The "close local" callback */
+ (H5Z_func_t)filter_bogus, /* The actual filter function */
+}};
+
+/*-------------------------------------------------------------------------
+ * Function: filter_bogus
+ *
+ * Purpose: A bogus compression method that doesn't do anything.
+ *
+ * Return: Success: Data chunk size
+ *
+ * Failure: 0
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, April 21, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+filter_bogus(unsigned int UNUSED flags, hsize_t UNUSED chunk_offset, size_t UNUSED cd_nelmts,
+ const unsigned int UNUSED *cd_values, size_t nbytes, size_t UNUSED *buf_size,
+ void UNUSED **buf)
+{
+ return nbytes;
+}
+#else
+static size_t filter_bogus(unsigned int flags, size_t cd_nelmts,
+ const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf);
+/* This message derives from H5Z */
+const H5Z_class_t H5Z_BOGUS[1] = {{
+ H5Z_CLASS_T_VERS, /* H5Z_class_t version */
+ H5Z_FILTER_BOGUS, /* Filter id number */
+ "bogus", /* Filter name for debugging */
+ NULL, /* The "can apply" callback */
+ NULL, /* The "set local" callback */
(H5Z_func_t)filter_bogus, /* The actual filter function */
}};
@@ -95,6 +136,8 @@ filter_bogus(unsigned int UNUSED flags, size_t UNUSED cd_nelmts,
return nbytes;
}
+#endif
+
/*-------------------------------------------------------------------------
* Function: test_null_filter
*
diff --git a/src/H5B2private.h b/src/H5B2private.h
index 6d8172c..db2e785 100644
--- a/src/H5B2private.h
+++ b/src/H5B2private.h
@@ -54,6 +54,7 @@ typedef enum H5B2_subid_t {
H5B2_SOHM_INDEX_ID, /* B-tree is an index for shared object header messages */
H5B2_ATTR_DENSE_NAME_ID, /* B-tree is for indexing 'name' field for "dense" attribute storage on objects */
H5B2_ATTR_DENSE_CORDER_ID, /* B-tree is for indexing 'creation order' field for "dense" attribute storage on objects */
+ H5B2_MODIFY_TYPE_ID, /* B-tree is for indexing 'datatype' field for filter of modifying datatype */
H5B2_NUM_BTREE_ID /* Number of B-tree IDs (must be last) */
} H5B2_subid_t;
diff --git a/src/H5Dint.c b/src/H5Dint.c
index 272b00a..6a636db 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -1228,6 +1228,7 @@ H5D_open(const H5G_loc_t *loc, hid_t dxpl_id)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINC, NULL, "can't increment object count")
} /* end else */
+#ifndef H5_USE_16_API
/* Get a file ID for the file */
if((fid = H5F_get_id(dataset->oloc.file)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "unable to get file ID")
@@ -1236,11 +1237,11 @@ H5D_open(const H5G_loc_t *loc, hid_t dxpl_id)
* Make the "reset local" filter callbacks for this dataset. It's mainly for some filters
* like datatype modification which need some info after the dataset is reopened.
* If the library has been closed and reopened, the user-defined filters aren't
- * registered in the library anymore. This function for those filters can't be
+ * registered in the library anymore. This function is for those filters can't be
* found and may fail. Therefore ignore the error if it's this case.
*/
H5E_BEGIN_TRY {
- H5Z_reset_local(dataset->shared->dcpl_id, dataset->shared->type_id, fid);
+ H5Z_reset_local(dataset->shared->dcpl_id, dataset->shared->type_id, fid, TRUE);
} H5E_END_TRY;
/* Release the file ID */
@@ -1248,6 +1249,7 @@ H5D_open(const H5G_loc_t *loc, hid_t dxpl_id)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEFILE, NULL, "can't close file")
fid = -1;
+#endif
ret_value = dataset;
@@ -1519,6 +1521,7 @@ done:
herr_t
H5D_close(H5D_t *dataset)
{
+ hid_t fid;
unsigned free_failed = FALSE;
herr_t ret_value = SUCCEED; /* Return value */
@@ -1533,6 +1536,10 @@ H5D_close(H5D_t *dataset)
H5D_istore_stats(dataset, FALSE);
#endif /* H5F_ISTORE_DEBUG */
+ /* Get a file ID for the file */
+ if((fid = H5F_get_id(dataset->oloc.file)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "unable to get file ID")
+
dataset->shared->fo_count--;
if(dataset->shared->fo_count == 0) {
/* Flush the dataset's information */
@@ -1588,6 +1595,12 @@ H5D_close(H5D_t *dataset)
#endif /* NDEBUG */
} /* end switch */ /*lint !e788 All appropriate cases are covered */
+#ifndef H5_USE_16_API
+ H5E_BEGIN_TRY {
+ H5Z_close_local(dataset->shared->dcpl_id, dataset->shared->type_id, fid);
+ } H5E_END_TRY;
+#endif
+
/*
* Release datatype, dataspace and creation property list -- there isn't
* much we can do if one of these fails, so we just continue.
@@ -1625,8 +1638,18 @@ H5D_close(H5D_t *dataset)
if(H5FO_top_count(dataset->oloc.file, dataset->oloc.addr) == 0)
if(H5O_close(&(dataset->oloc)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to close")
+
+ H5E_BEGIN_TRY {
+ H5Z_close_local(dataset->shared->dcpl_id, dataset->shared->type_id, fid);
+ } H5E_END_TRY;
} /* end else */
+ /* Release the file ID */
+ if(H5I_dec_ref(fid) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEFILE, NULL, "can't close file")
+
+ fid = -1;
+
/* Release the dataset's path info */
if(H5G_name_free(&(dataset->path)) < 0)
free_failed = TRUE;
@@ -2277,13 +2300,13 @@ H5D_check_filters(H5D_t *dataset)
if(H5Z_can_apply(dataset->shared->dcpl_id, dataset->shared->type_id, fid) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "can't apply filters")
- dataset->shared->checked_filters = TRUE;
-
/* Release the file ID */
if(H5I_dec_ref(fid) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEFILE, NULL, "can't close file")
fid = -1;
+
+ dataset->shared->checked_filters = TRUE;
} /* end if */
} /* end if */
} /* end if */
diff --git a/src/H5Dio.c b/src/H5Dio.c
index e05836d..dcc15bf 100644
--- a/src/H5Dio.c
+++ b/src/H5Dio.c
@@ -1449,8 +1449,15 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts,
store.chunk.offset = chunk_info->coords;
store.chunk.index = chunk_info->index;
- /* Load the chunk into cache and lock it. */
chunk_addr = H5D_istore_get_addr(io_info, &udata);
+
+ /* Translate the offset of the chunck into single-dimensional offset for
+ * the filter of modifying dataset's datatype */
+ if((io_info->store->chunk.linear_offset = H5D_istore_calc_offset(
+ dataset->shared->space, io_info->store->chunk.offset)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to calculate chunk offset")
+
+ /* Load the chunk into cache and lock it. */
if(H5D_istore_if_load(io_info, chunk_addr)) {
if(NULL == (chunk = H5D_istore_lock(io_info, &udata, FALSE, &idx_hint)))
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
@@ -1573,6 +1580,12 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts,
/* Load the chunk into cache and lock it. */
chunk_addr = H5D_istore_get_addr(io_info, &udata);
+ /* Translate the offset of the chunck into single-dimensional offset for
+ * the filter of modifying dataset's datatype */
+ if((io_info->store->chunk.linear_offset = H5D_istore_calc_offset(
+ dataset->shared->space, io_info->store->chunk.offset)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to calculate chunk offset")
+
if(H5D_istore_if_load(io_info, chunk_addr)) {
if(NULL == (chunk = H5D_istore_lock(io_info, &udata, FALSE, &idx_hint)))
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
@@ -1782,6 +1795,8 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts,
H5D_istore_ud1_t udata; /*B-tree pass-through */
unsigned idx_hint = 0; /* Cache index hint */
hbool_t relax=TRUE; /* Whether whole chunk is selected */
+ hbool_t has_mdtype_filter=FALSE;/* Whether filter for modifying dset's dtype
+ * is enabled */
herr_t ret_value = SUCCEED; /*return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_write)
@@ -1810,6 +1825,23 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts,
dst_type_size = H5T_get_size(dataset->shared->type);
max_type_size = MAX(src_type_size, dst_type_size);
+ /* If the filter for modifying dataset's datatype is enabled, don't relax
+ * because we need the offset of the chunk to pass through H5Z_pipeline. */
+ if(dataset->shared->dcpl_id != H5P_DATASET_CREATE_DEFAULT) {
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret = SUCCEED; /* Return value */
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(dataset->shared->dcpl_id, H5P_DATASET_CREATE)))
+ HGOTO_ERROR(H5E_DATASET, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ H5E_BEGIN_TRY {
+ ret = H5P_get_filter_by_id(plist, H5Z_FILTER_DTYPE_MODIFY, NULL, NULL, NULL, (size_t)0, NULL, NULL);
+ } H5E_END_TRY;
+
+ if(ret >= 0)
+ has_mdtype_filter = TRUE;
+ } /* end if */
+
/*
* If there is no type conversion then write directly from the
* application's buffer. This saves at least one mem-to-mem copy.
@@ -1851,9 +1883,15 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts,
* simply allocate space instead of load the chunk. */
chunk_addr = H5D_istore_get_addr(io_info, &udata);
+ /* Translate the offset of the chunck into single-dimensional offset for
+ * the filter of modifying dataset's datatype */
+ if((io_info->store->chunk.linear_offset = H5D_istore_calc_offset(
+ dataset->shared->space, io_info->store->chunk.offset)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to calculate chunk offset")
+
if(H5D_istore_if_load(io_info, chunk_addr)) {
accessed_bytes = chunk_info->chunk_points * dst_type_size;
- if(accessed_bytes != dataset->shared->layout.u.chunk.size)
+ if(has_mdtype_filter || accessed_bytes != dataset->shared->layout.u.chunk.size)
relax = FALSE;
if(NULL == (chunk = H5D_istore_lock(io_info, &udata, relax, &idx_hint)))
@@ -1977,6 +2015,12 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts,
store.chunk.offset = chunk_info->coords;
store.chunk.index = chunk_info->index;
+ /* Translate the offset of the chunck into single-dimensional offset for
+ * the filter of modifying dataset's datatype */
+ if((io_info->store->chunk.linear_offset = H5D_istore_calc_offset(
+ dataset->shared->space, io_info->store->chunk.offset)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to calculate chunk offset")
+
/* Load the chunk into cache. But if the whole chunk is written,
* simply allocate space instead of load the chunk. */
chunk_addr = H5D_istore_get_addr(io_info, &udata);
@@ -1987,7 +2031,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts,
relax=FALSE;
if(relax) {
accessed_bytes = H5S_GET_SELECT_NPOINTS(chunk_info->mspace) * src_type_size;
- if(accessed_bytes != dataset->shared->layout.u.chunk.size)
+ if(has_mdtype_filter || accessed_bytes != dataset->shared->layout.u.chunk.size)
relax = FALSE;
}
@@ -2381,7 +2425,7 @@ H5Dmodify_dtype(hid_t dset_id, hid_t new_type_id)
H5D_t *dset = NULL;
H5T_t *new_type = NULL;
- herr_t ret_value;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_API(H5Dmodify_dtype, FAIL)
H5TRACE2("e", "ii", dset_id, new_type_id);
@@ -2465,13 +2509,31 @@ H5D_modify_dtype(H5F_t *file, H5D_t *dataset, hid_t type_id, H5T_t *type, hid_t
HGOTO_ERROR(H5E_DATASET, H5E_BADATOM, FAIL, "can't find object for ID")
H5E_BEGIN_TRY {
- ret = H5P_get_filter_by_id(plist, H5Z_FILTER_DTYPE_MODIFY, NULL, NULL, NULL, (size_t)0, NULL, NULL);
+ ret = H5P_get_filter_by_id(plist, H5Z_FILTER_DTYPE_MODIFY, NULL, NULL,
+ NULL, (size_t)0, NULL, NULL);
} H5E_END_TRY;
if(ret >= 0)
filter_enabled = TRUE;
} /* end if */
+ /* If the filter is present, generally only support committed or shared datatype.
+ * We also allow integer or floating number because of their limited encoding size.
+ */
+ if(filter_enabled && !H5T_committed(type) &&
+ !H5SM_can_share(file, dxpl_id, NULL, NULL, H5O_DTYPE_ID, type)) {
+ H5T_class_t tclass;
+ if((tclass = H5T_get_class(type, TRUE)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "can't find datatype class")
+
+ if(tclass != H5T_INTEGER && tclass != H5T_FLOAT)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "violate datatype restriction")
+ }
+
+ /* Check if the datatype should be (or are already) shared in the SOHM table */
+ if(H5SM_try_share(file, dxpl_id, NULL, H5O_DTYPE_ID, dataset->shared->type, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADMESG, FAIL, "trying to share datatype failed")
+
/* If space hasn't been allocated and not using external storage,
* set the flag HAS_DATA to FALSE. If the dataset is compact,
* the flag is always TRUE.
@@ -2526,30 +2588,29 @@ H5D_modify_dtype(H5F_t *file, H5D_t *dataset, hid_t type_id, H5T_t *type, hid_t
default:
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "dataset should be contiguous or chunked")
}
+ } else if(filter_enabled && has_data && H5D_CHUNKED == dataset->shared->layout.type) {
+ /* Convert the chunks already in the cache */
+ if(H5D_istore_conv_dtype(dataset, type_id) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTCONVERT, FAIL, "can't convert data cache")
}
/* Get a file ID for the file */
if((fid = H5F_get_id(file)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get file ID")
- /* Copy & initialize datatype for the dataset struct */
- if(H5D_init_type(file, dataset, type_id, type) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't copy datatype")
-
- /* Check if the datatype should be (or are already) shared in the SOHM table */
- if(H5SM_try_share(file, dxpl_id, NULL, H5O_DTYPE_ID, dataset->shared->type, NULL) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_BADMESG, FAIL, "trying to share datatype failed")
-
/*
- * Check whether datatype is committed & increment ref count. (to maintain
- * ref. count incr/decr similarity with "shared message" type of datatype sharing)
+ * Check whether the old datatype is committed & decrement ref count.
*/
if(H5T_committed(dataset->shared->type)) {
- /* Increment the reference count on the shared datatype */
- if(H5T_link(dataset->shared->type, 1, dxpl_id) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count")
+ /* Decrement the reference count on the committed datatype */
+ if(H5T_link(dataset->shared->type, -1, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_LINKCOUNT, FAIL, "unable to adjust committed datatype link count")
} /* end if */
+ /* Copy & initialize datatype for the dataset struct */
+ if(H5D_init_type(file, dataset, type_id, type) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't copy datatype")
+
/* Open the object header of the original dataset for updating datatype and layout */
if(H5O_open(&(dataset->oloc)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to open dataset object header")
@@ -2561,8 +2622,8 @@ H5D_modify_dtype(H5F_t *file, H5D_t *dataset, hid_t type_id, H5T_t *type, hid_t
/* Delete the old datatype message */
if(H5O_msg_remove(&(dataset->oloc), H5O_DTYPE_ID, 0, FALSE, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to delete old dtype message")
-
- /* Add the new datatype message */
+
+ /* Add the new datatype message. Ref count for committed dtype is incremented here. */
if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_DTYPE_ID, H5O_MSG_FLAG_CONSTANT, 0, dataset->shared->type) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update datatype header message")
@@ -2606,7 +2667,9 @@ H5D_modify_dtype(H5F_t *file, H5D_t *dataset, hid_t type_id, H5T_t *type, hid_t
* allocation time is early, since space may not be allocated)
*/
fill_prop = &(dataset->shared->dcpl_cache.fill);
- if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_LAYOUT_ID, ((fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY && H5D_COMPACT != dataset->shared->layout.type) ? H5O_MSG_FLAG_CONSTANT : 0), 0, &(dataset->shared->layout)) < 0)
+ if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_LAYOUT_ID,
+ ((fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY && H5D_COMPACT != dataset->shared->layout.type) ? H5O_MSG_FLAG_CONSTANT : 0),
+ 0, &(dataset->shared->layout)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout")
/*
@@ -2666,7 +2729,7 @@ H5D_modify_dtype(H5F_t *file, H5D_t *dataset, hid_t type_id, H5T_t *type, hid_t
HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to close dataset")
} else if(filter_enabled) {
/* Make the "reset local" filter callbacks for this dataset */
- if(H5Z_reset_local(dataset->shared->dcpl_id, dataset->shared->type_id, fid) < 0)
+ if(H5Z_reset_local(dataset->shared->dcpl_id, dataset->shared->type_id, fid, FALSE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set local filter parameters")
/* Release the file ID */
@@ -2675,7 +2738,7 @@ H5D_modify_dtype(H5F_t *file, H5D_t *dataset, hid_t type_id, H5T_t *type, hid_t
fid = -1;
}
-
+
done:
/* Release the file ID */
if(fid>=0 && H5I_dec_ref(fid) < 0)
diff --git a/src/H5Distore.c b/src/H5Distore.c
index 2d47a5a..bc265c6 100644
--- a/src/H5Distore.c
+++ b/src/H5Distore.c
@@ -123,6 +123,7 @@ typedef struct H5D_rdcc_ent_t {
size_t alloc_size; /*amount allocated for the chunk */
uint8_t *chunk; /*the unfiltered chunk data */
unsigned idx; /*index in hash table */
+ hssize_t linear_offset; /* Chunk's coordinates translated into one-dimensional offset */
struct H5D_rdcc_ent_t *next;/*next item in doubly-linked list */
struct H5D_rdcc_ent_t *prev;/*previous item in doubly-linked list */
} H5D_rdcc_ent_t;
@@ -752,6 +753,8 @@ H5D_istore_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
int cmp;
unsigned u;
H5B_ins_t ret_value;
+
+ htri_t dis = FALSE;
FUNC_ENTER_NOAPI_NOINIT(H5D_istore_insert)
@@ -811,12 +814,15 @@ H5D_istore_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
ret_value = H5B_INS_NOOP;
}
- } else if (H5V_hyper_disjointp(udata->common.mesg->u.chunk.ndims,
+ } else if ((dis = H5V_hyper_disjointp(udata->common.mesg->u.chunk.ndims,
lt_key->offset, udata->common.mesg->u.chunk.dim,
- udata->common.offset, udata->common.mesg->u.chunk.dim)) {
- HDassert(H5V_hyper_disjointp(udata->common.mesg->u.chunk.ndims,
+ udata->common.offset, udata->common.mesg->u.chunk.dim)) == TRUE) {
+
+ dis = H5V_hyper_disjointp(udata->common.mesg->u.chunk.ndims,
rt_key->offset, udata->common.mesg->u.chunk.dim,
- udata->common.offset, udata->common.mesg->u.chunk.dim));
+ udata->common.offset, udata->common.mesg->u.chunk.dim);
+ HDassert(dis);
+
/*
* Split this node, inserting the new new node to the right of the
* current node. The MD_KEY is where the split occurs.
@@ -993,6 +999,7 @@ H5D_istore_iter_copy(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key,
H5Z_EDC_t edc_read = H5Z_NO_EDC;
size_t nbytes = lt_key->nbytes;
H5Z_cb_t cb_struct;
+ hsize_t linear_offset = 0; /* No real use */
int ret_value = H5_ITER_CONT; /* Return value */
@@ -1042,7 +1049,8 @@ H5D_istore_iter_copy(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key,
if(is_compressed && (is_vlen || fix_ref)) {
unsigned filter_mask = lt_key->filter_mask;
- if(H5Z_pipeline(pline, H5Z_FLAG_REVERSE, &filter_mask, edc_read, cb_struct, &nbytes, &buf_size, &buf) < 0)
+ if(H5Z_pipeline(pline, H5Z_FLAG_REVERSE, &filter_mask, edc_read, linear_offset,
+ cb_struct, &nbytes, &buf_size, &buf) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, H5_ITER_ERROR, "data pipeline read failed")
} /* end if */
@@ -1103,7 +1111,7 @@ H5D_istore_iter_copy(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key,
/* Need to compress variable-length & reference data elements before writing to file */
if(is_compressed && (is_vlen || fix_ref) ) {
- if(H5Z_pipeline(pline, 0, &(udata_dst.filter_mask), edc_read,
+ if(H5Z_pipeline(pline, 0, &(udata_dst.filter_mask), edc_read, linear_offset,
cb_struct, &nbytes, &buf_size, &buf) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, H5_ITER_ERROR, "output pipeline failed")
udata_dst.nbytes = nbytes;
@@ -1147,6 +1155,7 @@ H5D_istore_iter_copy_conv(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key,
H5D_istore_it_ud4_t *udata = (H5D_istore_it_ud4_t *)_udata;
const H5D_istore_key_t *lt_key = (const H5D_istore_key_t *)_lt_key;
H5D_istore_ud1_t udata_dst; /* User data about new destination chunk */
+ hsize_t linear_offset = 0; /* No real use */
/* General information about chunk copy */
void *bkg = udata->bkg;
@@ -1206,7 +1215,7 @@ H5D_istore_iter_copy_conv(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key,
if(is_compressed) {
unsigned filter_mask = lt_key->filter_mask;
- if(H5Z_pipeline(pline, H5Z_FLAG_REVERSE, &filter_mask, edc_read, cb_struct, &src_nbytes, &buf_size, &buf) < 0)
+ if(H5Z_pipeline(pline, H5Z_FLAG_REVERSE, &filter_mask, edc_read, linear_offset, cb_struct, &src_nbytes, &buf_size, &buf) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, H5_ITER_ERROR, "data pipeline read failed")
} /* end if */
@@ -1230,7 +1239,7 @@ H5D_istore_iter_copy_conv(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key,
/* Need to compress variable-length & reference data elements before writing to file */
if(is_compressed) {
- if(H5Z_pipeline(pline, 0, &(udata_dst.filter_mask), edc_read,
+ if(H5Z_pipeline(pline, 0, &(udata_dst.filter_mask), edc_read, linear_offset,
cb_struct, &dst_nbytes, &buf_size, &buf) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, H5_ITER_ERROR, "output pipeline failed")
udata->buf = buf;
@@ -1251,7 +1260,7 @@ H5D_istore_iter_copy_conv(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key,
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_istore_iter_copy() */
+} /* end H5D_istore_iter_copy_conv() */
/*-------------------------------------------------------------------------
@@ -1452,7 +1461,6 @@ H5D_istore_flush_entry(const H5D_io_info_t *io_info, H5D_rdcc_ent_t *ent, hbool_
udata.nbytes = ent->chunk_size;
udata.addr = HADDR_UNDEF;
- /* Should the chunk be filtered before writing it to disk? */
if(io_info->dset->shared->dcpl_cache.pline.nused) {
if(!reset) {
/*
@@ -1476,8 +1484,11 @@ H5D_istore_flush_entry(const H5D_io_info_t *io_info, H5D_rdcc_ent_t *ent, hbool_
point_of_no_return = TRUE;
ent->chunk = NULL;
} /* end else */
- if(H5Z_pipeline(&(io_info->dset->shared->dcpl_cache.pline), 0, &(udata.filter_mask), io_info->dxpl_cache->err_detect,
- io_info->dxpl_cache->filter_cb, &(udata.nbytes), &alloc, &buf) < 0)
+
+ if(H5Z_pipeline(&(io_info->dset->shared->dcpl_cache.pline), 0,
+ &(udata.filter_mask), io_info->dxpl_cache->err_detect,
+ (hsize_t)ent->linear_offset, io_info->dxpl_cache->filter_cb,
+ &(udata.nbytes), &alloc, &buf) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, FAIL, "output pipeline failed")
} /* end if */
@@ -1546,6 +1557,7 @@ static herr_t
H5D_istore_preempt(const H5D_io_info_t *io_info, H5D_rdcc_ent_t * ent, hbool_t flush)
{
H5D_rdcc_t *rdcc = &(io_info->dset->shared->cache.chunk);
+ hid_t dcpl_id = io_info->dset->shared->dcpl_id;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_istore_preempt)
@@ -1566,6 +1578,9 @@ H5D_istore_preempt(const H5D_io_info_t *io_info, H5D_rdcc_ent_t * ent, hbool_t f
ent->chunk = (uint8_t *)H5D_istore_chunk_xfree(ent->chunk, &(io_info->dset->shared->dcpl_cache.pline));
} /* end else */
+ if(H5Z_evict_local(dcpl_id, /*unused*/0, /*unused*/0, (hsize_t)ent->linear_offset) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "failed to evict local filter info")
+
/* Unlink from list */
if(ent->prev)
ent->prev->next = ent->next;
@@ -1644,6 +1659,174 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D_istore_conv_dtype
+ *
+ * Purpose: Convert all the chunks in the cache if the datatype for
+ * dataset has been changed (called by H5Dmodify_dtype).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * 16 April 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_istore_conv_dtype(H5D_t *dset, hid_t new_type_id)
+{
+ H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk);
+ const H5O_pline_t *pline = &(dset->shared->dcpl_cache.pline); /* I/O pipeline info */
+ H5D_rdcc_ent_t *ent, *next;
+ hid_t orig_type_id = dset->shared->type_id;
+ H5T_t *new_type, *orig_type;
+ H5T_t *new_type_copy;
+ hid_t new_type_copy_id;
+ size_t orig_type_size, new_type_size;
+ size_t nelmts;
+ unsigned char *new_chunk = NULL;
+ unsigned char *bkg=NULL; /* Pointer to background buffer */
+ H5T_path_t *tpath=NULL; /*type conversion info */
+ herr_t ret_value = SUCCEED; /* Return value */
+ htri_t is_vlen = FALSE;
+ hbool_t vlen_conv = FALSE;
+ hid_t dxpl_id;
+ H5P_genplist_t *def_dx_plist = NULL, *dx_plist = NULL;
+
+ FUNC_ENTER_NOAPI(H5D_istore_conv_dtype, FAIL)
+
+ /* If there's no chunks in the cache, skip this function */
+ if(!rdcc->head)
+ HGOTO_DONE(SUCCEED);
+
+ /* The current datatype of the dataset */
+ if(NULL==(orig_type=(H5T_t *)H5I_object_verify(orig_type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+
+ /* The new datatype of the dataset */
+ if(NULL==(new_type=(H5T_t *)H5I_object_verify(new_type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+
+ /* Make a copy of the new datatype to avoid changing the original new type */
+ if(NULL==(new_type_copy=H5T_copy(new_type, H5T_COPY_ALL)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy data type");
+
+ if((new_type_copy_id = H5I_register(H5I_DATATYPE, new_type_copy)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype atom")
+
+ /* Mark the new datatype as being on disk now because the data in the cache
+ * hasn't been converted to memory type yet. */
+ if(H5T_set_loc(new_type_copy, dset->oloc.file, H5T_LOC_DISK) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't set datatype location")
+
+ /* Get the object of default dataset creation property list */
+ if(NULL == (def_dx_plist = (H5P_genplist_t *)H5I_object(H5P_DATASET_XFER_DEFAULT)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get dataset creation property list")
+
+ /* Create a new default property list */
+ if((dxpl_id = H5P_copy_plist(def_dx_plist)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy dataset creation property list")
+
+ if(NULL == (dx_plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get dataset creation property list")
+
+ /* If the datatype is or contains vlen, set the property to indicate no conversion
+ * is needed. */
+ if((is_vlen = H5T_detect_class(orig_type, H5T_VLEN)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to detect dtatypes")
+
+ if(is_vlen ) {
+ vlen_conv = FALSE;
+
+ if(H5P_set(dx_plist, H5D_XFER_VLEN_CONV_NAME, &vlen_conv) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "Error setting vlen conv flag")
+ }
+
+ if((orig_type_size = H5T_get_size(orig_type)) == 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get size of original type")
+
+ if((new_type_size = H5T_get_size(new_type_copy)) == 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get size of new type")
+
+ /* If the new type is the same as the current, simply finish the function */
+ if(0 == H5T_cmp(orig_type, new_type_copy, FALSE))
+ HGOTO_DONE(SUCCEED)
+
+ /* Figure out the number of elements in a chunk */
+ nelmts = dset->shared->layout.u.chunk.size/orig_type_size;
+
+ /* Find the conversion function */
+ if (NULL==(tpath=H5T_path_find(orig_type, new_type_copy, NULL, NULL, dxpl_id, FALSE)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and dst data types");
+
+ if (H5T_path_bkg(tpath) && (NULL==(bkg=(unsigned char*)H5MM_malloc(nelmts*(new_type_size > orig_type_size ? new_type_size : orig_type_size)))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate buffer")
+
+ /* Loop over all entries in the chunk cache */
+ for(ent = rdcc->head; ent; ent = next) {
+ next = ent->next;
+ ent->locked = TRUE;
+
+ if(new_type_size > orig_type_size) {
+ if(NULL == (new_chunk = H5D_istore_chunk_alloc(nelmts*new_type_size, pline)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for raw data chunk")
+
+ HDmemcpy(new_chunk, ent->chunk, ent->chunk_size);
+
+ /* Convert the data */
+ if (H5T_convert(tpath, orig_type_id, new_type_copy_id, nelmts, (size_t)0,
+ (size_t)0, new_chunk, bkg, dxpl_id)<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed");
+
+ H5MM_free(ent->chunk);
+ ent->chunk = (uint8_t*)new_chunk;
+ } else if (new_type_size < orig_type_size) {
+ if(NULL == (new_chunk = H5D_istore_chunk_alloc(nelmts*new_type_size, pline)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for raw data chunk")
+
+ /* Convert the data */
+ if (H5T_convert(tpath, orig_type_id, new_type_copy_id, nelmts, (size_t)0,
+ (size_t)0, ent->chunk, bkg, dxpl_id)<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed");
+
+ HDmemcpy(new_chunk, ent->chunk, nelmts*new_type_size);
+
+ H5MM_free(ent->chunk);
+ ent->chunk = (uint8_t*)new_chunk;
+ } else {
+ /* Convert the data */
+ if (H5T_convert(tpath, orig_type_id, new_type_copy_id, nelmts, (size_t)0,
+ (size_t)0, ent->chunk, bkg, dxpl_id)<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed");
+ }
+
+ ent->chunk_size = nelmts*new_type_size;
+ ent->alloc_size = ent->chunk_size;
+ ent->rd_count = ent->chunk_size;
+ ent->wr_count = ent->chunk_size;
+ ent->offset[dset->shared->layout.u.chunk.ndims-1] = new_type_size;
+ ent->dirty = TRUE;
+ ent->locked = FALSE;
+
+ /* Update some local variables for the filter pipeline */
+ if(H5Z_change_local(dset->shared->dcpl_id, new_type_copy_id, /*unused*/0,
+ (hsize_t)ent->linear_offset) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "failed to change local filter info")
+ } /* end for */
+
+ rdcc->nbytes = new_type_size*rdcc->nbytes/orig_type_size;
+
+ H5MM_free(bkg);
+
+ if (H5I_dec_ref(new_type_copy_id) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "problem freeing id");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_istore_conv_dtype() */
+
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_istore_dest
*
* Purpose: Destroy the entire chunk cache by flushing dirty entries,
@@ -1908,6 +2091,52 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D_istore_calc_offset
+ *
+ * Purpose: Private function to translate from the multi-dimensional
+ * offset of a chunk in a dataspace to linear offset. At this
+ * moment, it's used for the filter for modifying dataset's
+ * datatype.
+ *
+ * Return: Success: Linear offset of the chunk.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * 12 March 2008
+ *
+ * Modification:
+ *-------------------------------------------------------------------------
+ */
+hssize_t H5D_istore_calc_offset(H5S_t *space, hsize_t offset[])
+{
+ hsize_t linear_offset = 0, tmp_offset = 0;
+ int space_ndims; /* Dataset's space rank */
+ hsize_t space_dim[H5O_LAYOUT_NDIMS]; /* Dataset's dataspace dimensions */
+ int u,v; /*counters */
+ hssize_t ret_value;
+
+ FUNC_ENTER_NOAPI(H5D_istore_calc_offset, FAIL)
+
+ /* Retrieve the dataset dimensions */
+ if((space_ndims = H5S_get_simple_extent_dims(space, space_dim, NULL)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get simple dataspace info")
+
+ for(u=0; u<space_ndims; u++) {
+ tmp_offset = offset[u];
+ for(v=u+1; v<space_ndims; v++)
+ tmp_offset *= space_dim[v];
+ linear_offset += tmp_offset;
+ }
+
+ ret_value = linear_offset;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_istore_lock
*
* Purpose: Return a pointer to a dataset chunk. The pointer points
@@ -2038,8 +2267,10 @@ H5D_istore_lock(const H5D_io_info_t *io_info, H5D_istore_ud1_t *udata,
HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "unable to read raw data chunk")
if(pline->nused)
- if(H5Z_pipeline(pline, H5Z_FLAG_REVERSE, &(udata->filter_mask), io_info->dxpl_cache->err_detect,
- io_info->dxpl_cache->filter_cb, &(udata->nbytes), &chunk_alloc, &chunk) < 0)
+ if(H5Z_pipeline(pline, H5Z_FLAG_REVERSE, &(udata->filter_mask),
+ io_info->dxpl_cache->err_detect, (hsize_t)io_info->store->chunk.linear_offset,
+ io_info->dxpl_cache->filter_cb, &(udata->nbytes), &chunk_alloc,
+ &chunk) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, NULL, "data pipeline read failed")
#ifdef H5D_ISTORE_DEBUG
rdcc->nmisses++;
@@ -2126,6 +2357,7 @@ H5D_istore_lock(const H5D_io_info_t *io_info, H5D_istore_ud1_t *udata,
assert(NULL==rdcc->slot[idx]);
rdcc->slot[idx] = ent;
ent->idx = idx;
+ ent->linear_offset = io_info->store->chunk.linear_offset;
rdcc->nbytes += chunk_size;
rdcc->nused++;
@@ -2856,7 +3088,7 @@ H5D_istore_chunk_alloc(size_t size, const H5O_pline_t *pline)
{
void *ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_istore_chunk_alloc)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_chunk_alloc)
HDassert(size);
HDassert(pline);
@@ -2928,6 +3160,7 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
H5D_io_info_t io_info; /* Dataset I/O info */
H5D_storage_t store; /* Dataset storage information */
hsize_t chunk_offset[H5O_LAYOUT_NDIMS]; /* Offset of current chunk */
+ hssize_t linear_offset = 0;
size_t orig_chunk_size; /* Original size of chunk in bytes */
unsigned filter_mask = 0; /* Filter mask for chunks that have them */
const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset layout */
@@ -3012,6 +3245,7 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
|| pline->nused > 0)
should_fill = TRUE;
+
/* Check if fill values should be written to chunks */
if(should_fill) {
/* Initialize the fill value buffer */
@@ -3033,7 +3267,9 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
size_t buf_size = orig_chunk_size;
/* Push the chunk through the filters */
- if(H5Z_pipeline(pline, 0, &filter_mask, dxpl_cache->err_detect, dxpl_cache->filter_cb, &orig_chunk_size, &buf_size, &fb_info.fill_buf) < 0)
+ if(H5Z_pipeline(pline, 0, &filter_mask, dxpl_cache->err_detect,
+ (hsize_t)linear_offset, dxpl_cache->filter_cb, &orig_chunk_size,
+ &buf_size, &fb_info.fill_buf) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_WRITEERROR, FAIL, "output pipeline failed")
} /* end if */
} /* end if */
@@ -3091,7 +3327,9 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
size_t nbytes = fb_info.fill_buf_size;
/* Push the chunk through the filters */
- if(H5Z_pipeline(pline, 0, &filter_mask, dxpl_cache->err_detect, dxpl_cache->filter_cb, &nbytes, &buf_size, &fb_info.fill_buf) < 0)
+ if(H5Z_pipeline(pline, 0, &filter_mask, dxpl_cache->err_detect,
+ (hsize_t)linear_offset, dxpl_cache->filter_cb, &nbytes,
+ &buf_size, &fb_info.fill_buf) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_WRITEERROR, FAIL, "output pipeline failed")
/* Keep the number of bytes the chunk turned in to */
@@ -3157,6 +3395,12 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
break;
} /* end else */
} /* end for */
+
+ /* Translate the offset of the chunck into single-dimensional offset for
+ * the filter of modifying dataset's datatype */
+ if((linear_offset = H5D_istore_calc_offset(dset->shared->space, chunk_offset)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to calculate chunk offset")
+
} /* end while */
#ifdef H5_HAVE_PARALLEL
@@ -3785,7 +4029,7 @@ H5D_istore_delete(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout)
/* Delete entire B-tree */
if(H5B_delete(f, dxpl_id, H5B_ISTORE, tmp_layout.u.chunk.addr, &udata)<0)
- HGOTO_ERROR(H5E_IO, H5E_CANTDELETE, 0, "unable to delete chunk B-tree")
+ HGOTO_ERROR(H5E_IO, H5E_CANTDELETE, FAIL, "unable to delete chunk B-tree")
/* Free the raw B-tree node buffer */
if(tmp_layout.u.chunk.btree_shared==NULL)
@@ -4217,8 +4461,6 @@ H5D_istore_copy_conv(H5F_t *file, const H5D_t *dset_src, const H5D_t *dset_dst,
if(H5P_set(plist, H5D_XFER_VLEN_CONV_NAME, &vlen_conv) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "Error setting vlen conv flag")
- /*if(H5P_get(plist, H5D_XFER_VLEN_CONV_NAME, &vlen_conv) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "Error getting vlen conv flag")*/
}
/* Set up the conversion functions */
@@ -4492,4 +4734,3 @@ H5D_istore_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int inden
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_istore_debug() */
-
diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h
index 300fb18..09b595d 100644
--- a/src/H5Dpkg.h
+++ b/src/H5Dpkg.h
@@ -112,7 +112,7 @@ typedef struct H5D_io_info_t {
hbool_t xfer_opt_mode_changed;
hbool_t using_mpi_vfd; /* Whether the file is using an MPI-based VFD */
#endif /* H5_HAVE_PARALLEL */
- const H5D_storage_t *store; /* Dataset storage info */
+ H5D_storage_t *store; /* Dataset storage info */
H5D_io_ops_t ops; /* I/O operation function pointers */
#ifdef H5S_DEBUG
H5S_iostats_t *stats; /* I/O statistics */
@@ -454,8 +454,8 @@ H5_DLL haddr_t H5D_istore_get_addr(const H5D_io_info_t *io_info,
H5_DLL herr_t H5D_istore_copy(H5F_t *f_src, H5O_layout_t *layout_src,
H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *src_dtype,
H5O_copy_t *cpy_info, H5O_pline_t *pline, hid_t dxpl_id);
-H5_DLL herr_t H5D_istore_copy_conv(H5F_t *file, const H5D_t *dset_src, const H5D_t *dset_dst,
- H5O_copy_t UNUSED *cpy_info, hid_t dxpl_id);
+H5_DLL herr_t H5D_istore_copy_conv(H5F_t *file, const H5D_t *dset_src, const H5D_t *dset_dst, H5O_copy_t UNUSED *cpy_info, hid_t dxpl_id);
+H5_DLL herr_t H5D_istore_conv_dtype(H5D_t *dset, hid_t new_type_id);
H5_DLL void * H5D_istore_lock(const H5D_io_info_t *io_info, H5D_istore_ud1_t *udata,
hbool_t relax, unsigned *idx_hint/*in,out*/);
H5_DLL herr_t H5D_istore_unlock(const H5D_io_info_t *io_info,
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index c5192b2..bab035c 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -112,6 +112,7 @@ typedef struct H5D_t H5D_t;
typedef struct {
hsize_t index; /* "Index" of chunk in dataset (must be first for TBBT routines) */
hsize_t *offset; /* Chunk's coordinates in elements */
+ hssize_t linear_offset; /* Chunk's coordinates translated into one-dimensional offset */
} H5D_chunk_storage_t;
typedef struct {
@@ -185,6 +186,7 @@ H5_DLL herr_t H5D_istore_delete(H5F_t *f, hid_t dxpl_id,
const H5O_layout_t *layout);
H5_DLL herr_t H5D_istore_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream,
int indent, int fwidth, unsigned ndims);
+H5_DLL hssize_t H5D_istore_calc_offset(H5S_t *space, hsize_t offset[]);
#endif /* _H5Dprivate_H */
diff --git a/src/H5HFcache.c b/src/H5HFcache.c
index 7454d76..9a83ec1 100644
--- a/src/H5HFcache.c
+++ b/src/H5HFcache.c
@@ -1290,7 +1290,7 @@ HDfprintf(stderr, "%s: read_size = %Zu, read_buf = %p\n", FUNC, read_size, read_
/* Push direct block data through I/O filter pipeline */
nbytes = read_size;
- if(H5Z_pipeline(&(hdr->pline), H5Z_FLAG_REVERSE, &filter_mask, H5Z_ENABLE_EDC,
+ if(H5Z_pipeline(&(hdr->pline), (H5Z_FLAG_REVERSE | H5Z_FLAG_SKIP_CRECORD), &filter_mask, H5Z_ENABLE_EDC, 0,
filter_cb, &nbytes, &read_size, &read_buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFILTER, NULL, "output pipeline failed")
#ifdef QAK
@@ -1465,7 +1465,7 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
/* Push direct block data through I/O filter pipeline */
nbytes = write_size;
- if(H5Z_pipeline(&(hdr->pline), 0, &filter_mask, H5Z_ENABLE_EDC,
+ if(H5Z_pipeline(&(hdr->pline), (0 | H5Z_FLAG_SKIP_CRECORD), &filter_mask, H5Z_ENABLE_EDC, 0,
filter_cb, &nbytes, &write_size, &write_buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "output pipeline failed")
#ifdef QAK
diff --git a/src/H5HFhuge.c b/src/H5HFhuge.c
index 198ef62..1634938 100644
--- a/src/H5HFhuge.c
+++ b/src/H5HFhuge.c
@@ -349,7 +349,7 @@ HDfprintf(stderr, "%s: obj_size = %Zu\n", FUNC, obj_size);
/* Push direct block data through I/O filter pipeline */
nbytes = write_size;
- if(H5Z_pipeline(&(hdr->pline), 0, &filter_mask, H5Z_NO_EDC,
+ if(H5Z_pipeline(&(hdr->pline), (0 | H5Z_FLAG_SKIP_CRECORD), &filter_mask, H5Z_NO_EDC, 0,
filter_cb, &nbytes, &write_size, &write_buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFILTER, FAIL, "output pipeline failed")
#ifdef QAK
@@ -675,7 +675,7 @@ H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id,
/* De-filter the object */
read_size = nbytes = obj_size;
- if(H5Z_pipeline(&(hdr->pline), H5Z_FLAG_REVERSE, &filter_mask, H5Z_NO_EDC, filter_cb, &nbytes, &read_size, &read_buf) < 0)
+ if(H5Z_pipeline(&(hdr->pline), (H5Z_FLAG_REVERSE | H5Z_FLAG_SKIP_CRECORD), &filter_mask, H5Z_NO_EDC, 0, filter_cb, &nbytes, &read_size, &read_buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFILTER, FAIL, "input filter failed")
obj_size = nbytes;
} /* end if */
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index ac07edf..389d989 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -743,7 +743,7 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
/* Sanity check */
/* (compound datatypes w/array members must be encoded w/version >= 2) */
- HDassert(dt->shared->u.compnd.memb[i].type->shared->type != H5T_ARRAY || dt->shared->version >= H5O_DTYPE_VERSION_2);
+ HDassert((dt->shared->u.compnd.memb[i].type)->shared->type != H5T_ARRAY || dt->shared->version >= H5O_DTYPE_VERSION_2);
/* Name */
HDstrcpy((char*)(*pp), dt->shared->u.compnd.memb[i].name);
diff --git a/src/H5Opline.c b/src/H5Opline.c
index 9a926c1..20b060d 100644
--- a/src/H5Opline.c
+++ b/src/H5Opline.c
@@ -24,13 +24,13 @@
#define H5Z_PACKAGE /*suppress error about including H5Zpkg */
#include "H5private.h" /* Generic Functions */
+#include "H5Dprivate.h" /* Error handling */
#include "H5Eprivate.h" /* Error handling */
#include "H5FLprivate.h" /* Free Lists */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
#include "H5Zpkg.h" /* Data filters */
-
/* PRIVATE PROTOTYPES */
static herr_t H5O_pline_encode(H5F_t *f, uint8_t *p, const void *mesg);
static void *H5O_pline_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p);
@@ -38,6 +38,8 @@ static void *H5O_pline_copy(const void *_mesg, void *_dest);
static size_t H5O_pline_size(const H5F_t *f, const void *_mesg);
static herr_t H5O_pline_reset(void *_mesg);
static herr_t H5O_pline_free(void *_mesg);
+static herr_t H5O_pline_delete(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh,
+ void *_mesg);
static herr_t H5O_pline_pre_copy_file(H5F_t *file_src,
const void *mesg_src, hbool_t *deleted, const H5O_copy_t *cpy_info, void *_udata);
static herr_t H5O_pline_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
@@ -52,7 +54,7 @@ static herr_t H5O_pline_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
#define H5O_SHARED_SIZE H5O_pline_shared_size
#define H5O_SHARED_SIZE_REAL H5O_pline_size
#define H5O_SHARED_DELETE H5O_pline_shared_delete
-#undef H5O_SHARED_DELETE_REAL
+#define H5O_SHARED_DELETE_REAL H5O_pline_delete
#define H5O_SHARED_LINK H5O_pline_shared_link
#undef H5O_SHARED_LINK_REAL
#define H5O_SHARED_COPY_FILE H5O_pline_shared_copy_file
@@ -551,6 +553,78 @@ H5O_pline_free(void *mesg)
/*-------------------------------------------------------------------------
+ * Function: H5O_pline_delete
+ *
+ * Purpose: Free file space referenced by message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * 13 August 2008
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_pline_delete(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, void *_mesg)
+{
+ H5O_pline_t *mesg = (H5O_pline_t *)_mesg;
+ H5O_pline_t *pline = NULL;
+ H5D_layout_t layout; /* Dataset's layout information */
+ hid_t dcpl_id, file_id;
+ H5P_genplist_t *dc_plist = NULL, *def_dc_plist=NULL; /* New Property list */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_pline_delete)
+
+ /* check args */
+ HDassert(f);
+ HDassert(mesg);
+
+ /* Get the object of default dataset creation property list */
+ if(NULL == (def_dc_plist = (H5P_genplist_t *)H5I_object(H5P_DATASET_CREATE_DEFAULT)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get dataset creation property list")
+
+ /* Create a new default property list */
+ if((dcpl_id = H5P_copy_plist(def_dc_plist)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy dataset creation property list")
+
+ if(NULL == (dc_plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get dataset creation property list")
+
+ /* Make a copy of filter pipeline and insert into the property list. Only the filter
+ * for modifying dataset's datatype has the callback function to delete the local
+ * values. This filter only needs the property of pipeline and chunking. */
+ if((pline = H5O_pline_copy(mesg, NULL)) == NULL)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTCOPY, FAIL, "unable to copy pipeline")
+
+ if(H5P_set(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, pline) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline")
+
+ layout = H5D_CHUNKED;
+ if(H5P_set(dc_plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve layout")
+
+ if((file_id = H5F_get_id(f)) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "can't get file ID")
+
+ /* Call the function of the filter pipeline */
+ if(H5Z_delete_local(dcpl_id, 0, file_id) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTDELETE, FAIL, "can't get dataset creation property list")
+
+ if(H5I_dec_ref(dcpl_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close property list ID");
+
+ if(H5I_dec_ref(file_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close file ID");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_pline_delete() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_pline_pre_copy_file
*
* Purpose: Perform any necessary actions before copying message between
diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c
index fa92315..747a5f0 100644
--- a/src/H5Pdcpl.c
+++ b/src/H5Pdcpl.c
@@ -2064,7 +2064,7 @@ H5Pset_dtype_modifiable(hid_t plist_id)
H5O_pline_t pline;
H5P_genplist_t *plist; /* Property list pointer */
size_t cd_nelmts=3; /* Number of filter parameters */
- unsigned cd_values[3]={0,0}; /* Filter parameters */
+ unsigned cd_values[3]={0,0,0};/* Filter parameters */
herr_t ret_value=SUCCEED; /* return value */
FUNC_ENTER_API(H5Pset_dtype_modifiable, FAIL)
diff --git a/src/H5T.c b/src/H5T.c
index 5175ebf..e479de3 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -5404,6 +5404,11 @@ H5T_dtype_is_valid(H5T_t *dtype, H5T_t *new_type)
}
}
break;
+ case H5T_TIME:
+ if(new_class != H5T_TIME)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new type must be time type")
+
+ break;
case H5T_STRING:
if(new_class != H5T_STRING)
HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new type must be a string type")
diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c
index bcb9962..8bcae49 100644
--- a/src/H5Tcommit.c
+++ b/src/H5Tcommit.c
@@ -434,6 +434,35 @@ H5T_committed(const H5T_t *type)
/*-------------------------------------------------------------------------
+ * Function: H5T_immutable
+ *
+ * Purpose: Determines if a datatype is predefined or not.
+ *
+ * Return: Success: TRUE if predefined, FALSE otherwise.
+ *
+ * Programmer: Raymond Lu
+ * 4 August 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5T_immutable(const H5T_t *type)
+{
+ /* Use no-init for efficiency */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_immutable)
+
+ HDassert(type);
+
+if(H5T_STATE_IMMUTABLE == type->shared->state)
+ fprintf(stderr, "H5T_immutable: state=%d\n", type->shared->state);
+else
+ fprintf(stderr, "H5T_immutable: state isn't immutable\n");
+
+ FUNC_LEAVE_NOAPI(H5T_STATE_IMMUTABLE == type->shared->state)
+} /* end H5T_immutable() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5T_link
*
* Purpose: Adjust the link count for an object header by adding
@@ -456,7 +485,8 @@ H5T_link(const H5T_t *type, int adjust, hid_t dxpl_id)
FUNC_ENTER_NOAPI(H5T_link, FAIL)
HDassert(type);
- HDassert(type->sh_loc.type == H5O_SHARE_TYPE_COMMITTED);
+ HDassert(type->sh_loc.type == H5O_SHARE_TYPE_COMMITTED ||
+ type->sh_loc.type == H5O_SHARE_TYPE_SOHM);
/* Adjust the link count on the named datatype */
if((ret_value = H5O_link(&type->oloc, adjust, dxpl_id)) < 0)
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index c102ead..8d5071a 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -130,6 +130,7 @@ H5_DLL H5R_type_t H5T_get_ref_type(const H5T_t *dt);
/* Operations on named datatypes */
H5_DLL H5T_t *H5T_open(const H5G_loc_t *loc, hid_t dxpl_id);
H5_DLL htri_t H5T_committed(const H5T_t *type);
+H5_DLL htri_t H5T_immutable(const H5T_t *type);
H5_DLL int H5T_link(const H5T_t *type, int adjust, hid_t dxpl_id);
H5_DLL herr_t H5T_update_shared(H5T_t *type);
diff --git a/src/H5V.c b/src/H5V.c
index 3e06636..fb3100e 100644
--- a/src/H5V.c
+++ b/src/H5V.c
@@ -416,10 +416,10 @@ H5V_hyper_disjointp(unsigned n,
if (0==size1[u] || 0==size2[u])
HGOTO_DONE(TRUE)
- if (((offset1?offset1[u]:0) < (offset2?offset2[u]:0) &&
- ((offset1?offset1[u]:0) + size1[u] <= (offset2?offset2[u]:0))) ||
- ((offset2?offset2[u]:0) < (offset1?offset1[u]:0) &&
- ((offset2?offset2[u]:0) + size2[u] <= (offset1?offset1[u]:0))))
+ if ((((offset1?offset1[u]:0) < (offset2?offset2[u]:0)) &&
+ ((offset1?offset1[u]:0) + (size1?size1[u]:0) <= (offset2?offset2[u]:0))) ||
+ (((offset2?offset2[u]:0) < (offset1?offset1[u]:0)) &&
+ ((offset2?offset2[u]:0) + (size2?size2[u]:0) <= (offset1?offset1[u]:0))))
HGOTO_DONE(TRUE)
}
diff --git a/src/H5Z.c b/src/H5Z.c
index aab81ad..de8f1cc 100644
--- a/src/H5Z.c
+++ b/src/H5Z.c
@@ -48,7 +48,11 @@ typedef struct H5Z_stats_t {
typedef enum {
H5Z_PRELUDE_CAN_APPLY, /* Call "can apply" callback */
H5Z_PRELUDE_SET_LOCAL, /* Call "set local" callback */
- H5Z_PRELUDE_RESET_LOCAL /* Call "reset local" callback */
+ H5Z_PRELUDE_RESET_LOCAL, /* Call "reset local" callback */
+ H5Z_PRELUDE_CHANGE_LOCAL, /* Call "change local" callback*/
+ H5Z_PRELUDE_EVICT_LOCAL, /* Call "evict local" callback */
+ H5Z_PRELUDE_DELETE_LOCAL, /* Call "delete local" callback*/
+ H5Z_PRELUDE_CLOSE_LOCAL /* Call "close local" callback */
} H5Z_prelude_type_t;
/* Local variables */
@@ -472,14 +476,14 @@ done:
*/
static herr_t
H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_type,
- hid_t file_id)
+ hid_t file_id, hsize_t chunk_offset, hbool_t from_reopen)
{
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5Z_prelude_callback)
assert (H5I_GENPROP_LST==H5I_get_type(dcpl_id));
- assert (H5I_DATATYPE==H5I_get_type(type_id));
+ /*assert (H5I_DATATYPE==H5I_get_type(type_id));*/
/* Check if the property list is non-default */
if(dcpl_id!=H5P_DATASET_CREATE_DEFAULT) {
@@ -545,15 +549,20 @@ H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_ty
/* Make correct callback */
switch(prelude_type) {
case H5Z_PRELUDE_CAN_APPLY:
+#ifndef H5_USE_16_API
/* Check if filter is configured to be able to encode */
if(! fclass->encoder_present)
HGOTO_ERROR(H5E_PLINE, H5E_NOENCODER, FAIL, "Filter present but encoding is disabled.");
-
+#endif
/* Check if there is a "can apply" callback */
if(fclass->can_apply) {
/* Make callback to filter's "can apply" function */
+#ifdef H5_USE_16_API
+ herr_t status=(fclass->can_apply)(dcpl_id, type_id, space_id);
+#else
herr_t status=(fclass->can_apply)(dcpl_id, type_id, space_id, file_id);
+#endif
/* Check return value */
if(status<=0) {
@@ -577,7 +586,11 @@ H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_ty
/* Check if there is a "set local" callback */
if(fclass->set_local) {
/* Make callback to filter's "set local" function */
+#ifdef H5_USE_16_API
+ if((fclass->set_local)(dcpl_id, type_id, space_id)<0) {
+#else
if((fclass->set_local)(dcpl_id, type_id, space_id, file_id)<0) {
+#endif
/* We're leaving, so close dataspace */
if(H5I_dec_ref(space_id)<0)
HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace")
@@ -588,11 +601,72 @@ H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_ty
} /* end if */
break;
+#ifndef H5_USE_16_API
case H5Z_PRELUDE_RESET_LOCAL:
/* Check if there is a "reset local" callback */
if(fclass->reset_local) {
/* Make callback to filter's "set local" function */
- if((fclass->reset_local)(dcpl_id, type_id, space_id, file_id)<0) {
+ if((fclass->reset_local)(dcpl_id, type_id, space_id, file_id, from_reopen)<0) {
+ /* We're leaving, so close dataspace */
+ if(H5I_dec_ref(space_id)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace")
+
+ /* Indicate error during filter callback */
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "error during user callback")
+ } /* end if */
+ } /* end if */
+ break;
+
+ case H5Z_PRELUDE_DELETE_LOCAL:
+ /* Check if there is a "delete local" callback */
+ if(fclass->delete_local) {
+ /* Make callback to filter's "delete local" function */
+ if((fclass->delete_local)(dcpl_id)<0) {
+ /* We're leaving, so close dataspace */
+ if(H5I_dec_ref(space_id)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace")
+
+ /* Indicate error during filter callback */
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "error during user callback")
+ } /* end if */
+ } /* end if */
+ break;
+
+ case H5Z_PRELUDE_CLOSE_LOCAL:
+ /* Check if there is a "close local" callback */
+ if(fclass->close_local) {
+ /* Make callback to filter's "close local" function */
+ if((fclass->close_local)(dcpl_id)<0) {
+ /* We're leaving, so close dataspace */
+ if(H5I_dec_ref(space_id)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace")
+
+ /* Indicate error during filter callback */
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "error during user callback")
+ } /* end if */
+ } /* end if */
+ break;
+
+ case H5Z_PRELUDE_CHANGE_LOCAL:
+ /* Check if there is a "change local" callback */
+ if(fclass->change_local) {
+ /* Make callback to filter's "change local" function */
+ if((fclass->change_local)(dcpl_id, chunk_offset)<0) {
+ /* We're leaving, so close dataspace */
+ if(H5I_dec_ref(space_id)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace")
+
+ /* Indicate error during filter callback */
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "error during user callback")
+ } /* end if */
+ } /* end if */
+ break;
+
+ case H5Z_PRELUDE_EVICT_LOCAL:
+ /* Check if there is a "evict local" callback */
+ if(fclass->evict_local) {
+ /* Make callback to filter's "evict local" function */
+ if((fclass->evict_local)(dcpl_id, chunk_offset)<0) {
/* We're leaving, so close dataspace */
if(H5I_dec_ref(space_id)<0)
HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace")
@@ -602,6 +676,7 @@ H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_ty
} /* end if */
} /* end if */
break;
+#endif
default:
assert("invalid prelude type" && 0);
@@ -653,7 +728,8 @@ H5Z_can_apply (hid_t dcpl_id, hid_t type_id, hid_t file_id)
assert (H5I_DATATYPE==H5I_get_type(type_id));
/* Make "can apply" callbacks for filters in pipeline */
- if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_CAN_APPLY, file_id)<0)
+ if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_CAN_APPLY, file_id,
+ /*UNUSED*/0, /*UNUSED*/0)<0)
HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "unable to apply filter")
done:
@@ -693,7 +769,8 @@ H5Z_set_local (hid_t dcpl_id, hid_t type_id, hid_t file_id)
assert (H5I_DATATYPE==H5I_get_type(type_id));
/* Make "set local" callbacks for filters in pipeline */
- if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_SET_LOCAL, file_id)<0)
+ if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_SET_LOCAL, file_id,
+ /*UNUSED*/0, /*UNUSED*/0)<0)
HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "local filter parameters not set")
done:
@@ -723,7 +800,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Z_reset_local (hid_t dcpl_id, hid_t type_id, hid_t file_id)
+H5Z_reset_local (hid_t dcpl_id, hid_t type_id, hid_t file_id, hbool_t from_reopen)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -733,7 +810,8 @@ H5Z_reset_local (hid_t dcpl_id, hid_t type_id, hid_t file_id)
assert (H5I_DATATYPE==H5I_get_type(type_id));
/* Make "reset local" callbacks for filters in pipeline */
- if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_RESET_LOCAL, file_id)<0)
+ if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_RESET_LOCAL, file_id,
+ /*UNUSED*/0, from_reopen)<0)
HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "local filter parameters not set")
done:
@@ -742,6 +820,134 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Z_change_local
+ *
+ * Purpose: Makes callback to change the local values for filters.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * 12 March 2008
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Z_change_local (hid_t dcpl_id, hid_t type_id, hid_t file_id, hsize_t chunk_offset)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_change_local,FAIL)
+
+ assert (H5I_GENPROP_LST==H5I_get_type(dcpl_id));
+
+ /* Make "change local" callbacks for filters in pipeline */
+ if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_CHANGE_LOCAL, file_id,
+ chunk_offset, /*UNUSED*/0)<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "local filter parameters not changed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_change_local() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_evict_local
+ *
+ * Purpose: Makes callback to evict the local values for filters.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * 12 March 2008
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Z_evict_local (hid_t dcpl_id, hid_t type_id, hid_t file_id, hsize_t chunk_offset)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_evict_local,FAIL)
+
+ assert (H5I_GENPROP_LST==H5I_get_type(dcpl_id));
+
+ /* Make "change local" callbacks for filters in pipeline */
+ if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_EVICT_LOCAL, file_id,
+ chunk_offset, /*UNUSED*/0)<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "local filter parameters not changed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_evict_local() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_delete_local
+ *
+ * Purpose: Makes callback to delete the local values for filters.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * 11 August 2008
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Z_delete_local(hid_t dcpl_id, hid_t type_id, hid_t file_id)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_delete_local,FAIL)
+
+ assert (H5I_GENPROP_LST==H5I_get_type(dcpl_id));
+
+ /* Make "delete local" callbacks for filters in pipeline */
+ if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_DELETE_LOCAL, file_id,
+ /*UNUSED*/0, /*UNUSED*/0)<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "local filter parameters not deleted")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_delete_local() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_close_local
+ *
+ * Purpose: Makes callback to close the local values for filters.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * 12 March 2008
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Z_close_local (hid_t dcpl_id, hid_t type_id, hid_t file_id)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_close_local,FAIL)
+
+ assert (H5I_GENPROP_LST==H5I_get_type(dcpl_id));
+
+ /* Make "close local" callbacks for filters in pipeline */
+ if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_CLOSE_LOCAL, file_id,
+ /*UNUSED*/0, /*UNUSED*/0)<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "local filter parameters not closed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_close_local() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Z_modify
*
* Purpose: Modify filter parameters for specified pipeline.
@@ -1010,14 +1216,17 @@ done:
* Programmer: Robb Matzke
* Tuesday, August 4, 1998
*
- * Modifications:
+ * Modifications: Raymond Lu
+ * 12 March 2008
+ * Added an additional parameter of CHUNK_OFFSET for the filter
+ * of modifying dataset's datatype.
*
*-------------------------------------------------------------------------
*/
herr_t
H5Z_pipeline(const H5O_pline_t *pline, unsigned flags,
unsigned *filter_mask/*in,out*/, H5Z_EDC_t edc_read,
- H5Z_cb_t cb_struct, size_t *nbytes/*in,out*/,
+ hsize_t chunk_offset, H5Z_cb_t cb_struct, size_t *nbytes/*in,out*/,
size_t *buf_size/*in,out*/, void **buf/*in,out*/)
{
size_t i, idx, new_nbytes;
@@ -1058,8 +1267,12 @@ H5Z_pipeline(const H5O_pline_t *pline, unsigned flags,
#endif
tmp_flags=flags|(pline->filter[idx].flags);
tmp_flags|=(edc_read== H5Z_DISABLE_EDC) ? H5Z_FLAG_SKIP_EDC : 0;
- new_nbytes = (fclass->filter)(tmp_flags, pline->filter[idx].cd_nelmts,
- pline->filter[idx].cd_values, *nbytes, buf_size, buf);
+
+#ifdef H5_USE_16_API
+ new_nbytes = (fclass->filter)(tmp_flags, pline->filter[idx].cd_nelmts, pline->filter[idx].cd_values, *nbytes, buf_size, buf);
+#else
+ new_nbytes = (fclass->filter)(tmp_flags, chunk_offset, pline->filter[idx].cd_nelmts, pline->filter[idx].cd_values, *nbytes, buf_size, buf);
+#endif
#ifdef H5Z_DEBUG
H5_timer_end(&(fstats->stats[1].timer), &timer);
@@ -1099,8 +1312,13 @@ H5Z_pipeline(const H5O_pline_t *pline, unsigned flags,
fstats=&H5Z_stat_table_g[fclass_idx];
H5_timer_begin(&timer);
#endif
- new_nbytes = (fclass->filter)(flags|(pline->filter[idx].flags), pline->filter[idx].cd_nelmts,
- pline->filter[idx].cd_values, *nbytes, buf_size, buf);
+
+#ifdef H5_USE_16_API
+ new_nbytes = (fclass->filter)(flags|(pline->filter[idx].flags), pline->filter[idx].cd_nelmts, pline->filter[idx].cd_values, *nbytes, buf_size, buf);
+#else
+ new_nbytes = (fclass->filter)(flags|(pline->filter[idx].flags), chunk_offset, pline->filter[idx].cd_nelmts, pline->filter[idx].cd_values, *nbytes, buf_size, buf);
+#endif
+
#ifdef H5Z_DEBUG
H5_timer_end(&(fstats->stats[0].timer), &timer);
fstats->stats[0].total += MAX(*nbytes, new_nbytes);
@@ -1161,7 +1379,7 @@ H5Z_filter_info(const H5O_pline_t *pline, H5Z_filter_t filter)
break;
/* Check if the filter was not already in the pipeline */
- if(idx>pline->nused)
+ if(idx>=pline->nused)
HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, NULL, "filter not in pipeline")
/* Set return value */
@@ -1303,15 +1521,19 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5Zget_filter_info
+ * Function: H5Zget_filter_info
+ *
+ * Purpose: Gets information about a pipeline data filter and stores it
+ * in filter_config_flags.
*
- * Purpose: Gets information about a pipeline data filter and stores it
- * in filter_config_flags.
+ * Return: zero on success / negative on failure
*
- * Return: zero on success / negative on failure
+ * Programmer: James Laird and Nat Furrer
+ * Monday, June 7, 2004
*
- * Programmer: James Laird and Nat Furrer
- * Monday, June 7, 2004
+ * Modification: Raymond Lu
+ * 12 March 2008
+ * Added compatibility for v1.6.
*
*-------------------------------------------------------------------------
*/
@@ -1324,6 +1546,28 @@ H5Zget_filter_info(H5Z_filter_t filter, unsigned int *filter_config_flags)
FUNC_ENTER_API(H5Zget_filter_info, FAIL)
H5TRACE2("e", "Zf*Iu", filter, filter_config_flags);
+#ifdef H5_USE_16_API
+ if (filter_config_flags != NULL)
+ {
+ if (filter == H5Z_FILTER_SZIP)
+ {
+ *filter_config_flags = 0;
+#ifdef H5_HAVE_FILTER_SZIP
+ if(SZ_encoder_enabled()>0)
+ *filter_config_flags |= H5Z_FILTER_CONFIG_ENCODE_ENABLED;
+#endif /* H5_HAVE_FILTER_SZIP */
+ *filter_config_flags |= H5Z_FILTER_CONFIG_DECODE_ENABLED;
+ }
+ else
+ *filter_config_flags = H5Z_FILTER_CONFIG_DECODE_ENABLED | H5Z_FILTER_CONFIG_ENCODE_ENABLED;
+
+ /* Make sure the filter exists */
+ if (H5Z_find(filter) == NULL) {
+ *filter_config_flags = 0;
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Filter not defined")
+ }
+ }
+#else
/* Look up the filter class info */
if(NULL == (fclass = H5Z_find(filter)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Filter not defined")
@@ -1337,6 +1581,7 @@ H5Zget_filter_info(H5Z_filter_t filter, unsigned int *filter_config_flags)
if(fclass->decoder_present)
*filter_config_flags |= H5Z_FILTER_CONFIG_DECODE_ENABLED;
} /* end if */
+#endif
done:
FUNC_LEAVE_API(ret_value)
diff --git a/src/H5Zdeflate.c b/src/H5Zdeflate.c
index a954c2a..b8fc124 100644
--- a/src/H5Zdeflate.c
+++ b/src/H5Zdeflate.c
@@ -32,22 +32,42 @@
# include "zlib.h"
#endif
+#ifndef H5_USE_16_API
/* Local function prototypes */
-static size_t H5Z_filter_deflate (unsigned flags, size_t cd_nelmts,
- const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
+static size_t H5Z_filter_deflate (unsigned flags, hsize_t UNUSED chunk_offset,
+ size_t cd_nelmts, const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
/* This message derives from H5Z */
const H5Z_class_t H5Z_DEFLATE[1] = {{
- H5Z_CLASS_T_VERS, /* H5Z_class_t version */
+ H5Z_CLASS_T_VERS, /* H5Z_class_t version */
H5Z_FILTER_DEFLATE, /* Filter id number */
- 1, /* encoder_present flag (set to true) */
- 1, /* decoder_present flag (set to true) */
+ 1, /* encoder_present flag (set to true) */
+ 1, /* decoder_present flag (set to true) */
"deflate", /* Filter name for debugging */
NULL, /* The "can apply" callback */
NULL, /* The "set local" callback */
NULL, /* The "reset local" callback */
+ NULL, /* The "change local" callback */
+ NULL, /* The "evict local" callback */
+ NULL, /* The "delete local" callback */
+ NULL, /* The "close local" callback */
H5Z_filter_deflate, /* The actual filter function */
}};
+#else
+/* Local function prototypes */
+static size_t H5Z_filter_deflate (unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
+ size_t nbytes, size_t *buf_size, void **buf);
+
+/* This message derives from H5Z */
+const H5Z_class_t H5Z_DEFLATE[1] = {{
+ H5Z_CLASS_T_VERS, /* H5Z_class_t version */
+ H5Z_FILTER_DEFLATE, /* Filter id number */
+ "deflate", /* Filter name for debugging */
+ NULL, /* The "can apply" callback */
+ NULL, /* The "set local" callback */
+ H5Z_filter_deflate, /* The actual filter function */
+}};
+#endif
#define H5Z_DEFLATE_SIZE_ADJUST(s) (HDceil(((double)(s))*1.001)+12)
@@ -68,14 +88,19 @@ const H5Z_class_t H5Z_DEFLATE[1] = {{
*
*-------------------------------------------------------------------------
*/
+#ifndef H5_USE_16_API
static size_t
-H5Z_filter_deflate (unsigned flags, size_t cd_nelmts,
- const unsigned cd_values[], size_t nbytes,
- size_t *buf_size, void **buf)
+H5Z_filter_deflate (unsigned flags, hsize_t UNUSED chunk_offset, size_t cd_nelmts,
+ const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf)
+#else
+static size_t
+H5Z_filter_deflate (unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
+ size_t nbytes, size_t *buf_size, void **buf)
+#endif
{
void *outbuf = NULL; /* Pointer to new buffer */
int status; /* Status from zlib operation */
- size_t ret_value; /* Return value */
+ size_t ret_value = nbytes; /* Return value */
FUNC_ENTER_NOAPI(H5Z_filter_deflate, 0)
@@ -83,7 +108,7 @@ H5Z_filter_deflate (unsigned flags, size_t cd_nelmts,
if (cd_nelmts!=1 || cd_values[0]>9)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid deflate aggression level")
- if (flags & H5Z_FLAG_REVERSE) {
+ if (flags & H5Z_FLAG_REVERSE) { /*read*/
/* Input; uncompress */
z_stream z_strm; /* zlib parameters */
size_t nalloc = *buf_size; /* Number of bytes for output (compressed) buffer */
@@ -148,8 +173,7 @@ H5Z_filter_deflate (unsigned flags, size_t cd_nelmts,
/* Finish uncompressing the stream */
(void)inflateEnd(&z_strm);
- }
- else {
+ } else if (!(flags & H5Z_FLAG_INVMASK) || (flags & H5Z_FLAG_SKIP_CRECORD)) { /*Write*/
/*
* Output; compress but fail if the result would be larger than the
* input. The library doesn't provide in-place compression, so we
@@ -197,4 +221,3 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
}
#endif /* H5_HAVE_FILTER_DEFLATE */
-
diff --git a/src/H5Zdtype_modify.c b/src/H5Zdtype_modify.c
index b3f074f..9a99cd8 100644
--- a/src/H5Zdtype_modify.c
+++ b/src/H5Zdtype_modify.c
@@ -21,21 +21,53 @@
#define H5Z_PACKAGE /*suppress error about including H5Zpkg */
#include "H5private.h" /* Generic Functions */
+#include "H5B2private.h" /* v2 B-trees */
#include "H5Eprivate.h" /* Error handling */
#include "H5Dprivate.h" /* Dataset */
#include "H5Fprivate.h" /* File access */
+#include "H5FLprivate.h" /* Free Lists */
#include "H5MMprivate.h" /* Memory management */
#include "H5SMprivate.h" /* Shared Object Header Messages */
+#include "H5Tprivate.h" /* Datatype */
#include "H5Zpkg.h" /* Data filters */
#ifdef H5_HAVE_FILTER_DTYPE_MODIFY
+/* Current version of the filter*/
+#define H5Z_DTYPE_MODIFY_VERS (1)
+
+/* Number of client data elements */
+#define CD_NELMTS 16
+
+#define H5Z_MDTYPE_DEC 0
+#define H5Z_MDTYPE_INC 1
+
+/* v2 B-tree creation macros for 'datatype' field index */
+/* How to determine the node size? */
+#define H5Z_DTYPE_BT2_NODE_SIZE 128
+#define H5Z_DTYPE_BT2_MERGE_PERC 40
+#define H5Z_DTYPE_BT2_SPLIT_PERC 100
+
/* Local function prototypes */
static herr_t H5Z_set_local_dtype_modify(hid_t dcpl_id, hid_t dtype_id, hid_t space_id,
hid_t file_id);
static herr_t H5Z_reset_local_dtype_modify(hid_t dcpl_id, hid_t dtype_id, hid_t space_id,
- hid_t file_id);
-static size_t H5Z_filter_dtype_modify (unsigned flags, size_t cd_nelmts,
+ hid_t file_id, hbool_t from_reopen);
+static herr_t H5Z_change_local_dtype_modify(hid_t dcpl_id, hsize_t chunk_offset);
+static herr_t H5Z_evict_local_dtype_modify(hid_t dcpl_id, hsize_t chunk_offset);
+static herr_t H5Z_delete_local_dtype_modify(hid_t dcpl_id);
+static herr_t H5Z_close_local_dtype_modify(hid_t dcpl_id);
+static herr_t H5Z_free_slist_node(void *item, void UNUSED *key, void UNUSED *operator_data);
+static herr_t H5Z_btree2_dtype_store(void *_nrecord, const void *_udata);
+static herr_t H5Z_btree2_dtype_retrieve(void *udata, const void *nrecord);
+static herr_t H5Z_btree2_dtype_encode(const H5F_t *f, uint8_t *raw, const void *_nrecord);
+static herr_t H5Z_btree2_dtype_decode(const H5F_t *f, const uint8_t *raw, void *_nrecord);
+static herr_t H5Z_btree2_dtype_compare(const void *_bt2_udata, const void *_bt2_rec);
+static herr_t H5Z_btree2_dtype_find_cb(void *record, void *op_data);
+static herr_t H5Z_btree2_dtype_remove_cb(void *record, void *op_data);
+static herr_t H5Z_btree2_dtype_delete_cb(void *record, void *op_data);
+
+static size_t H5Z_filter_dtype_modify (unsigned flags, hsize_t chunk_offset, size_t cd_nelmts,
const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
/* This message derives from H5Z */
@@ -47,15 +79,53 @@ H5Z_class_t H5Z_DTYPE_MODIFY[1] = {{
"dtype_modify", /* Filter name for debugging */
NULL, /* The "can apply" callback */
H5Z_set_local_dtype_modify, /* The "set local" callback */
- H5Z_reset_local_dtype_modify, /* The "reset local" callback */
+ H5Z_reset_local_dtype_modify, /* The "reset local" callback */
+ H5Z_change_local_dtype_modify,/* The "change local" callback*/
+ H5Z_evict_local_dtype_modify, /* The "evict local" callback */
+ H5Z_delete_local_dtype_modify, /* The "delete local" callback */
+ H5Z_close_local_dtype_modify, /* The "close local" callback */
H5Z_filter_dtype_modify, /* The actual filter function */
}};
+typedef struct H5Z_slist_node_t {
+ H5T_t *dtype;
+ hbool_t type_modified;
+ hsize_t key;
+} H5Z_slist_node_t;
+
+/* Typedef for native 'name' field index records in the v2 B-tree */
+typedef struct H5Z_mdtype_bt2_rec_t {
+ uint8_t version;
+ uint8_t is_shared;
+ uint64_t numb_ref;
+ H5T_t *dtype;
+ hbool_t found;
+ uint8_t adjust;
+} H5Z_mdtype_bt2_rec_t;
+
+/* The v2 B-tree class for indexing 'datatype' field */
+const H5B2_class_t H5Z_BT2_DTYPE[1]={{ /* B-tree class information */
+ H5B2_MODIFY_TYPE_ID, /* Type of B-tree */
+ sizeof(H5Z_mdtype_bt2_rec_t), /* Size of native record */
+ H5Z_btree2_dtype_store, /* Record storage callback */
+ H5Z_btree2_dtype_retrieve, /* Record retrieval callback */
+ H5Z_btree2_dtype_compare, /* Record comparison callback */
+ H5Z_btree2_dtype_encode, /* Record encoding callback */
+ H5Z_btree2_dtype_decode, /* Record decoding callback */
+ NULL /* Record debugging callback */
+}};
+
+
+/* Declare a free list to manage H5Z_slist_node_t objects */
+H5FL_DEFINE_STATIC(H5Z_slist_node_t);
+
/*-------------------------------------------------------------------------
* Function: H5Z_set_local_dtype_modify
*
- * Purpose: Set the "local" dataset parameters for datatype modification
+ * Purpose: Set the "local" dataset parameters for datatype modification.
+ * They are the ID of the dataset's datatype and the file
+ * pointer.
*
* Return: Success: Non-negative
* Failure: Negative
@@ -71,36 +141,149 @@ static herr_t
H5Z_set_local_dtype_modify(hid_t dcpl_id, hid_t dtype_id, hid_t UNUSED space_id,
hid_t file_id)
{
+ H5P_genplist_t *dc_plist = NULL; /* New Property list */
H5F_t *file=NULL; /* File object for file ID */
- size_t cd_nelmts = 1; /* Number of filter parameters */
- unsigned cd_values[8]={0,0,0,0,0,0,0,0}; /* Filter parameters */
+ H5T_t *dt = NULL; /* Datatype object for datatype ID */
+ H5SL_t *chunk_slist=NULL; /* Skip list for keeping record of chunks */
+ size_t dt_size; /* the size of datatype */
+ size_t bt2_rrec_size; /* v2 B-tree raw record size */
+ haddr_t baddr; /* Address of B-tree to store dtype info */
+ size_t cd_nelmts = 0; /* Number of filter parameters */
+ unsigned count = 0; /* Keeps track of pointer size */
+ unsigned baddr_count = 0; /* Keeps track of btree address size */
+ unsigned cd_values[CD_NELMTS]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* Filter parameters */
uint8_t *pp = NULL;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5Z_set_local_dtype_modify, FAIL)
+ /* Get the dataset's property list object */
+ if(NULL == (dc_plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get dataset creation property list")
+
if(NULL == (file = H5I_object_verify(file_id, H5I_FILE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
- /* The first element of the client data is the ID of dataset's datatype */
- cd_values[0] = dtype_id;
+ /* Check args */
+ if (NULL == (dt = H5I_object_verify(dtype_id,H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
- pp = (uint8_t*)((unsigned *)cd_values + 1);
+ /* The first element of the client data is reserved for COUNT, which is
+ * copied toward the end of this function. COUNT has two digits and
+ * keeps track of the number of elements in CD_VALUES except itself (first
+ * digit) and the size of file pointer and skip list pointer (second digit).
+ */
+ cd_nelmts = 1;
+
+ /* The second element of the client data is the ID of dataset's datatype. */
+ cd_values[1] = dtype_id;
+ cd_nelmts += 1;
+ count = 10;
+
+ pp = (uint8_t*)((unsigned *)cd_values + 2);
/*
- * The second is the file pointer copied as unsigned integer. Depending
- * on the size of pointer, it may take the space of 1 - 2 elements.
+ * The third is the file pointer copied as unsigned integer. The size of
+ * the pointer can be 4 or 8 bytes. Turn on the first digit of COUNT
+ * if the pointer size is 8 bytes. 8-byte pointer should take 2 CD_NELMTS.
*/
HDmemcpy(pp, &file, sizeof(H5F_t*));
- if(4 == sizeof(H5F_t*))
+ count +=10;
+ if(4 == sizeof(H5F_t*)) {
cd_nelmts += 1;
- else if(8 == sizeof(H5F_t*))
+ pp += 4;
+ } else if(8 == sizeof(H5F_t*)) {
cd_nelmts += 2;
- else
+ count +=1;
+ pp += 8;
+ } else
HGOTO_ERROR(H5E_PLINE, H5E_CANTENCODE, FAIL, "not implemented yet")
+ /* Create skip list to keep track of visited chunk. It's created here
+ * because the filter needs it when the dataset is just created and the
+ * data is being written to the file. But keep in mind that the client
+ * data is saved in the file. Everything is invalid when the file is
+ * reopened and the client data is retrieved. */
+ if((chunk_slist = H5SL_create(H5SL_TYPE_HSIZE, 0.5, (size_t)16)) == NULL)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTCREATE, FAIL, "can't create skip list for chunks")
+
+ /* The fourth element is the skip list for chunks. Again the second digit
+ * indicates whether the pointer is 8 bytes. */
+ HDmemcpy(pp, &chunk_slist, sizeof(H5SL_t*));
+ count += 10;
+ if(4 == sizeof(H5SL_t*)) {
+ cd_nelmts += 1;
+ pp += 4;
+ } else if(8 == sizeof(H5SL_t*)) {
+ count += 1;
+ cd_nelmts += 2;
+ pp += 8;
+ } else
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTENCODE, FAIL, "not implemented yet")
+
+ /* Set the COUNT */
+ cd_values[0] = count;
+
+ /* Generally only support committed or shared datatype. Check it
+ * here because this function can be called by H5D_create. We also allow
+ * integer or floating number because of their limited encoding size.
+ */
+ if(!H5T_committed(dt) &&
+ !H5SM_can_share(file, H5AC_dxpl_id, NULL, NULL, H5O_DTYPE_ID, dt)) {
+ H5T_class_t tclass;
+ if((tclass = H5T_get_class(dt, TRUE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't find datatype class")
+
+ if(tclass != H5T_INTEGER && tclass != H5T_FLOAT)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "violate datatype restriction")
+ }
+
+ /* Check if the datatype should be (or are already) shared in the SOHM table */
+ if(H5SM_try_share(file, H5AC_dxpl_id, NULL, H5O_DTYPE_ID, dt, NULL) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADMESG, FAIL, "trying to share datatype failed")
+
+ /* Get the encoding size of the dataset's datatype */
+ if((dt_size = H5O_msg_raw_size(file, H5O_DTYPE_ID, FALSE, dt))==0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, 0, "can't find datatype size")
+
+ /* If the datatype is committed or shared, its size should be the address plus
+ * index of heap, which is 12. If the datatype is predefined, the encoding
+ * size should be at most 20 bytes (for floating number. See H5O_dtype_size in
+ * H5Odtype.c). Because the datatype may be changed later, we make it big
+ * enough now.
+ */
+ if(dt_size < 20)
+ dt_size = 20;
+
+ /* Create a B-tree to store the info of all the dtypes used by the chunks. */
+ bt2_rrec_size = 1 + /* version number */
+ 1 + /* flag for shared datatype */
+ dt_size + /* datatype info */
+ 8; /* Number of reference */
+
+ if(H5B2_create(file, H5AC_dxpl_id, H5Z_BT2_DTYPE, (size_t)H5Z_DTYPE_BT2_NODE_SIZE,
+ bt2_rrec_size, H5Z_DTYPE_BT2_SPLIT_PERC, H5Z_DTYPE_BT2_MERGE_PERC, &baddr/*out*/) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "can't create B-tree")
+
+ /* the B-tree address can be 8 or 16 byte in size */
+ if(8 == sizeof(haddr_t)) {
+ baddr_count = 2;
+ cd_nelmts += 2;
+ } else if(16 == sizeof(haddr_t)) {
+ baddr_count = 4;
+ cd_nelmts += 4;
+ } else
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTENCODE, FAIL, "not implemented yet")
+
+ HDmemcpy(pp, &baddr_count, sizeof(unsigned));
+ pp += 4;
+ cd_nelmts += 1;
+
+ HDmemcpy(pp, &baddr, sizeof(haddr_t));
+
/* Modify the filter's parameters for this dataset */
- if(H5Pmodify_filter(dcpl_id, H5Z_FILTER_DTYPE_MODIFY, H5Z_FLAG_MANDATORY, (size_t)cd_nelmts, cd_values) < 0)
+ if(H5P_modify_filter(dc_plist, H5Z_FILTER_DTYPE_MODIFY, H5Z_FLAG_MANDATORY,
+ (size_t)cd_nelmts, cd_values) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTSET, FAIL, "can't set local parameters")
done:
@@ -114,7 +297,8 @@ done:
* Purpose: Reset the "local" dataset parameters for datatype
* modification. This function is the same as
* H5Z_set_local_dtype_modify. But it's called after the
- * dataset has been created.
+ * dataset has been created to update some info like file_id
+ * and datatype. It's called by H5D_modify_dtype and H5D_open.
*
* Return: Success: Non-negative
* Failure: Negative
@@ -128,14 +312,150 @@ done:
*/
static herr_t
H5Z_reset_local_dtype_modify(hid_t dcpl_id, hid_t dtype_id, hid_t UNUSED space_id,
- hid_t file_id)
+ hid_t file_id, hbool_t from_reopen)
{
+ H5P_genplist_t *dc_plist = NULL; /* New Property list */
+ H5F_t *file=NULL; /* File object for file ID */
+ H5SL_t *chunk_slist=NULL; /* Skip list for keeping record of chunks */
+ size_t cd_nelmts = 0; /* Number of filter parameters */
+ size_t orig_cd_nelmts = CD_NELMTS; /* Number of filter parameters */
+ unsigned count = 0; /* Keeps track of pointer size */
+ unsigned orig_count = 0; /* Keeps track of pointer size */
+ unsigned baddr_count = 0; /* Keeps track of pointer size */
+ unsigned orig_baddr_count = 0; /* Keeps track of pointer size */
+ unsigned cd_values[CD_NELMTS]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* Filter parameters */
+ unsigned orig_cd_values[CD_NELMTS]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* Filter parameters */
+ uint8_t *pp = NULL;
+ uint8_t *orig_pp = NULL;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5Z_reset_local_dtype_modify, FAIL)
- if((ret_value = H5Z_set_local_dtype_modify(dcpl_id, dtype_id, space_id, file_id))<0)
- HGOTO_ERROR(H5E_PLINE, H5E_CANTSET, FAIL, "can't reset local parameters")
+ /* Get the dataset's property list object */
+ if(NULL == (dc_plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get dataset creation property list")
+
+ if(H5P_get_filter_by_id(dc_plist, H5Z_FILTER_DTYPE_MODIFY, NULL,
+ &orig_cd_nelmts, orig_cd_values, (size_t)0, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get filter info")
+
+ orig_count = orig_cd_values[0];
+
+ if(NULL == (file = H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+
+ /* The first element of the client data is reserved for COUNT, which is
+ * copied toward the end of this function. COUNT has two digits and
+ * keeps track of the number of elements in CD_VALUES except itself (first
+ * digit) and the size of file pointer and skip list pointer (second digit).
+ */
+ cd_nelmts = 1;
+
+ /* The second element of the client data is the ID of dataset's datatype */
+ cd_values[1] = dtype_id;
+ cd_nelmts += 1;
+ count = 10;
+
+ pp = (uint8_t*)((unsigned *)cd_values + 2);
+
+ /*
+ * The third is the file pointer copied as unsigned integer. Depending
+ * on the size of pointer, it may take the space of 1 - 2 elements.
+ */
+ HDmemcpy(pp, &file, sizeof(H5F_t*));
+ if(4 == sizeof(H5F_t*)) {
+ cd_nelmts += 1;
+ count += 10;
+ pp += 4;
+ } else if(8 == sizeof(H5F_t*)) {
+ cd_nelmts += 2;
+ count += 10;
+ count += 1;
+ pp += 8;
+ } else
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTENCODE, FAIL, "not implemented yet")
+
+ /* Check whether the skip list for visited chunks has been created. If the first
+ * digit of original COUNT is 2, there're only 2 elements, and the skip list hasn't
+ * been created. If this function is called by H5Dopen and FROM_REOPEN is set, the
+ * pointer value is invalid because the client data was saved in the file. Create
+ * a new skip list in this case. If it's 3 and FROM_REOPEN isn't set, the skip
+ * list has been created. Simply copy the pointer over.
+ */
+ if(orig_count < 30 || from_reopen) {
+ /* Create skip list to keep track of visited chunk */
+ if((chunk_slist = H5SL_create(H5SL_TYPE_HSIZE, 0.5, (size_t)16)) == NULL)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTCREATE, FAIL, "can't create skip list for chunks")
+
+ /* The fourth element is the skip list for chunks. Again the second digit
+ * indicates whether the pointer is 8 bytes. */
+ HDmemcpy(pp, &chunk_slist, sizeof(H5SL_t*));
+ count += 10;
+ if(4 == sizeof(H5SL_t*)) {
+ cd_nelmts += 1;
+ pp += 4;
+ } else if(8 == sizeof(H5SL_t*)) {
+ count += 1;
+ cd_nelmts += 2;
+ pp += 8;
+ } else
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTENCODE, FAIL, "not implemented yet")
+
+ if(orig_count == 20)
+ orig_pp = (uint8_t*)((unsigned *)orig_cd_values + 3);
+ else if(orig_count > 20 && orig_count <= 30)
+ orig_pp = (uint8_t*)((unsigned *)orig_cd_values + 4);
+ else if(orig_count > 30)
+ orig_pp = (uint8_t*)((unsigned *)orig_cd_values + 6);
+ } else if (orig_count == 30 && !from_reopen) {
+ /* Copy the skip list. The size of pointer is 4 bytes. */
+ orig_pp = (uint8_t*)((unsigned *)orig_cd_values + 3);
+ HDmemcpy(pp, orig_pp, 4);
+ count += 10;
+ cd_nelmts += 1;
+ pp += 4;
+ orig_pp += 4;
+ } else if (orig_count > 30 && !from_reopen) {
+ /* Copy the skip list. The size of pointer is 8 bytes. */
+ orig_pp = (uint8_t*)((unsigned *)orig_cd_values + 4);
+ HDmemcpy(pp, orig_pp, 8);
+ count += 10;
+ count += 1;
+ cd_nelmts += 2;
+ pp += 8;
+ orig_pp += 8;
+ } else
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTENCODE, FAIL, "not implemented yet")
+
+ /* Set the COUNT */
+ cd_values[0] = count;
+
+ /* Copy B-tree address to the new client data */
+ HDmemcpy(&orig_baddr_count, orig_pp, sizeof(unsigned));
+ orig_pp += 4;
+
+ /* the B-tree address can be 8 or 16 byte in size */
+ if(orig_baddr_count == 2) {
+ baddr_count = 2;
+ HDmemcpy(pp, &baddr_count, sizeof(unsigned));
+ pp += 4;
+ cd_nelmts += 1;
+ HDmemcpy(pp, orig_pp, 8);
+ cd_nelmts += 2;
+ } else if(orig_baddr_count == 4) {
+ baddr_count = 4;
+ HDmemcpy(pp, &baddr_count, sizeof(unsigned));
+ pp += 4;
+ cd_nelmts += 1;
+ HDmemcpy(pp, orig_pp, 16);
+ cd_nelmts += 4;
+ } else
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTCOPY, FAIL, "not implemented yet")
+
+ /* Modify the filter's parameters for this dataset */
+ if(H5P_modify_filter(dc_plist, H5Z_FILTER_DTYPE_MODIFY, H5Z_FLAG_MANDATORY,
+ (size_t)cd_nelmts, cd_values) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTSET, FAIL, "can't set local parameters")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -143,6 +463,631 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Z_change_local_dtype_modify
+ *
+ * Purpose: Search the node of the skip list for chunk info and update it.
+ * This function is called by H5D_istore_conv_dtype when the
+ * datatype is changed and all the chunks in the cache have
+ * to be converted.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * 16 April 2008
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_change_local_dtype_modify(hid_t dcpl_id, hsize_t chunk_offset)
+{
+ H5P_genplist_t *dc_plist = NULL; /* New Property list */
+ H5SL_t *chunk_slist=NULL; /* Skip list for keeping record of chunks */
+ H5Z_slist_node_t *node;
+ size_t cd_nelmts=CD_NELMTS; /* Number of filter parameters */
+ unsigned count = 0; /* Keeps track of pointer size */
+ unsigned cd_values[CD_NELMTS]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* Filter parameters */
+ uint8_t *pp = NULL;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_change_local_dtype_modify, FAIL)
+
+ HDassert(H5I_GENPROP_LST==H5I_get_type(dcpl_id));
+
+ /* Get the dataset's property list object */
+ if(NULL == (dc_plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get dataset creation property list")
+
+ if(H5P_get_filter_by_id(dc_plist, H5Z_FILTER_DTYPE_MODIFY, NULL, &cd_nelmts, cd_values,
+ (size_t)0, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get filter info")
+
+ /* If the skip list exists, update the dtype modification info for the chunk */
+ count = cd_values[0];
+
+ if(count >= 30) {
+ pp = (uint8_t*)((unsigned *)cd_values + 2);
+
+ /* Depending on the size of pointer, retrieve the value of the pointer to
+ * the skip list. */
+ if (count == 30) {
+ pp += 4;
+ HDmemcpy(&chunk_slist, pp, 4);
+ } else if (count > 30) {
+ pp += 8;
+ HDmemcpy(&chunk_slist, pp, 8);
+ }
+
+ if(!chunk_slist)
+ HGOTO_ERROR(H5E_SLIST, H5E_CANTGET, FAIL, "can't find skip list")
+
+ /* Search the skip list and update the node */
+ if(NULL != (node = H5SL_search(chunk_slist, &chunk_offset)))
+ node->type_modified = TRUE;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_change_local_dtype_modify */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_evict_local_dtype_modify
+ *
+ * Purpose: Search the node of the skip list for chunk and remove the
+ * node. This function is called when the chunk is evicted
+ * from the cache.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * 16 April 2008
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_evict_local_dtype_modify(hid_t dcpl_id, hsize_t chunk_offset)
+{
+ H5P_genplist_t *dc_plist = NULL; /* New Property list */
+ H5SL_t *chunk_slist=NULL; /* Skip list for keeping record of chunks */
+ H5Z_slist_node_t *node;
+ size_t cd_nelmts=CD_NELMTS; /* Number of filter parameters */
+ unsigned count = 0; /* Keeps track of pointer size */
+ unsigned cd_values[CD_NELMTS]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* Filter parameters */
+ uint8_t *pp = NULL;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_evict_local_dtype_modify, FAIL)
+
+ HDassert(H5I_GENPROP_LST==H5I_get_type(dcpl_id));
+
+ /* Get the dataset's property list object */
+ if(NULL == (dc_plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get dataset creation property list")
+
+ if(H5P_get_filter_by_id(dc_plist, H5Z_FILTER_DTYPE_MODIFY, NULL, &cd_nelmts, cd_values,
+ (size_t)0, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get filter info")
+
+ /* If the skip list exists, remove the node for the chunk */
+ count = cd_values[0];
+
+ if(count >= 30 ) {
+ pp = (uint8_t*)((unsigned *)cd_values + 2);
+
+ /* Depending on the size of pointer, retrieve the value of the pointer to
+ * the skip list. */
+ if (count == 30) {
+ pp += 4;
+ HDmemcpy(&chunk_slist, pp, 4);
+ } else if (count > 30) {
+ pp += 8;
+ HDmemcpy(&chunk_slist, pp, 8);
+ }
+
+ if(!chunk_slist)
+ HGOTO_ERROR(H5E_SLIST, H5E_CANTGET, FAIL, "can't find skip list")
+
+ /* Search the skip list and update the node */
+ if(NULL != (node = H5SL_remove(chunk_slist, &chunk_offset))) {
+ /* Check whether datatype is committed & decrement ref count
+ * (to maintain ref. count incr/decr similarity with "shared message"
+ * type of datatype sharing)
+ */
+ if(H5T_committed(node->dtype)) {
+ /* Decrement the reference count on the committed datatype */
+ if(H5T_link(node->dtype, -1, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count")
+ } /* end if */
+
+ if(H5T_close(node->dtype) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "can't close data type")
+
+ H5FL_FREE(H5Z_slist_node_t, node);
+ }
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_evict_local_dtype_modify */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_delete_local_dtype_modify
+ *
+ * Purpose: When the dataset is deleted, free the nodes of the skip list
+ * and delete it. Also decrement the reference counts of the
+ * datatypes in B-tree nodes, free the nodes of the B-tree and
+ * delete it.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * 11 August 2008
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_delete_local_dtype_modify(hid_t dcpl_id)
+{
+ H5P_genplist_t *dc_plist = NULL; /* New Property list */
+ size_t cd_nelmts=CD_NELMTS; /* Number of filter parameters */
+ unsigned count = 0; /* Keeps track of pointer size */
+ unsigned cd_values[CD_NELMTS]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* Filter parameters */
+ uint8_t *pp = NULL;
+ H5F_t *file = NULL;
+ unsigned baddr_count = 0; /* Keeps track of pointer size */
+ haddr_t baddr; /* B-tree address */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_delete_local_dtype_modify, FAIL)
+
+ HDassert(H5I_GENPROP_LST==H5I_get_type(dcpl_id));
+
+ /* Get the dataset's property list object */
+ if(NULL == (dc_plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get dataset creation property list")
+
+ if(H5P_get_filter_by_id(dc_plist, H5Z_FILTER_DTYPE_MODIFY, NULL, &cd_nelmts, cd_values,
+ (size_t)0, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get filter info")
+
+ count = cd_values[0];
+ pp = (uint8_t*)((unsigned *)cd_values + 2);
+
+ /* Depending on number of elements and the size of pointer, retrieve the value
+ * of file pointer and skip list pointer. The first digit of CD_NELMTS indicates
+ * the number of elements in CD_VALUES. The second digit indicates whether the
+ * pointers are 8 bytes. 0 stands for 4 bytes. Greater than 0 means 8 bytes.
+ */
+ if (count == 20) {
+ HDmemcpy(&file, pp, 4);
+ pp += 4;
+ } else if (20 < count && count < 30) {
+ HDmemcpy(&file, pp, 8);
+ pp += 8;
+ } else if (count == 30) {
+ HDmemcpy(&file, pp, 4);
+ pp += 4;
+ /* Advance over the skip list address */
+ pp += 4;
+ } else if (count > 30) {
+ HDmemcpy(&file, pp, 8);
+ pp += 8;
+ /* Advance over the skip list address */
+ pp += 8;
+ } else
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTENCODE, 0, "not implemented yet")
+
+ HDmemcpy(&baddr_count, pp, sizeof(unsigned));
+ pp += 4;
+
+ /* the B-tree address can be 8 or 16 byte in size */
+ if(baddr_count == 2) {
+ HDmemcpy(&baddr, pp, 8);
+ } else if(baddr_count == 4) {
+ HDmemcpy(&baddr, pp, 16);
+ }
+
+ /* Delete the entire B-tree and decrement reference count of datatype */
+ if(H5B2_delete(file, H5AC_dxpl_id, H5Z_BT2_DTYPE, baddr, H5Z_btree2_dtype_delete_cb,
+ NULL) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "can't delete B-tree")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_delete_local_dtype_modify() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_close_local_dtype_modify
+ *
+ * Purpose: When the dataset is closed, free the nodes of the skip list
+ * and delete it.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * 22 Feb 2008
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_close_local_dtype_modify(hid_t dcpl_id)
+{
+ H5P_genplist_t *dc_plist = NULL; /* New Property list */
+ H5SL_t *chunk_slist=NULL; /* Skip list for keeping record of chunks */
+ size_t cd_nelmts=CD_NELMTS; /* Number of filter parameters */
+ unsigned count = 0; /* Keeps track of pointer size */
+ unsigned cd_values[CD_NELMTS]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* Filter parameters */
+ uint8_t *pp = NULL;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_close_local_dtype_modify, FAIL)
+
+ HDassert(H5I_GENPROP_LST==H5I_get_type(dcpl_id));
+
+ /* Get the dataset's property list object */
+ if(NULL == (dc_plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get dataset creation property list")
+
+ if(H5P_get_filter_by_id(dc_plist, H5Z_FILTER_DTYPE_MODIFY, NULL, &cd_nelmts, cd_values, (size_t)0, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get filter info")
+
+ count = cd_values[0];
+ pp = (uint8_t*)((unsigned *)cd_values + 2);
+
+ /* Depending on the size of pointer, retrieve the value of the pointer to
+ * the skip list. */
+ if (count == 30) {
+ pp += 4;
+ HDmemcpy(&chunk_slist, pp, 4);
+ } else if (count > 30) {
+ pp += 8;
+ HDmemcpy(&chunk_slist, pp, 8);
+ }
+
+ /* Free the skip list */
+ if(chunk_slist && H5SL_destroy(chunk_slist, H5Z_free_slist_node, NULL) < 0)
+ HGOTO_ERROR(H5E_SLIST, H5E_CANTFREE, FAIL, "can't free skip list")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_close_local_dtype_modify() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_free_slist_node
+ *
+ * Purpose: Private function for H5SL_destroy. Frees the nodes of
+ * skip list.
+ *
+ * Return: Non-negative on success, negative on failure
+ *
+ * Programmer: Raymond Lu
+ * 22 February 2008
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_free_slist_node(void *item, void UNUSED *key, void UNUSED *operator_data/*in,out*/)
+{
+ H5T_t *dtype = ((H5Z_slist_node_t*)item)->dtype;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_free_slist_node, FAIL)
+
+ /* Check whether datatype is committed & decrement ref count
+ * (to maintain ref. count incr/decr similarity with "shared message"
+ * type of datatype sharing)
+ */
+ if(H5T_committed(dtype)) {
+ /* Decrement the reference count on the committed datatype */
+ if(H5T_link(dtype, -1, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count")
+ } /* end if */
+
+ if(H5T_close(dtype) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "can't close data type")
+
+ H5FL_FREE(H5Z_slist_node_t, item);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_free_slist_node */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_btree2_dtype_store
+ *
+ * Purpose: Store user information into native record for v2 B-tree
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Raymond Lu
+ * 5 August 2008
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_btree2_dtype_store(void *_nrecord, const void *_udata)
+{
+ const H5Z_mdtype_bt2_rec_t *udata = (const H5Z_mdtype_bt2_rec_t *)_udata;
+ H5Z_mdtype_bt2_rec_t *nrecord = (H5Z_mdtype_bt2_rec_t *)_nrecord;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5Z_btree2_dtype_store, FAIL)
+
+ /* Copy user information info native record */
+ nrecord->version = udata->version;
+ nrecord->is_shared = udata->is_shared;
+ nrecord->numb_ref = udata->numb_ref;
+
+ /* Make a copy of the datatype because Btree resides in the cache separately.
+ * The dataset can be closed first. */
+ if((nrecord->dtype = H5T_copy(udata->dtype, H5T_COPY_ALL)) == NULL)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTCOPY, FAIL, "can't copy datatype")
+
+done:
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5Z_btree2_dtype_store() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_btree2_dtype_retrieve
+ *
+ * Purpose: Retrieve native information from record for v2 B-tree
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Raymond Lu
+ * 5 August 2008
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_btree2_dtype_retrieve(void *udata, const void *nrecord)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5Z_btree2_dtype_retrieve)
+
+ *(H5Z_mdtype_bt2_rec_t *)udata = *(const H5Z_mdtype_bt2_rec_t *)nrecord;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5Z_btree2_dtype_retrieve() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_btree2_dtype_encode
+ *
+ * Purpose: Encode native information into raw form for storing on disk
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Raymond Lu
+ * 5 August 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_btree2_dtype_encode(const H5F_t *f, uint8_t *raw, const void *_nrecord)
+{
+ const H5Z_mdtype_bt2_rec_t *nrecord = (const H5Z_mdtype_bt2_rec_t *)_nrecord;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5Z_btree2_dtype_encode, FAIL)
+
+ /* Encode the record's fields */
+ *raw++ = nrecord->version;
+
+ /* Encode the flag indicating whether the dtype is shared in Btree node buffer */
+ *raw++ = nrecord->is_shared;
+
+ UINT64ENCODE(raw, nrecord->numb_ref);
+
+ /* encode datatype info into Btree node buffer */
+ if(H5O_msg_encode((H5F_t *)f, H5O_DTYPE_ID, FALSE, (unsigned char *)raw,
+ (const void *)nrecord->dtype)<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTENCODE, FAIL, "can't encode object")
+
+ if(H5T_close(nrecord->dtype) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CLOSEERROR, FAIL, "can't close datatype")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5Z_btree2_dtype_encode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_btree2_dtype_decode
+ *
+ * Purpose: Decode raw disk form of record into native form
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Raymond Lu
+ * 5 August 2008
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_btree2_dtype_decode(const H5F_t *f, const uint8_t *raw, void *_nrecord)
+{
+ H5Z_mdtype_bt2_rec_t *nrecord = (H5Z_mdtype_bt2_rec_t *)_nrecord;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5Z_btree2_dtype_decode, FAIL)
+
+ /* Decode the record's fields */
+ nrecord->version = *raw++;
+ nrecord->is_shared = *raw++;
+ UINT64DECODE(raw, nrecord->numb_ref);
+
+ /*
+ * Decode the original datatype info from the chunk of data which might
+ * be shared or not shared.
+ */
+ if(nrecord->is_shared && (nrecord->dtype=(H5T_t *)H5O_msg_decode((H5F_t *)f,
+ H5AC_dxpl_id, H5O_DTYPE_ID, (const unsigned char *)raw, H5O_MSG_FLAG_SHARED))==NULL)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "can't decode object")
+ else if(!nrecord->is_shared && (nrecord->dtype=(H5T_t *)H5O_msg_decode((H5F_t *)f,
+ H5AC_dxpl_id, H5O_DTYPE_ID, (const unsigned char *)raw, H5O_MSG_FLAG_WAS_UNKNOWN))==NULL)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "can't decode object")
+
+done:
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5Z_btree2_dtype_decode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_btree2_dtype_compare
+ *
+ * Purpose: Compare two native information records, according to some key
+ *
+ * Return: <0 if rec1 < rec2
+ * =0 if rec1 == rec2
+ * >0 if rec1 > rec2
+ *
+ * Programmer: Raymond Lu
+ * 5 August 2008
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_btree2_dtype_compare(const void *_bt2_udata, const void *_bt2_rec)
+{
+ const H5Z_mdtype_bt2_rec_t *bt2_udata = (const H5Z_mdtype_bt2_rec_t *)_bt2_udata;
+ const H5Z_mdtype_bt2_rec_t *bt2_rec = (const H5Z_mdtype_bt2_rec_t *)_bt2_rec;
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5Z_btree2_dtype_compare)
+
+ /* Sanity check */
+ HDassert(bt2_udata);
+ HDassert(bt2_rec);
+
+ ret_value = H5T_cmp(bt2_udata->dtype, bt2_rec->dtype, FALSE);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5Z_btree2_dtype_compare() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_btree2_dtype_find_cb
+ *
+ * Purpose: Callback function for H5B2_find function.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Raymond Lu
+ * 5 August 2008
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_btree2_dtype_find_cb(void *record, void *op_data)
+{
+ H5Z_mdtype_bt2_rec_t *my_record = (H5Z_mdtype_bt2_rec_t *)record;
+ H5Z_mdtype_bt2_rec_t *udata = (H5Z_mdtype_bt2_rec_t *)op_data;
+ int compare;
+ herr_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5Z_btree2_dtype_find_cb)
+
+ compare = H5T_cmp(my_record->dtype, udata->dtype, FALSE);
+
+ if(compare == 0) {
+ if(udata->adjust == H5Z_MDTYPE_INC)
+ my_record->numb_ref++;
+ else if(udata->adjust == H5Z_MDTYPE_DEC)
+ my_record->numb_ref--;
+
+ udata->numb_ref = my_record->numb_ref;
+ udata->found = TRUE;
+ ret_value = SUCCEED;
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_btree2_dtype_remove_cb
+ *
+ * Purpose: Callback function for H5B2_remove function.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Raymond Lu
+ * 5 August 2008
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_btree2_dtype_remove_cb(void *record, void *op_data)
+{
+ H5Z_mdtype_bt2_rec_t *my_record = (H5Z_mdtype_bt2_rec_t *)record;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_btree2_dtype_remove_cb, FAIL)
+
+ /* Close the datatype saved in Btree node */
+ if(H5T_close(my_record->dtype) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CLOSEERROR, FAIL, "can't close datatype")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_btree2_dtype_delete_cb
+ *
+ * Purpose: Callback function for H5B2_delete function.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Raymond Lu
+ * 5 August 2008
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_btree2_dtype_delete_cb(void *record, void *op_data)
+{
+ H5Z_mdtype_bt2_rec_t *my_record = (H5Z_mdtype_bt2_rec_t *)record;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_btree2_dtype_delete_cb, FAIL)
+
+ /* Check whether datatype is committed & decrement ref count
+ * (to maintain ref. count incr/decr similarity with "shared message"
+ * type of datatype sharing)
+ */
+ if(H5T_committed(my_record->dtype)) {
+ /* Decrement the reference count on the committed datatype */
+ if(H5T_link(my_record->dtype, (int)-my_record->numb_ref, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count")
+ } /* end if */
+
+ if(H5T_close(my_record->dtype) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CLOSEERROR, FAIL, "can't close datatype")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5Z_filter_dtype_modify
*
* Purpose: Implement the I/O filter of the datatype modification for
@@ -163,8 +1108,8 @@ done:
*/
/* ARGSUSED */
static size_t
-H5Z_filter_dtype_modify (unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
- size_t nbytes, size_t *buf_size, void **buf)
+H5Z_filter_dtype_modify (unsigned flags, hsize_t chunk_offset, size_t cd_nelmts,
+ const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf)
{
unsigned char *outbuf = NULL; /* Pointer to new buffer */
hid_t dtype_id;
@@ -173,49 +1118,101 @@ H5Z_filter_dtype_modify (unsigned flags, size_t cd_nelmts, const unsigned cd_val
size_t type_msg_size;
size_t nelmts, dbuf_size;
H5F_t *file = NULL;
+ H5SL_t *chunk_slist=NULL; /* Skip list for keeping record of chunks */
+ H5Z_slist_node_t *node;
uint8_t *pp = NULL;
unsigned char *dst=NULL; /* Temporary pointer to destination buffer */
- size_t ret_value; /* Return value */
+ unsigned count = 0; /* Keeps track of pointer size */
+ unsigned baddr_count = 0; /* Keeps track of pointer size */
+ haddr_t baddr; /* B-tree address */
+ int8_t is_shared = FALSE; /* Whether dtype is committed or shared */
+ size_t ret_value=nbytes; /* Return value */
FUNC_ENTER_NOAPI(H5Z_filter_dtype_modify, 0)
- assert(cd_nelmts==2 || cd_nelmts==3);
+ count = cd_values[0];
+
+ assert(cd_nelmts>=2 && cd_nelmts<=10);
+ assert(count>=20 && count<40);
/* Get the dataset's datatype */
- dtype_id = cd_values[0];
- pp = (uint8_t*)((unsigned *)cd_values + 1);
+ dtype_id = cd_values[1];
+ pp = (uint8_t*)((unsigned *)cd_values + 2);
- /* Depending on the size of pointer, retrieve the value of file pointer */
- if(2 == cd_nelmts) {
+ /* Depending on number of elements and the size of pointer, retrieve the value
+ * of file pointer and skip list pointer. The first digit of CD_NELMTS indicates
+ * the number of elements in CD_VALUES. The second digit indicates whether the
+ * pointers are 8 bytes. 0 stands for 4 bytes. Greater than 0 means 8 bytes.
+ */
+ if (count == 20) {
HDmemcpy(&file, pp, 4);
- } else if(3 == cd_nelmts) {
+ pp += 4;
+ } else if (20 < count && count < 30) {
HDmemcpy(&file, pp, 8);
+ pp += 8;
+ } else if (count == 30) {
+ HDmemcpy(&file, pp, 4);
+ pp += 4;
+ HDmemcpy(&chunk_slist, pp, 4);
+ pp += 4;
+ } else if (count > 30) {
+ HDmemcpy(&file, pp, 8);
+ pp += 8;
+ HDmemcpy(&chunk_slist, pp, 8);
+ pp += 8;
} else
HGOTO_ERROR(H5E_PLINE, H5E_CANTENCODE, 0, "not implemented yet")
+ HDmemcpy(&baddr_count, pp, sizeof(unsigned));
+ pp += 4;
+
+ /* the B-tree address can be 8 or 16 byte in size */
+ if(baddr_count == 2) {
+ HDmemcpy(&baddr, pp, 8);
+ } else if(baddr_count == 4) {
+ HDmemcpy(&baddr, pp, 16);
+ }
+
/* The current datatype of the dataset */
if(NULL==(dtype=(H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype")
- if (flags & H5Z_FLAG_REVERSE) { /* Read */
+ if (flags & H5Z_FLAG_REVERSE) { /*Read*/
+ uint8_t version = 0;
+ hid_t orig_type_id;
+ size_t info_size = 0; /* the size of the encoded information except raw data */
+
+ /* Retrieve and verify version number */
+ HDmemcpy(&version, *buf, sizeof(uint8_t));
+
+ if(version != H5Z_DTYPE_MODIFY_VERS)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, 0, "wrong version number")
+
+ info_size = 1;
+
+ /* Retrieve the flag indicating whether the dtype is committed or shared */
+ outbuf = (unsigned char*)*buf + 1;
+ HDmemcpy(&is_shared, outbuf, sizeof(int8_t));
+ info_size += 1;
+ outbuf += 1;
+
/*
* Decode the original datatype info from the chunk of data which might
- * be shared or not shared. Try to treat it as shared then non-shared.
+ * be shared or not shared.
*/
- H5E_BEGIN_TRY {
- orig_type=(H5T_t *)H5O_msg_decode(file, H5AC_dxpl_id, H5O_DTYPE_ID,
- (unsigned char *)*buf, H5O_MSG_FLAG_SHARED);
- } H5E_END_TRY;
-
- if(!orig_type) {
- if((orig_type=(H5T_t *)H5O_msg_decode(file, H5AC_dxpl_id, H5O_DTYPE_ID, (unsigned char *)*buf, H5O_MSG_FLAG_WAS_UNKNOWN))==NULL)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, 0, "can't decode object")
- }
+ if(is_shared && (orig_type=(H5T_t *)H5O_msg_decode(file, H5AC_dxpl_id, H5O_DTYPE_ID,
+ outbuf, H5O_MSG_FLAG_SHARED))==NULL)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, 0, "can't decode object")
+ else if(!is_shared && (orig_type=(H5T_t *)H5O_msg_decode(file, H5AC_dxpl_id,
+ H5O_DTYPE_ID, outbuf, H5O_MSG_FLAG_WAS_UNKNOWN))==NULL)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, 0, "can't decode object")
/* Get the encoding size of the original datatype */
if((type_msg_size = H5O_msg_raw_size(file, H5O_DTYPE_ID, FALSE, orig_type))==0)
HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, 0, "can't find datatype size")
+ info_size += type_msg_size;
+
/* Calculate the size of buffer containing the new data */
if(0 != H5T_cmp(dtype, orig_type, FALSE)) {
if((dtype_size = H5T_get_size(dtype))==0)
@@ -225,19 +1222,19 @@ H5Z_filter_dtype_modify (unsigned flags, size_t cd_nelmts, const unsigned cd_val
nelmts = (nbytes-type_msg_size)/orig_size;
if(dtype_size <= orig_size)
- dbuf_size = nbytes-type_msg_size;
+ dbuf_size = nbytes-info_size;
else
dbuf_size = nelmts*dtype_size;
} else
- dbuf_size = nbytes-type_msg_size;
+ dbuf_size = nbytes-info_size;
/* Allocate the buffer for the data */
if (NULL==(dst=(unsigned char*)H5MM_malloc(dbuf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "unable to allocate buffer")
/* Copy the raw data */
- outbuf = (unsigned char*)*buf + type_msg_size;
- HDmemcpy((void*)dst, (void*)outbuf, nbytes-type_msg_size);
+ outbuf = (unsigned char*)*buf + info_size;
+ HDmemcpy((void*)dst, (void*)outbuf, nbytes-info_size);
/* Free input buffer */
H5MM_xfree(*buf);
@@ -248,35 +1245,31 @@ H5Z_filter_dtype_modify (unsigned flags, size_t cd_nelmts, const unsigned cd_val
*/
if(0 != H5T_cmp(dtype, orig_type, FALSE)) {
H5P_genplist_t *plist; /* Property list pointer */
- hbool_t is_vlen = FALSE; /* Flag to indicate VL type */
+ htri_t is_vlen = FALSE; /* Flag to indicate VL type */
hbool_t vlen_conv = TRUE; /* Transfer property to indicate no conversion for vlen */
H5T_path_t *tpath=NULL; /*type conversion info */
unsigned char *bkg=NULL; /* Pointer to background buffer */
- hid_t orig_type_id;
/* If the datatype is or contains vlen, set the property to indicate no conversion
* is needed for vlen. The file to memory conversion will take place at a
* higher level. */
- if((is_vlen = H5T_detect_class(orig_type, H5T_VLEN)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to detect dtatypes")
+ if((is_vlen = H5T_detect_class(orig_type, H5T_VLEN)) == FAIL)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, 0, "unable to detect dtatypes")
if(is_vlen ) {
vlen_conv = FALSE;
if(NULL == (plist = H5P_object_verify(H5AC_dxpl_id, H5P_DATASET_XFER)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADATOM, FAIL, "can't find object for ID")
+ HGOTO_ERROR(H5E_PLIST, H5E_BADATOM, 0, "can't find object for ID")
if(H5P_set(plist, H5D_XFER_VLEN_CONV_NAME, &vlen_conv) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "Error setting vlen conv flag")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, 0, "Error setting vlen conv flag")
}
/* Find the conversion function */
- if (NULL==(tpath=H5T_path_find(orig_type, dtype, NULL, NULL, /*H5P_DEFAULT*/H5AC_dxpl_id, FALSE)))
+ if (NULL==(tpath=H5T_path_find(orig_type, dtype, NULL, NULL, H5AC_dxpl_id, FALSE)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, 0, "unable to convert between src and dst data types");
/* Register the original type and return the ID */
- /*if((orig_type_copy = H5T_copy(orig_type,H5T_COPY_ALL)) == NULL)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, 0, "unable to copy data type")*/
-
if((orig_type_id = H5I_register(H5I_DATATYPE, orig_type)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, 0, "unable to register data type")
@@ -286,7 +1279,7 @@ H5Z_filter_dtype_modify (unsigned flags, size_t cd_nelmts, const unsigned cd_val
}
/* Convert the data */
- if (H5T_convert(tpath, orig_type_id, dtype_id, nelmts, (size_t)0, (size_t)0, dst, bkg, /*H5P_DATASET_XFER_DEFAULT*/H5AC_dxpl_id)<0)
+ if (H5T_convert(tpath, orig_type_id, dtype_id, nelmts, (size_t)0, (size_t)0, dst, bkg, H5AC_dxpl_id)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, 0, "data type conversion failed");
/* Set the property of vlen conversion back to normal */
@@ -294,12 +1287,9 @@ H5Z_filter_dtype_modify (unsigned flags, size_t cd_nelmts, const unsigned cd_val
vlen_conv = TRUE;
if(H5P_set(plist, H5D_XFER_VLEN_CONV_NAME, &vlen_conv) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "Error setting vlen conv flag")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, 0, "Error setting vlen conv flag")
}
- if(H5Tclose(orig_type_id)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, 0, "unable to close data type ID")
-
if(bkg)
H5MM_xfree(bkg);
}
@@ -308,41 +1298,95 @@ H5Z_filter_dtype_modify (unsigned flags, size_t cd_nelmts, const unsigned cd_val
if(0 != H5T_cmp(dtype, orig_type, FALSE))
*buf_size = nelmts*dtype_size;
else
- *buf_size = nbytes - type_msg_size;
+ *buf_size = nbytes - info_size;
*buf = (void*)dst;
dst = NULL;
outbuf = NULL;
ret_value = *buf_size;
- } else { /* Write */
- /* Mark the new datatype as being on disk now */
- if(H5T_set_loc(dtype, file, H5T_LOC_DISK) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, 0, "invalid datatype location")
+ /* If the caller isn't from fractal heap (the flag H5Z_FLAG_SKIP_CRECORD isn't
+ * set) and the current chunk isn't in the skip list, put the current datatype
+ * for this chunk in. When this datatype is being changed during the write
+ * call, the filter knows to decrement the reference count of the current type.
+ * The key of the node is the linear offset of the chunk in the dataspace. This
+ * linear offset is translated from the multi-dimensional offsets.
+ */
+ if(!(flags & H5Z_FLAG_SKIP_CRECORD) && chunk_slist) {
+ /* Allocate space for the shared structure */
+ if(NULL == (node = H5FL_MALLOC(H5Z_slist_node_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed")
+ node->key = chunk_offset;
+
+ if((NULL == H5SL_search(chunk_slist, &(node->key))) && H5T_committed(orig_type)) {
+ if ((NULL==(node->dtype=H5T_copy(orig_type, H5T_COPY_ALL))))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, 0, "unable to copy data type");
+
+ /* Check whether datatype is committed & increment ref count
+ * (to maintain ref. count incr/decr similarity with "shared message"
+ * type of datatype sharing)
+ */
+ /* Increment the reference count on the committed datatype */
+ if(H5T_link(node->dtype, 1, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_LINKCOUNT, 0, "unable to adjust shared datatype link count")
+
+ /* set the flag for the later increment and decrement of reference count */
+ if(0 != H5T_cmp(dtype, orig_type, FALSE))
+ node->type_modified = TRUE;
+ else
+ node->type_modified = FALSE;
+
+ if(H5SL_insert(chunk_slist, node, &(node->key)) < 0)
+ HGOTO_ERROR(H5E_SLIST, H5E_CANTINSERT, 0, "can't insert chunk node into skip list")
+ }
+ }
+
+ /* Close the ID registered for doing data conversion */
+ if(0 != H5T_cmp(dtype, orig_type, FALSE)) {
+ if(H5Tclose(orig_type_id)<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, 0, "unable to close data type ID")
+ }
+ } else if (!(flags & H5Z_FLAG_INVMASK) || (flags & H5Z_FLAG_SKIP_CRECORD)) { /*Write*/
+ uint8_t version = H5Z_DTYPE_MODIFY_VERS;
+ size_t final_size = 0;
+ htri_t is_shared_int;
+ herr_t found = FAIL;
+ H5Z_mdtype_bt2_rec_t udata;
+ hsize_t bnode_numb = 0;
+
+ /* Set the flag for committed or shared datatype */
+ if(H5T_committed(dtype))
+ is_shared = TRUE;
/* Check if the datatype should be (or are already) shared in the SOHM table */
- if(H5SM_try_share(file, H5AC_dxpl_id, NULL, H5O_DTYPE_ID, dtype, NULL) < 0)
+ if((is_shared_int = H5SM_try_share(file, H5AC_dxpl_id, NULL, H5O_DTYPE_ID, dtype, NULL)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_BADMESG, 0, "trying to share datatype failed")
-
- /* Check whether datatype is committed & increment ref count
- * (to maintain ref. count incr/decr similarity with "shared message"
- * type of datatype sharing)
- */
- if(H5T_committed(dtype)) {
- /* Increment the reference count on the shared datatype */
- if(H5T_link(dtype, 1, H5AC_dxpl_id) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_LINKCOUNT, 0, "unable to adjust shared datatype link count")
- } /* end if */
+ else if(is_shared_int)
+ is_shared = TRUE;
/* Get the encoding size of the dataset's datatype */
if((type_msg_size = H5O_msg_raw_size(file, H5O_DTYPE_ID, FALSE, dtype))==0)
HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, 0, "can't find datatype size")
+ /* Size of final chunk */
+ final_size = 1 /* Version number */
+ + 1 /* Whether dtype is committed or shared */
+ + type_msg_size /* Datatype message size */
+ + nbytes; /* Raw data size */
+
/* Allocate the buffer for the datatype info and the data */
- if (NULL==(dst=outbuf=(unsigned char*)H5MM_malloc(type_msg_size+nbytes)))
+ if (NULL==(dst=outbuf=(unsigned char*)H5MM_malloc(final_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "unable to allocate buffer")
- /* prepend datatype info to raw data for storage */
+ /* Encode version number */
+ HDmemcpy(dst, &version, sizeof(uint8_t));
+ dst += 1;
+
+ /* Encode the flag indicating whether the dtype is shared in Btree node buffer */
+ HDmemcpy(dst, &is_shared, sizeof(int8_t));
+ dst += 1;
+
+ /* prepend datatype info to raw data for storage as shared */
if(H5O_msg_encode(file, H5O_DTYPE_ID, FALSE, dst, dtype)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, 0, "can't encode object")
@@ -354,15 +1398,129 @@ H5Z_filter_dtype_modify (unsigned flags, size_t cd_nelmts, const unsigned cd_val
H5MM_xfree(*buf);
/* Set return values */
- *buf_size = type_msg_size + nbytes;
+ *buf_size = final_size;
*buf = (void*)outbuf;
outbuf = NULL;
ret_value = *buf_size;
+
+ /* Adjust reference count for the old and new datatypes. */
+ if(!(flags & H5Z_FLAG_SKIP_CRECORD) && chunk_slist) {
+ /* Decrement the reference count of the old datatype and increment
+ * the reference count of the new datatype if the chunk is in skip list. */
+ if((NULL != (node = H5SL_search(chunk_slist, &chunk_offset)))
+ && H5T_committed(node->dtype) && node->type_modified) {
+
+ udata.version = H5Z_DTYPE_MODIFY_VERS;
+ udata.is_shared = is_shared;
+ udata.dtype = node->dtype;
+ udata.numb_ref = 1;
+ udata.found = FALSE;
+ udata.adjust = H5Z_MDTYPE_DEC;
+
+ /* Find out the number of nodes in the Btree */
+ if(H5B2_get_nrec(file, H5AC_dxpl_id, H5Z_BT2_DTYPE, baddr, &bnode_numb) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, 0, "can't get number of nodes in Btree")
+
+ /* Find the old datatype and decrement the number of references to the type */
+ if(bnode_numb)
+ H5B2_find(file, H5AC_dxpl_id, H5Z_BT2_DTYPE, baddr, &udata,
+ H5Z_btree2_dtype_find_cb, &udata);
+
+ /* If found the old type and no other chunk uses it, delete the node from the
+ * Btree */
+ if(udata.found && !udata.numb_ref) {
+ /*delete the node*/
+ if(H5B2_remove(file, H5AC_dxpl_id, H5Z_BT2_DTYPE, baddr, &udata,
+ H5Z_btree2_dtype_remove_cb, NULL) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, 0, "can't remove node in Btree")
+
+ bnode_numb--;
+ }
+
+ /* Decrement the reference count of the old datatype in the skipped list.
+ * 1 for being prepended to the chunk. 1 is for the copy in the skip list.*/
+ if(H5T_link(node->dtype, -2, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_LINKCOUNT, 0, "unable to adjust shared datatype link count")
+
+ if(H5T_close(node->dtype) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, 0, "can't close data type")
+
+ /* Update the dtype in the skip list to the current dtype */
+ if ((NULL==(node->dtype=H5T_copy(dtype, H5T_COPY_ALL))))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, 0, "unable to copy data type");
+
+ /* Increment the reference count on the new datatype. 1 is encoded with
+ * the chunk. 1 is the copy in the skip list */
+ if(H5T_committed(node->dtype) && H5T_link(node->dtype, 2, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_LINKCOUNT, 0, "unable to adjust shared datatype link count")
+
+ node->type_modified = FALSE;
+
+ /* Update the node in the skip list? */
+
+ /* If the dtype info isn't in Btree, insert it and its reference number
+ * into Btree */
+ udata.dtype = dtype;
+ udata.numb_ref = 1;
+ udata.found = FALSE;
+ udata.adjust = H5Z_MDTYPE_INC;
+
+ /* Find the new datatype in the Btree and increment the number of references
+ * to the type */
+ if(bnode_numb)
+ H5B2_find(file, H5AC_dxpl_id, H5Z_BT2_DTYPE, baddr, &udata,
+ H5Z_btree2_dtype_find_cb, &udata);
+
+ if(udata.found == FALSE && H5B2_insert(file, H5AC_dxpl_id, H5Z_BT2_DTYPE,
+ baddr, &udata) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTINSERT, 0, "can't insert B-tree")
+ } else if(!node && H5T_committed(dtype)) {
+ /* Insert the chunk in the skip list. Increment type reference count. */
+ /* Allocate space for the node for the skip list */
+ if(NULL == (node = H5FL_MALLOC(H5Z_slist_node_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed")
+ node->key = chunk_offset;
+ node->type_modified = FALSE;
+
+ if ((NULL==(node->dtype=H5T_copy(dtype, H5T_COPY_ALL))))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, 0, "unable to copy data type");
+
+ /* Increment the reference count on the new datatype. 1 is encoded with
+ * the chunk. 1 is the copy in the skip list */
+ if(H5T_link(dtype, 2, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_LINKCOUNT, 0, "unable to adjust shared datatype link count")
+
+ /* Insert into the skip list */
+ if(H5SL_insert(chunk_slist, node, &(node->key)) < 0)
+ HGOTO_ERROR(H5E_SLIST, H5E_CANTINSERT, 0, "can't insert chunk node into skip list")
+
+ udata.version = H5Z_DTYPE_MODIFY_VERS;
+ udata.is_shared = is_shared;
+ udata.dtype = dtype;
+ udata.numb_ref = 1;
+ udata.found = FALSE;
+ udata.adjust = H5Z_MDTYPE_INC;
+
+ /* Find out the number of nodes in the Btree */
+ if(H5B2_get_nrec(file, H5AC_dxpl_id, H5Z_BT2_DTYPE, baddr, &bnode_numb) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, 0, "can't get number of nodes in Btree")
+
+ /* Find the datatype and increment the number of references to the type */
+ if(bnode_numb)
+ H5B2_find(file, H5AC_dxpl_id, H5Z_BT2_DTYPE, baddr, &udata,
+ H5Z_btree2_dtype_find_cb, &udata);
+ /*HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, 0, "can't locate dtype in Btree")*/
+
+ /* If the dtype info isn't in Btree, insert it and its reference number
+ * into Btree */
+ if(udata.found == FALSE && H5B2_insert(file, H5AC_dxpl_id, H5Z_BT2_DTYPE,
+ baddr, &udata) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTINSERT, 0, "can't insert B-tree")
+ }
+ }
}
done:
- /*if(outbuf)
- H5MM_xfree(outbuf);*/
FUNC_LEAVE_NOAPI(ret_value)
}
diff --git a/src/H5Zfletcher32.c b/src/H5Zfletcher32.c
index 2434537..a520cea 100644
--- a/src/H5Zfletcher32.c
+++ b/src/H5Zfletcher32.c
@@ -30,21 +30,40 @@
#ifdef H5_HAVE_FILTER_FLETCHER32
/* Local function prototypes */
-static size_t H5Z_filter_fletcher32 (unsigned flags, size_t cd_nelmts,
+#ifndef H5_USE_16_API
+static size_t H5Z_filter_fletcher32 (unsigned flags, hsize_t UNUSED chunk_offset,
+ size_t cd_nelmts, const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
+
+/* This message derives from H5Z */
+const H5Z_class_t H5Z_FLETCHER32[1] = {{
+ H5Z_CLASS_T_VERS, /* H5Z_class_t version */
+ H5Z_FILTER_FLETCHER32, /* Filter id number */
+ 1, /* encoder_present flag (set to true) */
+ 1, /* decoder_present flag (set to true) */
+ "fletcher32", /* Filter name for debugging */
+ NULL, /* The "can apply" callback */
+ NULL, /* The "set local" callback */
+ NULL, /* The "reset local" callback */
+ NULL, /* The "change local" callback */
+ NULL, /* The "evict local" callback */
+ NULL, /* The "delete local" callback */
+ NULL, /* The "close local" callback */
+ H5Z_filter_fletcher32, /* The actual filter function */
+}};
+#else
+static size_t H5Z_filter_fletcher32 (unsigned flags, size_t cd_nelmts,
const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
/* This message derives from H5Z */
const H5Z_class_t H5Z_FLETCHER32[1] = {{
H5Z_CLASS_T_VERS, /* H5Z_class_t version */
H5Z_FILTER_FLETCHER32, /* Filter id number */
- 1, /* encoder_present flag (set to true) */
- 1, /* decoder_present flag (set to true) */
"fletcher32", /* Filter name for debugging */
NULL, /* The "can apply" callback */
NULL, /* The "set local" callback */
- NULL, /* The "reset local" callback */
H5Z_filter_fletcher32, /* The actual filter function */
}};
+#endif
#define FLETCHER_LEN 4
@@ -74,9 +93,15 @@ const H5Z_class_t H5Z_FLETCHER32[1] = {{
*-------------------------------------------------------------------------
*/
/* ARGSUSED */
+#ifndef H5_USE_16_API
+static size_t
+H5Z_filter_fletcher32 (unsigned flags, hsize_t UNUSED chunk_offset, size_t UNUSED cd_nelmts,
+ const unsigned UNUSED cd_values[], size_t nbytes, size_t *buf_size, void **buf)
+#else
static size_t
-H5Z_filter_fletcher32 (unsigned flags, size_t UNUSED cd_nelmts, const unsigned UNUSED cd_values[],
- size_t nbytes, size_t *buf_size, void **buf)
+H5Z_filter_fletcher32 (unsigned flags, size_t UNUSED cd_nelmts,
+ const unsigned UNUSED cd_values[], size_t nbytes, size_t *buf_size, void **buf)
+#endif
{
void *outbuf = NULL; /* Pointer to new buffer */
unsigned char *src = (unsigned char*)(*buf);
@@ -84,7 +109,7 @@ H5Z_filter_fletcher32 (unsigned flags, size_t UNUSED cd_nelmts, const unsigned U
uint32_t reversed_fletcher; /* Possible wrong checksum value */
uint8_t c[4];
uint8_t tmp;
- size_t ret_value; /* Return value */
+ size_t ret_value = nbytes; /* Return value */
FUNC_ENTER_NOAPI(H5Z_filter_fletcher32, 0)
@@ -134,7 +159,7 @@ H5Z_filter_fletcher32 (unsigned flags, size_t UNUSED cd_nelmts, const unsigned U
/* Set return values */
/* (Re-use the input buffer, just note that the size is smaller by the size of the checksum) */
ret_value = nbytes-FLETCHER_LEN;
- } else { /* Write */
+ } else if (!(flags & H5Z_FLAG_INVMASK)){ /* Write */
unsigned char *dst; /* Temporary pointer to destination buffer */
/* Compute checksum (can't fail) */
diff --git a/src/H5Znbit.c b/src/H5Znbit.c
index 9827a9d..fe2054c 100644
--- a/src/H5Znbit.c
+++ b/src/H5Znbit.c
@@ -37,14 +37,6 @@ typedef struct {
int offset; /* datatype offset */
} parms_atomic;
-/* Local function prototypes */
-static herr_t H5Z_can_apply_nbit(hid_t dcpl_id, hid_t type_id, hid_t space_id,
- hid_t UNUSED file_id);
-static herr_t H5Z_set_local_nbit(hid_t dcpl_id, hid_t type_id, hid_t space_id,
- hid_t UNUSED file_id);
-static size_t H5Z_filter_nbit(unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
- size_t nbytes, size_t *buf_size, void **buf);
-
static void H5Z_calc_parms_nooptype(void);
static void H5Z_calc_parms_atomic(void);
static herr_t H5Z_calc_parms_array(const H5T_t *type);
@@ -81,16 +73,28 @@ static void H5Z_nbit_compress_one_compound(unsigned char *data, size_t data_offs
static void H5Z_nbit_compress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer,
size_t *buffer_size, const unsigned parms[]);
+/* Local function prototypes */
+static herr_t H5Z_can_apply_nbit(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t UNUSED file_id);
+static herr_t H5Z_set_local_nbit(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t UNUSED file_id);
+static size_t H5Z_filter_nbit(unsigned flags, hsize_t UNUSED chunk_offset, size_t cd_nelmts,
+ const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
+
/* This message derives from H5Z */
H5Z_class_t H5Z_NBIT[1] = {{
- H5Z_CLASS_T_VERS, /* H5Z_class_t version */
+ H5Z_CLASS_T_VERS, /* H5Z_class_t version */
H5Z_FILTER_NBIT, /* Filter id number */
- 1, /* Assume encoder present: check before registering */
- 1, /* decoder_present flag (set to true) */
- "nbit", /* Filter name for debugging */
+ 1, /* Assume encoder present: check before registering */
+ 1, /* decoder_present flag (set to true) */
+ "nbit", /* Filter name for debugging */
H5Z_can_apply_nbit, /* The "can apply" callback */
H5Z_set_local_nbit, /* The "set local" callback */
NULL, /* The "reset local" callback */
+ NULL, /* The "change local" callback */
+ NULL, /* The "evict local" callback */
+ NULL, /* The "delete local" callback */
+ NULL, /* The "close local" callback */
H5Z_filter_nbit, /* The actual filter function */
}};
@@ -871,10 +875,10 @@ done:
*-------------------------------------------------------------------------
*/
static size_t
-H5Z_filter_nbit(unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
- size_t nbytes, size_t *buf_size, void **buf)
+H5Z_filter_nbit(unsigned flags, hsize_t UNUSED chunk_offset, size_t cd_nelmts,
+ const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf)
{
- size_t ret_value = 0; /* return value */
+ size_t ret_value = nbytes; /* return value */
size_t size_out = 0; /* size of output buffer */
unsigned d_nelmts = 0; /* number of elements in the chunk */
unsigned char *outbuf = NULL; /* pointer to new output buffer */
@@ -899,7 +903,7 @@ H5Z_filter_nbit(unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
d_nelmts = cd_values[2];
/* input; decompress */
- if (flags & H5Z_FLAG_REVERSE) {
+ if (flags & H5Z_FLAG_REVERSE) { /*Read*/
size_out = d_nelmts * cd_values[4]; /* cd_values[4] stores datatype size */
/* allocate memory space for decompressed buffer */
@@ -908,9 +912,9 @@ H5Z_filter_nbit(unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
/* decompress the buffer */
H5Z_nbit_decompress(outbuf, d_nelmts, *buf, cd_values);
- }
+
/* output; compress */
- else {
+ } else if (!(flags & H5Z_FLAG_INVMASK)) { /*Write*/
assert(nbytes == d_nelmts * cd_values[4]);
size_out = nbytes;
diff --git a/src/H5Zprivate.h b/src/H5Zprivate.h
index 890125c..fd6327c 100644
--- a/src/H5Zprivate.h
+++ b/src/H5Zprivate.h
@@ -80,13 +80,17 @@ H5_DLL herr_t H5Z_modify(const struct H5O_pline_t *pline, H5Z_filter_t filter,
unsigned flags, size_t cd_nelmts, const unsigned int cd_values[]);
H5_DLL herr_t H5Z_pipeline(const struct H5O_pline_t *pline,
unsigned flags, unsigned *filter_mask/*in,out*/,
- H5Z_EDC_t edc_read, H5Z_cb_t cb_struct,
+ H5Z_EDC_t edc_read, hsize_t chunk_offset, H5Z_cb_t cb_struct,
size_t *nbytes/*in,out*/, size_t *buf_size/*in,out*/,
void **buf/*in,out*/);
H5_DLL H5Z_class_t *H5Z_find(H5Z_filter_t id);
H5_DLL herr_t H5Z_can_apply(hid_t dcpl_id, hid_t type_id, hid_t file_id);
H5_DLL herr_t H5Z_set_local(hid_t dcpl_id, hid_t type_id, hid_t file_id);
-H5_DLL herr_t H5Z_reset_local(hid_t dcpl_id, hid_t type_id, hid_t file_id);
+H5_DLL herr_t H5Z_reset_local(hid_t dcpl_id, hid_t type_id, hid_t file_id, hbool_t from_reopen);
+H5_DLL herr_t H5Z_change_local (hid_t dcpl_id, hid_t type_id, hid_t file_id, hsize_t chunk_offset);
+H5_DLL herr_t H5Z_evict_local (hid_t dcpl_id, hid_t type_id, hid_t file_id, hsize_t chunk_offset);
+H5_DLL herr_t H5Z_delete_local(hid_t dcpl_id, hid_t type_id, hid_t file_id);
+H5_DLL herr_t H5Z_close_local(hid_t dcpl_id, hid_t type_id, hid_t file_id);
H5_DLL H5Z_filter_info_t *H5Z_filter_info(const struct H5O_pline_t *pline,
H5Z_filter_t filter);
H5_DLL htri_t H5Z_all_filters_avail(const struct H5O_pline_t *pline);
diff --git a/src/H5Zpublic.h b/src/H5Zpublic.h
index 7ef9e98..c0ee263 100644
--- a/src/H5Zpublic.h
+++ b/src/H5Zpublic.h
@@ -64,6 +64,8 @@ typedef int H5Z_filter_t;
#define H5Z_FLAG_INVMASK 0xff00 /*invocation flag mask */
#define H5Z_FLAG_REVERSE 0x0100 /*reverse direction; read */
#define H5Z_FLAG_SKIP_EDC 0x0200 /*skip EDC filters for read */
+#define H5Z_FLAG_SKIP_CRECORD 0x0400 /*skip record keeping for chunks. Only for the
+ *filter of modifying dset's dtype*/
/* Special parameters for szip compression */
/* [These are aliases for the similar definitions in szlib.h, which we can't
@@ -84,7 +86,7 @@ typedef enum H5Z_SO_scale_type_t {
} H5Z_SO_scale_type_t;
/* Current version of the H5Z_class_t struct */
-#define H5Z_CLASS_T_VERS (1)
+#define H5Z_CLASS_T_VERS (2)
/* Values to decide if EDC is enabled for reading data */
typedef enum H5Z_EDC_t {
@@ -140,7 +142,7 @@ extern "C" {
* The "can_apply" callback returns positive a valid combination, zero for an
* invalid combination and negative for an error.
*/
-typedef herr_t (*H5Z_can_apply_func_t)(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+typedef herr_t (*H5Z_can_apply_func2_t)(hid_t dcpl_id, hid_t type_id, hid_t space_id,
hid_t file_id);
/*
@@ -170,9 +172,15 @@ typedef herr_t (*H5Z_can_apply_func_t)(hid_t dcpl_id, hid_t type_id, hid_t space
* again. The function prototype of "reset_local" callback is identical to
* the "set_local".
*/
-typedef herr_t (*H5Z_set_local_func_t)(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+typedef herr_t (*H5Z_set_local_func2_t)(hid_t dcpl_id, hid_t type_id, hid_t space_id,
hid_t file_id);
+typedef herr_t (*H5Z_reset_local_func2_t)(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t file_id, hbool_t from_reopen);
+
+typedef herr_t (*H5Z_change_local_func_t)(hid_t dcpl_id, hsize_t chunk_offset);
+typedef herr_t (*H5Z_close_local_func_t)(hid_t dcpl_id);
+
/*
* A filter gets definition flags and invocation flags (defined above), the
* client data array and size defined when the filter was added to the
@@ -188,7 +196,7 @@ typedef herr_t (*H5Z_set_local_func_t)(hid_t dcpl_id, hid_t type_id, hid_t space
* buffer. If an error occurs then the function should return zero and leave
* all pointer arguments unchanged.
*/
-typedef size_t (*H5Z_func_t)(unsigned int flags, size_t cd_nelmts,
+typedef size_t (*H5Z_func2_t)(unsigned int flags, hsize_t chunk_offset, size_t cd_nelmts,
const unsigned int cd_values[], size_t nbytes,
size_t *buf_size, void **buf);
@@ -196,17 +204,45 @@ typedef size_t (*H5Z_func_t)(unsigned int flags, size_t cd_nelmts,
* The filter table maps filter identification numbers to structs that
* contain a pointers to the filter function and timing statistics.
*/
-typedef struct H5Z_class_t {
+typedef struct H5Z_class2_t {
int version; /* Version number of the H5Z_class_t struct */
H5Z_filter_t id; /* Filter ID number */
unsigned encoder_present; /* Does this filter have an encoder? */
unsigned decoder_present; /* Does this filter have a decoder? */
const char *name; /* Comment for debugging */
- H5Z_can_apply_func_t can_apply; /* The "can apply" callback for a filter */
- H5Z_set_local_func_t set_local; /* The "set local" callback for a filter */
- H5Z_set_local_func_t reset_local; /* The "reset local" callback for a filter */
+ H5Z_can_apply_func2_t can_apply; /* The "can apply" callback for a filter */
+ H5Z_set_local_func2_t set_local; /* The "set local" callback for a filter */
+ H5Z_reset_local_func2_t reset_local; /* The "reset local" callback for a filter */
+ H5Z_change_local_func_t change_local; /* The "change local" callback for a filter */
+ H5Z_change_local_func_t evict_local; /* The "evict local" callback for a filter */
+ H5Z_close_local_func_t delete_local; /* The "delete local" callback for a filter */
+ H5Z_close_local_func_t close_local; /* The "close local" callback for a filter */
+ H5Z_func2_t filter; /* The actual filter function */
+} H5Z_class2_t;
+
+/* Symbols defined for compatibility with previous versions of the HDF5 API.
+ *
+ * Use of these symbols is deprecated.
+ */
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+
+/* Typedefs */
+typedef herr_t (*H5Z_can_apply_func1_t)(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+typedef herr_t (*H5Z_set_local_func1_t)(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+typedef size_t (*H5Z_func1_t)(unsigned int flags, size_t cd_nelmts,
+ const unsigned int cd_values[], size_t nbytes,
+ size_t *buf_size, void **buf);
+
+typedef struct H5Z_class1_t {
+ int version; /* Version number of the H5Z_class_t struct */
+ H5Z_filter_t id; /* Filter ID number */
+ const char *name; /* Comment for debugging */
+ H5Z_can_apply_func1_t can_apply; /* The "can apply" callback for a filter */
+ H5Z_set_local_func1_t set_local; /* The "set local" callback for a filter */
H5Z_func_t filter; /* The actual filter function */
-} H5Z_class_t;
+} H5Z_class1_t;
+
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
H5_DLL herr_t H5Zregister(const H5Z_class_t *cls);
H5_DLL herr_t H5Zunregister(H5Z_filter_t id);
@@ -217,4 +253,3 @@ H5_DLL herr_t H5Zget_filter_info(H5Z_filter_t filter, unsigned int *filter_confi
}
#endif
#endif
-
diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c
index 12e9aee..b3d62f5 100644
--- a/src/H5Zscaleoffset.c
+++ b/src/H5Zscaleoffset.c
@@ -40,17 +40,11 @@ enum H5Z_scaleoffset_type {t_bad=0, t_uchar=1, t_ushort, t_uint, t_ulong, t_ulon
/* Local function prototypes */
static double H5Z_scaleoffset_rnd(double val);
-static herr_t H5Z_can_apply_scaleoffset(hid_t dcpl_id, hid_t type_id, hid_t space_id,
- hid_t UNUSED file_id);
static enum H5Z_scaleoffset_type H5Z_scaleoffset_get_type(unsigned dtype_class,
unsigned dtype_size, unsigned dtype_sign);
static herr_t H5Z_scaleoffset_set_parms_fillval(H5P_genplist_t *dcpl_plist,
const H5T_t *type, enum H5Z_scaleoffset_type scale_type, unsigned cd_values[],
int need_convert, hid_t dxpl_id);
-static herr_t H5Z_set_local_scaleoffset(hid_t dcpl_id, hid_t type_id, hid_t space_id,
- hid_t UNUSED file_id);
-static size_t H5Z_filter_scaleoffset(unsigned flags, size_t cd_nelmts,
- const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
static void H5Z_scaleoffset_convert(void *buf, unsigned d_nelmts, size_t dtype_size);
static unsigned H5Z_scaleoffset_log2(unsigned long_long num);
static void H5Z_scaleoffset_precompress_i(void *data, unsigned d_nelmts,
@@ -81,16 +75,27 @@ static void H5Z_scaleoffset_decompress(unsigned char *data, unsigned d_nelmts,
static void H5Z_scaleoffset_compress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer,
size_t buffer_size, parms_atomic p);
+static herr_t H5Z_can_apply_scaleoffset(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t UNUSED file_id);
+static herr_t H5Z_set_local_scaleoffset(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t UNUSED file_id);
+static size_t H5Z_filter_scaleoffset(unsigned flags, hsize_t UNUSED chunk_offset,
+ size_t cd_nelmts, const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
+
/* This message derives from H5Z */
H5Z_class_t H5Z_SCALEOFFSET[1] = {{
- H5Z_CLASS_T_VERS, /* H5Z_class_t version */
- H5Z_FILTER_SCALEOFFSET, /* Filter id number */
- 1, /* Assume encoder present: check before registering */
- 1, /* decoder_present flag (set to true) */
+ H5Z_CLASS_T_VERS, /* H5Z_class_t version */
+ H5Z_FILTER_SCALEOFFSET, /* Filter id number */
+ 1, /* Assume encoder present: check before registering */
+ 1, /* decoder_present flag (set to true) */
"scaleoffset", /* Filter name for debugging */
H5Z_can_apply_scaleoffset, /* The "can apply" callback */
H5Z_set_local_scaleoffset, /* The "set local" callback */
NULL, /* The "reset local" callback */
+ NULL, /* The "change local" callback */
+ NULL, /* The "evict local" callback */
+ NULL, /* The "delete local" callback */
+ NULL, /* The "close local" callback */
H5Z_filter_scaleoffset, /* The actual filter function */
}};
@@ -911,8 +916,8 @@ done:
*-------------------------------------------------------------------------
*/
static size_t
-H5Z_filter_scaleoffset (unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
- size_t nbytes, size_t *buf_size, void **buf)
+H5Z_filter_scaleoffset (unsigned flags, hsize_t UNUSED chunk_offset, size_t cd_nelmts,
+ const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf)
{
size_t ret_value = 0; /* return value */
size_t size_out = 0; /* size of output buffer */
@@ -1008,7 +1013,7 @@ H5Z_filter_scaleoffset (unsigned flags, size_t cd_nelmts, const unsigned cd_valu
p.mem_order = H5T_native_order_g;
/* input; decompress */
- if (flags & H5Z_FLAG_REVERSE) {
+ if (flags & H5Z_FLAG_REVERSE) { /*Read*/
/* retrieve values of minbits and minval from input compressed buffer
* retrieve them corresponding to how they are stored during compression
*/
@@ -1090,7 +1095,7 @@ H5Z_filter_scaleoffset (unsigned flags, size_t cd_nelmts, const unsigned cd_valu
H5Z_scaleoffset_convert(outbuf, d_nelmts, p.size);
}
/* output; compress */
- else {
+ else if (!(flags & H5Z_FLAG_INVMASK)) { /*Write*/
assert(nbytes == d_nelmts * p.size);
/* before preprocess, convert to memory endianness order if needed */
diff --git a/src/H5Zshuffle.c b/src/H5Zshuffle.c
index cc0bb5a..d808014 100644
--- a/src/H5Zshuffle.c
+++ b/src/H5Zshuffle.c
@@ -27,22 +27,44 @@
#ifdef H5_HAVE_FILTER_SHUFFLE
/* Local function prototypes */
+#ifndef H5_USE_16_API
+static herr_t H5Z_set_local_shuffle(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t UNUSED file_id);
+static size_t H5Z_filter_shuffle(unsigned flags, hsize_t UNUSED chunk_offset,
+ size_t cd_nelmts, const unsigned cd_values[], size_t nbytes, size_t *buf_size,
+ void **buf);
+
+/* This message derives from H5Z */
+const H5Z_class_t H5Z_SHUFFLE[1] = {{
+ H5Z_CLASS_T_VERS, /* H5Z_class_t version */
+ H5Z_FILTER_SHUFFLE, /* Filter id number */
+ 1, /* encoder_present flag (set to true) */
+ 1, /* decoder_present flag (set to true) */
+ "shuffle", /* Filter name for debugging */
+ NULL, /* The "can apply" callback */
+ H5Z_set_local_shuffle, /* The "set local" callback */
+ NULL, /* The "reset local" callback */
+ NULL, /* The "change local" callback */
+ NULL, /* The "evict local" callback */
+ NULL, /* The "delete local" callback */
+ NULL, /* The "close local" callback */
+ H5Z_filter_shuffle, /* The actual filter function */
+}};
+#else
static herr_t H5Z_set_local_shuffle(hid_t dcpl_id, hid_t type_id, hid_t space_id);
-static size_t H5Z_filter_shuffle(unsigned flags, size_t cd_nelmts,
+static size_t H5Z_filter_shuffle(unsigned flags, size_t cd_nelmts,
const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
/* This message derives from H5Z */
const H5Z_class_t H5Z_SHUFFLE[1] = {{
H5Z_CLASS_T_VERS, /* H5Z_class_t version */
H5Z_FILTER_SHUFFLE, /* Filter id number */
- 1, /* encoder_present flag (set to true) */
- 1, /* decoder_present flag (set to true) */
"shuffle", /* Filter name for debugging */
NULL, /* The "can apply" callback */
H5Z_set_local_shuffle, /* The "set local" callback */
- NULL, /* The "reset local" callback */
H5Z_filter_shuffle, /* The actual filter function */
}};
+#endif
/* Local macros */
#define H5Z_SHUFFLE_USER_NPARMS 0 /* Number of parameters that users can set */
@@ -67,8 +89,13 @@ const H5Z_class_t H5Z_SHUFFLE[1] = {{
*-------------------------------------------------------------------------
*/
/* ARGSUSED */
+#ifndef H5_USE_16_API
+static herr_t H5Z_set_local_shuffle(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t UNUSED file_id)
+#else
static herr_t
H5Z_set_local_shuffle(hid_t dcpl_id, hid_t type_id, hid_t UNUSED space_id)
+#endif
{
H5P_genplist_t *dcpl_plist; /* Property list pointer */
const H5T_t *type; /* Datatype */
@@ -126,9 +153,15 @@ done:
*
*-------------------------------------------------------------------------
*/
+#ifndef H5_USE_16_API
+static size_t H5Z_filter_shuffle(unsigned flags, hsize_t UNUSED chunk_offset,
+ size_t cd_nelmts, const unsigned cd_values[], size_t nbytes, size_t *buf_size,
+ void **buf)
+#else
static size_t
H5Z_filter_shuffle(unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
size_t nbytes, size_t *buf_size, void **buf)
+#endif
{
void *dest = NULL; /* Buffer to deposit [un]shuffled bytes into */
unsigned char *_src=NULL; /* Alias for source buffer */
@@ -140,7 +173,7 @@ H5Z_filter_shuffle(unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
size_t j; /* Local index variable */
#endif /* NO_DUFFS_DEVICE */
size_t leftover; /* Extra bytes at end of buffer */
- size_t ret_value; /* Return value */
+ size_t ret_value=nbytes; /* Return value */
FUNC_ENTER_NOAPI(H5Z_filter_shuffle, 0)
@@ -163,7 +196,7 @@ H5Z_filter_shuffle(unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
if (NULL==(dest = H5MM_malloc(nbytes)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed for shuffle buffer")
- if(flags & H5Z_FLAG_REVERSE) {
+ if(flags & H5Z_FLAG_REVERSE) { /*Read*/
/* Get the pointer to the source buffer */
_src =(unsigned char *)(*buf);
@@ -218,7 +251,7 @@ H5Z_filter_shuffle(unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
HDmemcpy((void*)_dest, (void*)_src, leftover);
}
} /* end if */
- else {
+ else if (!(flags & H5Z_FLAG_INVMASK)) { /*Write*/
/* Get the pointer to the destination buffer */
_dest =(unsigned char *)dest;
diff --git a/src/H5Zszip.c b/src/H5Zszip.c
index 191d7e7..4263537 100644
--- a/src/H5Zszip.c
+++ b/src/H5Zszip.c
@@ -33,12 +33,13 @@
# include "szlib.h"
#endif
+#ifndef H5_USE_16_API
/* Local function prototypes */
static herr_t H5Z_can_apply_szip(hid_t dcpl_id, hid_t type_id, hid_t space_id,
hid_t UNUSED file_id);
static herr_t H5Z_set_local_szip(hid_t dcpl_id, hid_t type_id, hid_t space_id,
hid_t UNUSED file_id);
-static size_t H5Z_filter_szip (unsigned flags, size_t cd_nelmts,
+static size_t H5Z_filter_szip (unsigned flags, hsize_t UNUSED chunk_offset, size_t cd_nelmts,
const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
/* This message derives from H5Z */
@@ -51,8 +52,29 @@ H5Z_class_t H5Z_SZIP[1] = {{
H5Z_can_apply_szip, /* The "can apply" callback */
H5Z_set_local_szip, /* The "set local" callback */
NULL, /* The "reset local" callback */
+ NULL, /* The "change local" callback */
+ NULL, /* The "evict local" callback */
+ NULL, /* The "delete local" callback */
+ NULL, /* The "close local" callback */
H5Z_filter_szip, /* The actual filter function */
}};
+#else
+/* Local function prototypes */
+static herr_t H5Z_can_apply_szip(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+static herr_t H5Z_set_local_szip(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+static size_t H5Z_filter_szip (unsigned flags, size_t cd_nelmts,
+ const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
+
+/* This message derives from H5Z */
+H5Z_class_t H5Z_SZIP[1] = {{
+ H5Z_CLASS_T_VERS, /* H5Z_class_t version */
+ H5Z_FILTER_SZIP, /* Filter id number */
+ "szip", /* Filter name for debugging */
+ H5Z_can_apply_szip, /* The "can apply" callback */
+ H5Z_set_local_szip, /* The "set local" callback */
+ H5Z_filter_szip, /* The actual filter function */
+}};
+#endif
/* Local macros */
#define H5Z_SZIP_USER_NPARMS 2 /* Number of parameters that users can set */
@@ -86,9 +108,14 @@ H5Z_class_t H5Z_SZIP[1] = {{
*
*-------------------------------------------------------------------------
*/
+#ifndef H5_USE_16_API
static herr_t
H5Z_can_apply_szip(hid_t UNUSED dcpl_id, hid_t type_id, hid_t UNUSED space_id,
hid_t UNUSED file_id)
+#else
+static herr_t
+H5Z_can_apply_szip(hid_t UNUSED dcpl_id, hid_t type_id, hid_t UNUSED space_id)
+#endif
{
const H5T_t *type; /* Datatype */
unsigned dtype_size; /* Datatype's size (in bits) */
@@ -144,8 +171,13 @@ done:
*
*-------------------------------------------------------------------------
*/
+#ifndef H5_USE_16_API
static herr_t
H5Z_set_local_szip(hid_t dcpl_id, hid_t type_id, hid_t space_id, hid_t UNUSED file_id)
+#else
+static herr_t
+H5Z_set_local_szip(hid_t dcpl_id, hid_t type_id, hid_t space_id)
+#endif
{
H5P_genplist_t *dcpl_plist; /* Property list pointer */
const H5T_t *type; /* Datatype */
@@ -285,9 +317,15 @@ done:
*
*-------------------------------------------------------------------------
*/
+#ifndef H5_USE_16_API
+static size_t
+H5Z_filter_szip (unsigned flags, hsize_t UNUSED chunk_offset, size_t cd_nelmts,
+ const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf)
+#else
static size_t
-H5Z_filter_szip (unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
+H5Z_filter_szip (unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
size_t nbytes, size_t *buf_size, void **buf)
+#endif
{
size_t ret_value = 0; /* Return value */
size_t size_out = 0; /* Size of output buffer */
@@ -318,7 +356,7 @@ H5Z_filter_szip (unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
H5_ASSIGN_OVERFLOW(sz_param.pixels_per_scanline,cd_values[H5Z_SZIP_PARM_PPS],unsigned,int);
/* Input; uncompress */
- if (flags & H5Z_FLAG_REVERSE) {
+ if (flags & H5Z_FLAG_REVERSE) { /*Read*/
uint32_t stored_nalloc; /* Number of bytes the compressed block will expand into */
size_t nalloc; /* Number of bytes the compressed block will expand into */
@@ -347,7 +385,7 @@ H5Z_filter_szip (unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
ret_value = nalloc;
}
/* Output; compress */
- else {
+ else if (!(flags & H5Z_FLAG_INVMASK)) { /*Write*/
unsigned char *dst = NULL; /* Temporary pointer to new output buffer */
/* Allocate space for the compressed buffer & header (assume data won't get bigger) */
@@ -381,4 +419,3 @@ done:
}
#endif /* H5_HAVE_FILTER_SZIP */
-
diff --git a/src/H5vers.txt b/src/H5vers.txt
index 00ab84b..8cd03cb 100644
--- a/src/H5vers.txt
+++ b/src/H5vers.txt
@@ -71,4 +71,7 @@ FUNCTION: H5Topen; ; v10, v18
# (although not required, it's easier to compare this file with the headers
# generated if the list below is in alphanumeric sort order - QAK)
TYPEDEF: H5E_auto; v10, v18
-
+TYPEDEF: H5Z_func; v10, v18
+TYPEDEF: H5Z_can_apply_func; v10, v18
+TYPEDEF: H5Z_set_local_func; v10, v18
+TYPEDEF: H5Z_class; v10, v18
diff --git a/src/H5version.h b/src/H5version.h
index eab972c..1c9d8ff 100644
--- a/src/H5version.h
+++ b/src/H5version.h
@@ -130,6 +130,22 @@
#define H5E_auto_t_vers 1
#endif /* !defined(H5E_auto_t_vers) */
+#if !defined(H5Z_can_apply_func_t_vers)
+#define H5Z_can_apply_func_t_vers 1
+#endif /* !defined(H5Z_can_apply_func_t_vers) */
+
+#if !defined(H5Z_class_t_vers)
+#define H5Z_class_t_vers 1
+#endif /* !defined(H5Z_class_t_vers) */
+
+#if !defined(H5Z_func_t_vers)
+#define H5Z_func_t_vers 1
+#endif /* !defined(H5Z_func_t_vers) */
+
+#if !defined(H5Z_set_local_func_t_vers)
+#define H5Z_set_local_func_t_vers 1
+#endif /* !defined(H5Z_set_local_func_t_vers) */
+
#endif /* H5_USE_16_API */
@@ -395,5 +411,53 @@
#error "H5E_auto_t_vers set to invalid value"
#endif /* H5E_auto_t_vers */
+
+#if !defined(H5Z_can_apply_func_t_vers) || H5Z_can_apply_func_t_vers == 2
+#ifndef H5Z_can_apply_func_t_vers
+#define H5Z_can_apply_func_t_vers 2
+#endif /* H5Z_can_apply_func_t_vers */
+#define H5Z_can_apply_func_t H5Z_can_apply_func2_t
+#elif H5Z_can_apply_func_t_vers == 1
+#define H5Z_can_apply_func_t H5Z_can_apply_func1_t
+#else /* H5Z_can_apply_func_t_vers */
+#error "H5Z_can_apply_func_t_vers set to invalid value"
+#endif /* H5Z_can_apply_func_t_vers */
+
+
+#if !defined(H5Z_class_t_vers) || H5Z_class_t_vers == 2
+#ifndef H5Z_class_t_vers
+#define H5Z_class_t_vers 2
+#endif /* H5Z_class_t_vers */
+#define H5Z_class_t H5Z_class2_t
+#elif H5Z_class_t_vers == 1
+#define H5Z_class_t H5Z_class1_t
+#else /* H5Z_class_t_vers */
+#error "H5Z_class_t_vers set to invalid value"
+#endif /* H5Z_class_t_vers */
+
+
+#if !defined(H5Z_func_t_vers) || H5Z_func_t_vers == 2
+#ifndef H5Z_func_t_vers
+#define H5Z_func_t_vers 2
+#endif /* H5Z_func_t_vers */
+#define H5Z_func_t H5Z_func2_t
+#elif H5Z_func_t_vers == 1
+#define H5Z_func_t H5Z_func1_t
+#else /* H5Z_func_t_vers */
+#error "H5Z_func_t_vers set to invalid value"
+#endif /* H5Z_func_t_vers */
+
+
+#if !defined(H5Z_set_local_func_t_vers) || H5Z_set_local_func_t_vers == 2
+#ifndef H5Z_set_local_func_t_vers
+#define H5Z_set_local_func_t_vers 2
+#endif /* H5Z_set_local_func_t_vers */
+#define H5Z_set_local_func_t H5Z_set_local_func2_t
+#elif H5Z_set_local_func_t_vers == 1
+#define H5Z_set_local_func_t H5Z_set_local_func1_t
+#else /* H5Z_set_local_func_t_vers */
+#error "H5Z_set_local_func_t_vers set to invalid value"
+#endif /* H5Z_set_local_func_t_vers */
+
#endif /* H5version_H */
diff --git a/test/change_dtypes.c b/test/change_dtypes.c
index 0897de9..67adb64 100644
--- a/test/change_dtypes.c
+++ b/test/change_dtypes.c
@@ -20,6 +20,14 @@
#include "h5test.h"
+#ifdef H5_USE_16_API
+int main(void)
+{
+ printf("Test skipped because backward compatbility with v1.6 is configured in\n");
+ return 0;
+}
+#else /* H5_USE_16_API */
+
#define STR_LEN 16
#define NX 10u
#define NY 20u
@@ -43,6 +51,7 @@ const char *DSET_NAME[] = {
"enum",
"array",
"reference",
+ "btree_node",
NULL
};
@@ -128,6 +137,84 @@ error:
/*-------------------------------------------------------------------------
+ * Function: test_btree_node
+ *
+ * Purpose: Creates a simple dataset of an integer type and tries to
+ * change the datatype to a bigger size. Test whether the
+ * B-tree node works properly in the filter for modifying
+ * dataset's datatype. The B-tree is for storing the number
+ * of datatype reference by the data chunks.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Raymond Lu
+ * 19 November 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_btree_node(hid_t file)
+{
+ hid_t dset;
+ hid_t space;
+ hid_t dcpl;
+ hsize_t dims[2] = {NX, NY};
+ hsize_t chunk_dims[2] = {NX/2, NY/2};
+ int *wbuf = NULL, *ptr = NULL;
+ unsigned i;
+
+ /* Create dataset creation property list */
+ if((dcpl = H5Pcreate(H5P_DATASET_CREATE))<0)
+ TEST_ERROR;
+
+ if((space=H5Screate_simple(2, dims, NULL)) < 0)
+ TEST_ERROR;
+
+ if(H5Pset_dtype_modifiable(dcpl)<0)
+ TEST_ERROR;
+
+ /* Set chunking */
+ if(H5Pset_chunk(dcpl, 2, chunk_dims)<0)
+ TEST_ERROR;
+
+ if((dset=H5Dcreate2(file, DSET_NAME[10], H5T_STD_U32BE, space, H5P_DEFAULT, dcpl,
+ H5P_DEFAULT)) < 0)
+ TEST_ERROR;
+
+ wbuf = (int *)malloc(sizeof(int)*NX*NY);
+ ptr = wbuf;
+ for(i = 0; i<NX*NY; i++) {
+ *ptr = i;
+ ptr++;
+ }
+
+ if(H5Dwrite(dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf) < 0)
+ TEST_ERROR;
+
+ if(H5Dmodify_dtype(dset, H5T_STD_U64LE) < 0)
+ TEST_ERROR;
+
+ if(H5Dclose(dset) < 0)
+ TEST_ERROR;
+
+ free(wbuf);
+
+ PASSED();
+ return 0;
+
+error:
+ H5_FAILED();
+ H5E_BEGIN_TRY {
+ H5Sclose(space);
+ H5Dclose(dset);
+ } H5E_END_TRY;
+ return 1;
+}
+
+
+/*-------------------------------------------------------------------------
* Function: test_float
*
* Purpose: Creates a simple dataset of a float type and tries to
@@ -805,6 +892,9 @@ int main(void)
TESTING("dataset of reference type:");
nerrors += test_reference(fid);
+ TESTING("size of B-tree node");
+ nerrors += test_btree_node(fid);
+
if(H5Fclose(fid) < 0)
nerrors++;
@@ -819,3 +909,4 @@ int main(void)
return 0;
}
+#endif /* H5_USE_16_API */
diff --git a/test/cmpd_dset.c b/test/cmpd_dset.c
index 7a7f8fa..759549a 100644
--- a/test/cmpd_dset.c
+++ b/test/cmpd_dset.c
@@ -124,9 +124,16 @@ typedef struct {
hvl_t r;
long_long s, t, u;
} stype4;
+typedef struct {
+ int a, b, c[8], d, e;
+ float f, g, h[16], i, j;
+ double k, l, m, n;
+ long o, p, q;
+ hvl_t r;
+ long_long s, t, u;
+ char v, w;
+} stype5;
-/*#define NX 10u
-#define NY 20u*/
#define NX 100u
#define NY 200u
#define COMP_NX 8u
@@ -140,15 +147,14 @@ const unsigned test_type_flags[H5O_SHMESG_MAX_NINDEXES] =
H5O_MESG_SDSPACE_FLAG,
H5O_MESG_PLINE_FLAG,
0, 0};
-#ifndef TMP
+
const unsigned test_minsizes[H5O_SHMESG_MAX_NINDEXES] = {0, 2, 40, 100, 3, 1000};
#define TEST_L2B 65
#define TEST_B2L 64
-#else
-const unsigned test_minsizes[H5O_SHMESG_MAX_NINDEXES] = {250,250,250,250,250,250};
-#define TEST_L2B 50
-#define TEST_B2L 40
-#endif
+
+#define COMMITTED_DTYPE 0
+#define UNCOMMITTED_DTYPE 1
+#define MIXED_DTYPE 2
/*-------------------------------------------------------------------------
@@ -237,7 +243,6 @@ test_compound (char *filename, hid_t fapl)
/* Create xfer properties to preserve initialized data */
if ((PRESERVE = H5Pcreate (H5P_DATASET_XFER)) < 0) goto error;
- if (H5Pset_preserve (PRESERVE, 1) < 0) goto error;
/*
*######################################################################
@@ -897,17 +902,17 @@ initialize_stype1(void *buf, const size_t num)
s_ptr->d = i*8+6;
s_ptr->e = i*8+7;
- s_ptr->f = i*2/3;
- s_ptr->g = i*2/3+1;
+ s_ptr->f = (float)i*2/3;
+ s_ptr->g = (float)i*2/3+1;
for(j=0; j<16; j++)
- s_ptr->h[j] = i*j/5+j;
- s_ptr->i = i*2/3+2;
- s_ptr->j = i*2/3+3;
-
- s_ptr->k = i/7+1;
- s_ptr->l = i/7+2;
- s_ptr->m = i/7+3;
- s_ptr->n = i/7+4;
+ s_ptr->h[j] = (float)i*j/5+j;
+ s_ptr->i = (float)i*2/3+2;
+ s_ptr->j = (float)i*2/3+3;
+
+ s_ptr->k = (double)i/7+1;
+ s_ptr->l = (double)i/7+2;
+ s_ptr->m = (double)i/7+3;
+ s_ptr->n = (double)i/7+4;
}
}
@@ -940,17 +945,17 @@ initialize_stype2(void *buf, const size_t num)
s_ptr->d = i*8+6;
s_ptr->e = i*8+7;
- s_ptr->f = i*2/3;
- s_ptr->g = i*2/3+1;
+ s_ptr->f = (float)i*2/3;
+ s_ptr->g = (float)i*2/3+1;
for(j=0; j<16; j++)
- s_ptr->h[j] = i*j/5+j;
- s_ptr->i = i*2/3+2;
- s_ptr->j = i*2/3+3;
+ s_ptr->h[j] = (float)i*j/5+j;
+ s_ptr->i = (float)i*2/3+2;
+ s_ptr->j = (float)i*2/3+3;
- s_ptr->k = i/7+1;
- s_ptr->l = i/7+2;
- s_ptr->m = i/7+3;
- s_ptr->n = i/7+4;
+ s_ptr->k = (double)i/7+1;
+ s_ptr->l = (double)i/7+2;
+ s_ptr->m = (double)i/7+3;
+ s_ptr->n = (double)i/7+4;
s_ptr->o = i*3+0;
s_ptr->p = i*3+1;
@@ -1009,7 +1014,7 @@ initialize_stype3(void *buf, const size_t num)
*-------------------------------------------------------------------------
*/
static void
-initialize_stype4(void *buf, const size_t num)
+initialize_stype4(void *buf, const size_t num, int addition)
{
size_t i, j;
stype4 *s_ptr;
@@ -1023,17 +1028,17 @@ initialize_stype4(void *buf, const size_t num)
s_ptr->d = i*8+6;
s_ptr->e = i*8+7;
- s_ptr->f = i*2/3;
- s_ptr->g = i*2/3+1;
+ s_ptr->f = (float)i*2/3;
+ s_ptr->g = (float)i*2/3+1;
for(j=0; j<16; j++)
- s_ptr->h[j] = i*j/5+j;
- s_ptr->i = i*2/3+2;
- s_ptr->j = i*2/3+3;
+ s_ptr->h[j] = (float)i*j/5+j;
+ s_ptr->i = (float)i*2/3+2;
+ s_ptr->j = (float)i*2/3+3;
- s_ptr->k = i/7+1;
- s_ptr->l = i/7+2;
- s_ptr->m = i/7+3;
- s_ptr->n = i/7+4;
+ s_ptr->k = (double)i/7+1;
+ s_ptr->l = (double)i/7+2;
+ s_ptr->m = (double)i/7+3;
+ s_ptr->n = (double)i/7+4;
s_ptr->o = i*3+0;
s_ptr->p = i*3+1;
@@ -1044,9 +1049,9 @@ initialize_stype4(void *buf, const size_t num)
for(j=0; j<4; j++)
((unsigned int *)s_ptr->r.p)[j]=i*10+j;
- s_ptr->s = i*5+1;
- s_ptr->t = i*5+2;
- s_ptr->u = i*5+3;
+ s_ptr->s = i*5+1+addition;
+ s_ptr->t = i*5+2+addition;
+ s_ptr->u = i*5+3+addition;
}
}
@@ -1282,6 +1287,75 @@ error:
/*-------------------------------------------------------------------------
+ * Function: create_stype5
+ *
+ * Purpose: Create HDF5 compound datatype for stype5.
+ *
+ * Return: Success: datatype ID
+ *
+ * Failure: negative
+ *
+ * Programmer: Raymond Lu
+ * Friday, 15 June 2007
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+create_stype5(void)
+{
+ hid_t array_dt1, array_dt2, vl_tid, tid;
+ const hsize_t eight = 8, sixteen = 16;
+
+ /* Build hdf5 datatypes */
+ if((array_dt1 = H5Tarray_create2(H5T_NATIVE_INT,1, &eight)) < 0)
+ goto error;
+ if((array_dt2 = H5Tarray_create2(H5T_NATIVE_FLOAT,1, &sixteen)) < 0)
+ goto error;
+ if((vl_tid = H5Tvlen_create (H5T_NATIVE_UINT)) < 0)
+ goto error;
+
+ if((tid = H5Tcreate(H5T_COMPOUND, sizeof(stype5))) < 0 ||
+ H5Tinsert(tid, "a", HOFFSET(stype5, a), H5T_NATIVE_INT) < 0 ||
+ H5Tinsert(tid, "b", HOFFSET(stype5, b), H5T_NATIVE_INT) < 0 ||
+ H5Tinsert(tid, "c", HOFFSET(stype5, c), array_dt1) < 0 ||
+ H5Tinsert(tid, "d", HOFFSET(stype5, d), H5T_NATIVE_INT) < 0 ||
+ H5Tinsert(tid, "e", HOFFSET(stype5, e), H5T_NATIVE_INT) < 0 ||
+ H5Tinsert(tid, "f", HOFFSET(stype5, f), H5T_NATIVE_FLOAT) < 0 ||
+ H5Tinsert(tid, "g", HOFFSET(stype5, g), H5T_NATIVE_FLOAT) < 0 ||
+ H5Tinsert(tid, "h", HOFFSET(stype5, h), array_dt2) < 0 ||
+ H5Tinsert(tid, "i", HOFFSET(stype5, i), H5T_NATIVE_FLOAT) < 0 ||
+ H5Tinsert(tid, "j", HOFFSET(stype5, j), H5T_NATIVE_FLOAT) < 0 ||
+ H5Tinsert(tid, "k", HOFFSET(stype5, k), H5T_NATIVE_DOUBLE) < 0 ||
+ H5Tinsert(tid, "l", HOFFSET(stype5, l), H5T_NATIVE_DOUBLE) < 0 ||
+ H5Tinsert(tid, "m", HOFFSET(stype5, m), H5T_NATIVE_DOUBLE) < 0 ||
+ H5Tinsert(tid, "n", HOFFSET(stype5, n), H5T_NATIVE_DOUBLE) < 0 ||
+ H5Tinsert(tid, "o", HOFFSET(stype5, o), H5T_NATIVE_LONG) < 0 ||
+ H5Tinsert(tid, "p", HOFFSET(stype5, p), H5T_NATIVE_LONG) < 0 ||
+ H5Tinsert(tid, "q", HOFFSET(stype5, q), H5T_NATIVE_LONG) < 0 ||
+ H5Tinsert(tid, "r", HOFFSET(stype5, r), vl_tid) < 0 ||
+ H5Tinsert(tid, "s", HOFFSET(stype5, s), H5T_NATIVE_LLONG) < 0 ||
+ H5Tinsert(tid, "t", HOFFSET(stype5, t), H5T_NATIVE_LLONG) < 0 ||
+ H5Tinsert(tid, "u", HOFFSET(stype5, u), H5T_NATIVE_LLONG) < 0 ||
+ H5Tinsert(tid, "v", HOFFSET(stype5, v), H5T_NATIVE_CHAR) < 0 ||
+ H5Tinsert(tid, "w", HOFFSET(stype5, w), H5T_NATIVE_CHAR) < 0)
+ goto error;
+
+ if(H5Tclose(array_dt1) < 0)
+ goto error;
+ if(H5Tclose(array_dt2) < 0)
+ goto error;
+ if(H5Tclose(vl_tid) < 0)
+ goto error;
+
+ return tid;
+
+error:
+ return FAIL;
+}
+
+
+/*-------------------------------------------------------------------------
* Function: compare_data
*
* Purpose: Compare data of stype1 and stype2.
@@ -1332,6 +1406,7 @@ compare_data(void *src_data, void *dst_data, hbool_t src_subset)
!DBL_ABS_EQUAL(s_ptr->n, d_ptr->n) ) {
H5_FAILED();
+
printf(" i=%d\n", i);
printf(" src={a=%d, b=%d, c=[%d,%d,%d,%d,%d,%d,%d,%d], d=%d, e=%d, f=%f, g=%f, h=[%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f], i=%f, j=%f, k=%f, l=%f, m=%f, n=%f}\n",
s_ptr->a, s_ptr->b, s_ptr->c[0], s_ptr->c[1], s_ptr->c[2],
@@ -1348,6 +1423,7 @@ compare_data(void *src_data, void *dst_data, hbool_t src_subset)
d_ptr->h[9],d_ptr->h[10],d_ptr->h[11],d_ptr->h[12],d_ptr->h[13],
d_ptr->h[14], d_ptr->h[15], d_ptr->i,d_ptr->j,d_ptr->k,d_ptr->l,
d_ptr->m,d_ptr->n);
+
goto error;
}
}
@@ -1547,6 +1623,102 @@ error:
/*-------------------------------------------------------------------------
+ * Function: compare_stype4_stype5
+ *
+ * Purpose: Compare data between stype4 and stype5.
+ *
+ * Return: Success: 0
+ *
+ * Failure: negative
+ *
+ * Programmer: Raymond Lu
+ * Friday, 14 September 2007
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+static int
+compare_stype4_stype5(void *src_data, void *dst_data, size_t nelmts)
+{
+ stype4 *s_ptr;
+ stype5 *d_ptr;
+ size_t i, j;
+
+ for(i = 0; i < nelmts; i++) {
+ s_ptr = ((stype4*)src_data) + i;
+ d_ptr = ((stype5*)dst_data) + i;
+
+ if (s_ptr->a != d_ptr->a ||
+ s_ptr->b != d_ptr->b ||
+ s_ptr->c[0] != d_ptr->c[0] ||
+ s_ptr->c[1] != d_ptr->c[1] ||
+ s_ptr->c[2] != d_ptr->c[2] ||
+ s_ptr->c[3] != d_ptr->c[3] ||
+ s_ptr->d != d_ptr->d ||
+ s_ptr->e != d_ptr->e ||
+ !FLT_ABS_EQUAL(s_ptr->f, d_ptr->f) ||
+ !FLT_ABS_EQUAL(s_ptr->g, d_ptr->g) ||
+ !FLT_ABS_EQUAL(s_ptr->h[0], d_ptr->h[0]) ||
+ !FLT_ABS_EQUAL(s_ptr->h[1], d_ptr->h[1]) ||
+ !FLT_ABS_EQUAL(s_ptr->i, d_ptr->i) ||
+ !FLT_ABS_EQUAL(s_ptr->j, d_ptr->j) ||
+ !DBL_ABS_EQUAL(s_ptr->k, d_ptr->k) ||
+ !DBL_ABS_EQUAL(s_ptr->l, d_ptr->l) ||
+ !DBL_ABS_EQUAL(s_ptr->m, d_ptr->m) ||
+ !DBL_ABS_EQUAL(s_ptr->n, d_ptr->n) ||
+ s_ptr->o != d_ptr->o ||
+ s_ptr->p != d_ptr->p ||
+ s_ptr->q != d_ptr->q ||
+ s_ptr->s != d_ptr->s ||
+ s_ptr->t != d_ptr->t ||
+ s_ptr->u != d_ptr->u ) {
+
+ H5_FAILED();
+ printf(" i=%d\n", i);
+ printf(" src={a=%d, b=%d, c=[%d,%d,%d,%d,%d,%d,%d,%d], d=%d, e=%d, f=%f, g=%f, h=[%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f], i=%f, j=%f, k=%f, l=%f, m=%f, n=%f, o=%d, p=%d, q=%d, s=%ld, t=%ld, u=%ld}\n",
+ s_ptr->a, s_ptr->b, s_ptr->c[0], s_ptr->c[1], s_ptr->c[2],
+ s_ptr->c[3], s_ptr->c[4], s_ptr->c[5], s_ptr->c[6], s_ptr->c[7],
+ s_ptr->d, s_ptr->e, s_ptr->f, s_ptr->g,s_ptr->h[0],s_ptr->h[1],s_ptr->h[2],
+ s_ptr->h[3],s_ptr->h[4],s_ptr->h[5],s_ptr->h[6],s_ptr->h[7],s_ptr->h[8],
+ s_ptr->h[9],s_ptr->h[10],s_ptr->h[11],s_ptr->h[12],s_ptr->h[13],s_ptr->h[14],
+ s_ptr->h[15], s_ptr->i,s_ptr->j,s_ptr->k,s_ptr->l,s_ptr->m,s_ptr->n,
+ s_ptr->o, s_ptr->p, s_ptr->q, s_ptr->s, s_ptr->t, s_ptr->u);
+ printf(" dst={a=%d, b=%d, c=[%d,%d,%d,%d,%d,%d,%d,%d], d=%d, e=%d, f=%f, g=%f, h=[%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f], i=%f, j=%f, k=%f, l=%f, m=%f, n=%f, o=%d, p=%d, q=%d, s=%ld, t=%ld, u=%ld}\n",
+ d_ptr->a, d_ptr->b, d_ptr->c[0], d_ptr->c[1], d_ptr->c[2],
+ d_ptr->c[3], d_ptr->c[4], d_ptr->c[5], d_ptr->c[6], d_ptr->c[7],
+ d_ptr->d, d_ptr->e, d_ptr->f, d_ptr->g,d_ptr->h[0],d_ptr->h[1],d_ptr->h[2],
+ d_ptr->h[3],d_ptr->h[4],d_ptr->h[5],d_ptr->h[6],d_ptr->h[7],d_ptr->h[8],
+ d_ptr->h[9],d_ptr->h[10],d_ptr->h[11],d_ptr->h[12],d_ptr->h[13],
+ d_ptr->h[14], d_ptr->h[15], d_ptr->i,d_ptr->j,d_ptr->k,d_ptr->l,
+ d_ptr->m,d_ptr->n, d_ptr->o, d_ptr->p, d_ptr->q, d_ptr->s, d_ptr->t,
+ d_ptr->u);
+ goto error;
+ }
+
+ if(s_ptr->r.len!=d_ptr->r.len) {
+ H5_FAILED();
+ printf(" i=%d\n", i);
+ printf("VL data lengths don't match!, src len=%d, dst len=%d\n",(int)s_ptr->r.len,(int)d_ptr->r.len);
+ goto error;
+ } /* end if */
+ for(j=0; j<s_ptr->r.len; j++) {
+ if( ((unsigned int *)s_ptr->r.p)[j] != ((unsigned int *)d_ptr->r.p)[j] ) {
+ H5_FAILED();
+ printf(" i=%d\n", i);
+ printf("VL data values don't match!, src r.p[%d]=%u, dst r.p[%d]=%u\n",(int)j, ((unsigned int *)s_ptr->r.p)[j], (int)j, ((unsigned int *)d_ptr->r.p)[j]);
+ goto error;
+ }
+ }
+ }
+
+ return SUCCEED;
+
+error:
+ return FAIL;
+}
+
+
+/*-------------------------------------------------------------------------
* Function: test_hdf5_src_subset
*
* Purpose: Test the optimization of compound data writing, rewriting,
@@ -1659,9 +1831,6 @@ test_hdf5_src_subset(char *filename, hid_t fapl)
if((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0)
goto error;
- if(H5Pset_preserve(dxpl, TRUE) < 0)
- goto error;
-
/* Rewrite contiguous data set */
if((dataset = H5Dopen2(file, DSET_NAME[0], H5P_DEFAULT)) < 0)
goto error;
@@ -1813,7 +1982,7 @@ test_hdf5_dst_subset(char *filename, hid_t fapl)
rbuf = (void*)malloc(NX * NY * sizeof(stype1));
rew_buf = (void*)malloc(NX * NY * sizeof(stype4));
- initialize_stype4(rew_buf, (size_t)NX*NY);
+ initialize_stype4(rew_buf, (size_t)NX*NY, 0);
/* Create dataset creation property list */
if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
@@ -1863,9 +2032,6 @@ test_hdf5_dst_subset(char *filename, hid_t fapl)
if((dxpl = H5Pcreate (H5P_DATASET_XFER)) < 0)
goto error;
- if(H5Pset_preserve(dxpl, TRUE) < 0)
- goto error;
-
/* Rewrite contiguous data set */
if((dataset = H5Dopen2(file, DSET_NAME[2], H5P_DEFAULT)) < 0)
goto error;
@@ -1973,23 +2139,23 @@ error:
*/
#ifdef H5_HAVE_FILTER_DTYPE_MODIFY
static int
-test_hdf5_change_dtype_chunked(char *filename, hid_t fapl)
+test_hdf5_change_dtype_chunked(char *filename, hid_t fapl, int dtype_flag)
{
hid_t file;
- hid_t rew_tid, src_tid, dst_tid;
+ hid_t rew_tid, rew2_tid, src_tid, dst_tid;
hid_t dataset;
hid_t space, space2, mspace;
hid_t fcpl, dcpl, dxpl;
+ H5O_info_t type_info;
hsize_t dims[2] = {NX, NY};
hsize_t chunk_dims[2] = {NX/10, NY/10};
hsize_t mem_dims[2] = {NX/2, NY};
- void *orig=NULL, *rew_buf=NULL, *rbuf=NULL;
+ void *orig=NULL, *rew_buf=NULL, *rbuf=NULL, *rbuf2=NULL;
void *rew_half_buf=NULL, *new_rbuf_half=NULL, *orig_rbuf_half=NULL;
hsize_t hs_offset[2] = {0,0}; /* Hyperslab offset */
const hsize_t hs_size[2] = {NX/2, NY}; /* Hyperslab size */
const hsize_t hs_stride[2] = {1,1}; /* Hyperslab stride */
const hsize_t hs_count[2] = {1,1}; /* Hyperslab count */
- unsigned num_indexes;
unsigned x;
if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
@@ -2022,6 +2188,22 @@ test_hdf5_change_dtype_chunked(char *filename, hid_t fapl)
if ((rew_tid=create_stype4())<0)
goto error;
+ if ((rew2_tid=create_stype5())<0)
+ goto error;
+
+ /* Determine whether to test committed or uncomitted data types */
+ if((COMMITTED_DTYPE == dtype_flag || MIXED_DTYPE == dtype_flag) && H5Tcommit2(file,
+ "src type", src_tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0)
+ goto error;
+
+ if(COMMITTED_DTYPE == dtype_flag && H5Tcommit2(file, "rewrite type", rew_tid,
+ H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0)
+ goto error;
+
+ if((COMMITTED_DTYPE == dtype_flag || MIXED_DTYPE == dtype_flag) && H5Tcommit2(file,
+ "second rewrite type", rew2_tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0)
+ goto error;
+
/* Create the data space */
if((space = H5Screate_simple(2, dims, NULL))<0)
goto error;
@@ -2034,15 +2216,16 @@ test_hdf5_change_dtype_chunked(char *filename, hid_t fapl)
initialize_stype2(orig, (size_t)NX*NY);
rbuf = (void*)malloc(NX * NY * sizeof(stype1));
+ rbuf2 = (void*)malloc(NX * NY * sizeof(stype5));
orig_rbuf_half = (void*)malloc(NX/2 * NY * sizeof(stype2));
new_rbuf_half = (void*)malloc(NX/2 * NY * sizeof(stype4));
rew_half_buf = (void*)malloc((NX/2) * NY * sizeof(stype4));
- initialize_stype4(rew_half_buf, (size_t)(NX/2)*NY);
+ initialize_stype4(rew_half_buf, (size_t)(NX/2)*NY, 2);
rew_buf = (void*)malloc(NX * NY * sizeof(stype4));
- initialize_stype4(rew_buf, (size_t)NX*NY);
+ initialize_stype4(rew_buf, (size_t)NX*NY, 1);
/* Create dataset creation property list */
if((dcpl = H5Pcreate(H5P_DATASET_CREATE))<0)
@@ -2158,13 +2341,9 @@ test_hdf5_change_dtype_chunked(char *filename, hid_t fapl)
/*
*######################################################################
- * STEP 4. Rewrite the whole data.
+ * STEP 4. Rewrite the whole data with the new datatype.
*/
- TESTING("rewriting data with a subset of original data type");
-
- /* Create xfer properties to preserve initialized data */
- if ((dxpl = H5Pcreate (H5P_DATASET_XFER))<0)
- goto error;
+ TESTING("rewriting data with the new data type");
/* Rewrite chunked data set */
if((dataset = H5Dopen2(file, DSET_NAME[3], H5P_DEFAULT))<0)
@@ -2198,6 +2377,115 @@ test_hdf5_change_dtype_chunked(char *filename, hid_t fapl)
if(H5Dclose(dataset) < 0)
goto error;
+ PASSED();
+
+ /*
+ *######################################################################
+ * STEP 6. Change datatype after rewrite the whole data. The data in
+ * the cache should be converted and flushed to the file when the
+ * dataset is closed.
+ */
+ TESTING("change datatype after rewriting the data");
+
+ /* Rewrite chunked data set */
+ if((dataset = H5Dopen2(file, DSET_NAME[3], H5P_DEFAULT))<0)
+ goto error;
+
+ /* Modify the data buffer a little */
+ initialize_stype4(rew_buf, (size_t)NX*NY, 3);
+
+ /* Write the data to the dataset */
+ if(H5Dwrite(dataset, rew_tid, H5S_ALL, H5S_ALL, dxpl, rew_buf)<0)
+ goto error;
+
+ /* Modify the datatype of the chunked dataset now. It should only change
+ * the data of the chunks in the cache, not the data in the file. */
+ if(H5Dmodify_dtype(dataset, rew2_tid)<0)
+ goto error;
+
+#ifdef TMP
+ /* There seems to be some problem with this operation - temporarily disable it */
+ /* Read the data back with rew2_tid (stype5) and compare it with rew_buf
+ * of rew_tid (stype4). */
+ if(H5Dread(dataset, rew2_tid, H5S_ALL, H5S_ALL, dxpl, rbuf2)<0)
+ goto error;
+
+ if(compare_stype4_stype5(rew_buf, rbuf2, (size_t)NX*NY) < 0)
+ goto error;
+#endif
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ /* The reference count for the original dtype should be only 1, for
+ * it's a committed type and saved in the file, and no other reference. */
+ if(H5Tcommitted(src_tid)) {
+ if(H5Oget_info(src_tid, &type_info) < 0)
+ goto error;
+
+ if(type_info.rc != 1)
+ goto error;
+ }
+
+ /* The reference count for the changed dtype should be 100, for it's
+ * a committed type, and there're 100 chunks with one of them being
+ * changed to the new dtype, and the dataset's dtype has been changed,
+ * too. */
+ if(H5Tcommitted(rew_tid)) {
+ if(H5Oget_info(rew_tid, &type_info) < 0)
+ goto error;
+
+ if(type_info.rc != 100)
+ goto error;
+ }
+
+ /* The reference count for the second changed dtype should be 3, for
+ * it's a committed type, and one chunk has been converted in the cached
+ * and flushed to the file, and the dataset's dtype has been changed,
+ * too. */
+ if(H5Tcommitted(rew2_tid)) {
+ if(H5Oget_info(rew2_tid, &type_info) < 0)
+ goto error;
+
+ if(type_info.rc != 3)
+ goto error;
+ }
+
+ PASSED();
+
+ /*
+ *######################################################################
+ * STEP 7. Delete the dataset and verify the reference count of the
+ * data types.
+ */
+ TESTING("delete the dataset");
+
+ /* delete the data set */
+ if(H5Ldelete(file, DSET_NAME[3], H5P_DEFAULT)<0)
+ goto error;
+
+ /* The reference count for the changed dtype should be 1, for it's
+ * a committed type, and the dataset refered to it has been deleted.
+ */
+ if(H5Tcommitted(rew_tid)) {
+ if(H5Oget_info(rew_tid, &type_info) < 0)
+ goto error;
+
+ if(type_info.rc != 1)
+ goto error;
+ }
+
+ /* The reference count for the second changed dtype should be 1, for
+ * it's a committed type, and the dataset refered to it has been deleted.
+ */
+ if(H5Tcommitted(rew2_tid)) {
+ if(H5Oget_info(rew2_tid, &type_info) < 0)
+ goto error;
+
+ if(type_info.rc != 1)
+ goto error;
+ }
+
/* Finishing test and release resources */
if(H5Sclose(space) < 0)
goto error;
@@ -2217,6 +2505,9 @@ test_hdf5_change_dtype_chunked(char *filename, hid_t fapl)
goto error;
if(H5Tclose(rew_tid)<0)
goto error;
+ if(H5Tclose(rew2_tid)<0)
+ goto error;
+
if(H5Fclose(file) < 0)
goto error;
@@ -2264,7 +2555,7 @@ static int
test_hdf5_change_dtype_no_filter(char *filename, hid_t fapl, htri_t is_contig)
{
hid_t file;
- hid_t rew_tid, src_tid, dst_tid;
+ hid_t rew_tid, src_tid;
hid_t dataset;
hid_t space;
hid_t dcpl, dxpl;
@@ -2272,8 +2563,6 @@ test_hdf5_change_dtype_no_filter(char *filename, hid_t fapl, htri_t is_contig)
hsize_t chunk_dims[2] = {NX/10, NY/10};
/*hsize_t chunk_dims[2] = {NX, NY};*/
void *orig=NULL, *rew_buf=NULL, *rbuf1=NULL, *rbuf2=NULL;
- unsigned num_indexes;
- unsigned x;
/* Create the file for this test */
if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
@@ -2297,7 +2586,7 @@ test_hdf5_change_dtype_no_filter(char *filename, hid_t fapl, htri_t is_contig)
rbuf1 = (void*)malloc(NX * NY * sizeof(stype2));
rew_buf = (void*)malloc(NX * NY * sizeof(stype4));
- initialize_stype4(rew_buf, (size_t)NX*NY);
+ initialize_stype4(rew_buf, (size_t)NX*NY, 0);
rbuf2 = (void*)malloc(NX * NY * sizeof(stype4));
@@ -2461,14 +2750,12 @@ static int
test_hdf5_change_dtype_compact(char *filename, hid_t fapl)
{
hid_t file;
- hid_t rew_tid, src_tid, dst_tid;
+ hid_t rew_tid, src_tid;
hid_t dataset;
hid_t space;
hid_t dcpl, dxpl;
hsize_t dims[2] = {COMP_NX, COMP_NY};
void *orig=NULL, *rew_buf=NULL, *rbuf1=NULL, *rbuf2=NULL;
- unsigned num_indexes;
- unsigned x;
/* Create the file for this test */
if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
@@ -2492,7 +2779,7 @@ test_hdf5_change_dtype_compact(char *filename, hid_t fapl)
rbuf1 = (void*)malloc(COMP_NX * COMP_NY * sizeof(stype2));
rew_buf = (void*)malloc(COMP_NX * COMP_NY * sizeof(stype4));
- initialize_stype4(rew_buf, (size_t)COMP_NX*COMP_NY);
+ initialize_stype4(rew_buf, (size_t)COMP_NX*COMP_NY, 0);
rbuf2 = (void*)malloc(COMP_NX * COMP_NY * sizeof(stype4));
@@ -2694,21 +2981,31 @@ main (int argc, char *argv[])
h5_fixname(FILENAME[2], fapl_id, fname, sizeof(fname));
nerrors += test_hdf5_dst_subset(fname, fapl_id);
- puts("Testing the filter for modifying datatype of chunked dataset:");
+#ifndef H5_USE_16_API
+ puts("Testing the filter for modifying datatype of chunked dataset with uncommitted dtype:");
h5_fixname(FILENAME[3], fapl_id, fname, sizeof(fname));
- nerrors += test_hdf5_change_dtype_chunked(fname, fapl_id);
+ nerrors += test_hdf5_change_dtype_chunked(fname, fapl_id, UNCOMMITTED_DTYPE);
- puts("Testing modifying datatype of chunked dataset with no filter:");
+ puts("Testing the filter for modifying datatype of chunked dataset with committed and uncommitted dtype:");
h5_fixname(FILENAME[4], fapl_id, fname, sizeof(fname));
+ nerrors += test_hdf5_change_dtype_chunked(fname, fapl_id, MIXED_DTYPE);
+
+ puts("Testing the filter for modifying datatype of chunked dataset with committed dtype:");
+ h5_fixname(FILENAME[5], fapl_id, fname, sizeof(fname));
+ nerrors += test_hdf5_change_dtype_chunked(fname, fapl_id, COMMITTED_DTYPE);
+
+ puts("Testing modifying datatype of chunked dataset with no filter:");
+ h5_fixname(FILENAME[6], fapl_id, fname, sizeof(fname));
nerrors += test_hdf5_change_dtype_no_filter(fname, fapl_id, FALSE);
puts("Testing modifying datatype of contiguous dataset:");
- h5_fixname(FILENAME[5], fapl_id, fname, sizeof(fname));
+ h5_fixname(FILENAME[7], fapl_id, fname, sizeof(fname));
nerrors += test_hdf5_change_dtype_no_filter(fname, fapl_id, TRUE);
puts("Testing modifying datatype of compact dataset:");
- h5_fixname(FILENAME[6], fapl_id, fname, sizeof(fname));
+ h5_fixname(FILENAME[8], fapl_id, fname, sizeof(fname));
nerrors += test_hdf5_change_dtype_compact(fname, fapl_id);
+#endif
if (nerrors) {
printf("***** %u FAILURE%s! *****\n",
diff --git a/test/dsets.c b/test/dsets.c
index d5949eb..464cfad 100644
--- a/test/dsets.c
+++ b/test/dsets.c
@@ -160,17 +160,28 @@ const char *FILENAME[] = {
int points[DSET_DIM1][DSET_DIM2], check[DSET_DIM1][DSET_DIM2];
double points_dbl[DSET_DIM1][DSET_DIM2], check_dbl[DSET_DIM1][DSET_DIM2];
+#ifndef H5_USE_16_API
/* Local prototypes for filter functions */
-static size_t filter_bogus(unsigned int flags, size_t cd_nelmts,
+static size_t filter_bogus(unsigned int flags, hsize_t chunk_offset, size_t cd_nelmts,
const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf);
static herr_t can_apply_bogus(hid_t dcpl_id, hid_t type_id, hid_t space_id,
hid_t file_id);
static herr_t set_local_bogus2(hid_t dcpl_id, hid_t type_id, hid_t space_id,
hid_t file_id);
+static size_t filter_bogus2(unsigned int flags, hsize_t chunk_offset, size_t cd_nelmts,
+ const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf);
+static size_t filter_corrupt(unsigned int flags, hsize_t chunk_offset, size_t cd_nelmts,
+ const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf);
+#else
+static size_t filter_bogus(unsigned int flags, size_t cd_nelmts,
+ const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf);
+static herr_t can_apply_bogus(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+static herr_t set_local_bogus2(hid_t dcpl_id, hid_t type_id, hid_t space_id);
static size_t filter_bogus2(unsigned int flags, size_t cd_nelmts,
const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf);
static size_t filter_corrupt(unsigned int flags, size_t cd_nelmts,
const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf);
+#endif
/*-------------------------------------------------------------------------
@@ -991,16 +1002,31 @@ test_tconv(hid_t file)
}
/* This message derives from H5Z */
+#ifndef H5_USE_16_API
const H5Z_class_t H5Z_BOGUS[1] = {{
- H5Z_CLASS_T_VERS, /* H5Z_class_t version */
+ H5Z_CLASS_T_VERS, /* H5Z_class_t version */
H5Z_FILTER_BOGUS, /* Filter id number */
- 1, 1, /* Encoding and decoding enabled */
+ 1, 1, /* Encoding and decoding enabled*/
"bogus", /* Filter name for debugging */
NULL, /* The "can apply" callback */
NULL, /* The "set local" callback */
NULL, /* The "reset local" callback */
+ NULL, /* The "change local" callback */
+ NULL, /* The "evict local" callback */
+ NULL, /* The "delete local" callback */
+ NULL, /* The "close local" callback */
+ filter_bogus, /* The actual filter function */
+}};
+#else
+const H5Z_class_t H5Z_BOGUS[1] = {{
+ H5Z_CLASS_T_VERS, /* H5Z_class_t version */
+ H5Z_FILTER_BOGUS, /* Filter id number */
+ "bogus", /* Filter name for debugging */
+ NULL, /* The "can apply" callback */
+ NULL, /* The "set local" callback */
filter_bogus, /* The actual filter function */
}};
+#endif
/*-------------------------------------------------------------------------
@@ -1019,9 +1045,13 @@ const H5Z_class_t H5Z_BOGUS[1] = {{
*
*-------------------------------------------------------------------------
*/
+#ifndef H5_USE_16_API
static herr_t
can_apply_bogus(hid_t UNUSED dcpl_id, hid_t type_id, hid_t UNUSED space_id,
hid_t UNUSED file_id)
+#else
+can_apply_bogus(hid_t UNUSED dcpl_id, hid_t type_id, hid_t UNUSED space_id)
+#endif
{
if(H5Tequal(type_id,H5T_NATIVE_DOUBLE))
return 0;
@@ -1046,10 +1076,17 @@ can_apply_bogus(hid_t UNUSED dcpl_id, hid_t type_id, hid_t UNUSED space_id,
*
*-------------------------------------------------------------------------
*/
+#ifndef H5_USE_16_API
+static size_t
+filter_bogus(unsigned int UNUSED flags, hsize_t UNUSED chunk_offset,
+ size_t UNUSED cd_nelmts, const unsigned int UNUSED *cd_values,
+ size_t nbytes, size_t UNUSED *buf_size, void UNUSED **buf)
+#else
static size_t
-filter_bogus(unsigned int UNUSED flags, size_t UNUSED cd_nelmts,
- const unsigned int UNUSED *cd_values, size_t nbytes,
+filter_bogus(unsigned int UNUSED flags, size_t UNUSED cd_nelmts,
+ const unsigned int UNUSED *cd_values, size_t nbytes,
size_t UNUSED *buf_size, void UNUSED **buf)
+#endif
{
return nbytes;
}
@@ -1072,9 +1109,14 @@ filter_bogus(unsigned int UNUSED flags, size_t UNUSED cd_nelmts,
*
*-------------------------------------------------------------------------
*/
+#ifndef H5_USE_16_API
static herr_t
set_local_bogus2(hid_t dcpl_id, hid_t type_id, hid_t UNUSED space_id,
hid_t UNUSED file_id)
+#else
+static herr_t
+set_local_bogus2(hid_t dcpl_id, hid_t type_id, hid_t UNUSED space_id)
+#endif
{
unsigned add_on=0; /* Value to add to data going through */
unsigned flags; /* Filter flags */
@@ -1126,10 +1168,15 @@ set_local_bogus2(hid_t dcpl_id, hid_t type_id, hid_t UNUSED space_id,
*
*-------------------------------------------------------------------------
*/
+#ifndef H5_USE_16_API
+static size_t
+filter_bogus2(unsigned int flags, hsize_t UNUSED chunk_offset, size_t cd_nelmts,
+ const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf)
+#else
static size_t
filter_bogus2(unsigned int flags, size_t cd_nelmts,
- const unsigned int *cd_values, size_t nbytes,
- size_t *buf_size, void **buf)
+ const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf)
+#endif
{
/* Check for the correct number of parameters */
if(cd_nelmts!=BOGUS2_ALL_NPARMS)
@@ -1168,16 +1215,31 @@ filter_bogus2(unsigned int flags, size_t cd_nelmts,
}
/* This message derives from H5Z */
+#ifndef H5_USE_16_API
const H5Z_class_t H5Z_CORRUPT[1] = {{
- H5Z_CLASS_T_VERS, /* H5Z_class_t version */
+ H5Z_CLASS_T_VERS, /* H5Z_class_t version */
H5Z_FILTER_CORRUPT, /* Filter id number */
- 1, 1, /* Encoding and decoding enabled */
+ 1, 1, /* Encoding and decoding enabled*/
"corrupt", /* Filter name for debugging */
NULL, /* The "can apply" callback */
NULL, /* The "set local" callback */
NULL, /* The "reset local" callback */
+ NULL, /* The "change local" callback */
+ NULL, /* The "evict local" callback */
+ NULL, /* The "delete local" callback */
+ NULL, /* The "close local" callback */
+ filter_corrupt, /* The actual filter function */
+}};
+#else
+const H5Z_class_t H5Z_CORRUPT[1] = {{
+ H5Z_CLASS_T_VERS, /* H5Z_class_t version */
+ H5Z_FILTER_CORRUPT, /* Filter id number */
+ "corrupt", /* Filter name for debugging */
+ NULL, /* The "can apply" callback */
+ NULL, /* The "set local" callback */
filter_corrupt, /* The actual filter function */
}};
+#endif
/*-------------------------------------------------------------------------
@@ -1198,10 +1260,15 @@ const H5Z_class_t H5Z_CORRUPT[1] = {{
*
*-------------------------------------------------------------------------
*/
+#ifndef H5_USE_16_API
+static size_t
+filter_corrupt(unsigned int flags, hsize_t UNUSED chunk_offset, size_t cd_nelmts,
+ const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf)
+#else
static size_t
filter_corrupt(unsigned int flags, size_t cd_nelmts,
- const unsigned int *cd_values, size_t nbytes,
- size_t *buf_size, void **buf)
+ const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf)
+#endif
{
size_t ret_value = 0;
unsigned char *dst = (unsigned char*)(*buf);
@@ -1355,7 +1422,8 @@ test_filter_internal(hid_t fid, const char *name, hid_t dcpl, int if_fletcher32,
/* Create the dataset */
if((dataset = H5Dcreate2(fid, name, H5T_NATIVE_INT, sid, H5P_DEFAULT,
- dcpl, H5P_DEFAULT)) < 0) goto error;
+ dcpl, H5P_DEFAULT)) < 0)
+ goto error;
PASSED();
@@ -2018,8 +2086,16 @@ UNUSED
data_corrupt[1] = 33;
data_corrupt[2] = 27;
- /* Temporarily disable this test because the changes in chunk caching conflicts with
- * the way this test is conducted. -slu 2007/7/20 */
+ /* This is a shaky test because any changes in chunk caching may conflict with
+ * the way this test is conducted. In Step 4 of test_filter_internal, the
+ * program tries to modify some data. When it does H5Dwrite, the library will
+ * overwrite the entire chunks if all data in the chunks are being modified.
+ * However, if the data being modified doesn't cover the whole chunks or the
+ * filter for modifying dataset's datatype is enabled, the chunks will be read
+ * first which will cause the Fletcher32 checksum to fail. (See how the RELAX
+ * variable is defined in H5D_chunk_write of H5Dio.c and H5D_istore_lock of
+ * H5Distore.c.) - SLU 2008/3/5
+ */
if(H5Zregister (H5Z_CORRUPT) < 0) goto error;
if(H5Pset_filter(dc, H5Z_FILTER_CORRUPT, 0, (size_t)3, data_corrupt) < 0) goto error;
@@ -2124,6 +2200,7 @@ UNUSED
* STEP 5: Test datatype modification by itself.
*----------------------------------------------------------
*/
+#ifndef H5_USE_16_API
#ifdef H5_HAVE_FILTER_DTYPE_MODIFY
puts("Testing datatype modification filter");
if((dc = H5Pcreate(H5P_DATASET_CREATE))<0) goto error;
@@ -2139,6 +2216,7 @@ UNUSED
SKIPPED();
puts(" Datatype modification filter not enabled");
#endif /* H5_HAVE_FILTER_DTYPE_MODIFY */
+#endif /* H5_USE_16_API */
/*----------------------------------------------------------
* STEP 6: Test shuffle + deflate + dtype modification.
@@ -2148,11 +2226,17 @@ UNUSED
puts("Testing dtype modify+shuffle+deflate filters(dtype modify first)");
if((dc = H5Pcreate(H5P_DATASET_CREATE))<0) goto error;
if (H5Pset_chunk (dc, 2, chunk_size)<0) goto error;
+#ifndef H5_USE_16_API
if (H5Pset_dtype_modifiable (dc)<0) goto error;
+#endif /* H5_USE_16_API */
if (H5Pset_shuffle (dc)<0) goto error;
if (H5Pset_deflate (dc, 6)<0) goto error;
+#ifndef H5_USE_16_API
if(test_filter_internal(file,DSET_SHUF_DEF_DTMOD_NAME,dc,ENABLE_FLETCHER32,DATA_NOT_CORRUPTED,CHANGE_DTYPE,&combo_size)<0) goto error;
+#else
+ if(test_filter_internal(file,DSET_SHUF_DEF_DTMOD_NAME,dc,ENABLE_FLETCHER32,DATA_NOT_CORRUPTED,DONT_CHANGE_DTYPE,&combo_size)<0) goto error;
+#endif /* H5_USE_16_API */
/* Clean up objects used for this test */
if (H5Pclose (dc)<0) goto error;
@@ -4879,16 +4963,31 @@ test_types(hid_t file)
}
/* This message derives from H5Z */
+#ifndef H5_USE_16_API
const H5Z_class_t H5Z_CAN_APPLY_TEST[1] = {{
- H5Z_CLASS_T_VERS,
+ H5Z_CLASS_T_VERS,
H5Z_FILTER_BOGUS3, /* Filter id number */
- 1, 1,
+ 1, 1,
"bogus", /* Filter name for debugging */
can_apply_bogus, /* The "can apply" callback */
NULL, /* The "set local" callback */
NULL, /* The "reset local" callback */
+ NULL, /* The "change local" callback */
+ NULL, /* The "evict local" callback */
+ NULL, /* The "delete local" callback */
+ NULL, /* The "close local" callback */
filter_bogus, /* The actual filter function */
}};
+#else
+const H5Z_class_t H5Z_CAN_APPLY_TEST[1] = {{
+ H5Z_CLASS_T_VERS,
+ H5Z_FILTER_BOGUS3, /* Filter id number */
+ "bogus", /* Filter name for debugging */
+ can_apply_bogus, /* The "can apply" callback */
+ NULL, /* The "set local" callback */
+ filter_bogus, /* The actual filter function */
+}};
+#endif
/*-------------------------------------------------------------------------
@@ -5240,16 +5339,31 @@ error:
/* This message derives from H5Z */
+#ifndef H5_USE_16_API
const H5Z_class_t H5Z_SET_LOCAL_TEST[1] = {{
- H5Z_CLASS_T_VERS,
+ H5Z_CLASS_T_VERS,
H5Z_FILTER_BOGUS2, /* Filter id number */
- 1, 1,
+ 1, 1,
"bogus2", /* Filter name for debugging */
NULL, /* The "can apply" callback */
set_local_bogus2, /* The "set local" callback */
NULL, /* The "reset local" callback */
+ NULL, /* The "change local" callback */
+ NULL, /* The "evict local" callback */
+ NULL, /* The "delete local" callback */
+ NULL, /* The "close local" callback */
filter_bogus2, /* The actual filter function */
}};
+#else
+const H5Z_class_t H5Z_SET_LOCAL_TEST[1] = {{
+ H5Z_CLASS_T_VERS,
+ H5Z_FILTER_BOGUS2, /* Filter id number */
+ "bogus2", /* Filter name for debugging */
+ NULL, /* The "can apply" callback */
+ set_local_bogus2, /* The "set local" callback */
+ filter_bogus2, /* The actual filter function */
+}};
+#endif
/*-------------------------------------------------------------------------
@@ -6580,6 +6694,7 @@ main(void)
nerrors += (test_tconv(file) < 0 ? 1 : 0);
nerrors += (test_filters(file, my_fapl) < 0 ? 1 : 0);
nerrors += (test_onebyte_shuffle(file) < 0 ? 1 : 0);
+#ifndef H5_USE_16_API
nerrors += (test_nbit_int(file) < 0 ? 1 : 0);
nerrors += (test_nbit_float(file) < 0 ? 1 : 0);
nerrors += (test_nbit_double(file) < 0 ? 1 : 0);
@@ -6593,6 +6708,7 @@ main(void)
nerrors += (test_scaleoffset_float_2(file) < 0 ? 1 : 0);
nerrors += (test_scaleoffset_double(file) < 0 ? 1 : 0);
nerrors += (test_scaleoffset_double_2(file) < 0 ? 1 : 0);
+#endif
nerrors += (test_multiopen (file) < 0 ? 1 : 0);
nerrors += (test_types(file) < 0 ? 1 : 0);
nerrors += (test_userblock_offset(my_fapl) < 0 ? 1 : 0);
@@ -6635,4 +6751,3 @@ error:
nerrors, 1 == nerrors ? "" : "S");
return 1;
}
-
diff --git a/tools/h5dump/h5dumpgentest.c b/tools/h5dump/h5dumpgentest.c
index f72fe8f..a994d42 100644
--- a/tools/h5dump/h5dumpgentest.c
+++ b/tools/h5dump/h5dumpgentest.c
@@ -102,18 +102,18 @@ static int
write_dset( hid_t loc_id, int rank, hsize_t *dims, const char *dset_name,
hid_t tid, void *buf );
+#define MYFILTER_ID 405
+#ifndef H5_USE_16_API
/* a filter operation callback function */
static size_t
-myfilter(unsigned int UNUSED flags, size_t UNUSED cd_nelmts,
- const unsigned int UNUSED *cd_values, size_t nbytes,
- size_t UNUSED *buf_size, void UNUSED **buf);
+myfilter(unsigned int UNUSED flags, hsize_t UNUSED chunk_offset, size_t UNUSED cd_nelmts,
+ const unsigned int UNUSED *cd_values, size_t nbytes, size_t UNUSED *buf_size,
+ void UNUSED **buf);
/* a "set local" callback */
static herr_t
set_local_myfilter(hid_t dcpl_id, hid_t tid, hid_t UNUSED sid, hid_t UNUSED file_id);
-#define MYFILTER_ID 405
-
/* This message derives from H5Z */
const H5Z_class_t H5Z_MYFILTER[1] = {{
H5Z_CLASS_T_VERS,
@@ -123,9 +123,33 @@ const H5Z_class_t H5Z_MYFILTER[1] = {{
NULL, /* The "can apply" callback */
set_local_myfilter, /* The "set local" callback */
NULL, /* The "reset local" callback */
+ NULL, /* The "change local" callback */
+ NULL, /* The "evict local" callback */
+ NULL, /* The "delete local" callback */
+ NULL, /* The "close local" callback */
myfilter, /* The actual filter function */
}};
+#else
+/* a filter operation callback function */
+static size_t
+myfilter(unsigned int UNUSED flags, size_t UNUSED cd_nelmts,
+ const unsigned int UNUSED *cd_values, size_t nbytes, size_t UNUSED *buf_size,
+ void UNUSED **buf);
+/* a "set local" callback */
+static herr_t
+set_local_myfilter(hid_t dcpl_id, hid_t tid, hid_t UNUSED sid);
+
+/* This message derives from H5Z */
+const H5Z_class_t H5Z_MYFILTER[1] = {{
+ H5Z_CLASS_T_VERS,
+ MYFILTER_ID, /* Filter id number */
+ "myfilter", /* Filter name for debugging */
+ NULL, /* The "can apply" callback */
+ set_local_myfilter, /* The "set local" callback */
+ myfilter, /* The actual filter function */
+}};
+#endif
/* A UD link traversal function. Shouldn't actually be called. */
static hid_t UD_traverse(UNUSED const char * link_name, UNUSED hid_t cur_group,
@@ -4925,6 +4949,51 @@ static void gent_filters(void)
}
+#ifndef H5_USE_16_API
+/*-------------------------------------------------------------------------
+ * Function: myfilter
+ *
+ * Purpose: filter operation callback function; the filter does nothing
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+myfilter(unsigned int UNUSED flags, hsize_t chunk_offset, size_t UNUSED cd_nelmts,
+ const unsigned int UNUSED *cd_values, size_t nbytes, size_t UNUSED *buf_size,
+ void UNUSED **buf)
+{
+ return nbytes;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: set_local_myfilter
+ *
+ * Purpose: filter operation "set local" callback
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static herr_t
+set_local_myfilter(hid_t dcpl_id, hid_t UNUSED tid, hid_t UNUSED sid, hid_t UNUSED file_id)
+{
+ unsigned flags; /* Filter flags */
+ size_t cd_nelmts = 0; /* Number of filter parameters */
+ unsigned cd_values[2] = {5, 6}; /* Filter parameters */
+
+ /* Get the filter's current parameters */
+ if(H5Pget_filter_by_id2(dcpl_id, MYFILTER_ID, &flags, &cd_nelmts, cd_values, 0, NULL, NULL) < 0)
+ return(FAIL);
+
+ cd_nelmts = 2;
+
+ /* Modify the filter's parameters for this dataset */
+ if(H5Pmodify_filter(dcpl_id, MYFILTER_ID, flags, cd_nelmts, cd_values) < 0)
+ return(FAIL);
+
+ return(SUCCEED);
+}
+#else
/*-------------------------------------------------------------------------
* Function: myfilter
*
@@ -4950,7 +5019,7 @@ myfilter(unsigned int UNUSED flags, size_t UNUSED cd_nelmts,
*/
static herr_t
-set_local_myfilter(hid_t dcpl_id, hid_t UNUSED tid, hid_t UNUSED sid, hid_t UNUSED file_id)
+set_local_myfilter(hid_t dcpl_id, hid_t UNUSED tid, hid_t UNUSED sid)
{
unsigned flags; /* Filter flags */
size_t cd_nelmts = 0; /* Number of filter parameters */
@@ -4969,6 +5038,8 @@ set_local_myfilter(hid_t dcpl_id, hid_t UNUSED tid, hid_t UNUSED sid, hid_t UNUS
return(SUCCEED);
}
+#endif
+
/*-------------------------------------------------------------------------
* Function: gent_fcontents
*