예제 #1
0
파일: H5Odrvinfo.c 프로젝트: GATB/gatb-core
/*-------------------------------------------------------------------------
 * Function:	H5O_drvinfo_copy
 *
 * Purpose:	Copies a message from _MESG to _DEST, allocating _DEST if
 *		necessary.
 *
 * Return:	Success:	Ptr to _DEST
 *		Failure:	NULL
 *
 * Programmer:  Quincey Koziol
 *              Mar  1, 2007
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_drvinfo_copy(const void *_mesg, void *_dest)
{
    const H5O_drvinfo_t	*mesg = (const H5O_drvinfo_t *)_mesg;
    H5O_drvinfo_t	*dest = (H5O_drvinfo_t *)_dest;
    void		*ret_value = NULL;      /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

    /* Sanity check */
    HDassert(mesg);

    if(!dest && NULL == (dest = (H5O_drvinfo_t *)H5MM_malloc(sizeof(H5O_drvinfo_t))))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for shared message table message")

    /* Shallow copy the fields */
    *dest = *mesg;

    /* Copy the buffer */
    if(NULL == (dest->buf = (uint8_t *)H5MM_malloc(mesg->len))) {
        if(dest != _dest)
            dest = (H5O_drvinfo_t *)H5MM_xfree(dest);
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
    } /* end if */
    HDmemcpy(dest->buf, mesg->buf, mesg->len);

    /* Set return value */
    ret_value = dest;

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_drvinfo_copy() */
예제 #2
0
/*--------------------------------------------------------------------------
 * Function: H5L_build_name
 *
 * Purpose:  Prepend PREFIX to FILE_NAME and store in FULL_NAME
 *
 * Return:   Non-negative on success/Negative on failure
 *
 * Programmer:	Vailin Choi, April 2, 2008
 *
 * Modification: Raymond Lu, 14 Jan. 2009
 *           Added support for OpenVMS pathname
--------------------------------------------------------------------------*/
static herr_t
H5L_build_name(char *prefix, char *file_name, char **full_name/*out*/)
{
    size_t      prefix_len;             /* length of prefix */
    size_t      fname_len;              /* Length of external link file name */
    herr_t      ret_value = SUCCEED;    /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5L_build_name)

    prefix_len = HDstrlen(prefix);
    fname_len = HDstrlen(file_name);

    /* Allocate a buffer to hold the filename + prefix + possibly the delimiter + terminating null byte */
    if(NULL == (*full_name = (char *)H5MM_malloc(prefix_len + fname_len + 2)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate filename buffer")

    /* Copy the prefix into the buffer */
    HDstrcpy(*full_name, prefix);

    if (!CHECK_DELIMITER(prefix[prefix_len-1]))
        HDstrcat(*full_name, DIR_SEPS);

    /* Add the external link's filename to the prefix supplied */
    HDstrcat(*full_name, file_name);

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* H5L_build_name() */
예제 #3
0
/*-------------------------------------------------------------------------
 * Function:    H5O_fill_decode
 *
 * Purpose:     Decode a fill value message.
 *
 * Return:      Success:        Ptr to new message in native struct.
 *
 *              Failure:        NULL
 *
 * Programmer:  Robb Matzke
 *              Wednesday, September 30, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_fill_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p)
{
    H5O_fill_t  *mesg=NULL;
    void        *ret_value;

    FUNC_ENTER_NOAPI_NOINIT(H5O_fill_decode);

    assert(f);
    assert(p);

    if (NULL==(mesg=H5FL_CALLOC(H5O_fill_t)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value message");
    UINT32DECODE(p, mesg->size);
    if (mesg->size>0) {
        if (NULL==(mesg->buf=H5MM_malloc(mesg->size)))
            HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value");
        HDmemcpy(mesg->buf, p, mesg->size);
    }

    /* Set return value */
    ret_value = (void*)mesg;

done:
    if (!ret_value && mesg) {
        if(mesg->buf)
            H5MM_xfree(mesg->buf);
	H5FL_FREE(H5O_fill_t,mesg);
    }

    FUNC_LEAVE_NOAPI(ret_value);
}
예제 #4
0
/*-------------------------------------------------------------------------
 * Function:    H5O_name_decode
 *
 * Purpose:     Decode a name message and return a pointer to a new
 *              native message struct.
 *
 * Return:      Success:        Ptr to new message in native struct.
 *
 *              Failure:        NULL
 *
 * Programmer:  Robb Matzke
 *              [email protected]
 *              Aug 12 1997
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_name_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
    unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
    H5O_name_t          *mesg;
    void                *ret_value;     /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

    /* check args */
    HDassert(f);
    HDassert(p);

    /* decode */
    if(NULL == (mesg = (H5O_name_t *)H5MM_calloc(sizeof(H5O_name_t))) ||
            NULL == (mesg->s = (char *)H5MM_malloc(HDstrlen((const char *)p) + 1)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
    HDstrcpy(mesg->s, (const char *)p);

    /* Set return value */
    ret_value = mesg;

done:
    if(NULL == ret_value) {
        if(mesg)
            mesg = (H5O_name_t *)H5MM_xfree(mesg);
    } /* end if */

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_name_decode() */
예제 #5
0
파일: H5MM.c 프로젝트: MattNapsAlot/rHDF5
/*-------------------------------------------------------------------------
 * Function:	H5MM_realloc
 *
 * Purpose:	Just like the POSIX version of realloc(3). Specifically, the
 *		following calls are equivalent
 *
 *		H5MM_realloc (NULL, size) <==> H5MM_malloc (size)
 *		H5MM_realloc (ptr, 0)	  <==> H5MM_xfree (ptr)
 *		H5MM_realloc (NULL, 0)	  <==> NULL
 *
 * Return:	Success:	Ptr to new memory or NULL if the memory
 *				was freed.
 *
 *		Failure:	abort()
 *
 * Programmer:	Robb Matzke
 *		[email protected]
 *		Jul 10 1997
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
void *
H5MM_realloc(void *mem, size_t size)
{
    void *ret_value;

    /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MM_realloc);

    if (!mem) {
	if (0 == size)
            HGOTO_DONE(NULL);
	mem = H5MM_malloc(size);

    } else if (0 == size) {
	mem = H5MM_xfree(mem);

    } else {
	mem = HDrealloc(mem, size);
	assert(mem);
    }

    /* Set return value */
    ret_value=mem;

done:
    FUNC_LEAVE_NOAPI(ret_value);
}
예제 #6
0
파일: H5MP.c 프로젝트: ekjstm/permafrost
/*-------------------------------------------------------------------------
 * Function:	H5MP_new_page
 *
 * Purpose:	Allocate new page for a memory pool
 *
 * Return:	Pointer to the page allocated on success/NULL on failure
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		May  4 2005
 *
 *-------------------------------------------------------------------------
 */
static H5MP_page_t *
H5MP_new_page(H5MP_pool_t *mp, size_t page_size)
{
    H5MP_page_t *new_page;              /* New page created */
    H5MP_page_blk_t *first_blk;         /* Pointer to first block in page */
    H5MP_page_t *ret_value;             /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5MP_new_page)

    /* Sanity check */
    HDassert(mp);
    HDassert(page_size >= mp->page_size);

    /* Allocate page */
    if(page_size > mp->page_size) {
        if(NULL == (new_page = H5MM_malloc(page_size)))
            HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for page")
        new_page->free_size = page_size - H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t));
        new_page->fac_alloc = FALSE;
    } /* end if */
    else {
        if((new_page = H5FL_FAC_MALLOC(mp->page_fac)) == NULL)
            HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for page")
        new_page->free_size = mp->max_size;
        new_page->fac_alloc = TRUE;
    } /* end else */
#ifdef QAK
HDfprintf(stderr,"%s: Allocating new page = %p\n", FUNC, new_page);
#endif /* QAK */

    /* Initialize page information */
    first_blk = H5MP_PAGE_FIRST_BLOCK(new_page);
    first_blk->size = new_page->free_size;
    first_blk->page = new_page;
    first_blk->is_free = TRUE;
    first_blk->prev = NULL;
    first_blk->next = NULL;

    /* Insert into page list */
    new_page->prev = NULL;
    new_page->next = mp->first;
    if(mp->first)
        mp->first->prev = new_page;
    mp->first = new_page;

    /* Account for new free space */
    new_page->free_blk = first_blk;
    mp->free_size += new_page->free_size;

    /* Assign return value */
    ret_value = new_page;

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MP_new_page() */
예제 #7
0
/*-------------------------------------------------------------------------
 * Function:	H5O_fill_new_decode
 *
 * Purpose:	Decode a new fill value message.  The new fill value
 * 		message is fill value plus space allocation time and
 * 		fill value writing time and whether fill value is defined.
 *
 * Return:	Success:	Ptr to new message in native struct.
 *
 *		Failure:	NULL
 *
 * Programmer:  Raymond Lu
 *              Feb 26, 2002
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_fill_new_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p)
{
    H5O_fill_new_t	*mesg=NULL;
    int			version;
    void		*ret_value;

    FUNC_ENTER_NOAPI_NOINIT(H5O_fill_new_decode);

    assert(f);
    assert(p);

    if (NULL==(mesg=H5FL_CALLOC(H5O_fill_new_t)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value message");

    /* Version */
    version = *p++;
    if( version != H5O_FILL_VERSION && version !=H5O_FILL_VERSION_2)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for fill value message");

    /* Space allocation time */
    mesg->alloc_time = (H5D_alloc_time_t)*p++;

    /* Fill value write time */
    mesg->fill_time = (H5D_fill_time_t)*p++;

    /* Whether fill value is defined */
    mesg->fill_defined = *p++;

    /* Only decode fill value information if one is defined */
    if(mesg->fill_defined) {
        INT32DECODE(p, mesg->size);
        if (mesg->size>0) {
            H5_CHECK_OVERFLOW(mesg->size,ssize_t,size_t);
            if (NULL==(mesg->buf=H5MM_malloc((size_t)mesg->size)))
                HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value");
            HDmemcpy(mesg->buf, p, (size_t)mesg->size);
        }
    } /* end if */
    else
        mesg->size=(-1);

    /* Set return value */
    ret_value = (void*)mesg;

done:
    if (!ret_value && mesg) {
        if(mesg->buf)
            H5MM_xfree(mesg->buf);
	H5FL_FREE(H5O_fill_new_t,mesg);
    }

    FUNC_LEAVE_NOAPI(ret_value);
}
예제 #8
0
/*-------------------------------------------------------------------------
 * Function:	H5O_fill_copy_dyn
 *
 * Purpose:	Copy dynamic fill value fields
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Quincey Koziol
 *              Thursday, May 31, 2007
 *
 *-------------------------------------------------------------------------
 */
static herr_t
H5O_fill_copy_dyn(H5O_fill_t *dest, const H5O_fill_t *mesg)
{
    herr_t ret_value = SUCCEED;         /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5O_fill_copy_dyn)

    HDassert(dest);
    HDassert(mesg);

    /* Copy data type of fill value */
    if(mesg->type) {
        if(NULL == (dest->type = H5T_copy(mesg->type, H5T_COPY_TRANSIENT)))
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy fill value data type");
    } /* end if */
    else
        dest->type = NULL;

    /* Copy fill value and its size */
    if(mesg->buf) {
        H5_CHECK_OVERFLOW(mesg->size,ssize_t,size_t);
	if(NULL == (dest->buf = H5MM_malloc((size_t)mesg->size)))
	    HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fill value");
	HDmemcpy(dest->buf, mesg->buf, (size_t)mesg->size);

        /* Check for needing to convert/copy fill value */
        if(mesg->type) {
            H5T_path_t *tpath;      /* Conversion information */

            /* Set up type conversion function */
            if(NULL == (tpath = H5T_path_find(mesg->type, dest->type, NULL, NULL, H5AC_ind_dxpl_id)))
                HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types")

            /* If necessary, convert fill value datatypes (which copies VL components, etc.) */
            if(!H5T_path_noop(tpath)) {
                hid_t dst_id, src_id;       /* Source & destination datatypes for type conversion */
                uint8_t *bkg_buf = NULL;    /* Background conversion buffer */
                size_t bkg_size;            /* Size of background buffer */

                /* Wrap copies of types to convert */
                dst_id = H5I_register(H5I_DATATYPE, H5T_copy(dest->type, H5T_COPY_TRANSIENT));
                if(dst_id < 0)
                    HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register datatype")
                src_id = H5I_register(H5I_DATATYPE, H5T_copy(mesg->type, H5T_COPY_ALL));
                if(src_id < 0) {
                    H5I_dec_ref(dst_id);
                    HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register datatype")
                } /* end if */
예제 #9
0
/*-------------------------------------------------------------------------
 * Function:	H5MM_strdup
 *
 * Purpose:	Duplicates a string.  If the string to be duplicated is the
 *		null pointer, then return null.	 If the string to be duplicated
 *		is the empty string then return a new empty string.
 *
 * Return:	Success:	Ptr to a new string (or null if no string).
 *
 *		Failure:	abort()
 *
 * Programmer:	Robb Matzke
 *		[email protected]
 *		Jul 10 1997
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
char *
H5MM_strdup(const char *s)
{
    char	*ret_value;

    FUNC_ENTER_NOAPI(H5MM_strdup, NULL)

    if(!s)
	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "null string")
    if(NULL == (ret_value = (char *)H5MM_malloc(HDstrlen(s) + 1)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
    HDstrcpy(ret_value, s);

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MM_strdup() */
예제 #10
0
/*-------------------------------------------------------------------------
 * Function:	H5MM_xstrdup
 *
 * Purpose:	Duplicates a string.  If the string to be duplicated is the
 *		null pointer, then return null.	 If the string to be duplicated
 *		is the empty string then return a new empty string.
 *
 * Return:	Success:	Ptr to a new string (or null if no string).
 *
 *		Failure:	abort()
 *
 * Programmer:	Robb Matzke
 *		[email protected]
 *		Jul 10 1997
 *
 *-------------------------------------------------------------------------
 */
char *
H5MM_xstrdup(const char *s)
{
    char	*ret_value = NULL;

    /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MM_xstrdup)

    if(s) {
        ret_value = (char *)H5MM_malloc(HDstrlen(s) + 1);
        HDassert(ret_value);
        HDstrcpy(ret_value, s);
    } /* end if */

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MM_xstrdup() */
예제 #11
0
파일: H5Oefl.c 프로젝트: chaako/sceptic3D
/*-------------------------------------------------------------------------
 * Function:	H5O_efl_copy
 *
 * Purpose:	Copies a message from _MESG to _DEST, allocating _DEST if
 *		necessary.
 *
 * Return:	Success:	Ptr to _DEST
 *
 *		Failure:	NULL
 *
 * Programmer:	Robb Matzke
 *		Tuesday, November 25, 1997
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_efl_copy(const void *_mesg, void *_dest)
{
    const H5O_efl_t	*mesg = (const H5O_efl_t *) _mesg;
    H5O_efl_t		*dest = (H5O_efl_t *) _dest;
    size_t		u;              /* Local index variable */
    void                *ret_value;     /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5O_efl_copy)

    /* check args */
    HDassert(mesg);
    if(!dest) {
	if(NULL == (dest = (H5O_efl_t *)H5MM_calloc(sizeof(H5O_efl_t))) ||
                NULL == (dest->slot = (H5O_efl_entry_t *)H5MM_malloc(mesg->nalloc * sizeof(H5O_efl_entry_t))))
	    HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
    } else if(dest->nalloc < mesg->nalloc) {
예제 #12
0
파일: H5Olayout.c 프로젝트: 151706061/ITK
/*-------------------------------------------------------------------------
 * Function:    H5O_layout_copy
 *
 * Purpose:     Copies a message from _MESG to _DEST, allocating _DEST if
 *              necessary.
 *
 * Return:      Success:        Ptr to _DEST
 *
 *              Failure:        NULL
 *
 * Programmer:  Robb Matzke
 *              Wednesday, October  8, 1997
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_layout_copy(const void *_mesg, void *_dest)
{
    const H5O_layout_t     *mesg = (const H5O_layout_t *) _mesg;
    H5O_layout_t           *dest = (H5O_layout_t *) _dest;
    void                   *ret_value;          /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5O_layout_copy)

    /* check args */
    HDassert(mesg);

    /* Allocate destination message, if necessary */
    if(!dest && NULL == (dest = H5FL_MALLOC(H5O_layout_t)))
        HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "layout message allocation failed")

    /* copy */
    *dest = *mesg;

    /* Deep copy the buffer for compact datasets also */
    if(mesg->type == H5D_COMPACT && mesg->storage.u.compact.size > 0) {
        /* Allocate memory for the raw data */
        if(NULL == (dest->storage.u.compact.buf = H5MM_malloc(dest->storage.u.compact.size)))
            HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "unable to allocate memory for compact dataset")

        /* Copy over the raw data */
        HDmemcpy(dest->storage.u.compact.buf, mesg->storage.u.compact.buf, dest->storage.u.compact.size);
    } /* end if */

    /* Reset the pointer of the chunked storage index but not the address */
    if(dest->type == H5D_CHUNKED && dest->storage.u.chunk.ops)
	H5D_chunk_idx_reset(&dest->storage.u.chunk, FALSE);

    /* Set return value */
    ret_value = dest;

done:
    if(ret_value == NULL)
        if(NULL == _dest)
            dest = H5FL_FREE(H5O_layout_t, dest);

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_layout_copy() */
예제 #13
0
파일: H5MM.c 프로젝트: MattNapsAlot/rHDF5
/*-------------------------------------------------------------------------
 * Function:	H5MM_xstrdup
 *
 * Purpose:	Duplicates a string.  If the string to be duplicated is the
 *		null pointer, then return null.	 If the string to be duplicated
 *		is the empty string then return a new empty string.
 *
 * Return:	Success:	Ptr to a new string (or null if no string).
 *
 *		Failure:	abort()
 *
 * Programmer:	Robb Matzke
 *		[email protected]
 *		Jul 10 1997
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
char *
H5MM_xstrdup(const char *s)
{
    char	*ret_value=NULL;

    /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MM_xstrdup);

    if (s) {
        ret_value = H5MM_malloc(HDstrlen(s) + 1);
        assert (ret_value);
        HDstrcpy(ret_value, s);
    } /* end if */

#ifdef LATER
done:
#endif /* LATER */
    FUNC_LEAVE_NOAPI(ret_value);
}
예제 #14
0
/*-------------------------------------------------------------------------
 * Function:	H5G_compact_build_table
 *
 * Purpose:     Builds a table containing a sorted (alphabetically) list of
 *              links for a group
 *
 * Return:	Success:        Non-negative
 *		Failure:	Negative
 *
 * Programmer:	Quincey Koziol
 *	        Sep  6, 2005
 *
 *-------------------------------------------------------------------------
 */
static herr_t
H5G_compact_build_table(const H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo,
    H5_index_t idx_type, H5_iter_order_t order, H5G_link_table_t *ltable)
{
    herr_t	ret_value = SUCCEED;    /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5G_compact_build_table)

    /* Sanity check */
    HDassert(oloc);
    HDassert(linfo);
    HDassert(ltable);

    /* Set size of table */
    H5_CHECK_OVERFLOW(linfo->nlinks, hsize_t, size_t);
    ltable->nlinks = (size_t)linfo->nlinks;

    /* Allocate space for the table entries */
    if(ltable->nlinks > 0) {
        H5G_iter_bt_t udata;               /* User data for iteration callback */
        H5O_mesg_operator_t op;             /* Message operator */

        /* Allocate the link table */
        if((ltable->lnks = (H5O_link_t *)H5MM_malloc(sizeof(H5O_link_t) * ltable->nlinks)) == NULL)
            HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")

        /* Set up user data for iteration */
        udata.ltable = ltable;
        udata.curr_lnk = 0;

        /* Iterate through the link messages, adding them to the table */
        op.op_type = H5O_MESG_OP_APP;
        op.u.app_op = H5G_compact_build_table_cb;
        if(H5O_msg_iterate(oloc, H5O_LINK_ID, &op, &udata, dxpl_id) < 0)
            HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over link messages")

        /* Sort link table in correct iteration order */
        if(H5G_link_sort_table(ltable, idx_type, order) < 0)
            HGOTO_ERROR(H5E_SYM, H5E_CANTSORT, FAIL, "error sorting link messages")
    } /* end if */
예제 #15
0
/*-------------------------------------------------------------------------
 * Function:	H5F_cwfs_add
 *
 * Purpose:	Add a global heap collection to the CWFS for a file.
 *
 * Return:	Success:	Non-negative
 *		Failure:	Negative
 *
 * Programmer:	Quincey Koziol
 *              Tuesday, July 19, 2011
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5F_cwfs_add(H5F_t *f, H5HG_heap_t *heap)
{
    herr_t	ret_value = SUCCEED;        /* Return value */

    FUNC_ENTER_NOAPI(FAIL)

    /* Check args */
    HDassert(f);
    HDassert(f->shared);
    HDassert(heap);

    /*
     * Add the new heap to the CWFS list, removing some other entry if
     * necessary to make room. We remove the right-most entry that has less
     * free space than this heap.
     */
    if(NULL == f->shared->cwfs) {
	if(NULL == (f->shared->cwfs = (H5HG_heap_t **)H5MM_malloc(H5F_NCWFS * sizeof(H5HG_heap_t *))))
	    HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't allocate CWFS for file")
	f->shared->cwfs[0] = heap;
	f->shared->ncwfs = 1;
    } else if(H5F_NCWFS == f->shared->ncwfs) {
        int i;          /* Local index variable */

        for(i = H5F_NCWFS - 1; i >= 0; --i)
            if(H5HG_FREE_SIZE(f->shared->cwfs[i]) < H5HG_FREE_SIZE(heap)) {
                HDmemmove(f->shared->cwfs + 1, f->shared->cwfs, (size_t)i * sizeof(H5HG_heap_t *));
                f->shared->cwfs[0] = heap;
                break;
            } /* end if */
    } else {
        HDmemmove(f->shared->cwfs + 1, f->shared->cwfs, f->shared->ncwfs * sizeof(H5HG_heap_t *));
	f->shared->cwfs[0] = heap;
        f->shared->ncwfs += 1;
    } /* end else */

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* H5F_cwfs_add() */
예제 #16
0
/*--------------------------------------------------------------------------
 * Function: H5L_build_name
 *
 * Purpose:  Prepend PREFIX to FILE_NAME and store in FULL_NAME
 *
 * Return:   Non-negative on success/Negative on failure
 *
 * Programmer:	Vailin Choi, April 2, 2008
 *
 * Modification: Raymond Lu, 14 Jan. 2009
 *           Added support for OpenVMS pathname
--------------------------------------------------------------------------*/
static herr_t
H5L_build_name(char *prefix, char *file_name, char **full_name/*out*/)
{
    size_t      prefix_len;             /* length of prefix */
    size_t      fname_len;              /* Length of external link file name */
    herr_t      ret_value = SUCCEED;    /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

    prefix_len = HDstrlen(prefix);
    fname_len = HDstrlen(file_name);

    /* Allocate a buffer to hold the filename + prefix + possibly the delimiter + terminating null byte */
    if(NULL == (*full_name = (char *)H5MM_malloc(prefix_len + fname_len + 2)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate filename buffer")

    /* Compose the full file name */
    HDsnprintf(*full_name, (prefix_len + fname_len + 2), "%s%s%s", prefix,
        (H5_CHECK_DELIMITER(prefix[prefix_len - 1]) ? "" : H5_DIR_SEPS), file_name);

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* H5L_build_name() */
예제 #17
0
파일: H5Odrvinfo.c 프로젝트: GATB/gatb-core
/*-------------------------------------------------------------------------
 * Function:	H5O_drvinfo_decode
 *
 * Purpose:	Decode a shared message table message and return a pointer
 *              to a newly allocated H5O_drvinfo_t struct.
 *
 * Return:	Success:	Ptr to new message in native struct.
 *		Failure:	NULL
 *
 * Programmer:  Quincey Koziol
 *              Mar  1, 2007
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_drvinfo_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh,
    unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags,
    size_t H5_ATTR_UNUSED p_size, const uint8_t *p)
{
    H5O_drvinfo_t	*mesg;          /* Native message */
    void		*ret_value = NULL;      /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

    /* Sanity check */
    HDassert(f);
    HDassert(p);

    /* Version of message */
    if(*p++ != H5O_DRVINFO_VERSION)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message")

    /* Allocate space for message */
    if(NULL == (mesg = (H5O_drvinfo_t *)H5MM_calloc(sizeof(H5O_drvinfo_t))))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for driver info message")

    /* Retrieve driver name */
    HDmemcpy(mesg->name, p, 8);
    mesg->name[8] = '\0';
    p += 8;

    /* Decode buffer size */
    UINT16DECODE(p, mesg->len);
    HDassert(mesg->len);

    /* Allocate space for buffer */
    if(NULL == (mesg->buf = (uint8_t *)H5MM_malloc(mesg->len))) {
        mesg = (H5O_drvinfo_t *)H5MM_xfree(mesg);
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for driver info buffer")
    } /* end if */
/*-------------------------------------------------------------------------
 * Function:	H5O_shmesg_copy
 *
 * Purpose:	Copies a message from _MESG to _DEST, allocating _DEST if
 *		necessary.
 *
 * Return:	Success:	Ptr to _DEST
 *		Failure:	NULL
 *
 * Programmer:  James Laird
 *              Jan 29, 2007
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_shmesg_copy(const void *_mesg, void *_dest)
{
    const H5O_shmesg_table_t	*mesg = (const H5O_shmesg_table_t *)_mesg;
    H5O_shmesg_table_t		*dest = (H5O_shmesg_table_t *)_dest;
    void			*ret_value;

    FUNC_ENTER_NOAPI_NOINIT

    /* Sanity check */
    HDassert(mesg);

    if(!dest && NULL == (dest = (H5O_shmesg_table_t *)H5MM_malloc(sizeof(H5O_shmesg_table_t))))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for shared message table message")

    /* All this message requires is a shallow copy */
    *dest = *mesg;

    /* Set return value */
    ret_value = dest;

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_shmesg_copy() */
예제 #19
0
/*-------------------------------------------------------------------------
 * Function:	H5MM_realloc
 *
 * Purpose:	Just like the POSIX version of realloc(3). Specifically, the
 *		following calls are equivalent
 *
 *		H5MM_realloc (NULL, size) <==> H5MM_malloc (size)
 *		H5MM_realloc (ptr, 0)	  <==> H5MM_xfree (ptr)
 *		H5MM_realloc (NULL, 0)	  <==> NULL
 *
 * Return:	Success:	Ptr to new memory or NULL if the memory
 *				was freed.
 *
 *		Failure:	NULL
 *
 * Programmer:	Robb Matzke
 *		[email protected]
 *		Jul 10 1997
 *
 *-------------------------------------------------------------------------
 */
void *
H5MM_realloc(void *mem, size_t size)
{
    void *ret_value;

    /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MM_realloc)

    if(NULL == mem) {
	if(0 == size)
            mem = NULL;
        else
            mem = H5MM_malloc(size);
    } /* end if */
    else if(0 == size)
	mem = H5MM_xfree(mem);
    else
	mem = HDrealloc(mem, size);

    /* Set return value */
    ret_value = mem;

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MM_realloc() */
예제 #20
0
/*-------------------------------------------------------------------------
 * 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);
                }
예제 #21
0
파일: H5B2leaf.c 프로젝트: jpouderoux/VTK
/*-------------------------------------------------------------------------
 * Function:	H5B2__insert_leaf
 *
 * Purpose:	Adds a new record to a B-tree leaf node.
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		Mar  3 2005
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5B2__insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr,
    H5B2_nodepos_t curr_pos, void *parent, void *udata)
{
    H5B2_leaf_t *leaf;                  /* Pointer to leaf node */
    unsigned leaf_flags = H5AC__NO_FLAGS_SET;   /* Flags for unprotecting the leaf node */
    int         cmp;                    /* Comparison value of records */
    unsigned    idx = 0;                /* Location of record which matches key */
    herr_t	ret_value = SUCCEED;    /* Return value */

    FUNC_ENTER_PACKAGE

    /* Check arguments. */
    HDassert(hdr);
    HDassert(curr_node_ptr);
    HDassert(H5F_addr_defined(curr_node_ptr->addr));

    /* Lock current B-tree node */
    if(NULL == (leaf = H5B2__protect_leaf(hdr, dxpl_id, parent, curr_node_ptr, FALSE, H5AC__NO_FLAGS_SET)))
        HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree leaf node")

    /* Must have a leaf node with enough space to insert a record now */
    HDassert(curr_node_ptr->node_nrec < hdr->node_info[0].max_nrec);

    /* Sanity check number of records */
    HDassert(curr_node_ptr->all_nrec == curr_node_ptr->node_nrec);
    HDassert(leaf->nrec == curr_node_ptr->node_nrec);

    /* Check for inserting into empty leaf */
    if(leaf->nrec == 0)
        idx = 0;
    else {
        /* Find correct location to insert this record */
        if(H5B2__locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx, &cmp) < 0)
            HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records")
        if(cmp == 0)
            HGOTO_ERROR(H5E_BTREE, H5E_EXISTS, FAIL, "record is already in B-tree")
        if(cmp > 0)
            idx++;

        /* Make room for new record */
        if(idx < leaf->nrec)
            HDmemmove(H5B2_LEAF_NREC(leaf, hdr, idx + 1), H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size * (leaf->nrec - idx));
    } /* end else */

    /* Make callback to store record in native form */
    if((hdr->cls->store)(H5B2_LEAF_NREC(leaf, hdr, idx), udata) < 0)
        HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into leaf node")

    /* Mark the node as dirty */
    leaf_flags |= H5AC__DIRTIED_FLAG;

    /* Update record count for node pointer to current node */
    curr_node_ptr->all_nrec++;
    curr_node_ptr->node_nrec++;

    /* Update record count for current node */
    leaf->nrec++;

    /* Check for new record being the min or max for the tree */
    /* (Don't use 'else' for the idx check, to allow for root leaf node) */
    if(H5B2_POS_MIDDLE != curr_pos) {
        if(idx == 0) {
            if(H5B2_POS_LEFT == curr_pos || H5B2_POS_ROOT == curr_pos) {
                if(hdr->min_native_rec == NULL)
                    if(NULL == (hdr->min_native_rec = H5MM_malloc(hdr->cls->nrec_size)))
                        HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree min record info")
                HDmemcpy(hdr->min_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size);
            } /* end if */
        } /* end if */
        if(idx == (unsigned)(leaf->nrec - 1)) {
            if(H5B2_POS_RIGHT == curr_pos || H5B2_POS_ROOT == curr_pos) {
                if(hdr->max_native_rec == NULL)
                    if(NULL == (hdr->max_native_rec = H5MM_malloc(hdr->cls->nrec_size)))
                        HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree max record info")
                HDmemcpy(hdr->max_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size);
            } /* end if */
        } /* end if */
    } /* end if */

done:
    /* Release the B-tree leaf node (marked as dirty) */
    if(leaf) {
        /* Shadow the node if doing SWMR writes */
        if(hdr->swmr_write && (leaf_flags & H5AC__DIRTIED_FLAG))
            if(H5B2__shadow_leaf(leaf, dxpl_id, curr_node_ptr) < 0)
                HDONE_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow leaf B-tree node")

        /* Unprotect leaf node */
        if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, leaf, leaf_flags) < 0)
            HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release leaf B-tree node")
    } /* end if */

    FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2__insert_leaf() */
예제 #22
0
파일: H5Olayout.c 프로젝트: 151706061/ITK
/*-------------------------------------------------------------------------
 * Function:    H5O_layout_decode
 *
 * Purpose:     Decode an data layout message and return a pointer to a
 *              new one created with malloc().
 *
 * Return:      Success:        Ptr to new message in native order.
 *
 *              Failure:        NULL
 *
 * Programmer:  Robb Matzke
 *              Wednesday, October  8, 1997
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
    unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
    H5O_layout_t           *mesg = NULL;
    unsigned               u;
    void                   *ret_value;          /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5O_layout_decode)

    /* check args */
    HDassert(f);
    HDassert(p);

    /* decode */
    if(NULL == (mesg = H5FL_CALLOC(H5O_layout_t)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    mesg->version = *p++;
    if(mesg->version < H5O_LAYOUT_VERSION_1 || mesg->version > H5O_LAYOUT_VERSION_3)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for layout message")

    if(mesg->version < H5O_LAYOUT_VERSION_3) {
        unsigned	ndims;			/* Num dimensions in chunk           */

        /* Dimensionality */
        ndims = *p++;
        if(ndims > H5O_LAYOUT_NDIMS)
            HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large")

        /* Layout class */
        mesg->type = (H5D_layout_t)*p++;
        assert(H5D_CONTIGUOUS == mesg->type || H5D_CHUNKED == mesg->type || H5D_COMPACT == mesg->type);

        /* Reserved bytes */
        p += 5;

        /* Address */
        if(mesg->type == H5D_CONTIGUOUS) {
            H5F_addr_decode(f, &p, &(mesg->storage.u.contig.addr));

            /* Set the layout operations */
            mesg->ops = H5D_LOPS_CONTIG;
        } /* end if */
        else if(mesg->type == H5D_CHUNKED) {
            H5F_addr_decode(f, &p, &(mesg->storage.u.chunk.idx_addr));

            /* Set the layout operations */
            mesg->ops = H5D_LOPS_CHUNK;

            /* Set the chunk operations */
            /* (Only "btree" indexing type currently supported in this version) */
            mesg->storage.u.chunk.idx_type = H5D_CHUNK_BTREE;
            mesg->storage.u.chunk.ops = H5D_COPS_BTREE;
        } /* end if */
        else {
            /* Sanity check */
            HDassert(mesg->type == H5D_COMPACT);

            /* Set the layout operations */
            mesg->ops = H5D_LOPS_COMPACT;
        } /* end else */

        /* Read the size */
        if(mesg->type != H5D_CHUNKED) {
            /* Don't compute size of contiguous storage here, due to possible
             * truncation of the dimension sizes when they were stored in this
             * version of the layout message.  Compute the contiguous storage
             * size in the dataset code, where we've got the dataspace
             * information available also.  - QAK 5/26/04
             */
            p += ndims * 4;     /* Skip over dimension sizes (32-bit quantities) */
        } /* end if */
        else {
            mesg->u.chunk.ndims=ndims;
            for(u = 0; u < ndims; u++)
                UINT32DECODE(p, mesg->u.chunk.dim[u]);

            /* Compute chunk size */
            for(u = 1, mesg->u.chunk.size = mesg->u.chunk.dim[0]; u < ndims; u++)
                mesg->u.chunk.size *= mesg->u.chunk.dim[u];
        } /* end if */

        if(mesg->type == H5D_COMPACT) {
            UINT32DECODE(p, mesg->storage.u.compact.size);
            if(mesg->storage.u.compact.size > 0) {
                if(NULL == (mesg->storage.u.compact.buf = H5MM_malloc(mesg->storage.u.compact.size)))
                    HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer")
                HDmemcpy(mesg->storage.u.compact.buf, p, mesg->storage.u.compact.size);
                p += mesg->storage.u.compact.size;
            } /* end if */
        } /* end if */
    } /* end if */
    else {
        /* Layout class */
        mesg->type = (H5D_layout_t)*p++;

        /* Interpret the rest of the message according to the layout class */
        switch(mesg->type) {
            case H5D_COMPACT:
                UINT16DECODE(p, mesg->storage.u.compact.size);
                if(mesg->storage.u.compact.size > 0) {
                    if(NULL == (mesg->storage.u.compact.buf = H5MM_malloc(mesg->storage.u.compact.size)))
                        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer")
                    HDmemcpy(mesg->storage.u.compact.buf, p, mesg->storage.u.compact.size);
                    p += mesg->storage.u.compact.size;
                } /* end if */

                /* Set the layout operations */
                mesg->ops = H5D_LOPS_COMPACT;
                break;

            case H5D_CONTIGUOUS:
                H5F_addr_decode(f, &p, &(mesg->storage.u.contig.addr));
                H5F_DECODE_LENGTH(f, p, mesg->storage.u.contig.size);

                /* Set the layout operations */
                mesg->ops = H5D_LOPS_CONTIG;
                break;

            case H5D_CHUNKED:
                /* Dimensionality */
                mesg->u.chunk.ndims = *p++;
                if(mesg->u.chunk.ndims > H5O_LAYOUT_NDIMS)
                    HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large")

                /* B-tree address */
                H5F_addr_decode(f, &p, &(mesg->storage.u.chunk.idx_addr));

                /* Chunk dimensions */
                for(u = 0; u < mesg->u.chunk.ndims; u++)
                    UINT32DECODE(p, mesg->u.chunk.dim[u]);

                /* Compute chunk size */
                for(u = 1, mesg->u.chunk.size = mesg->u.chunk.dim[0]; u < mesg->u.chunk.ndims; u++)
                    mesg->u.chunk.size *= mesg->u.chunk.dim[u];

                /* Set the chunk operations */
                /* (Only "btree" indexing type supported with v3 of message format) */
                mesg->storage.u.chunk.idx_type = H5D_CHUNK_BTREE;
                mesg->storage.u.chunk.ops = H5D_COPS_BTREE;

                /* Set the layout operations */
                mesg->ops = H5D_LOPS_CHUNK;
                break;

            default:
                HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "Invalid layout class")
        } /* end switch */
    } /* end else */

    /* Set return value */
    ret_value = mesg;

done:
    if(ret_value == NULL)
        if(mesg)
            mesg = H5FL_FREE(H5O_layout_t, mesg);

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_layout_decode() */
예제 #23
0
/*-------------------------------------------------------------------------
 * Function:    H5O_layout_decode
 *
 * Purpose:     Decode an data layout message and return a pointer to a
 *              new one created with malloc().
 *
 * Return:      Success:        Ptr to new message in native order.
 *
 *              Failure:        NULL
 *
 * Programmer:  Robb Matzke
 *              Wednesday, October  8, 1997
 *
 * Modifications:
 * 	Robb Matzke, 1998-07-20
 *	Rearranged the message to add a version number at the beginning.
 *
 *      Raymond Lu, 2002-2-26
 *      Added version number 2 case depends on if space has been allocated
 *      at the moment when layout header message is updated.
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p)
{
    H5O_layout_t           *mesg = NULL;
    unsigned               u;
    void                   *ret_value;          /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5O_layout_decode);

    /* check args */
    assert(f);
    assert(p);

    /* decode */
    if (NULL==(mesg = H5FL_CALLOC(H5O_layout_t)))
        HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");

    /* Version. 1 when space allocated; 2 when space allocation is delayed */
    mesg->version = *p++;
    if (mesg->version<H5O_LAYOUT_VERSION_1 || mesg->version>H5O_LAYOUT_VERSION_3)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for layout message");

    if(mesg->version < H5O_LAYOUT_VERSION_3) {
        unsigned	ndims;			/* Num dimensions in chunk           */

        /* Dimensionality */
        ndims = *p++;
        if (ndims>H5O_LAYOUT_NDIMS)
            HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large");

        /* Layout class */
        mesg->type = (H5D_layout_t)*p++;
        assert(H5D_CONTIGUOUS == mesg->type || H5D_CHUNKED == mesg->type || H5D_COMPACT == mesg->type);

        /* Reserved bytes */
        p += 5;

        /* Address */
        if(mesg->type==H5D_CONTIGUOUS)
            H5F_addr_decode(f, &p, &(mesg->u.contig.addr));
        else if(mesg->type==H5D_CHUNKED)
            H5F_addr_decode(f, &p, &(mesg->u.chunk.addr));

        /* Read the size */
        if(mesg->type!=H5D_CHUNKED) {
	    mesg->unused.ndims=ndims;

            for (u = 0; u < ndims; u++)
                UINT32DECODE(p, mesg->unused.dim[u]);

            /* Don't compute size of contiguous storage here, due to possible
             * truncation of the dimension sizes when they were stored in this
             * version of the layout message.  Compute the contiguous storage
             * size in the dataset code, where we've got the dataspace
             * information available also.  - QAK 5/26/04
             */
        } /* end if */
        else {
            mesg->u.chunk.ndims=ndims;
            for (u = 0; u < ndims; u++)
                UINT32DECODE(p, mesg->u.chunk.dim[u]);

            /* Compute chunk size */
            for (u=1, mesg->u.chunk.size=mesg->u.chunk.dim[0]; u<ndims; u++)
                mesg->u.chunk.size *= mesg->u.chunk.dim[u];
        } /* end if */

        if(mesg->type == H5D_COMPACT) {
            UINT32DECODE(p, mesg->u.compact.size);
            if(mesg->u.compact.size > 0) {
                if(NULL==(mesg->u.compact.buf=H5MM_malloc(mesg->u.compact.size)))
                    HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer");
                HDmemcpy(mesg->u.compact.buf, p, mesg->u.compact.size);
                p += mesg->u.compact.size;
            }
        }
    } /* end if */
    else {
        /* Layout class */
        mesg->type = (H5D_layout_t)*p++;

        /* Interpret the rest of the message according to the layout class */
        switch(mesg->type) {
            case H5D_CONTIGUOUS:
                H5F_addr_decode(f, &p, &(mesg->u.contig.addr));
                H5F_DECODE_LENGTH(f, p, mesg->u.contig.size);
                break;

            case H5D_CHUNKED:
                /* Dimensionality */
                mesg->u.chunk.ndims = *p++;
                if (mesg->u.chunk.ndims>H5O_LAYOUT_NDIMS)
                    HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large");

                /* B-tree address */
                H5F_addr_decode(f, &p, &(mesg->u.chunk.addr));

                /* Chunk dimensions */
                for (u = 0; u < mesg->u.chunk.ndims; u++)
                    UINT32DECODE(p, mesg->u.chunk.dim[u]);

                /* Compute chunk size */
                for (u=1, mesg->u.chunk.size=mesg->u.chunk.dim[0]; u<mesg->u.chunk.ndims; u++)
                    mesg->u.chunk.size *= mesg->u.chunk.dim[u];
                break;

            case H5D_COMPACT:
                UINT16DECODE(p, mesg->u.compact.size);
                if(mesg->u.compact.size > 0) {
                    if(NULL==(mesg->u.compact.buf=H5MM_malloc(mesg->u.compact.size)))
                        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer");
                    HDmemcpy(mesg->u.compact.buf, p, mesg->u.compact.size);
                    p += mesg->u.compact.size;
                } /* end if */
                break;

            default:
                HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "Invalid layout class");
        } /* end switch */
    } /* end else */

    /* Set return value */
    ret_value=mesg;

done:
    if(ret_value==NULL) {
        if(mesg)
            H5FL_FREE(H5O_layout_t,mesg);
    } /* end if */
    FUNC_LEAVE_NOAPI(ret_value);
}
예제 #24
0
파일: H5Opline.c 프로젝트: jpouderoux/VTK
/*-------------------------------------------------------------------------
 * Function:	H5O_pline_decode
 *
 * Purpose:	Decodes a filter pipeline message.
 *
 * Return:	Success:	Ptr to the native message.
 *		Failure:	NULL
 *
 * Programmer:	Robb Matzke
 *              Wednesday, April 15, 1998
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_pline_decode(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_t H5_ATTR_UNUSED *open_oh,
    unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, const uint8_t *p)
{
    H5O_pline_t		*pline = NULL;          /* Pipeline message */
    H5Z_filter_info_t   *filter;                /* Filter to decode */
    size_t		name_length;            /* Length of filter name */
    size_t		i;                      /* Local index variable */
    void		*ret_value = NULL;      /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

    /* check args */
    HDassert(p);

    /* Allocate space for I/O pipeline message */
    if(NULL == (pline = H5FL_CALLOC(H5O_pline_t)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* Version */
    pline->version = *p++;
    if(pline->version < H5O_PLINE_VERSION_1 || pline->version > H5O_PLINE_VERSION_LATEST)
	HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "bad version number for filter pipeline message")

    /* Number of filters */
    pline->nused = *p++;
    if(pline->nused > H5Z_MAX_NFILTERS)
	HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "filter pipeline message has too many filters")

    /* Reserved */
    if(pline->version == H5O_PLINE_VERSION_1)
        p += 6;

    /* Allocate array for filters */
    pline->nalloc = pline->nused;
    if(NULL == (pline->filter = (H5Z_filter_info_t *)H5MM_calloc(pline->nalloc * sizeof(pline->filter[0]))))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* Decode filters */
    for(i = 0, filter = &pline->filter[0]; i < pline->nused; i++, filter++) {
        /* Filter ID */
	UINT16DECODE(p, filter->id);

        /* Length of filter name */
        if(pline->version > H5O_PLINE_VERSION_1 && filter->id < H5Z_FILTER_RESERVED)
            name_length = 0;
        else {
            UINT16DECODE(p, name_length);
            if(pline->version == H5O_PLINE_VERSION_1 && name_length % 8)
                HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "filter name length is not a multiple of eight")
        } /* end if */

        /* Filter flags */
	UINT16DECODE(p, filter->flags);

        /* Number of filter parameters ("client data elements") */
	UINT16DECODE(p, filter->cd_nelmts);

        /* Filter name, if there is one */
	if(name_length) {
            size_t actual_name_length;          /* Actual length of name */

            /* Determine actual name length (without padding, but with null terminator) */
	    actual_name_length = HDstrlen((const char *)p) + 1;
	    HDassert(actual_name_length <= name_length);

            /* Allocate space for the filter name, or use the internal buffer */
            if(actual_name_length > H5Z_COMMON_NAME_LEN) {
                filter->name = (char *)H5MM_malloc(actual_name_length);
                if(NULL == filter->name)
                    HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for filter name")
            } /* end if */
            else
                filter->name = filter->_name;

	    HDstrncpy(filter->name, (const char *)p, actual_name_length);
	    p += name_length;
	} /* end if */
예제 #25
0
/*-------------------------------------------------------------------------
 * Function:	H5L_extern_traverse
 *
 * Purpose:	Default traversal function for external links. This can
 *              be overridden using H5Lregister().
 *
 *              Given a filename and path packed into the link udata,
 *              attempts to open an object within an external file.
 *              If the H5L_ELINK_PREFIX_NAME property is set in the
 *              link access property list, appends that prefix to the
 *              filename being opened.
 *
 * Return:	ID of the opened object on success/Negative on failure
 *
 * Programmer:	James Laird
 *              Monday, July 10, 2006
 * Modifications:
 *		Vailin Choi, April 2, 2008
 *		Add handling to search for the target file
 *		See description in RM: H5Lcreate_external
 *
 *		Vailin Choi; Sept. 12th, 2008; bug #1247
 *		Retrieve the file access property list identifer that is set
 *		for link access property via H5Pget_elink_fapl().
 *		If the return value is H5P_DEFAULT, the parent's file access
 *		property is used to H5F_open() the target file;
 *		Otherwise, the file access property retrieved from H5Pget_elink_fapl()
 *		is used to H5F_open() the target file.
 *
 *		Vailin Choi; Nov 2010
 *		Free memory pointed to by tmp_env_prefix for HDF5_EXT_PREFIX case.
 *
 *-------------------------------------------------------------------------
 */
static hid_t
H5L_extern_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group,
    const void *_udata, size_t H5_ATTR_UNUSED udata_size, hid_t lapl_id)
{
    H5P_genplist_t *plist;              /* Property list pointer */
    char       *my_prefix;              /* Library's copy of the prefix */
    H5G_loc_t   root_loc;               /* Location of root group in external file */
    H5G_loc_t   loc;                    /* Location of object */
    H5F_t	*ext_file = NULL;	/* File struct for external file */
    const uint8_t *p = (const uint8_t *)_udata;  /* Pointer into external link buffer */
    const char *file_name;              /* Name of file containing external link's object */
    char *full_name = NULL;             /* File name with prefix */
    const char  *obj_name;              /* Name external link's object */
    size_t      fname_len;              /* Length of external link file name */
    unsigned    intent;                 /* File access permissions */
    H5L_elink_cb_t cb_info;             /* Callback info struct */
    hid_t       fapl_id = -1;           /* File access property list for external link's file */
    hid_t       ext_obj = -1;           /* ID for external link's object */
    char        *parent_group_name = NULL;/* Temporary pointer to group name */
    char        local_group_name[H5L_EXT_TRAVERSE_BUF_SIZE];  /* Local buffer to hold group name */
    char        *temp_file_name = NULL; /* Temporary pointer to file name */
    size_t      temp_file_name_len;     /* Length of temporary file name */
    char        *actual_file_name = NULL; /* Parent file's actual name */
    H5P_genplist_t  *fa_plist;          /* File access property list pointer */
    H5F_close_degree_t 	fc_degree = H5F_CLOSE_WEAK;  /* File close degree for target file */
    hid_t       ret_value;              /* Return value */

    FUNC_ENTER_NOAPI(FAIL)

    /* Sanity checks */
    HDassert(p);

    /* Check external link version & flags */
    if(((*p >> 4) & 0x0F) > H5L_EXT_VERSION)
        HGOTO_ERROR(H5E_LINK, H5E_CANTDECODE, FAIL, "bad version number for external link")
    if((*p & 0x0F) & ~H5L_EXT_FLAGS_ALL)
        HGOTO_ERROR(H5E_LINK, H5E_CANTDECODE, FAIL, "bad flags for external link")
    p++;

    /* Gather some information from the external link's user data */
    file_name = (const char *)p;
    fname_len = HDstrlen(file_name);
    obj_name = (const char *)p + fname_len + 1;

    /* Get the plist structure */
    if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
        HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")

    /* Get the fapl_id set for lapl_id if any */
    if(H5P_get(plist, H5L_ACS_ELINK_FAPL_NAME, &fapl_id) < 0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fapl for links")

    /* Get the location for the group holding the external link */
    if(H5G_loc(cur_group, &loc) < 0)
        HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get object location")

    /* get the access flags set for lapl_id if any */
    if(H5P_get(plist, H5L_ACS_ELINK_FLAGS_NAME, &intent) < 0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get elink file access flags")

    /* get the file access mode flags for the parent file, if they were not set
     * on lapl_id */
    if(intent == H5F_ACC_DEFAULT)
        intent = H5F_INTENT(loc.oloc->file);

    if((fapl_id == H5P_DEFAULT) && ((fapl_id = H5F_get_access_plist(loc.oloc->file, FALSE)) < 0))
	HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get parent's file access property list")

    /* Get callback_info */
    if(H5P_get(plist, H5L_ACS_ELINK_CB_NAME, &cb_info)<0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get elink callback info")

    /* Get file access property list */
    if(NULL == (fa_plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
	HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")

    /* Make callback if it exists */
    if(cb_info.func) {
        const char  *parent_file_name;  /* Parent file name */
        ssize_t group_name_len;         /* Length of parent group name */

        /* Get parent file name */
        parent_file_name = H5F_OPEN_NAME(loc.oloc->file);

        /* Query length of parent group name */
        if((group_name_len = H5G_get_name(&loc, NULL, (size_t) 0, NULL, lapl_id, H5AC_ind_dxpl_id)) < 0)
            HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve length of group name")

        /* Account for null terminator */
        group_name_len++;

        /* Check if we need to allocate larger buffer */
        if((size_t)group_name_len > sizeof(local_group_name)) {
            if(NULL == (parent_group_name = (char *)H5MM_malloc((size_t)group_name_len)))
                HGOTO_ERROR(H5E_LINK, H5E_CANTALLOC, FAIL, "can't allocate buffer to hold group name, group_name_len = %Zu", group_name_len)
        } /* end if */
        else
            parent_group_name = local_group_name;

        /* Get parent group name */
        if(H5G_get_name(&loc, parent_group_name, (size_t) group_name_len, NULL, lapl_id, H5AC_ind_dxpl_id) < 0)
            HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve group name")

        /* Make callback */
        if((cb_info.func)(parent_file_name, parent_group_name, file_name, obj_name, &intent, fapl_id, cb_info.user_data) < 0)
            HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "traversal operator failed")

        /* Check access flags */
        if((intent & H5F_ACC_TRUNC) || (intent & H5F_ACC_EXCL))
            HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags")
    } /* end if */
예제 #26
0
파일: H5Cmpio.c 프로젝트: MichaelToal/hdf5
/*-------------------------------------------------------------------------
 * Function:    H5C_apply_candidate_list
 *
 * Purpose:     Apply the supplied candidate list.
 *
 *		We used to do this by simply having each process write 
 *		every mpi_size-th entry in the candidate list, starting 
 *		at index mpi_rank, and mark all the others clean.  
 *
 *		However, this can cause unnecessary contention in a file 
 *		system by increasing the number of processes writing to 
 *		adjacent locations in the HDF5 file.
 *
 *		To attempt to minimize this, we now arange matters such 
 *		that each process writes n adjacent entries in the 
 *		candidate list, and marks all others clean.  We must do
 *		this in such a fashion as to guarantee that each entry 
 *		on the candidate list is written by exactly one process, 
 *		and marked clean by all others.  
 *
 *		To do this, first construct a table mapping mpi_rank
 *		to the index of the first entry in the candidate list to
 *		be written by the process of that mpi_rank, and then use
 *		the table to control which entries are written and which
 *		are marked as clean as a function of the mpi_rank.
 *
 *		Note that the table must be identical on all processes, as
 *		all see the same candidate list, mpi_size, and mpi_rank --
 *		the inputs used to construct the table.  
 *
 *		We construct the table as follows.  Let:
 *
 *			n = num_candidates / mpi_size;
 *
 *			m = num_candidates % mpi_size;
 *
 *		Now allocate an array of integers of length mpi_size + 1, 
 *		and call this array candidate_assignment_table. 
 *
 *		Conceptually, if the number of candidates is a multiple
 *		of the mpi_size, we simply pass through the candidate list
 *		and assign n entries to each process to flush, with the 
 *		index of the first entry to flush in the location in 
 *		the candidate_assignment_table indicated by the mpi_rank
 *		of the process.  
 *
 *		In the more common case in which the candidate list isn't 
 *		isn't a multiple of the mpi_size, we pretend it is, and 
 *		give num_candidates % mpi_size processes one extra entry
 *		each to make things work out.
 *
 *		Once the table is constructed, we determine the first and
 *		last entry this process is to flush as follows:
 *
 *	 	first_entry_to_flush = candidate_assignment_table[mpi_rank]
 *
 *		last_entry_to_flush = 
 *			candidate_assignment_table[mpi_rank + 1] - 1;
 *		
 *		With these values determined, we simply scan through the 
 *		candidate list, marking all entries in the range 
 *		[first_entry_to_flush, last_entry_to_flush] for flush,
 *		and all others to be cleaned.
 *
 *		Finally, we scan the LRU from tail to head, flushing 
 *		or marking clean the candidate entries as indicated.
 *		If necessary, we scan the pinned list as well.
 *
 *		Note that this function will fail if any protected or 
 *		clean entries appear on the candidate list.
 *
 *		This function is used in managing sync points, and 
 *		shouldn't be used elsewhere.
 *
 * Return:      Success:        SUCCEED
 *
 *              Failure:        FAIL
 *
 * Programmer:  John Mainzer
 *              3/17/10
 *
 * Changes:     Ported code to detect next entry status changes as the 
 *              the result of a flush from the serial code in the scan of 
 *              the LRU.  Also added code to detect and adapt to the 
 *              removal from the cache of the next entry in the scan of 
 *		the LRU.
 *
 *		Note that at present, all of these changes should not 
 *		be required as the operations on entries as they are 
 *		flushed that can cause these condiditions are not premitted
 *		in the parallel case.  However, Quincey indicates that 
 *		this may change, and thus has requested the modification.
 *
 *		Note the assert(FALSE) in the if statement whose body 
 *		restarts the scan of the LRU.  As the body of the if 
 *		statement should be unreachable, it should never be 
 *		triggered until the constraints on the parallel case 
 *		are relaxed.  Please remove the assertion at that time.
 *
 *		Also added warning on the Pinned Entry List scan, as it
 *		is potentially subject to the same issue.  As there is 
 *		no cognate of this scan in the serial code, I don't have
 *		a fix to port to it.
 *
 *						JRM -- 4/10/19
 *		
 *-------------------------------------------------------------------------
 */
herr_t
H5C_apply_candidate_list(H5F_t * f,
                         hid_t dxpl_id,
                         H5C_t * cache_ptr,
                         int num_candidates,
                         haddr_t * candidates_list_ptr,
                         int mpi_rank,
                         int mpi_size)
{
    hbool_t		restart_scan;
    hbool_t		prev_is_dirty;
    int                 i;
    int			m;
    int			n;
    int			first_entry_to_flush;
    int			last_entry_to_flush;
    int			entries_to_clear = 0;
    int			entries_to_flush = 0;
    int			entries_to_flush_or_clear_last = 0;
    int			entries_to_flush_collectively = 0;
    int			entries_cleared = 0;
    int			entries_flushed = 0;
    int			entries_delayed = 0;
    int			entries_flushed_or_cleared_last = 0;
    int			entries_flushed_collectively = 0;
    int			entries_examined = 0;
    int			initial_list_len;
    int               * candidate_assignment_table = NULL;
    haddr_t		addr;
    H5C_cache_entry_t *	clear_ptr = NULL;
    H5C_cache_entry_t *	next_ptr = NULL;
    H5C_cache_entry_t *	entry_ptr = NULL;
    H5C_cache_entry_t *	flush_ptr = NULL;
    H5C_cache_entry_t * delayed_ptr = NULL;
#if H5C_DO_SANITY_CHECKS
    haddr_t		last_addr;
#endif /* H5C_DO_SANITY_CHECKS */
#if H5C_APPLY_CANDIDATE_LIST__DEBUG
    char		tbl_buf[1024];
#endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */
    herr_t              ret_value = SUCCEED;      /* Return value */

    FUNC_ENTER_NOAPI(FAIL)

    HDassert( cache_ptr != NULL );
    HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
    HDassert( num_candidates > 0 );
    HDassert( num_candidates <= cache_ptr->slist_len );
    HDassert( candidates_list_ptr != NULL );
    HDassert( 0 <= mpi_rank );
    HDassert( mpi_rank < mpi_size );

#if H5C_APPLY_CANDIDATE_LIST__DEBUG
    HDfprintf(stdout, "%s:%d: setting up candidate assignment table.\n", 
              FUNC, mpi_rank);
    for ( i = 0; i < 1024; i++ ) tbl_buf[i] = '\0';
    sprintf(&(tbl_buf[0]), "candidate list = ");
    for ( i = 0; i < num_candidates; i++ )
    {
        sprintf(&(tbl_buf[HDstrlen(tbl_buf)]), " 0x%llx", 
                (long long)(*(candidates_list_ptr + i)));
    }
    sprintf(&(tbl_buf[HDstrlen(tbl_buf)]), "\n");
    HDfprintf(stdout, "%s", tbl_buf);
#endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */

    n = num_candidates / mpi_size;
    m = num_candidates % mpi_size;
    HDassert(n >= 0);

    if(NULL == (candidate_assignment_table = (int *)H5MM_malloc(sizeof(int) * (size_t)(mpi_size + 1))))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for candidate assignment table")

    candidate_assignment_table[0] = 0;
    candidate_assignment_table[mpi_size] = num_candidates;

    if(m == 0) { /* mpi_size is an even divisor of num_candidates */
        HDassert(n > 0);
        for(i = 1; i < mpi_size; i++)
            candidate_assignment_table[i] = candidate_assignment_table[i - 1] + n;
    } /* end if */
    else { 
        for(i = 1; i <= m; i++)
            candidate_assignment_table[i] = candidate_assignment_table[i - 1] + n + 1;

        if(num_candidates < mpi_size) {
            for(i = m + 1; i < mpi_size; i++)
                candidate_assignment_table[i] = num_candidates;
        } /* end if */
        else {
            for(i = m + 1; i < mpi_size; i++)
                candidate_assignment_table[i] = candidate_assignment_table[i - 1] + n;
        } /* end else */
    } /* end else */
    HDassert((candidate_assignment_table[mpi_size - 1] + n) == num_candidates);

#if H5C_DO_SANITY_CHECKS
    /* verify that the candidate assignment table has the expected form */
    for ( i = 1; i < mpi_size - 1; i++ ) 
    {
        int a, b;

        a = candidate_assignment_table[i] - candidate_assignment_table[i - 1];
        b = candidate_assignment_table[i + 1] - candidate_assignment_table[i];

        HDassert( n + 1 >= a );
        HDassert( a >= b );
        HDassert( b >= n );
    }
#endif /* H5C_DO_SANITY_CHECKS */

    first_entry_to_flush = candidate_assignment_table[mpi_rank];
    last_entry_to_flush = candidate_assignment_table[mpi_rank + 1] - 1;

#if H5C_APPLY_CANDIDATE_LIST__DEBUG
    for ( i = 0; i < 1024; i++ )
        tbl_buf[i] = '\0';
    sprintf(&(tbl_buf[0]), "candidate assignment table = ");
    for(i = 0; i <= mpi_size; i++)
        sprintf(&(tbl_buf[HDstrlen(tbl_buf)]), " %d", candidate_assignment_table[i]);
    sprintf(&(tbl_buf[HDstrlen(tbl_buf)]), "\n");
    HDfprintf(stdout, "%s", tbl_buf);

    HDfprintf(stdout, "%s:%d: flush entries [%d, %d].\n", 
              FUNC, mpi_rank, first_entry_to_flush, last_entry_to_flush);

    HDfprintf(stdout, "%s:%d: marking entries.\n", FUNC, mpi_rank);
#endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */

    for(i = 0; i < num_candidates; i++) {
        addr = candidates_list_ptr[i];
        HDassert( H5F_addr_defined(addr) );

#if H5C_DO_SANITY_CHECKS
        if ( i > 0 ) {
            if ( last_addr == addr ) {
                HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Duplicate entry in cleaned list.\n")
            } else if ( last_addr > addr ) {
                HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "candidate list not sorted.\n")
            }
        }

        last_addr = addr;
#endif /* H5C_DO_SANITY_CHECKS */

        H5C__SEARCH_INDEX(cache_ptr, addr, entry_ptr, FAIL)
        if(entry_ptr == NULL) {
            HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Listed candidate entry not in cache?!?!?.")
        } else if(!entry_ptr->is_dirty) {
            HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Listed entry not dirty?!?!?.")
        } else if ( entry_ptr->is_protected ) {
            /* For now at least, we can't deal with protected entries.
             * If we encounter one, scream and die.  If it becomes an
             * issue, we should be able to work around this. 
             */
            HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Listed entry is protected?!?!?.")
        } else {
            /* determine whether the entry is to be cleared or flushed,
             * and mark it accordingly.  We will scan the protected and 
             * pinned list shortly, and clear or flush according to these
             * markings.  
             */
            if((i >= first_entry_to_flush) && (i <= last_entry_to_flush)) {
                entries_to_flush++;
                entry_ptr->flush_immediately = TRUE;
            } /* end if */
            else {
                entries_to_clear++;
                entry_ptr->clear_on_unprotect = TRUE;
            } /* end else */
        } /* end else */
    } /* end for */

#if H5C_APPLY_CANDIDATE_LIST__DEBUG
    HDfprintf(stdout, "%s:%d: num candidates/to clear/to flush = %d/%d/%d.\n", 
              FUNC, mpi_rank, (int)num_candidates, (int)entries_to_clear,
              (int)entries_to_flush);
#endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */


    /* We have now marked all the entries on the candidate list for 
     * either flush or clear -- now scan the LRU and the pinned list
     * for these entries and do the deed.
     *
     * Note that we are doing things in this round about manner so as
     * to preserve the order of the LRU list to the best of our ability.
     * If we don't do this, my experiments indicate that we will have a
     * noticably poorer hit ratio as a result.
     */

#if H5C_APPLY_CANDIDATE_LIST__DEBUG
    HDfprintf(stdout, "%s:%d: scanning LRU list. len = %d.\n", FUNC, mpi_rank,
              (int)(cache_ptr->LRU_list_len));
#endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */

    /* ===================================================================== *
     * Now scan the LRU and PEL lists, flushing or clearing entries as
     * needed.
     *
     * The flush_me_last and flush_me_collectively flags may dictate how or
     * when some entries can be flushed, and should be addressed here.
     * However, in their initial implementation, these flags only apply to the
     * superblock, so there's only a relatively small change to this function
     * to account for this one case where they come into play. If these flags
     * are ever expanded upon, this function and the following flushing steps
     * should be reworked to account for additional cases.
     * ===================================================================== */

    HDassert(entries_to_flush >= 0);

    restart_scan = FALSE;
    entries_examined = 0;
    initial_list_len = cache_ptr->LRU_list_len;
    entry_ptr = cache_ptr->LRU_tail_ptr;

    /* Examine each entry in the LRU list */
    while ( ( entry_ptr != NULL ) 
            && 
            ( entries_examined <= (entries_to_flush + 1) * initial_list_len ) 
            &&
            ( (entries_cleared + entries_flushed) < num_candidates ) ) {

        if ( entry_ptr->prev != NULL )
            prev_is_dirty = entry_ptr->prev->is_dirty;

        /* If this process needs to clear this entry. */
        if(entry_ptr->clear_on_unprotect) {

            HDassert(entry_ptr->is_dirty);

            next_ptr = entry_ptr->next; 
            entry_ptr->clear_on_unprotect = FALSE;
            clear_ptr = entry_ptr;
            entry_ptr = entry_ptr->prev;
            entries_cleared++;

#if ( H5C_APPLY_CANDIDATE_LIST__DEBUG > 1 )
    HDfprintf(stdout, "%s:%d: clearing 0x%llx.\n", FUNC, mpi_rank,
              (long long)clear_ptr->addr);
#endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */

	    /* No need to check for the next entry in the scan being 
             * removed from the cache, as this call to H5C__flush_single_entry()
             * will not call either the pre_serialize or serialize callbacks.
             */

            if(H5C__flush_single_entry(f, dxpl_id, clear_ptr, H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, NULL) < 0)
                HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't clear entry.")
        } /* end if */

        /* Else, if this process needs to flush this entry. */
        else if (entry_ptr->flush_immediately) {
예제 #27
0
파일: H5Rint.c 프로젝트: Kitware/ITK
/*--------------------------------------------------------------------------
 NAME
    H5R__create
 PURPOSE
    Creates a particular kind of reference for the user
 USAGE
    herr_t H5R__create(ref, loc, name, ref_type, space)
        void *ref;          OUT: Reference created
        H5G_loc_t *loc;     IN: File location used to locate object pointed to
        const char *name;   IN: Name of object at location LOC_ID of object
                                    pointed to
        H5R_type_t ref_type;    IN: Type of reference to create
        H5S_t *space;       IN: Dataspace ID with selection, used for Dataset
                                    Region references.

 RETURNS
    Non-negative on success/Negative on failure
 DESCRIPTION
    Creates a particular type of reference specified with REF_TYPE, in the
    space pointed to by REF.  The LOC_ID and NAME are used to locate the object
    pointed to and the SPACE_ID is used to choose the region pointed to (for
    Dataset Region references).
 GLOBAL VARIABLES
 COMMENTS, BUGS, ASSUMPTIONS
 EXAMPLES
 REVISION LOG
--------------------------------------------------------------------------*/
herr_t
H5R__create(void *_ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type,
    H5S_t *space)
{
    H5G_loc_t	obj_loc;		/* Group hier. location of object */
    H5G_name_t  path;            	/* Object group hier. path */
    H5O_loc_t   oloc;            	/* Object object location */
    hbool_t     obj_found = FALSE;      /* Object location found */
    herr_t ret_value = SUCCEED;         /* Return value */

    FUNC_ENTER_PACKAGE_VOL

    HDassert(_ref);
    HDassert(loc);
    HDassert(name);
    HDassert(ref_type > H5R_BADTYPE && ref_type < H5R_MAXTYPE);

    /* Set up object location to fill in */
    obj_loc.oloc = &oloc;
    obj_loc.path = &path;
    H5G_loc_reset(&obj_loc);

    /* Find the object */
    if(H5G_loc_find(loc, name, &obj_loc) < 0)
        HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, FAIL, "object not found")
    obj_found = TRUE;

    switch (ref_type) {
        case H5R_OBJECT:
        {
            hobj_ref_t *ref = (hobj_ref_t *)_ref; /* Get pointer to correct type of reference struct */

            *ref = obj_loc.oloc->addr;
            break;
        }

        case H5R_DATASET_REGION:
        {
            H5HG_t hobjid;      /* Heap object ID */
            hdset_reg_ref_t *ref = (hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
            hssize_t buf_size;  /* Size of buffer needed to serialize selection */
            uint8_t *p;       /* Pointer to OID to store */
            uint8_t *buf;     /* Buffer to store serialized selection in */
            unsigned heapid_found;  /* Flag for non-zero heap ID found */
            unsigned u;        /* local index */

            /* Set up information for dataset region */

            /* Return any previous heap block to the free list if we are
             * garbage collecting
             */
            if (H5F_GC_REF(loc->oloc->file)) {
                /* Check for an existing heap ID in the reference */
                for (u = 0, heapid_found = 0, p = (uint8_t *)ref; u < H5R_DSET_REG_REF_BUF_SIZE; u++)
                    if (p[u] != 0) {
                        heapid_found = 1;
                        break;
                    }

                if (heapid_found != 0) {
                    /* Return heap block to free list */
                }
            }

            /* Zero the heap ID out, may leak heap space if user is re-using
             * reference and doesn't have garbage collection turned on
             */
            HDmemset(ref, 0, H5R_DSET_REG_REF_BUF_SIZE);

            /* Get the amount of space required to serialize the selection */
            if ((buf_size = H5S_SELECT_SERIAL_SIZE(space, loc->oloc->file)) < 0)
                HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "Invalid amount of space for serializing selection")

            /* Increase buffer size to allow for the dataset OID */
            buf_size += (hssize_t)sizeof(haddr_t);

            /* Allocate the space to store the serialized information */
            H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t);
            if (NULL == (buf = (uint8_t *)H5MM_malloc((size_t)buf_size)))
                HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")

            /* Serialize information for dataset OID into heap buffer */
            p = (uint8_t *)buf;
            H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr);

            /* Serialize the selection into heap buffer */
            if (H5S_SELECT_SERIALIZE(space, &p, loc->oloc->file) < 0)
                HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection")

            /* Save the serialized buffer for later */
            H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t);
            if(H5HG_insert(loc->oloc->file, (size_t)buf_size, buf, &hobjid) < 0)
                HGOTO_ERROR(H5E_REFERENCE, H5E_WRITEERROR, FAIL, "Unable to serialize selection")

            /* Serialize the heap ID and index for storage in the file */
            p = (uint8_t *)ref;
            H5F_addr_encode(loc->oloc->file, &p, hobjid.addr);
            UINT32ENCODE(p, hobjid.idx);

            /* Free the buffer we serialized data in */
            H5MM_xfree(buf);
            break;
        } /* end case H5R_DATASET_REGION */

        case H5R_BADTYPE:
        case H5R_MAXTYPE:
        default:
            HDassert("unknown reference type" && 0);
            HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)")
    } /* end switch */

done:
    if (obj_found)
        H5G_loc_free(&obj_loc);

    FUNC_LEAVE_NOAPI_VOL(ret_value)
}   /* end H5R__create() */