mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-11-21 01:04:10 +08:00
[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.
This commit is contained in:
parent
7c733b0afb
commit
25b96dc712
29
src/H5SM.c
29
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")
|
||||
|
@ -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 */
|
||||
|
||||
|
29
test/tsohm.c
29
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<DELETE_NUM_MESGS; ++x) {
|
||||
dspace_id[x] = H5Screate_simple(x + 1, dims, dims);
|
||||
CHECK_I(dspace_id[x], "H5Screate_simple");
|
||||
CHECK_I(dspace_id[x], "H5Screate_simple");
|
||||
}
|
||||
|
||||
/* Create a number of different filter pipelines. */
|
||||
@ -2752,7 +2754,6 @@ test_sohm_delete(void)
|
||||
/* Test that messages can be created and deleted properly */
|
||||
delete_helper(fcpl_id, dspace_id, dcpl_id);
|
||||
|
||||
|
||||
/* Use B-tree indexes */
|
||||
ret = H5Pset_shared_mesg_phase_change(fcpl_id, 0, 0);
|
||||
CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
|
||||
@ -2793,6 +2794,18 @@ test_sohm_delete(void)
|
||||
|
||||
delete_helper(fcpl_id, dspace_id, dcpl_id);
|
||||
|
||||
|
||||
/* Test with varying message sizes (ideally, so some messages are too
|
||||
* small to be written but some are big enough that they are still written
|
||||
*/
|
||||
ret = H5Pset_shared_mesg_nindexes(fcpl_id, 1);
|
||||
CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
|
||||
for(x=DELETE_MIN_MESG_SIZE; x<=DELETE_MAX_MESG_SIZE; x += 10) {
|
||||
ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_MESG_ALL_FLAG, (size_t) x);
|
||||
CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
|
||||
delete_helper(fcpl_id, dspace_id, dcpl_id);
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
ret = H5Pclose(fcpl_id);
|
||||
CHECK_I(ret, "H5Pclose");
|
||||
@ -2946,6 +2959,7 @@ test_sohm_delete_revert(void)
|
||||
ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_MESG_ALL_FLAG, 10);
|
||||
CHECK_I(ret, "H5Pset_shared_mesg_index");
|
||||
ret = H5Pset_shared_mesg_phase_change(fcpl_id, 10, 5);
|
||||
CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
|
||||
|
||||
test_sohm_delete_revert_helper(fcpl_id);
|
||||
|
||||
@ -2962,6 +2976,14 @@ test_sohm_delete_revert(void)
|
||||
CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
|
||||
test_sohm_delete_revert_helper(fcpl_id);
|
||||
|
||||
|
||||
/* Try with shared messages enabled, but when messages are too big
|
||||
* to be shared.
|
||||
*/
|
||||
ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_MESG_ALL_FLAG, 35);
|
||||
CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
|
||||
test_sohm_delete_revert_helper(fcpl_id);
|
||||
|
||||
ret = H5Pclose(fcpl_id);
|
||||
CHECK_I(ret, "H5Pclose");
|
||||
}
|
||||
@ -3330,7 +3352,6 @@ test_sohm(void)
|
||||
{
|
||||
/* Output message about test being performed */
|
||||
MESSAGE(5, ("Testing Shared Object Header Messages\n"));
|
||||
|
||||
test_sohm_fcpl(); /* Test SOHMs and file creation plists */
|
||||
test_sohm_size1(); /* Tests the sizes of files with one SOHM */
|
||||
test_sohm_attrs(); /* Tests shared messages in attributes */
|
||||
|
Loading…
Reference in New Issue
Block a user