summaryrefslogtreecommitdiffstats
path: root/src/H5Oshared.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/H5Oshared.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/H5Oshared.c')
-rw-r--r--src/H5Oshared.c302
1 files changed, 281 insertions, 21 deletions
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index f3f399e..1444e03 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -25,17 +25,22 @@
* the global heap.
*/
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
#define H5O_PACKAGE /*suppress error about including H5Opkg */
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
#include "H5Gprivate.h" /* Groups */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
static void *H5O_shared_decode (H5F_t*, hid_t dxpl_id, const uint8_t*, H5O_shared_t *sh);
static herr_t H5O_shared_encode (H5F_t*, uint8_t*, const void*);
-static size_t H5O_shared_size (H5F_t*, const void*);
+static void *H5O_shared_copy(const void *_mesg, void *_dest);
+static size_t H5O_shared_size (H5F_t*, const void *_mesg);
+static herr_t H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg);
+static herr_t H5O_shared_link(H5F_t *f, hid_t dxpl_id, const void *_mesg);
static herr_t H5O_shared_debug (H5F_t*, hid_t dxpl_id, const void*, FILE*, int, int);
/* This message derives from H5O */
@@ -45,17 +50,22 @@ const H5O_class_t H5O_SHARED[1] = {{
sizeof(H5O_shared_t), /*native message size */
H5O_shared_decode, /*decode method */
H5O_shared_encode, /*encode method */
- NULL, /*no copy method */
+ H5O_shared_copy, /*copy the native value */
H5O_shared_size, /*size method */
NULL, /*no reset method */
NULL, /*no free method */
- NULL, /* file delete method */
+ H5O_shared_delete, /*file delete method */
+ H5O_shared_link, /*link method */
NULL, /*get share method */
NULL, /*set share method */
H5O_shared_debug, /*debug method */
}};
-#define H5O_SHARED_VERSION 1
+/* Old version, with full symbol table entry as link for object header sharing */
+#define H5O_SHARED_VERSION_1 1
+
+/* New version, with just address of object as link for object header sharing */
+#define H5O_SHARED_VERSION 2
/* Interface initialization */
#define PABLO_MASK H5O_shared_mask
@@ -64,6 +74,123 @@ static int interface_initialize_g = 0;
/*-------------------------------------------------------------------------
+ * Function: H5O_shared_read
+ *
+ * Purpose: Reads a message referred to by a shared message.
+ *
+ * Return: Success: Ptr to message in native format. The message
+ * should be freed by calling H5O_reset(). If
+ * MESG is a null pointer then the caller should
+ * also call H5MM_xfree() on the return value
+ * after calling H5O_reset().
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 24 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_shared_t *shared, const H5O_class_t *type, void *mesg)
+{
+ void *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_shared_read,NULL);
+
+ /* check args */
+ assert(f);
+ assert(shared);
+ assert(type);
+
+ /* Get the shared message */
+ if (shared->in_gh) {
+ void *tmp_buf, *tmp_mesg;
+
+ if (NULL==(tmp_buf = H5HG_read (f, 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)(f, 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);
+ } /* end if */
+ else
+ ret_value = tmp_mesg;
+ } /* end if */
+ else {
+ ret_value = H5O_read_real(&(shared->u.ent), type, 0, mesg, dxpl_id);
+ if (type->set_share &&
+ (type->set_share)(f, ret_value, shared)<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, "unable to set sharing information");
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_shared_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_shared_link_adj
+ *
+ * Purpose: Changes the link count for the object referenced by a shared
+ * message.
+ *
+ * Return: Success: New link count
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 26 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5O_shared_link_adj(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared, int adjust)
+{
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_shared_link_adj,FAIL);
+
+ /* check args */
+ assert(f);
+ assert(shared);
+
+ if (shared->in_gh) {
+ /*
+ * The shared message is stored in the global heap.
+ * Adjust the reference count on the global heap message.
+ */
+ if ((ret_value = H5HG_link (f, dxpl_id, &(shared->u.gh), adjust))<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
+ } /* end if */
+ 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. Adjust the reference count on that
+ * object header.
+ */
+ if (shared->u.ent.file->shared != f->shared)
+ HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "interfile hard links are not allowed");
+ if ((ret_value = H5O_link (&(shared->u.ent), adjust, dxpl_id))<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_shared_link_adj() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_shared_decode
*
* Purpose: Decodes a shared object message and returns it.
@@ -95,28 +222,36 @@ H5O_shared_decode (H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *buf, H5O_share
assert (!sh);
/* Decode */
- if (NULL==(mesg = H5MM_calloc (sizeof *mesg)))
+ if (NULL==(mesg = H5MM_calloc (sizeof(H5O_shared_t))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* Version */
version = *buf++;
- if (version!=H5O_SHARED_VERSION)
+ if (version!=H5O_SHARED_VERSION_1 && version!=H5O_SHARED_VERSION)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for shared object message");
- /* Flags */
+ /* Get the shared information flags */
flags = *buf++;
mesg->in_gh = (flags & 0x01);
- /* Reserved */
- buf += 6;
+ /* Skip reserved bytes (for version 1) */
+ if(version==H5O_SHARED_VERSION_1)
+ buf += 6;
/* Body */
if (mesg->in_gh) {
- H5F_addr_decode (f, &buf, &(mesg->u.gh.addr));
- INT32DECODE (buf, mesg->u.gh.idx);
- } else {
- H5G_ent_decode (f, &buf, &(mesg->u.ent));
- }
+ H5F_addr_decode (f, &buf, &(mesg->u.gh.addr));
+ INT32DECODE (buf, mesg->u.gh.idx);
+ } /* end if */
+ else {
+ if(version==H5O_SHARED_VERSION_1)
+ H5G_ent_decode (f, &buf, &(mesg->u.ent));
+ else {
+ assert(version==H5O_SHARED_VERSION);
+ H5F_addr_decode (f, &buf, &(mesg->u.ent.header));
+ mesg->u.ent.file=f;
+ } /* end else */
+ } /* end else */
/* Set return value */
ret_value=mesg;
@@ -165,6 +300,7 @@ H5O_shared_encode (H5F_t *f, uint8_t *buf/*out*/, const void *_mesg)
*buf++ = H5O_SHARED_VERSION;
flags = mesg->in_gh ? 0x01 : 0x00;
*buf++ = flags;
+#ifdef OLD_WAY
*buf++ = 0; /*reserved 1*/
*buf++ = 0; /*reserved 2*/
*buf++ = 0; /*reserved 3*/
@@ -175,9 +311,17 @@ H5O_shared_encode (H5F_t *f, uint8_t *buf/*out*/, const void *_mesg)
if (mesg->in_gh) {
H5F_addr_encode (f, &buf, mesg->u.gh.addr);
INT32ENCODE (buf, mesg->u.gh.idx);
- } else {
+ } /* end if */
+ else
H5G_ent_encode (f, &buf, &(mesg->u.ent));
- }
+#else /* OLD_WAY */
+ if (mesg->in_gh) {
+ H5F_addr_encode (f, &buf, mesg->u.gh.addr);
+ INT32ENCODE (buf, mesg->u.gh.idx);
+ } /* end if */
+ else
+ H5F_addr_encode (f, &buf, mesg->u.ent.header);
+#endif /* OLD_WAY */
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -185,6 +329,49 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_shared_copy
+ *
+ * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if
+ * necessary.
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 26 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_shared_copy(const void *_mesg, void *_dest)
+{
+ const H5O_shared_t *mesg = (const H5O_shared_t *) _mesg;
+ H5O_shared_t *dest = (H5O_shared_t *) _dest;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_shared_copy, NULL);
+
+ /* check args */
+ assert(mesg);
+ if (!dest && NULL==(dest = H5MM_malloc (sizeof(H5O_shared_t))))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+
+ /* copy */
+ *dest = *mesg;
+
+ /* Set return value */
+ ret_value=dest;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_shared_copy() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_shared_size
*
* Purpose: Returns the length of a shared object message.
@@ -201,16 +388,18 @@ done:
*-------------------------------------------------------------------------
*/
static size_t
-H5O_shared_size (H5F_t *f, const void UNUSED *_mesg)
+H5O_shared_size (H5F_t *f, const void *_mesg)
{
+ const H5O_shared_t *shared = (const H5O_shared_t *) _mesg;
size_t ret_value;
FUNC_ENTER_NOAPI(H5O_shared_size, 0);
- ret_value = 1 + /*the flags field */
- 7 + /*reserved */
- MAX (H5F_SIZEOF_ADDR(f)+4, /*sharing via global heap */
- H5G_SIZEOF_ENTRY(f)); /*sharing by another obj hdr */
+ ret_value = 1 + /*version */
+ 1 + /*the flags field */
+ (shared->in_gh ?
+ (H5F_SIZEOF_ADDR(f)+4) : /*sharing via global heap */
+ H5F_SIZEOF_ADDR(f)); /*sharing by another obj hdr */
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -218,6 +407,77 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_shared_delete
+ *
+ * Purpose: Free file space referenced by message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 26, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg)
+{
+ const H5O_shared_t *shared = (const H5O_shared_t *) _mesg;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_shared_delete, FAIL);
+
+ /* check args */
+ assert(f);
+ assert(shared);
+
+ /* Decrement the reference count on the shared object */
+ if(H5O_shared_link_adj(f,dxpl_id,shared,-1)<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_shared_delete() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_shared_link
+ *
+ * Purpose: Increment reference count on any objects referenced by
+ * message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 26, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_shared_link(H5F_t *f, hid_t dxpl_id, const void *_mesg)
+{
+ const H5O_shared_t *shared = (const H5O_shared_t *) _mesg;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_shared_link, FAIL);
+
+ /* check args */
+ assert(f);
+ assert(shared);
+
+ /* Decrement the reference count on the shared object */
+ if(H5O_shared_link_adj(f,dxpl_id,shared,1)<0)
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_shared_link() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_shared_debug
*
* Purpose: Prints debugging info for the message