summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Laird <jlaird@hdfgroup.org>2007-01-11 19:19:40 (GMT)
committerJames Laird <jlaird@hdfgroup.org>2007-01-11 19:19:40 (GMT)
commitd8e4fcc4104953c58f6dbc0f92992b3684f70c90 (patch)
tree2c2f9d257a08faeae7c26384ca47bdcafcfebe02
parentba14f838467f787fd4d42185a7e65fc529f84af8 (diff)
downloadhdf5-d8e4fcc4104953c58f6dbc0f92992b3684f70c90.zip
hdf5-d8e4fcc4104953c58f6dbc0f92992b3684f70c90.tar.gz
hdf5-d8e4fcc4104953c58f6dbc0f92992b3684f70c90.tar.bz2
[svn-r13135] Continuing code cleanup.
Moved SOHM table version out of table encoding and completely into superblock. This is a file format change. Added test that extends shared dataspaces. Dynamically allocate arrays in shared message cache code. Clean up comments. Tested on windows, kagiso, smirom.
-rw-r--r--src/H5F.c28
-rw-r--r--src/H5Oattr.c7
-rw-r--r--src/H5Ocopy.c11
-rw-r--r--src/H5Ofill.c1
-rw-r--r--src/H5Omessage.c22
-rw-r--r--src/H5Oprivate.h5
-rw-r--r--src/H5Oshared.c8
-rwxr-xr-xsrc/H5SM.c66
-rwxr-xr-xsrc/H5SMbtree2.c59
-rw-r--r--src/H5SMcache.c59
-rwxr-xr-xsrc/H5SMpkg.h4
-rw-r--r--test/tsohm.c168
12 files changed, 292 insertions, 146 deletions
diff --git a/src/H5F.c b/src/H5F.c
index 847d912..cb809e0 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -895,7 +895,7 @@ static H5F_t *
H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
{
H5F_t *f = NULL, *ret_value;
- unsigned sohm_indexes; /* JAMES: necessary? */
+ unsigned sohm_indexes;
unsigned super_vers = HDF5_SUPERBLOCK_VERSION_DEF;
H5P_genplist_t *plist; /* Property list */
@@ -917,7 +917,7 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
f->shared->base_addr = HADDR_UNDEF;
f->shared->freespace_addr = HADDR_UNDEF;
f->shared->sohm_addr = HADDR_UNDEF;
- f->shared->sohm_vers = 0;
+ f->shared->sohm_vers = HDF5_SHAREDHEADER_VERSION;
f->shared->sohm_nindexes = 0;
f->shared->driver_addr = HADDR_UNDEF;
f->shared->lf = lf;
@@ -954,6 +954,8 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
*/
if(H5P_get(plist, H5F_CRT_SHMSG_NINDEXES_NAME, &sohm_indexes)<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get number of SOHM indexes")
+ HDassert(sohm_indexes < 255);
+ f->shared->sohm_nindexes = sohm_indexes;
if(sohm_indexes > 0) {
super_vers= HDF5_SUPERBLOCK_VERSION_2; /* Super block version 2 */
@@ -1249,9 +1251,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
unsigned tent_flags; /*tentative flags */
H5FD_class_t *drvr; /*file driver class info */
H5P_genplist_t *a_plist; /*file access property list */
- H5P_genplist_t *c_plist; /*file access property list */
H5F_close_degree_t fc_degree; /*file close degree */
- unsigned num_sohm_indexes; /*number of SOHM indexes */
H5F_t *ret_value; /*actual return value */
FUNC_ENTER_NOAPI(H5F_open, NULL)
@@ -1381,19 +1381,15 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
if(H5F_init_superblock(file, dxpl_id) == 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to allocate file superblock")
- /* Create the Shared Object Header Message table and register it with the
- * metadata cache */
- /* JAMES: hack. Should check f->shared directly? */
- if(NULL == (c_plist = H5P_object_verify(fcpl_id,H5P_FILE_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+ /* Create the Shared Object Header Message table and register it with the
+ * metadata cache, if this file supports shared messages */
+ if(file->shared->sohm_nindexes > 0) {
+ H5P_genplist_t *c_plist; /*file creation property list */
+ if(NULL == (c_plist = H5P_object_verify(fcpl_id,H5P_FILE_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
- if(H5P_get(c_plist, H5F_CRT_SHMSG_NINDEXES_NAME, &num_sohm_indexes)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get SOHM information")
-
- if(num_sohm_indexes > 0)
- {
- if(H5SM_init(file, c_plist, dxpl_id) <0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create SOHM table")
+ if(H5SM_init(file, c_plist, dxpl_id) <0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create SOHM table")
}
/* Create and open the root group */
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index 1358147..037239f 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -366,11 +366,7 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg)
UINT16ENCODE(p, attr->dt_size);
UINT16ENCODE(p, attr->ds_size);
- /*
- * Encode the character encoding used for the attribute's name
- * Also add several "reserved" fields to pad to 16 bytes.
- */
- /* JAMES: only do this if flag says to? */
+ /* The character encoding for the attribute's name, in later versions */
if(version >= H5O_ATTR_VERSION_3)
*p++ = attr->encoding;
@@ -873,7 +869,6 @@ H5O_attr_copy_file(H5F_t *file_src, const H5O_msg_class_t UNUSED *mesg_type,
} /* end if */
/* Copy the dataspace for the attribute */
- /* JAMES: does this need to be copy_file? */
attr_dst->ds = H5S_copy(attr_src->ds, FALSE);
HDassert(attr_dst->ds);
diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c
index df8fe01..4e457ac 100644
--- a/src/H5Ocopy.c
+++ b/src/H5Ocopy.c
@@ -579,22 +579,19 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
current_pos = oh_dst->chunk[0].image;
- /* Copy the message header. Most of this will be overwritten when
- * the header is flushed to disk, but later versions have a
- * magic number that isn't.
+ /* Copy the header. Most of this (number of messages, etc.) will be
+ * overwritten when the header is flushed to disk, but later versions have
+ * a magic number that isn't.
*/
HDmemcpy(current_pos, oh_src->chunk[0].image,
(size_t)(H5O_SIZEOF_HDR_OH(oh_dst) - H5O_SIZEOF_CHKSUM_OH(oh_dst)));
current_pos += H5O_SIZEOF_HDR_OH(oh_dst) - H5O_SIZEOF_CHKSUM_OH(oh_dst);
- /* JAMES: include this in loop above? Doesn't take deleted messages
- * into account
- */
/* Copy each message that wasn't dirtied above */
null_msgs = 0;
for(mesgno = 0; mesgno < oh_dst->nmesgs; mesgno++) {
/* Skip any deleted or NULL messages in the source unless the
- * preserve_null flag is set
+ * preserve_null flag is set.
*/
if(FALSE == cpy_info->preserve_null) {
while(deleted[mesgno + null_msgs]) {
diff --git a/src/H5Ofill.c b/src/H5Ofill.c
index 78b5c77..73732b2 100644
--- a/src/H5Ofill.c
+++ b/src/H5Ofill.c
@@ -634,7 +634,6 @@ H5O_fill_new_free (void *mesg)
HDassert(mesg);
- /* JAMES: should this free the O_loc? */
H5FL_FREE(H5O_fill_new_t, mesg);
FUNC_LEAVE_NOAPI(SUCCEED)
diff --git a/src/H5Omessage.c b/src/H5Omessage.c
index bcb3e6e..e1ae146 100644
--- a/src/H5Omessage.c
+++ b/src/H5Omessage.c
@@ -441,11 +441,13 @@ H5O_msg_write_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type,
* though, and that the library doesn't try to reset the current
* message like it would in a normal overwrite (this message is
* realy a shared pointer, not a real message).
- * JAMES: will this break if a shared message is overwritten with a larger
- * non-shared message?
+ *
+ * Note that this only works when shared messages are replaced by other
+ * shared messages. Currently, messages can't shrink once they've
+ * been written to object headers so this is a safe assumption (for
+ * now).
*/
- HDassert(H5O_msg_is_shared(type->id, mesg) > 0); /* JAMES: this should work with
- * replacement messages that aren't shared, too. */
+ HDassert(H5O_msg_is_shared(type->id, mesg) > 0);
/* Extract shared message info from current message */
if(NULL == H5O_msg_get_share(type->id, mesg, &sh_mesg))
@@ -2007,9 +2009,10 @@ done:
*
* Purpose: Calls a message's delete callback.
*
- * JAMES: this is mostly redundant with H5O_delete_mesg below,
+ * This is mostly redundant with H5O_delete_mesg below,
* but H5O_delete_mesg only works on messages in object headers
- * (i.e., not shared messages).
+ * (while the shared message code needs to delete messages in
+ * the heap).
*
* Return: Success: Non-negative
* Failure: Negative
@@ -2084,11 +2087,10 @@ H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg, hbool_t adj_link)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message")
} /* end if */
- /* Check if this message needs to be removed from the SOHM table */
- /* JAMES: there should be a callback, maybe in H5O_shared_delete, to fiddle w/ the ref. count.
- * We shouldn't need to do a search in the SOHM table on delete. */
+ /* Check if this message needs to be removed from the SOHM table if
+ * it's a shared message.
+ */
if(type == H5O_MSG_SHARED) {
- /* 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")
} /* end if */
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 2d555e8..f40d28e 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -135,11 +135,14 @@ typedef struct H5O_copy_t {
* Shared object message.
* This needs to go first because other messages can be shared and
* include a H5O_shared_t struct
+ * The oloc shouldn't ever be holding open a file; if it ever is (if
+ * H5O_loc_hold_file was ever called on it) it won't be closed properly,
+ * since shared messages don't close their olocs.
*/
typedef struct H5O_shared_t {
unsigned flags; /* flags describing how message is shared */
union {
- H5O_loc_t oloc; /*object location info */
+ H5O_loc_t oloc; /* object location info */
H5SM_fheap_id_t heap_id; /* ID within the SOHM heap */
} u;
} H5O_shared_t;
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index eef0bd8..d665742 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -207,8 +207,7 @@ done:
* reference count is stored in the file-wide shared message
* index and is changed in a different place in the code.
*
- * Return: Success: New link count
- *
+ * Return: Success: New link count, or 1 for messages in heap
* Failure: Negative
*
* Programmer: Quincey Koziol
@@ -245,8 +244,11 @@ H5O_shared_link_adj(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared, int adj
}
else
{
+ /* Messages in the heap don't have file object ref counts; they
+ * return 1 as a dummy value.
+ */
HDassert(shared->flags & H5O_SHARED_IN_HEAP_FLAG);
- ret_value = 1; /* JAMES temp refcount*/
+ ret_value = 1;
}
done:
diff --git a/src/H5SM.c b/src/H5SM.c
index 40e47c7..94d1d67 100755
--- a/src/H5SM.c
+++ b/src/H5SM.c
@@ -157,10 +157,6 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, hid_t dxpl_id)
*/
HDassert(num_indexes < 256);
table->num_indexes = num_indexes;
- table->version = H5SM_MASTER_TABLE_VERSION;
-
- f->shared->sohm_nindexes = table->num_indexes;
- f->shared->sohm_vers = table->version;
/* Check that list and btree cutoffs make sense. There can't be any
* values greater than the list max but less than the btree min; the
@@ -463,9 +459,6 @@ H5SM_create_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id)
}
/* Create a heap to hold the shared messages that the list or B-tree will index */
- /* JAMES: this should happen first, so that the list/btree size can scale depending
- * on how big a heap pointer is.
- */
HDmemset(&fheap_cparam, 0, sizeof(fheap_cparam));
fheap_cparam.managed.width = H5SM_FHEAP_MAN_WIDTH;
fheap_cparam.managed.start_block_size = H5SM_FHEAP_MAN_START_BLOCK_SIZE;
@@ -828,6 +821,7 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, unsigned type_id, void *mesg)
HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL, "can't tell if datatype is immutable")
/* Don't share committed datatypes */
+ /* JAMES: Quincey says this check isn't working! */
if((tri_ret = H5T_committed((H5T_t*) mesg)) > 0)
HGOTO_DONE(FALSE)
else if(tri_ret < 0)
@@ -1421,6 +1415,64 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5SM_message_encode
+ *
+ * Purpose: Serialize a H5SM_sohm_t struct into a buffer RAW.
+ *
+ * Return: Non-negative on success
+ * Negative on failure
+ *
+ * Programmer: James Laird
+ * Monday, November 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5SM_message_encode(const H5F_t UNUSED *f, uint8_t *raw, const void *_nrecord)
+{
+ const H5SM_sohm_t *message = (const H5SM_sohm_t *)_nrecord;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_message_encode)
+
+ /* Encode the SOHM's fields */
+ UINT32ENCODE(raw, message->hash);
+ UINT32ENCODE(raw, message->ref_count);
+ UINT64ENCODE(raw, message->fheap_id);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5SM_message_encode */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5SM_message_decode
+ *
+ * Purpose: Read an encoded SOHM message from RAW into an H5SM_sohm_t struct.
+ *
+ * Return: Non-negative on success
+ * Negative on failure
+ *
+ * Programmer: James Laird
+ * Monday, November 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5SM_message_decode(const H5F_t UNUSED *f, const uint8_t *raw, void *_nrecord)
+{
+ H5SM_sohm_t *message = (H5SM_sohm_t *)_nrecord;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_message_decode)
+
+ /* Encode the SOHM's fields */
+ UINT32DECODE(raw, message->hash);
+ UINT32DECODE(raw, message->ref_count);
+ UINT64DECODE(raw, message->fheap_id);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5SM_message_decode */
+
+
+/*-------------------------------------------------------------------------
* Function: H5SM_reconstitute
*
* Purpose: Reconstitute a shared object header message structure from
diff --git a/src/H5SMbtree2.c b/src/H5SMbtree2.c
index c6b0aa2..1b5cb98 100755
--- a/src/H5SMbtree2.c
+++ b/src/H5SMbtree2.c
@@ -244,65 +244,6 @@ H5SM_btree_retrieve(void *udata, const void *native)
/*-------------------------------------------------------------------------
- * Function: H5SM_message_encode
- *
- * Purpose: Serialize the SOHM message.
- *
- * Return: Non-negative on success
- * Negative on failure
- *
- * Programmer: James Laird
- * Monday, November 6, 2006
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5SM_message_encode(const H5F_t UNUSED *f, uint8_t *raw, const void *_nrecord)
-{
- const H5SM_sohm_t *message = (const H5SM_sohm_t *)_nrecord;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_message_encode)
-
- /* Encode the SOHM's fields */
- UINT32ENCODE(raw, message->hash);
- UINT32ENCODE(raw, message->ref_count);
- UINT64ENCODE(raw, message->fheap_id);
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_message_encode */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5SM_message_decode
- *
- * Purpose: Read an encoded SOHM message into an H5SM_sohm_t struct.
- *
- * Return: Non-negative on success
- * Negative on failure
- *
- * Programmer: James Laird
- * Monday, November 6, 2006
- *
- *-------------------------------------------------------------------------
- */
-/* JAMES: move to H5SM.c or something */
-herr_t
-H5SM_message_decode(const H5F_t UNUSED *f, const uint8_t *raw, void *_nrecord)
-{
- H5SM_sohm_t *message = (H5SM_sohm_t *)_nrecord;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_message_decode)
-
- /* Encode the SOHM's fields */
- UINT32DECODE(raw, message->hash);
- UINT32DECODE(raw, message->ref_count);
- UINT64DECODE(raw, message->fheap_id);
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SM_message_decode */
-
-
-/*-------------------------------------------------------------------------
* Function: H5SM_btree_debug
*
* Purpose: Print debugging information for a H5SM_sohm_t.
diff --git a/src/H5SMcache.c b/src/H5SMcache.c
index c79c7d6..1031a5c 100644
--- a/src/H5SMcache.c
+++ b/src/H5SMcache.c
@@ -104,6 +104,7 @@ const H5AC_class_t H5AC_SOHM_LIST[1] = {{
static herr_t
H5SM_flush_table(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_master_table_t *table)
{
+ uint8_t *buf=NULL; /* Temporary buffer */
herr_t ret_value=SUCCEED;
FUNC_ENTER_NOAPI(H5SM_flush_table, FAIL)
@@ -114,7 +115,6 @@ H5SM_flush_table(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_ma
HDassert(table);
if(table->cache_info.is_dirty) {
- uint8_t *buf; /* Temporary buffer */
uint8_t *p; /* Pointer into raw data buffer */
size_t size; /* Header size on disk */
uint32_t computed_chksum; /* Computed metadata checksum value */
@@ -134,8 +134,6 @@ 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++ = table->version; /* Version */
-
/* Encode each index header */
for(x=0; x<table->num_indexes; ++x) {
*p++ = H5SM_LIST_VERSION; /* Encode version for this list. */
@@ -161,8 +159,6 @@ H5SM_flush_table(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_ma
table->cache_info.is_dirty = FALSE;
- /* Free buffer */
- H5MM_xfree(buf);
} /* end if */
if(destroy)
@@ -170,6 +166,9 @@ H5SM_flush_table(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_ma
HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy sohm table")
done:
+ /* Free buffer if allocated */
+ buf = H5MM_xfree(buf);
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_flush_table */
@@ -208,7 +207,6 @@ H5SM_load_table(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1
/* Read number of indexes and version from file superblock */
table->num_indexes = f->shared->sohm_nindexes;
- table->version = f->shared->sohm_vers;
HDassert(addr == f->shared->sohm_addr);
HDassert(addr != HADDR_UNDEF);
@@ -219,8 +217,8 @@ H5SM_load_table(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1
*/
table_size = H5SM_TABLE_SIZE(f) + (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f));
- /* Allocate temporary buffer */
- if(NULL == (buf = HDmalloc(table_size)))
+ /* Allocate temporary buffer */ /* JAMES: FL_BLK? */
+ if(NULL == (buf = H5MM_malloc(table_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Read header from disk */
@@ -234,10 +232,6 @@ H5SM_load_table(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1
HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM table signature");
p += H5SM_TABLE_SIZEOF_MAGIC;
- /* Version number */
- if (table->version != *p++)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "wrong SOHM table version number")
-
/* Don't count the checksum in the table size yet, since it comes after
* all of the index headers
*/
@@ -278,9 +272,8 @@ H5SM_load_table(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1
ret_value = table;
done:
- /* Free buffer if it was allocated */
- if(buf)
- HDfree(buf);
+ /* Free buffer if allocated */
+ buf = H5MM_xfree(buf);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_load_table */
@@ -397,6 +390,7 @@ H5SM_table_size(const H5F_t *f, const H5SM_master_table_t *table, size_t *size_p
static herr_t
H5SM_flush_list(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_list_t *list)
{
+ uint8_t *buf=NULL; /* Temporary buffer */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5SM_flush_list, FAIL)
@@ -408,18 +402,19 @@ H5SM_flush_list(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_lis
HDassert(list->header);
if (list->cache_info.is_dirty) {
- uint8_t buf[H5F_LISTBUF_SIZE]; /* Temporary buffer */ /* JAMES Do I need to use H5FL_BLK_MALLOC instead? */
uint8_t *p; /* Pointer into raw data buffer */
size_t size; /* Header size on disk */
uint32_t computed_chksum; /* Computed metadata checksum value */
hsize_t x;
hsize_t mesgs_written;
- /* JAMES: consider only writing as many messages as necessary, and then adding a
- * blank "end of list" message or something?
- */
size = H5SM_LIST_SIZE(f, list->header->num_messages);
+ /* Allocate temporary buffer */
+ /* JAMES: is BLK_MALLOC somehow better for this? */
+ if(NULL == (buf = H5MM_malloc(size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
/* Encode the list */
p = buf;
@@ -431,12 +426,11 @@ H5SM_flush_list(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_lis
mesgs_written = 0;
for(x=0; x<list->header->list_max && mesgs_written < list->header->num_messages; x++) {
if(list->messages[x].ref_count > 0) {
- /* JAMES: use H5SM_message_encode here */
- UINT32ENCODE(p, list->messages[x].hash); /* Read the hash value for this message */
- UINT32ENCODE(p, list->messages[x].ref_count); /* Read the reference count for this message */
- UINT64ENCODE(p, list->messages[x].fheap_id); /* Get the heap ID for the message */
+ if(H5SM_message_encode(f, p, &(list->messages[x]))< 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to write shared message to disk")
- ++mesgs_written;
+ p+=H5SM_SOHM_ENTRY_SIZE(f);
+ ++mesgs_written;
}
}
@@ -459,6 +453,9 @@ H5SM_flush_list(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_lis
HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy list")
done:
+ /* Free buffer if allocated */
+ buf = H5MM_xfree(buf);
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_flush_list */
@@ -509,7 +506,7 @@ H5SM_load_list(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1,
/* Allocate temporary buffer */
/* JAMES: is BLK_MALLOC somehow better for this? */
- if(NULL == (buf = HDmalloc(size)))
+ if(NULL == (buf = H5MM_malloc(size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Read list from disk */
@@ -519,15 +516,15 @@ H5SM_load_list(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1,
/* Check magic number */
if(HDmemcmp(p, H5SM_LIST_MAGIC, (size_t)H5SM_LIST_SIZEOF_MAGIC))
- HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM list signature");
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM list signature");
p += H5SM_LIST_SIZEOF_MAGIC;
/* Read messages into the list array */
for(x=0; x<header->num_messages; x++)
{
- UINT32DECODE(p, list->messages[x].hash); /* Read the hash value for this message */
- UINT32DECODE(p, list->messages[x].ref_count); /* Read the reference count for this message */
- UINT64DECODE(p, list->messages[x].fheap_id); /* Get the heap ID for the message */
+ if(H5SM_message_decode(f, p, &(list->messages[x])) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "can't decode shared message");
+ p += H5SM_SOHM_ENTRY_SIZE(f);
}
/* Read in checksum */
@@ -553,8 +550,8 @@ H5SM_load_list(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1,
ret_value = list;
done:
- if(buf)
- HDfree(buf);
+ /* Free buffer if allocated */
+ buf = H5MM_xfree(buf);
if(ret_value == NULL) {
if(list) {
diff --git a/src/H5SMpkg.h b/src/H5SMpkg.h
index b771893..37a40a1 100755
--- a/src/H5SMpkg.h
+++ b/src/H5SMpkg.h
@@ -37,14 +37,11 @@
#define H5SM_TABLE_SIZEOF_MAGIC 4
#define H5SM_SIZEOF_CHECKSUM 4
-#define H5SM_MASTER_TABLE_VERSION 0 /* Version of the Shared Object Header Message Master Table*/
-
#define H5SM_SOHM_ENTRY_SIZE(f) (4 /* Hash value */ \
+ 4 /* reference count*/ \
+ sizeof(H5SM_fheap_id_t)) /* size of heap ID on disk */
#define H5SM_TABLE_SIZE(f) ( H5SM_TABLE_SIZEOF_MAGIC \
- + 1 /* Table version */ \
+ H5SM_SIZEOF_CHECKSUM) /* Checksum */
#define H5SM_INDEX_HEADER_SIZE(f) (1 /* Whether index is a list or B-tree */ \
@@ -145,7 +142,6 @@ typedef struct {
/* Information for H5AC cache functions, _must_ be first field in structure */
H5AC_info_t cache_info;
- unsigned version; /* Version of the table struct */
uint8_t num_indexes; /* Number of indexes */
H5SM_index_header_t *indexes; /* Array of num_indexes indexes */
} H5SM_master_table_t;
diff --git a/test/tsohm.c b/test/tsohm.c
index 9fcbf41..4fe2d8b 100644
--- a/test/tsohm.c
+++ b/test/tsohm.c
@@ -3038,6 +3038,172 @@ test_sohm_extlink(void)
}
+/*-------------------------------------------------------------------------
+ * Function: test_sohm_extend_dset_helper
+ *
+ * Purpose: Tests extending a dataset's dataspace.
+ *
+ * Programmer: James Laird
+ * Wednesday, January 10, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void test_sohm_extend_dset_helper(hid_t fcpl_id)
+{
+ hid_t file_id = -1;
+ hid_t space_id = -1;
+ hid_t dcpl_id = -1;
+ hid_t dset_id = -1;
+ hsize_t dims1[] = {1, 2};
+ hsize_t max_dims1[] = {H5S_UNLIMITED, 2};
+ hsize_t dims2[] = {5, 2};
+ long data[10] = {0};
+ herr_t ret;
+
+ /* Create file */
+ file_id = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
+ CHECK_I(file_id, "H5Fcreate");
+
+ /* Create property list with chunking */
+ dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
+ CHECK_I(dcpl_id, "H5Pcreate");
+ ret = H5Pset_chunk(dcpl_id, 2, dims1);
+ CHECK_I(ret, "H5Pset_chunk");
+
+ /* Create a dataspace and a dataset*/
+ space_id = H5Screate_simple(2, dims1, max_dims1);
+ CHECK_I(space_id, "H5Screate_simple");
+ dset_id = H5Dcreate(file_id, "dataset", H5T_NATIVE_LONG, space_id, dcpl_id);
+ CHECK_I(dset_id, "H5Dcreate");
+
+ /* Extend the dataset */
+ ret = H5Dextend(dset_id, dims2);
+ CHECK_I(ret, "H5Dclose");
+
+ /* Write some garbage to the dataset */
+ ret = H5Dwrite(dset_id, H5T_NATIVE_LONG, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
+ CHECK_I(ret, "H5Dwrite");
+
+ /* Close the dataset and file */
+ ret = H5Dclose(dset_id);
+ CHECK_I(ret, "H5Dclose");
+ ret = H5Fclose(file_id);
+ CHECK_I(ret, "H5Fclose");
+
+
+ /* Create a new dataset in a new file, but this time close it before
+ * extending it to make sure that the old dataspace is written to
+ * disk.
+ */
+ file_id = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT);
+ CHECK_I(file_id, "H5Fcreate");
+ dset_id = H5Dcreate(file_id, "dataset", H5T_NATIVE_LONG, space_id, dcpl_id);
+ CHECK_I(dset_id, "H5Dcreate");
+
+ /* Close and re-open file and dataset */
+ ret = H5Dclose(dset_id);
+ CHECK_I(ret, "H5Dclose");
+ ret = H5Fclose(file_id);
+ CHECK_I(ret, "H5Fclose");
+
+ file_id = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
+ CHECK_I(file_id, "H5Fopen");
+ dset_id = H5Dopen(file_id, "dataset");
+ CHECK_I(dset_id, "H5Dopen");
+
+ /* Extend the dataset */
+ ret = H5Dextend(dset_id, dims2);
+ CHECK_I(ret, "H5Dclose");
+
+ /* Write some garbage to the dataset */
+ ret = H5Dwrite(dset_id, H5T_NATIVE_LONG, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
+ CHECK_I(ret, "H5Dwrite");
+
+ /* Close the dataset and file */
+ ret = H5Dclose(dset_id);
+ CHECK_I(ret, "H5Dclose");
+ ret = H5Fclose(file_id);
+ CHECK_I(ret, "H5Fclose");
+
+ /* Cleanup */
+ ret = H5Sclose(space_id);
+ CHECK_I(ret, "H5Sclose");
+ ret = H5Pclose(dcpl_id);
+ CHECK_I(ret, "H5Pclose");
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_sohm_extend_dset
+ *
+ * Purpose: Test extended shared dataspaces. An extended dataset's
+ * dataspace will change, possibly confusing the shared message
+ * code.
+ *
+ * Programmer: James Laird
+ * Wednesday, January 10, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+test_sohm_extend_dset(void)
+{
+ hid_t fcpl_id = -1;
+ herr_t ret;
+
+ /* Create fcpl */
+ fcpl_id = H5Pcreate(H5P_FILE_CREATE);
+ CHECK_I(fcpl_id, "H5Pcreate");
+
+ /* Test extending datasets with different FCPLs */
+ ret = H5Pset_shared_mesg_nindexes(fcpl_id, 1);
+ CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
+
+ /* No shared messages */
+ test_sohm_extend_dset_helper(fcpl_id);
+
+
+ /* Only dataspaces */
+ ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_MESG_SDSPACE_FLAG, 16);
+ CHECK_I(ret, "H5Pset_shared_mesg_index");
+
+ test_sohm_extend_dset_helper(fcpl_id);
+
+ /* All messages */
+ ret = H5Pset_shared_mesg_nindexes(fcpl_id, 1);
+ CHECK_I(ret, "H5Pset_shared_mesg_nindexes");
+ ret = H5Pset_shared_mesg_index(fcpl_id, 0, H5O_MESG_ALL_FLAG, 16);
+ CHECK_I(ret, "H5Pset_shared_mesg_index");
+
+ test_sohm_extend_dset_helper(fcpl_id);
+
+
+ /* All messages in lists */
+ ret = H5Pset_shared_mesg_phase_change(fcpl_id, 100, 50);
+ CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
+
+ test_sohm_extend_dset_helper(fcpl_id);
+
+
+ /* All messages in lists converted to B-trees */
+ ret = H5Pset_shared_mesg_phase_change(fcpl_id, 1, 0);
+ CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
+
+ test_sohm_extend_dset_helper(fcpl_id);
+
+
+ /* All messages in B-trees */
+ ret = H5Pset_shared_mesg_phase_change(fcpl_id, 0, 0);
+ CHECK_I(ret, "H5Pset_shared_mesg_phase_change");
+
+ test_sohm_extend_dset_helper(fcpl_id);
+}
+
+
/****************************************************************
**
@@ -3061,7 +3227,7 @@ test_sohm(void)
test_sohm_delete_revert(); /* Test that a file with SOHMs becomes an
* empty file again when they are deleted. */
test_sohm_extlink(); /* Test SOHMs when external links are used */
- /* JAMES: try extending dataspaces, overwriting attributes */
+ test_sohm_extend_dset(); /* Test extending shared datasets */
} /* test_sohm() */