mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-03-19 16:50:46 +08:00
[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)
This commit is contained in:
parent
2232cf942d
commit
c04a55d65e
@ -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 */
|
||||
|
@ -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 */
|
||||
|
115
src/H5Ocache.c
115
src/H5Ocache.c
@ -100,121 +100,6 @@ const H5AC_class_t H5AC_OHDR[1] = {{
|
||||
(H5AC_size_func_t)H5O_size,
|
||||
}};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* 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
|
||||
|
154
src/H5Omessage.c
154
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() */
|
||||
|
||||
|
22
src/H5Opkg.h
22
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);
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
61
src/H5SM.c
61
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;
|
||||
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")
|
||||
|
||||
raw_size = H5O_msg_raw_size(udata->file, udata->type_id, TRUE, _mesg);
|
||||
HDassert(raw_size);
|
||||
/* Get the message's encoded size */
|
||||
udata->buf_size = mesg->raw_size;
|
||||
HDassert(udata->buf_size);
|
||||
|
||||
if(NULL == (buf = HDmalloc(raw_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");
|
||||
|
@ -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 */
|
||||
|
||||
|
21
test/tsohm.c
21
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user