summaryrefslogtreecommitdiffstats
path: root/src/H5Dchunk.c
diff options
context:
space:
mode:
authorScot Breitenfeld <brtnfld@hdfgroup.org>2008-04-30 19:23:26 (GMT)
committerScot Breitenfeld <brtnfld@hdfgroup.org>2008-04-30 19:23:26 (GMT)
commit5773fd34bc5adf59b4530d95ac9f0c0585902803 (patch)
tree456ad239799382e1f083fb7fc74399e43b471912 /src/H5Dchunk.c
parent0138995d1ce2068db1f790503435a2121132d3ad (diff)
downloadhdf5-5773fd34bc5adf59b4530d95ac9f0c0585902803.zip
hdf5-5773fd34bc5adf59b4530d95ac9f0c0585902803.tar.gz
hdf5-5773fd34bc5adf59b4530d95ac9f0c0585902803.tar.bz2
[svn-r14902] Merged fortran_1_8 branch changes r14505:14901 into the trunk. New fortran wrappers added.
Diffstat (limited to 'src/H5Dchunk.c')
-rw-r--r--src/H5Dchunk.c1515
1 files changed, 0 insertions, 1515 deletions
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
deleted file mode 100644
index baaa5f1..0000000
--- a/src/H5Dchunk.c
+++ /dev/null
@@ -1,1515 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Copyright by The HDF Group. *
- * Copyright by the Board of Trustees of the University of Illinois. *
- * All rights reserved. *
- * *
- * This file is part of HDF5. The full HDF5 copyright notice, including *
- * terms governing use, modification, and redistribution, is contained in *
- * the files COPYING and Copyright.html. COPYING can be found at the root *
- * of the source code distribution tree; Copyright.html can be found at the *
- * root level of an installed copy of the electronic HDF5 document set and *
- * is linked from the top-level documents page. It can also be found at *
- * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
- * access to either file, you may request a copy from help@hdfgroup.org. *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/****************/
-/* Module Setup */
-/****************/
-
-#define H5D_PACKAGE /*suppress error about including H5Dpkg */
-
-
-/***********/
-/* Headers */
-/***********/
-#include "H5private.h" /* Generic Functions */
-#include "H5Dpkg.h" /* Dataset functions */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5FLprivate.h" /* Free Lists */
-#include "H5Iprivate.h" /* IDs */
-#ifdef H5_HAVE_PARALLEL
-#include "H5MMprivate.h" /* Memory management */
-#endif /* H5_HAVE_PARALLEL */
-#include "H5Vprivate.h" /* Vector and array functions */
-
-
-/****************/
-/* Local Macros */
-/****************/
-
-/* Default skip list height for storing list of chunks */
-#define H5D_DEFAULT_SKIPLIST_HEIGHT 8
-
-/* Macros for iterating over chunks to operate on */
-#define H5D_CHUNK_GET_FIRST_NODE(map) (map->use_single ? (H5SL_node_t *)(1) : H5SL_first(map->sel_chunks))
-#define H5D_CHUNK_GET_NODE_INFO(map, node) (map->use_single ? map->single_chunk_info : (H5D_chunk_info_t *)H5SL_item(node))
-#define H5D_CHUNK_GET_NEXT_NODE(map, node) (map->use_single ? (H5SL_node_t *)NULL : H5SL_next(node))
-
-
-/******************/
-/* Local Typedefs */
-/******************/
-
-
-/********************/
-/* Local Prototypes */
-/********************/
-
-/* Chunked layout operation callbacks */
-static herr_t H5D_chunk_io_init(const H5D_io_info_t *io_info,
- const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space,
- const H5S_t *mem_space, H5D_chunk_map_t *fm);
-static herr_t H5D_chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
- H5D_chunk_map_t *fm);
-static herr_t H5D_chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
- H5D_chunk_map_t *fm);
-static herr_t H5D_chunk_io_term(const H5D_chunk_map_t *fm);
-
-/* "Null" layout operation callbacks */
-static ssize_t H5D_null_readvv(const H5D_io_info_t *io_info,
- size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
- size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]);
-
-/* Helper routines */
-static herr_t H5D_free_chunk_info(void *item, void *key, void *opdata);
-static herr_t H5D_create_chunk_map_single(H5D_chunk_map_t *fm,
- const H5D_io_info_t *io_info);
-static herr_t H5D_create_chunk_file_map_hyper(H5D_chunk_map_t *fm,
- const H5D_io_info_t *io_info);
-static herr_t H5D_create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm);
-static herr_t H5D_chunk_file_cb(void *elem, hid_t type_id, unsigned ndims,
- const hsize_t *coords, void *fm);
-static herr_t H5D_chunk_mem_cb(void *elem, hid_t type_id, unsigned ndims,
- const hsize_t *coords, void *fm);
-
-
-
-/*********************/
-/* Package Variables */
-/*********************/
-
-/* Compact storage layout I/O ops */
-const H5D_layout_ops_t H5D_LOPS_CHUNK[1] = {{
- H5D_chunk_io_init,
- H5D_chunk_read,
- H5D_chunk_write,
-#ifdef H5_HAVE_PARALLEL
- H5D_chunk_collective_read,
- H5D_chunk_collective_write,
-#endif /* H5_HAVE_PARALLEL */
- NULL,
- NULL,
- H5D_chunk_io_term
-}};
-
-
-/*******************/
-/* Local Variables */
-/*******************/
-
-/* "null" storage layout I/O ops */
-const H5D_layout_ops_t H5D_LOPS_NULL[1] = {{
- NULL,
- NULL,
- NULL,
-#ifdef H5_HAVE_PARALLEL
- NULL,
- NULL,
-#endif /* H5_HAVE_PARALLEL */
- H5D_null_readvv,
- NULL,
- NULL
-}};
-
-/* Declare a free list to manage the H5D_chunk_info_t struct */
-H5FL_DEFINE(H5D_chunk_info_t);
-
-
-
-/*-------------------------------------------------------------------------
- * Function: H5D_chunk_io_init
- *
- * Purpose: Performs initialization before any sort of I/O on the raw data
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Thursday, March 20, 2008
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5D_chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
- H5D_chunk_map_t *fm)
-{
- H5D_t *dataset = io_info->dset; /* Local pointer to dataset info */
- const H5T_t *mem_type = type_info->mem_type; /* Local pointer to memory datatype */
- H5S_t *tmp_mspace = NULL; /* Temporary memory dataspace */
- hssize_t old_offset[H5O_LAYOUT_NDIMS]; /* Old selection offset */
- htri_t file_space_normalized = FALSE; /* File dataspace was normalized */
- hid_t f_tid = (-1); /* Temporary copy of file datatype for iteration */
- hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */
- unsigned f_ndims; /* The number of dimensions of the file's dataspace */
- int sm_ndims; /* The number of dimensions of the memory buffer's dataspace (signed) */
- H5SL_node_t *curr_node; /* Current node in skip list */
- H5S_sel_type fsel_type; /* Selection type on disk */
- char bogus; /* "bogus" buffer to pass to selection iterator */
- unsigned u; /* Local index variable */
- hbool_t sel_hyper_flag;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_io_init)
-
- /* Get layout for dataset */
- fm->layout = &(dataset->shared->layout);
- fm->nelmts = nelmts;
-
- /* Check if the memory space is scalar & make equivalent memory space */
- if((sm_ndims = H5S_GET_EXTENT_NDIMS(mem_space)) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimension number")
- /* Set the number of dimensions for the memory dataspace */
- H5_ASSIGN_OVERFLOW(fm->m_ndims, sm_ndims, int, unsigned);
-
- /* Get dim number and dimensionality for each dataspace */
- fm->f_ndims = f_ndims = dataset->shared->layout.u.chunk.ndims - 1;
- if(H5S_get_simple_extent_dims(file_space, fm->f_dims, NULL) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality")
-
- /* Normalize hyperslab selections by adjusting them by the offset */
- /* (It might be worthwhile to normalize both the file and memory dataspaces
- * before any (contiguous, chunked, etc) file I/O operation, in order to
- * speed up hyperslab calculations by removing the extra checks and/or
- * additions involving the offset and the hyperslab selection -QAK)
- */
- if((file_space_normalized = H5S_hyper_normalize_offset((H5S_t *)file_space, old_offset)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to normalize dataspace by offset")
-
- /* Decide the number of chunks in each dimension*/
- for(u=0; u<f_ndims; u++) {
- /* Keep the size of the chunk dimensions as hsize_t for various routines */
- fm->chunk_dim[u]=fm->layout->u.chunk.dim[u];
-
- /* Round up to the next integer # of chunks, to accomodate partial chunks */
- fm->chunks[u] = ((fm->f_dims[u]+dataset->shared->layout.u.chunk.dim[u])-1) / dataset->shared->layout.u.chunk.dim[u];
- } /* end for */
-
- /* Compute the "down" size of 'chunks' information */
- if(H5V_array_down(f_ndims,fm->chunks,fm->down_chunks) < 0)
- HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "can't compute 'down' sizes")
-
-#ifdef H5_HAVE_PARALLEL
- /* Calculate total chunk in file map*/
- fm->select_chunk = NULL;
- fm->total_chunks = 1;
- for(u = 0; u < fm->f_ndims; u++)
- fm->total_chunks = fm->total_chunks * fm->chunks[u];
- if(io_info->using_mpi_vfd) {
- H5_CHECK_OVERFLOW(fm->total_chunks, hsize_t, size_t);
- if(NULL == (fm->select_chunk = (H5D_chunk_info_t **)H5MM_calloc((size_t)fm->total_chunks * sizeof(H5D_chunk_info_t *))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info")
- } /* end if */
-#endif /* H5_HAVE_PARALLEL */
-
-
- /* Initialize "last chunk" information */
- fm->last_index = (hsize_t)-1;
- fm->last_chunk_info = NULL;
-
- /* Point at the dataspaces */
- fm->file_space = file_space;
- fm->mem_space = mem_space;
-
- /* Special case for only one element in selection */
- /* (usually appending a record) */
- if(nelmts == 1
-#ifdef H5_HAVE_PARALLEL
- && !(io_info->using_mpi_vfd)
-#endif /* H5_HAVE_PARALLEL */
- ) {
- /* Initialize skip list for chunk selections */
- fm->sel_chunks = NULL;
- fm->use_single = TRUE;
-
- /* Initialize single chunk dataspace */
- if(NULL == dataset->shared->cache.chunk.single_space) {
- /* Make a copy of the dataspace for the dataset */
- if((dataset->shared->cache.chunk.single_space = H5S_copy(file_space, TRUE, FALSE)) == NULL)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file space")
-
- /* Resize chunk's dataspace dimensions to size of chunk */
- if(H5S_set_extent_real(dataset->shared->cache.chunk.single_space, fm->chunk_dim) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't adjust chunk dimensions")
-
- /* Set the single chunk dataspace to 'all' selection */
- if(H5S_select_all(dataset->shared->cache.chunk.single_space, TRUE) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "unable to set all selection")
- } /* end if */
- fm->single_space = dataset->shared->cache.chunk.single_space;
- HDassert(fm->single_space);
-
- /* Allocate the single chunk information */
- if(NULL == dataset->shared->cache.chunk.single_chunk_info) {
- if(NULL == (dataset->shared->cache.chunk.single_chunk_info = H5FL_MALLOC(H5D_chunk_info_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info")
- } /* end if */
- fm->single_chunk_info = dataset->shared->cache.chunk.single_chunk_info;
- HDassert(fm->single_chunk_info);
-
- /* Reset chunk template information */
- fm->mchunk_tmpl = NULL;
-
- /* Set up chunk mapping for single element */
- if(H5D_create_chunk_map_single(fm, io_info) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create chunk selections for single element")
- } /* end if */
- else {
- /* Initialize skip list for chunk selections */
- if(NULL == dataset->shared->cache.chunk.sel_chunks) {
- if(NULL == (dataset->shared->cache.chunk.sel_chunks = H5SL_create(H5SL_TYPE_HSIZE, 0.5, (size_t)H5D_DEFAULT_SKIPLIST_HEIGHT)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create skip list for chunk selections")
- } /* end if */
- fm->sel_chunks = dataset->shared->cache.chunk.sel_chunks;
- HDassert(fm->sel_chunks);
-
- /* We are not using single element mode */
- fm->use_single = FALSE;
-
- /* Get type of selection on disk & in memory */
- if((fsel_type = H5S_GET_SELECT_TYPE(file_space)) < H5S_SEL_NONE)
- HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to get type of selection")
- if((fm->msel_type = H5S_GET_SELECT_TYPE(mem_space)) < H5S_SEL_NONE)
- HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to get type of selection")
-
- /* If the selection is NONE or POINTS, set the flag to FALSE */
- if(fsel_type == H5S_SEL_POINTS || fsel_type == H5S_SEL_NONE)
- sel_hyper_flag = FALSE;
- else
- sel_hyper_flag = TRUE;
-
- /* Check if file selection is a not a hyperslab selection */
- if(sel_hyper_flag) {
- /* Build the file selection for each chunk */
- if(H5D_create_chunk_file_map_hyper(fm, io_info) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections")
-
- /* Clean file chunks' hyperslab span "scratch" information */
- curr_node = H5SL_first(fm->sel_chunks);
- while(curr_node) {
- H5D_chunk_info_t *chunk_info; /* Pointer chunk information */
-
- /* Get pointer to chunk's information */
- chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node);
- HDassert(chunk_info);
-
- /* Clean hyperslab span's "scratch" information */
- if(H5S_hyper_reset_scratch(chunk_info->fspace) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset span scratch info")
-
- /* Get the next chunk node in the skip list */
- curr_node = H5SL_next(curr_node);
- } /* end while */
- } /* end if */
- else {
- /* Create temporary datatypes for selection iteration */
- if((f_tid = H5I_register(H5I_DATATYPE, H5T_copy(dataset->shared->type, H5T_COPY_ALL))) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register file datatype")
-
- /* Spaces might not be the same shape, iterate over the file selection directly */
- if(H5S_select_iterate(&bogus, f_tid, file_space, H5D_chunk_file_cb, fm) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections")
-
- /* Reset "last chunk" info */
- fm->last_index = (hsize_t)-1;
- fm->last_chunk_info = NULL;
- } /* end else */
-
- /* Build the memory selection for each chunk */
- if(sel_hyper_flag && H5S_select_shape_same(file_space, mem_space) == TRUE) {
- /* Reset chunk template information */
- fm->mchunk_tmpl = NULL;
-
- /* If the selections are the same shape, use the file chunk information
- * to generate the memory chunk information quickly.
- */
- if(H5D_create_chunk_mem_map_hyper(fm) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections")
- } /* end if */
- else {
- size_t elmt_size; /* Memory datatype size */
-
- /* Make a copy of equivalent memory space */
- if((tmp_mspace = H5S_copy(mem_space, TRUE, FALSE)) == NULL)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space")
-
- /* De-select the mem space copy */
- if(H5S_select_none(tmp_mspace) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to de-select memory space")
-
- /* Save chunk template information */
- fm->mchunk_tmpl = tmp_mspace;
-
- /* Create temporary datatypes for selection iteration */
- if(f_tid < 0) {
- if((f_tid = H5I_register(H5I_DATATYPE, H5T_copy(dataset->shared->type, H5T_COPY_ALL))) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register file datatype")
- } /* end if */
-
- /* Create selection iterator for memory selection */
- if(0 == (elmt_size = H5T_get_size(mem_type)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid")
- if(H5S_select_iter_init(&(fm->mem_iter), mem_space, elmt_size) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
- iter_init = TRUE; /* Selection iteration info has been initialized */
-
- /* Spaces aren't the same shape, iterate over the memory selection directly */
- if(H5S_select_iterate(&bogus, f_tid, file_space, H5D_chunk_mem_cb, fm) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections")
-
- /* Clean up hyperslab stuff, if necessary */
- if(fm->msel_type != H5S_SEL_POINTS) {
- /* Clean memory chunks' hyperslab span "scratch" information */
- curr_node = H5SL_first(fm->sel_chunks);
- while(curr_node) {
- H5D_chunk_info_t *chunk_info; /* Pointer chunk information */
-
- /* Get pointer to chunk's information */
- chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node);
- HDassert(chunk_info);
-
- /* Clean hyperslab span's "scratch" information */
- if(H5S_hyper_reset_scratch(chunk_info->mspace) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset span scratch info")
-
- /* Get the next chunk node in the skip list */
- curr_node = H5SL_next(curr_node);
- } /* end while */
- } /* end if */
- } /* end else */
- } /* end else */
-
-done:
- /* Release the [potentially partially built] chunk mapping information if an error occurs */
- if(ret_value < 0) {
- if(tmp_mspace && !fm->mchunk_tmpl) {
- if(H5S_close(tmp_mspace) < 0)
- HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "can't release memory chunk dataspace template")
- } /* end if */
-
- if(H5D_chunk_io_term(fm) < 0)
- HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release chunk mapping")
- } /* end if */
-
- /* Reset the global dataspace info */
- fm->file_space = NULL;
- fm->mem_space = NULL;
-
- if(iter_init) {
- if(H5S_SELECT_ITER_RELEASE(&(fm->mem_iter)) < 0)
- HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
- } /* end if */
- if(f_tid!=(-1)) {
- if(H5I_dec_ref(f_tid) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
- } /* end if */
- if(file_space_normalized) {
- if(H5S_hyper_denormalize_offset((H5S_t *)file_space, old_offset) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to normalize dataspace by offset")
- } /* end if */
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_chunk_io_init() */
-
-
-/*--------------------------------------------------------------------------
- NAME
- H5D_free_chunk_info
- PURPOSE
- Internal routine to destroy a chunk info node
- USAGE
- void H5D_free_chunk_info(chunk_info)
- void *chunk_info; IN: Pointer to chunk info to destroy
- RETURNS
- No return value
- DESCRIPTION
- Releases all the memory for a chunk info node. Called by H5SL_free
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-static herr_t
-H5D_free_chunk_info(void *item, void UNUSED *key, void UNUSED *opdata)
-{
- H5D_chunk_info_t *chunk_info = (H5D_chunk_info_t *)item;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_free_chunk_info)
-
- HDassert(chunk_info);
-
- /* Close the chunk's file dataspace, if it's not shared */
- if(!chunk_info->fspace_shared)
- (void)H5S_close(chunk_info->fspace);
- else
- H5S_select_all(chunk_info->fspace, TRUE);
-
- /* Close the chunk's memory dataspace, if it's not shared */
- if(!chunk_info->mspace_shared)
- (void)H5S_close(chunk_info->mspace);
-
- /* Free the actual chunk info */
- H5FL_FREE(H5D_chunk_info_t, chunk_info);
-
- FUNC_LEAVE_NOAPI(0)
-} /* H5D_free_chunk_info() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5D_create_chunk_map_single
- *
- * Purpose: Create chunk selections when appending a single record
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Tuesday, November 20, 2007
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5D_create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t
-#ifndef H5_HAVE_PARALLEL
- UNUSED
-#endif /* H5_HAVE_PARALLEL */
- *io_info)
-{
- H5D_chunk_info_t *chunk_info; /* Chunk information to insert into skip list */
- hsize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */
- hsize_t sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5D_create_chunk_map_single)
-
- /* Sanity check */
- HDassert(fm->f_ndims > 0);
-
- /* Get coordinate for selection */
- if(H5S_SELECT_BOUNDS(fm->file_space, sel_start, sel_end) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
-
- /* Initialize the 'single chunk' file & memory chunk information */
- chunk_info = fm->single_chunk_info;
- chunk_info->chunk_points = 1;
-
- /* Set chunk location & hyperslab size */
- for(u = 0; u < fm->f_ndims; u++) {
- HDassert(sel_start[u] == sel_end[u]);
- chunk_info->coords[u] = (sel_start[u] / fm->layout->u.chunk.dim[u]) * fm->layout->u.chunk.dim[u];
- } /* end for */
- chunk_info->coords[fm->f_ndims] = 0;
-
- /* Calculate the index of this chunk */
- if(H5V_chunk_index(fm->f_ndims, chunk_info->coords, fm->layout->u.chunk.dim, fm->down_chunks, &chunk_info->index) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
-
- /* Copy selection for file's dataspace into chunk dataspace */
- if(H5S_select_copy(fm->single_space, fm->file_space, FALSE) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file selection")
-
- /* Move selection back to have correct offset in chunk */
- if(H5S_SELECT_ADJUST_U(fm->single_space, chunk_info->coords) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk selection")
-
-#ifdef H5_HAVE_PARALLEL
- /* store chunk selection information */
- if(io_info->using_mpi_vfd)
- fm->select_chunk[chunk_info->index] = chunk_info;
-#endif /* H5_HAVE_PARALLEL */
-
- /* Set the file dataspace for the chunk to the shared 'single' dataspace */
- chunk_info->fspace = fm->single_space;
-
- /* Indicate that the chunk's file dataspace is shared */
- chunk_info->fspace_shared = TRUE;
-
- /* Just point at the memory dataspace & selection */
- /* (Casting away const OK -QAK) */
- chunk_info->mspace = (H5S_t *)fm->mem_space;
-
- /* Indicate that the chunk's memory dataspace is shared */
- chunk_info->mspace_shared = TRUE;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_create_chunk_map_single() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5D_create_chunk_file_map_hyper
- *
- * Purpose: Create all chunk selections in file.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Thursday, May 29, 2003
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5D_create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t
-#ifndef H5_HAVE_PARALLEL
- UNUSED
-#endif /* H5_HAVE_PARALLEL */
- *io_info)
-{
- hsize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */
- hsize_t sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */
- hsize_t sel_points; /* Number of elements in file selection */
- hsize_t start_coords[H5O_LAYOUT_NDIMS]; /* Starting coordinates of selection */
- hsize_t coords[H5O_LAYOUT_NDIMS]; /* Current coordinates of chunk */
- hsize_t end[H5O_LAYOUT_NDIMS]; /* Current coordinates of chunk */
- hsize_t chunk_index; /* Index of chunk */
- int curr_dim; /* Current dimension to increment */
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5D_create_chunk_file_map_hyper)
-
- /* Sanity check */
- assert(fm->f_ndims>0);
-
- /* Get number of elements selected in file */
- sel_points = fm->nelmts;
-
- /* Get bounding box for selection (to reduce the number of chunks to iterate over) */
- if(H5S_SELECT_BOUNDS(fm->file_space, sel_start, sel_end) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
-
- /* Set initial chunk location & hyperslab size */
-
- for(u=0; u<fm->f_ndims; u++) {
- start_coords[u]=(sel_start[u]/fm->layout->u.chunk.dim[u])*fm->layout->u.chunk.dim[u];
- coords[u]=start_coords[u];
- end[u]=(coords[u]+fm->chunk_dim[u])-1;
- } /* end for */
-
-
- /* Calculate the index of this chunk */
- if(H5V_chunk_index(fm->f_ndims,coords,fm->layout->u.chunk.dim,fm->down_chunks,&chunk_index) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
-
- /* Iterate through each chunk in the dataset */
- while(sel_points) {
- /* Check for intersection of temporary chunk and file selection */
- /* (Casting away const OK - QAK) */
- if(H5S_hyper_intersect_block((H5S_t *)fm->file_space,coords,end)==TRUE) {
- H5S_t *tmp_fchunk; /* Temporary file dataspace */
- H5D_chunk_info_t *new_chunk_info; /* chunk information to insert into skip list */
- hssize_t schunk_points; /* Number of elements in chunk selection */
-
- /* Create "temporary" chunk for selection operations (copy file space) */
- if((tmp_fchunk = H5S_copy(fm->file_space, TRUE, FALSE)) == NULL)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space")
-
- /* Make certain selections are stored in span tree form (not "optimized hyperslab" or "all") */
- if(H5S_hyper_convert(tmp_fchunk) < 0) {
- (void)H5S_close(tmp_fchunk);
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to convert selection to span trees")
- } /* end if */
-
- /* "AND" temporary chunk and current chunk */
- if(H5S_select_hyperslab(tmp_fchunk,H5S_SELECT_AND,coords,NULL,fm->chunk_dim,NULL) < 0) {
- (void)H5S_close(tmp_fchunk);
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't create chunk selection")
- } /* end if */
-
- /* Resize chunk's dataspace dimensions to size of chunk */
- if(H5S_set_extent_real(tmp_fchunk,fm->chunk_dim) < 0) {
- (void)H5S_close(tmp_fchunk);
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk dimensions")
- } /* end if */
-
- /* Move selection back to have correct offset in chunk */
- if(H5S_SELECT_ADJUST_U(tmp_fchunk, coords) < 0) {
- (void)H5S_close(tmp_fchunk);
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk selection")
- } /* end if */
-
- /* Add temporary chunk to the list of chunks */
-
- /* Allocate the file & memory chunk information */
- if (NULL==(new_chunk_info = H5FL_MALLOC (H5D_chunk_info_t))) {
- (void)H5S_close(tmp_fchunk);
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info")
- } /* end if */
-
- /* Initialize the chunk information */
-
- /* Set the chunk index */
- new_chunk_info->index=chunk_index;
-
-#ifdef H5_HAVE_PARALLEL
- /* store chunk selection information */
- if(io_info->using_mpi_vfd)
- fm->select_chunk[chunk_index] = new_chunk_info;
-#endif /* H5_HAVE_PARALLEL */
-
- /* Set the file chunk dataspace */
- new_chunk_info->fspace = tmp_fchunk;
- new_chunk_info->fspace_shared = FALSE;
-
- /* Set the memory chunk dataspace */
- new_chunk_info->mspace=NULL;
- new_chunk_info->mspace_shared = FALSE;
-
- /* Copy the chunk's coordinates */
- for(u=0; u<fm->f_ndims; u++)
- new_chunk_info->coords[u]=coords[u];
- new_chunk_info->coords[fm->f_ndims]=0;
-
- /* Insert the new chunk into the skip list */
- if(H5SL_insert(fm->sel_chunks,new_chunk_info,&new_chunk_info->index) < 0) {
- H5D_free_chunk_info(new_chunk_info,NULL,NULL);
- HGOTO_ERROR(H5E_DATASPACE,H5E_CANTINSERT,FAIL,"can't insert chunk into skip list")
- } /* end if */
-
- /* Get number of elements selected in chunk */
- if((schunk_points=H5S_GET_SELECT_NPOINTS(tmp_fchunk)) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection # of elements")
- H5_ASSIGN_OVERFLOW(new_chunk_info->chunk_points,schunk_points,hssize_t,size_t);
-
- /* Decrement # of points left in file selection */
- sel_points-=(hsize_t)schunk_points;
-
- /* Leave if we are done */
- if(sel_points==0)
- HGOTO_DONE(SUCCEED)
- assert(sel_points>0);
- } /* end if */
-
- /* Increment chunk index */
- chunk_index++;
-
- /* Set current increment dimension */
- curr_dim=(int)fm->f_ndims-1;
-
- /* Increment chunk location in fastest changing dimension */
- H5_CHECK_OVERFLOW(fm->chunk_dim[curr_dim],hsize_t,hssize_t);
- coords[curr_dim]+=fm->chunk_dim[curr_dim];
- end[curr_dim]+=fm->chunk_dim[curr_dim];
-
- /* Bring chunk location back into bounds, if necessary */
- if(coords[curr_dim]>sel_end[curr_dim]) {
- do {
- /* Reset current dimension's location to 0 */
- coords[curr_dim]=start_coords[curr_dim]; /*lint !e771 The start_coords will always be initialized */
- end[curr_dim]=(coords[curr_dim]+(hssize_t)fm->chunk_dim[curr_dim])-1;
-
- /* Decrement current dimension */
- curr_dim--;
-
- /* Increment chunk location in current dimension */
- coords[curr_dim]+=fm->chunk_dim[curr_dim];
- end[curr_dim]=(coords[curr_dim]+fm->chunk_dim[curr_dim])-1;
- } while(coords[curr_dim]>sel_end[curr_dim]);
-
- /* Re-Calculate the index of this chunk */
- if(H5V_chunk_index(fm->f_ndims,coords,fm->layout->u.chunk.dim,fm->down_chunks,&chunk_index) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
- } /* end if */
- } /* end while */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_create_chunk_file_map_hyper() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5D_create_chunk_mem_map_hyper
- *
- * Purpose: Create all chunk selections in memory by copying the file
- * chunk selections and adjusting their offsets to be correct
- * for the memory.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Thursday, May 29, 2003
- *
- * Assumptions: That the file and memory selections are the same shape.
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5D_create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm)
-{
- H5SL_node_t *curr_node; /* Current node in skip list */
- hsize_t file_sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */
- hsize_t file_sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */
- hsize_t mem_sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */
- hsize_t mem_sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */
- hssize_t adjust[H5O_LAYOUT_NDIMS]; /* Adjustment to make to all file chunks */
- hssize_t chunk_adjust[H5O_LAYOUT_NDIMS]; /* Adjustment to make to a particular chunk */
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5D_create_chunk_mem_map_hyper)
-
- /* Sanity check */
- assert(fm->f_ndims>0);
-
- /* Check for all I/O going to a single chunk */
- if(H5SL_count(fm->sel_chunks)==1) {
- H5D_chunk_info_t *chunk_info; /* Pointer to chunk information */
-
- /* Get the node */
- curr_node=H5SL_first(fm->sel_chunks);
-
- /* Get pointer to chunk's information */
- chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node);
- assert(chunk_info);
-
- /* Just point at the memory dataspace & selection */
- /* (Casting away const OK -QAK) */
- chunk_info->mspace=(H5S_t *)fm->mem_space;
-
- /* Indicate that the chunk's memory space is shared */
- chunk_info->mspace_shared = TRUE;
- } /* end if */
- else {
- /* Get bounding box for file selection */
- if(H5S_SELECT_BOUNDS(fm->file_space, file_sel_start, file_sel_end) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
-
- /* Get bounding box for memory selection */
- if(H5S_SELECT_BOUNDS(fm->mem_space, mem_sel_start, mem_sel_end) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
-
- /* Calculate the adjustment for memory selection from file selection */
- assert(fm->m_ndims==fm->f_ndims);
- for(u=0; u<fm->f_ndims; u++) {
- H5_CHECK_OVERFLOW(file_sel_start[u],hsize_t,hssize_t);
- H5_CHECK_OVERFLOW(mem_sel_start[u],hsize_t,hssize_t);
- adjust[u]=(hssize_t)file_sel_start[u]-(hssize_t)mem_sel_start[u];
- } /* end for */
-
- /* Iterate over each chunk in the chunk list */
- curr_node=H5SL_first(fm->sel_chunks);
- while(curr_node) {
- H5D_chunk_info_t *chunk_info; /* Pointer to chunk information */
-
- /* Get pointer to chunk's information */
- chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node);
- assert(chunk_info);
-
- /* Copy the information */
-
- /* Copy the memory dataspace */
- if((chunk_info->mspace = H5S_copy(fm->mem_space, TRUE, FALSE)) == NULL)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space")
-
- /* Release the current selection */
- if(H5S_SELECT_RELEASE(chunk_info->mspace) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection")
-
- /* Copy the file chunk's selection */
- if(H5S_select_copy(chunk_info->mspace,chunk_info->fspace,FALSE) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy selection")
-
- /* Compensate for the chunk offset */
- for(u=0; u<fm->f_ndims; u++) {
- H5_CHECK_OVERFLOW(chunk_info->coords[u],hsize_t,hssize_t);
- chunk_adjust[u]=adjust[u]-(hssize_t)chunk_info->coords[u]; /*lint !e771 The adjust array will always be initialized */
- } /* end for */
-
- /* Adjust the selection */
- if(H5S_hyper_adjust_s(chunk_info->mspace,chunk_adjust) < 0) /*lint !e772 The chunk_adjust array will always be initialized */
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk selection")
-
- /* Get the next chunk node in the skip list */
- curr_node=H5SL_next(curr_node);
- } /* end while */
- } /* end else */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_create_chunk_mem_map_hyper() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5D_chunk_file_cb
- *
- * Purpose: Callback routine for file selection iterator. Used when
- * creating selections in file for each point selected.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Wednesday, July 23, 2003
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5D_chunk_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const hsize_t *coords, void *_fm)
-{
- H5D_chunk_map_t *fm = (H5D_chunk_map_t *)_fm; /* File<->memory chunk mapping info */
- H5D_chunk_info_t *chunk_info; /* Chunk information for current chunk */
- hsize_t coords_in_chunk[H5O_LAYOUT_NDIMS]; /* Coordinates of element in chunk */
- hsize_t chunk_index; /* Chunk index */
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_file_cb)
-
- /* Calculate the index of this chunk */
- if(H5V_chunk_index(ndims,coords,fm->layout->u.chunk.dim,fm->down_chunks,&chunk_index) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
-
- /* Find correct chunk in file & memory skip list */
- if(chunk_index==fm->last_index) {
- /* If the chunk index is the same as the last chunk index we used,
- * get the cached info to operate on.
- */
- chunk_info=fm->last_chunk_info;
- } /* end if */
- else {
- /* If the chunk index is not the same as the last chunk index we used,
- * find the chunk in the skip list.
- */
- /* Get the chunk node from the skip list */
- if(NULL == (chunk_info = (H5D_chunk_info_t *)H5SL_search(fm->sel_chunks, &chunk_index))) {
- H5S_t *fspace; /* Memory chunk's dataspace */
-
- /* Allocate the file & memory chunk information */
- if (NULL==(chunk_info = H5FL_MALLOC (H5D_chunk_info_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info")
-
- /* Initialize the chunk information */
-
- /* Set the chunk index */
- chunk_info->index=chunk_index;
-
- /* Create a dataspace for the chunk */
- if((fspace = H5S_create_simple(fm->f_ndims,fm->chunk_dim,NULL))==NULL) {
- H5FL_FREE(H5D_chunk_info_t,chunk_info);
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create dataspace for chunk")
- } /* end if */
-
- /* De-select the chunk space */
- if(H5S_select_none(fspace) < 0) {
- (void)H5S_close(fspace);
- H5FL_FREE(H5D_chunk_info_t,chunk_info);
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to de-select dataspace")
- } /* end if */
-
- /* Set the file chunk dataspace */
- chunk_info->fspace = fspace;
- chunk_info->fspace_shared = FALSE;
-
- /* Set the memory chunk dataspace */
- chunk_info->mspace=NULL;
- chunk_info->mspace_shared = FALSE;
-
- /* Set the number of selected elements in chunk to zero */
- chunk_info->chunk_points=0;
-
- /* Compute the chunk's coordinates */
- for(u=0; u<fm->f_ndims; u++) {
- H5_CHECK_OVERFLOW(fm->layout->u.chunk.dim[u],hsize_t,hssize_t);
- chunk_info->coords[u]=(coords[u]/(hssize_t)fm->layout->u.chunk.dim[u])*(hssize_t)fm->layout->u.chunk.dim[u];
- } /* end for */
- chunk_info->coords[fm->f_ndims]=0;
-
- /* Insert the new chunk into the skip list */
- if(H5SL_insert(fm->sel_chunks,chunk_info,&chunk_info->index) < 0) {
- H5D_free_chunk_info(chunk_info,NULL,NULL);
- HGOTO_ERROR(H5E_DATASPACE,H5E_CANTINSERT,FAIL,"can't insert chunk into skip list")
- } /* end if */
- } /* end if */
-
- /* Update the "last chunk seen" information */
- fm->last_index=chunk_index;
- fm->last_chunk_info=chunk_info;
- } /* end else */
-
- /* Get the coordinates of the element in the chunk */
- for(u=0; u<fm->f_ndims; u++)
- coords_in_chunk[u]=coords[u]%fm->layout->u.chunk.dim[u];
-
- /* Add point to file selection for chunk */
- if(H5S_select_elements(chunk_info->fspace, H5S_SELECT_APPEND, (size_t)1, coords_in_chunk) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to select element")
-
- /* Increment the number of elemented selected in chunk */
- chunk_info->chunk_points++;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_chunk_file_cb() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5D_chunk_mem_cb
- *
- * Purpose: Callback routine for file selection iterator. Used when
- * creating selections in memory for each chunk.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Raymond Lu
- * Thursday, April 10, 2003
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static herr_t
-H5D_chunk_mem_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const hsize_t *coords, void *_fm)
-{
- H5D_chunk_map_t *fm = (H5D_chunk_map_t *)_fm; /* File<->memory chunk mapping info */
- H5D_chunk_info_t *chunk_info; /* Chunk information for current chunk */
- hsize_t coords_in_mem[H5O_LAYOUT_NDIMS]; /* Coordinates of element in memory */
- hsize_t chunk_index; /* Chunk index */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_mem_cb)
-
- /* Calculate the index of this chunk */
- if(H5V_chunk_index(ndims,coords,fm->layout->u.chunk.dim,fm->down_chunks,&chunk_index) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
-
- /* Find correct chunk in file & memory skip list */
- if(chunk_index==fm->last_index) {
- /* If the chunk index is the same as the last chunk index we used,
- * get the cached spaces to operate on.
- */
- chunk_info=fm->last_chunk_info;
- } /* end if */
- else {
- /* If the chunk index is not the same as the last chunk index we used,
- * find the chunk in the skip list.
- */
- /* Get the chunk node from the skip list */
- if(NULL == (chunk_info = (H5D_chunk_info_t *)H5SL_search(fm->sel_chunks, &chunk_index)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, FAIL, "can't locate chunk in skip list")
-
- /* Check if the chunk already has a memory space */
- if(chunk_info->mspace==NULL) {
- /* Copy the template memory chunk dataspace */
- if((chunk_info->mspace = H5S_copy(fm->mchunk_tmpl, FALSE, FALSE)) == NULL)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file space")
- } /* end else */
-
- /* Update the "last chunk seen" information */
- fm->last_index=chunk_index;
- fm->last_chunk_info=chunk_info;
- } /* end else */
-
- /* Get coordinates of selection iterator for memory */
- if(H5S_SELECT_ITER_COORDS(&fm->mem_iter,coords_in_mem) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator coordinates")
-
- /* Add point to memory selection for chunk */
- if(fm->msel_type==H5S_SEL_POINTS) {
- if(H5S_select_elements(chunk_info->mspace, H5S_SELECT_APPEND, (size_t)1, coords_in_mem) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to select element")
- } /* end if */
- else {
- if(H5S_hyper_add_span_element(chunk_info->mspace, fm->m_ndims, coords_in_mem) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to select element")
- } /* end else */
-
- /* Move memory selection iterator to next element in selection */
- if(H5S_SELECT_ITER_NEXT(&fm->mem_iter, (size_t)1) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to move to next iterator location")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_chunk_mem_cb() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5D_chunk_cacheable
- *
- * Purpose: A small internal function to if it's possible to load the
- * chunk into cache.
- *
- * Return: TRUE or FALSE
- *
- * Programmer: Raymond Lu
- * 17 July 2007
- *
- *-------------------------------------------------------------------------
- */
-hbool_t
-H5D_chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr)
-{
- const H5D_t *dataset = io_info->dset;
- hbool_t ret_value;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_chunk_cacheable)
-
- HDassert(io_info);
- HDassert(dataset);
-
- /* Must bring the whole chunk in if there are any filters */
- if(dataset->shared->dcpl_cache.pline.nused > 0)
- ret_value = TRUE;
- else
-#ifdef H5_HAVE_PARALLEL
- /* If MPI based VFD is used and the file is opened for write access, must
- * bypass the chunk-cache scheme because other MPI processes could
- * be writing to other elements in the same chunk. Do a direct
- * write-through of only the elements requested.
- */
- if(io_info->using_mpi_vfd && (H5F_ACC_RDWR & H5F_INTENT(dataset->oloc.file)))
- ret_value = FALSE;
- else
-#endif /* H5_HAVE_PARALLEL */
- /* If the chunk is too large to keep in the cache and if the address
- * for the chunk has been defined, then don't load the chunk into the
- * cache, just write the data to it directly.
- */
- if(dataset->shared->layout.u.chunk.size > dataset->shared->cache.chunk.nbytes
- && H5F_addr_defined(caddr))
- ret_value = FALSE;
- else
- ret_value = TRUE;
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_chunk_cacheable() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5D_chunk_in_cache
- *
- * Purpose: Check if a chunk is in the cache.
- *
- * Return: TRUE or FALSE
- *
- * Programmer: Quincey Koziol
- * 1 April 2008
- *
- *-------------------------------------------------------------------------
- */
-static hbool_t
-H5D_chunk_in_cache(const H5D_io_info_t *io_info)
-{
- H5D_rdcc_t *rdcc = &(io_info->dset->shared->cache.chunk);/*raw data chunk cache*/
- hbool_t found = FALSE; /*already in cache? */
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_chunk_in_cache)
-
- HDassert(io_info);
-
- /* Check if the chunk is in the cache (but hasn't been written to disk yet) */
- if(rdcc->nslots > 0) {
- unsigned idx = H5D_CHUNK_HASH(io_info->dset->shared, io_info->store->chunk.index); /* Cache entry index */
- H5D_rdcc_ent_t *ent = rdcc->slot[idx]; /* Cache entry */
-
- /* Potential match... */
- if(ent) {
- size_t u; /* Local index variable */
-
- for(u = 0, found = TRUE; u < io_info->dset->shared->layout.u.chunk.ndims; u++) {
- if(io_info->store->chunk.offset[u] != ent->offset[u]) {
- found = FALSE;
- break;
- } /* end if */
- } /* end for */
- } /* end if */
- } /* end if */
-
- FUNC_LEAVE_NOAPI(found)
-} /* end H5D_chunk_in_cache() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5D_chunk_read
- *
- * Purpose: Read from a chunked dataset.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Raymond Lu
- * Thursday, April 10, 2003
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5D_chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t UNUSED nelmts, const H5S_t UNUSED *file_space, const H5S_t UNUSED *mem_space,
- H5D_chunk_map_t *fm)
-{
- H5SL_node_t *chunk_node; /* Current node in chunk skip list */
- H5D_io_info_t nul_io_info; /* "null" I/O info object */
- H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
- H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
- H5D_io_info_t cpt_io_info; /* Compact I/O info object */
- H5D_storage_t cpt_store; /* Chunk storage information as compact dataset */
- hbool_t cpt_dirty; /* Temporary placeholder for compact storage "dirty" flag */
- size_t src_accessed_bytes = 0; /* Total accessed size in a chunk */
- hbool_t skip_missing_chunks = FALSE; /* Whether to skip missing chunks */
- unsigned idx_hint = 0; /* Cache index hint */
- herr_t ret_value = SUCCEED; /*return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_read)
-
- /* Sanity check */
- HDassert(io_info);
- HDassert(io_info->u.rbuf);
- HDassert(type_info);
- HDassert(fm);
-
- /* Set up "null" I/O info object */
- HDmemcpy(&nul_io_info, io_info, sizeof(nul_io_info));
- nul_io_info.layout_ops = *H5D_LOPS_NULL;
-
- /* Set up contiguous I/O info object */
- HDmemcpy(&ctg_io_info, io_info, sizeof(ctg_io_info));
- ctg_io_info.store = &ctg_store;
- ctg_io_info.layout_ops = *H5D_LOPS_CONTIG;
-
- /* Initialize temporary contiguous storage info */
- ctg_store.contig.dset_size = (hsize_t)io_info->dset->shared->layout.u.chunk.size;
-
- /* Set up compact I/O info object */
- HDmemcpy(&cpt_io_info, io_info, sizeof(cpt_io_info));
- cpt_io_info.store = &cpt_store;
- cpt_io_info.layout_ops = *H5D_LOPS_COMPACT;
-
- /* Initialize temporary compact storage info */
- cpt_store.compact.dirty = &cpt_dirty;
-
- {
- const H5O_fill_t *fill = &(io_info->dset->shared->dcpl_cache.fill); /* Fill value info */
- H5D_fill_value_t fill_status; /* Fill value status */
-
- /* Check the fill value status */
- if(H5P_is_fill_value_defined(fill, &fill_status) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined")
-
- /* If we are never to return fill values, or if we would return them
- * but they aren't set, set the flag to skip missing chunks.
- */
- if(fill->fill_time == H5D_FILL_TIME_NEVER ||
- (fill->fill_time == H5D_FILL_TIME_IFSET && fill_status != H5D_FILL_VALUE_USER_DEFINED))
- skip_missing_chunks = TRUE;
- }
-
- /* Iterate through nodes in chunk skip list */
- chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm);
- while(chunk_node) {
- H5D_chunk_info_t *chunk_info; /* Chunk information */
- H5D_io_info_t *chk_io_info; /* Pointer to I/O info object for this chunk */
- void *chunk; /* Pointer to locked chunk buffer */
- haddr_t chunk_addr; /* Chunk address on disk */
- H5D_istore_ud1_t udata; /* B-tree pass-through */
-
- /* Get the actual chunk information from the skip list node */
- chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
-
- /* Pass in chunk's coordinates in a union. */
- io_info->store->chunk.offset = chunk_info->coords;
- io_info->store->chunk.index = chunk_info->index;
-
- /* Get the address of the chunk in the file */
- chunk_addr = H5D_istore_get_addr(io_info, &udata);
-
- /* Check for non-existant chunk & skip it if appropriate */
- if(!H5F_addr_defined(chunk_addr) && !H5D_chunk_in_cache(io_info)
- && skip_missing_chunks) {
- /* No chunk cached */
- chunk = NULL;
-
- /* Point I/O info at "null" I/O info for this chunk */
- chk_io_info = &nul_io_info;
- } /* end if */
- else {
- /* Load the chunk into cache and lock it. */
- if(H5D_chunk_cacheable(io_info, chunk_addr)) {
- /* Compute # of bytes accessed in chunk */
- src_accessed_bytes = chunk_info->chunk_points * type_info->src_type_size;
-
- /* Lock the chunk into the cache */
- 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")
-
- /* Set up the storage buffer information for this chunk */
- cpt_store.compact.buf = chunk;
-
- /* Point I/O info at contiguous I/O info for this chunk */
- chk_io_info = &cpt_io_info;
- } /* end if */
- else {
- /* Sanity check */
- HDassert(H5F_addr_defined(chunk_addr));
-
- /* Set up the storage address information for this chunk */
- ctg_store.contig.dset_addr = chunk_addr;
-
- /* No chunk cached */
- chunk = NULL;
-
- /* Point I/O info at temporary I/O info for this chunk */
- chk_io_info = &ctg_io_info;
- } /* end else */
- } /* end else */
-
- /* Perform the actual read operation */
- if((io_info->io_ops.single_read)(chk_io_info, type_info,
- (hsize_t)chunk_info->chunk_points, chunk_info->fspace, chunk_info->mspace) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked read failed")
-
- /* Release the cache lock on the chunk. */
- if(chunk && H5D_istore_unlock(io_info, FALSE, idx_hint, chunk, src_accessed_bytes) < 0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
-
- /* Advance to next chunk in list */
- chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
- } /* end while */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5D_chunk_read() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5D_chunk_write
- *
- * Purpose: Writes to a chunked dataset.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Raymond Lu
- * Thursday, April 10, 2003
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5D_chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t UNUSED nelmts, const H5S_t UNUSED *file_space, const H5S_t UNUSED *mem_space,
- H5D_chunk_map_t *fm)
-{
- H5SL_node_t *chunk_node; /* Current node in chunk skip list */
- H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
- H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
- H5D_io_info_t cpt_io_info; /* Compact I/O info object */
- H5D_storage_t cpt_store; /* Chunk storage information as compact dataset */
- hbool_t cpt_dirty; /* Temporary placeholder for compact storage "dirty" flag */
- size_t dst_accessed_bytes = 0; /* Total accessed size in a chunk */
- unsigned idx_hint = 0; /* Cache index hint */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_write)
-
- /* Sanity check */
- HDassert(io_info);
- HDassert(io_info->u.wbuf);
- HDassert(type_info);
- HDassert(fm);
-
- /* Set up contiguous I/O info object */
- HDmemcpy(&ctg_io_info, io_info, sizeof(ctg_io_info));
- ctg_io_info.store = &ctg_store;
- ctg_io_info.layout_ops = *H5D_LOPS_CONTIG;
-
- /* Initialize temporary contiguous storage info */
- ctg_store.contig.dset_size = (hsize_t)io_info->dset->shared->layout.u.chunk.size;
-
- /* Set up compact I/O info object */
- HDmemcpy(&cpt_io_info, io_info, sizeof(cpt_io_info));
- cpt_io_info.store = &cpt_store;
- cpt_io_info.layout_ops = *H5D_LOPS_COMPACT;
-
- /* Initialize temporary compact storage info */
- cpt_store.compact.dirty = &cpt_dirty;
-
- /* Iterate through nodes in chunk skip list */
- chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm);
- while(chunk_node) {
- H5D_chunk_info_t *chunk_info; /* Chunk information */
- H5D_io_info_t *chk_io_info; /* Pointer to I/O info object for this chunk */
- void *chunk; /* Pointer to locked chunk buffer */
- haddr_t chunk_addr; /* Chunk address on disk */
- H5D_istore_ud1_t udata; /* B-tree pass-through */
-
- /* Get the actual chunk information from the skip list node */
- chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
-
- /* Pass in chunk's coordinates in a union. */
- io_info->store->chunk.offset = chunk_info->coords;
- io_info->store->chunk.index = chunk_info->index;
-
- /* 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);
- if(H5D_chunk_cacheable(io_info, chunk_addr)) {
- hbool_t entire_chunk = TRUE; /* Whether whole chunk is selected */
-
- /* Compute # of bytes accessed in chunk */
- dst_accessed_bytes = chunk_info->chunk_points * type_info->dst_type_size;
-
- /* Determine if we will access all the data in the chunk */
- if(dst_accessed_bytes != ctg_store.contig.dset_size ||
- (chunk_info->chunk_points * type_info->src_type_size) != ctg_store.contig.dset_size)
- entire_chunk = FALSE;
-
- /* Lock the chunk into the cache */
- if(NULL == (chunk = H5D_istore_lock(io_info, &udata, entire_chunk, &idx_hint)))
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
-
- /* Set up the storage buffer information for this chunk */
- cpt_store.compact.buf = chunk;
-
- /* Point I/O info at main I/O info for this chunk */
- chk_io_info = &cpt_io_info;
- } /* end if */
- else {
- /* Sanity check */
- HDassert(H5F_addr_defined(chunk_addr));
-
- /* Set up the storage address information for this chunk */
- ctg_store.contig.dset_addr = chunk_addr;
-
- /* No chunk cached */
- chunk = NULL;
-
- /* Point I/O info at temporary I/O info for this chunk */
- chk_io_info = &ctg_io_info;
- } /* end else */
-
- /* Perform the actual write operation */
- if((io_info->io_ops.single_write)(chk_io_info, type_info,
- (hsize_t)chunk_info->chunk_points, chunk_info->fspace, chunk_info->mspace) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked write failed")
-
- /* Release the cache lock on the chunk. */
- if(chunk && H5D_istore_unlock(io_info, TRUE, idx_hint, chunk, dst_accessed_bytes) < 0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
-
- /* Advance to next chunk in list */
- chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
- } /* end while */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5D_chunk_write() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5D_chunk_io_term
- *
- * Purpose: Destroy I/O operation information.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Saturday, May 17, 2003
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5D_chunk_io_term(const H5D_chunk_map_t *fm)
-{
- herr_t ret_value = SUCCEED; /*return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_io_term)
-
- /* Single element I/O vs. multiple element I/O cleanup */
- if(fm->use_single) {
- /* Sanity checks */
- HDassert(fm->sel_chunks == NULL);
- HDassert(fm->single_chunk_info);
- HDassert(fm->single_chunk_info->fspace_shared);
- HDassert(fm->single_chunk_info->mspace_shared);
-
- /* Reset the selection for the single element I/O */
- H5S_select_all(fm->single_space, TRUE);
- } /* end if */
- else {
- /* Release the nodes on the list of selected chunks */
- if(fm->sel_chunks)
- if(H5SL_free(fm->sel_chunks, H5D_free_chunk_info, NULL) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTNEXT, FAIL, "can't iterate over chunks")
- } /* end else */
-
- /* Free the memory chunk dataspace template */
- if(fm->mchunk_tmpl)
- if(H5S_close(fm->mchunk_tmpl) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "can't release memory chunk dataspace template")
-#ifdef H5_HAVE_PARALLEL
- if(fm->select_chunk)
- H5MM_xfree(fm->select_chunk);
-#endif /* H5_HAVE_PARALLEL */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_chunk_io_term() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5D_null_readvv
- *
- * Purpose: Performs "no-op" I/O operation, advancing through two I/O
- * vectors, until one runs out.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Tuesday, April 1, 2008
- *
- *-------------------------------------------------------------------------
- */
-static ssize_t
-H5D_null_readvv(const H5D_io_info_t UNUSED *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[])
-{
- size_t u, v; /* Local index variables */
- size_t size; /* Size of sequence in bytes */
- ssize_t bytes_processed = 0; /* Eventual return value */
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_null_readvv)
-
- /* Check args */
- HDassert(chunk_len_arr);
- HDassert(chunk_offset_arr);
- HDassert(mem_len_arr);
- HDassert(mem_offset_arr);
-
- /* Work through all the sequences */
- for(u = *mem_curr_seq, v = *chunk_curr_seq; u < mem_max_nseq && v < chunk_max_nseq; ) {
- /* Choose smallest buffer to write */
- if(chunk_len_arr[v] < mem_len_arr[u])
- size = chunk_len_arr[v];
- else
- size = mem_len_arr[u];
-
- /* Update source information */
- chunk_len_arr[v] -= size;
- chunk_offset_arr[v] += size;
- if(chunk_len_arr[v] == 0)
- v++;
-
- /* Update destination information */
- mem_len_arr[u] -= size;
- mem_offset_arr[u] += size;
- if(mem_len_arr[u] == 0)
- u++;
-
- /* Increment number of bytes copied */
- bytes_processed += (ssize_t)size;
- } /* end for */
-
- /* Update current sequence vectors */
- *mem_curr_seq = u;
- *chunk_curr_seq = v;
-
- FUNC_LEAVE_NOAPI(bytes_processed)
-} /* H5D_null_readvv() */
-