summaryrefslogtreecommitdiffstats
path: root/src/H5O.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5O.c')
-rw-r--r--src/H5O.c244
1 files changed, 162 insertions, 82 deletions
diff --git a/src/H5O.c b/src/H5O.c
index 64d0b9b..c294d01 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -84,6 +84,7 @@ static herr_t H5O_obj_type_real(H5O_t *oh, H5O_type_t *obj_type);
static herr_t H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id,
hid_t dxpl_id);
+static herr_t H5O_get_hdr_info_real(const H5O_t *oh, H5O_hdr_info_t *hdr);
/*********************/
@@ -127,18 +128,6 @@ const H5O_msg_class_t *const H5O_msg_class_g[] = {
H5O_MSG_UNKNOWN, /*0x0017 Placeholder for unknown message */
};
-/* Header object ID to class mapping */
-/*
- * Initialize the object class info table. Begin with the most general types
- * and end with the most specific. For instance, any object that has a
- * datatype message is a datatype but only some of them are datasets.
- */
-const H5O_obj_class_t *const H5O_obj_class_g[] = {
- H5O_OBJ_DATATYPE, /* Datatype object (H5O_TYPE_NAMED_DATATYPE - 2) */
- H5O_OBJ_DATASET, /* Dataset object (H5O_TYPE_DATASET - 1) */
- H5O_OBJ_GROUP, /* Group object (H5O_TYPE_GROUP - 0) */
-};
-
/* Declare a free list to manage the H5O_t struct */
H5FL_DEFINE(H5O_t);
@@ -167,6 +156,18 @@ H5FL_EXTERN(H5_obj_t);
/* Local Variables */
/*******************/
+/* Header object ID to class mapping */
+/*
+ * Initialize the object class info table. Begin with the most general types
+ * and end with the most specific. For instance, any object that has a
+ * datatype message is a datatype but only some of them are datasets.
+ */
+static const H5O_obj_class_t *const H5O_obj_class_g[] = {
+ H5O_OBJ_DATATYPE, /* Datatype object (H5O_TYPE_NAMED_DATATYPE - 2) */
+ H5O_OBJ_DATASET, /* Dataset object (H5O_TYPE_DATASET - 1) */
+ H5O_OBJ_GROUP, /* Group object (H5O_TYPE_GROUP - 0) */
+};
+
/*-------------------------------------------------------------------------
@@ -2296,6 +2297,131 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_get_hdr_info
+ *
+ * Purpose: Retrieve the object header information for an object
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * September 22 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_get_hdr_info(const H5O_loc_t *oloc, hid_t dxpl_id, H5O_hdr_info_t *hdr)
+{
+ H5O_t *oh = NULL; /* Object header */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_get_hdr_info, FAIL)
+
+ /* Check args */
+ HDassert(oloc);
+ HDassert(hdr);
+
+ /* Reset the object header info structure */
+ HDmemset(hdr, 0, sizeof(*hdr));
+
+ /* Get the object header */
+ 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")
+
+ /* Get the information for the object header */
+ if(H5O_get_hdr_info_real(oh, hdr) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object header info")
+
+done:
+ if(oh && H5AC_unprotect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_get_hdr_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_get_hdr_info_real
+ *
+ * Purpose: Internal routine to retrieve the object header information for an object
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * September 22 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_get_hdr_info_real(const H5O_t *oh, H5O_hdr_info_t *hdr)
+{
+ const H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
+ const H5O_chunk_t *curr_chunk; /* Pointer to current message being operated on */
+ unsigned u; /* Local index variable */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_get_hdr_info_real)
+
+ /* Check args */
+ HDassert(oh);
+ HDassert(hdr);
+
+ /* Set the version for the object header */
+ hdr->version = oh->version;
+
+ /* Set the number of messages & chunks */
+ hdr->nmesgs = oh->nmesgs;
+ hdr->nchunks = oh->nchunks;
+
+ /* Set the status flags */
+ hdr->flags = oh->flags;
+
+ /* Iterate over all the messages, accumulating message size & type information */
+ hdr->space.meta = H5O_SIZEOF_HDR(oh) + (H5O_SIZEOF_CHKHDR_OH(oh) * (oh->nchunks - 1));
+ hdr->space.mesg = 0;
+ hdr->space.free = 0;
+ hdr->mesg.present = 0;
+ hdr->mesg.shared = 0;
+ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
+ uint64_t type_flag; /* Flag for message type */
+
+ /* Accumulate space usage information, based on the type of message */
+ if(H5O_NULL_ID == curr_msg->type->id)
+ hdr->space.free += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size;
+ else if(H5O_CONT_ID == curr_msg->type->id)
+ hdr->space.meta += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size;
+ else {
+ hdr->space.meta += H5O_SIZEOF_MSGHDR_OH(oh);
+ hdr->space.mesg += curr_msg->raw_size;
+ } /* end else */
+
+ /* Set flag to indicate presence of message type */
+ type_flag = ((uint64_t)1) << curr_msg->type->id;
+ hdr->mesg.present |= type_flag;
+
+ /* Set flag if the message is shared in some way */
+ if(curr_msg->flags & H5O_MSG_FLAG_SHARED) \
+ hdr->mesg.shared |= type_flag;
+ } /* end for */
+
+ /* Iterate over all the chunks, adding any gaps to the free space */
+ hdr->space.total = 0;
+ for(u = 0, curr_chunk = &oh->chunk[0]; u < oh->nchunks; u++, curr_chunk++) {
+ /* Accumulate the size of the header on disk */
+ hdr->space.total += curr_chunk->size;
+
+ /* If the chunk has a gap, add it to the free space */
+ hdr->space.free += curr_chunk->gap;
+ } /* end for */
+
+ /* Sanity check that all the bytes are accounted for */
+ HDassert(hdr->space.total == (hdr->space.free + hdr->space.meta + hdr->space.mesg));
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_get_hdr_info_real() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_get_info
*
* Purpose: Retrieve the information for an object
@@ -2309,12 +2435,11 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_get_info(H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info_t *oinfo)
+H5O_get_info(const H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info,
+ H5O_info_t *oinfo)
{
+ const H5O_obj_class_t *obj_class; /* Class of object for header */
H5O_t *oh = NULL; /* Object header */
- H5O_chunk_t *curr_chunk; /* Pointer to current message being operated on */
- H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
- unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5O_get_info, FAIL)
@@ -2336,20 +2461,12 @@ H5O_get_info(H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info_t *o
/* Set the object's address */
oinfo->addr = oloc->addr;
- /* Retrieve the type of the object */
- if(H5O_obj_type_real(oh, &oinfo->type) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object type")
+ /* Get class for object */
+ if(NULL == (obj_class = H5O_obj_class_real(oh)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine object class")
- /* Retrieve btree and heap storage info, if requested */
- if(want_ih_info) {
- if(oinfo->type == H5O_TYPE_GROUP) {
- if(H5O_group_bh_info(oloc->file, dxpl_id, oh, &(oinfo->meta_size.obj)/*out*/) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve group btree & heap info")
- } else if(oinfo->type == H5O_TYPE_DATASET) {
- if(H5O_dset_bh_info(oloc->file, dxpl_id, oh, &(oinfo->meta_size.obj)/*out*/) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve chunked dataset btree info")
- }
- } /* end if */
+ /* Retrieve the type of the object */
+ oinfo->type = obj_class->type;
/* Set the object's reference count */
oinfo->rc = oh->nlink;
@@ -2395,66 +2512,29 @@ H5O_get_info(H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info_t *o
} /* end else */
} /* end else */
- /* Set the version for the object header */
- oinfo->hdr.version = oh->version;
-
- /* Set the number of messages & chunks */
- oinfo->hdr.nmesgs = oh->nmesgs;
- oinfo->hdr.nchunks = oh->nchunks;
-
- /* Set the status flags */
- oinfo->hdr.flags = oh->flags;
-
- /* Iterate over all the messages, accumulating message size & type information */
- oinfo->hdr.space.meta = H5O_SIZEOF_HDR(oh) + (H5O_SIZEOF_CHKHDR_OH(oh) * (oh->nchunks - 1));
- oinfo->hdr.space.mesg = 0;
- oinfo->hdr.space.free = 0;
- oinfo->hdr.mesg.present = 0;
- oinfo->hdr.mesg.shared = 0;
- for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
- uint64_t type_flag; /* Flag for message type */
-
- /* Accumulate space usage information, based on the type of message */
- if(H5O_NULL_ID == curr_msg->type->id)
- oinfo->hdr.space.free += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size;
- else if(H5O_CONT_ID == curr_msg->type->id)
- oinfo->hdr.space.meta += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size;
- else {
- oinfo->hdr.space.meta += H5O_SIZEOF_MSGHDR_OH(oh);
- oinfo->hdr.space.mesg += curr_msg->raw_size;
- } /* end else */
-
- /* Set flag to indicate presence of message type */
- type_flag = ((uint64_t)1) << curr_msg->type->id;
- oinfo->hdr.mesg.present |= type_flag;
-
- /* Set flag if the message is shared in some way */
- if(curr_msg->flags & H5O_MSG_FLAG_SHARED) \
- oinfo->hdr.mesg.shared |= type_flag;
- } /* end for */
+ /* Get the information for the object header */
+ if(H5O_get_hdr_info_real(oh, &oinfo->hdr) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object header info")
/* Retrieve # of attributes */
if(H5O_attr_count_real(oloc->file, dxpl_id, oh, &oinfo->num_attrs) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve attribute count")
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve attribute count")
/* Get B-tree & heap metadata storage size, if requested */
if(want_ih_info) {
- if((oinfo->num_attrs > 0) && (H5O_attr_bh_info(oloc->file, dxpl_id, oh, &oinfo->meta_size.attr/*out*/) < 0))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve attribute btree & heap info")
- } /* end if */
-
- /* Iterate over all the chunks, adding any gaps to the free space */
- oinfo->hdr.space.total = 0;
- for(u = 0, curr_chunk = &oh->chunk[0]; u < oh->nchunks; u++, curr_chunk++) {
- /* Accumulate the size of the header on disk */
- oinfo->hdr.space.total += curr_chunk->size;
-
- /* If the chunk has a gap, add it to the free space */
- oinfo->hdr.space.free += curr_chunk->gap;
- } /* end for */
+ /* Check for 'bh_info' callback for this type of object */
+ if(obj_class->bh_info) {
+ /* Call the object's class 'bh_info' routine */
+ if((obj_class->bh_info)(oloc->file, dxpl_id, oh, &(oinfo->meta_size.obj) /* out */) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object's btree & heap info")
+ } /* end if */
- /* Sanity check that all the bytes are accounted for */
- HDassert(oinfo->hdr.space.total == (oinfo->hdr.space.free + oinfo->hdr.space.meta + oinfo->hdr.space.mesg));
+ /* Get B-tree & heap info for any attributes */
+ if(oinfo->num_attrs > 0) {
+ if(H5O_attr_bh_info(oloc->file, dxpl_id, oh, &oinfo->meta_size.attr/*out*/) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve attribute btree & heap info")
+ } /* end if */
+ } /* end if */
done:
if(oh && H5AC_unprotect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0)