mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-01-12 15:04:59 +08:00
9c9ee2008c
Refactor function name macros and simplify the FUNC_ENTER macros, to clear away the cruft and prepare for further cleanups. Tested on: Mac OSX/64 10.7.3 (amazon) w/debug, production & parallel
359 lines
12 KiB
C
359 lines
12 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||
* Copyright by The HDF Group. *
|
||
* Copyright by the Board of Trustees of the University of Illinois. *
|
||
* All rights reserved. *
|
||
* *
|
||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||
* terms governing use, modification, and redistribution, is contained in *
|
||
* the files COPYING and Copyright.html. COPYING can be found at the root *
|
||
* of the source code distribution tree; Copyright.html can be found at the *
|
||
* root level of an installed copy of the electronic HDF5 document set and *
|
||
* is linked from the top-level documents page. It can also be found at *
|
||
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
|
||
* access to either file, you may request a copy from help@hdfgroup.org. *
|
||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||
|
||
/****************/
|
||
/* Module Setup */
|
||
/****************/
|
||
|
||
#define H5O_PACKAGE /*suppress error about including H5Opkg */
|
||
#define H5SM_PACKAGE /*suppress error about including H5SMpkg */
|
||
|
||
|
||
/***********/
|
||
/* Headers */
|
||
/***********/
|
||
#include "H5private.h" /* Generic Functions */
|
||
#include "H5Eprivate.h" /* Error handling */
|
||
#include "H5Opkg.h" /* Object Headers */
|
||
#include "H5SMpkg.h" /* Shared object header messages */
|
||
|
||
|
||
/****************/
|
||
/* Local Macros */
|
||
/****************/
|
||
|
||
|
||
/******************/
|
||
/* Local Typedefs */
|
||
/******************/
|
||
|
||
/* Udata struct for calls to H5SM_compare_cb and H5SM_compare_iter_op*/
|
||
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 */
|
||
herr_t ret; /* Return value; set this to result of memcmp */
|
||
} H5SM_compare_udata_t;
|
||
|
||
|
||
/********************/
|
||
/* Local Prototypes */
|
||
/********************/
|
||
static herr_t H5SM_compare_cb(const void *obj, size_t obj_len, void *udata);
|
||
static herr_t H5SM_compare_iter_op(H5O_t *oh, H5O_mesg_t *mesg, unsigned sequence,
|
||
unsigned *oh_modified, void *udata);
|
||
|
||
|
||
/*********************/
|
||
/* Package Variables */
|
||
/*********************/
|
||
|
||
|
||
/*****************************/
|
||
/* Library Private Variables */
|
||
/*****************************/
|
||
|
||
|
||
/*******************/
|
||
/* Local Variables */
|
||
/*******************/
|
||
|
||
|
||
|
||
/*-------------------------------------------------------------------------
|
||
* Function: H5SM_compare_cb
|
||
*
|
||
* Purpose: Callback for H5HF_op, used in H5SM_message_compare below.
|
||
* Determines whether the search key passed in in _UDATA is
|
||
* equal to OBJ or not.
|
||
*
|
||
* Passes back the result in _UDATA->RET
|
||
*
|
||
* Return: Negative on error, non-negative on success
|
||
*
|
||
* Programmer: James Laird
|
||
* Monday, January 8, 2007
|
||
*
|
||
*-------------------------------------------------------------------------
|
||
*/
|
||
static herr_t
|
||
H5SM_compare_cb(const void *obj, size_t obj_len, void *_udata)
|
||
{
|
||
H5SM_compare_udata_t *udata = (H5SM_compare_udata_t *)_udata;
|
||
|
||
FUNC_ENTER_NOAPI_NOINIT_NOERR
|
||
|
||
/* If the encoding sizes are different, it's not the same object */
|
||
if(udata->key->encoding_size > obj_len)
|
||
udata->ret = 1;
|
||
else if(udata->key->encoding_size < obj_len)
|
||
udata->ret = -1;
|
||
else
|
||
/* Sizes are the same. Return result of memcmp */
|
||
udata->ret = HDmemcmp(udata->key->encoding, obj, obj_len);
|
||
|
||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||
} /* end H5SM_compare_cb() */
|
||
|
||
|
||
/*-------------------------------------------------------------------------
|
||
* Function: H5SM_compare_iter_op
|
||
*
|
||
* Purpose: OH iteration callback to compare a key against a message in
|
||
* an OH
|
||
*
|
||
* Return: 0 if this is not the message we're searching for
|
||
* 1 if this is the message we're searching for (with memcmp
|
||
* result returned in udata)
|
||
* negative on error
|
||
*
|
||
* Programmer: James Laird
|
||
* Wednesday, February 7, 2007
|
||
*
|
||
*-------------------------------------------------------------------------
|
||
*/
|
||
static herr_t
|
||
H5SM_compare_iter_op(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned sequence,
|
||
unsigned UNUSED *oh_modified, void *_udata/*in,out*/)
|
||
{
|
||
H5SM_compare_udata_t *udata = (H5SM_compare_udata_t *) _udata;
|
||
herr_t ret_value = H5_ITER_CONT;
|
||
|
||
FUNC_ENTER_NOAPI_NOINIT
|
||
|
||
/*
|
||
* Check arguments.
|
||
*/
|
||
HDassert(oh);
|
||
HDassert(mesg);
|
||
HDassert(udata && udata->key);
|
||
|
||
/* Check the creation index for this message */
|
||
if(sequence == udata->idx) {
|
||
size_t aligned_encoded_size = H5O_ALIGN_OH(oh, udata->key->encoding_size);
|
||
|
||
/* Sanity check the message's length */
|
||
HDassert(mesg->raw_size > 0);
|
||
|
||
if(aligned_encoded_size > mesg->raw_size)
|
||
udata->ret = 1;
|
||
else if(aligned_encoded_size < mesg->raw_size)
|
||
udata->ret = -1;
|
||
else {
|
||
/* 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_SOHM, H5E_CANTENCODE, H5_ITER_ERROR, "unable to encode object header message")
|
||
|
||
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 */
|
||
ret_value = H5_ITER_STOP;
|
||
} /* end if */
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value)
|
||
} /* end H5SM_compare_iter_op() */
|
||
|
||
|
||
/*-------------------------------------------------------------------------
|
||
* Function: H5SM_message_compare
|
||
*
|
||
* Purpose: Determine whether the search key rec1 represents a shared
|
||
* message that is equal to rec2 or not, and if not, whether
|
||
* rec1 is "greater than" or "less than" rec2.
|
||
*
|
||
* Return: 0 if rec1 == rec2
|
||
* Negative if rec1 < rec2
|
||
* Positive if rec1 > rec2
|
||
*
|
||
* Programmer: James Laird
|
||
* Monday, November 6, 2006
|
||
*
|
||
*-------------------------------------------------------------------------
|
||
*/
|
||
herr_t
|
||
H5SM_message_compare(const void *rec1, const void *rec2)
|
||
{
|
||
const H5SM_mesg_key_t *key = (const H5SM_mesg_key_t *) rec1;
|
||
const H5SM_sohm_t *mesg = (const H5SM_sohm_t *) rec2;
|
||
herr_t ret_value = 0;
|
||
|
||
FUNC_ENTER_NOAPI_NOINIT_NOERR
|
||
|
||
/* If the key has an fheap ID, we're looking for a message that's
|
||
* already in the index; if the fheap ID matches, we've found the message
|
||
* and can stop immediately.
|
||
* Likewise, if the message has an OH location that is matched by the
|
||
* message in the index, we've found the message.
|
||
*/
|
||
if(mesg->location == H5SM_IN_HEAP && key->message.location == H5SM_IN_HEAP) {
|
||
if(key->message.u.heap_loc.fheap_id.val == mesg->u.heap_loc.fheap_id.val)
|
||
HGOTO_DONE(0);
|
||
} /* end if */
|
||
else if(mesg->location == H5SM_IN_OH && key->message.location == H5SM_IN_OH) {
|
||
if(key->message.u.mesg_loc.oh_addr == mesg->u.mesg_loc.oh_addr &&
|
||
key->message.u.mesg_loc.index == mesg->u.mesg_loc.index &&
|
||
key->message.msg_type_id == mesg->msg_type_id)
|
||
HGOTO_DONE(0);
|
||
} /* end if */
|
||
|
||
/* Compare hash values */
|
||
if(key->message.hash > mesg->hash)
|
||
ret_value = 1;
|
||
else if(key->message.hash < mesg->hash)
|
||
ret_value = -1;
|
||
/* If the hash values match, make sure the messages are really the same */
|
||
else {
|
||
/* Hash values match; compare the encoded message with the one in
|
||
* the index.
|
||
*/
|
||
H5SM_compare_udata_t udata;
|
||
herr_t status;
|
||
|
||
HDassert(key->message.hash == mesg->hash);
|
||
HDassert(key->encoding_size > 0 && key->encoding);
|
||
|
||
/* Set up user data for callback */
|
||
udata.key = key;
|
||
|
||
/* Compare the encoded message with either the message in the heap or
|
||
* the message in an object header.
|
||
*/
|
||
if(mesg->location == H5SM_IN_HEAP) {
|
||
/* Call heap op routine with comparison callback */
|
||
status = H5HF_op(key->fheap, key->dxpl_id, &(mesg->u.heap_loc.fheap_id), H5SM_compare_cb, &udata);
|
||
HDassert(status >= 0);
|
||
} /* end if */
|
||
else {
|
||
H5O_loc_t oloc; /* Object owning the message */
|
||
H5O_mesg_operator_t op; /* Message operator */
|
||
|
||
/* Sanity checks */
|
||
HDassert(key->file);
|
||
HDassert(mesg->location == H5SM_IN_OH);
|
||
|
||
/* Reset the object location */
|
||
status = H5O_loc_reset(&oloc);
|
||
HDassert(status >= 0);
|
||
|
||
/* Set up object location */
|
||
oloc.file = key->file;
|
||
oloc.addr = mesg->u.mesg_loc.oh_addr;
|
||
|
||
/* Finish setting up user data for iterator */
|
||
udata.idx = mesg->u.mesg_loc.index;
|
||
|
||
/* 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 */
|
||
|
||
ret_value = udata.ret;
|
||
} /* end if */
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value)
|
||
} /* end H5SM_message_compare */
|
||
|
||
|
||
/*-------------------------------------------------------------------------
|
||
* Function: H5SM_message_encode
|
||
*
|
||
* Purpose: Serialize a H5SM_sohm_t struct into a buffer RAW.
|
||
*
|
||
* Return: Non-negative on success
|
||
* Negative on failure
|
||
*
|
||
* Programmer: James Laird
|
||
* Monday, November 6, 2006
|
||
*
|
||
*-------------------------------------------------------------------------
|
||
*/
|
||
herr_t
|
||
H5SM_message_encode(uint8_t *raw, const void *_nrecord, void *_ctx)
|
||
{
|
||
H5SM_bt2_ctx_t *ctx = (H5SM_bt2_ctx_t *)_ctx; /* Callback context structure */
|
||
const H5SM_sohm_t *message = (const H5SM_sohm_t *)_nrecord;
|
||
|
||
FUNC_ENTER_NOAPI_NOINIT_NOERR
|
||
|
||
/* Sanity check */
|
||
HDassert(ctx);
|
||
|
||
*raw++ = message->location;
|
||
UINT32ENCODE(raw, message->hash);
|
||
|
||
if(message->location == H5SM_IN_HEAP) {
|
||
UINT32ENCODE(raw, message->u.heap_loc.ref_count);
|
||
HDmemcpy(raw, message->u.heap_loc.fheap_id.id, (size_t)H5O_FHEAP_ID_LEN);
|
||
} /* end if */
|
||
else {
|
||
HDassert(message->location == H5SM_IN_OH);
|
||
|
||
*raw++ = 0; /* reserved (possible flags byte) */
|
||
*raw++ = (uint8_t)message->msg_type_id;
|
||
UINT16ENCODE(raw, message->u.mesg_loc.index);
|
||
H5F_addr_encode_len((size_t)ctx->sizeof_addr, &raw, message->u.mesg_loc.oh_addr);
|
||
} /* end else */
|
||
|
||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||
} /* end H5SM_message_encode */
|
||
|
||
|
||
/*-------------------------------------------------------------------------
|
||
* Function: H5SM_message_decode
|
||
*
|
||
* Purpose: Read an encoded SOHM message from RAW into an H5SM_sohm_t struct.
|
||
*
|
||
* Return: Non-negative on success
|
||
* Negative on failure
|
||
*
|
||
* Programmer: James Laird
|
||
* Monday, November 6, 2006
|
||
*
|
||
*-------------------------------------------------------------------------
|
||
*/
|
||
herr_t
|
||
H5SM_message_decode(const uint8_t *raw, void *_nrecord, void *_ctx)
|
||
{
|
||
H5SM_bt2_ctx_t *ctx = (H5SM_bt2_ctx_t *)_ctx; /* Callback context structure */
|
||
H5SM_sohm_t *message = (H5SM_sohm_t *)_nrecord;
|
||
|
||
FUNC_ENTER_NOAPI_NOINIT_NOERR
|
||
|
||
message->location = (H5SM_storage_loc_t)*raw++;
|
||
UINT32DECODE(raw, message->hash);
|
||
|
||
if(message->location == H5SM_IN_HEAP) {
|
||
UINT32DECODE(raw, message->u.heap_loc.ref_count);
|
||
HDmemcpy(message->u.heap_loc.fheap_id.id, raw, (size_t)H5O_FHEAP_ID_LEN);
|
||
} /* end if */
|
||
else {
|
||
HDassert(message->location == H5SM_IN_OH);
|
||
|
||
raw++; /* reserved */
|
||
message->msg_type_id = *raw++;
|
||
UINT16DECODE(raw, message->u.mesg_loc.index);
|
||
H5F_addr_decode_len((size_t)ctx->sizeof_addr, &raw, &message->u.mesg_loc.oh_addr);
|
||
} /* end else */
|
||
|
||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||
} /* end H5SM_message_decode */
|
||
|