diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2009-12-01 17:05:23 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2009-12-01 17:05:23 (GMT) |
commit | 90c94ab5d7e86b7573d3d92cf11b14e4fd90dab8 (patch) | |
tree | b2f7787df09c5f036ba1f90a2283ad0c9dcaa179 /src/H5SMbtree2.c | |
parent | e3abb6e11a2dba5e57e1b36b9b4303a0007a5311 (diff) | |
download | hdf5-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-x | src/H5SMbtree2.c | 308 |
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() */ |