diff options
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); |