diff options
author | James Laird <jlaird@hdfgroup.org> | 2006-12-01 15:51:42 (GMT) |
---|---|---|
committer | James Laird <jlaird@hdfgroup.org> | 2006-12-01 15:51:42 (GMT) |
commit | 772730f4d744a0c8428f9c447b7b6073410a2880 (patch) | |
tree | f9fb0a1a5613e3c8705c7ea5e0b991cc2acfb82d /src | |
parent | 7855afc4b2a1fd4c266f96aa7a8dc21964e3bda3 (diff) | |
download | hdf5-772730f4d744a0c8428f9c447b7b6073410a2880.zip hdf5-772730f4d744a0c8428f9c447b7b6073410a2880.tar.gz hdf5-772730f4d744a0c8428f9c447b7b6073410a2880.tar.bz2 |
[svn-r13004] Much improved shared object header message test, along with some bug fixes
to make the test pass.
These changes involve changes to the file format of SOHMs, but that's okay
because nobody should have been using SOHMs yet anyway.
Tested on Windows, kagiso, copper, and heping
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Fsuper.c | 5 | ||||
-rw-r--r-- | src/H5O.c | 61 | ||||
-rw-r--r-- | src/H5Oalloc.c | 4 | ||||
-rw-r--r-- | src/H5Opublic.h | 2 | ||||
-rw-r--r-- | src/H5Oshared.c | 14 | ||||
-rw-r--r-- | src/H5Pfcpl.c | 20 | ||||
-rwxr-xr-x | src/H5SM.c | 84 | ||||
-rwxr-xr-x | src/H5SMbtree2.c | 22 | ||||
-rw-r--r-- | src/H5SMcache.c | 5 | ||||
-rwxr-xr-x | src/H5SMpkg.h | 4 | ||||
-rwxr-xr-x | src/H5SMprivate.h | 2 |
11 files changed, 121 insertions, 102 deletions
diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index 61ecacd..f1d2797 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -373,13 +373,14 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc, haddr_t addr, if(shared->sohm_addr != HADDR_UNDEF) { unsigned index_flags[H5SM_MAX_NUM_INDEXES] = {0}; + unsigned minsizes[H5SM_MAX_NUM_INDEXES] = {0}; size_t sohm_l2b; /* SOHM list-to-btree cutoff */ size_t sohm_b2l; /* SOHM btree-to-list cutoff */ HDassert(shared->sohm_nindexes > 0 && shared->sohm_nindexes <= H5SM_MAX_NUM_INDEXES); /* Read in the shared OH message information if there is any */ - if(H5SM_get_info(f, index_flags, &sohm_l2b, &sohm_b2l, dxpl_id) < 0) + if(H5SM_get_info(f, index_flags, minsizes, &sohm_l2b, &sohm_b2l, dxpl_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read SOHM table information") /* Set values in the property list */ @@ -387,6 +388,8 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc, haddr_t addr, HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set number of SOHM indexes"); if(H5P_set(c_plist, H5F_CRT_SHMSG_INDEX_TYPES_NAME, index_flags) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set type flags for indexes"); + if(H5P_set(c_plist, H5F_CRT_SHMSG_INDEX_MINSIZE_NAME, minsizes) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set type flags for indexes"); if(H5P_set(c_plist, H5F_CRT_SHMSG_LIST_MAX_NAME, &sohm_l2b) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set SOHM cutoff in property list"); if(H5P_set(c_plist, H5F_CRT_SHMSG_BTREE_MIN_NAME, &sohm_b2l) < 0) @@ -1884,7 +1884,7 @@ H5O_modify_real(H5O_loc_t *loc, const H5O_msg_class_t *type, int overwrite, if(overwrite < 0) { /* Create a new message */ /* JAMES: why is sh_mesg passed in here? Is it ever used? */ - if((idx = H5O_new_mesg(loc->file, oh, &mesg_flags, type, mesg, &sh_mesg, &type, &mesg, dxpl_id, &oh_flags)) == UFAIL) + if((idx = H5O_new_mesg(loc->file, oh, &mesg_flags, type, mesg, &sh_mesg, &write_type, &write_mesg, dxpl_id, &oh_flags)) == UFAIL) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create new message") /* Set the correct sequence number for the message created */ @@ -3135,15 +3135,9 @@ H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg, hbool_t adj_link) * We shouldn't need to do a search in the SOHM table on delete. */ if(type == H5O_MSG_SHARED) { - /* JAMES ugly! And not quite correct. */ - void * mesg_orig; - if(NULL == (mesg_orig = H5O_shared_read(f, dxpl_id, mesg->native, mesg->type, NULL))) - HGOTO_ERROR (H5E_OHDR, H5E_BADMESG, FAIL, "unable to read shared message") - + /* The native message here is actually a shared message. */ if(H5SM_try_delete(f, dxpl_id, mesg->type->id, mesg->native) < 0) HGOTO_ERROR (H5E_OHDR, H5E_CANTFREE, FAIL, "unable to delete message from SOHM table") - - H5O_free(mesg->type->id, mesg_orig); } if((type->del)(f, dxpl_id, mesg->native, adj_link) < 0) @@ -3337,6 +3331,9 @@ H5O_iterate_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, H5AC_protect unsigned idx; /* Absolute index of current message in all messages */ unsigned sequence; /* Relative index of current message for messages of type */ H5O_mesg_t *idx_msg; /* Pointer to current message */ + void *native_mesg; /* Native, readable message */ + hbool_t native_mesg_alloc = FALSE; /* True if native_mesg needs to be freed */ + herr_t ret_value = H5_ITER_CONT; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_iterate_real) @@ -3355,23 +3352,12 @@ H5O_iterate_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, H5AC_protect /* Iterate over messages */ for(sequence = 0, idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs && !ret_value; idx++, idx_msg++) { if(type->id == idx_msg->type->id) { - void * unshared_mesg; /* JAMES */ /* - * Decode the message if necessary. If the message is shared then decode - * a shared message, ignoring the message type. + * Decode the message if necessary. */ LOAD_NATIVE(loc->file, dxpl_id, idx_msg, FAIL) - /* JAMES: test */ - if(idx_msg->flags & H5O_MSG_FLAG_SHARED) - { - if(NULL == (unshared_mesg = H5O_shared_read(loc->file, dxpl_id, idx_msg->native, idx_msg->type, NULL))) - HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "unable to read shared message"); - } - else - unshared_mesg = idx_msg->native; - /* Check for making an "internal" (i.e. within the H5O package) callback */ if(internal) { /* Call the "internal" iterator callback */ @@ -3379,19 +3365,28 @@ H5O_iterate_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, H5AC_protect break; } /* end if */ else { + /* If the message is shared, get the real message it points to */ + /* JAMES: test */ + if(idx_msg->flags & H5O_MSG_FLAG_SHARED) { + if(NULL == (native_mesg = H5O_shared_read(loc->file, dxpl_id, + idx_msg->native, idx_msg->type, NULL))) + HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "unable to read shared message"); + native_mesg_alloc = TRUE; + } + else { + native_mesg = idx_msg->native; + } + /* Call the iterator callback */ -/* JAMES if((ret_value = (op.app_op)(idx_msg->native, sequence, op_data)) != 0) + if((ret_value = (op.app_op)(native_mesg, sequence, op_data)) != 0) break; -*/ - if((ret_value = (op.app_op)(unshared_mesg, sequence, op_data)) != 0) - break; - } /* end else */ - /* JAMES again */ - if(idx_msg->flags & H5O_MSG_FLAG_SHARED) - { - H5O_free_real(idx_msg->type, unshared_mesg); - } + /* Free the "real" message if it was allocated */ + if(native_mesg_alloc) { + H5O_free(idx_msg->type->id, native_mesg); + native_mesg_alloc = FALSE; + } + } /* end else */ /* Check for error from iterator */ if(ret_value < 0) @@ -3403,6 +3398,12 @@ H5O_iterate_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, H5AC_protect } /* end for */ done: + /* Free the native message if it was allocated */ + if(native_mesg_alloc) { + H5O_free(idx_msg->type->id, native_mesg); + native_mesg_alloc = FALSE; + } + if(oh) { /* Check if object header was modified */ if(oh_flags & H5AC__DIRTIED_FLAG) { diff --git a/src/H5Oalloc.c b/src/H5Oalloc.c index 3d728ce..ae1c5ff 100644 --- a/src/H5Oalloc.c +++ b/src/H5Oalloc.c @@ -663,11 +663,11 @@ H5O_alloc_new_chunk(H5F_t *f, (found_attr < 0 || oh->mesg[u].raw_size < oh->mesg[found_attr].raw_size)) found_attr = u; - } else if(H5O_LINK_ID == msg_id) { +/* } else if(H5O_LINK_ID == msg_id) { if(oh->mesg[u].raw_size >= cont_size && (found_link < 0 || oh->mesg[u].raw_size < oh->mesg[found_link].raw_size)) - found_link = u; + found_link = u; JAMES */ } else { if(oh->mesg[u].raw_size >= cont_size && (found_other < 0 || diff --git a/src/H5Opublic.h b/src/H5Opublic.h index 828506f..6895716 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -59,11 +59,9 @@ #define H5O_MESG_ATTR_FLAG 0x0010 /* Attribute Message. */ #define H5O_MESG_ALL_FLAG (H5O_MESG_SDSPACE_FLAG | H5O_MESG_DTYPE_FLAG | H5O_MESG_FILL_FLAG | H5O_MESG_PLINE_FLAG | H5O_MESG_ATTR_FLAG) - /*******************/ /* Public Typedefs */ /*******************/ - /* A struct that's part of the H5G_stat_t routine (deprecated) */ typedef struct H5O_stat_t { hsize_t size; /* Total size of object header in file */ diff --git a/src/H5Oshared.c b/src/H5Oshared.c index fa5f0d5..032e2b0 100644 --- a/src/H5Oshared.c +++ b/src/H5Oshared.c @@ -109,7 +109,7 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared, { H5HF_t *fheap = NULL; unsigned char *buf = NULL; /* Pointer to raw message in heap */ - void * native_mesg = NULL; /* Only used for messages shared in heap */ + void *native_mesg = NULL; /* Used for messages shared in heap */ void *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_shared_read) @@ -118,6 +118,7 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared, HDassert(f); HDassert(shared); HDassert(type); + HDassert(type->set_share); /* This message could have a heap ID (SOHM) or the address of an object * header on disk (named datatype) @@ -153,14 +154,9 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared, if(NULL == (native_mesg = H5O_decode(f, dxpl_id, buf, type->id))) HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "can't decode shared message.") - /* Make sure that this message is labeled as shared */ - HDassert(type->set_share); - if(((type->set_share)(f, native_mesg, shared)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to set sharing information") - - /* Get a copy of the message to return */ - if(NULL == (ret_value = H5O_copy(type->id, native_mesg, mesg))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy message") + /* Copy this message to the user's buffer */ + if(NULL == (ret_value = (type->copy) (native_mesg, mesg, 0))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to copy message to user space") } /* end if */ else { HDassert(shared->flags & H5O_COMMITTED_FLAG); diff --git a/src/H5Pfcpl.c b/src/H5Pfcpl.c index da8e0fa..d487f29 100644 --- a/src/H5Pfcpl.c +++ b/src/H5Pfcpl.c @@ -77,7 +77,6 @@ #define H5F_CRT_SHMSG_NINDEXES_DEF (0) #define H5F_CRT_SHMSG_INDEX_TYPES_SIZE sizeof(unsigned[H5SM_MAX_NUM_INDEXES]) #define H5F_CRT_SHMSG_INDEX_TYPES_DEF {0,0,0,0,0,0} -/* JAMES #define H5F_CRT_SHMSG_INDEX_TYPES_DEF { H5O_MESG_FILL_FLAG |H5O_MESG_SDSPACE_FLAG,H5O_MESG_ATTR_FLAG, 0, H5O_MESG_DTYPE_FLAG,0,H5O_MESG_PLINE_FLAG} */ #define H5F_CRT_SHMSG_INDEX_MINSIZE_SIZE sizeof(unsigned[H5SM_MAX_NUM_INDEXES]) #define H5F_CRT_SHMSG_INDEX_MINSIZE_DEF {250,250,250,250,250,250} /* Definitions for shared object header list/btree phase change cutoffs */ @@ -158,11 +157,11 @@ H5P_fcrt_reg_prop(H5P_genclass_t *pclass) unsigned freespace_ver = H5F_CRT_FREESPACE_VERS_DEF;/* Default free space version # */ unsigned objectdir_ver = H5F_CRT_OBJ_DIR_VERS_DEF; /* Default object directory version # */ unsigned sharedheader_ver = H5F_CRT_SHARE_HEAD_VERS_DEF; /* Default shared header message version # */ - unsigned num_sohm_indexes = H5F_CRT_SHMSG_NINDEXES_DEF; - unsigned sohm_index_flags[H5SM_MAX_NUM_INDEXES] = H5F_CRT_SHMSG_INDEX_TYPES_DEF; - unsigned sohm_index_minsizes[H5SM_MAX_NUM_INDEXES] = H5F_CRT_SHMSG_INDEX_MINSIZE_DEF; - unsigned sohm_list_max = H5F_CRT_SHMSG_LIST_MAX_DEF; - unsigned sohm_btree_min = H5F_CRT_SHMSG_BTREE_MIN_DEF; + unsigned num_sohm_indexes = H5F_CRT_SHMSG_NINDEXES_DEF; + unsigned sohm_index_flags[H5SM_MAX_NUM_INDEXES] = H5F_CRT_SHMSG_INDEX_TYPES_DEF; + unsigned sohm_index_minsizes[H5SM_MAX_NUM_INDEXES] = H5F_CRT_SHMSG_INDEX_MINSIZE_DEF; + unsigned sohm_list_max = H5F_CRT_SHMSG_LIST_MAX_DEF; + unsigned sohm_btree_min = H5F_CRT_SHMSG_BTREE_MIN_DEF; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5P_fcrt_reg_prop) @@ -798,7 +797,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5Pget_shared_imesg_nindexes + * Function: H5Pget_shared_mesg_nindexes * * Purpose: Get the number of Shared Object Header Message (SOHM) * indexes specified in this property list. @@ -852,7 +851,6 @@ H5Pset_shared_mesg_index(hid_t plist_id, unsigned index_num, unsigned mesg_type_ unsigned nindexes; /* Number of SOHM indexes */ unsigned type_flags[H5SM_MAX_NUM_INDEXES]; /* Array of mesg_type_flags*/ unsigned minsizes[H5SM_MAX_NUM_INDEXES]; /* Array of min_mesg_sizes*/ - unsigned x; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_API(H5Pset_shared_mesg_index, FAIL); @@ -885,12 +883,6 @@ H5Pset_shared_mesg_index(hid_t plist_id, unsigned index_num, unsigned mesg_type_ type_flags[index_num - 1] = mesg_type_flags; minsizes[index_num - 1] = min_mesg_size; - /* Check that type flags does introduce any duplicate values */ - for(x=0; x < nindexes; ++x) { - if(x != (index_num - 1) && (type_flags[index_num - 1] & type_flags[x]) != 0) - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't assign the same flag to different indexes") - } - /* Write arrays back to plist */ if(H5P_set(plist, H5F_CRT_SHMSG_INDEX_TYPES_NAME, type_flags) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set index type flags"); @@ -104,6 +104,8 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, hid_t dxpl_id) unsigned num_indexes; unsigned list_to_btree, btree_to_list; unsigned index_type_flags[H5SM_MAX_NUM_INDEXES]; + unsigned minsizes[H5SM_MAX_NUM_INDEXES]; + unsigned type_flags_used; ssize_t x; hsize_t table_size; herr_t ret_value=SUCCEED; @@ -120,13 +122,28 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, hid_t dxpl_id) /* Get information from fcpl */ if(H5P_get(fc_plist, H5F_CRT_SHMSG_NINDEXES_NAME, &num_indexes)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM information") + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get number of indexes") if(H5P_get(fc_plist, H5F_CRT_SHMSG_INDEX_TYPES_NAME, &index_type_flags)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM information") + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM type flags") if(H5P_get(fc_plist, H5F_CRT_SHMSG_LIST_MAX_NAME, &list_to_btree)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM information") + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM list maximum") if(H5P_get(fc_plist, H5F_CRT_SHMSG_BTREE_MIN_NAME, &btree_to_list)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM information") + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM btree minimum") + if(H5P_get(fc_plist, H5F_CRT_SHMSG_INDEX_MINSIZE_NAME, &minsizes) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM message min sizes") + + /* Verify that values are valid */ + if(num_indexes > H5SM_MAX_NUM_INDEXES) + HGOTO_ERROR(H5E_PLIST, H5E_BADRANGE, FAIL, "number of indexes in property list is too large") + + /* Check that type flags weren't duplicated anywhere */ + type_flags_used = 0; + for(x=0; x<num_indexes; ++x) { + if(index_type_flags[x] & type_flags_used) { + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "the same shared message type flag is assigned to more than one index") + } + type_flags_used |= index_type_flags[x]; + } /* Set version and number of indexes in table and in superblock. * Right now we just use one byte to hold the number of indexes. @@ -153,12 +170,12 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, hid_t dxpl_id) /* Initialize all of the indexes, but don't allocate space for them to * hold messages until we actually need to write to them. */ - /* JAMES: currently all indexes use the same values */ for(x=0; x<table->num_indexes; x++) { table->indexes[x].btree_to_list = btree_to_list; table->indexes[x].list_to_btree = list_to_btree; table->indexes[x].mesg_types = index_type_flags[x]; + table->indexes[x].min_mesg_size = minsizes[x]; table->indexes[x].index_addr = HADDR_UNDEF; table->indexes[x].heap_addr = HADDR_UNDEF; table->indexes[x].num_messages = 0; @@ -422,12 +439,13 @@ H5SM_create_list(H5F_t *f, H5SM_index_header_t * header, hid_t dxpl_id) if((list->messages = H5FL_ARR_MALLOC(H5SM_sohm_t, num_entries)) == NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list") - /* Initialize list */ + /* Initialize messages in list */ + HDmemset(list->messages, 0, sizeof(H5SM_sohm_t) * num_entries); + /* JAMES: would making fewer operations out of this make it faster? */ - for(x=0; x<num_entries; x++) - { - list->messages[x].ref_count=0; - list->messages[x].fheap_id=0; + for(x=0; x<num_entries; x++) { +// list->messages[x].ref_count=0; +// list->messages[x].fheap_id=0; list->messages[x].hash=H5O_HASH_UNDEF; } @@ -493,7 +511,7 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, unsigned type_id, void *mesg) H5SM_master_table_t *table = NULL; unsigned cache_flags = H5AC__NO_FLAGS_SET; ssize_t index_num; - herr_t ret_value = SUCCEED; + herr_t ret_value = TRUE; FUNC_ENTER_NOAPI(H5SM_try_share, FAIL) /* Check whether this message ought to be shared or not */ @@ -501,14 +519,6 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, unsigned type_id, void *mesg) if(f->shared->sohm_addr == HADDR_UNDEF) HGOTO_DONE(FALSE); - /* If the message isn't big enough, don't bother sharing it */ - if((mesg_size = H5O_mesg_size(type_id, f, mesg, 0)) == 0) - HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "unable to get OH message size") - if(mesg_size < 50) /* JAMES: arbitrary value. Make this per-index, along with index sizes? */ - HGOTO_DONE(FALSE); - - /* JAMES_HEAP: skip this step if it's already shared--just increment the refcount on the message itself */ - /* Type-specific checks */ /* JAMES: should this go here? Should there be a "can share" callback? */ if(type_id == H5O_DTYPE_ID) @@ -542,7 +552,13 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, unsigned type_id, void *mesg) if(index_num < 0) HGOTO_DONE(FALSE); - /* At this point, the message should definitely be shared. */ + /* If the message isn't big enough, don't bother sharing it */ + if((mesg_size = H5O_mesg_size(type_id, f, mesg, 0)) <0) + 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); + + /* At this point, the message will be shared. */ /* If the index hasn't been allocated yet, create it */ if(table->indexes[index_num].index_addr == HADDR_UNDEF) @@ -674,16 +690,19 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5SM_index_header_t *header, /* JAMES: wrap this in a function call? */ - /* Encode the message and get its size */ + /* Encode the message and get its size */ /* JAMES: already have this */ if((mesg_size = H5O_raw_size(type_id, f, mesg)) == 0) HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "unable to get size of message") + /* JAMES: fix memory problem */ + shared.u.heap_id = 0; + if(H5HF_insert(fheap, dxpl_id, mesg_size, key.encoding, &(shared.u.heap_id)) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap") /* Check whether the list has grown enough that it needs to become a B-tree */ /* JAMES: make this a separate function */ - if(header->index_type == H5SM_LIST && header->num_messages > header->list_to_btree) + if(header->index_type == H5SM_LIST && header->num_messages >= header->list_to_btree) { hsize_t list_size; /* Size of list on disk */ haddr_t tree_addr; @@ -788,7 +807,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5SM_try_delete(H5F_t *f, hid_t dxpl_id, unsigned type_id, const H5O_shared_t *mesg) +H5SM_try_delete(H5F_t *f, hid_t dxpl_id, unsigned type_id, const H5O_shared_t *sh_mesg) { H5SM_master_table_t *table = NULL; unsigned cache_flags = H5AC__NO_FLAGS_SET; @@ -797,10 +816,10 @@ H5SM_try_delete(H5F_t *f, hid_t dxpl_id, unsigned type_id, const H5O_shared_t *m FUNC_ENTER_NOAPI(H5SM_try_delete, FAIL) HDassert(f); - HDassert(mesg); + HDassert(sh_mesg); /* Make sure SHARED_IN_HEAP flag is set; if not, there's no message to delete */ - if(0 == (mesg->flags & H5O_SHARED_IN_HEAP_FLAG)) + if(0 == (sh_mesg->flags & H5O_SHARED_IN_HEAP_FLAG)) HGOTO_DONE(SUCCEED); HDassert(f->shared->sohm_addr != HADDR_UNDEF); @@ -814,7 +833,7 @@ H5SM_try_delete(H5F_t *f, hid_t dxpl_id, unsigned type_id, const H5O_shared_t *m HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "unable to find correct SOHM index") /* JAMES: this triggers some warning on heping. "overflow in implicit constant conversion" */ - if(H5SM_delete_from_index(f, dxpl_id, &(table->indexes[index_num]), type_id, mesg, &cache_flags) < 0) + if(H5SM_delete_from_index(f, dxpl_id, &(table->indexes[index_num]), type_id, sh_mesg, &cache_flags) < 0) HGOTO_ERROR(H5E_SOHM, H5E_CANTDELETE, FAIL, "unable to delete mesage from SOHM index") done: @@ -895,7 +914,6 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5SM_index_header_t *header, uns HDassert(mesg); HDassert(cache_flags); HDassert(mesg->flags & H5O_SHARED_IN_HEAP_FLAG); - /* Open the heap that this message is in */ if(NULL == (fheap=H5HF_open(f, dxpl_id, header->heap_addr))) @@ -957,6 +975,8 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5SM_index_header_t *header, uns if(header->index_type == H5SM_LIST) { list->messages[list_pos].hash = H5O_HASH_UNDEF; + list->messages[list_pos].fheap_id = 0; + list->messages[list_pos].ref_count = 0; /* Just in case */ } else { @@ -973,7 +993,7 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5SM_index_header_t *header, uns */ /* JAMES: there's an off-by-one error here */ /* JAMES: make this a separate function */ - if(header->num_messages < header->btree_to_list) + if(header->index_type == H5SM_BTREE && header->num_messages < header->btree_to_list) { /* Remember the btree address for this index; we'll overwrite the * address in the index header @@ -1037,8 +1057,8 @@ done: * *------------------------------------------------------------------------- */ -herr_t H5SM_get_info(H5F_t *f, unsigned *index_flags, size_t *list_to_btree, - size_t *btree_to_list, hid_t dxpl_id) +herr_t H5SM_get_info(H5F_t *f, unsigned *index_flags, unsigned *minsizes, + size_t *list_to_btree, size_t *btree_to_list, hid_t dxpl_id) { H5SM_master_table_t *table = NULL; haddr_t table_addr; @@ -1070,9 +1090,9 @@ herr_t H5SM_get_info(H5F_t *f, unsigned *index_flags, size_t *list_to_btree, *btree_to_list = table->indexes[0].btree_to_list; /* Get information about the individual SOHM indexes */ - for(i=0; i<table->num_indexes; ++i) - { + for(i=0; i<table->num_indexes; ++i) { index_flags[i] = table->indexes[i].mesg_types; + minsizes[i] = table->indexes[i].min_mesg_size; } done: diff --git a/src/H5SMbtree2.c b/src/H5SMbtree2.c index 666ead7..28401d9 100755 --- a/src/H5SMbtree2.c +++ b/src/H5SMbtree2.c @@ -89,11 +89,12 @@ const H5B2_class_t H5SM_INDEX[1]={{ /* B-tree class information */ herr_t H5SM_message_compare(const H5SM_mesg_key_t *rec1, const H5SM_sohm_t *rec2) { - herr_t hash_diff; + int64_t hash_diff; /* Has to be able to hold two 32-bit values */ herr_t ret_value=0; FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_message_compare) - hash_diff = (herr_t) (rec1->hash - rec2->hash); + hash_diff = rec1->hash; + hash_diff -= rec2->hash; /* If the hash values match, make sure the messages are really the same */ if(0 == hash_diff) { @@ -122,8 +123,13 @@ H5SM_message_compare(const H5SM_mesg_key_t *rec1, const H5SM_sohm_t *rec2) ret_value = HDmemcmp(rec1->encoding, buf2, rec1->encoding_size); } } - else - ret_value = hash_diff; + else { + /* Compress 64-bit hash_diff to fit in an herr_t */ + if(hash_diff > 0) + ret_value = 1; + else + ret_value = -1; + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_message_compare */ @@ -319,9 +325,9 @@ H5SM_incr_ref(void *record, void *op_data, hbool_t *changed) * remove the record from the B-tree even if the refcount * reaches zero. * - * The new refcount is returned through op_data. If this is - * zero, the calling function should remove this record from - * the B-tree. + * The new message is returned through op_data. If its + * reference count is zero, the calling function should + * remove this record from the B-tree. * * Return: Non-negative on success * Negative on failure @@ -345,7 +351,7 @@ H5SM_decr_ref(void *record, void *op_data, hbool_t *changed) *changed = TRUE; if(op_data) - *(hsize_t *)op_data = message->ref_count; + *(H5SM_sohm_t *)op_data = *message; FUNC_LEAVE_NOAPI(SUCCEED) } diff --git a/src/H5SMcache.c b/src/H5SMcache.c index e21757e..70b7b56 100644 --- a/src/H5SMcache.c +++ b/src/H5SMcache.c @@ -139,14 +139,14 @@ H5SM_flush_table(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_ma HDmemcpy(p, H5SM_TABLE_MAGIC, (size_t)H5SM_TABLE_SIZEOF_MAGIC); p += H5SM_TABLE_SIZEOF_MAGIC; - *p++ = H5SM_MASTER_TABLE_VERSION; /* Version */ + *p++ = table->version; /* Version */ /* Encode each index header */ for(x=0; x<table->num_indexes; ++x) { *p++ = table->indexes[x].index_type; /* Is message index a list or a B-tree? */ UINT16ENCODE(p, table->indexes[x].mesg_types); /* Type of messages in the index */ - + UINT32ENCODE(p, table->indexes[x].min_mesg_size); /* Minimum size of message to share */ UINT16ENCODE(p, table->indexes[x].list_to_btree); /* List cutoff; fewer than this number and index becomes a list */ UINT16ENCODE(p, table->indexes[x].btree_to_list); /* B-tree cutoff; more than this number and index becomes a B-tree */ UINT16ENCODE(p, table->indexes[x].num_messages); /* Number of messages shared */ @@ -239,6 +239,7 @@ H5SM_load_table(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1 table->indexes[x].index_type= *p++; /* type of the index (list or B-tree) */ UINT16DECODE(p, table->indexes[x].mesg_types); + UINT32DECODE(p, table->indexes[x].min_mesg_size); UINT16DECODE(p, table->indexes[x].list_to_btree); UINT16DECODE(p, table->indexes[x].btree_to_list); UINT16DECODE(p, table->indexes[x].num_messages); diff --git a/src/H5SMpkg.h b/src/H5SMpkg.h index 752ce84..51c6c1f 100755 --- a/src/H5SMpkg.h +++ b/src/H5SMpkg.h @@ -40,7 +40,7 @@ #define H5SM_SOHM_ENTRY_SIZE(f) (4 /* Hash value */ \ + 4 /* reference count*/ \ - + 8) /* JAMES: size of hash value on disk */ + + 8) /* JAMES: size of heap ID on disk */ #define H5SM_TABLE_SIZE(f) ( H5SM_TABLE_SIZEOF_MAGIC \ + 1 /* Table version */ \ @@ -48,6 +48,7 @@ #define H5SM_INDEX_HEADER_SIZE(f) (1 /* Whether index is a list or B-tree */ \ + 2 /* Type of messages stored in the index */ \ + + 4 /* Minimum size of messages to share */ \ + (3 * 2) /* B-tree cutoff, list cutoff, # of shared messages */ \ + H5F_SIZEOF_ADDR(f) /* Location of list or B-tree */ \ + H5F_SIZEOF_ADDR(f)) /* Address of heap */ @@ -115,6 +116,7 @@ typedef struct { /* Typedef for a SOHM index header */ typedef struct { unsigned mesg_types; /* Bit flag vector of message types */ + size_t min_mesg_size; /* number of messages being tracked */ size_t list_to_btree; /* >= this many messages, index with a B-tree */ size_t btree_to_list; /* <= this many messages, index with a list again */ size_t num_messages; /* number of messages being tracked */ diff --git a/src/H5SMprivate.h b/src/H5SMprivate.h index 5d75213..4430822 100755 --- a/src/H5SMprivate.h +++ b/src/H5SMprivate.h @@ -46,7 +46,7 @@ H5_DLL herr_t H5SM_init(H5F_t *f, H5P_genplist_t *fc_plist, hid_t dxpl_id); H5_DLL htri_t H5SM_try_share(H5F_t *f, hid_t dxpl_id, unsigned type_id, void *mesg); H5_DLL herr_t H5SM_try_delete(H5F_t *f, hid_t dxpl_id, unsigned type_id, const H5O_shared_t *mesg); -H5_DLL herr_t H5SM_get_info(H5F_t *f, unsigned *index_flags, +H5_DLL herr_t H5SM_get_info(H5F_t *f, unsigned *index_flags, unsigned *minsizes, size_t *list_to_btree, size_t *btree_to_list, hid_t dxpl_id); H5_DLL haddr_t H5SM_get_fheap_addr(H5F_t *f, unsigned type_id, hid_t dxpl_id); |