From 25b96dc712e467b5efe7b166c078e33ed8aef86c Mon Sep 17 00:00:00 2001 From: James Laird Date: Tue, 30 Jan 2007 15:40:44 -0500 Subject: [svn-r13224] Fixed a bug where messages would report their "raw size" as the size of a shared message rather than the full size of the unshared message, which confused some shared message code. Added a test that should make sure that some messages are too small to be written to the deletion test in tsohm.c. Also added a small optimization so that hash values don't need to be calculated on deletes in list indexes. Tested on Windows, smirom, and kagiso. --- src/H5SM.c | 29 ++++++++++++++++------------- src/H5SMbtree2.c | 19 ++++++++++++++++--- test/tsohm.c | 29 +++++++++++++++++++++++++---- 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/src/H5SM.c b/src/H5SM.c index 8b5faf9..efd1ea9 100755 --- a/src/H5SM.c +++ b/src/H5SM.c @@ -816,8 +816,8 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, unsigned type_id, void *mesg) } /* end if */ /* If the message isn't big enough, don't bother sharing it */ - if(0 == (mesg_size = H5O_msg_mesg_size(f, type_id, mesg, (size_t)0))) - HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "unable to get OH message size") + if(0 == (mesg_size = H5O_msg_raw_size(f, type_id, TRUE, mesg))) + HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "unable to get OH message size") if(mesg_size < table->indexes[index_num].min_mesg_size) HGOTO_DONE(FALSE); @@ -1223,14 +1223,9 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5SM_index_header_t *header, /* Prepare user data for fractal heap 'op' callback */ udata.type_id = type_id; - /* Compute the hash value for the B-tree lookup */ - if(H5HF_op(fheap, dxpl_id, &(mesg->u.heap_id), H5SM_get_hash_fh_cb, &udata) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't access message in fractal heap") - - /* Set up key for message to be deleted. */ key.message.fheap_id = mesg->u.heap_id; - key.message.hash = udata.hash; + key.message.hash = 0; /* Only needed for B-tree lookup */ key.message.ref_count = 0; /* Refcount isn't relevant here */ key.encoding = NULL; @@ -1259,6 +1254,12 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5SM_index_header_t *header, { HDassert(header->index_type == H5SM_BTREE); + /* Compute the hash value for the B-tree lookup */ + if(H5HF_op(fheap, dxpl_id, &(mesg->u.heap_id), H5SM_get_hash_fh_cb, &udata) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't access message in fractal heap") + + key.message.hash = udata.hash; + /* If this returns failure, it means that the message wasn't found. * If it succeeds, a copy of the modified message will be returned. */ if(H5B2_modify(f, dxpl_id, H5SM_INDEX, header->index_addr, &key, H5SM_decr_ref, &message) <0) @@ -1577,13 +1578,9 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, /* Prepare user data for callback */ udata.type_id = type_id; - /* Compute the hash value for the B-tree lookup */ - if(H5HF_op(fheap, dxpl_id, &(sh_mesg->u.heap_id), H5SM_get_hash_fh_cb, &udata) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't access message in fractal heap") - /* Set up key for message to locate */ key.message.fheap_id = sh_mesg->u.heap_id; - key.message.hash = udata.hash; + key.message.hash = 0; /* Only needed for B-tree lookup */ key.message.ref_count = 0; /* Ref count isn't needed to find message */ key.encoding = NULL; @@ -1609,6 +1606,12 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, { HDassert(header->index_type == H5SM_BTREE); + /* Compute the hash value for the B-tree lookup */ + if(H5HF_op(fheap, dxpl_id, &(sh_mesg->u.heap_id), H5SM_get_hash_fh_cb, &udata) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't access message in fractal heap") + + key.message.hash = udata.hash; + /* Look up the message in the v2 B-tree */ if(H5B2_find(f, dxpl_id, H5SM_INDEX, header->index_addr, &key, H5SM_get_refcount_bt2_cb, &message) < 0) HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "message not in index") diff --git a/src/H5SMbtree2.c b/src/H5SMbtree2.c index f1d12da..908729a 100755 --- a/src/H5SMbtree2.c +++ b/src/H5SMbtree2.c @@ -143,14 +143,26 @@ H5SM_message_compare(const void *rec1, const void *rec2) */ /* JAMES HDassert(mesg->ref_count > 0); */ + /* 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. + * This means that list indexes that don't care about ordering can + * pass in bogus hash values and they'll still get a match if the heap + * IDs are the same. + */ + if(key->encoding_size == 0) + { + HDassert(key->encoding == NULL); + if(key->message.fheap_id == mesg->fheap_id) + HGOTO_DONE(0); + } + hash_diff = key->message.hash; hash_diff -= mesg->hash; /* If the hash values match, make sure the messages are really the same */ if(0 == hash_diff) { - /* Compare either the heap_ids directly (if the key has one) - * or the encoded buffers - */ + /* Compare the encoded buffers or the fheap IDs */ if(key->encoding_size == 0) { HDassert(key->encoding == NULL); @@ -182,6 +194,7 @@ H5SM_message_compare(const void *rec1, const void *rec2) ret_value = -1; } +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_message_compare */ diff --git a/test/tsohm.c b/test/tsohm.c index 7361f3e..f0a3728 100644 --- a/test/tsohm.c +++ b/test/tsohm.c @@ -141,6 +141,9 @@ typedef struct size2_helper_struct { #define DELETE_NUM_MESGS 7 #define HALF_DELETE_NUM_MESGS 3 #define DELETE_DIMS {1,1,1,1,1,1,1} +#define DELETE_MIN_MESG_SIZE 10 +#define DELETE_MAX_MESG_SIZE 60 + /* Number of dimensions in extend_dset test */ #define EXTEND_NDIMS 2 @@ -2630,7 +2633,6 @@ static void delete_helper(hid_t fcpl_id, hid_t *dspace_id, hid_t *dcpl_id) CHECK_I(ret, "H5Fclose"); norm_filesize = h5_get_file_size(FILENAME); - /* Create a new file with messages 0 to (HALF_DELETE_NUM_MESGS - 1) */ file_id = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT); CHECK_I(file_id, "H5Fcreate"); @@ -2708,7 +2710,7 @@ test_sohm_delete(void) */ for(x=0; x