summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2008-10-03 14:55:22 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2008-10-03 14:55:22 (GMT)
commit3e1fd51a8a3dceb8229a0a34c5562f121e3f684d (patch)
tree5c0ff6033e9651e9dd6b8b1bc32cb80fe580dc28
parente1632d2284b4ad4da38be88900d197091b81cc89 (diff)
downloadhdf5-3e1fd51a8a3dceb8229a0a34c5562f121e3f684d.zip
hdf5-3e1fd51a8a3dceb8229a0a34c5562f121e3f684d.tar.gz
hdf5-3e1fd51a8a3dceb8229a0a34c5562f121e3f684d.tar.bz2
[svn-r15765] This is the second checkin for the filter of modifying dataset's datatype. There're a lot
of changes since the last checkin. Basically, I put a skipped list in the filter to keep track of the old (current) datatype for the chunk when the data chunk is read into the memory. When the datatype is changed, the filter will decrement the reference count for the old datatype. Another significant change is putting a B-tree in the filter to record the reference count of some datatype from the data chunks. When the dataset is deleted, the filter will decrement this many reference count for the datatype all at once to save time. This project is wrapped up at this point temporarily because of the flaws in the design. Quincey will talk to the people in Chicago about redesigning it. I've tested it on smirom, kagiso, and linew.
-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
*