From c04a55d65e694b7c3e36813f48c24d43118f8e87 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 22 May 2007 21:16:41 -0500 Subject: [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) --- src/H5Gcompact.c | 10 +++- src/H5Gobj.c | 5 +- src/H5Ocache.c | 115 ----------------------------------------- src/H5Omessage.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/H5Opkg.h | 22 ++------ src/H5Oprivate.h | 24 +++++++-- src/H5Oshared.c | 4 +- src/H5SM.c | 65 ++++++++++++----------- src/H5SMbtree2.c | 47 +++++++++-------- test/tsohm.c | 21 ++------ 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