コード例 #1
0
ファイル: H5MF.c プロジェクト: lsubigdata/hdf5ssh
/*-------------------------------------------------------------------------
 * Function:	H5MF_alloc_create
 *
 * Purpose:	Create free space manager of TYPE for the file by creating
 *		a free-space structure
 *
 * Return:	Success:	non-negative
 *		Failure:	negative
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		Jan  8 2008
 *
 *-------------------------------------------------------------------------
 */
static herr_t
H5MF_alloc_create(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type)
{
    const H5FS_section_class_t *classes[] = { /* Free space section classes implemented for file */
        H5MF_FSPACE_SECT_CLS_SIMPLE};
    herr_t ret_value = SUCCEED;         /* Return value */
    H5FS_create_t fs_create; 		/* Free space creation parameters */

    FUNC_ENTER_NOAPI_NOINIT

    /*
     * Check arguments.
     */
    HDassert(f);
    HDassert(f->shared);
    HDassert(type != H5FD_MEM_NOLIST);
    HDassert(!H5F_addr_defined(f->shared->fs_addr[type]));
    HDassert(f->shared->fs_state[type] == H5F_FS_STATE_CLOSED);

    /* Set the free space creation parameters */
    fs_create.client = H5FS_CLIENT_FILE_ID;
    fs_create.shrink_percent = H5MF_FSPACE_SHRINK;
    fs_create.expand_percent = H5MF_FSPACE_EXPAND;
    fs_create.max_sect_addr = 1 + H5VM_log2_gen((uint64_t)f->shared->maxaddr);
    fs_create.max_sect_size = f->shared->maxaddr;

    if(NULL == (f->shared->fs_man[type] = H5FS_create(f, dxpl_id, NULL,
	    &fs_create, NELMTS(classes), classes, f, f->shared->alignment, f->shared->threshold)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space info")


    /* Set the state for the free space manager to "open", if it is now */
    if(f->shared->fs_man[type])
        f->shared->fs_state[type] = H5F_FS_STATE_OPEN;

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF_alloc_create() */
コード例 #2
0
/*-------------------------------------------------------------------------
 * 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(H5F_t *f, H5FD_mem_t map_type, haddr_t addr,
    size_t size, void *buf/*out*/)
{
    H5FD_t *file;                       /* File driver pointer */
    herr_t ret_value = SUCCEED;         /* Return value */

    FUNC_ENTER_PACKAGE

    /* Sanity checks */
    HDassert(f);
    HDassert(buf);

    /* Translate to file driver I/O info object */
    file = f->shared->lf;

    /* Check if this information is in the metadata accumulator */
    if((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 = &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;

                    /* Clear the memory */
                    HDmemset(accum->buf + accum->size, 0, (accum->alloc_size - accum->size));
                } /* end if */

                /* Read the part before the metadata accumulator */
                if(addr < accum->loc) {
                    /* Set the amount to read */
                    H5_CHECKED_ASSIGN(amount_before, size_t, (accum->loc - addr), hsize_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(file, map_type, addr, amount_before, accum->buf) < 0)
                        HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed")
                } /* end if */
コード例 #3
0
ファイル: H5HFiter.c プロジェクト: jpouderoux/VTK
/*-------------------------------------------------------------------------
 * Function:	H5HF_man_iter_start_offset
 *
 * Purpose:	Initialize a block iterator to a particular location, given
 *              an offset in the heap
 *
 * Return:	SUCCEED/FAIL
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		Apr 24 2006
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5HF_man_iter_start_offset(H5HF_hdr_t *hdr, hid_t dxpl_id,
    H5HF_block_iter_t *biter, hsize_t offset)
{
    H5HF_indirect_t *iblock;        /* Indirect block for location context */
    haddr_t iblock_addr;            /* Address of indirect block */
    unsigned iblock_nrows;          /* # of rows in indirect block */
    H5HF_indirect_t *iblock_parent; /* Parent indirect block of location context */
    unsigned iblock_par_entry;      /* Entry within parent indirect block */
    hsize_t curr_offset;        /* Current offset, as adjusted */
    unsigned row;               /* Current row we are on */
    unsigned col;               /* Column in row */
    hbool_t root_block = TRUE;  /* Flag to indicate the current block is the root indirect block */
    herr_t ret_value = SUCCEED;         /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

    /*
     * Check arguments.
     */
    HDassert(biter);
    HDassert(!biter->ready);

    /* Check for empty heap */
    HDassert(offset >= hdr->man_dtable.cparam.start_block_size);

    /* Allocate level structure */
    if(NULL == (biter->curr = H5FL_MALLOC(H5HF_block_loc_t)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for direct block free list section")

/*
1:  <Scan down block offsets for dtable rows until find a row >= offset>
    <Set current location's row, col, entry & size>
    <If row < max_direct_rows>
        <Done>
    <Else - row > max_direct_rows>
        <Create new block level>
        <Link new block level into iterator>
        <Adjust offset for block offset for row>
        <Make new block level the current context>
        <Goto 1>

*/
    do {
        hbool_t did_protect;            /* Whether we protected the indirect block or not */

        /* Walk down the rows in the doubling table until we've found the correct row for the next block */
        for(row = 0; row < hdr->man_dtable.max_root_rows; row++)
            if((offset >= hdr->man_dtable.row_block_off[row]) &&
                    (offset < hdr->man_dtable.row_block_off[row] +
                        (hdr->man_dtable.cparam.width * hdr->man_dtable.row_block_size[row])))
                break;

        /* Adjust offset by row offset */
        curr_offset = offset - hdr->man_dtable.row_block_off[row];

        /* Compute column */
        H5_CHECK_OVERFLOW((curr_offset / hdr->man_dtable.row_block_size[row]), hsize_t, unsigned);
        col = (unsigned)(curr_offset / hdr->man_dtable.row_block_size[row]);

        /* Set the current level's context */
        biter->curr->row = row;
        biter->curr->col = col;
        biter->curr->entry = (row * hdr->man_dtable.cparam.width) + col;

        /* Get the context indirect block's information */
        if(root_block) {
            iblock_addr = hdr->man_dtable.table_addr;
            iblock_nrows = hdr->man_dtable.curr_root_rows;
            iblock_parent = NULL;
            iblock_par_entry = 0;

            /* The root block can't go up further... */
            biter->curr->up = NULL;

            /* Next time through the loop will not be with the root indirect block */
            root_block = FALSE;
        } /* end if */
        else {
            hsize_t child_size;     /* Size of new indirect block to create */

            /* Retrieve the parent information from the previous context location */
            iblock_parent = biter->curr->up->context;
            iblock_par_entry = biter->curr->up->entry;

            /* Look up the address of context indirect block */
            iblock_addr = iblock_parent->ents[iblock_par_entry].addr;

            /* Compute # of rows in context indirect block */
            child_size = hdr->man_dtable.row_block_size[biter->curr->up->row];
            iblock_nrows = (H5VM_log2_gen(child_size) - hdr->man_dtable.first_row_bits) + 1;
        } /* end else */

        /* Load indirect block for this context location */
        if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, iblock_nrows, iblock_parent, iblock_par_entry, FALSE, H5AC__NO_FLAGS_SET, &did_protect)))
            HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")

        /* Make indirect block the context for the current location */
        biter->curr->context = iblock;

        /* Hold the indirect block with the location */
        if(H5HF_iblock_incr(biter->curr->context) < 0)
            HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block")

        /* Release the current indirect block */
        if(H5HF_man_iblock_unprotect(iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0)
            HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
        iblock = NULL;

        /* See if the location falls in a direct block row */
        /* Or, if the offset has just filled up a direct or indirect block */
        if(curr_offset == (col * hdr->man_dtable.row_block_size[row]) || row < hdr->man_dtable.max_direct_rows) {
            HDassert(curr_offset - (col * hdr->man_dtable.row_block_size[row]) == 0);
            break;      /* Done now */
        } /* end if */
        /* Indirect block row */
        else {
            H5HF_block_loc_t *new_loc;      /* Pointer to new block location */

            /* Allocate level structure */
            if(NULL == (new_loc = H5FL_MALLOC(H5HF_block_loc_t)))
                HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for direct block free list section")

            /* Link new level into iterator */
            new_loc->up = biter->curr;

            /* Adjust offset for new level */
            offset = curr_offset - (col * hdr->man_dtable.row_block_size[row]);

            /* Make new block the current context */
            biter->curr = new_loc;
        } /* end else */
    } while(1);       /* Breaks out in middle */

    /* Set flag to indicate block iterator finished initializing */
    biter->ready = TRUE;

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_man_iter_start_offset() */