From d8e4fcc4104953c58f6dbc0f92992b3684f70c90 Mon Sep 17 00:00:00 2001 From: James Laird Date: Thu, 11 Jan 2007 14:19:40 -0500 Subject: [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. --- src/H5F.c | 28 ++++------ src/H5Oattr.c | 7 +-- src/H5Ocopy.c | 11 ++-- src/H5Ofill.c | 1 - src/H5Omessage.c | 22 ++++---- src/H5Oprivate.h | 5 +- src/H5Oshared.c | 8 ++- src/H5SM.c | 66 +++++++++++++++++++--- src/H5SMbtree2.c | 59 ------------------- src/H5SMcache.c | 59 ++++++++++--------- src/H5SMpkg.h | 4 -- test/tsohm.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 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; xnum_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; xheader->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; xnum_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() */ -- cgit v0.12