summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2007-05-23 02:16:41 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2007-05-23 02:16:41 (GMT)
commitc04a55d65e694b7c3e36813f48c24d43118f8e87 (patch)
tree545de5a9735eab1e44964c20c979565f0fa040d9
parent2232cf942df7b81ce44888a33e91fbe7077a1f6b (diff)
downloadhdf5-c04a55d65e694b7c3e36813f48c24d43118f8e87.zip
hdf5-c04a55d65e694b7c3e36813f48c24d43118f8e87.tar.gz
hdf5-c04a55d65e694b7c3e36813f48c24d43118f8e87.tar.bz2
[svn-r13796] Description:
Clean up ISOHM code further and get rid of several non-optimal ways of working with object headers. Tested on: FreeBSD/32 6.2 (duty) Mac OS X/32 10.4.9 (amazon)
-rw-r--r--src/H5Gcompact.c10
-rw-r--r--src/H5Gobj.c5
-rw-r--r--src/H5Ocache.c115
-rw-r--r--src/H5Omessage.c154
-rw-r--r--src/H5Opkg.h22
-rw-r--r--src/H5Oprivate.h24
-rw-r--r--src/H5Oshared.c4
-rwxr-xr-xsrc/H5SM.c65
-rwxr-xr-xsrc/H5SMbtree2.c47
-rw-r--r--test/tsohm.c21
10 files changed, 247 insertions, 220 deletions
diff --git a/src/H5Gcompact.c b/src/H5Gcompact.c
index 90ac2d0..68d5ac0 100644
--- a/src/H5Gcompact.c
+++ b/src/H5Gcompact.c
@@ -142,6 +142,7 @@ H5G_compact_build_table(const H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t
/* Allocate space for the table entries */
if(ltable->nlinks > 0) {
H5G_iter_bt_t udata; /* User data for iteration callback */
+ H5O_mesg_operator_t op; /* Message operator */
/* Allocate the link table */
if((ltable->lnks = H5MM_malloc(sizeof(H5O_link_t) * ltable->nlinks)) == NULL)
@@ -152,7 +153,9 @@ H5G_compact_build_table(const H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t
udata.curr_lnk = 0;
/* Iterate through the link messages, adding them to the table */
- if(H5O_msg_iterate(oloc, H5O_LINK_ID, H5G_compact_build_table_cb, &udata, dxpl_id) < 0)
+ op.op_type = H5O_MESG_OP_APP;
+ op.u.app_op = H5G_compact_build_table_cb;
+ if(H5O_msg_iterate(oloc, H5O_LINK_ID, &op, &udata, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over link messages")
/* Sort link table in correct iteration order */
@@ -565,6 +568,7 @@ H5G_compact_lookup(H5O_loc_t *oloc, const char *name, H5O_link_t *lnk,
hid_t dxpl_id)
{
H5G_iter_lkp_t udata; /* User data for iteration callback */
+ H5O_mesg_operator_t op; /* Message operator */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_compact_lookup, FAIL)
@@ -579,7 +583,9 @@ H5G_compact_lookup(H5O_loc_t *oloc, const char *name, H5O_link_t *lnk,
udata.found = FALSE;
/* Iterate through the link messages, adding them to the table */
- if(H5O_msg_iterate(oloc, H5O_LINK_ID, H5G_compact_lookup_cb, &udata, dxpl_id) < 0)
+ op.op_type = H5O_MESG_OP_APP;
+ op.u.app_op = H5G_compact_lookup_cb;
+ if(H5O_msg_iterate(oloc, H5O_LINK_ID, &op, &udata, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over link messages")
/* Check if we found the link we were looking for */
diff --git a/src/H5Gobj.c b/src/H5Gobj.c
index 9c8b8e6..a3166ba 100644
--- a/src/H5Gobj.c
+++ b/src/H5Gobj.c
@@ -500,6 +500,7 @@ H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk,
use_new_dense = FALSE;
else {
H5G_obj_oh_it_ud1_t udata; /* User data for iteration */
+ H5O_mesg_operator_t op; /* Message operator */
/* The group doesn't currently have "dense" storage for links */
if(H5G_dense_create(grp_oloc->file, dxpl_id, &linfo) < 0)
@@ -511,7 +512,9 @@ H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk,
udata.linfo = &linfo;
/* Iterate over the 'link' messages, inserting them into the dense link storage */
- if(H5O_msg_iterate(grp_oloc, H5O_LINK_ID, H5G_obj_compact_to_dense_cb, &udata, dxpl_id) < 0)
+ op.op_type = H5O_MESG_OP_APP;
+ op.u.app_op = H5G_obj_compact_to_dense_cb;
+ if(H5O_msg_iterate(grp_oloc, H5O_LINK_ID, &op, &udata, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over links")
/* Remove all the 'link' messages */
diff --git a/src/H5Ocache.c b/src/H5Ocache.c
index 2f89327..b5c8c7d 100644
--- a/src/H5Ocache.c
+++ b/src/H5Ocache.c
@@ -102,121 +102,6 @@ const H5AC_class_t H5AC_OHDR[1] = {{
/*-------------------------------------------------------------------------
- * Function: H5O_flush_msgs
- *
- * Purpose: Flushes messages for object header.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Nov 21 2005
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5O_flush_msgs(H5F_t *f, H5O_t *oh)
-{
- 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_flush_msgs, FAIL)
-
- /* check args */
- HDassert(f);
- HDassert(oh);
-
- /* Encode any dirty messages */
- for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
- if(curr_msg->dirty) {
- uint8_t *p; /* Temporary pointer to encode with */
- unsigned msg_id; /* ID for message */
-
- /* Point into message's chunk's image */
- p = curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh);
-
- /* Retrieve actual message ID, for unknown messages */
- if(curr_msg->type == H5O_MSG_UNKNOWN)
- msg_id = *(H5O_unknown_t *)(curr_msg->native);
- else
- msg_id = (uint8_t)curr_msg->type->id;
-
- /* Encode the message prefix */
- if(oh->version == H5O_VERSION_1)
- UINT16ENCODE(p, msg_id)
- else
- *p++ = (uint8_t)msg_id;
- HDassert(curr_msg->raw_size < H5O_MESG_MAX_SIZE);
- UINT16ENCODE(p, curr_msg->raw_size);
- *p++ = curr_msg->flags;
-
- /* Only encode reserved bytes for version 1 of format */
- if(oh->version == H5O_VERSION_1) {
- *p++ = 0; /*reserved*/
- *p++ = 0; /*reserved*/
- *p++ = 0; /*reserved*/
- } /* end for */
- /* Only encode creation index for version 2+ of format */
- else {
- /* Only encode creation index if they are being tracked */
- if(oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED)
- UINT16ENCODE(p, curr_msg->crt_idx);
- } /* end else */
- HDassert(p == curr_msg->raw);
-
-#ifndef NDEBUG
- /* Make certain that null messages aren't in chunks w/gaps */
- if(H5O_NULL_ID == msg_id)
- HDassert(oh->chunk[curr_msg->chunkno].gap == 0);
-
- /* Unknown messages should always have a native pointer */
- if(curr_msg->type == H5O_MSG_UNKNOWN)
- HDassert(curr_msg->native);
-#endif /* NDEBUG */
-
- /* Encode the message itself, if it's not an "unknown" message */
- if(curr_msg->native && curr_msg->type != H5O_MSG_UNKNOWN) {
- /*
- * Encode the message. If the message is shared then we
- * encode a Shared Object message instead of the object
- * which is being shared.
- */
- HDassert(curr_msg->raw >= oh->chunk[curr_msg->chunkno].image);
- HDassert(curr_msg->raw_size == H5O_ALIGN_OH(oh, curr_msg->raw_size));
- HDassert(curr_msg->raw + curr_msg->raw_size <=
- oh->chunk[curr_msg->chunkno].image + (oh->chunk[curr_msg->chunkno].size - H5O_SIZEOF_CHKSUM_OH(oh)));
-#ifndef NDEBUG
-/* Sanity check that the message won't overwrite past it's allocated space */
-{
- size_t msg_size;
-
- msg_size = curr_msg->type->raw_size(f, FALSE, curr_msg->native);
- msg_size = H5O_ALIGN_OH(oh, msg_size);
- HDassert(msg_size <= curr_msg->raw_size);
-}
-#endif /* NDEBUG */
- HDassert(curr_msg->type->encode);
- if((curr_msg->type->encode)(f, FALSE, curr_msg->raw, curr_msg->native) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message")
- } /* end if */
-
- /* Pass "modifiedness" from message to chunk */
- curr_msg->dirty = FALSE;
- oh->chunk[curr_msg->chunkno].dirty = TRUE;
- } /* end if */
- } /* end for */
-
- /* Sanity check for the correct # of messages in object header */
- if(oh->nmesgs != u)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "corrupt object header - too few messages")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_flush_msgs() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5O_load
*
* Purpose: Loads an object header from disk.
diff --git a/src/H5Omessage.c b/src/H5Omessage.c
index 7c5a38d..3538db1 100644
--- a/src/H5Omessage.c
+++ b/src/H5Omessage.c
@@ -1167,12 +1167,11 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_msg_iterate(const H5O_loc_t *loc, unsigned type_id, H5O_operator_t app_op,
- void *op_data, hid_t dxpl_id)
+H5O_msg_iterate(const H5O_loc_t *loc, unsigned type_id,
+ const H5O_mesg_operator_t *op, void *op_data, hid_t dxpl_id)
{
H5O_t *oh = NULL; /* Pointer to actual object header */
const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
- H5O_mesg_operator_t op; /* Wrapper for operator */
herr_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_msg_iterate, FAIL)
@@ -1184,15 +1183,14 @@ H5O_msg_iterate(const H5O_loc_t *loc, unsigned type_id, H5O_operator_t app_op,
HDassert(type_id < NELMTS(H5O_msg_class_g));
type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */
HDassert(type);
+ 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, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Call the "real" iterate routine */
- op.op_type = H5O_MESG_OP_APP;
- op.u.app_op = app_op;
- if((ret_value = H5O_msg_iterate_real(loc->file, oh, type, &op, op_data, dxpl_id)) < 0)
+ if((ret_value = H5O_msg_iterate_real(loc->file, oh, type, op, op_data, dxpl_id)) < 0)
HERROR(H5E_OHDR, H5E_BADITER, "unable to iterate over object header messages");
done:
@@ -2044,3 +2042,147 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_delete_mesg() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_msg_flush
+ *
+ * Purpose: Flushes a message for an object header.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * May 14 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_msg_flush(H5F_t *f, H5O_t *oh, H5O_mesg_t *mesg)
+{
+ uint8_t *p; /* Temporary pointer to encode with */
+ unsigned msg_id; /* ID for message */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_msg_flush, FAIL)
+
+ /* check args */
+ HDassert(f);
+ HDassert(oh);
+
+ /* Point into message's chunk's image */
+ p = mesg->raw - H5O_SIZEOF_MSGHDR_OH(oh);
+
+ /* Retrieve actual message ID, for unknown messages */
+ if(mesg->type == H5O_MSG_UNKNOWN)
+ msg_id = *(H5O_unknown_t *)(mesg->native);
+ else
+ msg_id = (uint8_t)mesg->type->id;
+
+ /* Encode the message prefix */
+ if(oh->version == H5O_VERSION_1)
+ UINT16ENCODE(p, msg_id)
+ else
+ *p++ = (uint8_t)msg_id;
+ HDassert(mesg->raw_size < H5O_MESG_MAX_SIZE);
+ UINT16ENCODE(p, mesg->raw_size);
+ *p++ = mesg->flags;
+
+ /* Only encode reserved bytes for version 1 of format */
+ if(oh->version == H5O_VERSION_1) {
+ *p++ = 0; /*reserved*/
+ *p++ = 0; /*reserved*/
+ *p++ = 0; /*reserved*/
+ } /* end for */
+ /* Only encode creation index for version 2+ of format */
+ else {
+ /* Only encode creation index if they are being tracked */
+ if(oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED)
+ UINT16ENCODE(p, mesg->crt_idx);
+ } /* end else */
+ HDassert(p == mesg->raw);
+
+#ifndef NDEBUG
+ /* Make certain that null messages aren't in chunks w/gaps */
+ if(H5O_NULL_ID == msg_id)
+ HDassert(oh->chunk[mesg->chunkno].gap == 0);
+
+ /* Unknown messages should always have a native pointer */
+ if(mesg->type == H5O_MSG_UNKNOWN)
+ HDassert(mesg->native);
+#endif /* NDEBUG */
+
+ /* Encode the message itself, if it's not an "unknown" message */
+ if(mesg->native && mesg->type != H5O_MSG_UNKNOWN) {
+ /*
+ * Encode the message. If the message is shared then we
+ * encode a Shared Object message instead of the object
+ * which is being shared.
+ */
+ HDassert(mesg->raw >= oh->chunk[mesg->chunkno].image);
+ HDassert(mesg->raw_size == H5O_ALIGN_OH(oh, mesg->raw_size));
+ HDassert(mesg->raw + mesg->raw_size <=
+ oh->chunk[mesg->chunkno].image + (oh->chunk[mesg->chunkno].size - H5O_SIZEOF_CHKSUM_OH(oh)));
+#ifndef NDEBUG
+/* Sanity check that the message won't overwrite past it's allocated space */
+{
+ size_t msg_size;
+
+ msg_size = mesg->type->raw_size(f, FALSE, mesg->native);
+ msg_size = H5O_ALIGN_OH(oh, msg_size);
+ HDassert(msg_size <= mesg->raw_size);
+}
+#endif /* NDEBUG */
+ HDassert(mesg->type->encode);
+ if((mesg->type->encode)(f, FALSE, mesg->raw, mesg->native) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message")
+ } /* end if */
+
+ /* Pass "modifiedness" from message to chunk */
+ mesg->dirty = FALSE;
+ oh->chunk[mesg->chunkno].dirty = TRUE;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_msg_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_flush_msgs
+ *
+ * Purpose: Flushes messages for object header.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Nov 21 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_flush_msgs(H5F_t *f, H5O_t *oh)
+{
+ 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_flush_msgs, FAIL)
+
+ /* check args */
+ HDassert(f);
+ HDassert(oh);
+
+ /* Encode any dirty messages */
+ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++)
+ if(curr_msg->dirty)
+ if(H5O_msg_flush(f, oh, curr_msg) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message")
+
+ /* Sanity check for the correct # of messages in object header */
+ if(oh->nmesgs != u)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "corrupt object header - too few messages")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_flush_msgs() */
+
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index 411297e..83dc647 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -227,7 +227,7 @@ struct H5O_msg_class_t {
herr_t (*debug)(H5F_t*, hid_t, const void*, FILE*, int, int);
};
-typedef struct H5O_mesg_t {
+struct H5O_mesg_t {
const H5O_msg_class_t *type; /*type of message */
hbool_t dirty; /*raw out of date wrt native */
uint8_t flags; /*message flags */
@@ -236,7 +236,7 @@ typedef struct H5O_mesg_t {
void *native; /*native format message */
uint8_t *raw; /*ptr to raw data */
size_t raw_size; /*size with alignment */
-} H5O_mesg_t;
+};
typedef struct H5O_chunk_t {
hbool_t dirty; /*dirty flag */
@@ -311,23 +311,6 @@ typedef struct H5O_addr_map_t {
} H5O_addr_map_t;
-/* Typedef for "internal library" iteration operations */
-typedef herr_t (*H5O_lib_operator_t)(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
- unsigned sequence, hbool_t *oh_modified/*out*/, void *operator_data/*in,out*/);
-
-/* Some syntactic sugar to make the compiler happy with two different kinds of iterator callbacks */
-typedef struct {
- enum {
- H5O_MESG_OP_APP, /* Application callback */
- H5O_MESG_OP_LIB /* Library internal callback */
- } op_type;
- union {
- H5O_operator_t app_op; /* Application callback for each message */
- H5O_lib_operator_t lib_op; /* Library internal callback for each message */
- } u;
-} H5O_mesg_operator_t;
-
-
/* H5O inherits cache-like properties from H5AC */
H5_DLLVAR const H5AC_class_t H5AC_OHDR[1];
@@ -467,6 +450,7 @@ H5_DLLVAR const H5O_obj_class_t H5O_OBJ_DATATYPE[1];
/* Package-local function prototypes */
+H5_DLL herr_t H5O_msg_flush(H5F_t *f, H5O_t *oh, H5O_mesg_t *mesg);
H5_DLL herr_t H5O_flush_msgs(H5F_t *f, H5O_t *oh);
H5_DLL hid_t H5O_open_by_loc(const H5G_loc_t *obj_loc, hid_t dxpl_id);
H5_DLL herr_t H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_mesg_t *mesg);
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 543f929..c4d2a1f 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -44,6 +44,7 @@
/* Forward references of package typedefs */
typedef struct H5O_msg_class_t H5O_msg_class_t;
+typedef struct H5O_mesg_t H5O_mesg_t;
typedef struct H5O_t H5O_t;
/* Values used to create the shared message & attribute heaps */
@@ -482,10 +483,27 @@ typedef uint32_t H5O_refcount_t; /* Contains # of links to object, if >1
typedef unsigned H5O_unknown_t; /* Original message type ID */
-/* Typedef for iteration operations */
+/* Typedef for "application" iteration operations */
typedef herr_t (*H5O_operator_t)(const void *mesg/*in*/, unsigned idx,
void *operator_data/*in,out*/);
+/* Typedef for "internal library" iteration operations */
+typedef herr_t (*H5O_lib_operator_t)(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/,
+ unsigned sequence, hbool_t *oh_modified/*out*/, void *operator_data/*in,out*/);
+
+/* Some syntactic sugar to make the compiler happy with two different kinds of iterator callbacks */
+typedef struct {
+ enum {
+ H5O_MESG_OP_APP, /* Application callback */
+ H5O_MESG_OP_LIB /* Library internal callback */
+ } op_type;
+ union {
+ H5O_operator_t app_op; /* Application callback for each message */
+ H5O_lib_operator_t lib_op; /* Library internal callback for each message */
+ } u;
+} H5O_mesg_operator_t;
+
+
/* Typedef for abstract object creation */
typedef struct {
H5O_type_t obj_type; /* Type of object to create */
@@ -538,8 +556,8 @@ H5_DLL herr_t H5O_msg_remove(const H5O_loc_t *loc, unsigned type_id, int sequenc
hbool_t adj_link, hid_t dxpl_id);
H5_DLL herr_t H5O_msg_remove_op(const H5O_loc_t *loc, unsigned type_id, int sequence,
H5O_operator_t op, void *op_data, hbool_t adj_link, hid_t dxpl_id);
-H5_DLL herr_t H5O_msg_iterate(const H5O_loc_t *loc, unsigned type_id, H5O_operator_t op,
- void *op_data, hid_t dxpl_id);
+H5_DLL herr_t H5O_msg_iterate(const H5O_loc_t *loc, unsigned type_id,
+ const H5O_mesg_operator_t *op, void *op_data, hid_t dxpl_id);
H5_DLL size_t H5O_msg_raw_size(const H5F_t *f, unsigned type_id,
hbool_t disable_shared, const void *mesg);
H5_DLL size_t H5O_msg_size_f(const H5F_t *f, hid_t ocpl_id, unsigned type_id,
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index 089c6f4..44b0992 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -565,7 +565,9 @@ H5O_shared_copy_file(H5F_t *file_src, H5F_t *file_dst,
} /* end if */
else {
/* Try to share new message in the destination file. */
- /* JAMES: message is always shared in heap in dest. file */
+ /* Message is always shared in heap in dest. file because the dest.
+ * object header doesn't quite exist yet - JML
+ */
if(H5SM_try_share(file_dst, dxpl_id, NULL, mesg_type->id, _native_dst, NULL) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to determine if message should be shared")
} /* end else */
diff --git a/src/H5SM.c b/src/H5SM.c
index a5b527a..c687681 100755
--- a/src/H5SM.c
+++ b/src/H5SM.c
@@ -46,10 +46,9 @@
/* Udata struct for calls to H5SM_read_iter_op */
typedef struct H5SM_read_udata_t {
H5F_t *file; /* File in which sharing is happening (in) */
- unsigned type_id; /* Type of the message (in) */
- size_t buf_size; /* Size of the encoded message (out) */
- void * encoding_buf; /* The encoded message (out) */
- H5O_msg_crt_idx_t idx; /* Creation index of this message */
+ H5O_msg_crt_idx_t idx; /* Creation index of this message (in) */
+ size_t buf_size; /* Size of the encoded message (out) */
+ void *encoding_buf; /* The encoded message (out) */
} H5SM_read_udata_t;
@@ -74,7 +73,8 @@ static herr_t H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
H5SM_index_header_t *header, const H5O_shared_t * mesg,
unsigned *cache_flags, void ** /*out*/ encoded_mesg);
static herr_t H5SM_type_to_flag(unsigned type_id, unsigned *type_flag);
-static herr_t H5SM_read_iter_op(const void *_mesg, unsigned idx, void *_udata);
+static herr_t H5SM_read_iter_op(H5O_t *oh, H5O_mesg_t *mesg, unsigned sequence,
+ hbool_t *oh_modified, void *_udata);
static herr_t H5SM_read_mesg(H5F_t *f, const H5SM_sohm_t *mesg, H5HF_t *fheap,
H5O_t * open_oh, hid_t dxpl_id, size_t *encoding_size /*out*/,
void ** encoded_mesg /*out*/);
@@ -1403,7 +1403,7 @@ H5SM_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_shared_t *sh_mesg)
} /* end if */
done:
- /* Release the master SOHM table on error */
+ /* Release the master SOHM table (should only happen on error) */
if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, cache_flags) < 0)
HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table")
@@ -1643,13 +1643,12 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
/* Set up user data for message iteration */
udata.file = f;
- udata.type_id = type_id;
udata.idx = mesg->u.loc.index;
udata.encoding_buf = NULL;
/* Use the "real" iterate routine so it doesn't try to protect the OH */
- op.op_type = H5O_MESG_OP_APP;
- op.u.app_op = H5SM_read_iter_op;
+ op.op_type = H5O_MESG_OP_LIB;
+ op.u.lib_op = H5SM_read_iter_op;
if((ret_value = H5O_msg_iterate_real(f, oh, type, &op, &udata, dxpl_id)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "unable to iterate over object header messages")
@@ -2180,10 +2179,10 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5SM_read_iter_op(const void *_mesg, unsigned idx, void *_udata)
+H5SM_read_iter_op(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned sequence,
+ hbool_t UNUSED *oh_modified, void *_udata/*in,out*/)
{
H5SM_read_udata_t *udata = (H5SM_read_udata_t *) _udata;
- unsigned char *buf = NULL;
herr_t ret_value = H5_ITER_CONT;
FUNC_ENTER_NOAPI_NOINIT(H5SM_read_iter_op)
@@ -2191,34 +2190,34 @@ H5SM_read_iter_op(const void *_mesg, unsigned idx, void *_udata)
/*
* Check arguments.
*/
- HDassert(_mesg);
+ HDassert(oh);
+ HDassert(mesg);
HDassert(udata);
HDassert(NULL == udata->encoding_buf);
/* Check the creation index for this message */
- if(idx == udata->idx) {
- size_t raw_size;
-
- raw_size = H5O_msg_raw_size(udata->file, udata->type_id, TRUE, _mesg);
- HDassert(raw_size);
-
- if(NULL == (buf = HDmalloc(raw_size)))
+ if(sequence == udata->idx) {
+ /* Check if the message is dirty & flush it to the object header if so */
+ if(mesg->dirty)
+ if(H5O_msg_flush(udata->file, oh, mesg) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, H5_ITER_ERROR, "unable to encode object header message")
+
+ /* Get the message's encoded size */
+ udata->buf_size = mesg->raw_size;
+ HDassert(udata->buf_size);
+
+ /* Allocate buffer to return the message in */
+ if(NULL == (udata->encoding_buf = H5MM_malloc(udata->buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed")
- /* JAMES: is there a faster way to get the encoded value here? Do we already have a raw value? */
- if(H5O_msg_encode(udata->file, udata->type_id, TRUE, buf, _mesg) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, H5_ITER_ERROR, "can't encode message from object header")
-
- udata->encoding_buf = buf;
- udata->buf_size = raw_size;
+ /* Copy the encoded message into the buffer to return */
+ HDmemcpy(udata->encoding_buf, mesg->raw, udata->buf_size);
+ /* Found the message we were looking for */
ret_value = H5_ITER_STOP;
} /* end if */
done:
- if(ret_value < 0 && buf)
- HDfree(buf);
-
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_read_iter_op() */
@@ -2285,13 +2284,13 @@ H5SM_read_mesg(H5F_t *f, const H5SM_sohm_t *mesg, H5HF_t *fheap,
/* Set up user data for message iteration */
udata.file = f;
- udata.type_id = mesg->msg_type_id;
+ udata.idx = mesg->u.mesg_loc.index;
udata.encoding_buf = NULL;
udata.idx = 0;
/* Use the "real" iterate routine so it doesn't try to protect the OH */
- op.op_type = H5O_MESG_OP_APP;
- op.u.app_op = H5SM_read_iter_op;
+ op.op_type = H5O_MESG_OP_LIB;
+ op.u.lib_op = H5SM_read_iter_op;
if((ret_value = H5O_msg_iterate_real(f, oh, type, &op, &udata, dxpl_id)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "unable to iterate over object header messages")
@@ -2474,8 +2473,8 @@ H5SM_list_debug(H5F_t *f, hid_t dxpl_id, haddr_t list_addr,
HDfprintf(stream, "%*sShared Message List Index...\n", indent, "");
for(x = 0; x < num_messages; ++x) {
HDfprintf(stream, "%*sShared Object Header Message %d...\n", indent, "", x);
- HDfprintf(stream, "%*s%-*s %Zu\n", indent + 3, "", fwidth, /* JAMES: better flag for this? */
- "Hash value:", list->messages[x].hash);
+ HDfprintf(stream, "%*s%-*s %08lu\n", indent + 3, "", fwidth,
+ "Hash value:", (unsigned long)list->messages[x].hash);
if(list->messages[x].location == H5SM_IN_HEAP) {
HDfprintf(stream, "%*s%-*s %s\n", indent + 3, "", fwidth,
"Location:", "in heap");
diff --git a/src/H5SMbtree2.c b/src/H5SMbtree2.c
index 3cd2f23..43ea1fd 100755
--- a/src/H5SMbtree2.c
+++ b/src/H5SMbtree2.c
@@ -17,6 +17,7 @@
/* Module Setup */
/****************/
+#define H5O_PACKAGE /*suppress error about including H5Opkg */
#define H5SM_PACKAGE /*suppress error about including H5SMpkg */
/***********/
@@ -24,6 +25,7 @@
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
+#include "H5Opkg.h" /* Object Headers */
#include "H5SMpkg.h" /* Shared object header messages */
@@ -40,7 +42,6 @@
typedef struct H5SM_compare_udata_t {
const H5SM_mesg_key_t *key; /* Key; compare this against stored message */
H5O_msg_crt_idx_t idx; /* Index of the message in the OH, if applicable */
- unsigned type_id; /* Type ID of the type being compared */
herr_t ret; /* Return value; set this to result of memcmp */
} H5SM_compare_udata_t;
@@ -131,10 +132,10 @@ H5SM_btree_compare_cb(const void *obj, size_t obj_len, void *_udata)
*-------------------------------------------------------------------------
*/
static herr_t
-H5SM_compare_iter_op(const void *_mesg, unsigned idx, void *_udata)
+H5SM_compare_iter_op(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned sequence,
+ hbool_t UNUSED *oh_modified, void *_udata/*in,out*/)
{
H5SM_compare_udata_t *udata = (H5SM_compare_udata_t *) _udata;
- unsigned char *buf = NULL;
herr_t ret_value = H5_ITER_CONT;
FUNC_ENTER_NOAPI_NOINIT(H5SM_compare_iter_op)
@@ -142,30 +143,29 @@ H5SM_compare_iter_op(const void *_mesg, unsigned idx, void *_udata)
/*
* Check arguments.
*/
- HDassert(_mesg);
+ HDassert(oh);
+ HDassert(mesg);
HDassert(udata && udata->key);
/* Check the creation index for this message */
- if(idx == udata->idx) {
- size_t raw_size;
+ if(sequence == udata->idx) {
+ size_t aligned_encoded_size = H5O_ALIGN_OH(oh, udata->key->encoding_size);
- /* Retrieve the length of the unshared version of the message */
- raw_size = H5O_msg_raw_size(udata->key->file, udata->type_id, TRUE, _mesg);
- HDassert(raw_size > 0);
+ /* Sanity check the message's length */
+ HDassert(mesg->raw_size > 0);
- if(udata->key->encoding_size > raw_size)
+ if(aligned_encoded_size > mesg->raw_size)
udata->ret = 1;
- else if(udata->key->encoding_size < raw_size)
+ else if(aligned_encoded_size < mesg->raw_size)
udata->ret = -1;
else {
- if(NULL == (buf = HDmalloc(raw_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed")
+ /* Check if the message is dirty & flush it to the object header if so */
+ if(mesg->dirty)
+ if(H5O_msg_flush(udata->key->file, oh, mesg) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, H5_ITER_ERROR, "unable to encode object header message")
- /* JAMES: is there a faster way to get the encoded value here? Do we already have a raw value? */
- if(H5O_msg_encode(udata->key->file, udata->type_id, TRUE, buf, _mesg) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, H5_ITER_ERROR, "unable to encode message from object header")
-
- udata->ret = HDmemcmp(udata->key->encoding, buf, raw_size);
+ HDassert(udata->key->encoding_size <= mesg->raw_size);
+ udata->ret = HDmemcmp(udata->key->encoding, mesg->raw, udata->key->encoding_size);
} /* end else */
/* Indicate that we found the message we were looking for */
@@ -173,9 +173,6 @@ H5SM_compare_iter_op(const void *_mesg, unsigned idx, void *_udata)
} /* end if */
done:
- if(buf)
- HDfree(buf);
-
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_compare_iter_op() */
@@ -251,6 +248,7 @@ H5SM_message_compare(const void *rec1, const void *rec2)
} /* end if */
else {
H5O_loc_t oloc; /* Object owning the message */
+ H5O_mesg_operator_t op; /* Message operator */
/* Sanity checks */
HDassert(key->file);
@@ -266,10 +264,11 @@ H5SM_message_compare(const void *rec1, const void *rec2)
/* Finish setting up user data for iterator */
udata.idx = mesg->u.mesg_loc.index;
- udata.type_id = mesg->msg_type_id;
- /* JAMES: is this okay? */
- status = H5O_msg_iterate(&oloc, mesg->msg_type_id, H5SM_compare_iter_op, &udata, key->dxpl_id);
+ /* Locate the right message and compare with it */
+ op.op_type = H5O_MESG_OP_LIB;
+ op.u.lib_op = H5SM_compare_iter_op;
+ status = H5O_msg_iterate(&oloc, mesg->msg_type_id, &op, &udata, key->dxpl_id);
HDassert(status >= 0);
} /* end else */
diff --git a/test/tsohm.c b/test/tsohm.c
index cae7a8f..d0459a80 100644
--- a/test/tsohm.c
+++ b/test/tsohm.c
@@ -566,8 +566,6 @@ size1_helper(hid_t file, const char* filename, hid_t fapl_id, int test_file_clos
dtype1_struct wdata = {11, "string", 22, 33, 44, 55, 66, 77, 88, 0.0};
dtype1_struct rdata;
hid_t dtype1_id = -1;
- hid_t dup_tid = -1;
- hid_t type_id = -1;
hid_t space_id = -1;
hid_t dset_id = -1;
hsize_t dim1[1];
@@ -642,13 +640,11 @@ size1_helper(hid_t file, const char* filename, hid_t fapl_id, int test_file_clos
if((dtype1_id = H5Dget_type(dset_id))<0) TEST_ERROR
- if((dup_tid = H5Tcopy(dtype1_id))<0) TEST_ERROR
-
rdata.i1 = rdata.i2 = 0;
strcpy(rdata.str, "\0");
/* Read data back again */
- if(H5Dread(dset_id,dup_tid,H5S_ALL,H5S_ALL,H5P_DEFAULT,&rdata)<0) {
+ if(H5Dread(dset_id,dtype1_id,H5S_ALL,H5S_ALL,H5P_DEFAULT,&rdata)<0) {
H5_FAILED(); AT();
printf("Can't read data\n");
goto error;
@@ -661,15 +657,12 @@ size1_helper(hid_t file, const char* filename, hid_t fapl_id, int test_file_clos
} /* end if */
if(H5Dclose(dset_id)<0) TEST_ERROR
- if(H5Tclose(dup_tid)<0) TEST_ERROR
/* Create several copies of the dataset (this increases the amount of space saved by sharing the datatype message) */
for(x=0; x<SOHM_HELPER_NUM_EX_DSETS; x++) {
- if((type_id = H5Tcopy(dtype1_id)) < 0) TEST_ERROR
- if((dset_id = H5Dcreate(file,EXTRA_DSETNAME[x],type_id,space_id,H5P_DEFAULT)) < 0) TEST_ERROR
-
- if(H5Tclose(type_id)<0) TEST_ERROR
+ if((dset_id = H5Dcreate(file,EXTRA_DSETNAME[x],dtype1_id,space_id,H5P_DEFAULT)) < 0) TEST_ERROR
if(H5Dclose(dset_id)<0) TEST_ERROR
+
/* Close and re-open the file if requested*/
if(test_file_closing) {
if((file = close_reopen_file(file, filename, fapl_id)) < 0) TEST_ERROR
@@ -684,12 +677,10 @@ size1_helper(hid_t file, const char* filename, hid_t fapl_id, int test_file_clos
if((dtype1_id = H5Dget_type(dset_id))<0) TEST_ERROR
- if((dup_tid = H5Tcopy(dtype1_id))<0) TEST_ERROR
-
rdata.i1 = rdata.i2 = 0;
/* Read data back again */
- if(H5Dread(dset_id,dup_tid,H5S_ALL,H5S_ALL,H5P_DEFAULT,&rdata)<0) {
+ if(H5Dread(dset_id,dtype1_id,H5S_ALL,H5S_ALL,H5P_DEFAULT,&rdata)<0) {
H5_FAILED(); AT();
printf("Can't read data\n");
goto error;
@@ -703,14 +694,12 @@ size1_helper(hid_t file, const char* filename, hid_t fapl_id, int test_file_clos
if(H5Dclose(dset_id)<0) TEST_ERROR
if(H5Tclose(dtype1_id)<0) TEST_ERROR
- if(H5Tclose(dup_tid)<0) TEST_ERROR
return file;
error:
H5E_BEGIN_TRY {
+ H5Sclose(space_id);
H5Tclose(dtype1_id);
- H5Tclose(type_id);
- H5Tclose(dup_tid);
H5Dclose(dset_id);
H5Fclose(file);
} H5E_END_TRY