diff options
Diffstat (limited to 'src/H5Dint.c')
-rw-r--r-- | src/H5Dint.c | 138 |
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") |