summaryrefslogtreecommitdiffstats
path: root/src/H5Dchunk.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2016-05-12 20:47:03 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2016-05-12 20:47:03 (GMT)
commit18ad868b231754e4da03c79828e8b18a2d63c80a (patch)
treeb1d25c0dd14fc2cfb50108a53e55f103488719c1 /src/H5Dchunk.c
parent92806fb5e6778373638c29d36ef3e4c1c1ac3ab0 (diff)
downloadhdf5-18ad868b231754e4da03c79828e8b18a2d63c80a.zip
hdf5-18ad868b231754e4da03c79828e8b18a2d63c80a.tar.gz
hdf5-18ad868b231754e4da03c79828e8b18a2d63c80a.tar.bz2
[svn-r29924] Description:
Bring h5format_convert tool from revise_chunks branch to trunk. Tested on: MacoSX/64 10.11.4 (amazon) w/serial, parallel & production (h5committest forthcoming)
Diffstat (limited to 'src/H5Dchunk.c')
-rw-r--r--src/H5Dchunk.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index da6a717..f4f9104 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -200,6 +200,13 @@ typedef struct H5D_chunk_it_ud4_t {
uint32_t *chunk_dim; /* Chunk dimensions */
} H5D_chunk_it_ud4_t;
+/* Callback info for iteration to format convert chunks */
+typedef struct H5D_chunk_it_ud5_t {
+ H5D_chk_idx_info_t *new_idx_info; /* Dest. chunk index info object */
+ unsigned dset_ndims; /* Number of dimensions in dataset */
+ hsize_t *dset_dims; /* Dataset dimensions */
+} H5D_chunk_it_ud5_t;
+
/* Callback info for nonexistent readvv operation */
typedef struct H5D_chunk_readvv_ud_t {
unsigned char *rbuf; /* Read buffer to initialize */
@@ -250,6 +257,9 @@ H5D__nonexistent_readvv(const H5D_io_info_t *io_info,
size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[], hsize_t chunk_offset_arr[],
size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]);
+/* format convert cb */
+static int H5D__chunk_format_convert_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata);
+
/* Helper routines */
static herr_t H5D__chunk_set_info_real(H5O_layout_chunk_t *layout, unsigned ndims,
const hsize_t *curr_dims, const hsize_t *max_dims);
@@ -6336,3 +6346,135 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D__chunk_file_alloc() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5D__chunk_format_convert_cb
+ *
+ * Purpose: Callback routine to insert chunk address into v1 B-tree
+ * chunk index.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Vailin Choi
+ * Feb 2015
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5D__chunk_format_convert_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
+{
+ H5D_chunk_it_ud5_t *udata = (H5D_chunk_it_ud5_t *)_udata; /* User data */
+ H5D_chk_idx_info_t *new_idx_info; /* The new chunk index information */
+ H5D_chunk_ud_t insert_udata; /* Chunk information to be inserted */
+ haddr_t chunk_addr; /* Chunk address */
+ size_t nbytes; /* Chunk size */
+ void *buf = NULL; /* Pointer to buffer of chunk data */
+ int ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Set up */
+ new_idx_info = udata->new_idx_info;
+ H5_CHECKED_ASSIGN(nbytes, size_t, chunk_rec->nbytes, uint32_t);
+ chunk_addr = chunk_rec->chunk_addr;
+
+ if(new_idx_info->pline->nused &&
+ (new_idx_info->layout->flags & H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS) &&
+ (H5D__chunk_is_partial_edge_chunk(udata->dset_ndims, new_idx_info->layout->dim, chunk_rec->scaled, udata->dset_dims))) {
+ /* This is a partial non-filtered edge chunk */
+ /* Convert the chunk to a filtered edge chunk for v1 B-tree chunk index */
+
+ unsigned filter_mask = chunk_rec->filter_mask;
+ H5Z_cb_t cb_struct; /* Filter failure callback struct */
+ size_t read_size = nbytes; /* Bytes to read */
+
+ HDassert(read_size == new_idx_info->layout->size);
+
+ cb_struct.func = NULL; /* no callback function when failed */
+
+ /* Allocate buffer for chunk data */
+ if(NULL == (buf = H5MM_malloc(read_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed for raw data chunk")
+
+ /* Read the non-filtered edge chunk */
+ if(H5F_block_read(new_idx_info->f, H5FD_MEM_DRAW, chunk_addr, read_size, H5AC_rawdata_dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, H5_ITER_ERROR, "unable to read raw data chunk")
+
+ /* Pass the chunk through the pipeline */
+ if(H5Z_pipeline(new_idx_info->pline, 0, &filter_mask, H5Z_NO_EDC, cb_struct, &nbytes, &read_size, &buf) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, H5_ITER_ERROR, "output pipeline failed")
+
+#if H5_SIZEOF_SIZE_T > 4
+ /* Check for the chunk expanding too much to encode in a 32-bit value */
+ if(nbytes > ((size_t)0xffffffff))
+ HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, H5_ITER_ERROR, "chunk too large for 32-bit length")
+#endif /* H5_SIZEOF_SIZE_T > 4 */
+
+ /* Allocate space for the filtered chunk */
+ if((chunk_addr = H5MF_alloc(new_idx_info->f, H5FD_MEM_DRAW, new_idx_info->dxpl_id, (hsize_t)nbytes)) == HADDR_UNDEF)
+ HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, H5_ITER_ERROR, "file allocation failed for filtered chunk")
+ HDassert(H5F_addr_defined(chunk_addr));
+
+ /* Write the filtered chunk to disk */
+ if(H5F_block_write(new_idx_info->f, H5FD_MEM_DRAW, chunk_addr, nbytes, H5AC_rawdata_dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, H5_ITER_ERROR, "unable to write raw data to file")
+ } /* end if */
+
+ /* Set up chunk information for insertion to chunk index */
+ insert_udata.chunk_block.offset = chunk_addr;
+ insert_udata.chunk_block.length = nbytes;
+ insert_udata.filter_mask = chunk_rec->filter_mask;
+ insert_udata.common.scaled = chunk_rec->scaled;
+ insert_udata.common.layout = new_idx_info->layout;
+ insert_udata.common.storage = new_idx_info->storage;
+
+ /* Insert chunk into the v1 B-tree chunk index */
+ if((new_idx_info->storage->ops->insert)(new_idx_info, &insert_udata, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, H5_ITER_ERROR, "unable to insert chunk addr into index")
+
+done:
+ if(buf)
+ H5MM_xfree(buf);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5D__chunk_format_convert_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D__chunk_format_convert
+ *
+ * Purpose: Iterate over the chunks for the current chunk index and insert the
+ * the chunk addresses into v1 B-tree chunk index via callback.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Feb 2015
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D__chunk_format_convert(H5D_t *dset, H5D_chk_idx_info_t *idx_info, H5D_chk_idx_info_t *new_idx_info)
+{
+ H5D_chunk_it_ud5_t udata; /* User data */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Check args */
+ HDassert(dset);
+
+ /* Set up user data */
+ udata.new_idx_info = new_idx_info;
+ udata.dset_ndims = dset->shared->ndims;
+ udata.dset_dims = dset->shared->curr_dims;
+
+ /* terate over the chunks in the current index and insert the chunk addresses into version 1 B-tree index */
+ if((dset->shared->layout.storage.u.chunk.ops->iterate)(idx_info, H5D__chunk_format_convert_cb, &udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to iterate over chunk index to chunk info")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__chunk_format_convert() */
+