[svn-r15131] Description:

Finish omnibus chunked dataset I/O refactoring, to separate general
actions on chunked datasets from actions that are specific to using the v1
B-tree index.

	Cleaned up a few bugs and added some additional tests also.

Tested on:
        FreeBSD/32 6.2 (duty) in debug mode
        FreeBSD/64 6.2 (liberty) w/C++ & FORTRAN, in debug mode
        Linux/32 2.6 (kagiso) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe,
                                in debug mode
        Linux/64-amd64 2.6 (smirom) w/default API=1.6.x, w/C++ & FORTRAN,
                                in production mode
        Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN,
                                in production mode
        Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN,
                                w/szip filter, in production mode
        Mac OS X/32 10.5.2 (amazon) in debug mode
        Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode
This commit is contained in:
Quincey Koziol 2008-06-03 14:44:12 -05:00
parent d36f67c0e2
commit 771bae8888
29 changed files with 4814 additions and 4011 deletions

539
src/H5B.c
View File

@ -128,6 +128,13 @@
/* Local Typedefs */
/******************/
/* "user data" for iterating over B-tree (collects B-tree metadata size) */
typedef struct H5B_iter_ud_t {
H5B_info_t *bt_info; /* Information about B-tree */
void *udata; /* Node type's 'udata' for loading & iterator callback */
} H5B_info_ud_t;
/********************/
/* Local Prototypes */
/********************/
@ -168,13 +175,20 @@ H5FL_DEFINE(H5B_t);
/* Library Private Variables */
/*****************************/
/* Declare a free list to manage the H5B_shared_t struct */
H5FL_DEFINE(H5B_shared_t);
/*******************/
/* Local Variables */
/*******************/
/* Declare a free list to manage the H5B_shared_t struct */
H5FL_DEFINE_STATIC(H5B_shared_t);
/* Declare a free list to manage the raw page information */
H5FL_BLK_DEFINE_STATIC(page);
/* Declare a free list to manage the native key offset sequence information */
H5FL_SEQ_DEFINE_STATIC(size_t);
/*-------------------------------------------------------------------------
* Function: H5B_create
@ -1141,6 +1155,145 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
* Function: H5B_iterate_helper
*
* Purpose: Calls the list callback for each leaf node of the
* B-tree, passing it the caller's UDATA structure.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
* matzke@llnl.gov
* Jun 23 1997
*
*-------------------------------------------------------------------------
*/
static herr_t
H5B_iterate_helper(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr,
H5B_operator_t op, void *udata)
{
H5B_t *bt = NULL; /* Pointer to current B-tree node */
uint8_t *native = NULL; /* Array of keys in native format */
haddr_t *child = NULL; /* Array of child pointers */
herr_t ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5B_iterate_helper)
/*
* Check arguments.
*/
HDassert(f);
HDassert(type);
HDassert(H5F_addr_defined(addr));
HDassert(op);
HDassert(udata);
/* Protect the initial/current node */
if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load B-tree node")
if(bt->level > 0) {
haddr_t left_child = bt->child[0]; /* Address of left-most child in node */
/* Release current node */
if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, H5_ITER_ERROR, "unable to release B-tree node")
bt = NULL;
/* Keep following the left-most child until we reach a leaf node. */
if((ret_value = H5B_iterate_helper(f, dxpl_id, type, left_child, op, udata)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, H5_ITER_ERROR, "unable to list B-tree node")
} /* end if */
else {
H5B_shared_t *shared; /* Pointer to shared B-tree info */
unsigned nchildren; /* Number of child pointers */
haddr_t next_addr; /* Address of next node to the right */
/* Get the shared B-tree information */
shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
HDassert(shared);
/* Allocate space for a copy of the native records & child pointers */
if(NULL == (native = H5FL_BLK_MALLOC(native_block, shared->sizeof_keys)))
HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed for shared B-tree native records")
if(NULL == (child = H5FL_SEQ_MALLOC(haddr_t, (size_t)shared->two_k)))
HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed for shared B-tree child addresses")
/* Cache information from this node */
nchildren = bt->nchildren;
next_addr = bt->right;
/* Copy the native keys & child pointers into local arrays */
HDmemcpy(native, bt->native, shared->sizeof_keys);
HDmemcpy(child, bt->child, (nchildren * sizeof(haddr_t)));
/* Release current node */
if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, H5_ITER_ERROR, "unable to release B-tree node")
bt = NULL;
/*
* We've reached the left-most leaf. Now follow the right-sibling
* pointer from leaf to leaf until we've processed all leaves.
*/
ret_value = H5_ITER_CONT;
while(ret_value == H5_ITER_CONT) {
haddr_t *curr_child; /* Pointer to node's child addresses */
uint8_t *curr_native; /* Pointer to node's native keys */
unsigned u; /* Local index variable */
/*
* Perform the iteration operator, which might invoke an
* application callback.
*/
for(u = 0, curr_child = child, curr_native = native; u < nchildren && ret_value == H5_ITER_CONT; u++, curr_child++, curr_native += type->sizeof_nkey) {
ret_value = (*op)(f, dxpl_id, curr_native, *curr_child, curr_native + type->sizeof_nkey, udata);
if(ret_value < 0)
HERROR(H5E_BTREE, H5E_CANTLIST, "iterator function failed");
} /* end for */
/* Check for continuing iteration */
if(ret_value == H5_ITER_CONT) {
/* Check for another node */
if(H5F_addr_defined(next_addr)) {
/* Protect the next node to the right */
addr = next_addr;
if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, H5_ITER_ERROR, "B-tree node")
/* Cache information from this node */
nchildren = bt->nchildren;
next_addr = bt->right;
/* Copy the native keys & child pointers into local arrays */
HDmemcpy(native, bt->native, shared->sizeof_keys);
HDmemcpy(child, bt->child, nchildren * sizeof(haddr_t));
/* Unprotect node */
if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, H5_ITER_ERROR, "unable to release B-tree node")
bt = NULL;
} /* end if */
else
/* Exit loop */
break;
} /* end if */
} /* end while */
} /* end else */
done:
if(bt && H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_BTREE, H5E_PROTECT, H5_ITER_ERROR, "unable to release B-tree node")
if(native)
(void)H5FL_BLK_FREE(native_block, native);
if(child)
(void)H5FL_SEQ_FREE(haddr_t, child);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B_iterate_helper() */
/*-------------------------------------------------------------------------
* Function: H5B_iterate
@ -1154,27 +1307,12 @@ done:
* matzke@llnl.gov
* Jun 23 1997
*
* Modifications:
* Robb Matzke, 1999-04-21
* The key values are passed to the function which is called.
*
* Robb Matzke, 1999-07-28
* The ADDR argument is passed by value.
*
* Quincey Koziol, 2002-04-22
* Changed callback to function pointer from static function
*
* John Mainzer, 6/10/05
* Modified the function to use the new dirtied parameter of
* of H5AC_unprotect() instead of modifying the is_dirty
* field of the cache info.
*
*-------------------------------------------------------------------------
*/
herr_t
H5B_iterate(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, H5B_operator_t op, haddr_t addr, void *udata)
H5B_iterate(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr,
H5B_operator_t op, void *udata)
{
H5B_t *bt = NULL; /* Pointer to current B-tree node */
herr_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5B_iterate, FAIL)
@ -1184,76 +1322,13 @@ H5B_iterate(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, H5B_operator_t op,
*/
HDassert(f);
HDassert(type);
HDassert(op);
HDassert(H5F_addr_defined(addr));
HDassert(op);
HDassert(udata);
/* Protect the initial/current node */
if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree node")
if(bt->level > 0) {
/* Keep following the left-most child until we reach a leaf node. */
if((ret_value = H5B_iterate(f, dxpl_id, type, op, bt->child[0], udata)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "unable to list B-tree node")
} /* end if */
else {
/*
* We've reached the left-most leaf. Now follow the right-sibling
* pointer from leaf to leaf until we've processed all leaves.
*/
ret_value = H5_ITER_CONT;
while(bt && ret_value == H5_ITER_CONT) {
haddr_t *child; /* Pointer to node's child addresses */
uint8_t *key; /* Pointer to node's native keys */
unsigned u; /* Local index variable */
/*
* Perform the iteration operator, which might invoke an
* application callback.
*/
for(u = 0, child = bt->child, key = bt->native; u < bt->nchildren && ret_value == H5_ITER_CONT; u++, child++, key += type->sizeof_nkey) {
ret_value = (*op)(f, dxpl_id, key, *child, key + type->sizeof_nkey, udata);
if(ret_value < 0)
HERROR(H5E_BTREE, H5E_CANTLIST, "iterator function failed");
} /* end for */
/* Check for continuing iteration */
if(ret_value == H5_ITER_CONT) {
H5B_t *next_bt; /* Pointer to next B-tree node */
haddr_t next_addr; /* Address of next node to iterate over */
/* Protect the next node to the right, if there is one */
if(H5F_addr_defined(bt->right)) {
next_addr = bt->right;
if(NULL == (next_bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, next_addr, type, udata, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "B-tree node")
} /* end if */
else {
next_addr = HADDR_UNDEF;
next_bt = NULL;
} /* end if */
/* Unprotect this node */
if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0) {
if(next_bt) {
HDassert(H5F_addr_defined(next_addr));
if(H5AC_unprotect(f, dxpl_id, H5AC_BT, next_addr, next_bt, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node")
} /* end if */
HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node")
} /* end if */
/* Advance to the next node */
bt = next_bt;
addr = next_addr;
} /* end if */
} /* end for */
} /* end else */
done:
if(bt && H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node")
/* Iterate over the B-tree records */
if((ret_value = H5B_iterate_helper(f, dxpl_id, type, addr, op, udata)) < 0)
HERROR(H5E_BTREE, H5E_BADITER, "B-tree iteration failed");
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B_iterate() */
@ -1704,59 +1779,99 @@ done:
/*-------------------------------------------------------------------------
* Function: H5B_nodesize
* Function: H5B_shared_new
*
* Purpose: Returns the number of bytes needed for this type of
* B-tree node. The size is the size of the header plus
* enough space for 2t child pointers and 2t+1 keys.
* Purpose: Allocates & constructs a shared v1 B-tree struct for client.
*
* If TOTAL_NKEY_SIZE is non-null, what it points to will
* be initialized with the total number of bytes required to
* hold all the key values in native order.
* Return: Success: non-NULL pointer to struct allocated
* Failure: NULL
*
* Return: Success: Size of node in file.
*
* Failure: 0
*
* Programmer: Robb Matzke
* matzke@llnl.gov
* Jul 3 1997
*
* Modifications:
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* May 27 2008
*
*-------------------------------------------------------------------------
*/
size_t
H5B_nodesize(const H5F_t *f, const H5B_shared_t *shared,
size_t *total_nkey_size/*out*/)
H5B_shared_t *
H5B_shared_new(const H5F_t *f, const H5B_class_t *type, size_t sizeof_rkey)
{
size_t size;
H5B_shared_t *shared; /* New shared B-tree struct */
size_t u; /* Local index variable */
H5B_shared_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B_nodesize)
FUNC_ENTER_NOAPI(H5B_shared_new, NULL)
/*
* Check arguments.
*/
assert(f);
assert(shared);
assert(shared->two_k > 0);
assert(shared->sizeof_rkey > 0);
HDassert(type);
/*
* Total native key size.
*/
if (total_nkey_size)
*total_nkey_size = (shared->two_k + 1) * shared->type->sizeof_nkey;
/* Allocate space for the shared structure */
if(NULL == (shared = H5FL_MALLOC(H5B_shared_t)))
HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "memory allocation failed for shared B-tree info")
/*
* Total node size.
*/
size = (H5B_SIZEOF_HDR(f) + /*node header */
/* Set up the "global" information for this file's groups */
shared->type = type;
shared->two_k = 2 * H5F_KVALUE(f, type);
shared->sizeof_rkey = sizeof_rkey;
HDassert(shared->sizeof_rkey);
shared->sizeof_keys = (shared->two_k + 1) * type->sizeof_nkey;
shared->sizeof_rnode = (H5B_SIZEOF_HDR(f) + /*node header */
shared->two_k * H5F_SIZEOF_ADDR(f) + /*child pointers */
(shared->two_k + 1) * shared->sizeof_rkey); /*keys */
HDassert(shared->sizeof_rnode);
FUNC_LEAVE_NOAPI(size)
}
/* Allocate shared buffers */
if(NULL == (shared->page = H5FL_BLK_MALLOC(page, shared->sizeof_rnode)))
HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree page")
#ifdef H5_CLEAR_MEMORY
HDmemset(shared->page, 0, shared->sizeof_rnode);
#endif /* H5_CLEAR_MEMORY */
if(NULL == (shared->nkey = H5FL_SEQ_MALLOC(size_t, (size_t)(2 * H5F_KVALUE(f, type) + 1))))
HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree page")
/* Initialize the offsets into the native key buffer */
for(u = 0; u < (2 * H5F_KVALUE(f, type) + 1); u++)
shared->nkey[u] = u * type->sizeof_nkey;
/* Set return value */
ret_value = shared;
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B_shared_new() */
/*-------------------------------------------------------------------------
* Function: H5B_shared_free
*
* Purpose: Free B-tree shared info
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* Tuesday, May 27, 2008
*
*-------------------------------------------------------------------------
*/
herr_t
H5B_shared_free(void *_shared)
{
H5B_shared_t *shared = (H5B_shared_t *)_shared;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B_shared_free)
/* Free the raw B-tree node buffer */
(void)H5FL_BLK_FREE(page, shared->page);
/* Free the B-tree native key offsets buffer */
(void)H5FL_SEQ_FREE(size_t, shared->nkey);
/* Free the shared B-tree info */
(void)H5FL_FREE(H5B_shared_t, shared);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5B_shared_free() */
/*-------------------------------------------------------------------------
@ -1827,12 +1942,109 @@ done:
/*-------------------------------------------------------------------------
* Function: H5B_iterate_size
* Function: H5B_get_info_helper
*
* Purpose: Walks the B-tree nodes, getting information for all of them.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* Jun 3 2008
*
*-------------------------------------------------------------------------
*/
static herr_t
H5B_get_info_helper(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr,
const H5B_info_ud_t *info_udata)
{
H5B_t *bt = NULL; /* Pointer to current B-tree node */
H5B_shared_t *shared; /* Pointer to shared B-tree info */
unsigned level; /* Node level */
size_t sizeof_rnode; /* Size of raw (disk) node */
haddr_t next_addr; /* Address of next node to the right */
haddr_t left_child; /* Address of left-most child in node */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5B_get_info_helper)
/*
* Check arguments.
*/
HDassert(f);
HDassert(type);
HDassert(H5F_addr_defined(addr));
HDassert(info_udata);
HDassert(info_udata->bt_info);
HDassert(info_udata->udata);
/* Protect the initial/current node */
if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, info_udata->udata, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree node")
/* Get the shared B-tree information */
shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared);
HDassert(shared);
/* Get the raw node size for iteration */
sizeof_rnode = shared->sizeof_rnode;
/* Cache information from this node */
left_child = bt->child[0];
next_addr = bt->right;
level = bt->level;
/* Update B-tree info */
info_udata->bt_info->size += sizeof_rnode;
info_udata->bt_info->num_nodes++;
/* Release current node */
if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node")
bt = NULL;
/*
* Follow the right-sibling pointer from node to node until we've
* processed all nodes.
*/
while(H5F_addr_defined(next_addr)) {
/* Protect the next node to the right */
addr = next_addr;
if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, info_udata->udata, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "B-tree node")
/* Cache information from this node */
next_addr = bt->right;
/* Update B-tree info */
info_udata->bt_info->size += sizeof_rnode;
info_udata->bt_info->num_nodes++;
/* Unprotect node */
if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node")
bt = NULL;
} /* end while */
/* Check for another "row" of B-tree nodes to iterate over */
if(level > 0) {
/* Keep following the left-most child until we reach a leaf node. */
if(H5B_get_info_helper(f, dxpl_id, type, left_child, info_udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "unable to list B-tree node")
} /* end if */
done:
if(bt && H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B_get_info_helper() */
/*-------------------------------------------------------------------------
* Function: H5B_get_info
*
* Purpose: Return the amount of storage used for the btree.
* Keep following the left-most child until reaching the leaf node.
* For each level, gather storage for all the nodes on that level.
* For 0 level, also gather storage for the SNODs.
*
* Return: Non-negative on success/Negative on failure
*
@ -1842,76 +2054,43 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
H5B_iterate_size(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type,
H5B_operator_t op, haddr_t addr, H5B_info_ud_t *bh_udata)
H5B_get_info(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr,
H5B_info_t *bt_info, H5B_operator_t op, void *udata)
{
H5B_t *bt = NULL; /* Pointer to current B-tree node */
H5B_shared_t *shared; /* Pointer to shared B-tree info */
H5B_info_ud_t info_udata; /* User-data for B-tree size iteration */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B_iterate_size, FAIL)
FUNC_ENTER_NOAPI(H5B_get_info, FAIL)
/*
* Check arguments.
*/
HDassert(f);
HDassert(type);
HDassert(bt_info);
HDassert(H5F_addr_defined(addr));
HDassert(bh_udata);
HDassert(udata);
/* Protect the initial/current node */
if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, bh_udata->udata, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree node")
shared = H5RC_GET_OBJ(bt->rc_shared);
HDassert(shared);
/* Portably initialize B-tree info struct */
HDmemset(bt_info, 0, sizeof(*bt_info));
/* Keep following the left-most child until we reach a leaf node. */
if(bt->level > 0)
if(H5B_iterate_size(f, dxpl_id, type, op, bt->child[0], bh_udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "unable to list B-tree node")
/* Set up internal user-data for the B-tree 'get info' helper routine */
info_udata.bt_info = bt_info;
info_udata.udata = udata;
/* Iterate through all nodes at this level of the tree */
while(bt) {
haddr_t next_addr; /* Address of next node to iterate over */
/* Iterate over the B-tree nodes */
if(H5B_get_info_helper(f, dxpl_id, type, addr, &info_udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_BADITER, FAIL, "B-tree iteration failed")
/* for leaf node with callback, add in the space pointed to by each key */
/* (currently only used for symbol table nodes) */
if(bt->level == 0 && op) {
haddr_t *child; /* Pointer to node's child addresses */
uint8_t *key; /* Pointer to node's native keys */
unsigned u; /* Local index variable */
for(u = 0, child = bt->child, key = bt->native; u < bt->nchildren; u++, child++, key += type->sizeof_nkey)
if((*op)(f, dxpl_id, key, *child, key + type->sizeof_nkey, bh_udata->btree_size) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "iterator function failed")
} /* end if */
/* count the size of this node */
*(bh_udata->btree_size) += H5B_nodesize(f, shared, NULL);
/* Get the address of the next node to the right */
next_addr = bt->right;
/* Unprotect current node */
if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node")
/* Protect bt's next node to the right, if there is one */
if(H5F_addr_defined(next_addr)) {
addr = next_addr;
if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, bh_udata->udata, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "B-tree node")
} /* end if */
else
bt = NULL;
} /* end while */
/* Iterate over the B-tree records, making any "leaf" callbacks */
/* (Only if operator defined) */
if(op)
if((ret_value = H5B_iterate_helper(f, dxpl_id, type, addr, op, udata)) < 0)
HERROR(H5E_BTREE, H5E_BADITER, "B-tree iteration failed");
done:
if(bt && H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B_iterate_size() */
} /* end H5B_get_info() */
/*-------------------------------------------------------------------------

View File

@ -397,10 +397,8 @@ static herr_t
H5B_compute_size(const H5F_t *f, const H5B_t *bt, size_t *size_ptr)
{
H5B_shared_t *shared; /* Pointer to shared B-tree info */
size_t size;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5B_compute_size)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B_compute_size)
/* check arguments */
HDassert(f);
@ -411,13 +409,8 @@ H5B_compute_size(const H5F_t *f, const H5B_t *bt, size_t *size_ptr)
HDassert(shared->type);
HDassert(size_ptr);
/* Check node's size */
if ((size = H5B_nodesize(f, shared, NULL)) == 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGETSIZE, FAIL, "H5B_nodesize() failed")
/* Set size value */
*size_ptr = size;
*size_ptr = shared->sizeof_rnode;
done:
FUNC_LEAVE_NOAPI(ret_value)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5B_compute_size() */

View File

@ -74,6 +74,7 @@ H5FL_EXTERN(H5B_t);
/******************************/
/* Package Private Prototypes */
/******************************/
herr_t H5B_dest(H5F_t *f, H5B_t *b);
H5_DLL herr_t H5B_dest(H5F_t *f, H5B_t *b);
#endif /*_H5Bpkg_H*/

View File

@ -124,42 +124,40 @@ typedef struct H5B_class_t {
herr_t (*debug_key)(FILE*, H5F_t*, hid_t, int, int, const void*, const void*);
} H5B_class_t;
/* "user data" for iterating over B-tree when collecting B-tree metadata size */
typedef struct H5B_info_ud_t {
void *udata; /* Node type's 'udata' for loading */
hsize_t *btree_size; /* Accumulated size for B-tree metadata */
} H5B_info_ud_t;
/* Information about B-tree */
typedef struct H5B_info_t {
hsize_t size; /* Size of B-tree nodes */
hsize_t num_nodes; /* Number of B-tree nodes */
} H5B_info_t;
/*****************************/
/* Library-private Variables */
/*****************************/
/* Declare a free list to manage the H5B_shared_t struct */
H5FL_EXTERN(H5B_shared_t);
/***************************************/
/* Library-private Function Prototypes */
/***************************************/
H5_DLL size_t H5B_nodesize(const H5F_t *f, const H5B_shared_t *shared,
size_t *total_nkey_size);
H5_DLL herr_t H5B_create(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, void *udata,
haddr_t *addr_p/*out*/);
H5_DLL herr_t H5B_find(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr,
void *udata);
H5_DLL herr_t H5B_insert(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr,
void *udata);
H5_DLL herr_t H5B_iterate(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, H5B_operator_t
op, haddr_t addr, void *udata);
H5_DLL herr_t H5B_iterate_size(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, H5B_operator_t
op, haddr_t addr, H5B_info_ud_t *bh_udata);
H5_DLL herr_t H5B_remove(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr,
void *udata);
H5_DLL herr_t H5B_delete(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr,
void *udata);
H5_DLL herr_t H5B_create(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type,
void *udata, haddr_t *addr_p/*out*/);
H5_DLL herr_t H5B_find(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type,
haddr_t addr, void *udata);
H5_DLL herr_t H5B_insert(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type,
haddr_t addr, void *udata);
H5_DLL herr_t H5B_iterate(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type,
haddr_t addr, H5B_operator_t op, void *udata);
H5_DLL herr_t H5B_get_info(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type,
haddr_t addr, H5B_info_t *bt_info, H5B_operator_t op, void *udata);
H5_DLL herr_t H5B_remove(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type,
haddr_t addr, void *udata);
H5_DLL herr_t H5B_delete(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type,
haddr_t addr, void *udata);
H5_DLL H5B_shared_t *H5B_shared_new(const H5F_t *f, const H5B_class_t *type,
size_t sizeof_rkey);
H5_DLL herr_t H5B_shared_free(void *_shared);
H5_DLL herr_t H5B_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream,
int indent, int fwidth, const H5B_class_t *type,
void *udata);
int indent, int fwidth, const H5B_class_t *type, void *udata);
#endif /* _H5Bprivate_H */

File diff suppressed because it is too large Load Diff

View File

@ -57,6 +57,8 @@
/********************/
/* Layout operation callbacks */
static herr_t H5D_compact_new(H5F_t *f, hid_t dxpl_id, H5D_t *dset,
const H5P_genplist_t *dc_plist);
static herr_t H5D_compact_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
H5D_chunk_map_t *cm);
@ -74,6 +76,7 @@ static ssize_t H5D_compact_writevv(const H5D_io_info_t *io_info,
/* Compact storage layout I/O ops */
const H5D_layout_ops_t H5D_LOPS_COMPACT[1] = {{
H5D_compact_new,
H5D_compact_io_init,
H5D_contig_read,
H5D_contig_write,
@ -147,6 +150,53 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_compact_fill() */
/*-------------------------------------------------------------------------
* Function: H5D_compact_new
*
* Purpose: Constructs new compact layout information for dataset
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* Thursday, May 22, 2008
*
*-------------------------------------------------------------------------
*/
/* ARGSUSED */
static herr_t
H5D_compact_new(H5F_t *f, hid_t UNUSED dxpl_id, H5D_t *dset,
const H5P_genplist_t UNUSED *dc_plist)
{
hssize_t tmp_size; /* Temporary holder for raw data size */
hsize_t comp_data_size; /* Size of compact data */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_compact_new)
/* Sanity checks */
HDassert(f);
HDassert(dset);
HDassert(dc_plist);
/*
* Compact dataset is stored in dataset object header message of
* layout.
*/
tmp_size = H5S_GET_EXTENT_NPOINTS(dset->shared->space) * H5T_get_size(dset->shared->type);
H5_ASSIGN_OVERFLOW(dset->shared->layout.u.compact.size, tmp_size, hssize_t, size_t);
/* Verify data size is smaller than maximum header message size
* (64KB) minus other layout message fields.
*/
comp_data_size = H5O_MESG_MAX_SIZE - H5O_layout_meta_size(f, &(dset->shared->layout));
if(dset->shared->layout.u.compact.size > comp_data_size)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "compact dataset size is bigger than header message maximum size")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_compact_new() */
/*-------------------------------------------------------------------------
* Function: H5D_compact_io_init

View File

@ -61,6 +61,8 @@
/********************/
/* Layout operation callbacks */
static herr_t H5D_contig_new(H5F_t *f, hid_t dxpl_id, H5D_t *dset,
const H5P_genplist_t *dc_plist);
static herr_t H5D_contig_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
H5D_chunk_map_t *cm);
@ -76,6 +78,7 @@ static herr_t H5D_contig_write_one(H5D_io_info_t *io_info, hsize_t offset,
/* Contiguous storage layout I/O ops */
const H5D_layout_ops_t H5D_LOPS_CONTIG[1] = {{
H5D_contig_new,
H5D_contig_io_init,
H5D_contig_read,
H5D_contig_write,
@ -102,7 +105,7 @@ H5FL_BLK_EXTERN(type_conv);
/*-------------------------------------------------------------------------
* Function: H5D_contig_create
* Function: H5D_contig_alloc
*
* Purpose: Allocate file space for a contiguously stored dataset
*
@ -114,11 +117,11 @@ H5FL_BLK_EXTERN(type_conv);
*-------------------------------------------------------------------------
*/
herr_t
H5D_contig_create(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout /*out */ )
H5D_contig_alloc(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout /*out */ )
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_contig_create, FAIL)
FUNC_ENTER_NOAPI(H5D_contig_alloc, FAIL)
/* check args */
HDassert(f);
@ -130,7 +133,7 @@ H5D_contig_create(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout /*out */ )
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_contig_create */
} /* end H5D_contig_alloc */
/*-------------------------------------------------------------------------
@ -353,6 +356,63 @@ H5D_contig_get_addr(const H5D_t *dset)
FUNC_LEAVE_NOAPI(dset->shared->layout.u.contig.addr)
} /* end H5D_contig_get_addr */
/*-------------------------------------------------------------------------
* Function: H5D_contig_new
*
* Purpose: Constructs new contiguous layout information for dataset
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* Thursday, May 22, 2008
*
*-------------------------------------------------------------------------
*/
/* ARGSUSED */
static herr_t
H5D_contig_new(H5F_t *f, hid_t UNUSED dxpl_id, H5D_t *dset,
const H5P_genplist_t UNUSED *dc_plist)
{
const H5T_t *type = dset->shared->type; /* Convenience pointer to dataset's datatype */
hssize_t tmp_size; /* Temporary holder for raw data size */
hsize_t dim[H5O_LAYOUT_NDIMS]; /* Current size of data in elements */
hsize_t max_dim[H5O_LAYOUT_NDIMS]; /* Maximum size of data in elements */
int ndims; /* Rank of dataspace */
int i; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_contig_new)
/* Sanity checks */
HDassert(f);
HDassert(dset);
/*
* The maximum size of the dataset cannot exceed the storage size.
* Also, only the slowest varying dimension of a simple data space
* can be extendible (currently only for external data storage).
*/
dset->shared->layout.u.contig.addr = HADDR_UNDEF; /* Initialize to no address */
/* Check for invalid dataset dimensions */
if((ndims = H5S_get_simple_extent_dims(dset->shared->space, dim, max_dim)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize contiguous storage")
for(i = 0; i < ndims; i++)
if(max_dim[i] > dim[i])
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "extendible contiguous non-external dataset")
/* Compute the total size of dataset */
tmp_size = H5S_GET_EXTENT_NPOINTS(dset->shared->space) * H5T_get_size(type);
H5_ASSIGN_OVERFLOW(dset->shared->layout.u.contig.size, tmp_size, hssize_t, hsize_t);
/* Get the sieve buffer size for this dataset */
dset->shared->cache.contig.sieve_buf_size = H5F_SIEVE_BUF_SIZE(f);
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_contig_new() */
/*-------------------------------------------------------------------------
* Function: H5D_contig_io_init
@ -1137,7 +1197,7 @@ H5D_contig_copy(H5F_t *f_src, const H5O_layout_t *layout_src, H5F_t *f_dst,
HDassert(dt_src);
/* Allocate space for destination raw data */
if(H5D_contig_create(f_dst, dxpl_id, layout_dst) < 0)
if(H5D_contig_alloc(f_dst, dxpl_id, layout_dst) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to allocate contiguous storage")
/* Set up number of bytes to copy, and initial buffer size */

View File

@ -113,7 +113,7 @@ H5Ddebug(hid_t dset_id)
/* Print B-tree information */
if(H5D_CHUNKED == dset->shared->layout.type)
(void)H5D_istore_dump_btree(dset->oloc.file, H5AC_dxpl_id, stdout, dset->shared->layout.u.chunk.ndims, dset->shared->layout.u.chunk.addr);
(void)H5D_chunk_dump_index(dset, H5AC_dxpl_id, stdout);
else if(H5D_CONTIGUOUS == dset->shared->layout.type)
HDfprintf(stdout, " %-10s %a\n", "Address:", dset->shared->layout.u.contig.addr);

View File

@ -346,13 +346,13 @@ H5D_extend(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id)
if(changed) {
/* Update the index values for the cached chunks for this dataset */
if(H5D_CHUNKED == dataset->shared->layout.type)
if(H5D_istore_update_cache(dataset, dxpl_id) < 0)
if(H5D_chunk_update_cache(dataset, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update cached chunk indices")
/* Allocate space for the new parts of the dataset, if appropriate */
fill = &dataset->shared->dcpl_cache.fill;
if(fill->alloc_time == H5D_ALLOC_TIME_EARLY)
if(H5D_alloc_storage(dataset->oloc.file, dxpl_id, dataset, H5D_ALLOC_EXTEND, FALSE) < 0)
if(H5D_alloc_storage(dataset, dxpl_id, H5D_ALLOC_EXTEND, FALSE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value")
/* Mark the dataspace as dirty, for later writing to the file */

View File

@ -49,6 +49,8 @@
/********************/
/* Layout operation callbacks */
static herr_t H5D_efl_new(H5F_t *f, hid_t dxpl_id, H5D_t *dset,
const H5P_genplist_t *dc_plist);
static herr_t H5D_efl_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
H5D_chunk_map_t *cm);
@ -72,6 +74,7 @@ static herr_t H5D_efl_write(const H5O_efl_t *efl, haddr_t addr, size_t size,
/* External File List (EFL) storage layout I/O ops */
const H5D_layout_ops_t H5D_LOPS_EFL[1] = {{
H5D_efl_new,
H5D_efl_io_init,
H5D_contig_read,
H5D_contig_write,
@ -90,6 +93,77 @@ const H5D_layout_ops_t H5D_LOPS_EFL[1] = {{
/*******************/
/*-------------------------------------------------------------------------
* Function: H5D_efl_new
*
* Purpose: Constructs new EFL layout information for dataset
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* Thursday, May 22, 2008
*
*-------------------------------------------------------------------------
*/
static herr_t
H5D_efl_new(H5F_t *f, hid_t UNUSED dxpl_id, H5D_t *dset,
const H5P_genplist_t *dc_plist)
{
const H5T_t *type = dset->shared->type; /* Convenience pointer to dataset's datatype */
hsize_t dim[H5O_LAYOUT_NDIMS]; /* Current size of data in elements */
hsize_t max_dim[H5O_LAYOUT_NDIMS]; /* Maximum size of data in elements */
hssize_t tmp_size; /* Temporary holder for raw data size */
hsize_t max_points; /* Maximum elements */
hsize_t max_storage; /* Maximum storage size */
int ndims; /* Rank of dataspace */
int i; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_efl_new)
/* Sanity checks */
HDassert(f);
HDassert(dset);
HDassert(dc_plist);
/*
* The maximum size of the dataset cannot exceed the storage size.
* Also, only the slowest varying dimension of a simple data space
* can be extendible (currently only for external data storage).
*/
dset->shared->layout.u.contig.addr = HADDR_UNDEF; /* Initialize to no address */
/* Check for invalid dataset dimensions */
if((ndims = H5S_get_simple_extent_dims(dset->shared->space, dim, max_dim)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize contiguous storage")
for(i = 1; i < ndims; i++)
if(max_dim[i] > dim[i])
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "only the first dimension can be extendible")
/* Check for storage overflows */
max_points = H5S_get_npoints_max(dset->shared->space);
max_storage = H5O_efl_total_size(&dset->shared->dcpl_cache.efl);
if(H5S_UNLIMITED == max_points) {
if(H5O_EFL_UNLIMITED != max_storage)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unlimited data space but finite storage")
} /* end if */
else if(max_points * H5T_get_size(type) < max_points)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data space * type size overflowed")
else if(max_points * H5T_get_size(type) > max_storage)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data space size exceeds external storage size")
/* Compute the total size of dataset */
tmp_size = H5S_GET_EXTENT_NPOINTS(dset->shared->space) * H5T_get_size(type);
H5_ASSIGN_OVERFLOW(dset->shared->layout.u.contig.size, tmp_size, hssize_t, hsize_t);
/* Get the sieve buffer size for this dataset */
dset->shared->cache.contig.sieve_buf_size = H5F_SIEVE_BUF_SIZE(f);
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_efl_new() */
/*-------------------------------------------------------------------------
* Function: H5D_efl_io_init

View File

@ -710,17 +710,21 @@ H5D_set_io_ops(H5D_t *dataset)
switch(dataset->shared->layout.type) {
case H5D_CONTIGUOUS:
if(dataset->shared->dcpl_cache.efl.nused > 0)
dataset->shared->layout_ops = H5D_LOPS_EFL;
dataset->shared->layout.ops = H5D_LOPS_EFL;
else
dataset->shared->layout_ops = H5D_LOPS_CONTIG;
dataset->shared->layout.ops = H5D_LOPS_CONTIG;
break;
case H5D_CHUNKED:
dataset->shared->layout_ops = H5D_LOPS_CHUNK;
dataset->shared->layout.ops = H5D_LOPS_CHUNK;
/* Set the chunk operations */
/* (Only "istore" indexing type currently supported */
dataset->shared->layout.u.chunk.ops = H5D_COPS_ISTORE;
break;
case H5D_COMPACT:
dataset->shared->layout_ops = H5D_LOPS_COMPACT;
dataset->shared->layout.ops = H5D_LOPS_COMPACT;
break;
default:
@ -831,6 +835,7 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset)
/* Create an object header for the dataset */
if(H5O_create(file, dxpl_id, ohdr_size, dset->shared->dcpl_id, oloc/*out*/) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset object header")
HDassert(file == dset->oloc.file);
/* Get a pointer to the object header itself */
if((oh = H5O_protect(oloc, dxpl_id)) == NULL)
@ -877,7 +882,7 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset)
* allocation until later.
*/
if(fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY)
if(H5D_alloc_storage(file, dxpl_id, dset, H5D_ALLOC_CREATE, FALSE) < 0)
if(H5D_alloc_storage(dset, dxpl_id, H5D_ALLOC_CREATE, FALSE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage")
/* Update external storage message, if it's used */
@ -1000,13 +1005,10 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
{
const H5T_t *type; /* Datatype for dataset */
H5D_t *new_dset = NULL;
int i, ndims;
unsigned chunk_ndims = 0; /* Dimensionality of chunk */
H5P_genplist_t *dc_plist = NULL; /* New Property list */
hbool_t has_vl_type = FALSE; /* Flag to indicate a VL-type for dataset */
hbool_t chunk_init = FALSE; /* Flag to indicate that chunk information was initialized */
hbool_t layout_init = FALSE; /* Flag to indicate that chunk information was initialized */
H5G_loc_t dset_loc; /* Dataset location */
unsigned u; /* Local index variable */
H5D_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5D_create, NULL)
@ -1101,10 +1103,6 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
if(IS_H5FD_MPI(file) && pline->nused > 0)
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "Parallel I/O does not support filters yet")
/* Chunked datasets are non-default, so retrieve their info here */
if(H5P_get(dc_plist, H5D_CRT_CHUNK_DIM_NAME, &chunk_ndims) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve chunk dimensions")
/* Get the dataset's external file list information */
if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &new_dset->shared->dcpl_cache.efl) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve external file list")
@ -1125,140 +1123,17 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
if(IS_H5FD_MPI(file))
new_dset->shared->dcpl_cache.fill.alloc_time = H5D_ALLOC_TIME_EARLY;
switch(new_dset->shared->layout.type) {
case H5D_CONTIGUOUS:
{
hssize_t tmp_size; /* Temporary holder for raw data size */
hsize_t dim[H5O_LAYOUT_NDIMS]; /* Current size of data in elements */
hsize_t max_dim[H5O_LAYOUT_NDIMS]; /* Maximum size of data in elements */
/*
* The maximum size of the dataset cannot exceed the storage size.
* Also, only the slowest varying dimension of a simple data space
* can be extendible (currently only for external data storage).
*/
new_dset->shared->layout.u.contig.addr = HADDR_UNDEF; /* Initialize to no address */
if((ndims = H5S_get_simple_extent_dims(new_dset->shared->space, dim, max_dim)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize contiguous storage")
for(i = 1; i < ndims; i++)
if(max_dim[i] > dim[i])
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "only the first dimension can be extendible")
if(new_dset->shared->dcpl_cache.efl.nused > 0) {
hsize_t max_points = H5S_get_npoints_max(new_dset->shared->space);
hsize_t max_storage = H5O_efl_total_size(&new_dset->shared->dcpl_cache.efl);
if(H5S_UNLIMITED == max_points) {
if(H5O_EFL_UNLIMITED != max_storage)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unlimited data space but finite storage")
} else if(max_points * H5T_get_size(type) < max_points) {
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "data space * type size overflowed")
} else if(max_points * H5T_get_size(type) > max_storage) {
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "data space size exceeds external storage size")
}
} /* end if */
else {
if(ndims > 0 && max_dim[0] > dim[0])
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "extendible contiguous non-external dataset")
} /* end else */
/* Compute the total size of a chunk */
tmp_size = H5S_GET_EXTENT_NPOINTS(new_dset->shared->space) * H5T_get_size(new_dset->shared->type);
H5_ASSIGN_OVERFLOW(new_dset->shared->layout.u.contig.size, tmp_size, hssize_t, hsize_t);
/* Get the sieve buffer size for this dataset */
new_dset->shared->cache.contig.sieve_buf_size = H5F_SIEVE_BUF_SIZE(file);
} /* end case */
break;
case H5D_CHUNKED:
{
hsize_t max_dim[H5O_LAYOUT_NDIMS]; /* Maximum size of data in elements */
uint64_t chunk_size; /* Size of chunk in bytes */
/* Set up layout information */
if((ndims = H5S_GET_EXTENT_NDIMS(new_dset->shared->space)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "unable to get rank")
new_dset->shared->layout.u.chunk.ndims = (unsigned)ndims + 1;
HDassert((unsigned)(new_dset->shared->layout.u.chunk.ndims) <= NELMTS(new_dset->shared->layout.u.chunk.dim));
/* Initialize to no address */
new_dset->shared->layout.u.chunk.addr = HADDR_UNDEF;
/*
* Chunked storage allows any type of data space extension, so we
* don't even bother checking.
*/
if(chunk_ndims != (unsigned)ndims)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "dimensionality of chunks doesn't match the data space")
if(new_dset->shared->dcpl_cache.efl.nused > 0)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "external storage not supported with chunked layout")
/*
* The chunk size of a dimension with a fixed size cannot exceed
* the maximum dimension size
*/
if(H5P_get(dc_plist, H5D_CRT_CHUNK_SIZE_NAME, new_dset->shared->layout.u.chunk.dim) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve chunk size")
new_dset->shared->layout.u.chunk.dim[new_dset->shared->layout.u.chunk.ndims-1] = H5T_get_size(new_dset->shared->type);
if(H5S_get_simple_extent_dims(new_dset->shared->space, NULL, max_dim) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to query maximum dimensions")
for(u = 0; u < new_dset->shared->layout.u.chunk.ndims - 1; u++)
if(max_dim[u] != H5S_UNLIMITED && max_dim[u] < new_dset->shared->layout.u.chunk.dim[u])
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "chunk size must be <= maximum dimension size for fixed-sized dimensions")
/* Compute the total size of a chunk */
/* (Use 64-bit value to ensure that we can detect >4GB chunks) */
for(u = 1, chunk_size = (uint64_t)new_dset->shared->layout.u.chunk.dim[0]; u < new_dset->shared->layout.u.chunk.ndims; u++)
chunk_size *= (uint64_t)new_dset->shared->layout.u.chunk.dim[u];
/* Check for chunk larger than can be represented in 32-bits */
/* (Chunk size is encoded in 32-bit value in v1 B-tree records) */
if(chunk_size > (uint64_t)0xffffffff)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "chunk size must be < 4GB")
/* Retain computed chunk size */
H5_ASSIGN_OVERFLOW(new_dset->shared->layout.u.chunk.size, chunk_size, uint64_t, uint32_t);
/* Initialize the chunk cache for the dataset */
if(H5D_istore_init(file, new_dset) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "can't initialize chunk cache")
/* Indicate that the chunk information was initialized */
chunk_init = TRUE;
} /* end case */
break;
case H5D_COMPACT:
{
hssize_t tmp_size; /* Temporary holder for raw data size */
hsize_t comp_data_size;
/*
* Compact dataset is stored in dataset object header message of
* layout.
*/
tmp_size = H5S_GET_EXTENT_NPOINTS(space) * H5T_get_size(new_dset->shared->type);
H5_ASSIGN_OVERFLOW(new_dset->shared->layout.u.compact.size, tmp_size, hssize_t, size_t);
/* Verify data size is smaller than maximum header message size
* (64KB) minus other layout message fields.
*/
comp_data_size = H5O_MESG_MAX_SIZE - H5O_layout_meta_size(file, &(new_dset->shared->layout));
if(new_dset->shared->layout.u.compact.size > comp_data_size)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "compact dataset size is bigger than header message maximum size")
} /* end case */
break;
default:
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "not implemented yet")
} /* end switch */ /*lint !e788 All appropriate cases are covered */
/* Set the dataset's I/O operations */
if(H5D_set_io_ops(new_dset) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize I/O operations")
/* Create the layout information for the new dataset */
if((new_dset->shared->layout.ops->new)(file, dxpl_id, new_dset, dc_plist) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize layout information")
/* Indicate that the layout information was initialized */
layout_init = TRUE;
/* Update the dataset's object header info. */
if(H5D_update_oh_info(file, dxpl_id, new_dset) != SUCCEED)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "can't update the metadata cache")
@ -1277,8 +1152,8 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
done:
if(!ret_value && new_dset && new_dset->shared) {
if(new_dset->shared) {
if(new_dset->shared->layout.type == H5D_CHUNKED && chunk_init) {
if(H5D_istore_dest(new_dset,H5AC_dxpl_id) < 0)
if(new_dset->shared->layout.type == H5D_CHUNKED && layout_init) {
if(H5D_chunk_dest(file, dxpl_id, new_dset) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, NULL, "unable to destroy chunk cache")
} /* end if */
if(new_dset->shared->space) {
@ -1482,6 +1357,30 @@ H5D_open_oid(H5D_t *dataset, hid_t dxpl_id)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data layout message")
if(H5P_set(plist, H5D_CRT_LAYOUT_NAME, &dataset->shared->layout.type) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set layout")
/* Get the external file list message, which might not exist. Space is
* also undefined when space allocate time is H5D_ALLOC_TIME_LATE. */
if((dataset->shared->layout.type == H5D_CONTIGUOUS && !H5F_addr_defined(dataset->shared->layout.u.contig.addr))
|| (dataset->shared->layout.type == H5D_CHUNKED && !H5F_addr_defined(dataset->shared->layout.u.chunk.addr))) {
if((msg_exists = H5O_msg_exists(&(dataset->oloc), H5O_EFL_ID, dxpl_id)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check if message exists")
if(msg_exists) {
/* Retrieve the EFL message */
if(NULL == H5O_msg_read(&(dataset->oloc), H5O_EFL_ID, &dataset->shared->dcpl_cache.efl, dxpl_id))
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve message")
/* Set the EFL info in the property list */
if(H5P_set(plist, H5D_CRT_EXT_FILE_LIST_NAME, &dataset->shared->dcpl_cache.efl) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set external file list")
/* Set the dataset's I/O operations */
dataset->shared->layout.ops = H5D_LOPS_EFL;
} /* end if */
} /* end if */
/* Sanity check that the layout operations are set up */
HDassert(dataset->shared->layout.ops);
switch(dataset->shared->layout.type) {
case H5D_CONTIGUOUS:
/* Compute the size of the contiguous storage for versions of the
@ -1516,7 +1415,7 @@ H5D_open_oid(H5D_t *dataset, hid_t dxpl_id)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set chunk size")
/* Initialize the chunk cache for the dataset */
if(H5D_istore_init(dataset->oloc.file, dataset) < 0)
if(H5D_chunk_init(dataset->oloc.file, dxpl_id, dataset) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize chunk cache")
}
break;
@ -1584,27 +1483,6 @@ H5D_open_oid(H5D_t *dataset, hid_t dxpl_id)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set allocation time state")
} /* end if */
/* Get the external file list message, which might not exist. Space is
* also undefined when space allocate time is H5D_ALLOC_TIME_LATE. */
if((dataset->shared->layout.type == H5D_CONTIGUOUS && !H5F_addr_defined(dataset->shared->layout.u.contig.addr))
|| (dataset->shared->layout.type == H5D_CHUNKED && !H5F_addr_defined(dataset->shared->layout.u.chunk.addr))) {
if((msg_exists = H5O_msg_exists(&(dataset->oloc), H5O_EFL_ID, dxpl_id)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check if message exists")
if(msg_exists) {
/* Retrieve the EFL message */
if(NULL == H5O_msg_read(&(dataset->oloc), H5O_EFL_ID, &dataset->shared->dcpl_cache.efl, dxpl_id))
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve message")
/* Set the EFL info in the property list */
if(H5P_set(plist, H5D_CRT_EXT_FILE_LIST_NAME, &dataset->shared->dcpl_cache.efl) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set external file list")
} /* end if */
} /* end if */
/* Set the dataset's I/O operations */
if(H5D_set_io_ops(dataset) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize I/O operations")
/*
* Make sure all storage is properly initialized.
* This is important only for parallel I/O where the space must
@ -1614,7 +1492,7 @@ H5D_open_oid(H5D_t *dataset, hid_t dxpl_id)
&& ((dataset->shared->layout.type == H5D_CONTIGUOUS && !H5F_addr_defined(dataset->shared->layout.u.contig.addr))
|| (dataset->shared->layout.type == H5D_CHUNKED && !H5F_addr_defined(dataset->shared->layout.u.chunk.addr)))
&& IS_H5FD_MPI(dataset->oloc.file)) {
if(H5D_alloc_storage(dataset->oloc.file, dxpl_id, dataset, H5D_ALLOC_OPEN, FALSE) < 0)
if(H5D_alloc_storage(dataset, dxpl_id, H5D_ALLOC_OPEN, FALSE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file storage")
} /* end if */
@ -1671,9 +1549,9 @@ H5D_close(H5D_t *dataset)
HDassert(dataset->shared->fo_count >0);
/* Dump debugging info */
#ifdef H5D_ISTORE_DEBUG
H5D_istore_stats(dataset, FALSE);
#endif /* H5F_ISTORE_DEBUG */
#ifdef H5D_CHUNK_DEBUG
H5D_chunk_stats(dataset, FALSE);
#endif /* H5D_CHUNK_DEBUG */
dataset->shared->fo_count--;
if(dataset->shared->fo_count == 0) {
@ -1714,7 +1592,7 @@ H5D_close(H5D_t *dataset)
} /* end if */
/* Flush and destroy chunks in the cache */
if(H5D_istore_dest(dataset, H5AC_dxpl_id) < 0)
if(H5D_chunk_dest(dataset->oloc.file, H5AC_dxpl_id, dataset) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to destroy chunk cache")
break;
@ -1899,10 +1777,11 @@ H5D_get_file(const H5D_t *dset)
*-------------------------------------------------------------------------
*/
herr_t
H5D_alloc_storage(H5F_t *f, hid_t dxpl_id, H5D_t *dset/*in,out*/, H5D_time_alloc_t time_alloc,
H5D_alloc_storage(H5D_t *dset/*in,out*/, hid_t dxpl_id, H5D_time_alloc_t time_alloc,
hbool_t full_overwrite)
{
struct H5O_layout_t *layout; /* The dataset's layout information */
H5F_t *f = dset->oloc.file; /* The dataset's file pointer */
H5O_layout_t *layout; /* The dataset's layout information */
hbool_t must_init_space = FALSE; /* Flag to indicate that space should be initialized */
hbool_t addr_set = FALSE; /* Flag to indicate that the dataset's storage address was set */
herr_t ret_value = SUCCEED; /* Return value */
@ -1910,8 +1789,8 @@ H5D_alloc_storage(H5F_t *f, hid_t dxpl_id, H5D_t *dset/*in,out*/, H5D_time_alloc
FUNC_ENTER_NOAPI_NOINIT(H5D_alloc_storage)
/* check args */
HDassert(f);
HDassert(dset);
HDassert(f);
/* If the data is stored in external files, don't set an address for the layout
* We assume that external storage is already
@ -1925,7 +1804,7 @@ H5D_alloc_storage(H5F_t *f, hid_t dxpl_id, H5D_t *dset/*in,out*/, H5D_time_alloc
case H5D_CONTIGUOUS:
if(!H5F_addr_defined(layout->u.contig.addr)) {
/* Reserve space in the file for the entire array */
if(H5D_contig_create(f, dxpl_id, layout/*out*/) < 0)
if(H5D_contig_alloc(f, dxpl_id, layout/*out*/) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to initialize contiguous storage")
/* Indicate that we set the storage addr */
@ -1939,7 +1818,7 @@ H5D_alloc_storage(H5F_t *f, hid_t dxpl_id, H5D_t *dset/*in,out*/, H5D_time_alloc
case H5D_CHUNKED:
if(!H5F_addr_defined(layout->u.chunk.addr)) {
/* Create the root of the B-tree that describes chunked storage */
if(H5D_istore_create(f, dxpl_id, layout/*out*/) < 0)
if(H5D_chunk_create(dset /*in,out*/, dxpl_id) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to initialize chunked storage")
/* Indicate that we set the storage addr */
@ -2079,7 +1958,7 @@ H5D_init_storage(H5D_t *dset, hbool_t full_overwrite, hid_t dxpl_id)
* Allocate file space
* for all chunks now and initialize each chunk with the fill value.
*/
if(H5D_istore_allocate(dset, dxpl_id, full_overwrite) < 0)
if(H5D_chunk_allocate(dset, dxpl_id, full_overwrite) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to allocate all chunks of dataset")
break;
@ -2122,7 +2001,8 @@ H5D_get_storage_size(H5D_t *dset, hid_t dxpl_id)
if(dset->shared->layout.u.chunk.addr == HADDR_UNDEF)
ret_value = 0;
else
ret_value = H5D_istore_allocated(dset, dxpl_id);
if(H5D_chunk_allocated(dset, dxpl_id, &ret_value) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, 0, "can't retrieve chunked dataset allocated size")
break;
case H5D_CONTIGUOUS:
@ -2428,7 +2308,7 @@ done:
* Function: H5D_set_extent
*
* Purpose: Based on H5D_extend, allows change to a lower dimension,
* calls H5S_set_extent and H5D_istore_prune_by_extent instead
* calls H5S_set_extent and H5D_chunk_prune_by_extent instead
*
* Return: Non-negative on success, negative on failure
*
@ -2491,12 +2371,12 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id)
*/
/* Update the index values for the cached chunks for this dataset */
if(H5D_CHUNKED == dset->shared->layout.type)
if(H5D_istore_update_cache(dset, dxpl_id) < 0)
if(H5D_chunk_update_cache(dset, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update cached chunk indices")
/* Allocate space for the new parts of the dataset, if appropriate */
if(expand && dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_EARLY)
if(H5D_alloc_storage(dset->oloc.file, dxpl_id, dset, H5D_ALLOC_EXTEND, FALSE) < 0)
if(H5D_alloc_storage(dset, dxpl_id, H5D_ALLOC_EXTEND, FALSE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset storage")
@ -2506,24 +2386,9 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id)
*-------------------------------------------------------------------------
*/
if(shrink && H5D_CHUNKED == dset->shared->layout.type) {
H5D_io_info_t io_info; /* Dataset I/O info */
H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */
H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */
/* Fill the DXPL cache values for later use */
if(H5D_get_dxpl_cache(dxpl_id, &dxpl_cache) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache")
/* Construct dataset I/O info */
H5D_BUILD_IO_INFO_RD(&io_info, dset, dxpl_cache, dxpl_id, NULL, NULL);
/* Remove excess chunks */
if(H5D_istore_prune_by_extent(&io_info, curr_dims) < 0)
if(H5D_chunk_prune_by_extent(dset, dxpl_id, curr_dims) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to remove chunks ")
/* Reset the elements outsize the new dimensions, but in existing chunks */
if(H5D_istore_initialize_by_extent(&io_info) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to initialize chunks ")
} /* end if */
/* Mark the dataspace as dirty, for later writing to the file */
@ -2611,7 +2476,7 @@ H5D_flush_real(H5D_t *dataset, hid_t dxpl_id, unsigned flags)
case H5D_CHUNKED:
/* Flush the raw data cache */
if(H5D_istore_flush(dataset, dxpl_id, flags & H5F_FLUSH_INVALIDATE) < 0)
if(H5D_chunk_flush(dataset, dxpl_id, flags & H5F_FLUSH_INVALIDATE) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush raw data cache")
break;

View File

@ -392,7 +392,7 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
|| dataset->shared->layout.type == H5D_COMPACT);
/* Call storage method's I/O initialization routine */
if(io_info.layout_ops.init && (*io_info.layout_ops.init)(&io_info, &type_info, nelmts, file_space, mem_space, &fm) < 0)
if(io_info.layout_ops.io_init && (*io_info.layout_ops.io_init)(&io_info, &type_info, nelmts, file_space, mem_space, &fm) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize I/O info")
io_op_init = TRUE;
@ -408,7 +408,7 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
done:
/* Shut down the I/O op information */
if(io_op_init && io_info.layout_ops.term && (*io_info.layout_ops.term)(&fm) < 0)
if(io_op_init && io_info.layout_ops.io_term && (*io_info.layout_ops.io_term)(&fm) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down I/O op info")
#ifdef H5_HAVE_PARALLEL
/* Shut down io_info struct */
@ -553,7 +553,7 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
full_overwrite = (hsize_t)file_nelmts == nelmts ? TRUE : FALSE;
/* Allocate storage */
if(H5D_alloc_storage(dataset->oloc.file, dxpl_id, dataset, H5D_ALLOC_WRITE, full_overwrite) < 0)
if(H5D_alloc_storage(dataset, dxpl_id, H5D_ALLOC_WRITE, full_overwrite) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage")
} /* end if */
@ -567,7 +567,7 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
#endif /*H5_HAVE_PARALLEL*/
/* Call storage method's I/O initialization routine */
if(io_info.layout_ops.init && (*io_info.layout_ops.init)(&io_info, &type_info, nelmts, file_space, mem_space, &fm) < 0)
if(io_info.layout_ops.io_init && (*io_info.layout_ops.io_init)(&io_info, &type_info, nelmts, file_space, mem_space, &fm) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize I/O info")
io_op_init = TRUE;
@ -598,7 +598,7 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
done:
/* Shut down the I/O op information */
if(io_op_init && io_info.layout_ops.term && (*io_info.layout_ops.term)(&fm) < 0)
if(io_op_init && io_info.layout_ops.io_term && (*io_info.layout_ops.io_term)(&fm) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down I/O op info")
#ifdef H5_HAVE_PARALLEL
/* Shut down io_info struct */
@ -646,11 +646,11 @@ H5D_ioinfo_init(H5D_t *dset, const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id,
io_info->store = store;
/* Set I/O operations to initial values */
io_info->layout_ops = *dset->shared->layout_ops;
io_info->layout_ops = *dset->shared->layout.ops;
/* Set the "high-level" I/O operations for the dataset */
io_info->io_ops.multi_read = dset->shared->layout_ops->ser_read;
io_info->io_ops.multi_write = dset->shared->layout_ops->ser_write;
io_info->io_ops.multi_read = dset->shared->layout.ops->ser_read;
io_info->io_ops.multi_write = dset->shared->layout.ops->ser_write;
/* Set the I/O operations for reading/writing single blocks on disk */
if(type_info->is_xform_noop && type_info->is_conv_noop) {
@ -887,8 +887,8 @@ H5D_ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset,
/* Check if we can use the optimized parallel I/O routines */
if(opt == TRUE) {
/* Override the I/O op pointers to the MPI-specific routines */
io_info->io_ops.multi_read = dset->shared->layout_ops->par_read;
io_info->io_ops.multi_write = dset->shared->layout_ops->par_write;
io_info->io_ops.multi_read = dset->shared->layout.ops->par_read;
io_info->io_ops.multi_write = dset->shared->layout.ops->par_write;
io_info->io_ops.single_read = H5D_mpio_select_read;
io_info->io_ops.single_write = H5D_mpio_select_write;
} /* end if */

File diff suppressed because it is too large Load Diff

View File

@ -822,7 +822,6 @@ H5D_link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type
* equivalent of compressed contiguous datasets - QAK]
*/
if(total_chunks == 1) {
H5D_storage_t chk_store; /* Temporary storage info for chunk address lookup */
hsize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of chunk in file dataset's dataspace */
H5SL_node_t *chunk_node; /* Pointer to chunk node for selection */
H5S_t *fspace; /* Dataspace describing chunk & selection in it */
@ -833,10 +832,7 @@ H5D_link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type
HDmemset(coords, 0, sizeof(coords));
/* Look up address of chunk */
io_info->store = &chk_store;
chk_store.chunk.offset = coords;
chk_store.chunk.index = 0;
if(HADDR_UNDEF == (ctg_store.contig.dset_addr = H5D_istore_get_addr(io_info, NULL)))
if(HADDR_UNDEF == (ctg_store.contig.dset_addr = H5D_chunk_get_addr(io_info->dset, io_info->dxpl_id, coords, NULL)))
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list")
/* Check for this process having selection in this chunk */
@ -968,7 +964,7 @@ if(H5DEBUG(D))
total_chunk_addr_array = H5MM_malloc(sizeof(haddr_t) * total_chunks);
/* Retrieve chunk address map */
if(H5D_istore_chunkmap(io_info, total_chunk_addr_array, fm->down_chunks) < 0)
if(H5D_chunk_addrmap(io_info, total_chunk_addr_array, fm->down_chunks) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address")
/* Get chunk with lowest address */
@ -1181,7 +1177,7 @@ if(H5DEBUG(D))
/* Check if this process has somethign to do with this chunk */
if(chunk_info) {
H5D_io_info_t *chk_io_info; /* Pointer to I/O info object for this chunk */
H5D_istore_ud1_t udata; /* B-tree pass-through */
H5D_chunk_ud_t udata; /* B-tree pass-through */
void *chunk; /* Pointer to the data chunk in cache */
uint32_t accessed_bytes; /* Total accessed size in a chunk */
unsigned idx_hint = 0; /* Cache index hint */
@ -1197,17 +1193,15 @@ if(H5DEBUG(D))
/* Load the chunk into cache. But if the whole chunk is written,
* simply allocate space instead of load the chunk.
*/
if(HADDR_UNDEF == (caddr = H5D_istore_get_addr(io_info, &udata)))
if(HADDR_UNDEF == (caddr = H5D_chunk_get_addr(io_info->dset, io_info->dxpl_id, chunk_info->coords, &udata)))
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list")
/* Load the chunk into cache and lock it. */
if(H5D_chunk_cacheable(io_info, caddr)) {
hbool_t entire_chunk = TRUE; /* Whether whole chunk is selected */
size_t tmp_accessed_bytes; /* Total accessed size in a chunk */
/* Compute # of bytes accessed in chunk */
tmp_accessed_bytes = chunk_info->chunk_points * type_info->src_type_size;
H5_ASSIGN_OVERFLOW(accessed_bytes, tmp_accessed_bytes, size_t, uint32_t);
accessed_bytes = chunk_info->chunk_points * type_info->src_type_size;
/* Determine if we will access all the data in the chunk */
if(((io_info->op_type == H5D_IO_OP_WRITE) && (accessed_bytes != ctg_store.contig.dset_size))
@ -1215,7 +1209,7 @@ if(H5DEBUG(D))
entire_chunk = FALSE;
/* Lock the chunk into the cache */
if(NULL == (chunk = H5D_istore_lock(io_info, &udata, entire_chunk, &idx_hint)))
if(NULL == (chunk = H5D_chunk_lock(io_info, &udata, entire_chunk, &idx_hint)))
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
/* Set up the storage buffer information for this chunk */
@ -1247,7 +1241,7 @@ if(H5DEBUG(D))
} /* end else */
/* Release the cache lock on the chunk. */
if(chunk && H5D_istore_unlock(io_info, (io_info->op_type == H5D_IO_OP_WRITE), idx_hint, chunk, accessed_bytes) < 0)
if(chunk && H5D_chunk_unlock(io_info, (io_info->op_type == H5D_IO_OP_WRITE), idx_hint, chunk, accessed_bytes) < 0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
} /* end if */
#else /* !defined(H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS) || !defined(H5_MPI_SPECIAL_COLLECTIVE_IO_WORKS) */
@ -1377,7 +1371,7 @@ if(H5DEBUG(D)) {
while(chunk_node) {
H5D_chunk_info_t *chunk_info; /* chunk information */
haddr_t chunk_addr; /* Address of chunk in file */
H5D_istore_ud1_t udata; /* B-tree pass-through */
H5D_chunk_ud_t udata; /* B-tree pass-through */
hbool_t make_ind, make_coll; /* Flags to indicate that the MPI mode should change */
/* Get the actual chunk information from the skip list node */
@ -1414,7 +1408,7 @@ if(H5DEBUG(D)) {
#endif /* H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS */
/* Retrieve the chunk's address */
if(HADDR_UNDEF == (chunk_addr = H5D_istore_get_addr(io_info, &udata)))
if(HADDR_UNDEF == (chunk_addr = H5D_chunk_get_addr(io_info->dset, io_info->dxpl_id, chunk_info->coords, &udata)))
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL,"couldn't get chunk info from skipped list")
/* Independent I/O */
@ -1431,11 +1425,9 @@ if(H5DEBUG(D)) {
/* Load the chunk into cache and lock it. */
if(H5D_chunk_cacheable(io_info, chunk_addr)) {
hbool_t entire_chunk = TRUE; /* Whether whole chunk is selected */
size_t tmp_accessed_bytes; /* Total accessed size in a chunk */
/* Compute # of bytes accessed in chunk */
tmp_accessed_bytes = chunk_info->chunk_points * type_info->src_type_size;
H5_ASSIGN_OVERFLOW(accessed_bytes, tmp_accessed_bytes, size_t, uint32_t);
accessed_bytes = chunk_info->chunk_points * type_info->src_type_size;
/* Determine if we will access all the data in the chunk */
if(((io_info->op_type == H5D_IO_OP_WRITE) && (accessed_bytes != ctg_store.contig.dset_size))
@ -1443,7 +1435,7 @@ if(H5DEBUG(D)) {
entire_chunk = FALSE;
/* Lock the chunk into the cache */
if(NULL == (chunk = H5D_istore_lock(io_info, &udata, entire_chunk, &idx_hint)))
if(NULL == (chunk = H5D_chunk_lock(io_info, &udata, entire_chunk, &idx_hint)))
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
/* Set up the storage buffer information for this chunk */
@ -1476,7 +1468,7 @@ if(H5DEBUG(D)) {
/* Release the cache lock on the chunk. */
if(chunk)
if(H5D_istore_unlock(io_info, (io_info->op_type == H5D_IO_OP_WRITE), idx_hint, chunk, accessed_bytes) < 0)
if(H5D_chunk_unlock(io_info, (io_info->op_type == H5D_IO_OP_WRITE), idx_hint, chunk, accessed_bytes) < 0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
} /* end if */
else { /*collective I/O */
@ -1657,7 +1649,6 @@ H5D_sort_chunk(H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
H5D_chunk_info_t *chunk_info; /* Current chunking info. of this node. */
haddr_t chunk_addr; /* Current chunking address of this node */
haddr_t *total_chunk_addr_array = NULL; /* The array of chunk address for the total number of chunk */
H5D_storage_t store; /*union of EFL and chunk pointer in file space */
hbool_t do_sort = FALSE; /* Whether the addresses need to be sorted */
int bsearch_coll_chunk_threshold;
int many_chunk_opt = H5D_OBTAIN_ONE_CHUNK_ADDR_IND;
@ -1706,7 +1697,7 @@ if(H5DEBUG(D))
if((mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file)) < 0)
HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi rank")
if(mpi_rank == 0) {
if(H5D_istore_chunkmap(io_info, total_chunk_addr_array, fm->down_chunks) < 0)
if(H5D_chunk_addrmap(io_info, total_chunk_addr_array, fm->down_chunks) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address")
} /* end if */
@ -1715,9 +1706,6 @@ if(H5DEBUG(D))
HMPI_GOTO_ERROR(FAIL, "MPI_BCast failed", mpi_code)
} /* end if */
/* Set dataset storage for I/O info */
io_info->store = &store;
/* Start at first node in chunk skip list */
i = 0;
if(NULL == (chunk_node = H5SL_first(fm->sel_chunks)))
@ -1729,9 +1717,7 @@ if(H5DEBUG(D))
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL,"couldn't get chunk info from skipped list")
if(many_chunk_opt == H5D_OBTAIN_ONE_CHUNK_ADDR_IND) {
store.chunk.offset = chunk_info->coords;
store.chunk.index = chunk_info->index;
if(HADDR_UNDEF == (chunk_addr = H5D_istore_get_addr(io_info, NULL)))
if(HADDR_UNDEF == (chunk_addr = H5D_chunk_get_addr(io_info->dset, io_info->dxpl_id, chunk_info->coords, NULL)))
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list")
} /* end if */
else
@ -1846,7 +1832,7 @@ H5D_obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm,
#if defined(H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS) && defined(H5_MPI_SPECIAL_COLLECTIVE_IO_WORKS)
chunk_opt_mode = (H5FD_mpio_chunk_opt_t)H5P_peek_unsigned(dx_plist, H5D_XFER_MPIO_CHUNK_OPT_HARD_NAME);
if((chunk_opt_mode == H5FD_MPIO_CHUNK_MULTI_IO) || (percent_nproc_per_chunk == 0)) {
if(H5D_istore_chunkmap(io_info, chunk_addr, fm->down_chunks) < 0)
if(H5D_chunk_addrmap(io_info, chunk_addr, fm->down_chunks) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address");
for(ic = 0; ic < total_chunks; ic++)
assign_io_mode[ic] = H5D_CHUNK_IO_MODE_COL;
@ -1903,7 +1889,7 @@ H5D_obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm,
#endif
/* calculating the chunk address */
if(H5D_istore_chunkmap(io_info, chunk_addr, fm->down_chunks) < 0) {
if(H5D_chunk_addrmap(io_info, chunk_addr, fm->down_chunks) < 0) {
HDfree(nproc_per_chunk);
#if !defined(H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS) || !defined(H5_MPI_SPECIAL_COLLECTIVE_IO_WORKS)
HDfree(ind_this_chunk);

View File

@ -361,7 +361,7 @@ H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info)
/* Check for chunked dataset storage */
if((layout.type == H5D_CHUNKED) && H5F_addr_defined(layout.u.chunk.addr))
if(H5D_istore_bh_info(f, dxpl_id, &layout, &(bh_info->index_size)) < 0)
if(H5D_chunk_bh_info(f, dxpl_id, &layout, &(bh_info->index_size)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't determine chunked dataset btree info")
done:

View File

@ -100,7 +100,9 @@ struct H5D_io_info_t;
struct H5D_chunk_map_t;
/* Function pointers for I/O on particular types of dataset layouts */
typedef herr_t (*H5D_layout_init_func_t)(const struct H5D_io_info_t *io_info,
typedef herr_t (*H5D_layout_new_func_t)(H5F_t *f, hid_t dxpl_id,
H5D_t *dset, const H5P_genplist_t *dc_plist);
typedef herr_t (*H5D_layout_io_init_func_t)(const struct H5D_io_info_t *io_info,
const H5D_type_info_t *type_info,
hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
struct H5D_chunk_map_t *cm);
@ -116,11 +118,12 @@ typedef ssize_t (*H5D_layout_readvv_func_t)(const struct H5D_io_info_t *io_info,
typedef ssize_t (*H5D_layout_writevv_func_t)(const struct H5D_io_info_t *io_info,
size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]);
typedef herr_t (*H5D_layout_term_func_t)(const struct H5D_chunk_map_t *cm);
typedef herr_t (*H5D_layout_io_term_func_t)(const struct H5D_chunk_map_t *cm);
/* Typedef for grouping layout I/O routines */
typedef struct H5D_layout_ops_t {
H5D_layout_init_func_t init; /* I/O initialization routine */
H5D_layout_new_func_t new; /* Layout constructor for new datasets */
H5D_layout_io_init_func_t io_init; /* I/O initialization routine */
H5D_layout_read_func_t ser_read; /* High-level I/O routine for reading data in serial */
H5D_layout_write_func_t ser_write; /* High-level I/O routine for writing data in serial */
#ifdef H5_HAVE_PARALLEL
@ -129,7 +132,7 @@ typedef struct H5D_layout_ops_t {
#endif /* H5_HAVE_PARALLEL */
H5D_layout_readvv_func_t readvv; /* Low-level I/O routine for reading data */
H5D_layout_writevv_func_t writevv; /* Low-level I/O routine for writing data */
H5D_layout_term_func_t term; /* I/O shutdown routine */
H5D_layout_io_term_func_t io_term; /* I/O shutdown routine */
} H5D_layout_ops_t;
/* Function pointers for either multiple or single block I/O access */
@ -201,6 +204,96 @@ typedef struct H5D_io_info_t {
} u;
} H5D_io_info_t;
/******************/
/* Chunk typedefs */
/******************/
/* Typedef for chunked dataset index operation info */
typedef struct H5D_chk_idx_info_t {
H5F_t *f; /* File pointer for operation */
hid_t dxpl_id; /* DXPL ID for operation */
H5O_layout_t *layout; /* Layout info for chunks */
} H5D_chk_idx_info_t;
/*
* "Generic" chunk record. Each chunk is keyed by the minimum logical
* N-dimensional coordinates and the datatype size of the chunk.
* The fastest-varying dimension is assumed to reference individual bytes of
* the array, so a 100-element 1-D array of 4-byte integers would really be a
* 2-D array with the slow varying dimension of size 100 and the fast varying
* dimension of size 4 (the storage dimensionality has very little to do with
* the real dimensionality).
*
* The chunk's file address, filter mask and size on disk are not key values.
*/
typedef struct H5D_chunk_rec_t {
uint32_t nbytes; /* Size of stored data */
hsize_t offset[H5O_LAYOUT_NDIMS]; /* Logical offset to start*/
unsigned filter_mask; /* Excluded filters */
haddr_t chunk_addr; /* Address of chunk in file */
} H5D_chunk_rec_t;
/*
* Common data exchange structure for indexed storage nodes. This structure is
* passed through the indexing layer to the methods for the objects
* to which the index points.
*/
typedef struct H5D_chunk_common_ud_t {
/* downward */
const H5O_layout_t *mesg; /*layout message */
const hsize_t *offset; /*logical offset of chunk*/
} H5D_chunk_common_ud_t;
/* B-tree callback info for various operations */
typedef struct H5D_chunk_ud_t {
H5D_chunk_common_ud_t common; /* Common info for B-tree user data (must be first) */
/* Upward */
uint32_t nbytes; /*size of stored data */
unsigned filter_mask; /*excluded filters */
haddr_t addr; /*file address of chunk */
} H5D_chunk_ud_t;
/* Typedef for "generic" chunk callbacks */
typedef int (*H5D_chunk_cb_func_t)(const H5D_chunk_rec_t *chunk_rec,
void *udata);
/* Typedefs for chunk operations */
typedef herr_t (*H5D_chunk_init_func_t)(const H5D_chk_idx_info_t *idx_info);
typedef herr_t (*H5D_chunk_create_func_t)(const H5D_chk_idx_info_t *idx_info);
typedef herr_t (*H5D_chunk_insert_func_t)(const H5D_chk_idx_info_t *idx_info,
H5D_chunk_ud_t *udata);
typedef haddr_t (*H5D_chunk_get_addr_func_t)(const H5D_chk_idx_info_t *idx_info,
H5D_chunk_ud_t *udata);
typedef int (*H5D_chunk_iterate_func_t)(const H5D_chk_idx_info_t *idx_info,
H5D_chunk_cb_func_t chunk_cb, void *chunk_udata);
typedef herr_t (*H5D_chunk_remove_func_t)(const H5D_chk_idx_info_t *idx_info,
H5D_chunk_common_ud_t *udata);
typedef herr_t (*H5D_chunk_delete_func_t)(const H5D_chk_idx_info_t *idx_info);
typedef herr_t (*H5D_chunk_copy_setup_func_t)(const H5D_chk_idx_info_t *idx_info_src,
const H5D_chk_idx_info_t *idx_info_dst);
typedef herr_t (*H5D_chunk_copy_shutdown_func_t)(H5O_layout_t *layout_src,
H5O_layout_t *layout_dst);
typedef herr_t (*H5D_chunk_size_func_t)(const H5D_chk_idx_info_t *idx_info,
hsize_t *idx_size);
typedef herr_t (*H5D_chunk_dest_func_t)(const H5D_chk_idx_info_t *idx_info);
/* Typedef for grouping chunk I/O routines */
typedef struct H5D_chunk_ops_t {
H5D_chunk_init_func_t init; /* Routine to initialize indexing information in memory */
H5D_chunk_create_func_t create; /* Routine to create chunk index */
H5D_chunk_insert_func_t insert; /* Routine to insert a chunk into an index */
H5D_chunk_get_addr_func_t get_addr; /* Routine to retrieve address of chunk in file */
H5D_chunk_iterate_func_t iterate; /* Routine to iterate over chunks */
H5D_chunk_remove_func_t remove; /* Routine to remove a chunk from an index */
H5D_chunk_delete_func_t delete; /* Routine to delete index & all chunks from file*/
H5D_chunk_copy_setup_func_t copy_setup; /* Routine to perform any necessary setup for copying chunks */
H5D_chunk_copy_shutdown_func_t copy_shutdown; /* Routine to perform any necessary shutdown for copying chunks */
H5D_chunk_size_func_t size; /* Routine to get size of indexing information */
H5D_chunk_dest_func_t dest; /* Routine to destroy indexing information in memory */
} H5D_chunk_ops_t;
/* Structure holding information about a chunk's selection for mapping */
typedef struct H5D_chunk_info_t {
hsize_t index; /* "Index" of chunk in dataset */
@ -212,6 +305,40 @@ typedef struct H5D_chunk_info_t {
unsigned mspace_shared; /* Indicate that the memory space for a chunk is shared and shouldn't be freed */
} H5D_chunk_info_t;
/* Main structure holding the mapping between file chunks and memory */
typedef struct H5D_chunk_map_t {
H5O_layout_t *layout; /* Dataset layout information*/
hsize_t nelmts; /* Number of elements selected in file & memory dataspaces */
const H5S_t *file_space; /* Pointer to the file dataspace */
unsigned f_ndims; /* Number of dimensions for file dataspace */
hsize_t f_dims[H5O_LAYOUT_NDIMS]; /* File dataspace dimensions */
const H5S_t *mem_space; /* Pointer to the memory dataspace */
H5S_t *mchunk_tmpl; /* Dataspace template for new memory chunks */
H5S_sel_iter_t mem_iter; /* Iterator for elements in memory selection */
unsigned m_ndims; /* Number of dimensions for memory dataspace */
H5S_sel_type msel_type; /* Selection type in memory */
H5SL_t *sel_chunks; /* Skip list containing information for each chunk selected */
H5S_t *single_space; /* Dataspace for single chunk */
H5D_chunk_info_t *single_chunk_info; /* Pointer to single chunk's info */
hbool_t use_single; /* Whether I/O is on a single element */
hsize_t last_index; /* Index of last chunk operated on */
H5D_chunk_info_t *last_chunk_info; /* Pointer to last chunk's info */
hsize_t chunks[H5O_LAYOUT_NDIMS]; /* Number of chunks in each dimension */
hsize_t chunk_dim[H5O_LAYOUT_NDIMS]; /* Size of chunk in each dimension */
hsize_t down_chunks[H5O_LAYOUT_NDIMS]; /* "down" size of number of chunks in each dimension */
#ifdef H5_HAVE_PARALLEL
hsize_t total_chunks; /* Number of chunks covered by dataspace */
H5D_chunk_info_t **select_chunk; /* Store the information about whether this chunk is selected or not */
#endif /* H5_HAVE_PARALLEL */
} H5D_chunk_map_t;
/* Cached information about a particular chunk */
typedef struct H5D_chunk_cached_t{
hbool_t valid; /*whether cache info is valid*/
@ -223,12 +350,12 @@ typedef struct H5D_chunk_cached_t{
/* The raw data chunk cache */
typedef struct H5D_rdcc_t {
#ifdef H5D_ISTORE_DEBUG
unsigned ninits; /* Number of chunk creations */
unsigned nhits; /* Number of cache hits */
unsigned nmisses;/* Number of cache misses */
unsigned nflushes;/* Number of cache flushes */
#endif /* H5D_ISTORE_DEBUG */
struct {
unsigned ninits; /* Number of chunk creations */
unsigned nhits; /* Number of cache hits */
unsigned nmisses;/* Number of cache misses */
unsigned nflushes;/* Number of cache flushes */
} stats;
size_t nbytes; /* Current cached raw data in bytes */
size_t nslots; /* Number of chunk slots allocated */
struct H5D_rdcc_ent_t *head; /* Head of doubly linked list */
@ -266,7 +393,6 @@ typedef struct H5D_shared_t {
hid_t dcpl_id; /* dataset creation property id */
H5D_dcpl_cache_t dcpl_cache; /* Cached DCPL values */
H5O_layout_t layout; /* data layout */
const H5D_layout_ops_t *layout_ops; /* Pointer to data layout I/O operations */
hbool_t checked_filters;/* TRUE if dataset passes can_apply check */
/* Buffered/cached information for types of raw data storage*/
@ -295,40 +421,6 @@ typedef enum {
} H5D_time_alloc_t;
/* Main structure holding the mapping between file chunks and memory */
typedef struct H5D_chunk_map_t {
H5O_layout_t *layout; /* Dataset layout information*/
hsize_t nelmts; /* Number of elements selected in file & memory dataspaces */
const H5S_t *file_space; /* Pointer to the file dataspace */
unsigned f_ndims; /* Number of dimensions for file dataspace */
hsize_t f_dims[H5O_LAYOUT_NDIMS]; /* File dataspace dimensions */
const H5S_t *mem_space; /* Pointer to the memory dataspace */
H5S_t *mchunk_tmpl; /* Dataspace template for new memory chunks */
H5S_sel_iter_t mem_iter; /* Iterator for elements in memory selection */
unsigned m_ndims; /* Number of dimensions for memory dataspace */
H5S_sel_type msel_type; /* Selection type in memory */
H5SL_t *sel_chunks; /* Skip list containing information for each chunk selected */
H5S_t *single_space; /* Dataspace for single chunk */
H5D_chunk_info_t *single_chunk_info; /* Pointer to single chunk's info */
hbool_t use_single; /* Whether I/O is on a single element */
hsize_t last_index; /* Index of last chunk operated on */
H5D_chunk_info_t *last_chunk_info; /* Pointer to last chunk's info */
hsize_t chunks[H5O_LAYOUT_NDIMS]; /* Number of chunks in each dimension */
hsize_t chunk_dim[H5O_LAYOUT_NDIMS]; /* Size of chunk in each dimension */
hsize_t down_chunks[H5O_LAYOUT_NDIMS]; /* "down" size of number of chunks in each dimension */
#ifdef H5_HAVE_PARALLEL
hsize_t total_chunks; /* Number of chunks covered by dataspace */
H5D_chunk_info_t **select_chunk; /* Store the information about whether this chunk is selected or not */
#endif /* H5_HAVE_PARALLEL */
} H5D_chunk_map_t;
/* Typedef for dataset creation operation */
typedef struct {
hid_t type_id; /* Datatype for dataset */
@ -361,51 +453,6 @@ typedef struct {
hbool_t has_vlen_fill_type; /* Whether the datatype for the fill value has a variable-length component */
} H5D_fill_buf_info_t;
/*************************/
/* For chunk lock */
/*************************/
/*
* B-tree key. A key contains the minimum logical N-dimensional address and
* the logical size of the chunk to which this key refers. The
* fastest-varying dimension is assumed to reference individual bytes of the
* array, so a 100-element 1-d array of 4-byte integers would really be a 2-d
* array with the slow varying dimension of size 100 and the fast varying
* dimension of size 4 (the storage dimensionality has very little to do with
* the real dimensionality).
*
* Only the first few values of the OFFSET and SIZE fields are actually
* stored on disk, depending on the dimensionality.
*
* The chunk's file address is part of the B-tree and not part of the key.
*/
typedef struct H5D_istore_key_t {
uint32_t nbytes; /*size of stored data */
hsize_t offset[H5O_LAYOUT_NDIMS]; /*logical offset to start*/
unsigned filter_mask; /*excluded filters */
} H5D_istore_key_t;
/*
* Common data exchange structure for indexed storage nodes. This structure is
* passed through the B-link tree layer to the methods for the objects
* to which the B-link tree points.
*/
typedef struct H5D_istore_bt_ud_common_t {
/* downward */
const H5O_layout_t *mesg; /*layout message */
const hsize_t *offset; /*logical offset of chunk*/
} H5D_istore_bt_ud_common_t;
/* B-tree callback info for various operations */
typedef struct H5D_istore_ud1_t {
H5D_istore_bt_ud_common_t common; /* Common info for B-tree user data (must be first) */
/* Upward */
uint32_t nbytes; /*size of stored data */
unsigned filter_mask; /*excluded filters */
haddr_t addr; /*file address of chunk */
} H5D_istore_ud1_t;
/* Internal data structure for computing variable-length dataset's total size */
typedef struct {
hid_t dataset_id; /* ID of the dataset we are working on */
@ -424,6 +471,7 @@ typedef struct H5D_rdcc_ent_t {
hsize_t offset[H5O_LAYOUT_NDIMS]; /*chunk name */
uint32_t rd_count; /*bytes remaining to be read */
uint32_t wr_count; /*bytes remaining to be written */
haddr_t chunk_addr; /*address of chunk in file */
uint32_t chunk_size; /*size of a chunk */
size_t alloc_size; /*amount allocated for the chunk */
uint8_t *chunk; /*the unfiltered chunk data */
@ -439,12 +487,15 @@ typedef H5D_rdcc_ent_t *H5D_rdcc_ent_ptr_t; /* For free lists */
/*****************************/
extern H5D_dxpl_cache_t H5D_def_dxpl_cache;
/* Storage layout classes */
/* Storage layout class I/O operations */
H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_CONTIG[1];
H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_EFL[1];
H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_COMPACT[1];
H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_CHUNK[1];
/* Chunked layout operations */
H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_ISTORE[1];
/******************************/
/* Package Private Prototypes */
@ -457,7 +508,7 @@ H5_DLL H5D_t *H5D_create_named(const H5G_loc_t *loc, const char *name,
hid_t dapl_id, hid_t dxpl_id);
H5_DLL herr_t H5D_get_space_status(H5D_t *dset, H5D_space_status_t *allocation,
hid_t dxpl_id);
H5_DLL herr_t H5D_alloc_storage(H5F_t *f, hid_t dxpl_id, H5D_t *dset, H5D_time_alloc_t time_alloc,
H5_DLL herr_t H5D_alloc_storage(H5D_t *dset, hid_t dxpl_id, H5D_time_alloc_t time_alloc,
hbool_t full_overwrite);
H5_DLL hsize_t H5D_get_storage_size(H5D_t *dset, hid_t dxpl_id);
H5_DLL haddr_t H5D_get_offset(const H5D_t *dset);
@ -490,7 +541,7 @@ H5_DLL herr_t H5D_scatgath_write(const H5D_io_info_t *io_info,
hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space);
/* Functions that operate on contiguous storage */
H5_DLL herr_t H5D_contig_create(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout);
H5_DLL herr_t H5D_contig_alloc(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout);
H5_DLL herr_t H5D_contig_fill(H5D_t *dset, hid_t dxpl_id);
H5_DLL haddr_t H5D_contig_get_addr(const H5D_t *dset);
H5_DLL herr_t H5D_contig_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
@ -510,45 +561,41 @@ H5_DLL herr_t H5D_contig_copy(H5F_t *f_src, const H5O_layout_t *layout_src, H5F_
/* Functions that operate on chunked dataset storage */
H5_DLL hbool_t H5D_chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr);
H5_DLL herr_t H5D_chunk_cinfo_cache_reset(H5D_chunk_cached_t *last);
H5_DLL herr_t H5D_chunk_create(H5D_t *dset /*in,out*/, hid_t dxpl_id);
H5_DLL herr_t H5D_chunk_init(H5F_t *f, hid_t dxpl_id, const H5D_t *dset);
H5_DLL haddr_t H5D_chunk_get_addr(const H5D_t *dset, hid_t dxpl_id,
const hsize_t *chunk_offset, H5D_chunk_ud_t *udata);
H5_DLL void *H5D_chunk_lock(const H5D_io_info_t *io_info,
H5D_chunk_ud_t *udata, hbool_t relax, unsigned *idx_hint/*in,out*/);
H5_DLL herr_t H5D_chunk_unlock(const H5D_io_info_t *io_info,
hbool_t dirty, unsigned idx_hint, void *chunk, uint32_t naccessed);
H5_DLL herr_t H5D_chunk_flush(H5D_t *dset, hid_t dxpl_id, unsigned flags);
H5_DLL herr_t H5D_chunk_allocated(H5D_t *dset, hid_t dxpl_id, hsize_t *nbytes);
H5_DLL herr_t H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite);
H5_DLL herr_t H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id,
const hsize_t *old_dims);
#ifdef H5_HAVE_PARALLEL
H5_DLL herr_t H5D_chunk_addrmap(const H5D_io_info_t *io_info,
haddr_t chunk_addr[], const hsize_t down_chunks[]);
#endif /* H5_HAVE_PARALLEL */
H5_DLL herr_t H5D_chunk_update_cache(H5D_t *dset, hid_t dxpl_id);
H5_DLL herr_t H5D_chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src,
H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *src_dtype,
H5O_copy_t *cpy_info, H5O_pline_t *pline, hid_t dxpl_id);
H5_DLL herr_t H5D_chunk_bh_info(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
hsize_t *btree_size);
H5_DLL herr_t H5D_chunk_dump_index(H5D_t *dset, hid_t dxpl_id, FILE *stream);
H5_DLL herr_t H5D_chunk_dest(H5F_t *f, hid_t dxpl_id, H5D_t *dset);
#ifdef H5D_CHUNK_DEBUG
H5_DLL herr_t H5D_chunk_stats(const H5D_t *dset, hbool_t headers);
#endif /* H5D_CHUNK_DEBUG */
/* Functions that operate on compact dataset storage */
H5_DLL herr_t H5D_compact_fill(H5D_t *dset, hid_t dxpl_id);
H5_DLL herr_t H5D_compact_copy(H5F_t *f_src, H5O_layout_t *layout_src,
H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info, hid_t dxpl_id);
/* Functions that operate on indexed storage */
/* forward reference for collective-chunk IO use */
struct H5D_istore_ud1_t; /*define in H5Distore.c*/
H5_DLL herr_t H5D_istore_init (const H5F_t *f, const H5D_t *dset);
H5_DLL herr_t H5D_istore_flush (H5D_t *dset, hid_t dxpl_id, unsigned flags);
H5_DLL herr_t H5D_istore_create(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout);
H5_DLL herr_t H5D_istore_dest (H5D_t *dset, hid_t dxpl_id);
H5_DLL herr_t H5D_istore_allocate (H5D_t *dset, hid_t dxpl_id,
hbool_t full_overwrite);
H5_DLL hsize_t H5D_istore_allocated(H5D_t *dset, hid_t dxpl_id);
H5_DLL herr_t H5D_istore_bh_info(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
hsize_t *btree_size);
H5_DLL herr_t H5D_istore_prune_by_extent(const H5D_io_info_t *io_info,
const hsize_t *old_dims);
H5_DLL herr_t H5D_istore_initialize_by_extent(H5D_io_info_t *io_info);
H5_DLL herr_t H5D_istore_update_cache(H5D_t *dset, hid_t dxpl_id);
H5_DLL herr_t H5D_istore_dump_btree(H5F_t *f, hid_t dxpl_id, FILE *stream, unsigned ndims,
haddr_t addr);
H5_DLL herr_t H5D_istore_chunkmap(const H5D_io_info_t *io_info,
haddr_t chunk_addr[], const hsize_t down_chunks[]);
#ifdef H5D_ISTORE_DEBUG
H5_DLL herr_t H5D_istore_stats (H5D_t *dset, hbool_t headers);
#endif /* H5D_ISTORE_DEBUG */
H5_DLL haddr_t H5D_istore_get_addr(const H5D_io_info_t *io_info,
struct H5D_istore_ud1_t *_udata);
H5_DLL herr_t H5D_istore_copy(H5F_t *f_src, H5O_layout_t *layout_src,
H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *src_dtype,
H5O_copy_t *cpy_info, H5O_pline_t *pline, hid_t dxpl_id);
H5_DLL void * H5D_istore_lock(const H5D_io_info_t *io_info, H5D_istore_ud1_t *udata,
hbool_t relax, unsigned *idx_hint/*in,out*/);
H5_DLL herr_t H5D_istore_unlock(const H5D_io_info_t *io_info,
hbool_t dirty, unsigned idx_hint, void *chunk, uint32_t naccessed);
/* Functions that perform fill value operations on datasets */
H5_DLL herr_t H5D_fill(const void *fill, const H5T_t *fill_type, void *buf,
const H5T_t *buf_type, const H5S_t *space, hid_t dxpl_id);

View File

@ -154,9 +154,10 @@ H5_DLL herr_t H5D_vlen_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id,
H5_DLL herr_t H5D_contig_delete(H5F_t *f, hid_t dxpl_id,
const H5O_layout_t *layout);
/* Functions that operate on chunked storage */
H5_DLL herr_t H5D_chunk_delete(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout);
/* Functions that operate on indexed storage */
H5_DLL herr_t H5D_istore_delete(H5F_t *f, hid_t dxpl_id,
const H5O_layout_t *layout);
H5_DLL herr_t H5D_istore_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream,
int indent, int fwidth, unsigned ndims);

View File

@ -67,9 +67,6 @@ typedef struct H5G_gnba_iter_t {
/* Declare extern the PQ free list for the wrapped strings */
H5FL_BLK_EXTERN(str_buf);
/* Declare the free list to manage haddr_t's */
H5FL_DEFINE_STATIC(haddr_t);
/* PRIVATE PROTOTYPES */
static htri_t H5G_common_path(const H5RS_str_t *fullpath_r, const H5RS_str_t *prefix_r);
static H5RS_str_t *H5G_build_fullpath(const char *prefix, const char *name);

View File

@ -74,7 +74,6 @@ typedef struct H5G_node_t {
/* PRIVATE PROTOTYPES */
static herr_t H5G_node_serialize(H5F_t *f, H5G_node_t *sym, size_t size, uint8_t *buf);
static size_t H5G_node_size_real(const H5F_t *f);
static herr_t H5G_node_shared_free(void *shared);
/* Metadata cache callbacks */
static H5G_node_t *H5G_node_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata1,
@ -146,12 +145,6 @@ H5FL_DEFINE_STATIC(H5G_node_t);
/* Declare a free list to manage sequences of H5G_entry_t's */
H5FL_SEQ_DEFINE_STATIC(H5G_entry_t);
/* Declare a free list to manage the native key offset sequence information */
H5FL_SEQ_DEFINE_STATIC(size_t);
/* Declare a free list to manage the raw page information */
H5FL_BLK_DEFINE_STATIC(grp_page);
/*-------------------------------------------------------------------------
* Function: H5G_node_get_shared
@ -1590,39 +1583,26 @@ herr_t
H5G_node_init(H5F_t *f)
{
H5B_shared_t *shared; /* Shared B-tree node info */
size_t u; /* Local index variable */
size_t sizeof_rkey; /* Size of raw (disk) key */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_node_init, FAIL);
/* Check arguments. */
assert(f);
HDassert(f);
/* Allocate space for the shared structure */
if(NULL==(shared=H5FL_MALLOC(H5B_shared_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for shared B-tree info")
/* Set the raw key size */
sizeof_rkey = H5F_SIZEOF_SIZE(f); /*name offset */
/* Set up the "global" information for this file's groups */
shared->type= H5B_SNODE;
shared->two_k=2*H5F_KVALUE(f,H5B_SNODE);
shared->sizeof_rkey = H5F_SIZEOF_SIZE(f); /*the name offset */
assert(shared->sizeof_rkey);
shared->sizeof_rnode = H5B_nodesize(f, shared, &shared->sizeof_keys);
assert(shared->sizeof_rnode);
if(NULL==(shared->page=H5FL_BLK_MALLOC(grp_page,shared->sizeof_rnode)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree page")
#ifdef H5_CLEAR_MEMORY
HDmemset(shared->page, 0, shared->sizeof_rnode);
#endif /* H5_CLEAR_MEMORY */
if(NULL==(shared->nkey=H5FL_SEQ_MALLOC(size_t,(size_t)(2*H5F_KVALUE(f,H5B_SNODE)+1))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree page")
/* Allocate & initialize global info for the shared structure */
if(NULL == (shared = H5B_shared_new(f, H5B_SNODE, sizeof_rkey)))
HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, FAIL, "memory allocation failed for shared B-tree info")
/* Initialize the offsets into the native key buffer */
for(u=0; u<(2*H5F_KVALUE(f,H5B_SNODE)+1); u++)
shared->nkey[u]=u*H5B_SNODE->sizeof_nkey;
/* Set up the "local" information for this file's groups */
/* <none> */
/* Make shared B-tree info reference counted */
if(NULL==(f->shared->grp_btree_shared=H5RC_create(shared,H5G_node_shared_free)))
if(NULL == (f->shared->grp_btree_shared = H5RC_create(shared, H5B_shared_free)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared B-tree info")
done:
@ -1660,40 +1640,6 @@ H5G_node_close(const H5F_t *f)
FUNC_LEAVE_NOAPI(SUCCEED);
} /* end H5G_node_close */
/*-------------------------------------------------------------------------
* Function: H5G_node_shared_free
*
* Purpose: Free B-tree shared info
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* Thursday, July 8, 2004
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
H5G_node_shared_free (void *_shared)
{
H5B_shared_t *shared = (H5B_shared_t *)_shared;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_shared_free)
/* Free the raw B-tree node buffer */
H5FL_BLK_FREE(grp_page,shared->page);
/* Free the B-tree native key offsets buffer */
H5FL_SEQ_FREE(size_t,shared->nkey);
/* Free the shared B-tree info */
H5FL_FREE(H5B_shared_t,shared);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5G_node_shared_free() */
/*-------------------------------------------------------------------------
* Function: H5G_node_copy

View File

@ -518,7 +518,7 @@ H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order,
udata.op_data = op_data;
/* Iterate over the group members */
if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_iterate, stab.btree_addr, &udata)) < 0)
if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, H5G_node_iterate, &udata)) < 0)
HERROR(H5E_SYM, H5E_CANTNEXT, "iteration operator failed");
/* Check for too high of a starting index (ex post facto :-) */
@ -535,8 +535,7 @@ H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order,
udata.ltable = &ltable;
/* Iterate over the group members */
if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_build_table,
stab.btree_addr, &udata) < 0)
if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, H5G_node_build_table, &udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to build link table")
/* Check for skipping out of bounds */
@ -595,7 +594,7 @@ H5G_stab_count(H5O_loc_t *oloc, hsize_t *num_objs, hid_t dxpl_id)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address")
/* Iterate over the group members */
if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_sumup, stab.btree_addr, num_objs) < 0)
if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, H5G_node_sumup, num_objs) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "iteration operator failed")
done:
@ -616,10 +615,12 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
H5G_stab_bh_size(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab, H5_ih_info_t *bh_info)
H5G_stab_bh_size(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab,
H5_ih_info_t *bh_info)
{
H5B_info_ud_t bh_udata; /* User-data for B-tree callbacks */
herr_t ret_value = SUCCEED;
hsize_t snode_size; /* Symbol table node size */
H5B_info_t bt_info; /* B-tree node info */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5G_stab_bh_size, FAIL)
@ -628,14 +629,16 @@ H5G_stab_bh_size(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab, H5_ih_info_t *
HDassert(stab);
HDassert(bh_info);
/* Set up user data for B-tree callback */
bh_udata.udata = NULL;
bh_udata.btree_size = &(bh_info->index_size);
/* Set up user data for B-tree iteration */
snode_size = 0;
/* Get the B-tree & symbol table node size info */
if(H5B_iterate_size(f, dxpl_id, H5B_SNODE, H5G_node_iterate_size, stab->btree_addr, &bh_udata) < 0)
if(H5B_get_info(f, dxpl_id, H5B_SNODE, stab->btree_addr, &bt_info, H5G_node_iterate_size, &snode_size) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "iteration operator failed")
/* Add symbol table & B-tree node sizes to index info */
bh_info->index_size += snode_size + bt_info.size;
/* Get the size of the local heap for the group */
if(H5HL_heapsize(f, dxpl_id, stab->heap_addr, &(bh_info->heap_size)) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "iteration operator failed")
@ -723,7 +726,7 @@ H5G_stab_get_name_by_idx(H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n,
hsize_t nlinks = 0; /* Number of links in group */
/* Iterate over the symbol table nodes, to count the links */
if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_sumup, stab.btree_addr, &nlinks) < 0)
if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, H5G_node_sumup, &nlinks) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "iteration operator failed")
/* Map decreasing iteration order index to increasing iteration order index */
@ -739,7 +742,7 @@ H5G_stab_get_name_by_idx(H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n,
udata.name = NULL;
/* Iterate over the group members */
if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_by_idx, stab.btree_addr, &udata) < 0)
if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, H5G_node_by_idx, &udata) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "iteration operator failed")
/* If we don't know the name now, we almost certainly went out of bounds */
@ -947,7 +950,7 @@ H5G_stab_lookup_by_idx(H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n,
hsize_t nlinks = 0; /* Number of links in group */
/* Iterate over the symbol table nodes, to count the links */
if(H5B_iterate(grp_oloc->file, dxpl_id, H5B_SNODE, H5G_node_sumup, stab.btree_addr, &nlinks) < 0)
if(H5B_iterate(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, H5G_node_sumup, &nlinks) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "iteration operator failed")
/* Map decreasing iteration order index to increasing iteration order index */
@ -964,7 +967,7 @@ H5G_stab_lookup_by_idx(H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n,
udata.found = FALSE;
/* Iterate over the group members */
if(H5B_iterate(grp_oloc->file, dxpl_id, H5B_SNODE, H5G_node_by_idx, stab.btree_addr, &udata) < 0)
if(H5B_iterate(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, H5G_node_by_idx, &udata) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "iteration operator failed")
/* If we didn't find the link, we almost certainly went out of bounds */
@ -1076,7 +1079,7 @@ H5G_stab_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id)
udata.type = H5G_UNKNOWN;
/* Iterate over the group members */
if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_by_idx, stab.btree_addr, &udata) < 0)
if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, H5G_node_by_idx, &udata) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "iteration operator failed")
/* If we don't know the type now, we almost certainly went out of bounds */

View File

@ -136,11 +136,30 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
p += 5;
/* Address */
if(mesg->type == H5D_CONTIGUOUS)
if(mesg->type == H5D_CONTIGUOUS) {
H5F_addr_decode(f, &p, &(mesg->u.contig.addr));
else if(mesg->type == H5D_CHUNKED)
/* Set the layout operations */
mesg->ops = H5D_LOPS_CONTIG;
} /* end if */
else if(mesg->type == H5D_CHUNKED) {
H5F_addr_decode(f, &p, &(mesg->u.chunk.addr));
/* Set the layout operations */
mesg->ops = H5D_LOPS_CHUNK;
/* Set the chunk operations */
/* (Only "istore" indexing type currently supported */
mesg->u.chunk.ops = H5D_COPS_ISTORE;
} /* 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
@ -185,11 +204,17 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
HDmemcpy(mesg->u.compact.buf, p, mesg->u.compact.size);
p += mesg->u.compact.size;
} /* end if */
/* Set the layout operations */
mesg->ops = H5D_LOPS_COMPACT;
break;
case H5D_CONTIGUOUS:
H5F_addr_decode(f, &p, &(mesg->u.contig.addr));
H5F_DECODE_LENGTH(f, p, mesg->u.contig.size);
/* Set the layout operations */
mesg->ops = H5D_LOPS_CONTIG;
break;
case H5D_CHUNKED:
@ -208,6 +233,13 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags,
/* 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 layout operations */
mesg->ops = H5D_LOPS_CHUNK;
/* Set the chunk operations */
/* (Only "istore" indexing type currently supported */
mesg->u.chunk.ops = H5D_COPS_ISTORE;
break;
default:
@ -576,8 +608,8 @@ H5O_layout_delete(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, void *_mesg)
break;
case H5D_CHUNKED: /* Chunked blocks on disk */
/* Free the file space for the raw data */
if(H5D_istore_delete(f, dxpl_id, mesg) < 0)
/* Free the file space for the index & chunk raw data */
if(H5D_chunk_delete(f, dxpl_id, mesg) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free raw data")
break;
@ -670,7 +702,7 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
layout_dst->u.chunk.addr = HADDR_UNDEF;
/* create chunked layout */
if(H5D_istore_copy(file_src, layout_src, file_dst, layout_dst, udata->src_dtype, cpy_info, udata->src_pline, dxpl_id) < 0)
if(H5D_chunk_copy(file_src, layout_src, file_dst, layout_dst, udata->src_dtype, cpy_info, udata->src_pline, dxpl_id) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to copy chunked storage")
/* Freed by copy routine */

View File

@ -326,6 +326,10 @@ typedef struct H5O_efl_t {
*/
#define H5O_LAYOUT_NDIMS (H5S_MAX_RANK+1)
/* Forward declaration of structs used below */
struct H5D_layout_ops_t; /* Defined in H5Dpkg.h */
struct H5D_chunk_ops_t; /* Defined in H5Dpkg.h */
typedef struct H5O_layout_contig_t {
haddr_t addr; /* File address of data */
hsize_t size; /* Size of data in bytes */
@ -337,6 +341,7 @@ typedef struct H5O_layout_chunk_t {
uint32_t dim[H5O_LAYOUT_NDIMS]; /* Size of chunk in elements */
uint32_t size; /* Size of chunk in bytes */
H5RC_t *btree_shared; /* Ref-counted info for B-tree nodes */
const struct H5D_chunk_ops_t *ops; /* Pointer to chunked layout operations */
} H5O_layout_chunk_t;
typedef struct H5O_layout_compact_t {
@ -348,6 +353,7 @@ typedef struct H5O_layout_compact_t {
typedef struct H5O_layout_t {
H5D_layout_t type; /* Type of layout */
unsigned version; /* Version of message */
const struct H5D_layout_ops_t *ops; /* Pointer to data layout I/O operations */
union {
H5O_layout_contig_t contig; /* Information for contiguous layout */
H5O_layout_chunk_t chunk; /* Information for chunked layout */

View File

@ -386,7 +386,7 @@ H5O_stab_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src, H5O_loc
udata.cpy_info = cpy_info;
/* Iterate over objects in group, copying them */
if((H5B_iterate(src_oloc->file, dxpl_id, H5B_SNODE, H5G_node_copy, stab_src->btree_addr, &udata)) < 0)
if((H5B_iterate(src_oloc->file, dxpl_id, H5B_SNODE, stab_src->btree_addr, H5G_node_copy, &udata)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "iteration operator failed")
done:

View File

@ -3556,7 +3556,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
H5P_get(H5P_genplist_t *plist, const char *name, void *value)
H5P_get(const H5P_genplist_t *plist, const char *name, void *value)
{
H5P_genclass_t *tclass; /* Temporary class pointer */
H5P_genprop_t *prop; /* Temporary property pointer */

View File

@ -59,7 +59,7 @@ H5_DLL herr_t H5P_init(void);
H5_DLL herr_t H5P_close(void *_plist);
H5_DLL hid_t H5P_create_id(H5P_genclass_t *pclass);
H5_DLL hid_t H5P_copy_plist(H5P_genplist_t *old_plist);
H5_DLL herr_t H5P_get(H5P_genplist_t *plist, const char *name, void *value);
H5_DLL herr_t H5P_get(const H5P_genplist_t *plist, const char *name, void *value);
H5_DLL herr_t H5P_set(H5P_genplist_t *plist, const char *name, const void *value);
H5_DLL herr_t H5P_insert(H5P_genplist_t *plist, const char *name, size_t size,
void *value, H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,

View File

@ -43,7 +43,6 @@ static herr_t H5S_set_extent_simple (H5S_t *space, unsigned rank,
static htri_t H5S_is_simple(const H5S_t *sdim);
static herr_t H5S_encode(H5S_t *obj, unsigned char *buf, size_t *nalloc);
static H5S_t *H5S_decode(const unsigned char *buf);
static htri_t H5S_extent_equal(const H5S_t *ds1, const H5S_t *ds2);
#ifdef H5_HAVE_PARALLEL
/* Global vars whose value can be set from environment variable also */
@ -1933,7 +1932,7 @@ done:
DESCRIPTION
Compare two dataspaces if their extents are identical.
--------------------------------------------------------------------------*/
static htri_t
htri_t
H5S_extent_equal(const H5S_t *ds1, const H5S_t *ds2)
{
unsigned u; /* Local index variable */

View File

@ -196,7 +196,9 @@ H5_DLL herr_t H5S_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE *stream
H5_DLL int H5S_extend(H5S_t *space, const hsize_t *size);
#endif /* H5_NO_DEPRECATED_SYMBOLS */
/* Operations on dataspace extents */
H5_DLL hsize_t H5S_extent_nelem(const H5S_extent_t *ext);
H5_DLL htri_t H5S_extent_equal(const H5S_t *ds1, const H5S_t *ds2);
/* Operations on selections */
H5_DLL herr_t H5S_select_deserialize(H5S_t *space, const uint8_t *buf);

View File

@ -39,7 +39,6 @@
int main( void )
{
hid_t file_id;
hid_t dataset_id=(-1);
hid_t space_id=(-1);
@ -55,6 +54,9 @@ int main( void )
int buf2[ 90 ][ 90 ];
int i, j, n = 0;
int fillvalue = 1; /* Fill value for the dataset */
#ifdef H5_HAVE_FILTER_DEFLATE
hbool_t do_compress; /* Iterator for looping over compress/no compress */
#endif /* H5_HAVE_FILTER_DEFLATE */
for( i = 0; i < 90; i++ )
@ -65,429 +67,458 @@ int main( void )
* Test H5Dset_extent with chunks on the raw data cache
*-------------------------------------------------------------------------
*/
#ifdef H5_HAVE_FILTER_DEFLATE
for(do_compress = FALSE; do_compress <= TRUE; do_compress++) {
if(do_compress)
puts("Testing WITH compression on chunks.");
else
puts("Testing with NO compression on chunks.");
#else /* H5_HAVE_FILTER_DEFLATE */
puts("** deflate filter nor available - Skipping tests for compression on chunks. **");
#endif /* H5_HAVE_FILTER_DEFLATE */
TESTING("extend dataset create with fill value");
/* Create a new file using default properties. */
if((file_id = H5Fcreate("set_extent_create.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Create the data space with unlimited dimensions. */
if((space_id = H5Screate_simple(RANK, dims, maxdims)) < 0) TEST_ERROR;
/* Modify dataset creation properties, i.e. enable chunking. */
if((plist_id = H5Pcreate (H5P_DATASET_CREATE)) < 0) TEST_ERROR;
if(H5Pset_chunk(plist_id, RANK, dims_chunk) < 0) TEST_ERROR;
if(H5Pset_fill_value(plist_id, H5T_NATIVE_INT, &fillvalue) < 0) TEST_ERROR;
#ifdef H5_HAVE_FILTER_DEFLATE
if(do_compress)
if(H5Pset_deflate(plist_id, 9) < 0) FAIL_STACK_ERROR
#endif /* H5_HAVE_FILTER_DEFLATE */
/* Create a new file using default properties. */
if((file_id = H5Fcreate("set_extent_create.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;
/*-------------------------------------------------------------------------
* Create and write one dataset
*-------------------------------------------------------------------------
*/
TESTING("extend dataset create with fill value");
/* Create a new dataset */
if((dataset_id = H5Dcreate2(file_id , "Dataset1", H5T_NATIVE_INT, space_id, H5P_DEFAULT, plist_id, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Create the data space with unlimited dimensions. */
if((space_id = H5Screate_simple(RANK, dims, maxdims)) < 0) TEST_ERROR;
/* Write the data. */
if(H5Dwrite(dataset_id , H5T_NATIVE_INT, space_id, H5S_ALL, H5P_DEFAULT, data) < 0) TEST_ERROR;
/* Modify dataset creation properties, i.e. enable chunking. */
if((plist_id = H5Pcreate (H5P_DATASET_CREATE)) < 0) TEST_ERROR;
if(H5Pset_chunk(plist_id, RANK, dims_chunk) < 0) TEST_ERROR;
if(H5Pset_fill_value(plist_id, H5T_NATIVE_INT, &fillvalue) < 0) TEST_ERROR;
/*-------------------------------------------------------------------------
* Set new dimensions for the array; shrink it
*-------------------------------------------------------------------------
*/
/* Set new dimensions for the array. */
if(H5Dset_extent(dataset_id , dims_new) < 0) TEST_ERROR;
/* Get the space. */
if((space_id = H5Dget_space(dataset_id)) < 0) TEST_ERROR;
/* Get dimensions. */
if(H5Sget_simple_extent_dims(space_id, dims_out, NULL) < 0) TEST_ERROR;
if(dims_out[0] != dims_new[0]) TEST_ERROR;
if(dims_out[1] != dims_new[1]) TEST_ERROR;
/*-------------------------------------------------------------------------
* Create and write one dataset
*-------------------------------------------------------------------------
*/
/*-------------------------------------------------------------------------
* Read
*-------------------------------------------------------------------------
*/
/* Create a new dataset */
if((dataset_id = H5Dcreate2(file_id , "Dataset1", H5T_NATIVE_INT, space_id, H5P_DEFAULT, plist_id, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Write the data. */
if(H5Dwrite(dataset_id , H5T_NATIVE_INT, space_id, H5S_ALL, H5P_DEFAULT, data) < 0) TEST_ERROR;
/*-------------------------------------------------------------------------
* Set new dimensions for the array; shrink it
*-------------------------------------------------------------------------
*/
/* Set new dimensions for the array. */
if(H5Dset_extent(dataset_id , dims_new) < 0) TEST_ERROR;
/* Get the space. */
if((space_id = H5Dget_space(dataset_id)) < 0) TEST_ERROR;
/* Get dimensions. */
if(H5Sget_simple_extent_dims(space_id, dims_out, NULL) < 0) TEST_ERROR;
if(dims_out[0] != dims_new[0]) TEST_ERROR;
if(dims_out[1] != dims_new[1]) TEST_ERROR;
/* Read the new dataset. */
if (H5Dread( dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf1 ) < 0) TEST_ERROR;
/*-------------------------------------------------------------------------
* Read
*-------------------------------------------------------------------------
*/
/* Read the new dataset. */
if (H5Dread( dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf1 ) < 0) TEST_ERROR;
/* Compare the read array with the original array */
for( i = 0; i < (int)dims_out[0]; i++ )
for( j = 0; j < (int)dims_out[1]; j++ )
if ( buf1[i][j] != data[i][j] ) {
printf("buf1[%d][%d] = %d\n", i, j, buf1[i][j]);
printf("data[%d][%d] = %d\n", i, j, data[i][j]);
TEST_ERROR;
} /* end if */
/*-------------------------------------------------------------------------
* Set new dimensions for the array; expand it back to original size
*-------------------------------------------------------------------------
*/
/* Set new dimensions for the array. */
if(H5Dset_extent(dataset_id, dims) < 0) TEST_ERROR;
/* Get the space. */
if((space_id = H5Dget_space(dataset_id)) < 0) TEST_ERROR;
/* Get dimensions. */
if(H5Sget_simple_extent_dims(space_id, dims_out, NULL) < 0) TEST_ERROR;
if(dims_out[0] != dims[0]) TEST_ERROR;
if(dims_out[1] != dims[1]) TEST_ERROR;
/*-------------------------------------------------------------------------
* Read
*-------------------------------------------------------------------------
*/
/* Read the new dataset. */
if(H5Dread(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf2) < 0) TEST_ERROR;
/* Compare the read array with the original array */
for(i = 0; i < (int)dims_out[0]; i++ )
for(j = 0; j < (int)dims_out[1]; j++ )
if(i >= 70 || j >= 70) {
if(buf2[i][j] != fillvalue) {
/* Compare the read array with the original array */
for( i = 0; i < (int)dims_out[0]; i++ )
for( j = 0; j < (int)dims_out[1]; j++ )
if ( buf1[i][j] != data[i][j] ) {
printf("buf1[%d][%d] = %d\n", i, j, buf1[i][j]);
printf("fillvalue = %d\n", fillvalue);
printf("data[%d][%d] = %d\n", i, j, data[i][j]);
TEST_ERROR;
} /* end if */
} /* end if */
else {
if(buf2[i][j] != data[i][j]) TEST_ERROR;
}
/*-------------------------------------------------------------------------
* Close/release resources
*-------------------------------------------------------------------------
*/
/*-------------------------------------------------------------------------
* Set new dimensions for the array; expand it back to original size
*-------------------------------------------------------------------------
*/
if(H5Dclose(dataset_id) < 0) TEST_ERROR
if(H5Sclose(space_id) < 0) TEST_ERROR
if(H5Pclose(plist_id) < 0) TEST_ERROR
/* Set new dimensions for the array. */
if(H5Dset_extent(dataset_id, dims) < 0) TEST_ERROR;
PASSED();
TESTING("extend dataset create without fill value");
/* Get the space. */
if((space_id = H5Dget_space(dataset_id)) < 0) TEST_ERROR;
/* Create the data space with unlimited dimensions. */
if((space_id = H5Screate_simple(RANK, dims, maxdims)) < 0) TEST_ERROR;
/* Get dimensions. */
if(H5Sget_simple_extent_dims(space_id, dims_out, NULL) < 0) TEST_ERROR;
/* Modify dataset creation properties, i.e. enable chunking. */
if((plist_id = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR;
if(H5Pset_chunk(plist_id, RANK, dims_chunk) < 0) TEST_ERROR;
if(H5Pset_fill_time(plist_id, H5D_FILL_TIME_ALLOC) < 0) TEST_ERROR;
/*-------------------------------------------------------------------------
* Create and write one dataset
*-------------------------------------------------------------------------
*/
/* Create a new dataset */
if((dataset_id = H5Dcreate2(file_id , "Dataset2", H5T_NATIVE_INT, space_id, H5P_DEFAULT, plist_id, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Write the data. */
if(H5Dwrite(dataset_id , H5T_NATIVE_INT, space_id, H5S_ALL, H5P_DEFAULT, data) < 0) TEST_ERROR;
/*-------------------------------------------------------------------------
* Set new dimensions for the array; shrink it
*-------------------------------------------------------------------------
*/
/* Set new dimensions for the array. */
if(H5Dset_extent(dataset_id , dims_new) < 0) TEST_ERROR;
/* Get the space. */
if((space_id = H5Dget_space(dataset_id)) < 0) TEST_ERROR;
/* Get dimensions. */
if(H5Sget_simple_extent_dims(space_id, dims_out, NULL) < 0) TEST_ERROR;
if(dims_out[0] != dims_new[0]) TEST_ERROR;
if(dims_out[0] != dims[0]) TEST_ERROR;
if(dims_out[1] != dims[1]) TEST_ERROR;
/*-------------------------------------------------------------------------
* Read
*-------------------------------------------------------------------------
*/
/*-------------------------------------------------------------------------
* Read
*-------------------------------------------------------------------------
*/
/* Read the new dataset. */
if (H5Dread( dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf1 ) < 0) TEST_ERROR;
/* Read the new dataset. */
if(H5Dread(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf2) < 0) TEST_ERROR;
/* Compare the read array with the original array */
for(i = 0; i < (int)dims_out[0]; i++ )
for(j = 0; j < (int)dims_out[1]; j++ )
if(i >= 70 || j >= 70) {
if(buf2[i][j] != fillvalue) {
printf("buf1[%d][%d] = %d\n", i, j, buf1[i][j]);
printf("fillvalue = %d\n", fillvalue);
TEST_ERROR;
} /* end if */
} /* end if */
else {
if(buf2[i][j] != data[i][j]) TEST_ERROR;
}
/* Compare the read array with the original array */
for( i = 0; i < (int)dims_out[0]; i++ )
for( j = 0; j < (int)dims_out[1]; j++ )
if ( buf1[i][j] != data[i][j] ) TEST_ERROR;
/*-------------------------------------------------------------------------
* Close/release resources
*-------------------------------------------------------------------------
*/
if(H5Dclose(dataset_id) < 0) TEST_ERROR
if(H5Sclose(space_id) < 0) TEST_ERROR
if(H5Pclose(plist_id) < 0) TEST_ERROR
PASSED();
/*-------------------------------------------------------------------------
* Set new dimensions for the array; expand it again
*-------------------------------------------------------------------------
*/
TESTING("extend dataset create without fill value");
/* Set new dimensions for the array. */
if (H5Dset_extent( dataset_id , dims ) < 0) TEST_ERROR;
/* Create the data space with unlimited dimensions. */
if((space_id = H5Screate_simple(RANK, dims, maxdims)) < 0) TEST_ERROR;
/* Get the space. */
if ((space_id = H5Dget_space( dataset_id )) < 0) TEST_ERROR;
/* Modify dataset creation properties, i.e. enable chunking. */
if((plist_id = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR;
if(H5Pset_chunk(plist_id, RANK, dims_chunk) < 0) TEST_ERROR;
if(H5Pset_fill_time(plist_id, H5D_FILL_TIME_ALLOC) < 0) TEST_ERROR;
#ifdef H5_HAVE_FILTER_DEFLATE
if(do_compress)
if(H5Pset_deflate(plist_id, 9) < 0) FAIL_STACK_ERROR
#endif /* H5_HAVE_FILTER_DEFLATE */
/* Get dimensions. */
if (H5Sget_simple_extent_dims( space_id, dims_out, NULL ) < 0) TEST_ERROR;
/*-------------------------------------------------------------------------
* Create and write one dataset
*-------------------------------------------------------------------------
*/
if ( dims_out[0] != dims[0] ) TEST_ERROR;
/* Create a new dataset */
if((dataset_id = H5Dcreate2(file_id , "Dataset2", H5T_NATIVE_INT, space_id, H5P_DEFAULT, plist_id, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Write the data. */
if(H5Dwrite(dataset_id , H5T_NATIVE_INT, space_id, H5S_ALL, H5P_DEFAULT, data) < 0) TEST_ERROR;
/*-------------------------------------------------------------------------
* Set new dimensions for the array; shrink it
*-------------------------------------------------------------------------
*/
/* Set new dimensions for the array. */
if(H5Dset_extent(dataset_id , dims_new) < 0) TEST_ERROR;
/* Get the space. */
if((space_id = H5Dget_space(dataset_id)) < 0) TEST_ERROR;
/* Get dimensions. */
if(H5Sget_simple_extent_dims(space_id, dims_out, NULL) < 0) TEST_ERROR;
if(dims_out[0] != dims_new[0]) TEST_ERROR;
/*-------------------------------------------------------------------------
* Read
*-------------------------------------------------------------------------
*/
/*-------------------------------------------------------------------------
* Read
*-------------------------------------------------------------------------
*/
/* Read the new dataset. */
if (H5Dread( dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf2 ) < 0) TEST_ERROR;
/* Read the new dataset. */
if (H5Dread( dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf1 ) < 0) TEST_ERROR;
/* Compare the read array with the original array */
for( i = 0; i < (int)dims_out[0]; i++ ) {
for( j = 0; j < (int)dims_out[1]; j++ ) {
if ( i >= 70 || j >= 70 ) {
if ( buf2[i][j] != 0 ) TEST_ERROR;
}
else {
if ( buf2[i][j] != data[i][j] ) TEST_ERROR;
/* Compare the read array with the original array */
for( i = 0; i < (int)dims_out[0]; i++ )
for( j = 0; j < (int)dims_out[1]; j++ )
if ( buf1[i][j] != data[i][j] ) TEST_ERROR;
/*-------------------------------------------------------------------------
* Set new dimensions for the array; expand it again
*-------------------------------------------------------------------------
*/
/* Set new dimensions for the array. */
if (H5Dset_extent( dataset_id , dims ) < 0) TEST_ERROR;
/* Get the space. */
if ((space_id = H5Dget_space( dataset_id )) < 0) TEST_ERROR;
/* Get dimensions. */
if (H5Sget_simple_extent_dims( space_id, dims_out, NULL ) < 0) TEST_ERROR;
if ( dims_out[0] != dims[0] ) TEST_ERROR;
/*-------------------------------------------------------------------------
* Read
*-------------------------------------------------------------------------
*/
/* Read the new dataset. */
if (H5Dread( dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf2 ) < 0) TEST_ERROR;
/* Compare the read array with the original array */
for( i = 0; i < (int)dims_out[0]; i++ ) {
for( j = 0; j < (int)dims_out[1]; j++ ) {
if ( i >= 70 || j >= 70 ) {
if ( buf2[i][j] != 0 ) TEST_ERROR;
}
else {
if ( buf2[i][j] != data[i][j] ) TEST_ERROR;
}
}
}
}
/*-------------------------------------------------------------------------
* Close/release resources
*-------------------------------------------------------------------------
*/
/*-------------------------------------------------------------------------
* Close/release resources
*-------------------------------------------------------------------------
*/
H5Dclose( dataset_id );
H5Sclose( space_id );
H5Pclose( plist_id );
H5Dclose( dataset_id );
H5Sclose( space_id );
H5Pclose( plist_id );
H5Fclose( file_id );
H5Fclose( file_id );
PASSED();
PASSED();
/*-------------------------------------------------------------------------
* Test H5Dset_extent with chunks written to file
*-------------------------------------------------------------------------
*/
/*-------------------------------------------------------------------------
* Test H5Dset_extent with chunks written to file
*-------------------------------------------------------------------------
*/
/* Create a file creation property list */
if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) TEST_ERROR;
/* Create a file creation property list */
if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) TEST_ERROR;
/* Set non-default indexed storage B-tree internal 'K' value */
if(H5Pset_istore_k(fcpl,ISTORE_IK) < 0) TEST_ERROR;
/* Set non-default indexed storage B-tree internal 'K' value */
if(H5Pset_istore_k(fcpl,ISTORE_IK) < 0) TEST_ERROR;
/* Create a new file using properties. */
if((file_id = H5Fcreate("set_extent_read.h5", H5F_ACC_TRUNC, fcpl, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Create a new file using properties. */
if((file_id = H5Fcreate("set_extent_read.h5", H5F_ACC_TRUNC, fcpl, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Close property list */
if(H5Pclose(fcpl) < 0) TEST_ERROR;
/* Close property list */
if(H5Pclose(fcpl) < 0) TEST_ERROR;
TESTING("extend dataset read with fill value");
TESTING("extend dataset read with fill value");
/* Create the data space with unlimited dimensions. */
if((space_id = H5Screate_simple(RANK, dims, maxdims)) < 0) TEST_ERROR;
/* Create the data space with unlimited dimensions. */
if((space_id = H5Screate_simple(RANK, dims, maxdims)) < 0) TEST_ERROR;
/* Modify dataset creation properties, i.e. enable chunking. */
if((plist_id = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR;
if(H5Pset_chunk(plist_id, RANK, dims_chunk) < 0) TEST_ERROR;
if(H5Pset_fill_value(plist_id, H5T_NATIVE_INT, &fillvalue) < 0) TEST_ERROR;
/* Modify dataset creation properties, i.e. enable chunking. */
if((plist_id = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR;
if(H5Pset_chunk(plist_id, RANK, dims_chunk) < 0) TEST_ERROR;
if(H5Pset_fill_value(plist_id, H5T_NATIVE_INT, &fillvalue) < 0) TEST_ERROR;
#ifdef H5_HAVE_FILTER_DEFLATE
if(do_compress)
if(H5Pset_deflate(plist_id, 9) < 0) FAIL_STACK_ERROR
#endif /* H5_HAVE_FILTER_DEFLATE */
/* Create a new dataset within the file using cparms creation properties. */
if((dataset_id = H5Dcreate2(file_id , "Dataset1", H5T_NATIVE_INT, space_id, H5P_DEFAULT, plist_id, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Create a new dataset within the file using cparms creation properties. */
if((dataset_id = H5Dcreate2(file_id , "Dataset1", H5T_NATIVE_INT, space_id, H5P_DEFAULT, plist_id, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Write the data. */
if(H5Dwrite(dataset_id , H5T_NATIVE_INT, space_id, H5S_ALL, H5P_DEFAULT, data) < 0) TEST_ERROR;
/* Write the data. */
if(H5Dwrite(dataset_id , H5T_NATIVE_INT, space_id, H5S_ALL, H5P_DEFAULT, data) < 0) TEST_ERROR;
/* Close/release resources. */
if(H5Dclose(dataset_id) < 0) FAIL_STACK_ERROR
if(H5Sclose(space_id) < 0) FAIL_STACK_ERROR
if(H5Pclose(plist_id) < 0) FAIL_STACK_ERROR
if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR
/* Close/release resources. */
if(H5Dclose(dataset_id) < 0) FAIL_STACK_ERROR
if(H5Sclose(space_id) < 0) FAIL_STACK_ERROR
if(H5Pclose(plist_id) < 0) FAIL_STACK_ERROR
if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR
/* Open the file */
if((file_id = H5Fopen("set_extent_read.h5", H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Open the file */
if((file_id = H5Fopen("set_extent_read.h5", H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Open the dataset */
if((dataset_id = H5Dopen2(file_id , "Dataset1", H5P_DEFAULT)) < 0) TEST_ERROR;
/* Open the dataset */
if((dataset_id = H5Dopen2(file_id , "Dataset1", H5P_DEFAULT)) < 0) TEST_ERROR;
/* Set new dimensions for the array. */
if(H5Dset_extent(dataset_id, dims_new) < 0) TEST_ERROR;
/* Set new dimensions for the array. */
if(H5Dset_extent(dataset_id, dims_new) < 0) TEST_ERROR;
/* Get the space. */
if((space_id = H5Dget_space(dataset_id)) < 0) TEST_ERROR;
/* Get the space. */
if((space_id = H5Dget_space(dataset_id)) < 0) TEST_ERROR;
/* Get dimensions. */
if(H5Sget_simple_extent_dims(space_id, dims_out, NULL) < 0) TEST_ERROR;
/* Get dimensions. */
if(H5Sget_simple_extent_dims(space_id, dims_out, NULL) < 0) TEST_ERROR;
if(dims_out[0] != dims_new[0]) TEST_ERROR;
if(dims_out[0] != dims_new[0]) TEST_ERROR;
/* Read the new dataset. */
if(H5Dread(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf1) < 0) TEST_ERROR;
/* Read the new dataset. */
if(H5Dread(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf1) < 0) TEST_ERROR;
/* Compare the read array with the original array */
for(i = 0; i < (int)dims_out[0]; i++)
for(j = 0; j < (int)dims_out[1]; j++)
if(buf1[i][j] != data[i][j])
TEST_ERROR;
/* Compare the read array with the original array */
for(i = 0; i < (int)dims_out[0]; i++)
for(j = 0; j < (int)dims_out[1]; j++)
if(buf1[i][j] != data[i][j])
TEST_ERROR;
/*-------------------------------------------------------------------------
* Set new dimensions for the array; expand it again
*-------------------------------------------------------------------------
*/
/*-------------------------------------------------------------------------
* Set new dimensions for the array; expand it again
*-------------------------------------------------------------------------
*/
/* Set new dimensions for the array. */
if (H5Dset_extent( dataset_id , dims ) < 0) TEST_ERROR;
/* Set new dimensions for the array. */
if (H5Dset_extent( dataset_id , dims ) < 0) TEST_ERROR;
/* Get the space. */
if ((space_id = H5Dget_space( dataset_id )) < 0) TEST_ERROR;
/* Get the space. */
if ((space_id = H5Dget_space( dataset_id )) < 0) TEST_ERROR;
/* Get dimensions. */
if (H5Sget_simple_extent_dims( space_id, dims_out, NULL ) < 0) TEST_ERROR;
/* Get dimensions. */
if (H5Sget_simple_extent_dims( space_id, dims_out, NULL ) < 0) TEST_ERROR;
if ( dims_out[0] != dims[0] ) TEST_ERROR;
if ( dims_out[0] != dims[0] ) TEST_ERROR;
/* Read the new dataset. */
if (H5Dread( dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf2 ) < 0) TEST_ERROR;
/* Read the new dataset. */
if (H5Dread( dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf2 ) < 0) TEST_ERROR;
/* Compare the read array with the original array */
for( i = 0; i < (int)dims_out[0]; i++ ) {
for( j = 0; j < (int)dims_out[1]; j++ ) {
if ( i >= 70 || j >= 70 ) {
if ( buf2[i][j] != fillvalue ) TEST_ERROR;
}
else {
if ( buf2[i][j] != data[i][j] ) TEST_ERROR;
/* Compare the read array with the original array */
for( i = 0; i < (int)dims_out[0]; i++ ) {
for( j = 0; j < (int)dims_out[1]; j++ ) {
if ( i >= 70 || j >= 70 ) {
if ( buf2[i][j] != fillvalue ) TEST_ERROR;
}
else {
if ( buf2[i][j] != data[i][j] ) TEST_ERROR;
}
}
}
}
/*-------------------------------------------------------------------------
* Close/release resources
*-------------------------------------------------------------------------
*/
/*-------------------------------------------------------------------------
* Close/release resources
*-------------------------------------------------------------------------
*/
H5Dclose( dataset_id );
H5Sclose( space_id );
H5Dclose( dataset_id );
H5Sclose( space_id );
PASSED();
PASSED();
TESTING("extend dataset read without fill value");
TESTING("extend dataset read without fill value");
/* Create the data space with unlimited dimensions. */
if((space_id = H5Screate_simple(RANK, dims, maxdims)) < 0) TEST_ERROR;
/* Create the data space with unlimited dimensions. */
if((space_id = H5Screate_simple(RANK, dims, maxdims)) < 0) TEST_ERROR;
/* Modify dataset creation properties, i.e. enable chunking. */
if((plist_id = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR;
if(H5Pset_chunk(plist_id, RANK, dims_chunk) < 0) TEST_ERROR;
if(H5Pset_fill_time(plist_id, H5D_FILL_TIME_ALLOC) < 0) TEST_ERROR;
/* Modify dataset creation properties, i.e. enable chunking. */
if((plist_id = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR;
if(H5Pset_chunk(plist_id, RANK, dims_chunk) < 0) TEST_ERROR;
if(H5Pset_fill_time(plist_id, H5D_FILL_TIME_ALLOC) < 0) TEST_ERROR;
#ifdef H5_HAVE_FILTER_DEFLATE
if(do_compress)
if(H5Pset_deflate(plist_id, 9) < 0) FAIL_STACK_ERROR
#endif /* H5_HAVE_FILTER_DEFLATE */
/* Create a new dataset within the file using cparms creation properties. */
if((dataset_id = H5Dcreate2(file_id , "Dataset2", H5T_NATIVE_INT, space_id, H5P_DEFAULT, plist_id, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Create a new dataset within the file using cparms creation properties. */
if((dataset_id = H5Dcreate2(file_id , "Dataset2", H5T_NATIVE_INT, space_id, H5P_DEFAULT, plist_id, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Write the data. */
if(H5Dwrite(dataset_id , H5T_NATIVE_INT, space_id, H5S_ALL, H5P_DEFAULT, data) < 0) TEST_ERROR;
/* Write the data. */
if(H5Dwrite(dataset_id , H5T_NATIVE_INT, space_id, H5S_ALL, H5P_DEFAULT, data) < 0) TEST_ERROR;
/* Close/release resources. */
if(H5Dclose(dataset_id) < 0) FAIL_STACK_ERROR
if(H5Sclose(space_id) < 0) FAIL_STACK_ERROR
if(H5Pclose(plist_id) < 0) FAIL_STACK_ERROR
if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR
/* Close/release resources. */
if(H5Dclose(dataset_id) < 0) FAIL_STACK_ERROR
if(H5Sclose(space_id) < 0) FAIL_STACK_ERROR
if(H5Pclose(plist_id) < 0) FAIL_STACK_ERROR
if(H5Fclose(file_id) < 0) FAIL_STACK_ERROR
/* Open the file */
if((file_id = H5Fopen("set_extent_read.h5", H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Open the file */
if((file_id = H5Fopen("set_extent_read.h5", H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Open the dataset */
if((dataset_id = H5Dopen2(file_id , "Dataset2", H5P_DEFAULT)) < 0) TEST_ERROR;
/* Open the dataset */
if((dataset_id = H5Dopen2(file_id , "Dataset2", H5P_DEFAULT)) < 0) TEST_ERROR;
/* Set new dimensions for the array. */
if(H5Dset_extent(dataset_id, dims_new) < 0) TEST_ERROR;
/* Set new dimensions for the array. */
if(H5Dset_extent(dataset_id, dims_new) < 0) TEST_ERROR;
/* Get the space. */
if((space_id = H5Dget_space(dataset_id)) < 0) TEST_ERROR;
/* Get the space. */
if((space_id = H5Dget_space(dataset_id)) < 0) TEST_ERROR;
/* Get dimensions. */
if(H5Sget_simple_extent_dims(space_id, dims_out, NULL) < 0) TEST_ERROR;
/* Get dimensions. */
if(H5Sget_simple_extent_dims(space_id, dims_out, NULL) < 0) TEST_ERROR;
if(dims_out[0] != dims_new[0]) TEST_ERROR;
if(dims_out[0] != dims_new[0]) TEST_ERROR;
/* Read the new dataset. */
if(H5Dread(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf1) < 0) TEST_ERROR;
/* Read the new dataset. */
if(H5Dread(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf1) < 0) TEST_ERROR;
/* Compare the read array with the original array */
for(i = 0; i < (int)dims_out[0]; i++)
for(j = 0; j < (int)dims_out[1]; j++)
if(buf1[i][j] != data[i][j])
TEST_ERROR;
/* Compare the read array with the original array */
for(i = 0; i < (int)dims_out[0]; i++)
for(j = 0; j < (int)dims_out[1]; j++)
if(buf1[i][j] != data[i][j])
TEST_ERROR;
/*-------------------------------------------------------------------------
* Set new dimensions for the array; expand it again
*-------------------------------------------------------------------------
*/
/*-------------------------------------------------------------------------
* Set new dimensions for the array; expand it again
*-------------------------------------------------------------------------
*/
/* Set new dimensions for the array. */
if (H5Dset_extent( dataset_id , dims ) < 0) TEST_ERROR;
/* Set new dimensions for the array. */
if (H5Dset_extent( dataset_id , dims ) < 0) TEST_ERROR;
/* Get the space. */
if ((space_id = H5Dget_space( dataset_id )) < 0) TEST_ERROR;
/* Get the space. */
if ((space_id = H5Dget_space( dataset_id )) < 0) TEST_ERROR;
/* Get dimensions. */
if (H5Sget_simple_extent_dims( space_id, dims_out, NULL ) < 0) TEST_ERROR;
/* Get dimensions. */
if (H5Sget_simple_extent_dims( space_id, dims_out, NULL ) < 0) TEST_ERROR;
if ( dims_out[0] != dims[0] ) TEST_ERROR;
if ( dims_out[0] != dims[0] ) TEST_ERROR;
/* Read the new dataset. */
if (H5Dread( dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf2 ) < 0) TEST_ERROR;
/* Read the new dataset. */
if (H5Dread( dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf2 ) < 0) TEST_ERROR;
/* Compare the read array with the original array */
for( i = 0; i < (int)dims_out[0]; i++ ) {
for( j = 0; j < (int)dims_out[1]; j++ ) {
if ( i >= 70 || j >= 70 ) {
if ( buf2[i][j] != 0 ) TEST_ERROR;
}
else {
if ( buf2[i][j] != data[i][j] ) TEST_ERROR;
/* Compare the read array with the original array */
for( i = 0; i < (int)dims_out[0]; i++ ) {
for( j = 0; j < (int)dims_out[1]; j++ ) {
if ( i >= 70 || j >= 70 ) {
if ( buf2[i][j] != 0 ) TEST_ERROR;
}
else {
if ( buf2[i][j] != data[i][j] ) TEST_ERROR;
}
}
}
}
/*-------------------------------------------------------------------------
* Close/release resources
*-------------------------------------------------------------------------
*/
/*-------------------------------------------------------------------------
* Close/release resources
*-------------------------------------------------------------------------
*/
H5Dclose( dataset_id );
H5Sclose( space_id );
H5Dclose( dataset_id );
H5Sclose( space_id );
H5Fclose( file_id );
H5Fclose( file_id );
PASSED();
PASSED();
#ifdef H5_HAVE_FILTER_DEFLATE
} /* end for */
#endif /* H5_HAVE_FILTER_DEFLATE */
puts("All set_extent tests passed.");
return 0;

View File

@ -200,7 +200,7 @@ main(int argc, char *argv[])
} /* end if */
ndims = (unsigned)extra;
status = H5D_istore_debug (f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, ndims);
status = H5D_istore_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, ndims);
break;
default: