summaryrefslogtreecommitdiffstats
path: root/src/H5Oshared.c
diff options
context:
space:
mode:
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