summaryrefslogtreecommitdiffstats
path: root/src/H5Oshared.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Oshared.c')
-rw-r--r--src/H5Oshared.c363
1 files changed, 337 insertions, 26 deletions
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index b5e599d..19673a5 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -268,6 +268,80 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_shared_decode_new
+ *
+ * Purpose: Decodes a shared object message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, January 22, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_shared_decode_new(H5F_t *f, const uint8_t *buf, H5O_shared_t *sh_mesg)
+{
+ unsigned version; /* Shared message version */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_shared_decode_new)
+
+ /* Check args */
+ HDassert(f);
+ HDassert(buf);
+ HDassert(sh_mesg);
+
+ /* Version */
+ version = *buf++;
+ if(version < H5O_SHARED_VERSION_1 || version > H5O_SHARED_VERSION_LATEST)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "bad version number for shared object message")
+
+ /* Get the shared information flags
+ * Flags are unused before version 3.
+ */
+ if(version >= H5O_SHARED_VERSION_2)
+ sh_mesg->flags = *buf++;
+ else {
+ sh_mesg->flags = H5O_COMMITTED_FLAG;
+ buf++;
+ } /* end else */
+
+ /* Skip reserved bytes (for version 1) */
+ if(version == H5O_SHARED_VERSION_1)
+ buf += 6;
+
+ /* Body */
+ if(version == H5O_SHARED_VERSION_1)
+ H5G_obj_ent_decode(f, &buf, &(sh_mesg->u.oloc));
+ else if (version >= H5O_SHARED_VERSION_2) {
+ /* If this message is in the heap, copy a heap ID.
+ * Otherwise, it is a named datatype, so copy an H5O_loc_t.
+ */
+ if(sh_mesg->flags & H5O_SHARED_IN_HEAP_FLAG) {
+ HDassert(version >= H5O_SHARED_VERSION_3 );
+ HDmemcpy(&(sh_mesg->u.heap_id), buf, sizeof(sh_mesg->u.heap_id));
+ }
+ else {
+ /* The H5O_COMMITTED_FLAG should be set if this message
+ * is from an older version before the flag existed.
+ */
+ if(version < H5O_SHARED_VERSION_3)
+ sh_mesg->flags = H5O_COMMITTED_FLAG;
+
+ HDassert(sh_mesg->flags & H5O_COMMITTED_FLAG);
+
+ H5F_addr_decode(f, &buf, &(sh_mesg->u.oloc.addr));
+ sh_mesg->u.oloc.file = f;
+ } /* end else */
+ } /* end else if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_shared_decode_new() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_shared_decode
*
* Purpose: Decodes a shared object message and returns it.
@@ -349,16 +423,64 @@ H5O_shared_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *buf)
ret_value = mesg;
done:
- if(ret_value == NULL) {
+ if(ret_value == NULL)
if(mesg != NULL)
H5MM_xfree(mesg);
- } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_shared_decode() */
/*-------------------------------------------------------------------------
+ * Function: H5O_shared_encode_new
+ *
+ * Purpose: Encodes message _MESG into buffer BUF.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Thursday, April 2, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_shared_encode_new(const H5F_t *f, uint8_t *buf/*out*/, const H5O_shared_t *sh_mesg)
+{
+ unsigned version;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_shared_encode_new)
+
+ /* Check args */
+ HDassert(f);
+ HDassert(buf);
+ HDassert(sh_mesg);
+
+ /* If this message is shared in the heap, we need to use version 3 of the
+ * encoding and encode the SHARED_IN_HEAP flag.
+ */
+ if(sh_mesg->flags & H5O_SHARED_IN_HEAP_FLAG || H5F_USE_LATEST_FORMAT(f))
+ version = H5O_SHARED_VERSION_LATEST;
+ else {
+ HDassert(sh_mesg->flags & H5O_COMMITTED_FLAG);
+ version = H5O_SHARED_VERSION_2; /* version 1 is no longer used */
+ } /* end else */
+
+ *buf++ = version;
+ *buf++ = (unsigned)sh_mesg->flags;
+
+ /* Encode either the heap ID of the message or the address of the
+ * object header that holds it.
+ */
+ if(sh_mesg->flags & H5O_SHARED_IN_HEAP_FLAG)
+ HDmemcpy(buf, &(sh_mesg->u.heap_id), sizeof(sh_mesg->u.heap_id));
+ else
+ H5F_addr_encode(f, &buf, sh_mesg->u.oloc.addr);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_shared_encode_new() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_shared_encode
*
* Purpose: Encodes message _MESG into buffer BUF.
@@ -461,6 +583,42 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_shared_size_new
+ *
+ * Purpose: Returns the length of a shared object message.
+ *
+ * Return: Success: Length
+ * Failure: 0
+ *
+ * Programmer: Robb Matzke
+ * Thursday, April 2, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5O_shared_size_new(const H5F_t *f, const H5O_shared_t *sh_mesg)
+{
+ size_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_shared_size_new)
+
+ if(sh_mesg->flags & H5O_COMMITTED_FLAG) {
+ ret_value = 1 + /*version */
+ 1 + /*the flags field */
+ H5F_SIZEOF_ADDR(f); /*sharing by another obj hdr */
+ } /* end if */
+ else {
+ HDassert(sh_mesg->flags & H5O_SHARED_IN_HEAP_FLAG);
+ ret_value = 1 + /*version */
+ 1 + /*the flags field */
+ H5O_FHEAP_ID_LEN; /* Shared in the heap */
+ } /* end else */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_shared_size_new() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_shared_size
*
* Purpose: Returns the length of a shared object message.
@@ -477,27 +635,67 @@ done:
static size_t
H5O_shared_size(const H5F_t *f, const void *_mesg)
{
- const H5O_shared_t *shared = (const H5O_shared_t *) _mesg;
- size_t ret_value;
+ const H5O_shared_t *shared = (const H5O_shared_t *)_mesg;
+ size_t ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_shared_size)
- if(shared->flags & H5O_COMMITTED_FLAG)
- {
+ if(shared->flags & H5O_COMMITTED_FLAG) {
ret_value = 1 + /*version */
1 + /*the flags field */
H5F_SIZEOF_ADDR(f); /*sharing by another obj hdr */
- }
- else
- {
+ } /* end if */
+ else {
HDassert(shared->flags & H5O_SHARED_IN_HEAP_FLAG);
ret_value = 1 + /*version */
1 + /*the flags field */
H5O_FHEAP_ID_LEN; /* Shared in the heap */
- }
+ } /* end else */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_shared_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_shared_delete_new
+ *
+ * Purpose: Free file space referenced by message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 26, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_shared_delete_new(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *sh_mesg, hbool_t adj_link)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_shared_delete_new)
+
+ /* check args */
+ HDassert(f);
+ HDassert(sh_mesg);
+
+ /*
+ * Committed datatypes increment the OH of the original message when they
+ * are written (in H5O_shared_link) and decrement it here.
+ * SOHMs in the heap behave differently; their refcount is incremented
+ * during H5SM_share when they are going to be written (in H5O_msg_append
+ * or H5O_msg_write). Their refcount in the SOHM indexes still needs to
+ * be decremented when they're deleted (in H5O_shared_link_adj).
+ */
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ /* Decrement the reference count on the shared object, if requested */
+ if(adj_link)
+ if(H5O_shared_link_adj(f, dxpl_id, sh_mesg, -1) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared object link count")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_shared_delete_new() */
/*-------------------------------------------------------------------------
@@ -515,8 +713,7 @@ H5O_shared_size(const H5F_t *f, const void *_mesg)
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg,
- hbool_t adj_link)
+H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link)
{
const H5O_shared_t *shared = (const H5O_shared_t *) _mesg;
herr_t ret_value = SUCCEED; /* Return value */
@@ -547,6 +744,39 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_shared_link_new
+ *
+ * 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
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_shared_link_new(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *sh_mesg)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_shared_link_new)
+
+ /* check args */
+ HDassert(f);
+ HDassert(sh_mesg);
+
+ /* Increment the reference count on the shared object */
+ if(H5O_shared_link_adj(f, dxpl_id, sh_mesg, 1) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared object link count")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_shared_link_new() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_shared_link
*
* Purpose: Increment reference count on any objects referenced by
@@ -629,6 +859,91 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_shared_copy_file_new
+ *
+ * Purpose: Copies a message from _MESG to _DEST in file
+ *
+ * Return: Success: Ptr to _DEST
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * November 1, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5O_shared_copy_file_new(H5F_t *file_src, const H5O_msg_class_t *mesg_type,
+ const H5O_shared_t *shared_src, H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info,
+ void *udata)
+{
+ H5O_shared_t *shared_dst = NULL; /* The destination message if
+ * it is a shared message */
+ void *dst_mesg = NULL; /* The destination message if
+ * it's an unshared message */
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_shared_copy_file_new)
+
+ /* check args */
+ HDassert(shared_src);
+ HDassert(file_dst);
+ HDassert(cpy_info);
+
+HDfprintf(stderr, "%s: Copying shared messages not supported yet!\n", FUNC);
+HGOTO_ERROR(H5E_OHDR, H5E_UNSUPPORTED, NULL, "copying shared messages not supported yet")
+
+ /* Committed shared messages create a shared message at the destination
+ * and also copy the committed object that they point to.
+ * SOHMs actually write a non-shared message at the destination.
+ */
+ if(shared_src->flags & H5O_COMMITTED_FLAG) {
+ /* Allocate space for the destination message */
+ if(NULL == (shared_dst = H5MM_malloc(sizeof(H5O_shared_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Reset group entry for new object */
+ H5O_loc_reset(&(shared_dst->u.oloc));
+ shared_dst->u.oloc.file = file_dst;
+
+ /* Set flags for new shared object */
+ shared_dst->flags = shared_src->flags;
+
+ /* Copy the shared object from source to destination */
+ if(H5O_copy_header_map(&(shared_src->u.oloc), &(shared_dst->u.oloc), dxpl_id, cpy_info, FALSE) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object")
+
+ /* Set return value */
+ ret_value = shared_dst;
+ } /* end if */
+ else {
+ HDassert(shared_src->flags & H5O_SHARED_IN_HEAP_FLAG);
+
+ /* Read the shared message to get the original message */
+ if(NULL == (dst_mesg = H5O_shared_read(file_src, dxpl_id, shared_src, mesg_type, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, NULL, "unable to read shared message")
+
+ if(mesg_type->copy_file) {
+ /* Copy the original, un-shared message and return it */
+ ret_value = (mesg_type->copy_file)(file_src, mesg_type, dst_mesg, file_dst, dxpl_id, cpy_info, udata);
+ H5O_msg_free(mesg_type->id, dst_mesg);
+ } /* end else */
+ else
+ ret_value = dst_mesg;
+ } /* end else */
+
+done:
+ if(!ret_value) {
+ if(shared_dst)
+ H5O_msg_free(H5O_SHARED_ID, shared_dst);
+ if(dst_mesg)
+ H5O_msg_free(mesg_type->id, dst_mesg);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_shared_copy_file_new() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_shared_copy_file
*
* Purpose: Copies a message from _MESG to _DEST in file
@@ -665,8 +980,7 @@ H5O_shared_copy_file(H5F_t *file_src, const H5O_msg_class_t *mesg_type,
* and also copy the committed object that they point to.
* SOHMs actually write a non-shared message at the destination.
*/
- if(shared_src->flags & H5O_COMMITTED_FLAG)
- {
+ if(shared_src->flags & H5O_COMMITTED_FLAG) {
/* Allocate space for the destination message */
if(NULL == (shared_dst = H5MM_malloc(sizeof(H5O_shared_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
@@ -684,9 +998,8 @@ H5O_shared_copy_file(H5F_t *file_src, const H5O_msg_class_t *mesg_type,
/* Set return value */
ret_value = shared_dst;
- }
- else
- {
+ } /* end if */
+ else {
HDassert(shared_src->flags & H5O_SHARED_IN_HEAP_FLAG);
/* Read the shared message to get the original message */
@@ -697,20 +1010,18 @@ H5O_shared_copy_file(H5F_t *file_src, const H5O_msg_class_t *mesg_type,
/* Copy the original, un-shared message and return it */
ret_value = (mesg_type->copy_file)(file_src, mesg_type, dst_mesg, file_dst, dxpl_id, cpy_info, udata);
H5O_msg_free(mesg_type->id, dst_mesg);
- }
- else {
+ } /* end else */
+ else
ret_value = dst_mesg;
- }
- }
+ } /* end else */
done:
- if(!ret_value)
- {
+ if(!ret_value) {
if(shared_dst)
H5O_msg_free(H5O_SHARED_ID, shared_dst);
if(dst_mesg)
H5O_msg_free(mesg_type->id, dst_mesg);
- }
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* H5O_shared_copy_file() */