summaryrefslogtreecommitdiffstats
path: root/src/H5Dint.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Dint.c')
-rw-r--r--src/H5Dint.c138
1 files changed, 99 insertions, 39 deletions
diff --git a/src/H5Dint.c b/src/H5Dint.c
index 86d241b..b0e31a6 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -1461,6 +1461,10 @@ H5D__open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id)
fill_prop->alloc_time = H5D_ALLOC_TIME_INCR;
break;
+ case H5D_VIRTUAL:
+ fill_prop->alloc_time = H5D_ALLOC_TIME_INCR;
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -1475,7 +1479,8 @@ H5D__open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id)
alloc_time_state = 0;
if((dataset->shared->layout.type == H5D_COMPACT && fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY)
|| (dataset->shared->layout.type == H5D_CONTIGUOUS && fill_prop->alloc_time == H5D_ALLOC_TIME_LATE)
- || (dataset->shared->layout.type == H5D_CHUNKED && fill_prop->alloc_time == H5D_ALLOC_TIME_INCR))
+ || (dataset->shared->layout.type == H5D_CHUNKED && fill_prop->alloc_time == H5D_ALLOC_TIME_INCR)
+ || (dataset->shared->layout.type == H5D_VIRTUAL && fill_prop->alloc_time == H5D_ALLOC_TIME_INCR))
alloc_time_state = 1;
/* Set revised fill value properties, if they are different from the defaults */
@@ -1601,6 +1606,34 @@ H5D_close(H5D_t *dataset)
/* Nothing special to do (info freed in the layout destroy) */
break;
+ case H5D_VIRTUAL:
+ {
+ size_t i, j;
+
+ HDassert(dataset->shared->layout.storage.u.virt.list || (dataset->shared->layout.storage.u.virt.list_nused == 0));
+
+ /* Close source datasets */
+ for(i = 0; i < dataset->shared->layout.storage.u.virt.list_nused; i++) {
+ /* Close source dataset */
+ if(dataset->shared->layout.storage.u.virt.list[i].source_dset.dset) {
+ HDassert(dataset->shared->layout.storage.u.virt.list[i].source_dset.dset != dataset);
+ if(H5D_close(dataset->shared->layout.storage.u.virt.list[i].source_dset.dset) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to close source dataset")
+ dataset->shared->layout.storage.u.virt.list[i].source_dset.dset = NULL;
+ } /* end if */
+
+ /* Close sub datasets */
+ for(j = 0; j < dataset->shared->layout.storage.u.virt.list[i].sub_dset_nused; j++)
+ if(dataset->shared->layout.storage.u.virt.list[i].sub_dset[j].dset) {
+ HDassert(dataset->shared->layout.storage.u.virt.list[i].sub_dset[j].dset != dataset);
+ if(H5D_close(dataset->shared->layout.storage.u.virt.list[i].sub_dset[j].dset) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to close source dataset")
+ dataset->shared->layout.storage.u.virt.list[i].sub_dset[j].dset = NULL;
+ } /* end if */
+ } /* end for */
+ } /* end block */
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -1857,6 +1890,15 @@ H5D__alloc_storage(const H5D_t *dset, hid_t dxpl_id, H5D_time_alloc_t time_alloc
} /* end if */
break;
+ case H5D_VIRTUAL:
+ /* No-op, as the raw data is stored elsewhere and the global
+ * heap object containing the mapping information is created
+ * when the layout message is encoded. We may wish to move the
+ * creation of the global heap object here at some point, but we
+ * will have to make sure is it always created before the
+ * dataset is closed. */
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -1976,6 +2018,9 @@ H5D__init_storage(const H5D_t *dset, hbool_t full_overwrite, hsize_t old_dim[],
break;
} /* end block */
+ case H5D_VIRTUAL:
+ /* No-op, as the raw data is stored elsewhere */
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -2032,6 +2077,12 @@ H5D__get_storage_size(H5D_t *dset, hid_t dxpl_id, hsize_t *storage_size)
*storage_size = dset->shared->layout.storage.u.compact.size;
break;
+ case H5D_VIRTUAL:
+ /* Just set to 0, as virtual datasets do not actually store raw data
+ */
+ *storage_size = 0;
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -2068,6 +2119,7 @@ H5D__get_offset(const H5D_t *dset)
HDassert(dset);
switch(dset->shared->layout.type) {
+ case H5D_VIRTUAL:
case H5D_CHUNKED:
case H5D_COMPACT:
break;
@@ -2092,41 +2144,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D__iterate
- *
- * Purpose: Internal version of H5Diterate()
- *
- * Return: Returns the return value of the last operator if it was non-zero,
- * or zero if all elements were processed. Otherwise returns a
- * negative value.
- *
- * Programmer: Quincey Koziol
- * Tuesday, November 22, 2005
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5D__iterate(void *buf, hid_t type_id, const H5S_t *space, H5D_operator_t op,
- void *operator_data)
-{
- herr_t ret_value = FAIL; /* Return value */
-
- FUNC_ENTER_PACKAGE_NOERR
-
- /* Check args */
- HDassert(buf);
- HDassert(H5I_DATATYPE == H5I_get_type(type_id));
- HDassert(space);
- HDassert(H5S_has_extent(space));
- HDassert(op);
-
- ret_value = H5S_select_iterate(buf, type_id, space, op, operator_data);
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D__iterate() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5D_vlen_reclaim
*
* Purpose: Frees the buffers allocated for storing variable-length data
@@ -2144,6 +2161,8 @@ H5D__iterate(void *buf, hid_t type_id, const H5S_t *space, H5D_operator_t op,
herr_t
H5D_vlen_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id, void *buf)
{
+ H5T_t *type; /* Datatype */
+ H5S_sel_iter_op_t dset_op; /* Operator for iteration */
H5T_vlen_alloc_info_t _vl_alloc_info; /* VL allocation info buffer */
H5T_vlen_alloc_info_t *vl_alloc_info = &_vl_alloc_info; /* VL allocation info */
herr_t ret_value = FAIL; /* Return value */
@@ -2156,12 +2175,19 @@ H5D_vlen_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id, void *buf)
HDassert(H5P_isa_class(plist_id, H5P_DATASET_XFER));
HDassert(buf);
+ if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype")
+
/* Get the allocation info */
if(H5T_vlen_get_alloc_info(plist_id,&vl_alloc_info) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info")
- /* Call H5D__iterate with args, etc. */
- ret_value = H5D__iterate(buf, type_id, space ,H5T_vlen_reclaim, vl_alloc_info);
+ /* Call H5S_select_iterate with args, etc. */
+ dset_op.op_type = H5S_SEL_ITER_OP_APP;
+ dset_op.u.app_op.op = H5T_vlen_reclaim;
+ dset_op.u.app_op.type_id = type_id;
+
+ ret_value = H5S_select_iterate(buf, type, space, &dset_op, vl_alloc_info);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -2333,7 +2359,7 @@ H5D__set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id)
{
hsize_t curr_dims[H5S_MAX_RANK]; /* Current dimension sizes */
htri_t changed; /* Whether the dataspace changed size */
- size_t u; /* Local index variable */
+ size_t u, v; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE_TAG(dxpl_id, dset->oloc.addr, FAIL)
@@ -2432,6 +2458,30 @@ H5D__set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update cached chunk indices")
} /* end if */
+ /* Operations for virtual datasets */
+ if(H5D_VIRTUAL == dset->shared->layout.type) {
+ /* Check that the dimensions of the VDS are large enough */
+ if(H5D_virtual_check_min_dims(dset) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "virtual dataset dimensions not large enough to contain all limited dimensions in all selections")
+
+ /* Patch the virtual selection dataspaces */
+ for(u = 0; u < dset->shared->layout.storage.u.virt.list_nused; u++) {
+ /* Patch extent */
+ if(H5S_set_extent(dset->shared->layout.storage.u.virt.list[u].source_dset.virtual_select, size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space")
+ dset->shared->layout.storage.u.virt.list[u].virtual_space_status = H5O_VIRTUAL_STATUS_CORRECT;
+
+ /* Patch sub-source datasets */
+ for(v = 0; v < dset->shared->layout.storage.u.virt.list[u].sub_dset_nalloc; v++)
+ if(H5S_set_extent(dset->shared->layout.storage.u.virt.list[u].sub_dset[v].virtual_select, size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space")
+ } /* end for */
+
+ /* Mark virtual datasets as not fully initialized so internal
+ * selections are recalculated (at next I/O operation) */
+ dset->shared->layout.storage.u.virt.init = FALSE;
+ } /* end if */
+
/* Allocate space for the new parts of the dataset, if appropriate */
if(expand && dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_EARLY)
if(H5D__alloc_storage(dset, dxpl_id, H5D_ALLOC_EXTEND, FALSE, curr_dims) < 0)
@@ -2757,6 +2807,11 @@ H5D_get_create_plist(H5D_t *dset)
copied_layout.storage.u.chunk.ops = NULL;
break;
+ case H5D_VIRTUAL:
+ copied_layout.storage.u.virt.serial_list_hobjid.addr = HADDR_UNDEF;
+ copied_layout.storage.u.virt.serial_list_hobjid.idx = 0;
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -2939,6 +2994,11 @@ H5D_get_space(H5D_t *dset)
FUNC_ENTER_NOAPI_NOINIT
+ /* If the layout is virtual, update the extent */
+ if(dset->shared->layout.type == H5D_VIRTUAL)
+ if(H5D__virtual_set_extent_unlim(dset, H5AC_ind_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update virtual dataset extent")
+
/* Read the data space message and return a data space object */
if(NULL == (space = H5S_copy(dset->shared->space, FALSE, TRUE)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get data space")