summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2009-01-31 18:19:49 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2009-01-31 18:19:49 (GMT)
commit2d74d46d3fe259ed51b2b996b56559563999e852 (patch)
treefaff172323e140a2446f90e935589708f9bd0830 /src
parent7191f26717255667e86c86559ffc316f73f4c1bd (diff)
downloadhdf5-2d74d46d3fe259ed51b2b996b56559563999e852.zip
hdf5-2d74d46d3fe259ed51b2b996b56559563999e852.tar.gz
hdf5-2d74d46d3fe259ed51b2b996b56559563999e852.tar.bz2
[svn-r16392] Description:
Bring r16367:16391 back from trunk into revise_chunks branch. Tested on: FreeBSD 6.3/32 (duty) (h5committest not required on this branch)
Diffstat (limited to 'src')
-rw-r--r--src/H5Aint.c537
-rw-r--r--src/H5Apkg.h9
-rw-r--r--src/H5EA.c30
-rw-r--r--src/H5EAcache.c30
-rw-r--r--src/H5EAdblock.c24
-rw-r--r--src/H5EAhdr.c4
-rw-r--r--src/H5EAiblock.c25
-rw-r--r--src/H5EApkg.h13
-rw-r--r--src/H5EAprivate.h10
-rw-r--r--src/H5EAsblock.c23
-rw-r--r--src/H5FDcore.c12
-rw-r--r--src/H5O.c3
-rw-r--r--src/H5Oainfo.c66
-rw-r--r--src/H5Oattr.c286
-rw-r--r--src/H5Oattribute.c2
-rw-r--r--src/H5Ocache.c18
-rw-r--r--src/H5Ocopy.c3
-rw-r--r--src/H5Omessage.c12
-rw-r--r--src/H5Opkg.h17
19 files changed, 765 insertions, 359 deletions
diff --git a/src/H5Aint.c b/src/H5Aint.c
index aadf79c..a47c5c3 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -37,9 +37,12 @@
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Apkg.h" /* Attributes */
+#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
+#include "H5SMprivate.h" /* Shared Object Header Messages */
/****************/
@@ -66,6 +69,17 @@ typedef struct {
size_t curr_attr; /* Current attribute to operate on */
} H5A_dense_bt_ud_t;
+/* Data exchange structure to use when copying an attribute from _SRC to _DST */
+typedef struct {
+ const H5O_ainfo_t *ainfo; /* dense information */
+ H5F_t *file; /* file */
+ hbool_t *recompute_size; /* Flag to indicate if size changed */
+ H5O_copy_t *cpy_info; /* Information on copying options */
+ hid_t dxpl_id; /* DXPL for operation */
+ const H5O_loc_t *oloc_src;
+ H5O_loc_t *oloc_dst;
+} H5A_dense_file_cp_ud_t;
+
/********************/
/* Package Typedefs */
@@ -765,3 +779,526 @@ H5A_set_version(const H5F_t *f, H5A_t *attr)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5A_set_version() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_attr_copy_file
+ *
+ * Purpose: Copies a message from _MESG to _DEST in file
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * November 1, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+H5A_t *
+H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_size,
+ H5O_copy_t *cpy_info, hid_t dxpl_id)
+{
+ H5A_t *attr_dst = NULL;
+
+ /* for dataype conversion */
+ hid_t tid_src = -1; /* Datatype ID for source datatype */
+ hid_t tid_dst = -1; /* Datatype ID for destination datatype */
+ hid_t tid_mem = -1; /* Datatype ID for memory datatype */
+ void *buf = NULL; /* Buffer for copying data */
+ void *reclaim_buf = NULL; /* Buffer for reclaiming data */
+ hid_t buf_sid = -1; /* ID for buffer dataspace */
+
+ H5A_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5A_attr_copy_file)
+
+ /* check args */
+ HDassert(attr_src);
+ HDassert(file_dst);
+ HDassert(cpy_info);
+ HDassert(!cpy_info->copy_without_attr);
+
+ /* Allocate space for the destination message */
+ if(NULL == (attr_dst = H5FL_CALLOC(H5A_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Copy the top level of the attribute */
+ *attr_dst = *attr_src;
+
+ if(NULL == (attr_dst->shared = H5FL_CALLOC(H5A_shared_t)))
+ HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared attr structure")
+
+ /* Don't have an opened group location for copy */
+ H5O_loc_reset(&(attr_dst->shared->oloc));
+ H5G_name_reset(&(attr_dst->path));
+ attr_dst->obj_opened = FALSE;
+
+ /* Reference count for the header message in the cache */
+ attr_dst->shared->nrefs = 1;
+
+ /* Copy attribute's name */
+ attr_dst->shared->name = H5MM_strdup(attr_src->shared->name);
+ HDassert(attr_dst->shared->name);
+
+ /* Copy attribute's datatype */
+ /* (Start destination datatype as transient, even if source is named) */
+ if(NULL == (attr_dst->shared->dt = H5T_copy(attr_src->shared->dt, H5T_COPY_ALL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "cannot copy datatype")
+
+ /* Set the location of the destination datatype */
+ if(H5T_set_loc(attr_dst->shared->dt, file_dst, H5T_LOC_DISK) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "cannot mark datatype on disk")
+
+ /* Check for named datatype being copied */
+ if(H5T_committed(attr_src->shared->dt)) {
+ H5O_loc_t *src_oloc; /* Pointer to source datatype's object location */
+ H5O_loc_t *dst_oloc; /* Pointer to dest. datatype's object location */
+
+ /* Get group entries for source & destination */
+ src_oloc = H5T_oloc(attr_src->shared->dt);
+ HDassert(src_oloc);
+ dst_oloc = H5T_oloc(attr_dst->shared->dt);
+ HDassert(dst_oloc);
+
+ /* Reset object location for new object */
+ H5O_loc_reset(dst_oloc);
+ dst_oloc->file = file_dst;
+
+ /* Copy the shared object from source to destination */
+ if(H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, cpy_info, FALSE) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object")
+
+ /* Update shared message info from named datatype info */
+ H5T_update_shared(attr_dst->shared->dt);
+ } /* end if */
+ else {
+ /* If the datatype is not named, it may have been shared in the
+ * source file's heap. Un-share it for now. We'll try to shared
+ * it in the destination file below.
+ */
+ if(H5O_msg_reset_share(H5O_DTYPE_ID, attr_dst->shared->dt) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to reset datatype sharing")
+ } /* end else */
+
+ /* Copy the dataspace for the attribute */
+ attr_dst->shared->ds = H5S_copy(attr_src->shared->ds, FALSE, FALSE);
+ HDassert(attr_dst->shared->ds);
+
+ /* Reset the dataspace's sharing in the source file before trying to share
+ * it in the destination.
+ */
+ if(H5O_msg_reset_share(H5O_SDSPACE_ID, attr_dst->shared->ds) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to reset dataspace sharing")
+
+
+ /* Try to share both the datatype and dataset. This does nothing if the
+ * datatype is committed or sharing is disabled.
+ */
+ if(H5SM_try_share(file_dst, dxpl_id, NULL, H5O_DTYPE_ID, attr_dst->shared->dt, NULL) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "can't share attribute datatype")
+ if(H5SM_try_share(file_dst, dxpl_id, NULL, H5O_SDSPACE_ID, attr_dst->shared->ds, NULL) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "can't share attribute dataspace")
+
+ /* Compute the sizes of the datatype and dataspace. This is their raw
+ * size unless they're shared.
+ */
+ attr_dst->shared->dt_size = H5O_msg_raw_size(file_dst, H5O_DTYPE_ID, FALSE, attr_dst->shared->dt);
+ HDassert(attr_dst->shared->dt_size > 0);
+ attr_dst->shared->ds_size = H5O_msg_raw_size(file_dst, H5O_SDSPACE_ID, FALSE, attr_dst->shared->ds);
+ HDassert(attr_dst->shared->ds_size > 0);
+
+ /* Check whether to recompute the size of the attribute */
+ /* (happens when the datatype or dataspace changes sharing status) */
+ if(attr_dst->shared->dt_size != attr_src->shared->dt_size || attr_dst->shared->ds_size != attr_src->shared->ds_size)
+ *recompute_size = TRUE;
+
+ /* Compute the size of the data */
+ H5_ASSIGN_OVERFLOW(attr_dst->shared->data_size, H5S_GET_EXTENT_NPOINTS(attr_dst->shared->ds) * H5T_get_size(attr_dst->shared->dt), hsize_t, size_t);
+
+ /* Copy (& convert) the data, if necessary */
+ if(attr_src->shared->data) {
+ if(NULL == (attr_dst->shared->data = H5FL_BLK_MALLOC(attr_buf, attr_dst->shared->data_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Check if we need to convert data */
+ if(H5T_detect_class(attr_src->shared->dt, H5T_VLEN) > 0) {
+ H5T_path_t *tpath_src_mem, *tpath_mem_dst; /* Datatype conversion paths */
+ H5T_t *dt_mem; /* Memory datatype */
+ size_t src_dt_size; /* Source datatype size */
+ size_t tmp_dt_size; /* Temp. datatype size */
+ size_t max_dt_size; /* Max atatype size */
+ H5S_t *buf_space; /* Dataspace describing buffer */
+ hsize_t buf_dim; /* Dimension for buffer */
+ size_t nelmts; /* Number of elements in buffer */
+ size_t buf_size; /* Size of copy buffer */
+
+ /* Create datatype ID for src datatype */
+ if((tid_src = H5I_register(H5I_DATATYPE, attr_src->shared->dt, FALSE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register source file datatype")
+
+ /* create a memory copy of the variable-length datatype */
+ if(NULL == (dt_mem = H5T_copy(attr_src->shared->dt, H5T_COPY_TRANSIENT)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy")
+ if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem, FALSE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register memory datatype")
+
+ /* create variable-length datatype at the destinaton file */
+ if((tid_dst = H5I_register(H5I_DATATYPE, attr_dst->shared->dt, FALSE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register destination file datatype")
+
+ /* Set up the conversion functions */
+ if(NULL == (tpath_src_mem = H5T_path_find(attr_src->shared->dt, dt_mem, NULL, NULL, dxpl_id, FALSE)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to convert between src and mem datatypes")
+ if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, attr_dst->shared->dt, NULL, NULL, dxpl_id, FALSE)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to convert between mem and dst datatypes")
+
+ /* Determine largest datatype size */
+ if(0 == (src_dt_size = H5T_get_size(attr_src->shared->dt)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to determine datatype size")
+ if(0 == (tmp_dt_size = H5T_get_size(dt_mem)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to determine datatype size")
+ max_dt_size = MAX(src_dt_size, tmp_dt_size);
+ if(0 == (tmp_dt_size = H5T_get_size(attr_dst->shared->dt)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to determine datatype size")
+ max_dt_size = MAX(max_dt_size, tmp_dt_size);
+
+ /* Set number of whole elements that fit in buffer */
+ if(0 == (nelmts = attr_src->shared->data_size / src_dt_size))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "element size too large")
+
+ /* Set up number of bytes to copy, and initial buffer size */
+ buf_size = nelmts * max_dt_size;
+
+ /* Create dataspace for number of elements in buffer */
+ buf_dim = nelmts;
+
+ /* Create the space and set the initial extent */
+ if(NULL == (buf_space = H5S_create_simple((unsigned)1, &buf_dim, NULL)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, NULL, "can't create simple dataspace")
+
+ /* Atomize */
+ if((buf_sid = H5I_register(H5I_DATASPACE, buf_space, FALSE)) < 0) {
+ H5S_close(buf_space);
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, NULL, "unable to register dataspace ID")
+ } /* end if */
+
+ /* Allocate memory for recclaim buf */
+ if(NULL == (reclaim_buf = H5FL_BLK_MALLOC(attr_buf, buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation NULLed for raw data chunk")
+
+ /* Allocate memory for copying the chunk */
+ if(NULL == (buf = H5FL_BLK_MALLOC(attr_buf, buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation NULLed for raw data chunk")
+
+ HDmemcpy(buf, attr_src->shared->data, attr_src->shared->data_size);
+
+ /* Convert from source file to memory */
+ if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "datatype conversion NULLed")
+
+ HDmemcpy(reclaim_buf, buf, buf_size);
+
+ /* Convert from memory to destination file */
+ if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "datatype conversion NULLed")
+
+ HDmemcpy(attr_dst->shared->data, buf, attr_dst->shared->data_size);
+
+ if(H5D_vlen_reclaim(tid_mem, buf_space, H5P_DATASET_XFER_DEFAULT, reclaim_buf) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADITER, NULL, "unable to reclaim variable-length data")
+ } /* end if */
+ else {
+ HDassert(attr_dst->shared->data_size == attr_src->shared->data_size);
+ HDmemcpy(attr_dst->shared->data, attr_src->shared->data, attr_src->shared->data_size);
+ } /* end else */
+ } /* end if(attr_src->shared->data) */
+
+ /* Recompute the version to encode the destination attribute */
+ if(H5A_set_version(file_dst, attr_dst) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, NULL, "unable to update attribute version")
+
+ /* Indicate that the fill values aren't to be written out */
+ attr_dst->shared->initialized = TRUE;
+
+ /* Set return value */
+ ret_value = attr_dst;
+
+done:
+ if(buf_sid > 0)
+ if(H5I_dec_ref(buf_sid, FALSE) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary dataspace ID")
+ if(tid_src > 0)
+ /* Don't decrement ID, we want to keep underlying datatype */
+ if(H5I_remove(tid_src) == NULL)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
+ if(tid_dst > 0)
+ /* Don't decrement ID, we want to keep underlying datatype */
+ if(H5I_remove(tid_dst) == NULL)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
+ if(tid_mem > 0)
+ /* Decrement the memory datatype ID, it's transient */
+ if(H5I_dec_ref(tid_mem, FALSE) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
+ if(buf)
+ buf = H5FL_BLK_FREE(attr_buf, buf);
+ if(reclaim_buf)
+ reclaim_buf = H5FL_BLK_FREE(attr_buf, reclaim_buf);
+
+ /* Release destination attribute information on failure */
+ if(!ret_value && attr_dst && H5A_close(attr_dst) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A_attr_copy_file() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_attr_post_copy_file
+ *
+ * Purpose: Finish copying a message from between files.
+ * We have to copy the values of a reference attribute in the
+ * post copy because H5O_post_copy_file() fails at the case that
+ * an object may have a reference attribute that points to the
+ * object itself.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Peter Cao
+ * March 6, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5A_attr_post_copy_file(const H5O_loc_t *src_oloc, const H5A_t UNUSED *attr_src,
+ H5O_loc_t *dst_oloc, const H5A_t *attr_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
+{
+ H5F_t *file_src = src_oloc->file;
+ H5F_t *file_dst = dst_oloc->file;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+
+ FUNC_ENTER_NOAPI_NOINIT(H5A_attr_post_copy_file)
+
+ /* check args */
+ HDassert(attr_dst);
+ HDassert(file_dst);
+
+
+ /* Only need to fix reference attribute with real data being copied to
+ * another file.
+ */
+ if((NULL != attr_dst->shared->data) && (H5T_get_class(attr_dst->shared->dt, FALSE) == H5T_REFERENCE) ) {
+
+ /* copy object pointed by reference. The current implementation does not
+ * deal with nested reference such as reference in a compound structure
+ */
+
+ /* Check for expanding references */
+ if(cpy_info->expand_ref) {
+ size_t ref_count;
+
+ /* Determine # of reference elements to copy */
+ ref_count = attr_dst->shared->data_size / H5T_get_size(attr_dst->shared->dt);
+
+ /* Copy objects referenced in source buffer to destination file and set destination elements */
+ if(H5O_copy_expand_ref(file_src, attr_dst->shared->data, dxpl_id,
+ file_dst, attr_dst->shared->data, ref_count, H5T_get_ref_type(attr_dst->shared->dt), cpy_info) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy reference attribute")
+ } /* end if */
+ else
+ /* Reset value to zero */
+ HDmemset(attr_dst->shared->data, 0, attr_dst->shared->data_size);
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A_attr_post_copy_file() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_dense_copy_file_cb
+ *
+ * Purpose: Callback routine for copying a dense attribute from SRC to DST.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Peter Cao
+ * xcao@hdfgroup.org
+ * July 20, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5A_dense_copy_file_cb(const H5A_t *attr_src, void *_udata)
+{
+ H5A_dense_file_cp_ud_t *udata = (H5A_dense_file_cp_ud_t *)_udata;
+ H5A_t *attr_dst = NULL;
+ herr_t ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5A_dense_copy_file_cb)
+
+ /* check arguments */
+ HDassert(attr_src);
+ HDassert(udata);
+ HDassert(udata->ainfo);
+ HDassert(udata->file);
+ HDassert(udata->cpy_info);
+
+ if ( NULL == (attr_dst=H5A_attr_copy_file(attr_src, udata->file,
+ udata->recompute_size, udata->cpy_info, udata->dxpl_id)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute")
+
+ /* Reset shared location information */
+ if(H5O_msg_reset_share(H5O_ATTR_ID, attr_dst) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to reset attribute sharing")
+
+ /* Insert attribute into dense storage */
+ if(H5A_dense_insert(udata->file, udata->dxpl_id, udata->ainfo, attr_dst) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, H5_ITER_ERROR, "unable to add to dense storage")
+
+done:
+ if (attr_dst) {
+ (void)H5A_free(attr_dst);
+ (void)H5FL_FREE(H5A_t, attr_dst);
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5A_dense_copy_file_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_dense_copy_file_all
+ *
+ * Purpose: Copy all dense attributes from SRC to DST.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Peter Cao
+ * xcao@hdfgroup.org
+ * July 20, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5A_dense_copy_file_all(H5F_t *file_src, H5O_ainfo_t *ainfo_src, H5F_t *file_dst,
+ const H5O_ainfo_t *ainfo_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, hid_t dxpl_id)
+{
+ H5A_dense_file_cp_ud_t udata; /* User data for iteration callback */
+ H5A_attr_iter_op_t attr_op; /* Attribute operator */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5A_dense_copy_file_all)
+
+ /* check arguments */
+ HDassert(ainfo_src);
+ HDassert(ainfo_dst);
+
+ udata.ainfo = ainfo_dst; /* Destination dense information */
+ udata.file = file_dst; /* Destination file */
+ udata.recompute_size = recompute_size; /* Flag to indicate if size changed */
+ udata.cpy_info = cpy_info; /* Information on copying options */
+ udata.dxpl_id = dxpl_id; /* DXPL for operation */
+
+ attr_op.op_type = H5A_ATTR_OP_LIB;
+ attr_op.u.lib_op = H5A_dense_copy_file_cb;
+
+ if(H5A_dense_iterate(file_src, dxpl_id, (hid_t)0, ainfo_src, H5_INDEX_NAME,
+ H5_ITER_NATIVE, (hsize_t)0, NULL, &attr_op, &udata) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "error building attribute table")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5A_dense_copy_file_all */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_dense_post_copy_file_cb
+ *
+ * Purpose: Callback routine to perfom post copy for a dense attribute.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Peter Cao
+ * xcao@hdfgroup.org
+ * July 25, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5A_dense_post_copy_file_cb(const H5A_t *attr_dst, void *_udata)
+{
+ H5A_dense_file_cp_ud_t *udata = (H5A_dense_file_cp_ud_t *)_udata;
+ herr_t ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5A_dense_post_copy_file_cb)
+
+ /* check arguments */
+ HDassert(attr_dst);
+ HDassert(udata);
+ HDassert(udata->ainfo);
+ HDassert(udata->file);
+ HDassert(udata->cpy_info);
+
+ if ( H5A_attr_post_copy_file(udata->oloc_src, NULL,
+ udata->oloc_dst, attr_dst, udata->dxpl_id, udata->cpy_info) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute")
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5A_dense_post_copy_file_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_dense_post_copy_file_all
+ *
+ * Purpose: Do post copy for all dense attributes.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Peter Cao
+ * xcao@hdfgroup.org
+ * July 25, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5A_dense_post_copy_file_all(const H5O_loc_t *src_oloc, const H5O_ainfo_t *ainfo_src,
+ H5O_loc_t *dst_oloc, H5O_ainfo_t *ainfo_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
+{
+ H5A_dense_file_cp_ud_t udata; /* User data for iteration callback */
+ H5A_attr_iter_op_t attr_op; /* Attribute operator */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5A_dense_post_copy_file_all)
+
+ /* check arguments */
+ HDassert(ainfo_src);
+ HDassert(ainfo_dst);
+ HDassert(src_oloc);
+ HDassert(dst_oloc);
+ HDassert(src_oloc->file);
+ HDassert(dst_oloc->file);
+
+ udata.ainfo = ainfo_src;
+ udata.file = src_oloc->file;
+ udata.cpy_info = cpy_info; /* Information on copying options */
+ udata.dxpl_id = dxpl_id; /* DXPL for operation */
+ udata.oloc_src = src_oloc;
+ udata.oloc_dst = dst_oloc;
+
+ attr_op.op_type = H5A_ATTR_OP_LIB;
+ attr_op.u.lib_op = H5A_dense_post_copy_file_cb;
+
+ if(H5A_dense_iterate(dst_oloc->file, dxpl_id, (hid_t)0, ainfo_dst, H5_INDEX_NAME,
+ H5_ITER_NATIVE, (hsize_t)0, NULL, &attr_op, &udata) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "error building attribute table")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
diff --git a/src/H5Apkg.h b/src/H5Apkg.h
index a1b5e62..9027864 100644
--- a/src/H5Apkg.h
+++ b/src/H5Apkg.h
@@ -279,6 +279,15 @@ H5_DLL htri_t H5O_attr_exists(const H5O_loc_t *loc, const char *name, hid_t dxpl
#ifndef H5_NO_DEPRECATED_SYMBOLS
H5_DLL int H5O_attr_count(const H5O_loc_t *loc, hid_t dxpl_id);
#endif /* H5_NO_DEPRECATED_SYMBOLS */
+H5_DLL H5A_t *H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_size,
+ H5O_copy_t *cpy_info, hid_t dxpl_id);
+H5_DLL herr_t H5A_attr_post_copy_file(const H5O_loc_t *src_oloc, const H5A_t *mesg_src,
+ H5O_loc_t *dst_oloc, const H5A_t *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info);
+H5_DLL herr_t H5A_dense_copy_file_all(H5F_t *file_src, H5O_ainfo_t *ainfo_src, H5F_t *file_dst,
+ const H5O_ainfo_t *ainfo_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, hid_t dxpl_id);
+H5_DLL herr_t H5A_dense_post_copy_file_all(const H5O_loc_t *src_oloc, const H5O_ainfo_t * ainfo_src,
+ H5O_loc_t *dst_oloc, H5O_ainfo_t *ainfo_dst, hid_t dxpl_id, H5O_copy_t *cpy_info);
+
/* Testing functions */
#ifdef H5A_TESTING
diff --git a/src/H5EA.c b/src/H5EA.c
index aa65da7..86c54fd 100644
--- a/src/H5EA.c
+++ b/src/H5EA.c
@@ -355,15 +355,9 @@ HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx);
HDfprintf(stderr, "%s: Index block address not defined!\n", FUNC, idx);
#endif /* QAK */
/* Create the index block */
- hdr->idx_blk_addr = H5EA__iblock_create(hdr, dxpl_id);
+ hdr->idx_blk_addr = H5EA__iblock_create(hdr, dxpl_id, &hdr_dirty);
if(!H5F_addr_defined(hdr->idx_blk_addr))
H5E_THROW(H5E_CANTCREATE, "unable to create index block")
-
- /* Increment count of elements "realized" */
- hdr->stats.nelmts += hdr->cparam.idx_blk_elmts;
-
- /* Mark the header dirty */
- hdr_dirty = TRUE;
} /* end if */
#ifdef QAK
HDfprintf(stderr, "%s: Index block address is: %a\n", FUNC, hdr->idx_blk_addr);
@@ -415,18 +409,13 @@ HDfprintf(stderr, "%s: dblk_idx = %u, iblock->ndblk_addrs = %Zu\n", FUNC, dblk_i
/* Create data block */
dblk_off = hdr->sblk_info[sblk_idx].start_idx + (dblk_idx * hdr->sblk_info[sblk_idx].dblk_nelmts);
- dblk_addr = H5EA__dblock_create(hdr, dxpl_id, dblk_off, hdr->sblk_info[sblk_idx].dblk_nelmts);
+ dblk_addr = H5EA__dblock_create(hdr, dxpl_id, &hdr_dirty, dblk_off, hdr->sblk_info[sblk_idx].dblk_nelmts);
if(!H5F_addr_defined(dblk_addr))
H5E_THROW(H5E_CANTCREATE, "unable to create extensible array data block")
/* Set data block address in index block */
iblock->dblk_addrs[dblk_idx] = dblk_addr;
iblock_cache_flags |= H5AC__DIRTIED_FLAG;
-
- /* Increment count of elements "realized" and actual data blocks created */
- hdr->stats.ndata_blks++;
- hdr->stats.nelmts += hdr->sblk_info[sblk_idx].dblk_nelmts;
- hdr_dirty = TRUE;
} /* end if */
/* Protect data block */
@@ -452,7 +441,7 @@ HDfprintf(stderr, "%s: dblk_idx = %u, iblock->ndblk_addrs = %Zu\n", FUNC, dblk_i
haddr_t sblk_addr; /* Address of data block created */
/* Create super block */
- sblk_addr = H5EA__sblock_create(hdr, dxpl_id, sblk_idx);
+ sblk_addr = H5EA__sblock_create(hdr, dxpl_id, &hdr_dirty, sblk_idx);
#ifdef QAK
HDfprintf(stderr, "%s: New super block address is: %a\n", FUNC, sblk_addr);
#endif /* QAK */
@@ -462,10 +451,6 @@ HDfprintf(stderr, "%s: New super block address is: %a\n", FUNC, sblk_addr);
/* Set super block address in index block */
iblock->sblk_addrs[sblk_off] = sblk_addr;
iblock_cache_flags |= H5AC__DIRTIED_FLAG;
-
- /* Increment count of actual super blocks created */
- hdr->stats.nsuper_blks++;
- hdr_dirty = TRUE;
} /* end if */
/* Protect super block */
@@ -486,18 +471,13 @@ HDfprintf(stderr, "%s: dblk_idx = %u, sblock->ndblks = %Zu\n", FUNC, dblk_idx, s
/* Create data block */
dblk_off = hdr->sblk_info[sblk_idx].start_idx + (dblk_idx * hdr->sblk_info[sblk_idx].dblk_nelmts);
- dblk_addr = H5EA__dblock_create(hdr, dxpl_id, dblk_off, sblock->dblk_nelmts);
+ dblk_addr = H5EA__dblock_create(hdr, dxpl_id, &hdr_dirty, dblk_off, sblock->dblk_nelmts);
if(!H5F_addr_defined(dblk_addr))
H5E_THROW(H5E_CANTCREATE, "unable to create extensible array data block")
/* Set data block address in index block */
sblock->dblk_addrs[dblk_idx] = dblk_addr;
sblock_cache_flags |= H5AC__DIRTIED_FLAG;
-
- /* Increment count of elements "realized" and actual data blocks created */
- hdr->stats.ndata_blks++;
- hdr->stats.nelmts += hdr->sblk_info[sblk_idx].dblk_nelmts;
- hdr_dirty = TRUE;
} /* end if */
#ifdef QAK
@@ -832,7 +812,7 @@ CATCH
if(dblk_page && H5EA__dblk_page_unprotect(dblk_page, dxpl_id, H5AC__NO_FLAGS_SET) < 0)
H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array data block page")
-END_FUNC(PRIV) /* end H5EA_set() */
+END_FUNC(PRIV) /* end H5EA_get() */
/*-------------------------------------------------------------------------
diff --git a/src/H5EAcache.c b/src/H5EAcache.c
index bf2bf43..286c6a5 100644
--- a/src/H5EAcache.c
+++ b/src/H5EAcache.c
@@ -254,14 +254,38 @@ H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls,
hdr->cparam.max_dblk_page_nelmts_bits = *p++; /* Log2(Max. # of elements in data block page) - i.e. # of bits needed to store max. # of elements in data block page */
/* Array statistics */
- H5F_DECODE_LENGTH(f, p, hdr->stats.max_idx_set); /* Max. index set (+1) */
+ hdr->stats.hdr_size = size; /* Size of header in file */
H5F_DECODE_LENGTH(f, p, hdr->stats.nsuper_blks); /* Number of super blocks created */
+ H5F_DECODE_LENGTH(f, p, hdr->stats.super_blk_size); /* Size of super blocks created */
H5F_DECODE_LENGTH(f, p, hdr->stats.ndata_blks); /* Number of data blocks created */
+ H5F_DECODE_LENGTH(f, p, hdr->stats.data_blk_size); /* Size of data blocks created */
+ H5F_DECODE_LENGTH(f, p, hdr->stats.max_idx_set); /* Max. index set (+1) */
H5F_DECODE_LENGTH(f, p, hdr->stats.nelmts); /* Number of elements 'realized' */
/* Internal information */
H5F_addr_decode(f, &p, &hdr->idx_blk_addr); /* Address of index block */
+ /* Index block statistics */
+ if(H5F_addr_defined(hdr->idx_blk_addr)) {
+ H5EA_iblock_t iblock; /* Fake index block for computing size */
+
+ /* Set index block count for file */
+ hdr->stats.nindex_blks = 1;
+
+ /* Set up fake index block for computing size on disk */
+ iblock.hdr = hdr;
+ iblock.nsblks = H5EA_SBLK_FIRST_IDX(hdr->cparam.sup_blk_min_data_ptrs);
+ iblock.ndblk_addrs = 2 * ((size_t)hdr->cparam.sup_blk_min_data_ptrs - 1);
+ iblock.nsblk_addrs = hdr->nsblks - iblock.nsblks;
+
+ /* Compute size of index block in file */
+ hdr->stats.index_blk_size = H5EA_IBLOCK_SIZE(&iblock);
+ } /* end if */
+ else {
+ hdr->stats.nindex_blks = 0; /* Number of index blocks in file */
+ hdr->stats.index_blk_size = 0; /* Size of index blocks in file */
+ } /* end else */
+
/* Sanity check */
/* (allow for checksum not decoded yet) */
HDassert((size_t)(p - buf) == (size - H5EA_SIZEOF_CHKSUM));
@@ -365,9 +389,11 @@ H5EA__cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
*p++ = hdr->cparam.max_dblk_page_nelmts_bits; /* Log2(Max. # of elements in data block page) - i.e. # of bits needed to store max. # of elements in data block page */
/* Array statistics */
- H5F_ENCODE_LENGTH(f, p, hdr->stats.max_idx_set); /* Max. index set (+1) */
H5F_ENCODE_LENGTH(f, p, hdr->stats.nsuper_blks); /* Number of super blocks created */
+ H5F_ENCODE_LENGTH(f, p, hdr->stats.super_blk_size); /* Size of super blocks created */
H5F_ENCODE_LENGTH(f, p, hdr->stats.ndata_blks); /* Number of data blocks created */
+ H5F_ENCODE_LENGTH(f, p, hdr->stats.data_blk_size); /* Size of data blocks created */
+ H5F_ENCODE_LENGTH(f, p, hdr->stats.max_idx_set); /* Max. index set (+1) */
H5F_ENCODE_LENGTH(f, p, hdr->stats.nelmts); /* Number of elements 'realized' */
/* Internal information */
diff --git a/src/H5EAdblock.c b/src/H5EAdblock.c
index b64cb7d..aec5af2 100644
--- a/src/H5EAdblock.c
+++ b/src/H5EAdblock.c
@@ -160,10 +160,12 @@ END_FUNC(PKG) /* end H5EA__dblock_alloc() */
*/
BEGIN_FUNC(PKG, ERR,
haddr_t, HADDR_UNDEF, HADDR_UNDEF,
-H5EA__dblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, hsize_t dblk_off, size_t nelmts))
+H5EA__dblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, hbool_t *hdr_dirty,
+ hsize_t dblk_off, size_t nelmts))
/* Local variables */
- H5EA_dblock_t *dblock = NULL; /* Extensible array data block */
+ H5EA_dblock_t *dblock = NULL; /* Extensible array data block */
+ haddr_t dblock_addr; /* Extensible array data block address */
#ifdef QAK
HDfprintf(stderr, "%s: Called, hdr->dblk_page_nelmts = %Zu, nelmts = %Zu\n", FUNC, hdr->dblk_page_nelmts, nelmts);
@@ -171,6 +173,7 @@ HDfprintf(stderr, "%s: Called, hdr->dblk_page_nelmts = %Zu, nelmts = %Zu\n", FUN
/* Sanity check */
HDassert(hdr);
+ HDassert(hdr_dirty);
HDassert(nelmts > 0);
/* Allocate the data block */
@@ -190,8 +193,9 @@ HDfprintf(stderr, "%s: dblock->block_off = %Hu\n", FUNC, dblock->block_off);
#endif /* QAK */
/* Allocate space for the data block on disk */
- if(HADDR_UNDEF == (dblock->addr = H5MF_alloc(hdr->f, H5FD_MEM_EARRAY_DBLOCK, dxpl_id, (hsize_t)dblock->size)))
+ if(HADDR_UNDEF == (dblock_addr = H5MF_alloc(hdr->f, H5FD_MEM_EARRAY_DBLOCK, dxpl_id, (hsize_t)dblock->size)))
H5E_THROW(H5E_CANTALLOC, "file allocation failed for extensible array data block")
+ dblock->addr = dblock_addr;
/* Don't initialize elements if paged */
if(!dblock->npages)
@@ -200,11 +204,21 @@ HDfprintf(stderr, "%s: dblock->block_off = %Hu\n", FUNC, dblock->block_off);
H5E_THROW(H5E_CANTSET, "can't set extensible array data block elements to class's fill value")
/* Cache the new extensible array data block */
- if(H5AC_set(hdr->f, dxpl_id, H5AC_EARRAY_DBLOCK, dblock->addr, dblock, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_set(hdr->f, dxpl_id, H5AC_EARRAY_DBLOCK, dblock_addr, dblock, H5AC__NO_FLAGS_SET) < 0)
H5E_THROW(H5E_CANTINSERT, "can't add extensible array data block to cache")
+ /* Update extensible array data block statistics */
+ hdr->stats.ndata_blks++;
+ hdr->stats.data_blk_size += dblock->size;
+
+ /* Increment count of elements "realized" */
+ hdr->stats.nelmts += nelmts;
+
+ /* Mark the header dirty (for updating statistics) */
+ *hdr_dirty = TRUE;
+
/* Set address of data block to return */
- ret_value = dblock->addr;
+ ret_value = dblock_addr;
CATCH
if(!H5F_addr_defined(ret_value))
diff --git a/src/H5EAhdr.c b/src/H5EAhdr.c
index 349dceb..998e169 100644
--- a/src/H5EAhdr.c
+++ b/src/H5EAhdr.c
@@ -235,8 +235,8 @@ HDfprintf(stderr, "%s: hdr->sblk_info[%Zu] = {%Zu, %Zu, %Hu, %Hu}\n", FUNC, u, h
start_dblk += (hsize_t)hdr->sblk_info[u].ndblks;
} /* end for */
- /* Set size of header on disk */
- hdr->size = H5EA_HEADER_SIZE(hdr);
+ /* Set size of header on disk (locally and in statistics) */
+ hdr->stats.hdr_size = hdr->size = H5EA_HEADER_SIZE(hdr);
CATCH
diff --git a/src/H5EAiblock.c b/src/H5EAiblock.c
index dcb75d1..6fd6f2a 100644
--- a/src/H5EAiblock.c
+++ b/src/H5EAiblock.c
@@ -178,10 +178,11 @@ END_FUNC(PKG) /* end H5EA__iblock_alloc() */
*/
BEGIN_FUNC(PKG, ERR,
haddr_t, HADDR_UNDEF, HADDR_UNDEF,
-H5EA__iblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id))
+H5EA__iblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, hbool_t *hdr_dirty))
/* Local variables */
- H5EA_iblock_t *iblock = NULL; /* Extensible array index block */
+ H5EA_iblock_t *iblock = NULL; /* Extensible array index block */
+ haddr_t iblock_addr; /* Extensible array index block address */
#ifdef QAK
HDfprintf(stderr, "%s: Called\n", FUNC);
@@ -189,6 +190,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
/* Sanity check */
HDassert(hdr);
+ HDassert(hdr_dirty);
/* Allocate the index block */
if(NULL == (iblock = H5EA__iblock_alloc(hdr)))
@@ -201,8 +203,9 @@ HDfprintf(stderr, "%s: iblock->size = %Zu\n", FUNC, iblock->size);
#endif /* QAK */
/* Allocate space for the index block on disk */
- if(HADDR_UNDEF == (iblock->addr = H5MF_alloc(hdr->f, H5FD_MEM_EARRAY_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
+ if(HADDR_UNDEF == (iblock_addr = H5MF_alloc(hdr->f, H5FD_MEM_EARRAY_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
H5E_THROW(H5E_CANTALLOC, "file allocation failed for extensible array index block")
+ iblock->addr = iblock_addr;
/* Clear any elements in index block to fill value */
if(hdr->cparam.idx_blk_elmts > 0) {
@@ -228,11 +231,23 @@ HDfprintf(stderr, "%s: iblock->size = %Zu\n", FUNC, iblock->size);
} /* end if */
/* Cache the new extensible array index block */
- if(H5AC_set(hdr->f, dxpl_id, H5AC_EARRAY_IBLOCK, iblock->addr, iblock, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_set(hdr->f, dxpl_id, H5AC_EARRAY_IBLOCK, iblock_addr, iblock, H5AC__NO_FLAGS_SET) < 0)
H5E_THROW(H5E_CANTINSERT, "can't add extensible array index block to cache")
+ /* Update extensible array index block statistics */
+ HDassert(0 == hdr->stats.nindex_blks);
+ HDassert(0 == hdr->stats.index_blk_size);
+ hdr->stats.nindex_blks = 1;
+ hdr->stats.index_blk_size = iblock->size;
+
+ /* Increment count of elements "realized" */
+ hdr->stats.nelmts += hdr->cparam.idx_blk_elmts;
+
+ /* Mark the header dirty (for updating statistics) */
+ *hdr_dirty = TRUE;
+
/* Set address of index block to return */
- ret_value = iblock->addr;
+ ret_value = iblock_addr;
CATCH
if(!H5F_addr_defined(ret_value))
diff --git a/src/H5EApkg.h b/src/H5EApkg.h
index 7ac5be6..e374d3a 100644
--- a/src/H5EApkg.h
+++ b/src/H5EApkg.h
@@ -372,9 +372,11 @@ func_init_failed: \
+ 1 /* Log2(Max. # of elements in data block page) - i.e. # of bits needed to store max. # of elements in data block page */ \
\
/* Extensible Array Header statistics fields */ \
- + (h)->sizeof_size /* Max. index set */ \
+ (h)->sizeof_size /* Number of super blocks created */ \
+ + (h)->sizeof_size /* Size of super blocks created */ \
+ (h)->sizeof_size /* Number of data blocks created */ \
+ + (h)->sizeof_size /* Size of data blocks created */ \
+ + (h)->sizeof_size /* Max. index set */ \
+ (h)->sizeof_size /* Number of elements 'realized' */ \
\
/* Extensible Array Header specific fields */ \
@@ -471,6 +473,7 @@ typedef struct H5EA_hdr_t {
haddr_t idx_blk_addr; /* Address of index block in header */
/* Statistics for array (stored in header) */
+ /* (header and index number/size fields not stored) */
H5EA_stat_t stats; /* Statistics for extensible array */
/* Data block element buffer factory info (not stored in header) */
@@ -636,7 +639,8 @@ H5_DLL herr_t H5EA__hdr_dest(H5EA_hdr_t *hdr);
/* Index block routines */
H5_DLL H5EA_iblock_t *H5EA__iblock_alloc(H5EA_hdr_t *hdr);
-H5_DLL haddr_t H5EA__iblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id);
+H5_DLL haddr_t H5EA__iblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id,
+ hbool_t *hdr_dirty);
H5_DLL H5EA_iblock_t *H5EA__iblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id,
H5AC_protect_t rw);
H5_DLL herr_t H5EA__iblock_unprotect(H5EA_iblock_t *iblock, hid_t dxpl_id,
@@ -646,7 +650,8 @@ H5_DLL herr_t H5EA__iblock_dest(H5F_t *f, H5EA_iblock_t *iblock);
/* Super block routines */
H5_DLL H5EA_sblock_t *H5EA__sblock_alloc(H5EA_hdr_t *hdr, unsigned sblk_idx);
-H5_DLL haddr_t H5EA__sblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, unsigned sblk_idx);
+H5_DLL haddr_t H5EA__sblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, hbool_t *hdr_dirty,
+ unsigned sblk_idx);
H5_DLL H5EA_sblock_t *H5EA__sblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id,
haddr_t sblk_addr, unsigned sblk_idx, H5AC_protect_t rw);
H5_DLL herr_t H5EA__sblock_unprotect(H5EA_sblock_t *sblock, hid_t dxpl_id,
@@ -657,7 +662,7 @@ H5_DLL herr_t H5EA__sblock_dest(H5F_t *f, H5EA_sblock_t *sblock);
/* Data block routines */
H5_DLL H5EA_dblock_t *H5EA__dblock_alloc(H5EA_hdr_t *hdr, size_t nelmts);
-H5_DLL haddr_t H5EA__dblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id,
+H5_DLL haddr_t H5EA__dblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, hbool_t *hdr_dirty,
hsize_t dblk_off, size_t nelmts);
H5_DLL unsigned H5EA__dblock_sblk_idx(const H5EA_hdr_t *hdr, hsize_t idx);
H5_DLL H5EA_dblock_t *H5EA__dblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id,
diff --git a/src/H5EAprivate.h b/src/H5EAprivate.h
index 3b9ba4d..f44d046 100644
--- a/src/H5EAprivate.h
+++ b/src/H5EAprivate.h
@@ -83,9 +83,17 @@ typedef struct H5EA_create_t {
/* Extensible array metadata statistics info */
typedef struct H5EA_stat_t {
- hsize_t max_idx_set; /* Highest element index stored (+1 - i.e. if element 0 has been set, this value with be '1', if no elements have been stored, this value will be '0') */
+ /* Non-stored (i.e. computed) fields */
+ hsize_t hdr_size; /* Size of header */
+ hsize_t nindex_blks; /* # of index blocks (should be 0 or 1) */
+ hsize_t index_blk_size; /* Size of index blocks allocated */
+
+ /* Stored fields */
hsize_t nsuper_blks; /* # of super blocks */
+ hsize_t super_blk_size; /* Size of super blocks allocated */
hsize_t ndata_blks; /* # of data blocks */
+ hsize_t data_blk_size; /* Size of data blocks allocated */
+ hsize_t max_idx_set; /* Highest element index stored (+1 - i.e. if element 0 has been set, this value with be '1', if no elements have been stored, this value will be '0') */
hsize_t nelmts; /* # of elements "realized" */
} H5EA_stat_t;
diff --git a/src/H5EAsblock.c b/src/H5EAsblock.c
index 3d3d4e3..4ad83b0 100644
--- a/src/H5EAsblock.c
+++ b/src/H5EAsblock.c
@@ -190,11 +190,13 @@ END_FUNC(PKG) /* end H5EA__sblock_alloc() */
*/
BEGIN_FUNC(PKG, ERR,
haddr_t, HADDR_UNDEF, HADDR_UNDEF,
-H5EA__sblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, unsigned sblk_idx))
+H5EA__sblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, hbool_t *hdr_dirty,
+ unsigned sblk_idx))
/* Local variables */
- H5EA_sblock_t *sblock = NULL; /* Extensible array super block */
- haddr_t tmp_addr = HADDR_UNDEF; /* Address value to fill data block addresses with */
+ H5EA_sblock_t *sblock = NULL; /* Extensible array super block */
+ haddr_t sblock_addr; /* Extensible array super block address */
+ haddr_t tmp_addr = HADDR_UNDEF; /* Address value to fill data block addresses with */
#ifdef QAK
HDfprintf(stderr, "%s: Called\n", FUNC);
@@ -202,6 +204,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
/* Sanity check */
HDassert(hdr);
+ HDassert(hdr_dirty);
/* Allocate the super block */
if(NULL == (sblock = H5EA__sblock_alloc(hdr, sblk_idx)))
@@ -220,18 +223,26 @@ HDfprintf(stderr, "%s: sblock->block_off = %Hu\n", FUNC, sblock->block_off);
#endif /* QAK */
/* Allocate space for the super block on disk */
- if(HADDR_UNDEF == (sblock->addr = H5MF_alloc(hdr->f, H5FD_MEM_EARRAY_SBLOCK, dxpl_id, (hsize_t)sblock->size)))
+ if(HADDR_UNDEF == (sblock_addr = H5MF_alloc(hdr->f, H5FD_MEM_EARRAY_SBLOCK, dxpl_id, (hsize_t)sblock->size)))
H5E_THROW(H5E_CANTALLOC, "file allocation failed for extensible array super block")
+ sblock->addr = sblock_addr;
/* Reset data block addresses to "undefined" address value */
H5V_array_fill(sblock->dblk_addrs, &tmp_addr, sizeof(haddr_t), sblock->ndblks);
/* Cache the new extensible array super block */
- if(H5AC_set(hdr->f, dxpl_id, H5AC_EARRAY_SBLOCK, sblock->addr, sblock, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_set(hdr->f, dxpl_id, H5AC_EARRAY_SBLOCK, sblock_addr, sblock, H5AC__NO_FLAGS_SET) < 0)
H5E_THROW(H5E_CANTINSERT, "can't add extensible array super block to cache")
+ /* Update extensible array super block statistics */
+ hdr->stats.nsuper_blks++;
+ hdr->stats.super_blk_size += sblock->size;
+
+ /* Mark the header dirty (for updating statistics) */
+ *hdr_dirty = TRUE;
+
/* Set address of super block to return */
- ret_value = sblock->addr;
+ ret_value = sblock_addr;
CATCH
if(!H5F_addr_defined(ret_value))
diff --git a/src/H5FDcore.c b/src/H5FDcore.c
index cda7308..1e30ace 100644
--- a/src/H5FDcore.c
+++ b/src/H5FDcore.c
@@ -378,6 +378,9 @@ done:
* Raymond Lu, 2006-11-30
* Enabled the driver to read an existing file depending on
* the setting of the backing_store and file open flags.
+ *
+ * Allen Byrne, 2008-1-23
+ * changed if of fapl_id to assert
*-------------------------------------------------------------------------
*/
static H5FD_t *
@@ -401,11 +404,10 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr")
if(ADDR_OVERFLOW(maxaddr))
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "maxaddr overflow")
- if(H5P_DEFAULT != fapl_id) {
- if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
- fa = (H5FD_core_fapl_t *)H5P_get_driver_info(plist);
- } /* end if */
+ assert(H5P_DEFAULT != fapl_id);
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
+ fa = (H5FD_core_fapl_t *)H5P_get_driver_info(plist);
/* Build the open flags */
o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY;
diff --git a/src/H5O.c b/src/H5O.c
index 52338cc..1d640fa 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -2273,8 +2273,7 @@ H5O_get_info(H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info_t *o
HDassert(oinfo);
/* Get the object header */
- if(NULL == (oh = (H5O_t *)H5AC_protect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, NULL, NULL,
- (H5F_get_intent(oloc->file) & H5F_ACC_RDWR) ? H5AC_WRITE : H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Reset the object info structure */
diff --git a/src/H5Oainfo.c b/src/H5Oainfo.c
index 2a9d403..7f6a55d 100644
--- a/src/H5Oainfo.c
+++ b/src/H5Oainfo.c
@@ -48,6 +48,9 @@ static herr_t H5O_ainfo_pre_copy_file(H5F_t *file_src, const void *mesg_src,
static void *H5O_ainfo_copy_file(H5F_t *file_src, void *mesg_src,
H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, void *udata,
hid_t dxpl_id);
+static herr_t H5O_ainfo_post_copy_file(const H5O_loc_t *src_oloc,
+ const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id,
+ H5O_copy_t *cpy_info);
static herr_t H5O_ainfo_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -69,7 +72,7 @@ const H5O_msg_class_t H5O_MSG_AINFO[1] = {{
NULL, /*can share method */
H5O_ainfo_pre_copy_file, /* pre copy native value to file */
H5O_ainfo_copy_file, /* copy native value to file */
- NULL, /* post copy native value to file */
+ H5O_ainfo_post_copy_file, /* post copy native value to file */
NULL, /* get creation index */
NULL, /* set creation index */
H5O_ainfo_debug /*debug the message */
@@ -393,15 +396,14 @@ H5O_ainfo_pre_copy_file(H5F_t UNUSED *file_src, const void UNUSED *native_src,
* Return: Success: Ptr to _DEST
* Failure: NULL
*
- * Programmer: Quincey Koziol
- * March 9, 2007
+ * Programmer: Peter Cao
+ * July 18, 2007
*
*-------------------------------------------------------------------------
*/
static void *
-H5O_ainfo_copy_file(H5F_t UNUSED *file_src, void *mesg_src,
- H5F_t UNUSED *file_dst, hbool_t UNUSED *recompute_size,
- H5O_copy_t UNUSED *cpy_info, void UNUSED *udata, hid_t UNUSED dxpl_id)
+H5O_ainfo_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
+ hbool_t *recompute_size, H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id)
{
H5O_ainfo_t *ainfo_src = (H5O_ainfo_t *)mesg_src;
H5O_ainfo_t *ainfo_dst = NULL;
@@ -416,10 +418,6 @@ H5O_ainfo_copy_file(H5F_t UNUSED *file_src, void *mesg_src,
HDassert(cpy_info);
HDassert(!cpy_info->copy_without_attr);
-/* XXX: Bail out for now, if the source object has densely stored attributes */
- if(H5F_addr_defined(ainfo_src->fheap_addr))
- HGOTO_ERROR(H5E_OHDR, H5E_UNSUPPORTED, NULL, "densely stored attributes not supported yet")
-
/* Allocate space for the destination message */
if(NULL == (ainfo_dst = H5FL_MALLOC(H5O_ainfo_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
@@ -427,6 +425,16 @@ H5O_ainfo_copy_file(H5F_t UNUSED *file_src, void *mesg_src,
/* Copy the top level of the information */
*ainfo_dst = *ainfo_src;
+ if(H5F_addr_defined(ainfo_src->fheap_addr)) {
+ /* copy dense attribute */
+
+ if(H5A_dense_create(file_dst, dxpl_id, ainfo_dst) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to create dense storage for attributes")
+
+ if ( (H5A_dense_copy_file_all(file_src, ainfo_src, file_dst, ainfo_dst, recompute_size, cpy_info, dxpl_id)) <0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to create dense storage for attributes")
+ }
+
/* Set return value */
ret_value = ainfo_dst;
@@ -440,6 +448,44 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_ainfo_post_copy_file
+ *
+ * Purpose: Finish copying a message from between files.
+ * We have to copy the values of a reference attribute in the
+ * post copy because H5O_post_copy_file() fails at the case that
+ * an object may have a reference attribute that points to the
+ * object itself.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Peter Cao
+ * July 25, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_ainfo_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
+ H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
+{
+ H5O_ainfo_t *ainfo_src = (const H5O_ainfo_t *)mesg_src;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_ainfo_post_copy_file)
+
+ HDassert(ainfo_src);
+
+ if(H5F_addr_defined(ainfo_src->fheap_addr)) {
+ if ( H5A_dense_post_copy_file_all(src_oloc, ainfo_src, dst_oloc,
+ (H5O_ainfo_t *)mesg_dst, dxpl_id, cpy_info) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "can't copy attribute")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_ainfo_post_copy_file() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_ainfo_debug
*
* Purpose: Prints debugging info for a message.
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index 85b1ef3..b875d02 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -20,13 +20,10 @@
#include "H5private.h" /* Generic Functions */
#include "H5Apkg.h" /* Attributes */
-#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
-#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
#include "H5Spkg.h" /* Dataspaces */
-#include "H5SMprivate.h" /* Shared Object Header Messages */
/* PRIVATE PROTOTYPES */
static herr_t H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg);
@@ -641,257 +638,20 @@ H5O_attr_copy_file(H5F_t UNUSED *file_src, const H5O_msg_class_t UNUSED *mesg_ty
void *native_src, H5F_t *file_dst, hbool_t *recompute_size,
H5O_copy_t *cpy_info, void UNUSED *udata, hid_t dxpl_id)
{
- H5A_t *attr_src = (H5A_t *)native_src;
- H5A_t *attr_dst = NULL;
-
- /* for dataype conversion */
- hid_t tid_src = -1; /* Datatype ID for source datatype */
- hid_t tid_dst = -1; /* Datatype ID for destination datatype */
- hid_t tid_mem = -1; /* Datatype ID for memory datatype */
- void *buf = NULL; /* Buffer for copying data */
- void *reclaim_buf = NULL; /* Buffer for reclaiming data */
- hid_t buf_sid = -1; /* ID for buffer dataspace */
-
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_attr_copy_file)
/* check args */
- HDassert(attr_src);
+ HDassert(native_src);
HDassert(file_dst);
HDassert(cpy_info);
HDassert(!cpy_info->copy_without_attr);
- /* Allocate space for the destination message */
- if(NULL == (attr_dst = H5FL_CALLOC(H5A_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
- /* Copy the top level of the attribute */
- *attr_dst = *attr_src;
-
- if(NULL == (attr_dst->shared = H5FL_CALLOC(H5A_shared_t)))
- HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared attr structure")
-
- /* Don't have an opened group location for copy */
- H5O_loc_reset(&(attr_dst->shared->oloc));
- H5G_name_reset(&(attr_dst->path));
- attr_dst->obj_opened = FALSE;
-
- /* Reference count for the header message in the cache */
- attr_dst->shared->nrefs = 1;
-
- /* Copy attribute's name */
- attr_dst->shared->name = H5MM_strdup(attr_src->shared->name);
- HDassert(attr_dst->shared->name);
-
- /* Copy attribute's datatype */
- /* (Start destination datatype as transient, even if source is named) */
- if(NULL == (attr_dst->shared->dt = H5T_copy(attr_src->shared->dt, H5T_COPY_ALL)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "cannot copy datatype")
-
- /* Set the location of the destination datatype */
- if(H5T_set_loc(attr_dst->shared->dt, file_dst, H5T_LOC_DISK) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "cannot mark datatype on disk")
-
- /* Check for named datatype being copied */
- if(H5T_committed(attr_src->shared->dt)) {
- H5O_loc_t *src_oloc; /* Pointer to source datatype's object location */
- H5O_loc_t *dst_oloc; /* Pointer to dest. datatype's object location */
-
- /* Get group entries for source & destination */
- src_oloc = H5T_oloc(attr_src->shared->dt);
- HDassert(src_oloc);
- dst_oloc = H5T_oloc(attr_dst->shared->dt);
- HDassert(dst_oloc);
-
- /* Reset object location for new object */
- H5O_loc_reset(dst_oloc);
- dst_oloc->file = file_dst;
-
- /* Copy the shared object from source to destination */
- if(H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, cpy_info, FALSE) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object")
-
- /* Update shared message info from named datatype info */
- H5T_update_shared(attr_dst->shared->dt);
- } /* end if */
- else {
- /* If the datatype is not named, it may have been shared in the
- * source file's heap. Un-share it for now. We'll try to shared
- * it in the destination file below.
- */
- if(H5O_msg_reset_share(H5O_DTYPE_ID, attr_dst->shared->dt) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to reset datatype sharing")
- } /* end else */
-
- /* Copy the dataspace for the attribute */
- attr_dst->shared->ds = H5S_copy(attr_src->shared->ds, FALSE, FALSE);
- HDassert(attr_dst->shared->ds);
-
- /* Reset the dataspace's sharing in the source file before trying to share
- * it in the destination.
- */
- if(H5O_msg_reset_share(H5O_SDSPACE_ID, attr_dst->shared->ds) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to reset dataspace sharing")
-
-
- /* Try to share both the datatype and dataset. This does nothing if the
- * datatype is committed or sharing is disabled.
- */
- if(H5SM_try_share(file_dst, dxpl_id, NULL, H5O_DTYPE_ID, attr_dst->shared->dt, NULL) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "can't share attribute datatype")
- if(H5SM_try_share(file_dst, dxpl_id, NULL, H5O_SDSPACE_ID, attr_dst->shared->ds, NULL) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "can't share attribute dataspace")
-
- /* Compute the sizes of the datatype and dataspace. This is their raw
- * size unless they're shared.
- */
- attr_dst->shared->dt_size = H5O_msg_raw_size(file_dst, H5O_DTYPE_ID, FALSE, attr_dst->shared->dt);
- HDassert(attr_dst->shared->dt_size > 0);
- attr_dst->shared->ds_size = H5O_msg_raw_size(file_dst, H5O_SDSPACE_ID, FALSE, attr_dst->shared->ds);
- HDassert(attr_dst->shared->ds_size > 0);
-
- /* Check whether to recompute the size of the attribute */
- /* (happens when the datatype or dataspace changes sharing status) */
- if(attr_dst->shared->dt_size != attr_src->shared->dt_size || attr_dst->shared->ds_size != attr_src->shared->ds_size)
- *recompute_size = TRUE;
-
- /* Compute the size of the data */
- H5_ASSIGN_OVERFLOW(attr_dst->shared->data_size, H5S_GET_EXTENT_NPOINTS(attr_dst->shared->ds) * H5T_get_size(attr_dst->shared->dt), hsize_t, size_t);
-
- /* Copy (& convert) the data, if necessary */
- if(attr_src->shared->data) {
- if(NULL == (attr_dst->shared->data = H5FL_BLK_MALLOC(attr_buf, attr_dst->shared->data_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
- /* Check if we need to convert data */
- if(H5T_detect_class(attr_src->shared->dt, H5T_VLEN) > 0) {
- H5T_path_t *tpath_src_mem, *tpath_mem_dst; /* Datatype conversion paths */
- H5T_t *dt_mem; /* Memory datatype */
- size_t src_dt_size; /* Source datatype size */
- size_t tmp_dt_size; /* Temp. datatype size */
- size_t max_dt_size; /* Max atatype size */
- H5S_t *buf_space; /* Dataspace describing buffer */
- hsize_t buf_dim; /* Dimension for buffer */
- size_t nelmts; /* Number of elements in buffer */
- size_t buf_size; /* Size of copy buffer */
-
- /* Create datatype ID for src datatype */
- if((tid_src = H5I_register(H5I_DATATYPE, attr_src->shared->dt, FALSE)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register source file datatype")
-
- /* create a memory copy of the variable-length datatype */
- if(NULL == (dt_mem = H5T_copy(attr_src->shared->dt, H5T_COPY_TRANSIENT)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy")
- if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem, FALSE)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register memory datatype")
-
- /* create variable-length datatype at the destinaton file */
- if((tid_dst = H5I_register(H5I_DATATYPE, attr_dst->shared->dt, FALSE)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register destination file datatype")
-
- /* Set up the conversion functions */
- if(NULL == (tpath_src_mem = H5T_path_find(attr_src->shared->dt, dt_mem, NULL, NULL, dxpl_id, FALSE)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to convert between src and mem datatypes")
- if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, attr_dst->shared->dt, NULL, NULL, dxpl_id, FALSE)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to convert between mem and dst datatypes")
-
- /* Determine largest datatype size */
- if(0 == (src_dt_size = H5T_get_size(attr_src->shared->dt)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to determine datatype size")
- if(0 == (tmp_dt_size = H5T_get_size(dt_mem)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to determine datatype size")
- max_dt_size = MAX(src_dt_size, tmp_dt_size);
- if(0 == (tmp_dt_size = H5T_get_size(attr_dst->shared->dt)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to determine datatype size")
- max_dt_size = MAX(max_dt_size, tmp_dt_size);
-
- /* Set number of whole elements that fit in buffer */
- if(0 == (nelmts = attr_src->shared->data_size / src_dt_size))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "element size too large")
-
- /* Set up number of bytes to copy, and initial buffer size */
- buf_size = nelmts * max_dt_size;
-
- /* Create dataspace for number of elements in buffer */
- buf_dim = nelmts;
-
- /* Create the space and set the initial extent */
- if(NULL == (buf_space = H5S_create_simple((unsigned)1, &buf_dim, NULL)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, NULL, "can't create simple dataspace")
-
- /* Atomize */
- if((buf_sid = H5I_register(H5I_DATASPACE, buf_space, FALSE)) < 0) {
- H5S_close(buf_space);
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, NULL, "unable to register dataspace ID")
- } /* end if */
-
- /* Allocate memory for recclaim buf */
- if(NULL == (reclaim_buf = H5FL_BLK_MALLOC(attr_buf, buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation NULLed for raw data chunk")
-
- /* Allocate memory for copying the chunk */
- if(NULL == (buf = H5FL_BLK_MALLOC(attr_buf, buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation NULLed for raw data chunk")
-
- HDmemcpy(buf, attr_src->shared->data, attr_src->shared->data_size);
-
- /* Convert from source file to memory */
- if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "datatype conversion NULLed")
-
- HDmemcpy(reclaim_buf, buf, buf_size);
-
- /* Convert from memory to destination file */
- if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "datatype conversion NULLed")
-
- HDmemcpy(attr_dst->shared->data, buf, attr_dst->shared->data_size);
-
- if(H5D_vlen_reclaim(tid_mem, buf_space, H5P_DATASET_XFER_DEFAULT, reclaim_buf) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_BADITER, NULL, "unable to reclaim variable-length data")
- } /* end if */
- else {
- HDassert(attr_dst->shared->data_size == attr_src->shared->data_size);
- HDmemcpy(attr_dst->shared->data, attr_src->shared->data, attr_src->shared->data_size);
- } /* end else */
- } /* end if(attr_src->shared->data) */
-
- /* Recompute the version to encode the destination attribute */
- if(H5A_set_version(file_dst, attr_dst) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, NULL, "unable to update attribute version")
-
- /* Indicate that the fill values aren't to be written out */
- attr_dst->shared->initialized = TRUE;
-
- /* Set return value */
- ret_value = attr_dst;
+ if ( NULL == (ret_value=H5A_attr_copy_file((H5A_t *)native_src, file_dst, recompute_size, cpy_info, dxpl_id)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "can't copy attribute")
done:
- if(buf_sid > 0)
- if(H5I_dec_ref(buf_sid, FALSE) < 0)
- HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary dataspace ID")
- if(tid_src > 0)
- /* Don't decrement ID, we want to keep underlying datatype */
- if(H5I_remove(tid_src) == NULL)
- HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
- if(tid_dst > 0)
- /* Don't decrement ID, we want to keep underlying datatype */
- if(H5I_remove(tid_dst) == NULL)
- HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
- if(tid_mem > 0)
- /* Decrement the memory datatype ID, it's transient */
- if(H5I_dec_ref(tid_mem, FALSE) < 0)
- HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
- if(buf)
- buf = H5FL_BLK_FREE(attr_buf, buf);
- if(reclaim_buf)
- reclaim_buf = H5FL_BLK_FREE(attr_buf, reclaim_buf);
-
- /* Release destination attribute information on failure */
- if(!ret_value && attr_dst && H5A_close(attr_dst) < 0)
- HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute")
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5O_attr_copy_file() */
@@ -916,48 +676,14 @@ static herr_t
H5O_attr_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
{
- const H5A_t *attr_src = (const H5A_t *)mesg_src;
- H5A_t *attr_dst = (H5A_t *)mesg_dst;
- H5F_t *file_src = src_oloc->file;
- H5F_t *file_dst = dst_oloc->file;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_attr_post_copy_file)
- /* check args */
- HDassert(attr_src);
- HDassert(file_src);
- HDassert(attr_dst);
- HDassert(file_dst);
-
- /* Only need to fix reference attribute with real data being copied to
- * another file.
- */
- if((NULL != attr_src->shared->data) &&
- (H5T_get_class(attr_src->shared->dt, FALSE) == H5T_REFERENCE) &&
- (file_src != file_dst)) {
-
- /* copy object pointed by reference. The current implementation does not
- * deal with nested reference such as reference in a compound structure
- */
-
- /* Check for expanding references */
- if(cpy_info->expand_ref) {
- size_t ref_count;
-
- /* Determine # of reference elements to copy */
- ref_count = attr_dst->shared->data_size / H5T_get_size(attr_dst->shared->dt);
-
- /* Copy objects referenced in source buffer to destination file and set destination elements */
- if(H5O_copy_expand_ref(file_src, attr_src->shared->data, dxpl_id,
- file_dst, attr_dst->shared->data, ref_count, H5T_get_ref_type(attr_src->shared->dt), cpy_info) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy reference attribute")
- } /* end if */
- else
- /* Reset value to zero */
- HDmemset(attr_dst->shared->data, 0, attr_dst->shared->data_size);
- } /* end if */
+ if ( H5A_attr_post_copy_file(src_oloc, (const H5A_t *)mesg_src,
+ dst_oloc, (H5A_t *)mesg_dst, dxpl_id, cpy_info) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "can't copy attribute")
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index 846d2ec..ea9a7f5 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -1207,7 +1207,7 @@ H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id,
/* Protect the object header to iterate over */
if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr,
- NULL, NULL, (H5F_get_intent(loc->file) & H5F_ACC_RDWR) ? H5AC_WRITE : H5AC_READ)))
+ NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Check for attribute info stored */
diff --git a/src/H5Ocache.c b/src/H5Ocache.c
index e5a772f..db093a4 100644
--- a/src/H5Ocache.c
+++ b/src/H5Ocache.c
@@ -880,12 +880,21 @@ HDfprintf(stderr, "%s: oh->cache_info.free_file_space_on_destroy = %t\n", FUNC,
/* destroy messages */
if(oh->mesg) {
for(u = 0; u < oh->nmesgs; u++) {
- /* Verify that message is clean */
- HDassert(oh->mesg[u].dirty == 0);
+ /* Verify that message is clean, unless it could have been marked
+ * dirty by decoding */
+#ifndef NDEBUG
+ if(oh->ndecode_dirtied && oh->mesg[u].dirty)
+ oh->ndecode_dirtied--;
+ else
+ HDassert(oh->mesg[u].dirty == 0);
+#endif /* NDEBUG */
H5O_msg_free_mesg(&oh->mesg[u]);
} /* end for */
+ /* Make sure we accounted for all the messages dirtied by decoding */
+ HDassert(!oh->ndecode_dirtied);
+
oh->mesg = (H5O_mesg_t *)H5FL_SEQ_FREE(H5O_mesg_t, oh->mesg);
} /* end if */
@@ -929,6 +938,11 @@ H5O_clear(H5F_t *f, H5O_t *oh, hbool_t destroy)
for(u = 0; u < oh->nmesgs; u++)
oh->mesg[u].dirty = FALSE;
+#ifndef NDEBUG
+ /* Reset the number of messages dirtied by decoding */
+ oh->ndecode_dirtied = 0;
+#endif /* NDEBUG */
+
/* Mark whole header as clean */
oh->cache_info.is_dirty = FALSE;
diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c
index 9a905d2..5334539 100644
--- a/src/H5Ocopy.c
+++ b/src/H5Ocopy.c
@@ -315,8 +315,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
HDassert(cpy_info);
/* Get source object header */
- if(NULL == (oh_src = (H5O_t *)H5AC_protect(oloc_src->file, dxpl_id, H5AC_OHDR, oloc_src->addr, NULL, NULL,
- (H5F_get_intent(oloc_src->file) & H5F_ACC_RDWR) ? H5AC_WRITE : H5AC_READ)))
+ if(NULL == (oh_src = (H5O_t *)H5AC_protect(oloc_src->file, dxpl_id, H5AC_OHDR, oloc_src->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Get pointer to object class for this object */
diff --git a/src/H5Omessage.c b/src/H5Omessage.c
index 1682117..5a0577a 100644
--- a/src/H5Omessage.c
+++ b/src/H5Omessage.c
@@ -484,8 +484,7 @@ H5O_msg_read(const H5O_loc_t *loc, unsigned type_id, void *mesg,
HDassert(type_id < NELMTS(H5O_msg_class_g));
/* Get the object header */
- if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL,
- (H5F_get_intent(loc->file) & H5F_ACC_RDWR) ? H5AC_WRITE : H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unable to load object header")
/* Call the "real" read routine */
@@ -1231,8 +1230,7 @@ H5O_msg_iterate(const H5O_loc_t *loc, unsigned type_id,
HDassert(op);
/* Protect the object header to iterate over */
- if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL,
- (H5F_get_intent(loc->file) & H5F_ACC_RDWR) ? H5AC_WRITE : H5AC_READ)))
+ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Call the "real" iterate routine */
@@ -2229,6 +2227,12 @@ H5O_flush_msgs(H5F_t *f, H5O_t *oh)
if(oh->nmesgs != u)
HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "corrupt object header - too few messages")
+#ifndef NDEBUG
+ /* Reset the number of messages dirtied by decoding, as they have all
+ * been flushed */
+ oh->ndecode_dirtied = 0;
+#endif /* NDEBUG */
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_flush_msgs() */
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index f15198e..b7d4202 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -171,6 +171,13 @@
#define H5O_DECODEIO_NOCHANGE 0x01u /* IN: do not modify values */
#define H5O_DECODEIO_DIRTY 0x02u /* OUT: message has been changed */
+/* Macro to incremend ndecode_dirtied (only if we are debugging) */
+#ifndef NDEBUG
+#define INCR_NDECODE_DIRTIED(OH) (OH)->ndecode_dirtied++;
+#else /* NDEBUG */
+#define INCR_NDECODE_DIRTIED(OH) ;
+#endif /* NDEBUG */
+
/* Load native information for a message, if it's not already present */
/* (Only works for messages with decode callback) */
#define H5O_LOAD_NATIVE(F, DXPL, IOF, OH, MSG, ERR) \
@@ -183,11 +190,12 @@
if(NULL == ((MSG)->native = (msg_type->decode)((F), (DXPL), (MSG)->flags, &ioflags, (MSG)->raw))) \
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, ERR, "unable to decode message") \
\
- /* Mark the object header dirty if the message was changed by decoding */ \
+ /* Mark the message dirty if it was changed by decoding */ \
if((ioflags & H5O_DECODEIO_DIRTY) && (H5F_get_intent((F)) & H5F_ACC_RDWR)) { \
(MSG)->dirty = TRUE; \
- if(H5AC_mark_pinned_or_protected_entry_dirty((F), (OH)) < 0) \
- HGOTO_ERROR(H5E_OHDR, H5E_CANTMARKDIRTY, ERR, "unable to mark object header as dirty") \
+ /* Increment the count of messages dirtied by decoding, but */ \
+ /* only ifndef NDEBUG */ \
+ INCR_NDECODE_DIRTIED(OH) \
} \
\
/* Set the message's "shared info", if it's shareable */ \
@@ -264,6 +272,9 @@ struct H5O_t {
* versions of the library)
*/
#endif /* H5O_ENABLE_BAD_MESG_COUNT */
+#ifndef NDEBUG
+ size_t ndecode_dirtied; /* Number of messages dirtied by decoding */
+#endif /* NDEBUG */
/* Object information (stored) */
hbool_t has_refcount_msg; /* Whether the object has a ref. count message */