summaryrefslogtreecommitdiffstats
path: root/src/H5SMbtree2.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2009-12-01 17:05:23 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2009-12-01 17:05:23 (GMT)
commit90c94ab5d7e86b7573d3d92cf11b14e4fd90dab8 (patch)
treeb2f7787df09c5f036ba1f90a2283ad0c9dcaa179 /src/H5SMbtree2.c
parente3abb6e11a2dba5e57e1b36b9b4303a0007a5311 (diff)
downloadhdf5-90c94ab5d7e86b7573d3d92cf11b14e4fd90dab8.zip
hdf5-90c94ab5d7e86b7573d3d92cf11b14e4fd90dab8.tar.gz
hdf5-90c94ab5d7e86b7573d3d92cf11b14e4fd90dab8.tar.bz2
[svn-r17944] Description:
Bring r17943 from trunk to 1.8 branch: Finish refactoring v2 B-trees so that they can have client callback context provided to the encode/decode callbacks. Tested on: FreeBSD/64 6.3 (liberty) (h5committested on trunk)
Diffstat (limited to 'src/H5SMbtree2.c')
-rwxr-xr-xsrc/H5SMbtree2.c308
1 files changed, 111 insertions, 197 deletions
diff --git a/src/H5SMbtree2.c b/src/H5SMbtree2.c
index 2be7745..95527f9 100755
--- a/src/H5SMbtree2.c
+++ b/src/H5SMbtree2.c
@@ -20,6 +20,7 @@
#define H5O_PACKAGE /*suppress error about including H5Opkg */
#define H5SM_PACKAGE /*suppress error about including H5SMpkg */
+
/***********/
/* Headers */
/***********/
@@ -38,23 +39,18 @@
/* Local Typedefs */
/******************/
-/* Udata struct for calls to H5SM_btree_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 */
/********************/
/* v2 B-tree callbacks */
-static herr_t H5SM_btree_compare_cb(const void *obj, size_t obj_len, void *_udata);
-static herr_t H5SM_btree_store(void *native, const void *udata);
-static herr_t H5SM_btree_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
+static void *H5SM_bt2_crt_context(void *udata);
+static herr_t H5SM_bt2_dst_context(void *ctx);
+static herr_t H5SM_bt2_store(void *native, const void *udata);
+static herr_t H5SM_bt2_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
int indent, int fwidth, const void *record, const void *_udata);
+static void *H5SM_bt2_crt_dbg_context(H5F_t *f, hid_t dxpl_id, haddr_t addr);
/*****************************/
@@ -65,221 +61,99 @@ const H5B2_class_t H5SM_INDEX[1]={{ /* B-tree class information */
H5B2_SOHM_INDEX_ID, /* Type of B-tree */
"H5B2_SOHM_INDEX_ID", /* Name of B-tree class */
sizeof(H5SM_sohm_t), /* Size of native record */
- H5SM_btree_store, /* Record storage callback */
+ H5SM_bt2_crt_context, /* Create client callback context */
+ H5SM_bt2_dst_context, /* Destroy client callback context */
+ H5SM_bt2_store, /* Record storage callback */
H5SM_message_compare, /* Record comparison callback */
H5SM_message_encode, /* Record encoding callback */
H5SM_message_decode, /* Record decoding callback */
- H5SM_btree_debug /* Record debugging callback */
+ H5SM_bt2_debug, /* Record debugging callback */
+ H5SM_bt2_crt_dbg_context, /* Create debugging context */
+ H5SM_bt2_dst_context /* Destroy debugging context */
}};
+
/*******************/
/* Local Variables */
/*******************/
+/* Declare a free list to manage the H5SM_bt2_ctx_t struct */
+H5FL_DEFINE_STATIC(H5SM_bt2_ctx_t);
+
+
/*-------------------------------------------------------------------------
- * Function: H5SM_btree_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.
+ * Function: H5SM_bt2_crt_context
*
- * Passes back the result in _UDATA->RET
+ * Purpose: Create client callback context
*
- * Return: Negative on error, non-negative on success
+ * Return: Success: non-NULL
+ * Failure: NULL
*
- * Programmer: James Laird
- * Monday, January 8, 2007
+ * Programmer: Quincey Koziol
+ * Thursday, November 26, 2009
*
*-------------------------------------------------------------------------
*/
-static herr_t
-H5SM_btree_compare_cb(const void *obj, size_t obj_len, void *_udata)
+static void *
+H5SM_bt2_crt_context(void *_f)
{
- H5SM_compare_udata_t *udata = (H5SM_compare_udata_t *)_udata;
+ H5F_t *f = (H5F_t *)_f; /* User data for building callback context */
+ H5SM_bt2_ctx_t *ctx; /* Callback context structure */
+ void *ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_btree_compare_cb)
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_bt2_crt_context)
- /* 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);
+ /* Sanity check */
+ HDassert(f);
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_btree_compare_cb() */
+ /* Allocate callback context */
+ if(NULL == (ctx = H5FL_MALLOC(H5SM_bt2_ctx_t)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate callback context")
-
-/*-------------------------------------------------------------------------
- * 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,
- hbool_t 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(H5SM_compare_iter_op)
-
- /*
- * 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 */
+ /* Determine the size of addresses & lengths in the file */
+ ctx->sizeof_addr = H5F_SIZEOF_ADDR(f);
+
+ /* Set return value */
+ ret_value = ctx;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5SM_compare_iter_op() */
+} /* H5SM_bt2_crt_context() */
/*-------------------------------------------------------------------------
- * Function: H5SM_message_compare
+ * Function: H5SM_bt2_dst_context
*
- * 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.
+ * Purpose: Destroy client callback context
*
- * Return: 0 if rec1 == rec2
- * Negative if rec1 < rec2
- * Positive if rec1 > rec2
+ * Return: Success: non-negative
+ * Failure: negative
*
- * Programmer: James Laird
- * Monday, November 6, 2006
+ * Programmer: Quincey Koziol
+ * Thursday, November 26, 2009
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5SM_message_compare(const void *rec1, const void *rec2)
+static herr_t
+H5SM_bt2_dst_context(void *_ctx)
{
- 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_NOFUNC(H5SM_message_compare)
-
- /* 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 == mesg->u.heap_loc.fheap_id)
- 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_btree_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 */
+ H5SM_bt2_ctx_t *ctx = (H5SM_bt2_ctx_t *)_ctx; /* Callback context structure */
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5SM_message_compare */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_bt2_dst_context)
+
+ /* Sanity check */
+ HDassert(ctx);
+
+ /* Release callback context */
+ ctx = H5FL_FREE(H5SM_bt2_ctx_t, ctx);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5SM_bt2_dst_context() */
/*-------------------------------------------------------------------------
- * Function: H5SM_btree_store
+ * Function: H5SM_bt2_store
*
* Purpose: Store a H5SM_sohm_t SOHM message in the B-tree. The message
* comes in UDATA as a H5SM_mesg_key_t* and is copied to
@@ -294,21 +168,21 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5SM_btree_store(void *native, const void *udata)
+H5SM_bt2_store(void *native, const void *udata)
{
const H5SM_mesg_key_t *key = (const H5SM_mesg_key_t *)udata;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_btree_store)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_bt2_store)
/* Copy the source message to the B-tree */
*(H5SM_sohm_t *)native = key->message;
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_btree_store */
+} /* end H5SM_bt2_store */
/*-------------------------------------------------------------------------
- * Function: H5SM_btree_debug
+ * Function: H5SM_bt2_debug
*
* Purpose: Print debugging information for a H5SM_sohm_t.
*
@@ -321,12 +195,12 @@ H5SM_btree_store(void *native, const void *udata)
*-------------------------------------------------------------------------
*/
static herr_t
-H5SM_btree_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
+H5SM_bt2_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
int indent, int fwidth, const void *record, const void UNUSED *_udata)
{
const H5SM_sohm_t *sohm = (const H5SM_sohm_t *)record;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_btree_debug)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_bt2_debug)
if(sohm->location == H5SM_IN_HEAP)
HDfprintf(stream, "%*s%-*s {%a, %lo, %Hx}\n", indent, "", fwidth,
@@ -340,11 +214,51 @@ H5SM_btree_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
} /* end else */
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_btree_debug */
+} /* end H5SM_bt2_debug */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_bt2_crt_dbg_context
+ *
+ * Purpose: Create context for debugging callback
+ *
+ * Return: Success: non-NULL
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, December 1, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5SM_bt2_crt_dbg_context(H5F_t *f, hid_t UNUSED dxpl_id, haddr_t UNUSED addr)
+{
+ H5SM_bt2_ctx_t *ctx; /* Callback context structure */
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5SM_bt2_crt_dbg_context)
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+
+ /* Allocate callback context */
+ if(NULL == (ctx = H5FL_MALLOC(H5SM_bt2_ctx_t)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate callback context")
+
+ /* Determine the size of addresses & lengths in the file */
+ ctx->sizeof_addr = H5F_SIZEOF_ADDR(f);
+
+ /* Set return value */
+ ret_value = ctx;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5SM_bt2_crt_dbg_context() */
/*-------------------------------------------------------------------------
- * Function: H5SM_btree_convert_to_list_op
+ * Function: H5SM_bt2_convert_to_list_op
*
* Purpose: An H5B2_remove_t callback function to convert a SOHM
* B-tree index to a list.
@@ -360,13 +274,13 @@ H5SM_btree_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
*-------------------------------------------------------------------------
*/
herr_t
-H5SM_btree_convert_to_list_op(const void * record, void *op_data)
+H5SM_bt2_convert_to_list_op(const void * record, void *op_data)
{
const H5SM_sohm_t *message = (const H5SM_sohm_t *)record;
const H5SM_list_t *list = (const H5SM_list_t *)op_data;
size_t mesg_idx; /* Index of message to modify */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_btree_convert_to_list_op)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_bt2_convert_to_list_op)
/* Sanity checks */
HDassert(record);
@@ -382,5 +296,5 @@ H5SM_btree_convert_to_list_op(const void * record, void *op_data)
HDmemcpy(&(list->messages[mesg_idx]), message, sizeof(H5SM_sohm_t));
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_btree_convert_to_list_op() */
+} /* end H5SM_bt2_convert_to_list_op() */