/*------------------------------------------------------------------------- * Function: H5S_mpio_all_type * * Purpose: Translate an HDF5 "all" selection into an MPI type. * * Return: non-negative on success, negative on failure. * * Outputs: *new_type the MPI type corresponding to the selection * *count how many objects of the new_type in selection * (useful if this is the buffer type for xfer) * *extra_offset Number of bytes of offset within dataset * *is_derived_type 0 if MPI primitive type, 1 if derived * * Programmer: rky 980813 * * Modifications: * * Quincey Koziol, June 18, 2002 * Added 'extra_offset' parameter * *------------------------------------------------------------------------- */ static herr_t H5S_mpio_all_type( const H5S_t *space, size_t elmt_size, /* out: */ MPI_Datatype *new_type, size_t *count, hsize_t *extra_offset, hbool_t *is_derived_type ) { hsize_t total_bytes; hssize_t snelmts; /*total number of elmts (signed) */ hsize_t nelmts; /*total number of elmts */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_all_type); /* Check args */ assert (space); /* Just treat the entire extent as a block of bytes */ if((snelmts = H5S_GET_EXTENT_NPOINTS(space))<0) HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection") H5_ASSIGN_OVERFLOW(nelmts,snelmts,hssize_t,hsize_t); total_bytes = (hsize_t)elmt_size*nelmts; /* fill in the return values */ *new_type = MPI_BYTE; H5_ASSIGN_OVERFLOW(*count, total_bytes, hsize_t, size_t); *extra_offset = 0; *is_derived_type = 0; done: FUNC_LEAVE_NOAPI(ret_value); } /* H5S_mpio_all_type() */
/*------------------------------------------------------------------------- * Function: H5D_compact_fill * * Purpose: Write fill values to a compactly stored dataset. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * May 6, 2007 * *------------------------------------------------------------------------- */ herr_t H5D_compact_fill(H5D_t *dset, hid_t dxpl_id) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5D_compact_fill, FAIL) /* Check args */ HDassert(TRUE == H5P_isa_class(dxpl_id, H5P_DATASET_XFER)); HDassert(dset && H5D_COMPACT == dset->shared->layout.type); HDassert(dset->shared->layout.u.compact.buf); HDassert(dset->shared->type); HDassert(dset->shared->space); /* If the fill value is defined, initialize the data buffer with it */ if(dset->shared->fill.buf) { hssize_t snpoints; /* Number of points in space (for error checking) */ size_t npoints; /* Number of points in space */ /* Get the number of elements in the dataset's dataspace */ snpoints = H5S_GET_EXTENT_NPOINTS(dset->shared->space); HDassert(snpoints >= 0); H5_ASSIGN_OVERFLOW(npoints, snpoints, hssize_t, size_t); /* If necessary, convert fill value datatypes (which copies VL components, etc.) */ if(H5T_detect_class(dset->shared->type, H5T_VLEN) > 0) { H5T_path_t *tpath; /* Datatype conversion path */ uint8_t *bkg_buf = NULL; /* Background conversion buffer */ H5T_t *mem_type; /* Pointer to memory datatype */ size_t mem_type_size, file_type_size; /* Size of datatype in memory and on disk */ hid_t mem_tid; /* Memory version of disk datatype */ /* Create temporary datatype for conversion operation */ if(NULL == (mem_type = H5T_copy(dset->shared->type, H5T_COPY_REOPEN))) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy file datatype") if((mem_tid = H5I_register(H5I_DATATYPE, mem_type)) < 0) { H5T_close(mem_type); HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype") } /* end if */
/*------------------------------------------------------------------------- * Function: H5Tget_ebias * * Purpose: Retrieves the exponent bias of a floating-point type. * * Return: Success: The bias * * Failure: 0 * * Programmer: Robb Matzke * Wednesday, January 7, 1998 * * Modifications: * Robb Matzke, 22 Dec 1998 * Also works with derived datatypes. *------------------------------------------------------------------------- */ size_t H5Tget_ebias(hid_t type_id) { H5T_t *dt = NULL; size_t ret_value; FUNC_ENTER_API(H5Tget_ebias, 0) H5TRACE1("z","i",type_id); /* Check args */ if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype") while (dt->shared->parent) dt = dt->shared->parent; /*defer to parent*/ if (H5T_FLOAT != dt->shared->type) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, 0, "operation not defined for datatype class") /* bias */ H5_ASSIGN_OVERFLOW(ret_value,dt->shared->u.atomic.u.f.ebias,uint64_t,size_t); done: FUNC_LEAVE_API(ret_value) }
/*------------------------------------------------------------------------- * Function: H5F_accum_read * * Purpose: Attempts to read some data from the metadata accumulator for * a file into a buffer. * * Note: We can't change (or add to) the metadata accumulator, because * this might be a speculative read and could possibly read raw * data into the metadata accumulator. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * [email protected] * Jan 10 2008 * *------------------------------------------------------------------------- */ herr_t H5F_accum_read(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, size_t size, void *buf/*out*/) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) HDassert(f); HDassert(f->shared); HDassert(buf); /* Check if this information is in the metadata accumulator */ if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && type != H5FD_MEM_DRAW) { if(size < H5F_ACCUM_MAX_SIZE) { /* Sanity check */ HDassert(!f->shared->accum.buf || (f->shared->accum.alloc_size >= f->shared->accum.size)); /* Current read adjoins or overlaps with metadata accumulator */ if(H5F_addr_overlap(addr, size, f->shared->accum.loc, f->shared->accum.size) || ((addr + size) == f->shared->accum.loc) || (f->shared->accum.loc + f->shared->accum.size) == addr) { size_t amount_before; /* Amount to read before current accumulator */ haddr_t new_addr; /* New address of the accumulator buffer */ size_t new_size; /* New size of the accumulator buffer */ /* Compute new values for accumulator */ new_addr = MIN(addr, f->shared->accum.loc); new_size = (size_t)(MAX((addr + size), (f->shared->accum.loc + f->shared->accum.size)) - new_addr); /* Check if we need more buffer space */ if(new_size > f->shared->accum.alloc_size) { size_t new_alloc_size; /* New size of accumulator */ /* Adjust the buffer size to be a power of 2 that is large enough to hold data */ new_alloc_size = (size_t)1 << (1 + H5V_log2_gen((uint64_t)(new_size - 1))); /* Reallocate the metadata accumulator buffer */ if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, new_alloc_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") /* Note the new buffer size */ f->shared->accum.alloc_size = new_alloc_size; #ifdef H5_CLEAR_MEMORY HDmemset(f->shared->accum.buf + f->shared->accum.size, 0, (f->shared->accum.alloc_size - f->shared->accum.size)); #endif /* H5_CLEAR_MEMORY */ } /* end if */ /* Read the part before the metadata accumulator */ if(addr < f->shared->accum.loc) { /* Set the amount to read */ H5_ASSIGN_OVERFLOW(amount_before, (f->shared->accum.loc - addr), hsize_t, size_t); /* Make room for the metadata to read in */ HDmemmove(f->shared->accum.buf + amount_before, f->shared->accum.buf, f->shared->accum.size); /* Adjust dirty region tracking info, if present */ if(f->shared->accum.dirty) f->shared->accum.dirty_off += amount_before; /* Dispatch to driver */ if(H5FD_read(f->shared->lf, dxpl_id, type, addr, amount_before, f->shared->accum.buf) < 0) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") } /* end if */ else
/*------------------------------------------------------------------------- * Function: H5Z_filter_deflate * * Purpose: Implement an I/O filter around the 'deflate' algorithm in * libz * * Return: Success: Size of buffer filtered * Failure: 0 * * Programmer: Robb Matzke * Thursday, April 16, 1998 * * Modifications: * *------------------------------------------------------------------------- */ 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) { void *outbuf = NULL; /* Pointer to new buffer */ int status; /* Status from zlib operation */ size_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5Z_filter_deflate, 0) /* Check arguments */ if (cd_nelmts!=1 || cd_values[0]>9) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid deflate aggression level") if (flags & H5Z_FLAG_REVERSE) { /* Input; uncompress */ z_stream z_strm; /* zlib parameters */ size_t nalloc = *buf_size; /* Number of bytes for output (compressed) buffer */ /* Allocate space for the compressed buffer */ if (NULL==(outbuf = H5MM_malloc(nalloc))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed for deflate uncompression") /* Set the uncompression parameters */ HDmemset(&z_strm, 0, sizeof(z_strm)); z_strm.next_in = *buf; H5_ASSIGN_OVERFLOW(z_strm.avail_in,nbytes,size_t,uInt); z_strm.next_out = outbuf; H5_ASSIGN_OVERFLOW(z_strm.avail_out,nalloc,size_t,uInt); /* Initialize the uncompression routines */ if (Z_OK!=inflateInit(&z_strm)) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, 0, "inflateInit() failed") /* Loop to uncompress the buffer */ do { /* Uncompress some data */ status = inflate(&z_strm, Z_SYNC_FLUSH); /* Check if we are done uncompressing data */ if (Z_STREAM_END==status) break; /*done*/ /* Check for error */ if (Z_OK!=status) { (void)inflateEnd(&z_strm); HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, 0, "inflate() failed") } else { /* If we're not done and just ran out of buffer space, get more */ if (0==z_strm.avail_out) { /* Allocate a buffer twice as big */ nalloc *= 2; if (NULL==(outbuf = H5MM_realloc(outbuf, nalloc))) { (void)inflateEnd(&z_strm); HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed for deflate uncompression") } /* Update pointers to buffer for next set of uncompressed data */ z_strm.next_out = (unsigned char*)outbuf + z_strm.total_out; z_strm.avail_out = (uInt)(nalloc - z_strm.total_out); }
/*------------------------------------------------------------------------- * Function: H5HF_man_dblock_create * * Purpose: Allocate & initialize a managed direct block * * Return: Pointer to new direct block on success, NULL on failure * * Programmer: Quincey Koziol * [email protected] * Feb 27 2006 * *------------------------------------------------------------------------- */ herr_t H5HF_man_dblock_create(hid_t dxpl_id, H5HF_hdr_t *hdr, H5HF_indirect_t *par_iblock, unsigned par_entry, haddr_t *addr_p, H5HF_free_section_t **ret_sec_node) { H5HF_free_section_t *sec_node; /* Pointer to free space section for block */ H5HF_direct_t *dblock = NULL; /* Pointer to direct block */ haddr_t dblock_addr; /* Direct block's address */ size_t free_space; /* Free space in new block */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* * Check arguments. */ HDassert(hdr); /* * Allocate file and memory data structures. */ if(NULL == (dblock = H5FL_MALLOC(H5HF_direct_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fractal heap direct block") /* Reset the metadata cache info for the heap header */ HDmemset(&dblock->cache_info, 0, sizeof(H5AC_info_t)); /* Share common heap information */ dblock->hdr = hdr; if(H5HF_hdr_incr(hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared heap header") /* Set info for direct block */ if(par_iblock) { unsigned par_row = par_entry / hdr->man_dtable.cparam.width; /* Row for block */ /* Compute offset & size, based on parent's information */ dblock->block_off = par_iblock->block_off; dblock->block_off += hdr->man_dtable.row_block_off[par_row]; dblock->block_off += hdr->man_dtable.row_block_size[par_row] * (par_entry % hdr->man_dtable.cparam.width); H5_ASSIGN_OVERFLOW(/* To: */ dblock->size, /* From: */ hdr->man_dtable.row_block_size[par_row], /* From: */ hsize_t, /* To: */ size_t); } /* end if */ else { /* Must be the root direct block */ dblock->block_off = 0; dblock->size = hdr->man_dtable.cparam.start_block_size; } /* end else */ dblock->file_size = 0; dblock->blk_off_size = H5HF_SIZEOF_OFFSET_LEN(dblock->size); free_space = dblock->size - H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr); /* Allocate buffer for block */ /* XXX: Change to using free-list factories */ if((dblock->blk = H5FL_BLK_MALLOC(direct_block, dblock->size)) == NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") #ifdef H5_CLEAR_MEMORY HDmemset(dblock->blk, 0, dblock->size); #endif /* H5_CLEAR_MEMORY */ /* Allocate [temporary] space for the direct block on disk */ if(H5F_USE_TMP_SPACE(hdr->f)) { if(HADDR_UNDEF == (dblock_addr = H5MF_alloc_tmp(hdr->f, (hsize_t)dblock->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block") } /* end if */ else { if(HADDR_UNDEF == (dblock_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)dblock->size)))
/*-------------------------------------------------------------------------- NAME H5O_attr_decode PURPOSE Decode a attribute message and return a pointer to a memory struct with the decoded information USAGE void *H5O_attr_decode(f, raw_size, p) H5F_t *f; IN: pointer to the HDF5 file struct size_t raw_size; IN: size of the raw information buffer const uint8_t *p; IN: the raw information buffer RETURNS Pointer to the new message in native order on success, NULL on failure DESCRIPTION This function decodes the "raw" disk form of a attribute message into a struct in memory native format. The struct is allocated within this function using malloc() and is returned to the caller. --------------------------------------------------------------------------*/ static void * H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p) { H5A_t *attr = NULL; H5S_extent_t *extent; /*extent dimensionality information */ size_t name_len; /*attribute name length */ int version; /*message version number*/ unsigned flags = 0; /* Attribute flags */ H5A_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_decode); /* check args */ HDassert(f); HDassert(p); if(NULL == (attr = H5FL_CALLOC(H5A_t))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); /* Version number */ version = *p++; if (version!=H5O_ATTR_VERSION && version!=H5O_ATTR_VERSION_NEW) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for attribute message"); /* Get the flags byte if we have a later version of the attribute */ if(version>H5O_ATTR_VERSION) flags = *p++; else p++; /* Byte is unused when version<2 */ /* * Decode the sizes of the parts of the attribute. The sizes stored in * the file are exact but the parts are aligned on 8-byte boundaries. */ UINT16DECODE(p, name_len); /*including null*/ UINT16DECODE(p, attr->dt_size); UINT16DECODE(p, attr->ds_size); /* Decode and store the name */ if (NULL==(attr->name=H5MM_strdup((const char *)p))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); if(version < H5O_ATTR_VERSION_NEW) p += H5O_ALIGN(name_len); /* advance the memory pointer */ else p += name_len; /* advance the memory pointer */ /* decode the attribute datatype */ if (flags & H5O_ATTR_FLAG_TYPE_SHARED) { H5O_shared_t *shared; /* Shared information */ /* Get the shared information */ if (NULL == (shared = (H5O_MSG_SHARED->decode) (f, dxpl_id, p))) HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode shared message"); /* Get the actual datatype information */ if((attr->dt= H5O_shared_read(f, dxpl_id, shared, H5O_MSG_DTYPE, NULL))==NULL) HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype"); /* Free the shared information */ H5O_free_real(H5O_MSG_SHARED, shared); } /* end if */ else { if((attr->dt=(H5O_MSG_DTYPE->decode)(f,dxpl_id,p))==NULL) HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype"); } /* end else */ if(version < H5O_ATTR_VERSION_NEW) p += H5O_ALIGN(attr->dt_size); else p += attr->dt_size; /* decode the attribute dataspace */ if (NULL==(attr->ds = H5FL_CALLOC(H5S_t))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); if((extent=(H5O_MSG_SDSPACE->decode)(f,dxpl_id,p))==NULL) HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute dataspace"); /* Copy the extent information */ HDmemcpy(&(attr->ds->extent),extent, sizeof(H5S_extent_t)); /* Release temporary extent information */ H5FL_FREE(H5S_extent_t,extent); /* Default to entire dataspace being selected */ if(H5S_select_all(attr->ds, 0) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection") if(version < H5O_ATTR_VERSION_NEW) p += H5O_ALIGN(attr->ds_size); else p += attr->ds_size; /* Compute the size of the data */ H5_ASSIGN_OVERFLOW(attr->data_size,H5S_GET_EXTENT_NPOINTS(attr->ds)*H5T_get_size(attr->dt),hsize_t,size_t); /* Go get the data */ if(attr->data_size) { if (NULL==(attr->data = H5FL_BLK_MALLOC(attr_buf, attr->data_size))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); HDmemcpy(attr->data,p,attr->data_size); } /* Indicate that the fill values aren't to be written out */ attr->initialized=1; /* Set return value */ ret_value = attr; done: if(!ret_value) if(attr) { /* Free dynamicly allocated items */ if(H5A_free(attr) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't release attribute info") H5FL_FREE(H5A_t, attr); } /* end if */ FUNC_LEAVE_NOAPI(ret_value); }
/*------------------------------------------------------------------------- * Function: H5O_load * * Purpose: Loads an object header from disk. * * Return: Success: Pointer to the new object header. * * Failure: NULL * * Programmer: Robb Matzke * [email protected] * Aug 5 1997 * *------------------------------------------------------------------------- */ static H5O_t * H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, void UNUSED * _udata2) { H5O_t *oh = NULL; /* Object header read in */ uint8_t read_buf[H5O_SPEC_READ_SIZE]; /* Buffer for speculative read */ const uint8_t *p; /* Pointer into buffer to decode */ size_t spec_read_size; /* Size of buffer to speculatively read in */ size_t prefix_size; /* Size of object header prefix */ unsigned nmesgs; /* Total # of messages in this object header */ unsigned curmesg = 0; /* Current message being decoded in object header */ unsigned merged_null_msgs = 0; /* Number of null messages merged together */ haddr_t chunk_addr; /* Address of first chunk */ size_t chunk_size; /* Size of first chunk */ haddr_t eoa; /* Relative end of file address */ H5O_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_load, NULL) /* check args */ HDassert(f); HDassert(H5F_addr_defined(addr)); HDassert(!_udata1); HDassert(!_udata2); /* Make certain we don't speculatively read off the end of the file */ if(HADDR_UNDEF == (eoa = H5F_get_eoa(f, H5FD_MEM_OHDR))) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "unable to determine file size") /* Compute the size of the speculative object header buffer */ H5_ASSIGN_OVERFLOW(spec_read_size, MIN(eoa - addr, H5O_SPEC_READ_SIZE), /* From: */ hsize_t, /* To: */ size_t); /* Attempt to speculatively read both object header prefix and first chunk */ if(H5F_block_read(f, H5FD_MEM_OHDR, addr, spec_read_size, dxpl_id, read_buf) < 0) HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header") p = read_buf; /* allocate ohdr and init chunk list */ if(NULL == (oh = H5FL_CALLOC(H5O_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* File-specific, non-stored information */ oh->sizeof_size = H5F_SIZEOF_SIZE(f); oh->sizeof_addr = H5F_SIZEOF_ADDR(f); /* Check for magic number */ /* (indicates version 2 or later) */ if(!HDmemcmp(p, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* Magic number */ p += H5_SIZEOF_MAGIC; /* Version */ oh->version = *p++; if(H5O_VERSION_2 != oh->version) HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header version number") /* Flags */ oh->flags = *p++; if(oh->flags & ~H5O_HDR_ALL_FLAGS) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "unknown object header status flag(s)") /* Number of messages (to allocate initially) */ nmesgs = 1; /* Number of links to object (unless overridden by refcount message) */ oh->nlink = 1; /* Time fields */ if(oh->flags & H5O_HDR_STORE_TIMES) { uint32_t tmp; /* Temporary value */ UINT32DECODE(p, tmp); oh->atime = (time_t)tmp; UINT32DECODE(p, tmp); oh->mtime = (time_t)tmp; UINT32DECODE(p, tmp); oh->ctime = (time_t)tmp; UINT32DECODE(p, tmp); oh->btime = (time_t)tmp; } /* end if */ else oh->atime = oh->mtime = oh->ctime = oh->btime = 0; /* Attribute fields */ if(oh->flags & H5O_HDR_ATTR_STORE_PHASE_CHANGE) { UINT16DECODE(p, oh->max_compact); UINT16DECODE(p, oh->min_dense); if(oh->max_compact < oh->min_dense) HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header attribute phase change values") } /* end if */
/*------------------------------------------------------------------------- * Function: H5HF_man_dblock_create * * Purpose: Allocate & initialize a managed direct block * * Return: Pointer to new direct block on success, NULL on failure * * Programmer: Quincey Koziol * [email protected] * Feb 27 2006 * *------------------------------------------------------------------------- */ herr_t H5HF_man_dblock_create(hid_t dxpl_id, H5HF_hdr_t *hdr, H5HF_indirect_t *par_iblock, unsigned par_entry, haddr_t *addr_p, H5HF_free_section_t **ret_sec_node) { H5HF_free_section_t *sec_node; /* Pointer to free space section for block */ H5HF_direct_t *dblock = NULL; /* Pointer to direct block */ haddr_t dblock_addr; /* Direct block's address */ size_t free_space; /* Free space in new block */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_dblock_create) /* * Check arguments. */ HDassert(hdr); /* * Allocate file and memory data structures. */ if(NULL == (dblock = H5FL_MALLOC(H5HF_direct_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fractal heap direct block") /* Reset the metadata cache info for the heap header */ HDmemset(&dblock->cache_info, 0, sizeof(H5AC_info_t)); /* Share common heap information */ dblock->hdr = hdr; if(H5HF_hdr_incr(hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared heap header") /* Set info for direct block */ if(par_iblock) { unsigned par_row = par_entry / hdr->man_dtable.cparam.width; /* Row for block */ /* Compute offset & size, based on parent's information */ dblock->block_off = par_iblock->block_off; dblock->block_off += hdr->man_dtable.row_block_off[par_row]; dblock->block_off += hdr->man_dtable.row_block_size[par_row] * (par_entry % hdr->man_dtable.cparam.width); H5_ASSIGN_OVERFLOW(/* To: */ dblock->size, /* From: */ hdr->man_dtable.row_block_size[par_row], /* From: */ hsize_t, /* To: */ size_t); } /* end if */ else { /* Must be the root direct block */ dblock->block_off = 0; dblock->size = hdr->man_dtable.cparam.start_block_size; } /* end else */ dblock->blk_off_size = H5HF_SIZEOF_OFFSET_LEN(dblock->size); free_space = dblock->size - H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr); /* Allocate buffer for block */ /* XXX: Change to using free-list factories */ if((dblock->blk = H5FL_BLK_MALLOC(direct_block, dblock->size)) == NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") #ifdef H5_CLEAR_MEMORY HDmemset(dblock->blk, 0, dblock->size); #endif /* H5_CLEAR_MEMORY */ /* Allocate space for the direct block on disk */ if(HADDR_UNDEF == (dblock_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)dblock->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block") #ifdef QAK HDfprintf(stderr, "%s: direct block address = %a\n", FUNC, dblock_addr); #endif /* QAK */ /* Attach to parent indirect block, if there is one */ dblock->parent = par_iblock; if(dblock->parent) if(H5HF_man_iblock_attach(dblock->parent, par_entry, dblock_addr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTATTACH, FAIL, "can't attach direct block to parent indirect block") dblock->par_entry = par_entry; /* Create a new 'single' section for the free space in the block */ if(NULL == (sec_node = H5HF_sect_single_new((dblock->block_off + H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr)), free_space, dblock->parent, dblock->par_entry))) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't create section for new direct block's free space") /* Check what to do with section node */ if(ret_sec_node) /* Pass back the pointer to the section instead of adding it to the free list */ *ret_sec_node = sec_node; else { /* Add new free space to the heap's list of space */ if(H5HF_space_add(hdr, dxpl_id, sec_node, 0) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add direct block free space to global list") } /* end else */ /* Cache the new fractal heap direct block */ if(H5AC_set(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add fractal heap direct block to cache") /* Increase the allocated heap size */ if(H5HF_hdr_inc_alloc(hdr, dblock->size) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't increase allocated heap size") /* Set the address of of direct block, if requested */ if(addr_p) *addr_p = dblock_addr; done: if(ret_value < 0) if(dblock) (void)H5HF_cache_dblock_dest(hdr->f, dblock); FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_man_dblock_create() */
/*------------------------------------------------------------------------- * Function: H5F__accum_read * * Purpose: Attempts to read some data from the metadata accumulator for * a file into a buffer. * * Note: We can't change (or add to) the metadata accumulator, because * this might be a speculative read and could possibly read raw * data into the metadata accumulator. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * [email protected] * Jan 10 2008 * *------------------------------------------------------------------------- */ herr_t H5F__accum_read(const H5F_io_info_t *fio_info, H5FD_mem_t type, haddr_t addr, size_t size, void *buf/*out*/) { H5FD_mem_t map_type; /* Mapped memory type */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE HDassert(fio_info); HDassert(fio_info->f); HDassert(fio_info->dxpl); HDassert(buf); /* Treat global heap as raw data */ map_type = (type == H5FD_MEM_GHEAP) ? H5FD_MEM_DRAW : type; /* Check if this information is in the metadata accumulator */ if((fio_info->f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && map_type != H5FD_MEM_DRAW) { H5F_meta_accum_t *accum; /* Alias for file's metadata accumulator */ /* Set up alias for file's metadata accumulator info */ accum = &fio_info->f->shared->accum; if(size < H5F_ACCUM_MAX_SIZE) { /* Sanity check */ HDassert(!accum->buf || (accum->alloc_size >= accum->size)); /* Current read adjoins or overlaps with metadata accumulator */ if(H5F_addr_overlap(addr, size, accum->loc, accum->size) || ((addr + size) == accum->loc) || (accum->loc + accum->size) == addr) { size_t amount_before; /* Amount to read before current accumulator */ haddr_t new_addr; /* New address of the accumulator buffer */ size_t new_size; /* New size of the accumulator buffer */ /* Compute new values for accumulator */ new_addr = MIN(addr, accum->loc); new_size = (size_t)(MAX((addr + size), (accum->loc + accum->size)) - new_addr); /* Check if we need more buffer space */ if(new_size > accum->alloc_size) { size_t new_alloc_size; /* New size of accumulator */ /* Adjust the buffer size to be a power of 2 that is large enough to hold data */ new_alloc_size = (size_t)1 << (1 + H5VM_log2_gen((uint64_t)(new_size - 1))); /* Reallocate the metadata accumulator buffer */ if(NULL == (accum->buf = H5FL_BLK_REALLOC(meta_accum, accum->buf, new_alloc_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") /* Note the new buffer size */ accum->alloc_size = new_alloc_size; #ifdef H5_CLEAR_MEMORY HDmemset(accum->buf + accum->size, 0, (accum->alloc_size - accum->size)); #endif /* H5_CLEAR_MEMORY */ } /* end if */ /* Read the part before the metadata accumulator */ if(addr < accum->loc) { /* Set the amount to read */ H5_ASSIGN_OVERFLOW(amount_before, (accum->loc - addr), hsize_t, size_t); /* Make room for the metadata to read in */ HDmemmove(accum->buf + amount_before, accum->buf, accum->size); /* Adjust dirty region tracking info, if present */ if(accum->dirty) accum->dirty_off += amount_before; /* Dispatch to driver */ if(H5FD_read(fio_info->f->shared->lf, fio_info->dxpl, map_type, addr, amount_before, accum->buf) < 0) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") } /* end if */