summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5Fsuper.c5
-rw-r--r--src/H5O.c61
-rw-r--r--src/H5Oalloc.c4
-rw-r--r--src/H5Opublic.h2
-rw-r--r--src/H5Oshared.c14
-rw-r--r--src/H5Pfcpl.c20
-rwxr-xr-xsrc/H5SM.c84
-rwxr-xr-xsrc/H5SMbtree2.c22
-rw-r--r--src/H5SMcache.c5
-rwxr-xr-xsrc/H5SMpkg.h4
-rwxr-xr-xsrc/H5SMprivate.h2
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)
diff --git a/src/H5O.c b/src/H5O.c
index 72a5c27..253e535 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -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");
diff --git a/src/H5SM.c b/src/H5SM.c
index 2984805..dd5b1d2 100755
--- a/src/H5SM.c
+++ b/src/H5SM.c
@@ -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);