summaryrefslogtreecommitdiffstats
path: root/src/H5Ocopy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Ocopy.c')
-rw-r--r--src/H5Ocopy.c66
1 files changed, 47 insertions, 19 deletions
diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c
index 7a10765..1ecd16f 100644
--- a/src/H5Ocopy.c
+++ b/src/H5Ocopy.c
@@ -66,7 +66,7 @@
static herr_t H5O_copy_free_addrmap_cb(void *item, void *key, void *op_data);
static herr_t H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
- hid_t dxpl_id, H5O_copy_t *cpy_info);
+ hid_t dxpl_id, H5O_copy_t *cpy_info, H5O_type_t *obj_type, void **udata);
static herr_t H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
hid_t dxpl_id, unsigned cpy_option);
static herr_t H5O_copy_obj(H5G_loc_t *src_loc, H5G_loc_t *dst_loc,
@@ -285,7 +285,7 @@ done:
*/
static herr_t
H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
- hid_t dxpl_id, H5O_copy_t *cpy_info)
+ hid_t dxpl_id, H5O_copy_t *cpy_info, H5O_type_t *obj_type, void **udata)
{
H5O_addr_map_t *addr_map = NULL; /* Address mapping of object copied */
H5O_t *oh_src = NULL; /* Object header for source object */
@@ -299,7 +299,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
H5O_mesg_t *mesg_dst; /* Message in source object header */
const H5O_msg_class_t *copy_type; /* Type of message to use for copying */
const H5O_obj_class_t *obj_class = NULL; /* Type of object we are copying */
- void *udata = NULL; /* User data for passing to message callbacks */
+ void *cpy_udata = NULL; /* User data for passing to message callbacks */
uint64_t dst_oh_size; /* Total size of the destination OH */
size_t dst_oh_null; /* Size of the null message to add to destination OH */
unsigned dst_oh_gap; /* Size of the gap in chunk #0 of destination OH */
@@ -325,7 +325,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
/* Retrieve user data for particular type of object to copy */
if(obj_class->get_copy_file_udata &&
- (NULL == (udata = (obj_class->get_copy_file_udata)())))
+ (NULL == (cpy_udata = (obj_class->get_copy_file_udata)())))
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to retrieve copy user data")
/* Flush any dirty messages in source object header to update the header chunks */
@@ -404,7 +404,8 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
H5O_LOAD_NATIVE(oloc_src->file, dxpl_id, 0, oh_src, mesg_src, FAIL)
/* Perform "pre copy" operation on message */
- if((copy_type->pre_copy_file)(oloc_src->file, mesg_src->native, &(deleted[mesgno]), cpy_info, udata) < 0)
+ if((copy_type->pre_copy_file)(oloc_src->file, mesg_src->native,
+ &(deleted[mesgno]), cpy_info, cpy_udata) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to perform 'pre copy' operation on message")
/* Check if the message should be deleted in the destination */
@@ -478,7 +479,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
recompute_size = FALSE;
if((mesg_dst->native = H5O_msg_copy_file(copy_type,
oloc_src->file, mesg_src->native, oloc_dst->file,
- &recompute_size, cpy_info, udata, dxpl_id)) == NULL)
+ &recompute_size, cpy_info, cpy_udata, dxpl_id)) == NULL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
/* Check if new message is shared */
@@ -680,6 +681,8 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
addr_map->dst_addr = oloc_dst->addr;
addr_map->is_locked = TRUE; /* We've locked the object currently */
addr_map->inc_ref_count = 0; /* Start with no additional ref counts to add */
+ addr_map->obj_class = obj_class;
+ addr_map->udata = cpy_udata;
/* Insert into skip list */
if(H5SL_insert(cpy_info->map_list, addr_map, &(addr_map->src_obj_pos)) < 0)
@@ -742,7 +745,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
if(H5AC_insert_entry(oloc_dst->file, dxpl_id, H5AC_OHDR, oloc_dst->addr, oh_dst, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header")
oh_dst = NULL;
-
+
/* Reset metadat tag */
H5_END_TAG(FAIL);
@@ -750,6 +753,13 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
if(H5AC_retag_copied_metadata(oloc_dst->file, oloc_dst->addr) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "unable to re-tag metadata entries")
+ /* Set obj_type and udata, if requested */
+ if(obj_type) {
+ HDassert(udata);
+ *obj_type = obj_class->type;
+ *udata = cpy_udata;
+ } /* end if */
+
done:
/* Free deleted array */
if(deleted)
@@ -763,13 +773,6 @@ done:
if(ret_value < 0 && oh_dst && H5O_free(oh_dst) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data")
- /* Release user data for particular type of object to copy */
- if(udata) {
- HDassert(obj_class);
- HDassert(obj_class->free_copy_file_udata);
- (obj_class->free_copy_file_udata)(udata);
- } /* end if */
-
FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
} /* end H5O_copy_header_real() */
@@ -789,7 +792,8 @@ done:
*/
herr_t
H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
- hid_t dxpl_id, H5O_copy_t *cpy_info, hbool_t inc_depth)
+ hid_t dxpl_id, H5O_copy_t *cpy_info, hbool_t inc_depth,
+ H5O_type_t *obj_type, void **udata)
{
H5O_addr_map_t *addr_map = NULL; /* Address mapping of object copied */
H5_obj_t src_obj_pos; /* Position of source object */
@@ -823,7 +827,8 @@ H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
cpy_info->curr_depth++;
/* Copy object referred to */
- if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, cpy_info) < 0)
+ if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, cpy_info, obj_type,
+ udata) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
/* Check for incrementing the depth of copy */
@@ -840,6 +845,13 @@ H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
/* Object has already been copied, set its address in destination file */
oloc_dst->addr = addr_map->dst_addr;
+ /* Return saved obj_type and udata, if requested */
+ if(obj_type) {
+ HDassert(udata);
+ *obj_type = addr_map->obj_class->type;
+ *udata = addr_map->udata;
+ } /* end if */
+
/* If the object is locked currently (because we are copying a group
* hierarchy and this is a link to a group higher in the hierarchy),
* increment it's deferred reference count instead of incrementing the
@@ -883,12 +895,21 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5O_copy_free_addrmap_cb(void *item, void UNUSED *key, void UNUSED *op_data)
+H5O_copy_free_addrmap_cb(void *_item, void UNUSED *key, void UNUSED *op_data)
{
+ H5O_addr_map_t *item = (H5O_addr_map_t *)_item;
+
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_copy_free_addrmap_cb)
HDassert(item);
+ /* Release user data for particular type of object */
+ if(item->udata) {
+ HDassert(item->obj_class);
+ HDassert(item->obj_class->free_copy_file_udata);
+ (item->obj_class->free_copy_file_udata)(item->udata);
+ } /* end if */
+
/* Release the item */
item = H5FL_FREE(H5O_addr_map_t, item);
@@ -947,7 +968,8 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
HGOTO_ERROR(H5E_SLIST, H5E_CANTCREATE, FAIL, "cannot make skip list")
/* copy the object from the source file to the destination file */
- if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, &cpy_info) < 0)
+ if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, &cpy_info, NULL, NULL)
+ < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
done:
@@ -1057,7 +1079,8 @@ H5O_copy_obj_by_ref(H5O_loc_t *src_oloc, hid_t dxpl_id, H5O_loc_t *dst_oloc,
HDassert(dst_oloc);
/* Perform the copy, or look up existing copy */
- if((ret_value = H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, cpy_info, FALSE)) < 0)
+ if((ret_value = H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, cpy_info,
+ FALSE, NULL, NULL)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
/* Check if a new valid object is copied to the destination */
@@ -1078,6 +1101,11 @@ H5O_copy_obj_by_ref(H5O_loc_t *src_oloc, hid_t dxpl_id, H5O_loc_t *dst_oloc,
sprintf(tmp_obj_name, "~obj_pointed_by_%llu", (unsigned long long)dst_oloc->addr);
/* Create a link to the newly copied object */
+ /* Note: since H5O_copy_header_map actually copied the target object, it
+ * must exist either in cache or on disk, therefore it is is safe to not
+ * pass the obj_type and udata fields returned by H5O_copy_header_map.
+ * This could be changed in the future to slightly improve performance
+ * --NAF */
if(H5L_link(dst_root_loc, tmp_obj_name, &new_loc, H5P_DEFAULT, H5P_DEFAULT, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert link")