/*------------------------------------------------------------------------- * Function: H5D_select_io * * Purpose: Perform I/O directly from application memory and a file * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Tuesday, November 27, 2007 * *------------------------------------------------------------------------- */ static herr_t H5D_select_io(H5D_io_info_t *io_info, size_t nelmts, size_t elmt_size, const H5S_t *file_space, const H5S_t *mem_space, haddr_t addr, void *chunk/*in*/, const H5D_select_buf_t *io_buf) { H5S_sel_iter_t mem_iter; /* Memory selection iteration info */ hbool_t mem_iter_init = 0; /* Memory selection iteration info has been initialized */ H5S_sel_iter_t file_iter; /* File selection iteration info */ hbool_t file_iter_init = 0; /* File selection iteration info has been initialized */ hsize_t _mem_off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets in memory */ hsize_t *mem_off = NULL; /* Pointer to sequence offsets in memory */ hsize_t _file_off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets in the file */ hsize_t *file_off = NULL; /* Pointer to sequence offsets in the file */ size_t _mem_len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths in memory */ size_t *mem_len = NULL; /* Pointer to sequence lengths in memory */ size_t _file_len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths in the file */ size_t *file_len = NULL; /* Pointer to sequence lengths in the file */ size_t curr_mem_seq; /* Current memory sequence to operate on */ size_t curr_file_seq; /* Current file sequence to operate on */ size_t mem_nseq; /* Number of sequences generated in the file */ size_t file_nseq; /* Number of sequences generated in memory */ ssize_t tmp_file_len; /* Temporary number of bytes in file sequence */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5D_select_io, FAIL) /* Check args */ HDassert(io_info); HDassert(io_info->dset); HDassert(io_info->store); HDassert(TRUE == H5P_isa_class(io_info->dxpl_id, H5P_DATASET_XFER)); HDassert(io_buf->u.rbuf); /* Allocate the vector I/O arrays */ if(io_info->dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) { if(NULL == (mem_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array") if(NULL == (mem_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array") if(NULL == (file_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array") if(NULL == (file_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array") } /* end if */ else {
/*-------------------------------------------------------------------------- NAME H5HP_create PURPOSE Create a heap USAGE H5HP_t *H5HP_create(heap_type) H5HP_type_t heap_type; IN: Type of heap to create RETURNS Returns a pointer to a heap on success, NULL on failure. DESCRIPTION Create a priority queue. The SIZE is used to set the initial number of entries allocated. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ H5HP_t * H5HP_create(H5HP_type_t heap_type) { H5HP_t *new_heap=NULL; /* Pointer to new heap object created */ H5HP_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI(NULL) /* Check args */ HDassert(heap_type==H5HP_MIN_HEAP || heap_type==H5HP_MAX_HEAP); /* Allocate ref-counted string structure */ if((new_heap=H5FL_MALLOC(H5HP_t))==NULL) HGOTO_ERROR(H5E_HEAP,H5E_NOSPACE,NULL,"memory allocation failed"); /* Allocate the array to store the heap entries */ if((new_heap->heap = H5FL_SEQ_MALLOC(H5HP_ent_t, (size_t)(H5HP_START_SIZE + 1)))==NULL) HGOTO_ERROR(H5E_HEAP,H5E_NOSPACE,NULL,"memory allocation failed"); /* Set the internal fields */ new_heap->type=heap_type; new_heap->nobjs=0; new_heap->nalloc=H5HP_START_SIZE+1; /* Set the information in the 0'th location based on the type of heap */ if(heap_type==H5HP_MIN_HEAP) { /* Set the value in the '0' location to be the minimum value, to * simplify the algorithms */ new_heap->heap[0].val=INT_MIN; new_heap->heap[0].obj=NULL; } /* end if */ else { /* Set the value in the '0' location to be the maximum value, to * simplify the algorithms */ new_heap->heap[0].val=INT_MAX; new_heap->heap[0].obj=NULL; } /* end else */ /* Set the return value */ ret_value=new_heap; done: /* Error cleanup */ if(NULL ==ret_value) { if(NULL != new_heap) { if(NULL != new_heap->heap) new_heap->heap = H5FL_SEQ_FREE(H5HP_ent_t, new_heap->heap); new_heap = H5FL_FREE(H5HP_t, new_heap); } /* end if */ } /* end if */ FUNC_LEAVE_NOAPI(ret_value); } /* end H5HP_create() */
/*------------------------------------------------------------------------- * Function: H5D__scatter_file * * Purpose: Scatters dataset elements from the type conversion buffer BUF * to the file F where the data points are arranged according to * the file dataspace FILE_SPACE and stored according to * LAYOUT and EFL. Each element is ELMT_SIZE bytes. * The caller is requesting that NELMTS elements are copied. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Thursday, June 20, 2002 * *------------------------------------------------------------------------- */ static herr_t H5D__scatter_file(const H5D_io_info_t *_io_info, const H5S_t *space, H5S_sel_iter_t *iter, size_t nelmts, const void *_buf) { H5D_io_info_t tmp_io_info; /* Temporary I/O info object */ hsize_t _off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets */ hsize_t *off = NULL; /* Pointer to sequence offsets */ hsize_t mem_off; /* Offset in memory */ size_t mem_curr_seq; /* "Current sequence" in memory */ size_t dset_curr_seq; /* "Current sequence" in dataset */ size_t _len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths */ size_t *len = NULL; /* Array to store sequence lengths */ size_t orig_mem_len, mem_len; /* Length of sequence in memory */ size_t nseq; /* Number of sequences generated */ size_t nelem; /* Number of elements used in sequences */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC /* Check args */ HDassert(_io_info); HDassert(space); HDassert(iter); HDassert(nelmts > 0); HDassert(_buf); /* Set up temporary I/O info object */ HDmemcpy(&tmp_io_info, _io_info, sizeof(*_io_info)); tmp_io_info.op_type = H5D_IO_OP_WRITE; tmp_io_info.u.wbuf = _buf; /* Allocate the vector I/O arrays */ if(tmp_io_info.dxpl_cache->vec_size > H5D_IO_VECTOR_SIZE) { if(NULL == (len = H5FL_SEQ_MALLOC(size_t, tmp_io_info.dxpl_cache->vec_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array") if(NULL == (off = H5FL_SEQ_MALLOC(hsize_t, tmp_io_info.dxpl_cache->vec_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array") } /* end if */ else {
/*------------------------------------------------------------------------- * Function: H5D_select_fscat * * Purpose: Scatters dataset elements from the type conversion buffer BUF * to the file F where the data points are arranged according to * the file dataspace FILE_SPACE and stored according to * LAYOUT and EFL. Each element is ELMT_SIZE bytes. * The caller is requesting that NELMTS elements are copied. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Thursday, June 20, 2002 * *------------------------------------------------------------------------- */ herr_t H5D_select_fscat (H5D_io_info_t *io_info, const H5S_t *space, H5S_sel_iter_t *iter, size_t nelmts, haddr_t chunk_addr, void *chunk/*in*/, const void *_buf) { const uint8_t *buf=_buf; /* Alias for pointer arithmetic */ hsize_t _off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets */ hsize_t *off=NULL; /* Pointer to sequence offsets */ hsize_t mem_off; /* Offset in memory */ size_t mem_curr_seq; /* "Current sequence" in memory */ size_t dset_curr_seq; /* "Current sequence" in dataset */ size_t _len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths */ size_t *len=NULL; /* Array to store sequence lengths */ size_t orig_mem_len, mem_len; /* Length of sequence in memory */ size_t nseq; /* Number of sequences generated */ size_t nelem; /* Number of elements used in sequences */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5D_select_fscat, FAIL); /* Check args */ assert (io_info); assert (space); assert (iter); assert (nelmts>0); assert (_buf); assert(TRUE==H5P_isa_class(io_info->dxpl_id,H5P_DATASET_XFER)); /* Allocate the vector I/O arrays */ if(io_info->dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) { if((len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array"); if((off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array"); } /* end if */ else { len=_len; off=_off; } /* end else */ /* Loop until all elements are written */ while(nelmts>0) { /* Get list of sequences for selection to write */ if(H5S_SELECT_GET_SEQ_LIST(space,H5S_GET_SEQ_LIST_SORTED,iter,io_info->dxpl_cache->vec_size,nelmts,&nseq,&nelem,off,len)<0) HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed"); /* Reset the current sequence information */ mem_curr_seq=dset_curr_seq=0; orig_mem_len=mem_len=nelem*iter->elmt_size; mem_off=0; /* Write sequence list out */ if((*io_info->ops.writevv)(io_info, nseq, &dset_curr_seq, len, off, (size_t)1, &mem_curr_seq, &mem_len, &mem_off, chunk_addr, chunk, buf) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error"); /* Update buffer */ buf += orig_mem_len; /* Decrement number of elements left to process */ nelmts -= nelem; } /* end while */ done: if(io_info->dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) { if(len!=NULL) H5FL_SEQ_FREE(size_t,len); if(off!=NULL) H5FL_SEQ_FREE(hsize_t,off); } /* end if */ FUNC_LEAVE_NOAPI(ret_value); } /* H5D_select_fscat() */
/*------------------------------------------------------------------------- * Function: H5D_select_mgath * * Purpose: Gathers dataset elements from application memory BUF and * copies them into the gather buffer TGATH_BUF. * Each element is ELMT_SIZE bytes and arranged in application * memory according to SPACE. * The caller is requesting that at most NELMTS be gathered. * * Return: Success: Number of elements copied. * Failure: 0 * * Programmer: Quincey Koziol * Monday, June 24, 2002 * *------------------------------------------------------------------------- */ size_t H5D_select_mgath (const void *_buf, const H5S_t *space, H5S_sel_iter_t *iter, size_t nelmts, const H5D_dxpl_cache_t *dxpl_cache, void *_tgath_buf/*out*/) { const uint8_t *buf=(const uint8_t *)_buf; /* Get local copies for address arithmetic */ uint8_t *tgath_buf=(uint8_t *)_tgath_buf; hsize_t _off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets */ hsize_t *off=NULL; /* Pointer to sequence offsets */ size_t _len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths */ size_t *len=NULL; /* Pointer to sequence lengths */ size_t curr_len; /* Length of bytes left to process in sequence */ size_t nseq; /* Number of sequences generated */ size_t curr_seq; /* Current sequence being processed */ size_t nelem; /* Number of elements used in sequences */ size_t ret_value=nelmts; /* Number of elements gathered */ FUNC_ENTER_NOAPI(H5D_select_mgath, 0); /* Check args */ assert (buf); assert (space); assert (iter); assert (nelmts>0); assert (tgath_buf); /* Allocate the vector I/O arrays */ if(dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) { if((len = H5FL_SEQ_MALLOC(size_t,dxpl_cache->vec_size))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "can't allocate I/O length vector array"); if((off = H5FL_SEQ_MALLOC(hsize_t,dxpl_cache->vec_size))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "can't allocate I/O offset vector array"); } /* end if */ else { len=_len; off=_off; } /* end else */ /* Loop until all elements are written */ while(nelmts>0) { /* Get list of sequences for selection to write */ if(H5S_SELECT_GET_SEQ_LIST(space,0,iter,dxpl_cache->vec_size,nelmts,&nseq,&nelem,off,len)<0) HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, 0, "sequence length generation failed"); /* Loop, while sequences left to process */ for(curr_seq=0; curr_seq<nseq; curr_seq++) { /* Get the number of bytes in sequence */ curr_len=len[curr_seq]; HDmemcpy(tgath_buf,buf+off[curr_seq],curr_len); /* Advance offset in gather buffer */ tgath_buf+=curr_len; } /* end for */ /* Decrement number of elements left to process */ nelmts -= nelem; } /* end while */ done: if(dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) { if(len!=NULL) H5FL_SEQ_FREE(size_t,len); if(off!=NULL) H5FL_SEQ_FREE(hsize_t,off); } /* end if */ FUNC_LEAVE_NOAPI(ret_value); } /* H5D_select_mgath() */