summaryrefslogtreecommitdiffstats
path: root/src/H5O.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2003-10-05 21:12:26 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2003-10-05 21:12:26 (GMT)
commitb8201120fc7547b912222f22a41193921a0c003a (patch)
treeb9dc0099e8c7c4d5899216969be95ff20e6d394f /src/H5O.c
parentb6be270f1fc2d8af09b0986e9f792f0af44a4ae6 (diff)
downloadhdf5-b8201120fc7547b912222f22a41193921a0c003a.zip
hdf5-b8201120fc7547b912222f22a41193921a0c003a.tar.gz
hdf5-b8201120fc7547b912222f22a41193921a0c003a.tar.bz2
[svn-r7538] Purpose:
Bug fixes and code cleanup Description: Lots of changes here: - Fixed bug #691 - when shared datatypes are used in attributes they are incorrectly copied into the attribute instead of referring the the named datatype in the file. This required bumping the version of the attribute message. The new version of the attribute message is only written out when a shared datatype is used in the attribute. [Also, this format change made the size of the attribute smaller.] - Added information to attribute debugging routine so that shared datatypes are displayed correctly with the h5debug tool. - Refactored the H5O* routines to extract code that was common to several routines into subroutines to call. - Added 'link' method for H5O message sub-classes, which increments the link count on shared objects when a message is created which shares them. - Corrected [unreported] bug where the link count was not being decremented on the shared object when a object header message with a reference to that object was deleted from the file. - Reduced size of shared message from 49 bytes (which was incorrect anyway and should have been 48 bytes) to 10 bytes, which required bumping the version of "shared" messages. - Refactored some of the shared datatype routines to allow for easier queries of "committedness" internally to the library and also added routine to easily increment/decrement the reference count of a shared datatype. Platforms tested: FreeBSD 4.9 (sleipnir) h5committest
Diffstat (limited to 'src/H5O.c')
-rw-r--r--src/H5O.c500
1 files changed, 276 insertions, 224 deletions
diff --git a/src/H5O.c b/src/H5O.c
index f436e29..d9ef4ff 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -49,15 +49,12 @@
static herr_t H5O_init(H5F_t *f, hid_t dxpl_id, size_t size_hint,
H5G_entry_t *ent/*out*/, haddr_t header);
static herr_t H5O_reset_real(const H5O_class_t *type, void *native);
-static void * H5O_free_real(const H5O_class_t *type, void *mesg);
static void * H5O_copy_real(const H5O_class_t *type, const void *mesg,
void *dst);
static int H5O_count_real (H5G_entry_t *ent, const H5O_class_t *type,
hid_t dxpl_id);
static htri_t H5O_exists_real(H5G_entry_t *ent, const H5O_class_t *type,
int sequence, hid_t dxpl_id);
-static void * H5O_read_real(H5G_entry_t *ent, const H5O_class_t *type,
- int sequence, void *mesg, hid_t dxpl_id);
#ifdef NOT_YET
static herr_t H5O_share(H5F_t *f, hid_t dxpl_id, const H5O_class_t *type, const void *mesg,
H5HG_t *hobj/*out*/);
@@ -76,6 +73,12 @@ static unsigned H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type,
static unsigned H5O_alloc_extend_chunk(H5O_t *oh, unsigned chunkno, size_t size);
static unsigned H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size);
static herr_t H5O_delete_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh);
+static herr_t H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg);
+static unsigned H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags,
+ const H5O_class_t *orig_type, const void *orig_mesg, H5O_shared_t *sh_mesg,
+ const H5O_class_t **new_type, const void **new_mesg, hid_t dxpl_id);
+static herr_t H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_class_t *type,
+ const void *mesg, unsigned flags);
/* Metadata cache callbacks */
static H5O_t *H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata1,
@@ -119,7 +122,7 @@ static const H5O_class_t *const message_type_g[] = {
H5O_ATTR, /*0x000C Attribute list */
H5O_NAME, /*0x000D Object name */
H5O_MTIME, /*0x000E Object modification date and time */
- NULL, /*0x000F Shared header message */
+ H5O_SHARED, /*0x000F Shared header message */
H5O_CONT, /*0x0010 Object header continuation */
H5O_STAB, /*0x0011 Symbol table */
H5O_MTIME_NEW, /*0x0012 New Object modification date and time */
@@ -582,7 +585,8 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
/* decode next object header continuation message */
for (chunk_addr = HADDR_UNDEF; !H5F_addr_defined(chunk_addr) && curmesg < oh->nmesgs; ++curmesg) {
if (H5O_CONT_ID == oh->mesg[curmesg].type->id) {
- H5O_cont_t *cont = NULL;
+ H5O_cont_t *cont;
+
cont = (H5O_CONT->decode) (f, dxpl_id, oh->mesg[curmesg].raw, NULL);
oh->mesg[curmesg].native = cont;
chunk_addr = cont->addr;
@@ -1003,8 +1007,7 @@ H5O_free (hid_t type_id, void *mesg)
assert(type);
/* Call the "real" free routine */
- if((ret_value=H5O_free_real(type, mesg))==NULL)
- HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to free object header");
+ ret_value=H5O_free_real(type, mesg);
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -1028,7 +1031,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static void *
+void *
H5O_free_real(const H5O_class_t *type, void *mesg)
{
void * ret_value=NULL; /* Return value */
@@ -1156,7 +1159,7 @@ done:
*-------------------------------------------------------------------------
*/
int
-H5O_link(H5G_entry_t *ent, int adjust, hid_t dxpl_id)
+H5O_link(const H5G_entry_t *ent, int adjust, hid_t dxpl_id)
{
H5O_t *oh = NULL;
hbool_t deleted=FALSE; /* Whether the object was deleted as a result of this action */
@@ -1505,7 +1508,7 @@ done:
* actually destroys the object in the cache.
*-------------------------------------------------------------------------
*/
-static void *
+void *
H5O_read_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, void *mesg, hid_t dxpl_id)
{
H5O_t *oh = NULL;
@@ -1548,28 +1551,9 @@ H5O_read_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, void *mes
* message in the global heap or some other object header.
*/
H5O_shared_t *shared;
- void *tmp_buf, *tmp_mesg;
shared = (H5O_shared_t *)(oh->mesg[idx].native);
- if (shared->in_gh) {
- if (NULL==(tmp_buf = H5HG_read (ent->file, dxpl_id, &(shared->u.gh), NULL)))
- HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL, "unable to read shared message from global heap");
- tmp_mesg = (type->decode)(ent->file, dxpl_id, tmp_buf, shared);
- tmp_buf = H5MM_xfree (tmp_buf);
- if (!tmp_mesg)
- HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL, "unable to decode object header shared message");
- if (mesg) {
- HDmemcpy (mesg, tmp_mesg, type->native_size);
- H5MM_xfree (tmp_mesg);
- } else {
- ret_value = tmp_mesg;
- }
- } else {
- ret_value = H5O_read_real(&(shared->u.ent), type, 0, mesg, dxpl_id);
- if (type->set_share &&
- (type->set_share)(ent->file, ret_value, shared)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, "unable to set sharing information");
- }
+ ret_value=H5O_shared_read(ent->file,dxpl_id,shared,type,mesg);
} else {
/*
* The message is not shared, but rather exists in the object
@@ -1590,7 +1574,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5O_find_in_ohdr
+ * Function: H5O_find_in_ohdr
*
* Purpose: Find a message in the object header without consulting
* a symbol table entry.
@@ -1622,6 +1606,7 @@ H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t **type_p,
/* Check args */
assert(f);
+ assert(oh);
assert(type_p);
/* Scan through the messages looking for the right one */
@@ -1789,7 +1774,6 @@ H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
int sequence;
unsigned idx; /* Index of message to modify */
H5O_mesg_t *idx_msg; /* Pointer to message to modify */
- size_t size=0;
H5O_shared_t sh_mesg;
int ret_value;
@@ -1815,64 +1799,24 @@ H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
continue;
if (++sequence == overwrite)
break;
- }
+ } /* end for */
/* Was the right message found? */
- if (overwrite >= 0 &&
- (idx >= oh->nmesgs || sequence != overwrite)) {
-
+ if (overwrite >= 0 && (idx >= oh->nmesgs || sequence != overwrite)) {
/* But can we insert a new one with this sequence number? */
- if (overwrite == sequence + 1) {
+ if (overwrite == sequence + 1)
overwrite = -1;
- } else {
+ else
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message not found");
- }
- }
+ } /* end if */
+
+ /* Check for creating new message */
if (overwrite < 0) {
- /* Allocate space for the new message */
- if (flags & H5O_FLAG_SHARED) {
- HDmemset(&sh_mesg,0,sizeof(H5O_shared_t));
-
- if (NULL==type->get_share)
- HGOTO_ERROR (H5E_OHDR, H5E_UNSUPPORTED, FAIL, "message class is not sharable");
- if ((type->get_share)(ent->file, mesg, &sh_mesg/*out*/)<0) {
- /*
- * If the message isn't shared then turn off the shared bit
- * and treat it as an unshared message.
- */
- H5E_clear (NULL);
- flags &= ~H5O_FLAG_SHARED;
- } else if (sh_mesg.in_gh) {
- /*
- * The shared message is stored in the global heap.
- * Increment the reference count on the global heap message.
- */
- if (H5HG_link (ent->file, dxpl_id, &(sh_mesg.u.gh), 1)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
- size = (H5O_SHARED->raw_size)(ent->file, &sh_mesg);
- } else {
- /*
- * The shared message is stored in some other object header.
- * The other object header must be in the same file as the
- * new object header. Increment the reference count on that
- * object header.
- */
- if (sh_mesg.u.ent.file->shared != ent->file->shared)
- HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "interfile hard links are not allowed");
- if (H5O_link (&(sh_mesg.u.ent), 1, dxpl_id)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
- size = (H5O_SHARED->raw_size)(ent->file, &sh_mesg);
- }
- }
- /* This can't be an 'else' statement due to the possibility of the shared bit getting turned off above */
- if (0== (flags & H5O_FLAG_SHARED)) {
- size = (type->raw_size) (ent->file, mesg);
- if (size>=H5O_MAX_SIZE)
- HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL, "object header message is too large (16k max)");
- }
- idx = H5O_alloc(ent->file, oh, type, size);
- if (idx == UFAIL)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for message");
+ /* Create a new message */
+ if((idx=H5O_new_mesg(ent->file,oh,&flags,type,mesg,&sh_mesg,&type,&mesg,dxpl_id))==UFAIL)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create new message");
+
+ /* Set the correct sequence number for the message created */
sequence++;
} else if (oh->mesg[idx].flags & H5O_FLAG_CONSTANT) {
@@ -1881,30 +1825,14 @@ H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify shared (constant) message");
}
- /* Set pointer to the correct message */
- idx_msg=&oh->mesg[idx];
-
- /* Copy the native value into the object header */
- if (flags & H5O_FLAG_SHARED) {
- if (NULL==(idx_msg->native = H5MM_malloc (sizeof (H5O_shared_t))))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDmemcpy(idx_msg->native,&sh_mesg,sizeof(H5O_shared_t));
- } else {
- if (idx_msg->native)
- H5O_reset_real(idx_msg->type, idx_msg->native);
- idx_msg->native = (type->copy) (mesg, idx_msg->native);
- if (NULL == idx_msg->native)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy message to object header");
- }
+ /* Write the information to the message */
+ if(H5O_write_mesg(oh,idx,type,mesg,flags)<0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to write message");
/* Update the modification time message if any */
if(update_time)
H5O_touch_oh(ent->file, oh, FALSE);
- idx_msg->flags = flags;
- idx_msg->dirty = TRUE;
- oh->cache_info.dirty = TRUE;
-
/* Set return value */
ret_value = sequence;
@@ -2007,13 +1935,6 @@ done:
* Purpose: Simplified version of H5O_modify, used when creating a new
* object header message (usually during object creation)
*
- * Modifies an existing message or creates a new message.
- * The cache fields in that symbol table entry ENT are *not*
- * updated, you must do that separately because they often
- * depend on multiple object header messages. Besides, we
- * don't know which messages will be constant and which will
- * not.
- *
* Return: Success: The sequence number of the message that
* was created.
*
@@ -2064,13 +1985,6 @@ done:
* Purpose: Simplified version of H5O_modify, used when creating a new
* object header message (usually during object creation)
*
- * Modifies an existing message or creates a new message.
- * The cache fields in that symbol table entry ENT are *not*
- * updated, you must do that separately because they often
- * depend on multiple object header messages. Besides, we
- * don't know which messages will be constant and which will
- * not.
- *
* Return: Success: The sequence number of the message that
* was created.
*
@@ -2089,8 +2003,6 @@ H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t *type,
unsigned flags, const void *mesg)
{
unsigned idx; /* Index of message to modify */
- H5O_mesg_t *idx_msg; /* Pointer to message to modify */
- size_t size=0;
H5O_shared_t sh_mesg;
int ret_value = FAIL;
@@ -2103,76 +2015,143 @@ H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t *type,
assert(0==(flags & ~H5O_FLAG_BITS));
assert(mesg);
- /* Allocate space for the new message */
- if (flags & H5O_FLAG_SHARED) {
- HDmemset(&sh_mesg,0,sizeof(H5O_shared_t));
+ /* Create a new message */
+ if((idx=H5O_new_mesg(f,oh,&flags,type,mesg,&sh_mesg,&type,&mesg,dxpl_id))==UFAIL)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create new message");
+
+ /* Write the information to the message */
+ if(H5O_write_mesg(oh,idx,type,mesg,flags)<0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to write message");
+
+ /* Set return value */
+ ret_value = idx;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_append_real () */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_new_mesg
+ *
+ * Purpose: Create a new message in an object header
+ *
+ * Return: Success: Index of message
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static unsigned
+H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_class_t *orig_type,
+ const void *orig_mesg, H5O_shared_t *sh_mesg, const H5O_class_t **new_type,
+ const void **new_mesg, hid_t dxpl_id)
+{
+ size_t size; /* Size of space allocated for object header */
+ unsigned ret_value=UFAIL; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5O_new_mesg);
- if (NULL==type->get_share)
- HGOTO_ERROR (H5E_OHDR, H5E_UNSUPPORTED, FAIL, "message class is not sharable");
- if ((type->get_share)(f, mesg, &sh_mesg/*out*/)<0) {
+ /* check args */
+ assert(f);
+ assert(oh);
+ assert(flags);
+ assert(orig_type);
+ assert(orig_mesg);
+ assert(sh_mesg);
+ assert(new_mesg);
+ assert(new_type);
+
+ /* Check for shared message */
+ if (*flags & H5O_FLAG_SHARED) {
+ HDmemset(sh_mesg,0,sizeof(H5O_shared_t));
+
+ if (NULL==orig_type->get_share)
+ HGOTO_ERROR (H5E_OHDR, H5E_UNSUPPORTED, UFAIL, "message class is not sharable");
+ if ((orig_type->get_share)(f, orig_mesg, sh_mesg/*out*/)<0) {
/*
* If the message isn't shared then turn off the shared bit
* and treat it as an unshared message.
*/
H5E_clear (NULL);
- flags &= ~H5O_FLAG_SHARED;
- } else if (sh_mesg.in_gh) {
- /*
- * The shared message is stored in the global heap.
- * Increment the reference count on the global heap message.
- */
- if (H5HG_link (f, dxpl_id, &(sh_mesg.u.gh), 1)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
- size = (H5O_SHARED->raw_size)(f, &sh_mesg);
+ *flags &= ~H5O_FLAG_SHARED;
} else {
- /*
- * The shared message is stored in some other object header.
- * The other object header must be in the same file as the
- * new object header. Increment the reference count on that
- * object header.
- */
- if (sh_mesg.u.ent.file->shared != f->shared)
- HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "interfile hard links are not allowed");
- if (H5O_link (&(sh_mesg.u.ent), 1, dxpl_id)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
- size = (H5O_SHARED->raw_size)(f, &sh_mesg);
- }
- }
- /* This can't be an 'else' statement due to the possibility of the shared bit getting turned off above */
- if (0== (flags & H5O_FLAG_SHARED)) {
- size = (type->raw_size) (f, mesg);
- if (size>=H5O_MAX_SIZE)
- HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL, "object header message is too large (16k max)");
- }
- if ((idx = H5O_alloc(f, oh, type, size)) == UFAIL)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for message");
-
+ /* Change type & message to use shared information */
+ *new_type=H5O_SHARED;
+ *new_mesg=sh_mesg;
+ } /* end else */
+ } /* end if */
+ else {
+ *new_type=orig_type;
+ *new_mesg=orig_mesg;
+ } /* end else */
+
+ /* Compute the size needed to store the message on disk */
+ if ((size = ((*new_type)->raw_size) (f, *new_mesg)) >=H5O_MAX_SIZE)
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, UFAIL, "object header message is too large (16k max)");
+
+ /* Allocate space in the object headed for the message */
+ if ((ret_value = H5O_alloc(f, oh, orig_type, size)) == UFAIL)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, UFAIL, "unable to allocate space for message");
+
+ /* Increment any links in message */
+ if((*new_type)->link && ((*new_type)->link)(f,dxpl_id,(*new_mesg))<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, UFAIL, "unable to adjust shared object link count");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_new_mesg() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_write_mesg
+ *
+ * Purpose: Write message to object header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_class_t *type,
+ const void *mesg, unsigned flags)
+{
+ H5O_mesg_t *idx_msg; /* Pointer to message to modify */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5O_write_mesg);
+
+ /* check args */
+ assert(oh);
+ assert(type);
+ assert(mesg);
+
/* Set pointer to the correct message */
idx_msg=&oh->mesg[idx];
- /* Copy the native value into the object header */
- if (flags & H5O_FLAG_SHARED) {
- if (NULL==(idx_msg->native = H5MM_malloc (sizeof (H5O_shared_t))))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDmemcpy(idx_msg->native,&sh_mesg,sizeof(H5O_shared_t));
- } else {
- if (idx_msg->native)
- H5O_reset_real(idx_msg->type, idx_msg->native);
- idx_msg->native = (type->copy) (mesg, idx_msg->native);
- if (NULL == idx_msg->native)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy message to object header");
- }
-
+ /* Reset existing native information */
+ H5O_reset_real(type, idx_msg->native);
+
+ /* Copy the native value for the message */
+ if (NULL == (idx_msg->native = (type->copy) (mesg, idx_msg->native)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy message to object header");
+
idx_msg->flags = flags;
idx_msg->dirty = TRUE;
oh->cache_info.dirty = TRUE;
- /* Set return value */
- ret_value = idx;
-
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5O_append_real () */
+} /* end H5O_write_mesg() */
/*-------------------------------------------------------------------------
@@ -2478,10 +2457,10 @@ done:
static herr_t
H5O_remove_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, hid_t dxpl_id)
{
- H5O_t *oh = NULL;
+ H5O_t *oh = NULL;
+ H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
int seq, nfailed = 0;
- unsigned u;
- H5O_shared_t *sh_mesg = NULL;
+ unsigned u;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOINIT(H5O_remove_real);
@@ -2499,40 +2478,32 @@ H5O_remove_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, hid_t d
if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
- for (u = seq = 0; u < oh->nmesgs; u++) {
- if (type->id != oh->mesg[u].type->id)
+ for (u = seq = 0, curr_msg=&oh->mesg[0]; u < oh->nmesgs; u++,curr_msg++) {
+ if (type->id != curr_msg->type->id)
continue;
if (seq++ == sequence || H5O_ALL == sequence) {
+
/*
* Keep track of how many times we failed trying to remove constant
* messages.
*/
- if (oh->mesg[u].flags & H5O_FLAG_CONSTANT) {
+ if (curr_msg->flags & H5O_FLAG_CONSTANT) {
nfailed++;
continue;
- }
+ } /* end if */
- if (oh->mesg[u].flags & H5O_FLAG_SHARED) {
- if (NULL==oh->mesg[u].native) {
- sh_mesg = (H5O_SHARED->decode)(ent->file, dxpl_id, oh->mesg[u].raw,
- NULL);
- if (NULL==(oh->mesg[u].native = sh_mesg))
- HGOTO_ERROR (H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode shared message info");
- }
- if (sh_mesg->in_gh) {
- if (H5HG_link (ent->file, dxpl_id, &(sh_mesg->u.gh), -1)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to decrement link count on shared message");
- } else {
- if (H5O_link (&(sh_mesg->u.ent), -1, dxpl_id)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to decrement link count on shared message");
- }
- }
+ /* Free any space referred to in the file from this message */
+ if(H5O_delete_mesg(ent->file,dxpl_id,curr_msg)<0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message");
/* change message type to nil and zero it */
- oh->mesg[u].type = H5O_NULL;
- HDmemset(oh->mesg[u].raw, 0, oh->mesg[u].raw_size);
- oh->mesg[u].native = H5O_free_real(type, oh->mesg[u].native);
- oh->mesg[u].dirty = TRUE;
+ curr_msg->type = H5O_NULL;
+ HDmemset(curr_msg->raw, 0, curr_msg->raw_size);
+ if(curr_msg->flags & H5O_FLAG_SHARED)
+ curr_msg->native = H5O_free_real(H5O_SHARED, curr_msg->native);
+ else
+ curr_msg->native = H5O_free_real(type, curr_msg->native);
+ curr_msg->dirty = TRUE;
oh->cache_info.dirty = TRUE;
H5O_touch_oh(ent->file, oh, FALSE);
}
@@ -3095,6 +3066,51 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_get_share
+ *
+ * Purpose: Call the 'get_share' method for a
+ * particular class of object header.
+ *
+ * Return: Success: Non-negative, and SHARE describes the shared
+ * object.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Oct 2 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_get_share(hid_t type_id, H5F_t *f, const void *mesg, H5O_shared_t *share)
+{
+ const H5O_class_t *type; /* Actual H5O class type for the ID */
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_get_share,FAIL);
+
+ /* Check args */
+ assert(type_id>=0 && type_id<(hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0])));
+ type=message_type_g[type_id]; /* map the type ID to the actual type object */
+ assert (type);
+ assert (type->get_share);
+ assert (f);
+ assert (mesg);
+ assert (share);
+
+ /* Compute the raw data size for the mesg */
+ if ((ret_value = (type->get_share)(f, mesg, share))<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTGET, FAIL, "unable to retrieve shared message information");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_get_share() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_delete
*
* Purpose: Delete an object header from a file. This frees the file
@@ -3173,33 +3189,13 @@ H5O_delete_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
assert (f);
assert (oh);
- /* Walk through the list of object header messages, asking each on to
+ /* Walk through the list of object header messages, asking each one to
* delete any file space used
*/
for (u = 0, curr_msg=&oh->mesg[0]; u < oh->nmesgs; u++,curr_msg++) {
- const H5O_class_t *type = NULL;
-
- /* Don't handle shared messages yet */
- assert(!(curr_msg->flags & H5O_FLAG_SHARED));
-
- /* Get the message's type */
- type = curr_msg->type;
-
- /* Check if there is a file space deletion callback for this type of message */
- if(type->del) {
- /*
- * Decode the message if necessary.
- */
- if (NULL == curr_msg->native) {
- assert(type->decode);
- curr_msg->native = (type->decode) (f, dxpl_id, curr_msg->raw, NULL);
- if (NULL == curr_msg->native)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message");
- } /* end if */
-
- if ((type->del)(f, dxpl_id, curr_msg->native)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message");
- } /* end if */
+ /* Free any space referred to in the file from this message */
+ if(H5O_delete_mesg(f,dxpl_id,curr_msg)<0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message");
} /* end for */
/* Free all the chunks for the object header */
@@ -3227,6 +3223,62 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_delete_mesg
+ *
+ * Purpose: Internal function to:
+ * Delete an object header message from a file. This frees the file
+ * space used for anything referred to in the object header message.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * September 26 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg)
+{
+ const H5O_class_t *type; /* Type of object to free */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5O_delete_mesg);
+
+ /* Check args */
+ assert (f);
+ assert (mesg);
+
+ /* Get the message to free's type */
+ if(mesg->flags & H5O_FLAG_SHARED)
+ type=H5O_SHARED;
+ else
+ type = mesg->type;
+
+ /* Check if there is a file space deletion callback for this type of message */
+ if(type->del) {
+ /*
+ * Decode the message if necessary.
+ */
+ if (NULL == mesg->native) {
+ assert(type->decode);
+ mesg->native = (type->decode) (f, dxpl_id, mesg->raw, NULL);
+ if (NULL == mesg->native)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message");
+ } /* end if */
+
+ if ((type->del)(f, dxpl_id, mesg->native)<0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message");
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_delete_msg() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_debug_id
*
* Purpose: Act as a proxy for calling the 'debug' method for a
@@ -3410,7 +3462,7 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
decode = oh->mesg[i].type->decode;
debug = oh->mesg[i].type->debug;
}
- if (NULL==oh->mesg[i].native && oh->mesg[i].type->decode)
+ if (NULL==oh->mesg[i].native && decode)
oh->mesg[i].native = (decode)(f, dxpl_id, oh->mesg[i].raw, NULL);
if (NULL==oh->mesg[i].native)
debug = NULL;