summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5B2.c120
-rw-r--r--src/H5B2hdr.c10
-rw-r--r--src/H5B2int.c138
-rw-r--r--src/H5B2pkg.h30
-rw-r--r--src/H5D.c6
-rw-r--r--src/H5Dchunk.c436
-rw-r--r--src/H5Dcompact.c15
-rw-r--r--src/H5Dcontig.c13
-rw-r--r--src/H5Ddeprec.c44
-rw-r--r--src/H5Dearray.c12
-rw-r--r--src/H5Defl.c13
-rw-r--r--src/H5Dfarray.c6
-rw-r--r--src/H5Dint.c109
-rw-r--r--src/H5Dio.c19
-rw-r--r--src/H5Dmpio.c8
-rw-r--r--src/H5Dnone.c21
-rw-r--r--src/H5Dpkg.h21
-rw-r--r--src/H5VM.c126
-rw-r--r--src/H5VMprivate.h31
-rw-r--r--test/dsets.c10
20 files changed, 789 insertions, 399 deletions
diff --git a/src/H5B2.c b/src/H5B2.c
index e551f9b..a684d3a 100644
--- a/src/H5B2.c
+++ b/src/H5B2.c
@@ -306,11 +306,11 @@ H5B2_insert(H5B2_t *bt2, hid_t dxpl_id, void *udata)
/* Attempt to insert record into B-tree */
if(hdr->depth > 0) {
- if(H5B2_insert_internal(hdr, dxpl_id, hdr->depth, NULL, &hdr->root, hdr, udata) < 0)
+ if(H5B2_insert_internal(hdr, dxpl_id, hdr->depth, NULL, &hdr->root, H5B2_POS_ROOT, hdr, udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree internal node")
} /* end if */
else {
- if(H5B2_insert_leaf(hdr, dxpl_id, &hdr->root, hdr, udata) < 0)
+ if(H5B2_insert_leaf(hdr, dxpl_id, &hdr->root, H5B2_POS_ROOT, hdr, udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree leaf node")
} /* end else */
@@ -433,6 +433,7 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
unsigned depth; /* Current depth of the tree */
int cmp; /* Comparison value of records */
unsigned idx; /* Location of record which matches key */
+ H5B2_nodepos_t curr_pos; /* Position of the current node */
htri_t ret_value = TRUE; /* Return value */
FUNC_ENTER_NOAPI(FALSE)
@@ -453,6 +454,28 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
if(curr_node_ptr.node_nrec == 0)
HGOTO_DONE(FALSE)
+ /* Check record against min & max records in tree, to attempt to quickly
+ * find candidates or avoid further searching.
+ */
+ if(hdr->min_native_rec != NULL) {
+ if((cmp = (hdr->cls->compare)(udata, hdr->min_native_rec)) < 0)
+ HGOTO_DONE(FALSE) /* Less than the least record--not found */
+ else if(cmp == 0) { /* Record is found */
+ if(op && (op)(hdr->min_native_rec, op_data) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation")
+ HGOTO_DONE(TRUE)
+ } /* end if */
+ } /* end if */
+ if(hdr->max_native_rec != NULL) {
+ if((cmp = (hdr->cls->compare)(udata, hdr->max_native_rec)) > 0)
+ HGOTO_DONE(FALSE) /* Greater than the greatest record--not found */
+ else if(cmp == 0) { /* Record is found */
+ if(op && (op)(hdr->max_native_rec, op_data) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation")
+ HGOTO_DONE(TRUE)
+ } /* end if */
+ } /* end if */
+
/* Current depth of the tree */
depth = hdr->depth;
@@ -462,6 +485,7 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
/* Walk down B-tree to find record or leaf node where record is located */
cmp = -1;
+ curr_pos = H5B2_POS_ROOT;
while(depth > 0) {
H5B2_internal_t *internal; /* Pointer to internal node in B-tree */
H5B2_node_ptr_t next_node_ptr; /* Node pointer info for next node */
@@ -486,6 +510,24 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
/* Get node pointer for next node to search */
next_node_ptr=internal->node_ptrs[idx];
+ /* Set the position of the next node */
+ if(H5B2_POS_MIDDLE != curr_pos) {
+ if(idx == 0) {
+ if(H5B2_POS_LEFT == curr_pos || H5B2_POS_ROOT == curr_pos)
+ curr_pos = H5B2_POS_LEFT;
+ else
+ curr_pos = H5B2_POS_MIDDLE;
+ } /* end if */
+ else if(idx == internal->nrec) {
+ if(H5B2_POS_RIGHT == curr_pos || H5B2_POS_ROOT == curr_pos)
+ curr_pos = H5B2_POS_RIGHT;
+ else
+ curr_pos = H5B2_POS_MIDDLE;
+ } /* end if */
+ else
+ curr_pos = H5B2_POS_MIDDLE;
+ } /* end if */
+
/* Unlock current node */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, (unsigned)(hdr->swmr_write ? H5AC__PIN_ENTRY_FLAG : H5AC__NO_FLAGS_SET)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
@@ -553,6 +595,27 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation")
} /* end if */
+
+ /* Check for record being the min or max for the tree */
+ /* (Don't use 'else' for the idx check, to allow for root leaf node) */
+ if(H5B2_POS_MIDDLE != curr_pos) {
+ if(idx == 0) {
+ if(H5B2_POS_LEFT == curr_pos || H5B2_POS_ROOT == curr_pos) {
+ if(hdr->min_native_rec == NULL)
+ if(NULL == (hdr->min_native_rec = (uint8_t *)HDmalloc(hdr->cls->nrec_size)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree min record info")
+ HDmemcpy(hdr->min_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size);
+ } /* end if */
+ } /* end if */
+ if(idx == (unsigned)(leaf->nrec - 1)) {
+ if(H5B2_POS_RIGHT == curr_pos || H5B2_POS_ROOT == curr_pos) {
+ if(hdr->max_native_rec == NULL)
+ if(NULL == (hdr->max_native_rec = (uint8_t *)HDmalloc(hdr->cls->nrec_size)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree max record info")
+ HDmemcpy(hdr->max_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size);
+ } /* end if */
+ } /* end if */
+ } /* end if */
} /* end else */
/* Unlock current node */
@@ -805,8 +868,8 @@ H5B2_remove(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_remove_t op,
hbool_t depth_decreased = FALSE; /* Flag to indicate whether the depth of the B-tree decreased */
if(H5B2_remove_internal(hdr, dxpl_id, &depth_decreased, NULL, NULL,
- hdr->depth, &(hdr->cache_info), NULL, &hdr->root, udata, op,
- op_data) < 0)
+ hdr->depth, &(hdr->cache_info), NULL, H5B2_POS_ROOT, &hdr->root,
+ udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree internal node")
/* Check for decreasing the depth of the B-tree */
@@ -824,7 +887,7 @@ H5B2_remove(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_remove_t op,
} /* end for */
} /* end if */
else {
- if(H5B2_remove_leaf(hdr, dxpl_id, &hdr->root, hdr, udata, op, op_data) < 0)
+ if(H5B2_remove_leaf(hdr, dxpl_id, &hdr->root, H5B2_POS_ROOT, hdr, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree leaf node")
} /* end else */
@@ -894,8 +957,8 @@ H5B2_remove_by_idx(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order,
hbool_t depth_decreased = FALSE; /* Flag to indicate whether the depth of the B-tree decreased */
if(H5B2_remove_internal_by_idx(hdr, dxpl_id, &depth_decreased, NULL,
- NULL, hdr->depth, &(hdr->cache_info), NULL, &hdr->root, idx,
- udata, op, op_data) < 0)
+ NULL, hdr->depth, &(hdr->cache_info), NULL, &hdr->root,
+ H5B2_POS_ROOT, idx, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree internal node")
/* Check for decreasing the depth of the B-tree */
@@ -913,7 +976,7 @@ H5B2_remove_by_idx(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order,
} /* end for */
} /* end if */
else {
- if(H5B2_remove_leaf_by_idx(hdr, dxpl_id, &hdr->root, hdr, (unsigned)idx, op, op_data) < 0)
+ if(H5B2_remove_leaf_by_idx(hdr, dxpl_id, &hdr->root, H5B2_POS_ROOT, hdr, (unsigned)idx, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree leaf node")
} /* end else */
@@ -1048,6 +1111,7 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */
void *parent = NULL; /* Parent of current node */
+ H5B2_nodepos_t curr_pos; /* Position of current node */
unsigned depth; /* Current depth of the tree */
int cmp; /* Comparison value of records */
unsigned idx; /* Location of record which matches key */
@@ -1081,6 +1145,7 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
/* Walk down B-tree to find record or leaf node where record is located */
cmp = -1;
+ curr_pos = H5B2_POS_ROOT;
while(depth > 0) {
unsigned internal_flags = H5AC__NO_FLAGS_SET;
H5B2_internal_t *internal; /* Pointer to internal node in B-tree */
@@ -1106,6 +1171,24 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
/* Get node pointer for next node to search */
next_node_ptr = internal->node_ptrs[idx];
+ /* Set the position of the next node */
+ if(H5B2_POS_MIDDLE != curr_pos) {
+ if(idx == 0) {
+ if(H5B2_POS_LEFT == curr_pos || H5B2_POS_ROOT == curr_pos)
+ curr_pos = H5B2_POS_LEFT;
+ else
+ curr_pos = H5B2_POS_MIDDLE;
+ } /* end if */
+ else if(idx == internal->nrec) {
+ if(H5B2_POS_RIGHT == curr_pos || H5B2_POS_ROOT == curr_pos)
+ curr_pos = H5B2_POS_RIGHT;
+ else
+ curr_pos = H5B2_POS_MIDDLE;
+ } /* end if */
+ else
+ curr_pos = H5B2_POS_MIDDLE;
+ } /* end if */
+
/* Unlock current node */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, (unsigned)(hdr->swmr_write ? H5AC__PIN_ENTRY_FLAG : H5AC__NO_FLAGS_SET)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
@@ -1192,6 +1275,27 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
HGOTO_ERROR(H5E_BTREE, H5E_CANTMODIFY, FAIL, "'modify' callback failed for B-tree find operation")
} /* end if */
+
+ /* Check for modified record being the min or max for the tree */
+ /* (Don't use 'else' for the idx check, to allow for root leaf node) */
+ if(H5B2_POS_MIDDLE != curr_pos) {
+ if(idx == 0) {
+ if(H5B2_POS_LEFT == curr_pos || H5B2_POS_ROOT == curr_pos) {
+ if(hdr->min_native_rec == NULL)
+ if(NULL == (hdr->min_native_rec = (uint8_t *)HDmalloc(hdr->cls->nrec_size)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree min record info")
+ HDmemcpy(hdr->min_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size);
+ } /* end if */
+ } /* end if */
+ if(idx == (unsigned)(leaf->nrec - 1)) {
+ if(H5B2_POS_RIGHT == curr_pos || H5B2_POS_ROOT == curr_pos) {
+ if(hdr->max_native_rec == NULL)
+ if(NULL == (hdr->max_native_rec = (uint8_t *)HDmalloc(hdr->cls->nrec_size)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree max record info")
+ HDmemcpy(hdr->max_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size);
+ } /* end if */
+ } /* end if */
+ } /* end if */
} /* end else */
/* Mark the node as dirty if it changed */
diff --git a/src/H5B2hdr.c b/src/H5B2hdr.c
index 702854b..5e00139 100644
--- a/src/H5B2hdr.c
+++ b/src/H5B2hdr.c
@@ -553,6 +553,16 @@ H5B2_hdr_free(H5B2_hdr_t *hdr)
hdr->node_info = H5FL_SEQ_FREE(H5B2_node_info_t, hdr->node_info);
} /* end if */
+ /* Release the min & max record info, if set */
+ if(hdr->min_native_rec) {
+ HDfree(hdr->min_native_rec);
+ hdr->min_native_rec = NULL;
+ } /* end if */
+ if(hdr->max_native_rec) {
+ HDfree(hdr->max_native_rec);
+ hdr->max_native_rec = NULL;
+ } /* end if */
+
/* Free B-tree header info */
hdr = H5FL_FREE(H5B2_hdr_t, hdr);
diff --git a/src/H5B2int.c b/src/H5B2int.c
index bf76d5c..b8c5c8c 100644
--- a/src/H5B2int.c
+++ b/src/H5B2int.c
@@ -2272,7 +2272,7 @@ done:
*/
herr_t
H5B2_insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr,
- void *parent, void *udata)
+ H5B2_nodepos_t curr_pos, void *parent, void *udata)
{
H5B2_leaf_t *leaf; /* Pointer to leaf node */
int cmp; /* Comparison value of records */
@@ -2328,6 +2328,27 @@ H5B2_insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr,
/* Update record count for current node */
leaf->nrec++;
+ /* Check for new record being the min or max for the tree */
+ /* (Don't use 'else' for the idx check, to allow for root leaf node) */
+ if(H5B2_POS_MIDDLE != curr_pos) {
+ if(idx == 0) {
+ if(H5B2_POS_LEFT == curr_pos || H5B2_POS_ROOT == curr_pos) {
+ if(hdr->min_native_rec == NULL)
+ if(NULL == (hdr->min_native_rec = (uint8_t *)HDmalloc(hdr->cls->nrec_size)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree min record info")
+ HDmemcpy(hdr->min_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size);
+ } /* end if */
+ } /* end if */
+ if(idx == (unsigned)(leaf->nrec - 1)) {
+ if(H5B2_POS_RIGHT == curr_pos || H5B2_POS_ROOT == curr_pos) {
+ if(hdr->max_native_rec == NULL)
+ if(NULL == (hdr->max_native_rec = (uint8_t *)HDmalloc(hdr->cls->nrec_size)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree max record info")
+ HDmemcpy(hdr->max_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size);
+ } /* end if */
+ } /* end if */
+ } /* end if */
+
done:
/* Release the B-tree leaf node (marked as dirty) */
if(leaf && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, leaf, H5AC__DIRTIED_FLAG) < 0)
@@ -2353,11 +2374,12 @@ done:
herr_t
H5B2_insert_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
unsigned *parent_cache_info_flags_ptr, H5B2_node_ptr_t *curr_node_ptr,
- void *parent, void *udata)
+ H5B2_nodepos_t curr_pos, void *parent, void *udata)
{
H5B2_internal_t *internal = NULL; /* Pointer to internal node */
unsigned internal_flags = H5AC__NO_FLAGS_SET;
unsigned idx; /* Location of record which matches key */
+ H5B2_nodepos_t next_pos = H5B2_POS_MIDDLE; /* Position of node */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -2450,13 +2472,25 @@ H5B2_insert_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
} /* end while */
} /* end block */
+ /* Check if this node is left/right-most */
+ if(H5B2_POS_MIDDLE != curr_pos) {
+ if(idx == 0) {
+ if(H5B2_POS_LEFT == curr_pos || H5B2_POS_ROOT == curr_pos)
+ next_pos = H5B2_POS_LEFT;
+ } /* end if */
+ else if(idx == internal->nrec) {
+ if(H5B2_POS_RIGHT == curr_pos || H5B2_POS_ROOT == curr_pos)
+ next_pos = H5B2_POS_RIGHT;
+ } /* end else */
+ } /* end if */
+
/* Attempt to insert node */
if(depth > 1) {
- if(H5B2_insert_internal(hdr, dxpl_id, (depth - 1), &internal_flags, &internal->node_ptrs[idx], internal, udata) < 0)
+ if(H5B2_insert_internal(hdr, dxpl_id, (depth - 1), &internal_flags, &internal->node_ptrs[idx], next_pos, internal, udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree internal node")
} /* end if */
else {
- if(H5B2_insert_leaf(hdr, dxpl_id, &internal->node_ptrs[idx], internal, udata) < 0)
+ if(H5B2_insert_leaf(hdr, dxpl_id, &internal->node_ptrs[idx], next_pos, internal, udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree leaf node")
} /* end else */
@@ -2856,7 +2890,7 @@ done:
*/
herr_t
H5B2_remove_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr,
- void *parent, void *udata, H5B2_remove_t op, void *op_data)
+ H5B2_nodepos_t curr_pos, void *parent, void *udata, H5B2_remove_t op, void *op_data)
{
H5B2_leaf_t *leaf; /* Pointer to leaf node */
haddr_t leaf_addr = HADDR_UNDEF; /* Leaf address on disk */
@@ -2884,6 +2918,27 @@ H5B2_remove_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr,
if(H5B2_locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx) != 0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "record is not in B-tree")
+ /* Check for invalidating the min/max record for the tree */
+ if(H5B2_POS_MIDDLE != curr_pos) {
+ /* (Don't use 'else' for the idx check, to allow for root leaf node) */
+ if(idx == 0) {
+ if(H5B2_POS_LEFT == curr_pos || H5B2_POS_ROOT == curr_pos) {
+ if(hdr->min_native_rec) {
+ HDfree(hdr->min_native_rec);
+ hdr->min_native_rec = NULL;
+ } /* end if */
+ } /* end if */
+ } /* end if */
+ if(idx == (unsigned)(leaf->nrec - 1)) {
+ if(H5B2_POS_RIGHT == curr_pos || H5B2_POS_ROOT == curr_pos) {
+ if(hdr->max_native_rec) {
+ HDfree(hdr->max_native_rec);
+ hdr->max_native_rec = NULL;
+ } /* end if */
+ } /* end if */
+ } /* end if */
+ } /* end if */
+
/* Make 'remove' callback if there is one */
if(op)
if((op)(H5B2_LEAF_NREC(leaf, hdr, idx), op_data) < 0)
@@ -2945,8 +3000,8 @@ done:
herr_t
H5B2_remove_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, hbool_t *depth_decreased,
void *swap_loc, void *swap_parent, unsigned depth, H5AC_info_t *parent_cache_info,
- unsigned *parent_cache_info_flags_ptr, H5B2_node_ptr_t *curr_node_ptr,
- void *udata, H5B2_remove_t op, void *op_data)
+ unsigned *parent_cache_info_flags_ptr, H5B2_nodepos_t curr_pos,
+ H5B2_node_ptr_t *curr_node_ptr, void *udata, H5B2_remove_t op, void *op_data)
{
H5AC_info_t *new_cache_info; /* Pointer to new cache info */
unsigned *new_cache_info_flags_ptr = NULL;
@@ -2954,6 +3009,7 @@ H5B2_remove_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, hbool_t *depth_decreased,
H5B2_internal_t *internal; /* Pointer to internal node */
const H5AC_class_t *new_root_class; /* Pointer to new root node's class info */
void *new_root = NULL; /* Pointer to new root node (if old root collapsed) */
+ H5B2_nodepos_t next_pos = H5B2_POS_MIDDLE; /* Position of next node */
unsigned internal_flags = H5AC__NO_FLAGS_SET;
haddr_t internal_addr; /* Address of internal node */
size_t merge_nrec; /* Number of records to merge node at */
@@ -3058,6 +3114,9 @@ H5B2_remove_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, hbool_t *depth_decreased,
/* Set flag to indicate root was collapsed */
collapsed_root = TRUE;
+
+ /* Indicate position of next node */
+ next_pos = H5B2_POS_ROOT;
} /* end if */
/* Merge or redistribute child node pointers, if necessary */
else {
@@ -3165,16 +3224,28 @@ H5B2_remove_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, hbool_t *depth_decreased,
new_cache_info_flags_ptr = &internal_flags;
new_cache_info = &internal->cache_info;
new_node_ptr = &internal->node_ptrs[idx];
+
+ /* Indicate position of next node */
+ if(H5B2_POS_MIDDLE != curr_pos) {
+ if(idx == 0) {
+ if(H5B2_POS_LEFT == curr_pos || H5B2_POS_ROOT == curr_pos)
+ next_pos = H5B2_POS_LEFT;
+ } /* end if */
+ else if(idx == internal->nrec) {
+ if(H5B2_POS_RIGHT == curr_pos || H5B2_POS_ROOT == curr_pos)
+ next_pos = H5B2_POS_RIGHT;
+ } /* end if */
+ } /* end if */
} /* end else */
/* Attempt to remove record from child node */
if(depth > 1) {
if(H5B2_remove_internal(hdr, dxpl_id, depth_decreased, swap_loc, swap_parent, depth - 1,
- new_cache_info, new_cache_info_flags_ptr, new_node_ptr, udata, op, op_data) < 0)
+ new_cache_info, new_cache_info_flags_ptr, next_pos, new_node_ptr, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree internal node")
} /* end if */
else {
- if(H5B2_remove_leaf(hdr, dxpl_id, new_node_ptr, new_cache_info, udata, op, op_data) < 0)
+ if(H5B2_remove_leaf(hdr, dxpl_id, new_node_ptr, next_pos, new_cache_info, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree leaf node")
} /* end else */
@@ -3222,8 +3293,8 @@ done:
*/
herr_t
H5B2_remove_leaf_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id,
- H5B2_node_ptr_t *curr_node_ptr, void *parent, unsigned idx,
- H5B2_remove_t op, void *op_data)
+ H5B2_node_ptr_t *curr_node_ptr, H5B2_nodepos_t curr_pos, void *parent,
+ unsigned idx, H5B2_remove_t op, void *op_data)
{
H5B2_leaf_t *leaf; /* Pointer to leaf node */
haddr_t leaf_addr = HADDR_UNDEF; /* Leaf address on disk */
@@ -3247,6 +3318,27 @@ H5B2_remove_leaf_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id,
HDassert(leaf->nrec == curr_node_ptr->node_nrec);
HDassert(idx < leaf->nrec);
+ /* Check for invalidating the min/max record for the tree */
+ if(H5B2_POS_MIDDLE != curr_pos) {
+ /* (Don't use 'else' for the idx check, to allow for root leaf node) */
+ if(idx == 0) {
+ if(H5B2_POS_LEFT == curr_pos || H5B2_POS_ROOT == curr_pos) {
+ if(hdr->min_native_rec) {
+ HDfree(hdr->min_native_rec);
+ hdr->min_native_rec = NULL;
+ } /* end if */
+ } /* end if */
+ } /* end if */
+ if(idx == (unsigned)(leaf->nrec - 1)) {
+ if(H5B2_POS_RIGHT == curr_pos || H5B2_POS_ROOT == curr_pos) {
+ if(hdr->max_native_rec) {
+ HDfree(hdr->max_native_rec);
+ hdr->max_native_rec = NULL;
+ } /* end if */
+ } /* end if */
+ } /* end if */
+ } /* end if */
+
/* Make 'remove' callback if there is one */
if(op)
if((op)(H5B2_LEAF_NREC(leaf, hdr, idx), op_data) < 0)
@@ -3310,8 +3402,8 @@ herr_t
H5B2_remove_internal_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id,
hbool_t *depth_decreased, void *swap_loc, void *swap_parent, unsigned depth,
H5AC_info_t *parent_cache_info, unsigned *parent_cache_info_flags_ptr,
- H5B2_node_ptr_t *curr_node_ptr, hsize_t n, void *udata, H5B2_remove_t op,
- void *op_data)
+ H5B2_node_ptr_t *curr_node_ptr, H5B2_nodepos_t curr_pos, hsize_t n,
+ void *udata, H5B2_remove_t op, void *op_data)
{
H5AC_info_t *new_cache_info; /* Pointer to new cache info */
unsigned *new_cache_info_flags_ptr = NULL;
@@ -3319,6 +3411,7 @@ H5B2_remove_internal_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id,
const H5AC_class_t *new_root_class; /* Pointer to new root node's class info */
void *new_root = NULL; /* Pointer to new root node (if old root collapsed) */
H5B2_internal_t *internal; /* Pointer to internal node */
+ H5B2_nodepos_t next_pos = H5B2_POS_MIDDLE; /* Position of next node */
unsigned internal_flags = H5AC__NO_FLAGS_SET;
haddr_t internal_addr; /* Address of internal node */
size_t merge_nrec; /* Number of records to merge node at */
@@ -3426,6 +3519,9 @@ H5B2_remove_internal_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id,
/* Set flag to indicate root was collapsed */
collapsed_root = TRUE;
+
+ /* Indicate position of next node */
+ next_pos = H5B2_POS_ROOT;
} /* end if */
/* Merge or redistribute child node pointers, if necessary */
else {
@@ -3585,16 +3681,28 @@ H5B2_remove_internal_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id,
new_cache_info_flags_ptr = &internal_flags;
new_cache_info = &internal->cache_info;
new_node_ptr = &internal->node_ptrs[idx];
+
+ /* Indicate position of next node */
+ if(H5B2_POS_MIDDLE != curr_pos) {
+ if(idx == 0) {
+ if(H5B2_POS_LEFT == curr_pos || H5B2_POS_ROOT == curr_pos)
+ next_pos = H5B2_POS_LEFT;
+ } /* end if */
+ else if(idx == internal->nrec) {
+ if(H5B2_POS_RIGHT == curr_pos || H5B2_POS_ROOT == curr_pos)
+ next_pos = H5B2_POS_RIGHT;
+ } /* end if */
+ } /* end if */
} /* end else */
/* Attempt to remove record from child node */
if(depth > 1) {
if(H5B2_remove_internal_by_idx(hdr, dxpl_id, depth_decreased, swap_loc, swap_parent, depth - 1,
- new_cache_info, new_cache_info_flags_ptr, new_node_ptr, n, udata, op, op_data) < 0)
+ new_cache_info, new_cache_info_flags_ptr, new_node_ptr, next_pos, n, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree internal node")
} /* end if */
else {
- if(H5B2_remove_leaf_by_idx(hdr, dxpl_id, new_node_ptr, new_cache_info, (unsigned)n, op, op_data) < 0)
+ if(H5B2_remove_leaf_by_idx(hdr, dxpl_id, new_node_ptr, next_pos, new_cache_info, (unsigned)n, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree leaf node")
} /* end else */
diff --git a/src/H5B2pkg.h b/src/H5B2pkg.h
index 29cde6f..55e00d9 100644
--- a/src/H5B2pkg.h
+++ b/src/H5B2pkg.h
@@ -176,6 +176,8 @@ typedef struct H5B2_hdr_t {
hbool_t swmr_write; /* Whether we are doing SWMR writes */
struct H5B2_leaf_t *shadowed_leaf; /* Linked list of shadowed leaf nodes */
struct H5B2_internal_t *shadowed_internal; /* Linked list of shadowed internal nodes */
+ uint8_t *min_native_rec; /* Pointer to minimum native record */
+ uint8_t *max_native_rec; /* Pointer to maximum native record */
/* Client information (not stored) */
const H5B2_class_t *cls; /* Class of B-tree client */
@@ -218,6 +220,14 @@ struct H5B2_t {
H5F_t *f; /* Pointer to file for v2 B-tree */
};
+/* Node position, for min/max determination */
+typedef enum H5B2_nodepos_t {
+ H5B2_POS_ROOT, /* Node is root (i.e. both right & left-most in tree) */
+ H5B2_POS_RIGHT, /* Node is right-most in tree, at a given depth */
+ H5B2_POS_LEFT, /* Node is left-most in tree, at a given depth */
+ H5B2_POS_MIDDLE /* Node is neither right or left-most in tree */
+} H5B2_nodepos_t;
+
/* Callback info for loading a free space header into the cache */
typedef struct H5B2_hdr_cache_ud_t {
H5F_t *f; /* File that v2 b-tree header is within */
@@ -323,9 +333,9 @@ H5_DLL herr_t H5B2_internal_free(H5B2_internal_t *i);
/* Routines for inserting records */
H5_DLL herr_t H5B2_insert_internal(H5B2_hdr_t *hdr, hid_t dxpl_id,
unsigned depth, unsigned *parent_cache_info_flags_ptr,
- H5B2_node_ptr_t *curr_node_ptr, void *parent, void *udata);
+ H5B2_node_ptr_t *curr_node_ptr, H5B2_nodepos_t curr_pos, void *parent, void *udata);
H5_DLL herr_t H5B2_insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id,
- H5B2_node_ptr_t *curr_node_ptr, void *parent, void *udata);
+ H5B2_node_ptr_t *curr_node_ptr, H5B2_nodepos_t curr_pos, void *parent, void *udata);
/* Routines for iterating over nodes/records */
H5_DLL herr_t H5B2_iterate_node(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
@@ -349,19 +359,19 @@ H5_DLL herr_t H5B2_neighbor_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id,
H5_DLL herr_t H5B2_remove_internal(H5B2_hdr_t *hdr, hid_t dxpl_id,
hbool_t *depth_decreased, void *swap_loc, void *swap_parent, unsigned depth,
H5AC_info_t *parent_cache_info, hbool_t * parent_cache_info_dirtied_ptr,
- H5B2_node_ptr_t *curr_node_ptr, void *udata, H5B2_remove_t op,
- void *op_data);
+ H5B2_nodepos_t curr_pos, H5B2_node_ptr_t *curr_node_ptr, void *udata,
+ H5B2_remove_t op, void *op_data);
H5_DLL herr_t H5B2_remove_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id,
- H5B2_node_ptr_t *curr_node_ptr, void *parent, void *udata, H5B2_remove_t op,
- void *op_data);
+ H5B2_node_ptr_t *curr_node_ptr, H5B2_nodepos_t curr_pos, void *parent,
+ void *udata, H5B2_remove_t op, void *op_data);
H5_DLL herr_t H5B2_remove_internal_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id,
hbool_t *depth_decreased, void *swap_loc, void *swap_parent, unsigned depth,
H5AC_info_t *parent_cache_info, hbool_t * parent_cache_info_dirtied_ptr,
- H5B2_node_ptr_t *curr_node_ptr, hsize_t idx, void *udata, H5B2_remove_t op,
- void *op_data);
+ H5B2_node_ptr_t *curr_node_ptr, H5B2_nodepos_t curr_pos, hsize_t idx,
+ void *udata, H5B2_remove_t op, void *op_data);
H5_DLL herr_t H5B2_remove_leaf_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id,
- H5B2_node_ptr_t *curr_node_ptr, void *parent, unsigned idx,
- H5B2_remove_t op, void *op_data);
+ H5B2_node_ptr_t *curr_node_ptr, H5B2_nodepos_t curr_pos, void *parent,
+ unsigned idx, H5B2_remove_t op, void *op_data);
/* Routines for deleting nodes */
H5_DLL herr_t H5B2_delete_node(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth,
diff --git a/src/H5D.c b/src/H5D.c
index d8ae800..7445b70 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -1040,8 +1040,8 @@ done:
herr_t
H5Drefresh(hid_t dset_id)
{
- H5D_t * dset = NULL;
- hid_t ret_value = SUCCEED; /* return value */
+ H5D_t *dset; /* Dataset to refresh */
+ herr_t ret_value = SUCCEED; /* return value */
FUNC_ENTER_API(FAIL)
H5TRACE1("e", "i", dset_id);
@@ -1051,7 +1051,7 @@ H5Drefresh(hid_t dset_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
/* Call private function to refresh dataset object */
- if ((H5O_refresh_metadata(dset_id, dset->oloc, H5AC_dxpl_id)) < 0)
+ if((H5O_refresh_metadata(dset_id, dset->oloc, H5AC_dxpl_id)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTLOAD, FAIL, "unable to refresh dataset")
done:
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index 2557d1a..1311ba9 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -233,11 +233,11 @@ static herr_t H5D__chunk_file_cb(void *elem, hid_t type_id, unsigned ndims,
const hsize_t *coords, void *fm);
static herr_t H5D__chunk_mem_cb(void *elem, hid_t type_id, unsigned ndims,
const hsize_t *coords, void *fm);
+static size_t H5D__chunk_hash_val(const H5D_shared_t *shared, const hsize_t *scaled);
static herr_t H5D__chunk_cache_evict(const H5D_t *dset, hid_t dxpl_id,
const H5D_dxpl_cache_t *dxpl_cache, H5D_rdcc_ent_t *ent, hbool_t flush);
-static htri_t H5D__chunk_is_partial_edge_chunk(const hsize_t offset[],
- const H5D_t *dset, unsigned dset_ndims, const hsize_t *dset_dims,
- const uint32_t *chunk_dims);
+static hbool_t H5D__chunk_is_partial_edge_chunk(const hsize_t *chunk_offset,
+ unsigned dset_ndims, const hsize_t *dset_dims, const uint32_t *chunk_dims);
static herr_t H5D__chunk_cache_prune(const H5D_t *dset, hid_t dxpl_id,
const H5D_dxpl_cache_t *dxpl_cache, size_t size);
static herr_t H5D__chunk_prune_fill(H5D_chunk_it_ud1_t *udata, hbool_t new_unfilt_chunk);
@@ -323,15 +323,13 @@ H5D__chunk_direct_write(const H5D_t *dset, hid_t dxpl_id, uint32_t filters, hsiz
uint32_t data_size, const void *buf)
{
const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset layout */
- H5D_chunk_ud_t udata; /* User data for querying chunk info */
- hsize_t chunk_idx;
+ H5D_chunk_ud_t udata; /* User data for querying chunk info */
H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */
H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */
const H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /*raw data chunk cache */
- int space_ndims; /* Dataset's space rank */
- hsize_t space_dim[H5O_LAYOUT_NDIMS]; /* Dataset's dataspace dimensions */
H5D_chk_idx_info_t idx_info; /* Chunked index info */
- herr_t ret_value = SUCCEED; /* Return value */
+ hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for this chunk */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC_TAG(dxpl_id, dset->oloc.addr, FAIL)
@@ -342,18 +340,11 @@ H5D__chunk_direct_write(const H5D_t *dset, hid_t dxpl_id, uint32_t filters, hsiz
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage")
} /* end if */
-
- /* Retrieve the dataset dimensions */
- if((space_ndims = H5S_get_simple_extent_dims(dset->shared->space, space_dim, NULL)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get simple dataspace info")
-
/* Calculate the index of this chunk */
- if(H5VM_chunk_index((unsigned)space_ndims, offset,
- layout->u.chunk.dim, layout->u.chunk.down_chunks, &chunk_idx) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't get chunk index")
+ H5VM_chunk_scaled(dset->shared->ndims, offset, layout->u.chunk.dim, scaled);
/* Find out the file address of the chunk */
- if(H5D__chunk_lookup(dset, dxpl_id, offset, chunk_idx, &udata) < 0)
+ if(H5D__chunk_lookup(dset, dxpl_id, offset, scaled, &udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
udata.filter_mask = filters;
@@ -473,24 +464,15 @@ done:
herr_t
H5D__chunk_set_info(const H5D_t *dset)
{
- hsize_t curr_dims[H5O_LAYOUT_NDIMS]; /* Curr. size of dataset dimensions */
- hsize_t max_dims[H5O_LAYOUT_NDIMS]; /* Max. size of dataset dimensions */
- int sndims; /* Rank of dataspace */
- unsigned ndims; /* Rank of dataspace */
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
/* Sanity checks */
HDassert(dset);
- /* Get the dim info for dataset */
- if((sndims = H5S_get_simple_extent_dims(dset->shared->space, curr_dims, max_dims)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataspace dimensions")
- H5_ASSIGN_OVERFLOW(ndims, sndims, int, unsigned);
-
/* Set the base layout information */
- if(H5D__chunk_set_info_real(&dset->shared->layout.u.chunk, ndims, curr_dims, max_dims) < 0)
+ if(H5D__chunk_set_info_real(&dset->shared->layout.u.chunk, dset->shared->ndims, dset->shared->curr_dims, dset->shared->max_dims) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set layout's chunk info")
/* Call the index's "resize" callback */
@@ -518,10 +500,7 @@ static herr_t
H5D__chunk_construct(H5F_t UNUSED *f, H5D_t *dset)
{
const H5T_t *type = dset->shared->type; /* Convenience pointer to dataset's datatype */
- hsize_t max_dims[H5O_LAYOUT_NDIMS]; /* Maximum size of data in elements */
- hsize_t dims[H5O_LAYOUT_NDIMS]; /* Dimension size of data in elements */
uint64_t chunk_size; /* Size of chunk in bytes */
- int ndims; /* Rank of dataspace */
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -536,9 +515,7 @@ H5D__chunk_construct(H5F_t UNUSED *f, H5D_t *dset)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "no chunk information set?")
/* Set up layout information */
- if((ndims = H5S_GET_EXTENT_NDIMS(dset->shared->space)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get rank")
- if(dset->shared->layout.u.chunk.ndims != (unsigned)ndims)
+ if(dset->shared->layout.u.chunk.ndims != dset->shared->ndims)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "dimensionality of chunks doesn't match the dataspace")
/* Increment # of chunk dimensions, to account for datatype size as last element */
@@ -552,10 +529,6 @@ H5D__chunk_construct(H5F_t UNUSED *f, H5D_t *dset)
/* Set the last dimension of the chunk size to the size of the datatype */
dset->shared->layout.u.chunk.dim[dset->shared->layout.u.chunk.ndims - 1] = (uint32_t)H5T_GET_SIZE(type);
- /* Get local copy of dataset dimensions (for sanity checking) */
- if(H5S_get_simple_extent_dims(dset->shared->space, dims, max_dims) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to query maximum dimensions")
-
/* Sanity check dimensions */
for(u = 0; u < dset->shared->layout.u.chunk.ndims - 1; u++) {
/* Don't allow zero-sized chunk dimensions */
@@ -567,7 +540,7 @@ H5D__chunk_construct(H5F_t UNUSED *f, H5D_t *dset)
* the maximum dimension size. If any dimension size is zero, there
* will be no such restriction.
*/
- if(dims[u] && max_dims[u] != H5S_UNLIMITED && max_dims[u] < dset->shared->layout.u.chunk.dim[u])
+ if(dset->shared->curr_dims[u] && dset->shared->max_dims[u] != H5S_UNLIMITED && dset->shared->max_dims[u] < dset->shared->layout.u.chunk.dim[u])
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "chunk size must be <= maximum dimension size for fixed-sized dimensions")
} /* end for */
@@ -1197,8 +1170,7 @@ H5D__create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t
chunk_info->coords[fm->f_ndims] = 0;
/* Calculate the index of this chunk */
- if(H5VM_chunk_index(fm->f_ndims, chunk_info->coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_info->index) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
+ chunk_info->index = H5VM_chunk_index_scaled(fm->f_ndims, chunk_info->coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, chunk_info->scaled);
/* Copy selection for file's dataspace into chunk dataspace */
if(H5S_select_copy(fm->single_space, fm->file_space, FALSE) < 0)
@@ -1258,6 +1230,7 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t
hsize_t coords[H5O_LAYOUT_NDIMS]; /* Current coordinates of chunk */
hsize_t end[H5O_LAYOUT_NDIMS]; /* Current coordinates of chunk */
hsize_t chunk_index; /* Index of chunk */
+ hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for this chunk */
int curr_dim; /* Current dimension to increment */
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1282,8 +1255,7 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t
} /* end for */
/* Calculate the index of this chunk */
- if(H5VM_chunk_index(fm->f_ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_index) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
+ chunk_index = H5VM_chunk_index_scaled(fm->f_ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, scaled);
/* Iterate through each chunk in the dataset */
while(sel_points) {
@@ -1350,9 +1322,11 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t
new_chunk_info->mspace_shared = FALSE;
/* Copy the chunk's coordinates */
- for(u=0; u<fm->f_ndims; u++)
- new_chunk_info->coords[u]=coords[u];
- new_chunk_info->coords[fm->f_ndims]=0;
+ HDmemcpy(new_chunk_info->coords, coords, sizeof(hsize_t) * fm->f_ndims);
+ new_chunk_info->coords[fm->f_ndims] = 0;
+
+ /* Copy the chunk's scaled coordinates */
+ HDmemcpy(new_chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims);
/* Insert the new chunk into the skip list */
if(H5SL_insert(fm->sel_chunks, new_chunk_info, &new_chunk_info->index) < 0) {
@@ -1383,6 +1357,7 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t
H5_CHECK_OVERFLOW(fm->chunk_dim[curr_dim],hsize_t,hssize_t);
coords[curr_dim]+=fm->chunk_dim[curr_dim];
end[curr_dim]+=fm->chunk_dim[curr_dim];
+ scaled[curr_dim]++;
/* Bring chunk location back into bounds, if necessary */
if(coords[curr_dim] > sel_end[curr_dim]) {
@@ -1400,8 +1375,8 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t
} while(coords[curr_dim] > sel_end[curr_dim]);
/* Re-calculate the index of this chunk */
- if(H5VM_chunk_index(fm->f_ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_index) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
+ /* (Technically, adjusting the scaled[] values could be moved inside loop above -QAK) */
+ chunk_index = H5VM_chunk_index_scaled(fm->f_ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, scaled);
} /* end if */
} /* end while */
@@ -1541,16 +1516,16 @@ H5D__chunk_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, cons
H5D_chunk_file_iter_ud_t *udata = (H5D_chunk_file_iter_ud_t *)_udata; /* User data for operation */
H5D_chunk_map_t *fm = udata->fm; /* File<->memory chunk mapping info */
H5D_chunk_info_t *chunk_info; /* Chunk information for current chunk */
- hsize_t coords_in_chunk[H5O_LAYOUT_NDIMS]; /* Coordinates of element in chunk */
+ hsize_t coords_in_chunk[H5O_LAYOUT_NDIMS]; /* Coordinates of element in chunk */
hsize_t chunk_index; /* Chunk index */
+ hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for this chunk */
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
/* Calculate the index of this chunk */
- if(H5VM_chunk_index(ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_index) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
+ chunk_index = H5VM_chunk_index_scaled(ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, scaled);
/* Find correct chunk in file & memory skip list */
if(chunk_index==fm->last_index) {
@@ -1603,9 +1578,10 @@ H5D__chunk_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, cons
/* Compute the chunk's coordinates */
for(u = 0; u < fm->f_ndims; u++) {
H5_CHECK_OVERFLOW(fm->layout->u.chunk.dim[u], hsize_t, hssize_t);
- chunk_info->coords[u] = (coords[u] / (hssize_t)fm->layout->u.chunk.dim[u]) * (hssize_t)fm->layout->u.chunk.dim[u];
+ chunk_info->coords[u] = scaled[u] * (hssize_t)fm->layout->u.chunk.dim[u];
} /* end for */
chunk_info->coords[fm->f_ndims] = 0;
+ HDmemcpy(chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims);
/* Insert the new chunk into the skip list */
if(H5SL_insert(fm->sel_chunks,chunk_info,&chunk_info->index) < 0) {
@@ -1667,8 +1643,7 @@ H5D__chunk_mem_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const
FUNC_ENTER_STATIC
/* Calculate the index of this chunk */
- if(H5VM_chunk_index(ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_index) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
+ chunk_index = H5VM_chunk_index(ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks);
/* Find correct chunk in file & memory skip list */
if(chunk_index == fm->last_index) {
@@ -1737,7 +1712,7 @@ htri_t
H5D__chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr, hbool_t write_op)
{
const H5D_t *dataset = io_info->dset;
- htri_t no_filters = TRUE;
+ hbool_t no_filters = TRUE;
htri_t ret_value = FAIL;
FUNC_ENTER_PACKAGE
@@ -1751,9 +1726,10 @@ H5D__chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr, hbool_t write_
if(dataset->shared->dcpl_cache.pline.nused > 0) {
if(dataset->shared->layout.u.chunk.flags
& H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS) {
- if((no_filters = H5D__chunk_is_partial_edge_chunk(
- io_info->store->chunk.offset, io_info->dset, 0, NULL, NULL)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to determine if chunk is edge chunk")
+ no_filters = H5D__chunk_is_partial_edge_chunk(
+ io_info->store->chunk.offset, io_info->dset->shared->ndims,
+ io_info->dset->shared->curr_dims,
+ io_info->dset->shared->layout.u.chunk.dim);
} /* end if */
else
no_filters = FALSE;
@@ -1896,7 +1872,7 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
/* Get the info for the chunk in the file */
- if(H5D__chunk_lookup(io_info->dset, io_info->dxpl_id, chunk_info->coords, chunk_info->index, &udata) < 0)
+ if(H5D__chunk_lookup(io_info->dset, io_info->dxpl_id, chunk_info->coords, chunk_info->scaled, &udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
/* Check for non-existant chunk & skip it if appropriate */
@@ -1911,8 +1887,6 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
if(cacheable) {
/* Load the chunk into cache and lock it. */
- /* Pass in chunk's index. */
- io_info->store->chunk.index = chunk_info->index;
/* Compute # of bytes accessed in chunk */
H5_CHECK_OVERFLOW(type_info->src_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
@@ -2029,7 +2003,7 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
/* Look up the chunk */
- if(H5D__chunk_lookup(io_info->dset, io_info->dxpl_id, chunk_info->coords, chunk_info->index, &udata) < 0)
+ if(H5D__chunk_lookup(io_info->dset, io_info->dxpl_id, chunk_info->coords, chunk_info->scaled, &udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
/* Pass in chunk's coordinates. */
@@ -2044,9 +2018,6 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
* simply allocate space instead of load the chunk. */
hbool_t entire_chunk = TRUE; /* Whether whole chunk is selected */
- /* Pass in chunk's index. */
- io_info->store->chunk.index = chunk_info->index;
-
/* Compute # of bytes accessed in chunk */
H5_CHECK_OVERFLOW(type_info->dst_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
dst_accessed_bytes = chunk_info->chunk_points * (uint32_t)type_info->dst_type_size;
@@ -2313,8 +2284,6 @@ H5D__chunk_cinfo_cache_reset(H5D_chunk_cached_t *last)
static herr_t
H5D__chunk_cinfo_cache_update(H5D_chunk_cached_t *last, const H5D_chunk_ud_t *udata)
{
- unsigned u; /* Local index variable */
-
FUNC_ENTER_STATIC_NOERR
/* Sanity check */
@@ -2325,8 +2294,7 @@ H5D__chunk_cinfo_cache_update(H5D_chunk_cached_t *last, const H5D_chunk_ud_t *ud
HDassert(udata->common.offset);
/* Stored the information to cache */
- for(u = 0; u < udata->common.layout->ndims; u++)
- last->offset[u] = udata->common.offset[u];
+ HDmemcpy(last->offset, udata->common.offset, sizeof(hsize_t) * udata->common.layout->ndims);
last->nbytes = udata->nbytes;
last->chunk_idx = udata->chunk_idx;
last->filter_mask = udata->filter_mask;
@@ -2452,6 +2420,53 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D__chunk_hash_val
+ *
+ * Purpose: To calculate an index based on the dataset's scaled coordinates and
+ * sizes of the faster dimensions.
+ *
+ * Return: Hash value index
+ *
+ * Programmer: Vailin Choi; Nov 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5D__chunk_hash_val(const H5D_shared_t *shared, const hsize_t *scaled)
+{
+ hsize_t val; /* Intermediate value */
+ size_t ret; /* Value to return */
+ unsigned ndims = shared->layout.u.chunk.ndims - 1; /* Rank of dataset */
+
+ FUNC_ENTER_STATIC_NOERR
+
+ /* Sanity check */
+ HDassert(shared);
+ HDassert(scaled);
+
+ /* If the fastest changing dimension doesn't have enough entropy, use
+ * other dimensions too
+ */
+ if(ndims > 1 && shared->curr_dims[ndims - 1] <= shared->cache.chunk.nslots) {
+ unsigned u; /* Local index variable */
+
+ val = scaled[0];
+ for(u = 1; u < ndims; u++) {
+ val <<= H5VM_log2_gen(H5VM_power2up(shared->curr_dims[u]));
+ val ^= scaled[u];
+ } /* end for */
+ } /* end if */
+ else
+ val = scaled[ndims - 1];
+
+ /* Modulo value against the number of array slots */
+ ret = val % shared->cache.chunk.nslots;
+
+ FUNC_LEAVE_NOAPI(ret)
+} /* H5D__chunk_hash_val() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D__chunk_lookup
*
* Purpose: Loops up a chunk in cache and on disk, and retrieves
@@ -2466,7 +2481,7 @@ done:
*/
herr_t
H5D__chunk_lookup(const H5D_t *dset, hid_t dxpl_id, const hsize_t *chunk_offset,
- hsize_t chunk_idx, H5D_chunk_ud_t *udata)
+ const hsize_t *scaled, H5D_chunk_ud_t *udata)
{
H5D_rdcc_ent_t *ent = NULL; /* Cache entry */
hbool_t found = FALSE; /* In cache? */
@@ -2495,6 +2510,8 @@ H5D__chunk_lookup(const H5D_t *dset, hid_t dxpl_id, const hsize_t *chunk_offset,
udata->common.storage = &(dset->shared->layout.storage.u.chunk);
udata->common.offset = chunk_offset;
udata->common.rdcc = &(dset->shared->cache.chunk);
+ udata->common.space_dim = dset->shared->curr_dims;
+ udata->common.scaled = scaled;
/* Reset information about the chunk we are looking for */
udata->nbytes = 0;
@@ -2506,7 +2523,7 @@ H5D__chunk_lookup(const H5D_t *dset, hid_t dxpl_id, const hsize_t *chunk_offset,
/* Check for chunk in cache */
if(dset->shared->cache.chunk.nslots > 0) {
- udata->idx_hint = H5D_CHUNK_HASH(dset->shared, chunk_idx);
+ udata->idx_hint = H5D__chunk_hash_val(dset->shared, scaled);
ent = dset->shared->cache.chunk.slot[udata->idx_hint];
if(ent)
@@ -2521,7 +2538,7 @@ H5D__chunk_lookup(const H5D_t *dset, hid_t dxpl_id, const hsize_t *chunk_offset,
/* Find chunk addr */
if(found) {
udata->addr = ent->chunk_addr;
- udata->chunk_idx = chunk_idx;
+ udata->chunk_idx = ent->chunk_idx;
} else {
/* Invalidate idx_hint, to signal that the chunk is not in cache */
udata->idx_hint = UINT_MAX;
@@ -2603,6 +2620,8 @@ H5D__chunk_flush_entry(const H5D_t *dset, hid_t dxpl_id, const H5D_dxpl_cache_t
udata.common.storage = &dset->shared->layout.storage.u.chunk;
udata.common.offset = ent->offset;
udata.common.rdcc = &(dset->shared->cache.chunk);
+ udata.common.scaled = ent->scaled;
+
udata.filter_mask = 0;
udata.nbytes = dset->shared->layout.u.chunk.size;
udata.addr = ent->chunk_addr;
@@ -2980,7 +2999,6 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
H5D_rdcc_ent_t *ent = NULL; /*cache entry */
haddr_t chunk_addr = HADDR_UNDEF; /* Address of chunk on disk */
size_t chunk_size; /*size of a chunk */
- htri_t is_edge_chunk; /* Whether the chunk is an edge chunk */
hbool_t disable_filters = FALSE; /* Whether to disable filters (when adding to cache) */
void *chunk = NULL; /*the file chunk */
unsigned u; /*counters */
@@ -3104,11 +3122,9 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
else if(layout->u.chunk.flags
& H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS) {
/* Check if this is an edge chunk */
- if((is_edge_chunk = H5D__chunk_is_partial_edge_chunk(
- io_info->store->chunk.offset, io_info->dset, 0, NULL, layout->u.chunk.dim)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to determine if chunk is edge chunk")
-
- if(is_edge_chunk) {
+ if(H5D__chunk_is_partial_edge_chunk(
+ io_info->store->chunk.offset, io_info->dset->shared->ndims,
+ io_info->dset->shared->curr_dims, layout->u.chunk.dim)) {
/* Disable the filters for both writing and reading */
disable_filters = TRUE;
old_pline = NULL;
@@ -3256,7 +3272,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
} /* end if */
else if(rdcc->nslots > 0 && chunk_size <= rdcc->nbytes_max) {
/* Calculate the index */
- udata->idx_hint = H5D_CHUNK_HASH(dset->shared, io_info->store->chunk.index);
+ udata->idx_hint = H5D__chunk_hash_val(io_info->dset->shared, udata->common.scaled);
/* Add the chunk to the cache only if the slot is not already locked */
ent = rdcc->slot[udata->idx_hint];
@@ -3281,8 +3297,9 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
ent->deleted = FALSE;
ent->chunk_addr = chunk_addr;
ent->chunk_idx = udata->chunk_idx;
- for(u = 0; u < layout->u.chunk.ndims; u++)
- ent->offset[u] = io_info->store->chunk.offset[u];
+ HDmemcpy(ent->offset, io_info->store->chunk.offset, sizeof(hsize_t) * layout->u.chunk.ndims);
+ HDmemcpy(ent->scaled, udata->common.scaled, sizeof(hsize_t) * layout->u.chunk.ndims);
+
H5_ASSIGN_OVERFLOW(ent->rd_count, chunk_size, size_t, uint32_t);
H5_ASSIGN_OVERFLOW(ent->wr_count, chunk_size, size_t, uint32_t);
ent->chunk = (uint8_t *)chunk;
@@ -3388,7 +3405,7 @@ H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata,
* Note: we have to copy the layout and filter messages so we
* don't discard the `const' qualifier.
*/
- htri_t is_unfiltered_edge_chunk = FALSE; /* Whether the chunk is an unfiltered edge chunk */
+ hbool_t is_unfiltered_edge_chunk = FALSE; /* Whether the chunk is an unfiltered edge chunk */
/* Check if we should disable filters on this chunk */
if(udata->new_unfilt_chunk) {
@@ -3400,9 +3417,9 @@ H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata,
else if(layout->u.chunk.flags
& H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS) {
/* Check if the chunk is an edge chunk, and disable filters if so */
- if((is_unfiltered_edge_chunk = H5D__chunk_is_partial_edge_chunk(
- io_info->store->chunk.offset, io_info->dset, 0, NULL, layout->u.chunk.dim)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to determine if chunk is edge chunk")
+ is_unfiltered_edge_chunk = H5D__chunk_is_partial_edge_chunk(
+ io_info->store->chunk.offset, io_info->dset->shared->ndims,
+ io_info->dset->shared->curr_dims, layout->u.chunk.dim);
} /* end if */
if(dirty) {
@@ -3415,6 +3432,7 @@ H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata,
if(udata->new_unfilt_chunk)
fake_ent.edge_chunk_state |= H5D_RDCC_NEWLY_DISABLED_FILTERS;
HDmemcpy(fake_ent.offset, io_info->store->chunk.offset, layout->u.chunk.ndims * sizeof(fake_ent.offset[0]));
+ HDmemcpy(fake_ent.scaled, udata->common.scaled, sizeof(hsize_t) * layout->u.chunk.ndims);
HDassert(layout->u.chunk.size > 0);
fake_ent.chunk_idx = udata->chunk_idx;
fake_ent.chunk_addr = udata->addr;
@@ -3595,10 +3613,10 @@ H5D__chunk_allocate(const H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite,
H5D_chunk_coll_info_t chunk_info; /* chunk address information for doing I/O */
#endif /* H5_HAVE_PARALLEL */
hbool_t carry; /* Flag to indicate that chunk increment carrys to higher dimension (sorta) */
- int space_ndims; /* Dataset's space rank */
- hsize_t space_dim[H5O_LAYOUT_NDIMS]; /* Dataset's dataspace dimensions */
+ unsigned space_ndims; /* Dataset's space rank */
+ const hsize_t *space_dim; /* Dataset's dataspace dimensions */
const uint32_t *chunk_dim = layout->u.chunk.dim; /* Convenience pointer to chunk dimensions */
- int op_dim; /* Current operationg dimension */
+ unsigned op_dim; /* Current operationg dimension */
H5D_fill_buf_info_t fb_info; /* Dataset's fill buffer info */
hbool_t fb_info_init = FALSE; /* Whether the fill value buffer has been initialized */
hbool_t has_unfilt_edge_chunks = FALSE; /* Whether there are partial edge chunks with disabled filters */
@@ -3625,9 +3643,8 @@ H5D__chunk_allocate(const H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite,
HDassert(TRUE == H5P_isa_class(dxpl_id, H5P_DATASET_XFER));
/* Retrieve the dataset dimensions */
- if((space_ndims = H5S_get_simple_extent_dims(dset->shared->space, space_dim, NULL)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get simple dataspace info")
- space_dim[space_ndims] = layout->u.chunk.dim[space_ndims];
+ space_dim = dset->shared->curr_dims;
+ space_ndims = dset->shared->ndims;
/* The last dimension in chunk_offset is always 0 */
chunk_offset[space_ndims] = (hsize_t)0;
@@ -3772,6 +3789,7 @@ H5D__chunk_allocate(const H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite,
chunk_size = orig_chunk_size;
for(op_dim=0; op_dim<space_ndims; op_dim++) {
H5D_chunk_ud_t udata; /* User data for querying chunk info */
+ unsigned u; /* Local index variable */
int i; /* Local index variable */
/* Check if allocation along this dimension is really necessary */
@@ -3779,16 +3797,15 @@ H5D__chunk_allocate(const H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite,
continue;
else {
/* Reset the chunk offset indices */
- HDmemset(chunk_offset, 0, ((unsigned)space_ndims
- * sizeof(chunk_offset[0])));
+ HDmemset(chunk_offset, 0, (space_ndims * sizeof(chunk_offset[0])));
chunk_offset[op_dim] = min_unalloc[op_dim];
if(has_unfilt_edge_chunks) {
/* Initialize nunfilt_edge_chunk_dims */
nunfilt_edge_chunk_dims = 0;
- for(i=0; i<space_ndims; i++)
- if(unfilt_edge_chunk_dim[i] && chunk_offset[i]
- == edge_chunk_offset[i])
+ for(u = 0; u < space_ndims; u++)
+ if(unfilt_edge_chunk_dim[u] && chunk_offset[u]
+ == edge_chunk_offset[u])
nunfilt_edge_chunk_dims++;
/* Initialize chunk_size and fill_buf */
@@ -3811,13 +3828,11 @@ H5D__chunk_allocate(const H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite,
while(!carry) {
/* None of the chunks should be allocated */
- hsize_t chunk_idx;
+ hsize_t scaled[H5O_LAYOUT_NDIMS]; /* Scaled coordinates for this chunk */
- /* Calculate the index of this chunk */
- if(H5VM_chunk_index((unsigned)space_ndims, chunk_offset, layout->u.chunk.dim,
- layout->u.chunk.down_chunks, &chunk_idx) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't get chunk index")
- if(H5D__chunk_lookup(dset, dxpl_id, chunk_offset, chunk_idx, &udata) < 0)
+ /* Look up this chunk */
+ H5VM_chunk_scaled(space_ndims, chunk_offset, layout->u.chunk.dim, scaled);
+ if(H5D__chunk_lookup(dset, dxpl_id, chunk_offset, scaled, &udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
#ifndef NDEBUG
@@ -3828,9 +3843,9 @@ H5D__chunk_allocate(const H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite,
* original dimensions */
{
hbool_t outside_orig = FALSE;
- for(i=0; i<space_ndims; i++) {
- HDassert(chunk_offset[i] < space_dim[i]);
- if(chunk_offset[i] >= old_dim[i])
+ for(u = 0; u < space_ndims; u++) {
+ HDassert(chunk_offset[u] < space_dim[u]);
+ if(chunk_offset[u] >= old_dim[u])
outside_orig = TRUE;
} /* end for */
HDassert(outside_orig);
@@ -3941,10 +3956,10 @@ H5D__chunk_allocate(const H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite,
/* Increment indices and adjust the edge chunk state */
carry = TRUE;
- for(i = (space_ndims - 1); i >= 0; --i) {
+ for(i = ((int)space_ndims - 1); i >= 0; --i) {
chunk_offset[i] += chunk_dim[i];
if(chunk_offset[i] > max_unalloc[i]) {
- if(i == op_dim)
+ if((unsigned)i == op_dim)
chunk_offset[i] = min_unalloc[i];
else
chunk_offset[i] = 0;
@@ -3957,7 +3972,7 @@ H5D__chunk_allocate(const H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite,
if(should_fill && nunfilt_edge_chunk_dims == 0
&& !fb_info.has_vlen_fill_type) {
HDassert(!H5D__chunk_is_partial_edge_chunk(
- chunk_offset, NULL, (unsigned)space_ndims,
+ chunk_offset, space_ndims,
space_dim, chunk_dim));
fill_buf = &fb_info.fill_buf;
chunk_size = orig_chunk_size;
@@ -3973,7 +3988,7 @@ H5D__chunk_allocate(const H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite,
if(should_fill && nunfilt_edge_chunk_dims == 1
&& !fb_info.has_vlen_fill_type) {
HDassert(H5D__chunk_is_partial_edge_chunk(
- chunk_offset, NULL, (unsigned)space_ndims,
+ chunk_offset, space_ndims,
space_dim, chunk_dim));
fill_buf = &unfilt_fill_buf;
chunk_size = layout->u.chunk.size;
@@ -4051,9 +4066,9 @@ H5D__chunk_update_old_edge_chunks(H5D_t *dset, hid_t dxpl_id, hsize_t old_dim[])
const H5O_pline_t *pline = &(dset->shared->dcpl_cache.pline); /* I/O pipeline info */
hsize_t chunk_offset[H5O_LAYOUT_NDIMS]; /* Offset of current chunk */
const uint32_t *chunk_dim = layout->u.chunk.dim; /* Convenience pointer to chunk dimensions */
- int space_ndims; /* Dataset's space rank */
- hsize_t space_dim[H5O_LAYOUT_NDIMS]; /* Dataset's dataspace dimensions */
- int op_dim; /* Current operationg dimension */
+ unsigned space_ndims; /* Dataset's space rank */
+ const hsize_t *space_dim; /* Dataset's dataspace dimensions */
+ unsigned op_dim; /* Current operationg dimension */
H5D_io_info_t chk_io_info; /* Chunked I/O info object */
H5D_chunk_ud_t chk_udata; /* User data for locking chunk */
H5D_storage_t chk_store; /* Chunk storage information */
@@ -4084,9 +4099,8 @@ H5D__chunk_update_old_edge_chunks(H5D_t *dset, hid_t dxpl_id, hsize_t old_dim[])
& H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS);
/* Retrieve the dataset dimensions */
- if((space_ndims = H5S_get_simple_extent_dims(dset->shared->space, space_dim, NULL)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get simple dataspace info")
- space_dim[space_ndims] = layout->u.chunk.dim[space_ndims];
+ space_dim = dset->shared->curr_dims;
+ space_ndims = dset->shared->ndims;
/* The last dimension in chunk_offset is always 0 */
chunk_offset[space_ndims] = (hsize_t)0;
@@ -4145,37 +4159,32 @@ H5D__chunk_update_old_edge_chunks(H5D_t *dset, hid_t dxpl_id, hsize_t old_dim[])
/* Main loop: fix old edge chunks */
for(op_dim=0; op_dim<space_ndims; op_dim++) {
- int i; /* Local index variable */
-
/* Check if allocation along this dimension is really necessary */
if(!new_full_dim[op_dim])
continue;
else {
- HDassert((hsize_t) max_edge_chunk_off[op_dim]
- == old_edge_chunk_off[op_dim]);
+ HDassert(max_edge_chunk_off[op_dim] == old_edge_chunk_off[op_dim]);
/* Reset the chunk offset indices */
- HDmemset(chunk_offset, 0, ((unsigned)space_ndims
- * sizeof(chunk_offset[0])));
+ HDmemset(chunk_offset, 0, (space_ndims * sizeof(chunk_offset[0])));
chunk_offset[op_dim] = old_edge_chunk_off[op_dim];
carry = FALSE;
} /* end if */
while(!carry) {
+ hsize_t scaled[H5O_LAYOUT_NDIMS]; /* Scaled coordinates for this chunk */
+ int i; /* Local index variable */
+
/* Make sure the chunk is really a former edge chunk */
- HDassert(H5D__chunk_is_partial_edge_chunk(chunk_offset, NULL, (unsigned)space_ndims, old_dim, chunk_dim)
- && !H5D__chunk_is_partial_edge_chunk(chunk_offset, NULL, (unsigned)space_ndims, space_dim, chunk_dim));
+ HDassert(H5D__chunk_is_partial_edge_chunk(chunk_offset, space_ndims, old_dim, chunk_dim)
+ && !H5D__chunk_is_partial_edge_chunk(chunk_offset, space_ndims, space_dim, chunk_dim));
- /* Calculate the index of this chunk */
- if(H5VM_chunk_index((unsigned)space_ndims, chunk_offset, chunk_dim,
- layout->u.chunk.down_chunks,
- &(chk_io_info.store->chunk.index)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't get chunk index")
+ /* Compute the scaled coordinates */
+ H5VM_chunk_scaled(space_ndims, chunk_offset, chunk_dim, scaled);
/* Lookup the chunk */
- if(H5D__chunk_lookup(dset, dxpl_id, chunk_offset,
- chk_io_info.store->chunk.index, &chk_udata) < 0)
+ if(H5D__chunk_lookup(dset, dxpl_id, chunk_offset, scaled, &chk_udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
/* If this chunk does not exist in cache or on disk, no need to do
@@ -4194,8 +4203,8 @@ H5D__chunk_update_old_edge_chunks(H5D_t *dset, hid_t dxpl_id, hsize_t old_dim[])
/* Increment indices */
carry = TRUE;
- for(i = (space_ndims - 1); i >= 0; --i) {
- if(i != op_dim) {
+ for(i = ((int)space_ndims - 1); i >= 0; --i) {
+ if((unsigned)i != op_dim) {
chunk_offset[i] += chunk_dim[i];
if(chunk_offset[i] > (hsize_t) max_edge_chunk_off[i])
chunk_offset[i] = 0;
@@ -4420,7 +4429,7 @@ H5D__chunk_prune_fill(H5D_chunk_it_ud1_t *udata, hbool_t new_unfilt_chunk)
H5_ASSIGN_OVERFLOW(chunk_size, layout->u.chunk.size, uint32_t, size_t);
/* Get the info for the chunk in the file */
- if(H5D__chunk_lookup(dset, io_info->dxpl_id, chunk_offset, io_info->store->chunk.index, &chk_udata) < 0)
+ if(H5D__chunk_lookup(dset, io_info->dxpl_id, chunk_offset, udata->common.scaled, &chk_udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
chk_udata.new_unfilt_chunk = new_unfilt_chunk;
@@ -4623,14 +4632,13 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim)
const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset's layout */
const H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /*raw data chunk cache */
H5D_rdcc_ent_t *ent = NULL; /* Cache entry */
- int space_ndims; /* Dataset's space rank */
- hsize_t space_dim[H5O_LAYOUT_NDIMS]; /* Current dataspace dimensions */
- int op_dim; /* Current operationg dimension */
+ unsigned space_ndims; /* Dataset's space rank */
+ const hsize_t *space_dim; /* Current dataspace dimensions */
+ unsigned op_dim; /* Current operationg dimension */
hbool_t shrunk_dim[H5O_LAYOUT_NDIMS]; /* Dimensions which have shrunk */
H5D_chunk_it_ud1_t udata; /* Chunk index iterator user data */
hbool_t udata_init = FALSE; /* Whether the chunk index iterator user data has been initialized */
H5D_chunk_common_ud_t idx_udata; /* User data for index removal routine */
- H5D_chunk_ud_t chk_udata; /* User data for getting chunk info */
H5S_t *chunk_space = NULL; /* Dataspace for a chunk */
hsize_t chunk_dim[H5O_LAYOUT_NDIMS]; /* Chunk dimensions */
hsize_t chunk_offset[H5O_LAYOUT_NDIMS]; /* Offset of current chunk */
@@ -4639,7 +4647,7 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim)
hbool_t disable_edge_filters = FALSE; /* Whether to disable filters on partial edge chunks */
hbool_t new_unfilt_chunk = FALSE; /* Whether the chunk is newly unfiltered */
hbool_t carry; /* Flag to indicate that chunk increment carrys to higher dimension (sorta) */
- int i; /* Local index variable */
+ unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
@@ -4664,10 +4672,8 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache")
/* Go get the rank & dimensions (including the element size) */
- if((space_ndims = H5S_get_simple_extent_dims(dset->shared->space, space_dim,
- NULL)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset dimensions")
- space_dim[space_ndims] = layout->u.chunk.dim[space_ndims];
+ space_dim = dset->shared->curr_dims;
+ space_ndims = dset->shared->ndims;;
/* The last dimension in chunk_offset is always 0 */
chunk_offset[space_ndims] = (hsize_t)0;
@@ -4686,15 +4692,14 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim)
/* (also copy the chunk dimensions into 'hsize_t' array for creating dataspace) */
/* (also compute the dimensions which have been shrunk) */
elmts_per_chunk = 1;
- for(i = 0; i < space_ndims; i++) {
- elmts_per_chunk *= layout->u.chunk.dim[i];
- chunk_dim[i] = layout->u.chunk.dim[i];
- shrunk_dim[i] = space_dim[i] < old_dim[i];
+ for(u = 0; u < space_ndims; u++) {
+ elmts_per_chunk *= layout->u.chunk.dim[u];
+ chunk_dim[u] = layout->u.chunk.dim[u];
+ shrunk_dim[u] = space_dim[u] < old_dim[u];
} /* end for */
/* Create a dataspace for a chunk & set the extent */
- if(NULL == (chunk_space = H5S_create_simple((unsigned)space_ndims,
- chunk_dim, NULL)))
+ if(NULL == (chunk_space = H5S_create_simple(space_ndims, chunk_dim, NULL)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace")
/* Reset hyperslab start array */
@@ -4804,8 +4809,8 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim)
if(has_fill)
for(ent = rdcc->head; ent; ent = ent->next)
/* Check for chunk offset outside of new dimensions */
- for(i = 0; i<space_ndims; i++)
- if((hsize_t)ent->offset[i] >= space_dim[i]) {
+ for(u = 0; u < space_ndims; u++)
+ if((hsize_t)ent->offset[u] >= space_dim[u]) {
/* Mark the entry as "deleted" */
ent->deleted = TRUE;
break;
@@ -4821,43 +4826,43 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim)
>= min_mod_chunk_off[op_dim]);
/* Reset the chunk offset indices */
- HDmemset(chunk_offset, 0, ((unsigned)space_ndims
- * sizeof(chunk_offset[0])));
+ HDmemset(chunk_offset, 0, (space_ndims * sizeof(chunk_offset[0])));
chunk_offset[op_dim] = min_mod_chunk_off[op_dim];
/* Initialize "dims_outside_fill" array */
ndims_outside_fill = 0;
- for(i=0; i<space_ndims; i++)
- if((hssize_t)chunk_offset[i] > max_fill_chunk_off[i]) {
- dims_outside_fill[i] = TRUE;
+ for(u = 0; u < space_ndims; u++)
+ if((hssize_t)chunk_offset[u] > max_fill_chunk_off[u]) {
+ dims_outside_fill[u] = TRUE;
ndims_outside_fill++;
} /* end if */
else
- dims_outside_fill[i] = FALSE;
+ dims_outside_fill[u] = FALSE;
carry = FALSE;
} /* end if */
while(!carry) {
- /* Calculate the index of this chunk */
- if(H5VM_chunk_index((unsigned)space_ndims, chunk_offset,
- layout->u.chunk.dim, layout->u.chunk.down_chunks,
- &(chk_io_info.store->chunk.index)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't get chunk index")
+ hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for the current chunk */
+ int i; /* Local index variable */
+
+ /* Compute the scaled coordinates */
+ H5VM_chunk_scaled(space_ndims, chunk_offset, layout->u.chunk.dim, scaled);
+ udata.common.scaled = scaled;
if(0 == ndims_outside_fill) {
HDassert(fill_dim[op_dim]);
HDassert(chunk_offset[op_dim] == min_mod_chunk_off[op_dim]);
/* Make sure this is an edge chunk */
- HDassert(H5D__chunk_is_partial_edge_chunk(chunk_offset, NULL,
- (unsigned)space_ndims, space_dim, layout->u.chunk.dim));
+ HDassert(H5D__chunk_is_partial_edge_chunk(chunk_offset,
+ space_ndims, space_dim, layout->u.chunk.dim));
/* Determine if the chunk just became an unfiltered chunk */
if(new_unfilt_dim[op_dim]) {
new_unfilt_chunk = TRUE;
- for(i=0; i<space_ndims; i++)
- if(chunk_offset[i] == min_partial_chunk_off[i]) {
+ for(u = 0; u < space_ndims; u++)
+ if(chunk_offset[u] == min_partial_chunk_off[u]) {
new_unfilt_chunk = FALSE;
break;
} /* end if */
@@ -4866,8 +4871,8 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim)
/* Make sure that, if we think this is a new unfiltered chunk,
* it was previously not an edge chunk */
HDassert(!new_unfilt_dim[op_dim] || (!new_unfilt_chunk !=
- !H5D__chunk_is_partial_edge_chunk(chunk_offset, NULL,
- (unsigned)space_ndims, old_dim, layout->u.chunk.dim)));
+ !H5D__chunk_is_partial_edge_chunk(chunk_offset,
+ space_ndims, old_dim, layout->u.chunk.dim)));
HDassert(!new_unfilt_chunk || new_unfilt_dim[op_dim]);
/* Fill the unused parts of the chunk */
@@ -4875,13 +4880,15 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to write fill value")
} /* end if */
else {
+ H5D_chunk_ud_t chk_udata; /* User data for getting chunk info */
+
#ifndef NDEBUG
/* Make sure this chunk is really outside the new dimensions */
{
hbool_t outside_dim = FALSE;
- for(i=0; i<space_ndims; i++)
- if(chunk_offset[i] >= space_dim[i]){
+ for(u = 0; u < space_ndims; u++)
+ if(chunk_offset[u] >= space_dim[u]) {
outside_dim = TRUE;
break;
} /* end if */
@@ -4890,7 +4897,7 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim)
#endif /* NDEBUG */
/* Check if the chunk exists in cache or on disk */
- if(H5D__chunk_lookup(dset, dxpl_id, chunk_offset, chk_io_info.store->chunk.index, &chk_udata) < 0)
+ if(H5D__chunk_lookup(dset, dxpl_id, chunk_offset, udata.common.scaled, &chk_udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk")
/* Evict the entry from the cache if present, but do not flush
@@ -4905,10 +4912,10 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim)
if(H5F_addr_defined(chk_udata.addr)) {
/* Update the offset in idx_udata */
idx_udata.offset = chunk_offset;
+ idx_udata.scaled = udata.common.scaled;
/* Remove the chunk from disk */
- if((layout->storage.u.chunk.ops->remove)(&idx_info, &idx_udata)
- < 0)
+ if((layout->storage.u.chunk.ops->remove)(&idx_info, &idx_udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to remove chunk entry from index")
} /* end if */
} /* end else */
@@ -4920,7 +4927,7 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim)
if(chunk_offset[i] > (hsize_t) max_mod_chunk_off[i]) {
/* Left maximum dimensions, "wrap around" and check if this
* dimension is no longer outside the fill dimension */
- if(i == op_dim) {
+ if((unsigned)i == op_dim) {
chunk_offset[i] = min_mod_chunk_off[i];
if(dims_outside_fill[i] && fill_dim[i]) {
dims_outside_fill[i] = FALSE;
@@ -5001,8 +5008,7 @@ H5D__chunk_addrmap_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
FUNC_ENTER_STATIC
/* Compute the index for this chunk */
- if(H5VM_chunk_index(rank, chunk_rec->offset, udata->common.layout->dim, udata->common.layout->down_chunks, &chunk_index) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, H5_ITER_ERROR, "can't get chunk index")
+ chunk_index = H5VM_chunk_index(rank, chunk_rec->offset, udata->common.layout->dim, udata->common.layout->down_chunks);
/* Set it in the userdata to return */
udata->chunk_addr[chunk_index] = chunk_rec->chunk_addr;
@@ -5184,7 +5190,7 @@ H5D__chunk_update_cache(H5D_t *dset, hid_t dxpl_id)
H5D_rdcc_ent_t *tmp_tail; /* Tail pointer for temporary entry list */
H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */
H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */
- unsigned rank; /*current # of dimensions */
+ unsigned rank; /* Current # of dimensions */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
@@ -5195,11 +5201,7 @@ H5D__chunk_update_cache(H5D_t *dset, hid_t dxpl_id)
/* Get the rank */
rank = dset->shared->layout.u.chunk.ndims-1;
- HDassert(rank > 0);
-
- /* 1-D dataset's chunks can't have their index change */
- if(rank == 1)
- HGOTO_DONE(SUCCEED)
+ HDassert(rank > 1);
/* Fill the DXPL cache values for later use */
if(H5D__get_dxpl_cache(dxpl_id, &dxpl_cache) < 0)
@@ -5212,19 +5214,14 @@ H5D__chunk_update_cache(H5D_t *dset, hid_t dxpl_id)
/* Recompute the index for each cached chunk that is in a dataset */
for(ent = rdcc->head; ent; ent = next) {
- hsize_t idx; /* Chunk index */
unsigned old_idx; /* Previous index number */
/* Get the pointer to the next cache entry */
next = ent->next;
- /* Calculate the index of this chunk */
- if(H5VM_chunk_index(rank, ent->offset, dset->shared->layout.u.chunk.dim, dset->shared->layout.u.chunk.down_chunks, &idx) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
-
/* Compute the index for the chunk entry */
old_idx = ent->idx; /* Save for later */
- ent->idx = H5D_CHUNK_HASH(dset->shared, idx);
+ ent->idx = H5D__chunk_hash_val(dset->shared, ent->scaled);
if(old_idx != ent->idx) {
/* Check if there is already a chunk at this chunk's new location */
@@ -5306,6 +5303,7 @@ H5D__chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
{
H5D_chunk_it_ud3_t *udata = (H5D_chunk_it_ud3_t *)_udata; /* User data for callback */
H5D_chunk_ud_t udata_dst; /* User data about new destination chunk */
+ hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates of chunk */
hbool_t is_vlen = FALSE; /* Whether datatype is variable-length */
hbool_t fix_ref = FALSE; /* Whether to fix up references in the dest. file */
@@ -5342,15 +5340,9 @@ H5D__chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
/* Check if we should disable filters on this chunk */
if(udata->common.layout->flags
& H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS) {
- htri_t is_edge_chunk; /* Whether the chunk is an edge chunk */
-
/* Check if the chunk is an edge chunk, and disable filters if so */
- if((is_edge_chunk = H5D__chunk_is_partial_edge_chunk(
- chunk_rec->offset, NULL, udata->dset_ndims,
- udata->dset_dims, udata->common.layout->dim)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, H5_ITER_ERROR, "unable to determine if chunk is edge chunk")
-
- if(!is_edge_chunk)
+ if(!H5D__chunk_is_partial_edge_chunk(chunk_rec->offset, udata->dset_ndims,
+ udata->dset_dims, udata->common.layout->dim))
must_filter = TRUE;
} /* end if */
else
@@ -5463,6 +5455,10 @@ H5D__chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
udata->buf_size = buf_size;
} /* end if */
+ /* Compute the index and scaled coordinates for this chunk */
+ udata_dst.chunk_idx = H5VM_chunk_index_scaled(udata_dst.common.layout->ndims - 1, chunk_rec->offset, udata_dst.common.layout->dim, udata_dst.common.layout->down_chunks, scaled);
+ udata_dst.common.scaled = scaled;
+
/* Insert chunk into the destination index */
if(H5D__idx_chunk_alloc(udata->idx_info_dst, &udata_dst) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert/resize chunk on chunk level")
@@ -5475,10 +5471,6 @@ H5D__chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
/* Set metadata tag in dxpl_id */
H5_BEGIN_TAG(udata->idx_info_dst->dxpl_id, H5AC__COPIED_TAG, H5_ITER_ERROR);
- /* Compute the index for this chunk */
- if(H5VM_chunk_index(udata_dst.common.layout->ndims - 1, chunk_rec->offset, udata_dst.common.layout->dim, udata_dst.common.layout->down_chunks, &udata_dst.chunk_idx) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, H5_ITER_ERROR, "can't get chunk index")
-
if((udata_dst.need_insert || udata_dst.need_modify) && udata->idx_info_dst->storage->ops->insert_addr) {
if((udata->idx_info_dst->storage->ops->insert_addr)(udata->idx_info_dst, &udata_dst) < 0)
HGOTO_ERROR_TAG(H5E_DATASET, H5E_CANTINSERT, H5_ITER_ERROR, "unable to insert chunk addr into index")
@@ -6198,42 +6190,25 @@ done:
*
*-------------------------------------------------------------------------
*/
-static htri_t
-H5D__chunk_is_partial_edge_chunk(const hsize_t offset[], const H5D_t *dset,
- unsigned dset_ndims, const hsize_t *dset_dims, const uint32_t *chunk_dims)
+static hbool_t
+H5D__chunk_is_partial_edge_chunk(const hsize_t offset[], unsigned dset_ndims,
+ const hsize_t *dset_dims, const uint32_t *chunk_dims)
{
- hsize_t _dset_dims[H5O_LAYOUT_NDIMS]; /* Dataset dimensions */
- unsigned i; /* Local index variables */
- htri_t ret_value = FALSE; /* Return value */
+ unsigned u; /* Local index variable */
+ hbool_t ret_value = FALSE; /* Return value */
- FUNC_ENTER_STATIC
+ FUNC_ENTER_STATIC_NOERR
/* Check args */
HDassert(offset);
- HDassert((chunk_dims && dset_dims) || dset);
-
- /* Get chunk dimensions if not specified */
- if(!chunk_dims)
- chunk_dims = dset->shared->layout.u.chunk.dim;
-
- /* Get dataset dimensions if not specified */
- if(!dset_dims) {
- int tmp_ndims;
- if((tmp_ndims = H5S_get_simple_extent_dims(dset->shared->space,
- _dset_dims, NULL)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to get simple dataspace info")
-
- dset_dims = _dset_dims;
- H5_ASSIGN_OVERFLOW(dset_ndims, tmp_ndims, int, unsigned);
- } /* end if */
+ HDassert(dset_ndims > 0);
+ HDassert(dset_dims);
+ HDassert(chunk_dims);
/* check if this is a partial edge chunk */
- for(i=0; i<dset_ndims; i++)
- if((offset[i] + chunk_dims[i]) > dset_dims[i]) {
- ret_value = TRUE;
- break;
- } /* end if */
+ for(u = 0; u < dset_ndims; u++)
+ if((offset[u] + chunk_dims[u]) > dset_dims[u])
+ HGOTO_DONE(TRUE);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -6278,7 +6253,6 @@ H5D__idx_chunk_alloc(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata)
if(idx_info->pline->nused > 0) {
unsigned allow_chunk_size_len; /* Allowed size of encoded chunk size */
unsigned new_chunk_size_len; /* Size of encoded chunk size */
- hsize_t chunk_offset[H5O_LAYOUT_NDIMS];
H5D_chunk_ud_t found_udata;
HDassert(idx_info->storage->idx_type != H5D_CHUNK_IDX_NONE);
@@ -6301,8 +6275,8 @@ H5D__idx_chunk_alloc(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata)
/* Initialize found_udata for ops->get_addr() */
HDmemset(&found_udata, 0, sizeof found_udata);
- HDmemcpy(chunk_offset, udata->common.offset, idx_info->layout->ndims * sizeof(udata->common.offset[0]));
- found_udata.common.offset = chunk_offset;
+ found_udata.common.offset = udata->common.offset;
+ found_udata.common.scaled = udata->common.scaled;
found_udata.common.storage = udata->common.storage;
found_udata.common.layout = udata->common.layout;
found_udata.addr = HADDR_UNDEF;
diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c
index 7d3f313..c053a68 100644
--- a/src/H5Dcompact.c
+++ b/src/H5Dcompact.c
@@ -174,11 +174,8 @@ H5D__compact_construct(H5F_t *f, H5D_t *dset)
hssize_t stmp_size; /* Temporary holder for raw data size */
hsize_t tmp_size; /* Temporary holder for raw data size */
hsize_t max_comp_data_size; /* Max. allowed size of compact data */
- 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 */
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
@@ -187,11 +184,9 @@ H5D__compact_construct(H5F_t *f, H5D_t *dset)
HDassert(dset);
/* Check for invalid dataset dimensions */
- if((ndims = H5S_get_simple_extent_dims(dset->shared->space, dim, max_dim)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataspace dimensions")
- for(i = 0; i < ndims; i++)
- if(max_dim[i] > dim[i])
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "extendible compact dataset")
+ for(u = 0; u < dset->shared->ndims; u++)
+ if(dset->shared->max_dims[u] > dset->shared->curr_dims[u])
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "extendible compact dataset not allowed")
/*
* Compact dataset is stored in dataset object header message of
diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c
index 8d4cd02..11d6f60 100644
--- a/src/H5Dcontig.c
+++ b/src/H5Dcontig.c
@@ -396,10 +396,7 @@ H5D__contig_construct(H5F_t *f, H5D_t *dset)
size_t dt_size; /* Size of datatype */
hsize_t tmp_size; /* Temporary holder for raw data size */
size_t tmp_sieve_buf_size; /* Temporary holder for sieve buffer 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 */
+ unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
@@ -415,11 +412,9 @@ H5D__contig_construct(H5F_t *f, H5D_t *dset)
*/
/* 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")
+ for(u = 0; u < dset->shared->ndims; u++)
+ if(dset->shared->max_dims[u] > dset->shared->curr_dims[u])
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "extendible contiguous non-external dataset not allowed")
/* Retrieve the number of elements in the dataspace */
if((snelmts = H5S_GET_EXTENT_NPOINTS(dset->shared->space)) < 0)
diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c
index 04cf032..eb3f285 100644
--- a/src/H5Ddeprec.c
+++ b/src/H5Ddeprec.c
@@ -341,9 +341,7 @@ static herr_t
H5D__extend(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id)
{
htri_t changed; /* Flag to indicate that the dataspace was successfully extended */
- H5S_t *space; /* Dataset's dataspace */
- int rank; /* Dataspace # of dimensions */
- hsize_t curr_dims[H5O_LAYOUT_NDIMS];/* Current dimension sizes */
+ hsize_t old_dims[H5S_MAX_RANK]; /* Current (i.e. old, if changed) dimension sizes */
H5O_fill_t *fill; /* Dataset's fill value */
herr_t ret_value = SUCCEED; /* Return value */
@@ -364,29 +362,53 @@ H5D__extend(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id)
*/
/* Retrieve the current dimensions */
- space = dataset->shared->space;
- if((rank = H5S_get_simple_extent_dims(space, curr_dims, NULL)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset dimensions")
+ HDcompile_assert(sizeof(old_dims) == sizeof(dataset->shared->curr_dims));
+ HDmemcpy(old_dims, dataset->shared->curr_dims, H5S_MAX_RANK * sizeof(old_dims[0]));
/* Increase the size of the data space */
- if((changed = H5S_extend(space, size)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to increase size of data space")
+ if((changed = H5S_extend(dataset->shared->space, size)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to increase size of dataspace")
/* Updated the dataset's info if the dataspace was successfully extended */
if(changed) {
+ /* Get the extended dimension sizes */
+ /* (Need to retrieve this here, since the 'size' dimensions could
+ * extend one dimension but be smaller in a different dimension,
+ * and the dataspace's extent is the larger of the current and
+ * 'size' dimension values. - QAK)
+ */
+ if(H5S_get_simple_extent_dims(dataset->shared->space, dataset->shared->curr_dims, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset dimensions")
+
/* Update the index values for the cached chunks for this dataset */
if(H5D_CHUNKED == dataset->shared->layout.type) {
+ unsigned u;
+
+ /* Update general information for chunks */
if(H5D__chunk_set_info(dataset) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to update # of chunks")
- if(H5D__chunk_update_cache(dataset, dxpl_id) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update cached chunk indices")
+
+ for(u = 1; u < dataset->shared->ndims; u++) {
+ hsize_t size_power2up; /* New size value, rounded to next power of 2 */
+
+ if((size_power2up = H5VM_power2up(dataset->shared->curr_dims[u])) != dataset->shared->curr_power2up[u]) {
+ /* Update the 'power2up' value for the current dimension */
+ dataset->shared->curr_power2up[u] = size_power2up;
+
+ /* Update the chunk cache indices */
+ if(H5D__chunk_update_cache(dataset, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update cached chunk indices")
+ break;
+ } /* end if */
+ } /* end for */
+
} /* end if */
/* 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, dxpl_id, H5D_ALLOC_EXTEND, FALSE,
- curr_dims) < 0)
+ old_dims) < 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 */
diff --git a/src/H5Dearray.c b/src/H5Dearray.c
index 8df16de..fcb60aa 100644
--- a/src/H5Dearray.c
+++ b/src/H5Dearray.c
@@ -1166,13 +1166,11 @@ H5D_earray_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udat
H5VM_swizzle_coords(hsize_t, swizzled_coords, idx_info->layout->u.earray.unlim_dim);
/* Calculate the index of this chunk */
- if(H5VM_chunk_index(ndims, swizzled_coords, idx_info->layout->u.earray.swizzled_dim, idx_info->layout->u.earray.swizzled_down_chunks, &idx) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
+ idx = H5VM_chunk_index(ndims, swizzled_coords, idx_info->layout->u.earray.swizzled_dim, idx_info->layout->u.earray.swizzled_down_chunks);
} /* end if */
else {
/* Calculate the index of this chunk */
- if(H5VM_chunk_index((idx_info->layout->ndims - 1), udata->common.offset, idx_info->layout->dim, idx_info->layout->down_chunks, &idx) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
+ idx = H5VM_array_offset_pre((idx_info->layout->ndims - 1), idx_info->layout->down_chunks, udata->common.scaled);
} /* end else */
udata->chunk_idx = idx;
@@ -1415,13 +1413,11 @@ H5D_earray_idx_remove(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t
H5VM_swizzle_coords(hsize_t, swizzled_coords, idx_info->layout->u.earray.unlim_dim);
/* Calculate the index of this chunk */
- if(H5VM_chunk_index(ndims, swizzled_coords, idx_info->layout->u.earray.swizzled_dim, idx_info->layout->u.earray.swizzled_down_chunks, &idx) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
+ idx = H5VM_chunk_index(ndims, swizzled_coords, idx_info->layout->u.earray.swizzled_dim, idx_info->layout->u.earray.swizzled_down_chunks);
} /* end if */
else {
/* Calculate the index of this chunk */
- if(H5VM_chunk_index((idx_info->layout->ndims - 1), udata->offset, idx_info->layout->dim, idx_info->layout->down_chunks, &idx) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
+ idx = H5VM_array_offset_pre((idx_info->layout->ndims - 1), idx_info->layout->down_chunks, udata->scaled);
} /* end else */
/* Check for filters on chunks */
diff --git a/src/H5Defl.c b/src/H5Defl.c
index 38c8ccd..355492f 100644
--- a/src/H5Defl.c
+++ b/src/H5Defl.c
@@ -126,14 +126,11 @@ static herr_t
H5D__efl_construct(H5F_t *f, H5D_t *dset)
{
size_t dt_size; /* Size of 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 stmp_size; /* Temporary holder for raw data size */
hsize_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 */
+ unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
@@ -149,11 +146,9 @@ H5D__efl_construct(H5F_t *f, H5D_t *dset)
*/
/* 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")
+ for(u = 1; u < dset->shared->ndims; u++)
+ if(dset->shared->max_dims[u] > dset->shared->curr_dims[u])
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "only the first dimension can be extendible")
/* Retrieve the size of the dataset's datatype */
if(0 == (dt_size = H5T_get_size(dset->shared->type)))
diff --git a/src/H5Dfarray.c b/src/H5Dfarray.c
index 6423804..09476ab 100644
--- a/src/H5Dfarray.c
+++ b/src/H5Dfarray.c
@@ -1134,8 +1134,7 @@ H5D_farray_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udat
fa = idx_info->storage->u.farray.fa;
/* Calculate the index of this chunk */
- if(H5VM_chunk_index((idx_info->layout->ndims - 1), udata->common.offset, idx_info->layout->dim, idx_info->layout->max_down_chunks, &idx) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
+ idx = H5VM_array_offset_pre((idx_info->layout->ndims - 1), idx_info->layout->max_down_chunks, udata->common.scaled);
udata->chunk_idx = idx;
@@ -1355,8 +1354,7 @@ H5D_farray_idx_remove(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t
fa = idx_info->storage->u.farray.fa;
/* Calculate the index of this chunk */
- if(H5VM_chunk_index((idx_info->layout->ndims - 1), udata->offset, idx_info->layout->dim, idx_info->layout->max_down_chunks, &idx) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
+ idx = H5VM_array_offset_pre((idx_info->layout->ndims - 1), idx_info->layout->max_down_chunks, udata->scaled);
/* Check for filters on chunks */
if(idx_info->pline->nused > 0) {
diff --git a/src/H5Dint.c b/src/H5Dint.c
index bddc017..c7a4704 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -62,6 +62,7 @@ static H5D_shared_t *H5D__new(hid_t dcpl_id, hbool_t creating,
hbool_t vl_type);
static herr_t H5D__init_type(H5F_t *file, const H5D_t *dset, hid_t type_id,
const H5T_t *type);
+static herr_t H5D__cache_dataspace_info(const H5D_t *dset);
static herr_t H5D__init_space(H5F_t *file, const H5D_t *dset, const H5S_t *space);
static herr_t H5D__swmr_setup(const H5D_t *dset, hid_t dxpl_id);
static herr_t H5D__swmr_teardown(const H5D_t *dataset, hid_t dxpl_id);
@@ -480,7 +481,6 @@ done:
herr_t
H5D__get_space_status(H5D_t *dset, H5D_space_status_t *allocation, hid_t dxpl_id)
{
- H5S_t *space; /* Dataset's dataspace */
hsize_t space_allocated; /* The number of bytes allocated for chunks */
hssize_t snelmts; /* Temporary holder for number of elements in dataspace */
hsize_t nelmts; /* Number of elements in dataspace */
@@ -493,11 +493,10 @@ H5D__get_space_status(H5D_t *dset, H5D_space_status_t *allocation, hid_t dxpl_id
HDassert(dset);
/* Get the dataset's dataspace */
- space = dset->shared->space;
- HDassert(space);
+ HDassert(dset->shared->space);
/* Get the total number of elements in dataset's dataspace */
- if((snelmts = H5S_GET_EXTENT_NPOINTS(space)) < 0)
+ if((snelmts = H5S_GET_EXTENT_NPOINTS(dset->shared->space)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve number of elements in dataspace")
nelmts = (hsize_t)snelmts;
@@ -669,6 +668,45 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D__cache_dataspace_info
+ *
+ * Purpose: Cache dataspace info for a dataset
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, November 19, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__cache_dataspace_info(const H5D_t *dset)
+{
+ int sndims; /* Signed number of dimensions of dataspace rank */
+ unsigned u; /* Local index value */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity checking */
+ HDassert(dset);
+
+ /* Cache info for dataset's dataspace */
+ if((sndims = H5S_get_simple_extent_dims(dset->shared->space, dset->shared->curr_dims, dset->shared->max_dims)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't cache dataspace dimensions")
+ dset->shared->ndims = (unsigned)sndims;
+
+ /* Compute the inital 'power2up' values */
+ for(u = 0; u < dset->shared->ndims; u++)
+ dset->shared->curr_power2up[u] = H5VM_power2up(dset->shared->curr_dims[u]);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__cache_dataspace_info() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D__init_space
*
* Purpose: Copy a dataspace for a dataset's use, performing all the
@@ -702,6 +740,10 @@ H5D__init_space(H5F_t *file, const H5D_t *dset, const H5S_t *space)
if(NULL == (dset->shared->space = H5S_copy(space, FALSE, TRUE)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy dataspace")
+ /* Cache the dataset's dataspace info */
+ if(H5D__cache_dataspace_info(dset) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't cache dataspace info")
+
/* Set the latest format, if requested */
if(use_latest_format)
if(H5S_set_latest_version(dset->shared->space) < 0)
@@ -1365,6 +1407,10 @@ H5D__open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id)
if(NULL == (dataset->shared->space = H5S_read(&(dataset->oloc), dxpl_id)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to load dataspace info from dataset header")
+ /* Cache the dataset's dataspace info */
+ if(H5D__cache_dataspace_info(dataset) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't cache dataspace info")
+
/* Get a datatype ID for the dataset's datatype */
if((dataset->shared->type_id = H5I_register(H5I_DATATYPE, dataset->shared->type, FALSE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register type")
@@ -2278,9 +2324,7 @@ done:
herr_t
H5D__set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id)
{
- H5S_t *space; /* Dataset's dataspace */
- int rank; /* Dataspace # of dimensions */
- hsize_t curr_dims[H5O_LAYOUT_NDIMS];/* Current dimension sizes */
+ hsize_t curr_dims[H5S_MAX_RANK]; /* Current dimension sizes */
htri_t changed; /* Whether the dataspace changed size */
herr_t ret_value = SUCCEED; /* Return value */
@@ -2304,29 +2348,41 @@ H5D__set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id)
if(H5D__check_filters(dset) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't apply filters")
- /* Get the data space */
- space = dset->shared->space;
-
- /* Check if we are shrinking or expanding any of the dimensions */
- if((rank = H5S_get_simple_extent_dims(space, curr_dims, NULL)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset dimensions")
+ /* Keep the current dataspace dimensions for later */
+ HDcompile_assert(sizeof(curr_dims) == sizeof(dset->shared->curr_dims));
+ HDmemcpy(curr_dims, dset->shared->curr_dims, H5S_MAX_RANK * sizeof(curr_dims[0]));
- /* Modify the size of the data space */
- if((changed = H5S_set_extent(space, size)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space")
+ /* Modify the size of the dataspace */
+ if((changed = H5S_set_extent(dset->shared->space, size)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of dataspace")
/* Don't bother updating things, unless they've changed */
if(changed) {
hbool_t shrink = FALSE; /* Flag to indicate a dimension has shrank */
hbool_t expand = FALSE; /* Flag to indicate a dimension has grown */
+ hbool_t update_chunks = FALSE; /* Flag to indicate chunk cache update is needed */
unsigned u; /* Local index variable */
/* Determine if we are shrinking and/or expanding any dimensions */
- for(u = 0; u < (unsigned)rank; u++) {
+ for(u = 0; u < dset->shared->ndims; u++) {
+ hsize_t size_power2up; /* Size value, rounded to next power of 2 */
+
+ /* Check for various status changes */
if(size[u] < curr_dims[u])
shrink = TRUE;
if(size[u] > curr_dims[u])
expand = TRUE;
+ if(dset->shared->curr_power2up[u] != (size_power2up = H5VM_power2up(size[u]))) {
+ /* Update the 'power2up' value for the current dimension */
+ dset->shared->curr_power2up[u] = size_power2up;
+
+ /* Only need to update the chunk indices if >1 dimension */
+ if(u > 0)
+ update_chunks = TRUE;
+ } /* end if */
+
+ /* Update the cached copy of the dataset's dimensions */
+ dset->shared->curr_dims[u] = size[u];
} /* end for */
/*-------------------------------------------------------------------------
@@ -2335,10 +2391,15 @@ 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) {
+ /* Update the cached chunk info */
if(H5D__chunk_set_info(dset) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to update # of chunks")
- if(H5D__chunk_update_cache(dset, dxpl_id) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update cached chunk indices")
+
+ /* Check if updating the chunk cache indices is necessary */
+ if(update_chunks)
+ /* Update the chunk cache indices */
+ if(H5D__chunk_update_cache(dset, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update cached chunk indices")
} /* end if */
/* Allocate space for the new parts of the dataset, if appropriate */
@@ -2797,16 +2858,14 @@ H5D_get_space(H5D_t *dset)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get data space")
/* Create an atom */
- if((ret_value = H5I_register (H5I_DATASPACE, space, TRUE)) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register data space")
+ if((ret_value = H5I_register(H5I_DATASPACE, space, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace")
done:
- if(ret_value < 0) {
- if(space!=NULL) {
+ if(ret_value < 0)
+ if(space != NULL)
if(H5S_close(space) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace")
- } /* end if */
- } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_get_space() */
diff --git a/src/H5Dio.c b/src/H5Dio.c
index 096a211..e9f6f10 100644
--- a/src/H5Dio.c
+++ b/src/H5Dio.c
@@ -302,10 +302,8 @@ H5D__pre_write(H5D_t *dset, hbool_t direct_write, hid_t mem_type_id,
uint32_t direct_filters;
hsize_t *direct_offset;
uint32_t direct_datasize;
- int ndims = 0;
- hsize_t dims[H5O_LAYOUT_NDIMS];
hsize_t internal_offset[H5O_LAYOUT_NDIMS];
- int i;
+ unsigned u;
/* Get the dataset transfer property list */
if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
@@ -322,25 +320,20 @@ H5D__pre_write(H5D_t *dset, hbool_t direct_write, hid_t mem_type_id,
if(H5P_get(plist, H5D_XFER_DIRECT_CHUNK_WRITE_DATASIZE_NAME, &direct_datasize) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "error getting data size for direct chunk write")
- /* The library's chunking code requires the offset terminates with a zero. So transfer the
- * offset array to an internal offset array */
- if((ndims = H5S_get_simple_extent_dims(dset->shared->space, dims, NULL)) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve dataspace extent dims")
-
- for(i = 0; i < ndims; i++) {
+ for(u = 0; u < dset->shared->ndims; u++) {
/* Make sure the offset doesn't exceed the dataset's dimensions */
- if(direct_offset[i] > dims[i])
+ if(direct_offset[u] > dset->shared->curr_dims[u])
HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "offset exceeds dimensions of dataset")
/* Make sure the offset fall right on a chunk's boundary */
- if(direct_offset[i] % dset->shared->layout.u.chunk.dim[i])
+ if(direct_offset[u] % dset->shared->layout.u.chunk.dim[u])
HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "offset doesn't fall on chunks's boundary")
- internal_offset[i] = direct_offset[i];
+ internal_offset[u] = direct_offset[u];
} /* end for */
/* Terminate the offset with a zero */
- internal_offset[ndims] = 0;
+ internal_offset[dset->shared->ndims] = 0;
/* write raw data */
if(H5D__chunk_direct_write(dset, dxpl_id, direct_filters, internal_offset, direct_datasize, buf) < 0)
diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c
index 88c6075..11cb913 100644
--- a/src/H5Dmpio.c
+++ b/src/H5Dmpio.c
@@ -835,6 +835,7 @@ H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *typ
if(total_chunks == 1) {
H5D_chunk_ud_t udata; /* User data for querying chunk info */
hsize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of chunk in file dataset's dataspace */
+ hsize_t scaled[H5O_LAYOUT_NDIMS]; /* Scaled coordinates for this chunk */
H5SL_node_t *chunk_node; /* Pointer to chunk node for selection */
H5S_t *fspace; /* Dataspace describing chunk & selection in it */
H5S_t *mspace; /* Dataspace describing selection in memory corresponding to this chunk */
@@ -842,10 +843,10 @@ H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *typ
/* Initialize the chunk coordinates */
/* (must be all zero, since there's only one chunk) */
HDmemset(coords, 0, sizeof(coords));
+ HDmemset(scaled, 0, sizeof(scaled));
/* Look up address of chunk */
- if(H5D__chunk_lookup(io_info->dset, io_info->dxpl_id, coords,
- io_info->store->chunk.index, &udata) < 0)
+ if(H5D__chunk_lookup(io_info->dset, io_info->dxpl_id, coords, scaled, &udata) < 0)
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list")
ctg_store.contig.dset_addr = udata.addr;
@@ -1204,7 +1205,6 @@ if(H5DEBUG(D))
/* Pass in chunk's coordinates in a union. */
store.chunk.offset = chunk_info->coords;
- store.chunk.index = chunk_info->index;
} /* end if */
/* Collective IO for this chunk,
@@ -1592,7 +1592,7 @@ if(H5DEBUG(D))
/* Get address of chunk */
if(H5D__chunk_lookup(io_info->dset, io_info->dxpl_id,
- chunk_info->coords, chunk_info->index, &udata) < 0)
+ chunk_info->coords, chunk_info->scaled, &udata) < 0)
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list")
chunk_addr = udata.addr;
} /* end if */
diff --git a/src/H5Dnone.c b/src/H5Dnone.c
index 60194c3..c059066 100644
--- a/src/H5Dnone.c
+++ b/src/H5Dnone.c
@@ -192,10 +192,7 @@ H5D_none_is_space_alloc(const H5O_storage_chunk_t *storage)
static herr_t
H5D_none_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata)
{
- hsize_t idx; /* Array index of chunk */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(idx_info);
HDassert(idx_info->f);
@@ -207,20 +204,16 @@ H5D_none_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata)
HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
/* Calculate the index of this chunk */
- if(H5VM_chunk_index((idx_info->layout->ndims - 1), udata->common.offset, idx_info->layout->dim, idx_info->layout->max_down_chunks, &idx) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
-
- udata->chunk_idx = idx;
+ udata->chunk_idx = H5VM_array_offset_pre((idx_info->layout->ndims - 1), idx_info->layout->max_down_chunks, udata->common.scaled);
/* Calculate the address of the chunk */
- udata->addr = idx_info->storage->idx_addr + idx * idx_info->layout->size;
+ udata->addr = idx_info->storage->idx_addr + udata->chunk_idx * idx_info->layout->size;
/* Update the other (constant) information for the chunk */
udata->nbytes = idx_info->layout->size;
udata->filter_mask = 0;
-done:
- FUNC_LEAVE_NOAPI(ret_value)
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5D_none_get_addr() */
@@ -248,7 +241,7 @@ H5D_none_iterate(const H5D_chk_idx_info_t *idx_info,
hsize_t idx; /* Array index of chunk */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(idx_info);
HDassert(idx_info->f);
@@ -273,8 +266,7 @@ H5D_none_iterate(const H5D_chk_idx_info_t *idx_info,
/* Iterate over all the chunks in the dataset's dataspace */
for(u = 0; u < idx_info->layout->nchunks; u++) {
/* Calculate the index of this chunk */
- if(H5VM_chunk_index(ndims, chunk_rec.offset, idx_info->layout->dim, idx_info->layout->max_down_chunks, &idx) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
+ idx = H5VM_chunk_index(ndims, chunk_rec.offset, idx_info->layout->dim, idx_info->layout->max_down_chunks);
/* Calculate the address of the chunk */
chunk_rec.chunk_addr = idx_info->storage->idx_addr + idx * idx_info->layout->size;
@@ -302,7 +294,6 @@ H5D_none_iterate(const H5D_chk_idx_info_t *idx_info,
} /* end while */
} /* end for */
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_none_iterate() */
diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h
index 10591d4..108ee03 100644
--- a/src/H5Dpkg.h
+++ b/src/H5Dpkg.h
@@ -61,8 +61,6 @@
(io_info)->op_type = H5D_IO_OP_READ; \
(io_info)->u.rbuf = buf
-#define H5D_CHUNK_HASH(D, ADDR) H5F_addr_hash(ADDR, (D)->cache.chunk.nslots)
-
/* Flags for marking aspects of a dataset dirty */
#define H5D_MARK_SPACE 0x01
#define H5D_MARK_LAYOUT 0x02
@@ -186,7 +184,6 @@ typedef struct {
} H5D_contig_storage_t;
typedef struct {
- hsize_t index; /* "Index" of chunk in dataset (must be first for TBBT routines) */
hsize_t *offset; /* Chunk's coordinates in elements */
} H5D_chunk_storage_t;
@@ -276,6 +273,8 @@ typedef struct H5D_chunk_common_ud_t {
const H5O_layout_chunk_t *layout; /* Chunk layout description */
const H5O_storage_chunk_t *storage; /* Chunk storage description */
const hsize_t *offset; /* Logical offset of chunk */
+ const hsize_t *space_dim; /* Dataset dimension sizes */
+ const hsize_t *scaled; /* Scaled coordinates for a chunk */
const struct H5D_rdcc_t *rdcc; /* Chunk cache. Only necessary if the index may
* be modified, and if any chunks in the dset
* may be cached */
@@ -351,6 +350,7 @@ typedef struct H5D_chunk_info_t {
hsize_t index; /* "Index" of chunk in dataset */
uint32_t chunk_points; /* Number of elements selected in chunk */
hsize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of chunk in file dataset's dataspace */
+ hsize_t scaled[H5O_LAYOUT_NDIMS]; /* Scaled coordinates of chunk (in file dataset's dataspace) */
H5S_t *fspace; /* Dataspace describing chunk & selection in it */
unsigned fspace_shared; /* Indicate that the file space for a chunk is shared and shouldn't be freed */
H5S_t *mspace; /* Dataspace describing selection in memory corresponding to this chunk */
@@ -389,11 +389,11 @@ typedef struct H5D_chunk_map_t {
} H5D_chunk_map_t;
/* Cached information about a particular chunk */
-typedef struct H5D_chunk_cached_t{
+typedef struct H5D_chunk_cached_t {
hbool_t valid; /*whether cache info is valid*/
hsize_t offset[H5O_LAYOUT_NDIMS]; /*logical offset to start*/
uint32_t nbytes; /*size of stored data */
- hsize_t chunk_idx; /*index of chunk in dataset */
+ hsize_t chunk_idx; /*index of chunk in dataset */
unsigned filter_mask; /*excluded filters */
haddr_t addr; /*file address of chunk */
} H5D_chunk_cached_t;
@@ -450,6 +450,12 @@ typedef struct H5D_shared_t {
H5O_t *oh; /* Pointer to dataset's object header, pinned */
hbool_t is_swimming; /* TRUE if dataset has SWMR access enabled */
+ /* Cached dataspace info */
+ unsigned ndims; /* The dataset's dataspace rank */
+ hsize_t curr_dims[H5S_MAX_RANK]; /* The curr. size of dataset dimensions */
+ hsize_t curr_power2up[H5S_MAX_RANK]; /* The curr. dim sizes, rounded up to next power of 2 */
+ hsize_t max_dims[H5S_MAX_RANK]; /* The max. size of dataset dimensions */
+
/* Buffered/cached information for types of raw data storage*/
struct {
H5D_rdcdc_t contig; /* Information about contiguous data */
@@ -531,10 +537,11 @@ typedef struct H5D_rdcc_ent_t {
hbool_t deleted; /*chunk about to be deleted (do not flush) */
unsigned edge_chunk_state; /*states related to edge chunks (see above) */
hsize_t offset[H5O_LAYOUT_NDIMS]; /*chunk name */
+ hsize_t scaled[H5O_LAYOUT_NDIMS]; /*scaled chunk 'name' (coordinates) */
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 */
- hsize_t chunk_idx; /*index of chunk in dataset */
+ hsize_t chunk_idx; /*index of chunk in dataset */
uint8_t *chunk; /*the unfiltered chunk data */
unsigned idx; /*index in hash table */
struct H5D_rdcc_ent_t *next;/*next item in doubly-linked list */
@@ -663,7 +670,7 @@ H5_DLL herr_t H5D__chunk_init(H5F_t *f, hid_t dxpl_id, const H5D_t *dset,
hid_t dapl_id);
H5_DLL hbool_t H5D__chunk_is_space_alloc(const H5O_storage_t *storage);
H5_DLL herr_t H5D__chunk_lookup(const H5D_t *dset, hid_t dxpl_id,
- const hsize_t *chunk_offset, hsize_t chunk_idx, H5D_chunk_ud_t *udata);
+ const hsize_t *chunk_offset, const hsize_t *scaled, 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, hbool_t prev_unfilt_chunk);
H5_DLL herr_t H5D__chunk_unlock(const H5D_io_info_t *io_info,
diff --git a/src/H5VM.c b/src/H5VM.c
index 179ec7b..2fb56c4 100644
--- a/src/H5VM.c
+++ b/src/H5VM.c
@@ -1259,21 +1259,119 @@ done:
* The chunk index is placed in the CHUNK_IDX location for return
* from this function
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Chunk index on success (can't fail)
*
* Programmer: Quincey Koziol
* Monday, April 21, 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
-herr_t
+hsize_t
H5VM_chunk_index(unsigned ndims, const hsize_t *coord, const uint32_t *chunk,
- const hsize_t *down_nchunks, hsize_t *chunk_idx)
+ const hsize_t *down_nchunks)
{
- hsize_t scaled_coord[H5VM_HYPER_NDIMS]; /* Scaled, coordinates, in terms of chunks */
- unsigned u; /* Local index variable */
+ hsize_t scaled_coord[H5VM_HYPER_NDIMS]; /* Scaled, coordinates, in terms of chunks */
+ hsize_t chunk_idx; /* Chunk index computed */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /* Sanity check */
+ HDassert(ndims <= H5VM_HYPER_NDIMS);
+ HDassert(coord);
+ HDassert(chunk);
+ HDassert(down_nchunks);
+
+ /* Defer to H5VM_chunk_index_scaled */
+ chunk_idx = H5VM_chunk_index_scaled(ndims, coord, chunk, down_nchunks, scaled_coord);
+
+ FUNC_LEAVE_NOAPI(chunk_idx)
+} /* end H5VM_chunk_index() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VM_chunk_scaled
+ *
+ * Purpose: Compute the scaled coordinates for a chunk offset
+ *
+ * Return: <none>
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, November 19, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VM_chunk_scaled(unsigned ndims, const hsize_t *coord, const uint32_t *chunk,
+ hsize_t *scaled)
+{
+ unsigned u; /* Local index variable */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /* Sanity check */
+ HDassert(ndims <= H5VM_HYPER_NDIMS);
+ HDassert(coord);
+ HDassert(chunk);
+ HDassert(scaled);
+
+ /* Compute the scaled coordinates for actual coordinates */
+ /* (Note that the 'scaled' array is an 'OUT' parameter) */
+ for(u = 0; u < ndims; u++)
+ scaled[u] = coord[u] / chunk[u];
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VM_chunk_scaled() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VM_chunk_index_scaled
+ *
+ * Purpose: Given a coordinate offset (COORD), the size of each chunk
+ * (CHUNK), the number of chunks in each dimension (NCHUNKS)
+ * and the number of dimensions of all of these (NDIMS), calculate
+ * a "chunk index" for the chunk that the coordinate offset is
+ * located in.
+ *
+ * The chunk index starts at 0 and increases according to the
+ * fastest changing dimension, then the next fastest, etc.
+ *
+ * For example, with a 3x5 chunk size and 6 chunks in the fastest
+ * changing dimension and 3 chunks in the slowest changing
+ * dimension, the chunk indices are as follows:
+ *
+ * +-----+-----+-----+-----+-----+-----+
+ * | | | | | | |
+ * | 0 | 1 | 2 | 3 | 4 | 5 |
+ * | | | | | | |
+ * +-----+-----+-----+-----+-----+-----+
+ * | | | | | | |
+ * | 6 | 7 | 8 | 9 | 10 | 11 |
+ * | | | | | | |
+ * +-----+-----+-----+-----+-----+-----+
+ * | | | | | | |
+ * | 12 | 13 | 14 | 15 | 16 | 17 |
+ * | | | | | | |
+ * +-----+-----+-----+-----+-----+-----+
+ *
+ * The chunk index is placed in the CHUNK_IDX location for return
+ * from this function
+ *
+ * Note: This routine is identical to H5VM_chunk_index(), except for
+ * caching the scaled information. Make changes in both places.
+ *
+ * Return: Chunk index on success (can't fail)
+ *
+ * Programmer: Quincey Koziol
+ * Monday, April 21, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+hsize_t
+H5VM_chunk_index_scaled(unsigned ndims, const hsize_t *coord, const uint32_t *chunk,
+ const hsize_t *down_nchunks, hsize_t *scaled)
+{
+ hsize_t chunk_idx; /* Computed chunk index */
+ unsigned u; /* Local index variable */
FUNC_ENTER_NOAPI_NOINIT_NOERR
@@ -1281,17 +1379,19 @@ H5VM_chunk_index(unsigned ndims, const hsize_t *coord, const uint32_t *chunk,
HDassert(ndims <= H5VM_HYPER_NDIMS);
HDassert(coord);
HDassert(chunk);
- HDassert(chunk_idx);
+ HDassert(down_nchunks);
+ HDassert(scaled);
/* Compute the scaled coordinates for actual coordinates */
- for(u=0; u<ndims; u++)
- scaled_coord[u]=coord[u]/chunk[u];
+ /* (Note that the 'scaled' array is an 'OUT' parameter) */
+ for(u = 0; u < ndims; u++)
+ scaled[u] = coord[u] / chunk[u];
/* Compute the chunk index */
- *chunk_idx=H5VM_array_offset_pre(ndims,down_nchunks,scaled_coord); /*lint !e772 scaled_coord will always be initialized */
+ chunk_idx = H5VM_array_offset_pre(ndims, down_nchunks, scaled); /*lint !e772 scaled_coord will always be initialized */
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5VM_chunk_index() */
+ FUNC_LEAVE_NOAPI(chunk_idx)
+} /* end H5VM_chunk_index_scaled() */
/*-------------------------------------------------------------------------
diff --git a/src/H5VMprivate.h b/src/H5VMprivate.h
index 9170b93..fe7baed 100644
--- a/src/H5VMprivate.h
+++ b/src/H5VMprivate.h
@@ -124,8 +124,12 @@ H5_DLL herr_t H5VM_array_calc_pre(hsize_t offset, unsigned n,
const hsize_t *down, hsize_t *coords);
H5_DLL herr_t H5VM_array_calc(hsize_t offset, unsigned n,
const hsize_t *total_size, hsize_t *coords);
-H5_DLL herr_t H5VM_chunk_index(unsigned ndims, const hsize_t *coord,
- const uint32_t *chunk, const hsize_t *down_nchunks, hsize_t *chunk_idx);
+H5_DLL hsize_t H5VM_chunk_index(unsigned ndims, const hsize_t *coord,
+ const uint32_t *chunk, const hsize_t *down_nchunks);
+H5_DLL void H5VM_chunk_scaled(unsigned ndims, const hsize_t *coord,
+ const uint32_t *chunk, hsize_t *scaled);
+H5_DLL hsize_t H5VM_chunk_index_scaled(unsigned ndims, const hsize_t *coord,
+ const uint32_t *chunk, const hsize_t *down_nchunks, hsize_t *scaled);
H5_DLL ssize_t H5VM_opvv(size_t dst_max_nseq, size_t *dst_curr_seq, size_t dst_len_arr[],
hsize_t dst_off_arr[],
size_t src_max_nseq, size_t *src_curr_seq, size_t src_len_arr[],
@@ -454,6 +458,29 @@ H5VM_log2_of2(uint32_t n)
/*-------------------------------------------------------------------------
+ * Function: H5VM_power2up
+ *
+ * Purpose: Round up a number to the next power of 2
+ *
+ * Return: Return the number which is a power of 2
+ *
+ * Programmer: Vailin Choi; Nov 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5_inline hsize_t UNUSED
+H5VM_power2up(hsize_t n)
+{
+ hsize_t ret_value = 1; /* Return value */
+
+ while(ret_value < n)
+ ret_value <<= 1;
+
+ return(ret_value);
+} /* H5VM_power2up */
+
+
+/*-------------------------------------------------------------------------
* Function: H5VM_limit_enc_size
*
* Purpose: Determine the # of bytes needed to encode values within a
diff --git a/test/dsets.c b/test/dsets.c
index 809cf84..ffee6af 100644
--- a/test/dsets.c
+++ b/test/dsets.c
@@ -7205,7 +7205,10 @@ test_random_chunks_real(const char *testname, hbool_t early_alloc, hid_t fapl)
if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR;
/* Create dataspace with unlimited maximum dimensions */
- if((s = H5Screate_simple(2, dsize, dmax)) < 0) TEST_ERROR;
+ if(early_alloc) {
+ if((s = H5Screate_simple(2, dsize, fixed_dmax)) < 0) TEST_ERROR;
+ } else
+ if((s = H5Screate_simple(2, dsize, dmax)) < 0) TEST_ERROR;
/* Create dataset creation property list */
if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR;
@@ -7225,7 +7228,10 @@ test_random_chunks_real(const char *testname, hbool_t early_alloc, hid_t fapl)
/* Verify index type */
if(low == H5F_LIBVER_LATEST) {
- if(idx_type != H5D_CHUNK_IDX_BT2)
+ if(early_alloc) {
+ if(idx_type != H5D_CHUNK_IDX_NONE)
+ FAIL_PUTS_ERROR("should be using implicit indexing");
+ } else if(idx_type != H5D_CHUNK_IDX_BT2)
FAIL_PUTS_ERROR("should be using v2 B-tree as index");
} else if(idx_type != H5D_CHUNK_IDX_BTREE)
FAIL_PUTS_ERROR("should be using v1 B-tree as index");