diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2006-06-26 22:01:43 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2006-06-26 22:01:43 (GMT) |
commit | 8d72542a50fac7a747fe0bfec8d2285de8efd29f (patch) | |
tree | da26f38920601ae4274e77d3363767ca057a66ab /src | |
parent | 785938ace19e2533ab94c14b6cd8de508fe18f15 (diff) | |
download | hdf5-8d72542a50fac7a747fe0bfec8d2285de8efd29f.zip hdf5-8d72542a50fac7a747fe0bfec8d2285de8efd29f.tar.gz hdf5-8d72542a50fac7a747fe0bfec8d2285de8efd29f.tar.bz2 |
[svn-r12439] Purpose:
New feature
Description:
Check in Peter's code to add support for "shallow copy", "create
intermediate groups", "no attributes" and "expand soft links" support.
Platforms tested:
FreeBSD 4.11 (sleipnir)
Linux 2.4 (chicago) w/ & w/o group-revision enabled
h5committest
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Dcontig.c | 3 | ||||
-rw-r--r-- | src/H5G.c | 35 | ||||
-rw-r--r-- | src/H5Gnode.c | 50 | ||||
-rw-r--r-- | src/H5Gpkg.h | 10 | ||||
-rw-r--r-- | src/H5Gprivate.h | 2 | ||||
-rw-r--r-- | src/H5Gpublic.h | 14 | ||||
-rw-r--r-- | src/H5O.c | 112 | ||||
-rw-r--r-- | src/H5Oattr.c | 49 | ||||
-rw-r--r-- | src/H5Ocont.c | 4 | ||||
-rw-r--r-- | src/H5Odtype.c | 12 | ||||
-rw-r--r-- | src/H5Oefl.c | 4 | ||||
-rw-r--r-- | src/H5Olayout.c | 4 | ||||
-rw-r--r-- | src/H5Olinfo.c | 55 | ||||
-rw-r--r-- | src/H5Olink.c | 103 | ||||
-rw-r--r-- | src/H5Opkg.h | 7 | ||||
-rw-r--r-- | src/H5Opline.c | 8 | ||||
-rw-r--r-- | src/H5Oprivate.h | 15 | ||||
-rw-r--r-- | src/H5Oshared.c | 28 | ||||
-rw-r--r-- | src/H5Ostab.c | 23 |
19 files changed, 412 insertions, 126 deletions
diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index 97fd043..09af474 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -990,6 +990,9 @@ done: * Programmer: Quincey Koziol * Monday, November 21, 2005 * + * Modifier: Peter Cao + * Saturday, January 07, 2006 + * Add case to deal with compressed variable length datasets *------------------------------------------------------------------------- */ herr_t @@ -2356,7 +2356,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5G_get_objinfo(H5G_loc_t *loc, const char *name, hbool_t follow_link, +H5G_get_objinfo(const H5G_loc_t *loc, const char *name, hbool_t follow_link, H5G_stat_t *statbuf/*out*/, hid_t dxpl_id) { H5G_trav_ud4_t udata; /* User data for callback */ @@ -2999,17 +2999,17 @@ H5G_unmount(H5G_t *grp) static herr_t H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, hid_t plist_id) { - H5P_genplist_t *gcrt_plist = NULL; /* Group create property list created */ - H5P_genplist_t *gcpy_plist; /* Group copy property list created */ - hid_t dxpl_id = H5AC_dxpl_id; + H5P_genplist_t *gcrt_plist=NULL; /* Group create property list created */ + H5P_genplist_t *gcpy_plist=NULL; /* Group copy property list created */ + hid_t dxpl_id=H5AC_dxpl_id; H5G_name_t new_path; /* Copied object group hier. path */ H5O_loc_t new_oloc; /* Copied object object location */ H5G_loc_t new_loc; /* Group location of object copied */ - hbool_t entry_inserted = FALSE; /* Flag to indicate that the new entry was inserted into a group */ + hbool_t entry_inserted=FALSE; /* Flag to indicate that the new entry was inserted into a group */ + hbool_t gcrt_plist_created=FALSE; /* Flag to indicate if H5G_CREATE_INTERMEDIATE_GROUP_FLAG is set */ unsigned cpy_option = 0; /* Copy options */ H5P_genclass_t *gcrt_class; /* Group creation property class */ - hid_t gcplist_id = H5P_DEFAULT; /* Group creation property list */ - hbool_t gcplist_created = FALSE; /* Flag o indicate if group creation property list is created */ + hid_t gcplist_id = H5P_DEFAULT; /* Group creation property list */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_copy, FAIL); @@ -3041,22 +3041,26 @@ H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, hid_t pli /* Create group creatiion property to create missing groups */ if((cpy_option & H5G_COPY_CREATE_INTERMEDIATE_GROUP_FLAG) > 0) { if(NULL == (gcrt_class = H5I_object_verify(H5P_GROUP_CREATE, H5I_GENPROP_CLS))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class") /* Create the new property list */ if((gcplist_id = H5P_create_id(gcrt_class)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list"); - gcplist_created = TRUE; + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list") + gcrt_plist_created = TRUE; } else gcplist_id = H5P_GROUP_CREATE_DEFAULT; + /* Get a pointer to the group creation property list */ if(NULL == (gcrt_plist = H5I_object(gcplist_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") /* Set the intermediate group creation property, if requested */ - if(gcplist_created) - if(H5P_set(gcrt_plist, H5G_CRT_INTERMEDIATE_GROUP_NAME, &cpy_option) < 0) + if(gcrt_plist_created) { + unsigned crt_intmd_group = TRUE; + + if(H5P_set(gcrt_plist, H5G_CRT_INTERMEDIATE_GROUP_NAME, &crt_intmd_group) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set intermediate group creation flag") + } /* end if */ /* Insert the new object in the destination file's group */ if(H5G_insert(dst_loc, dst_name, &new_loc, dxpl_id, gcrt_plist) < 0) @@ -3067,8 +3071,11 @@ done: /* Free the ID to name buffers */ if(entry_inserted) H5G_loc_free(&new_loc); - if (gcplist_created) - H5P_close(gcrt_plist); + + if(gcplist_id>0 && gcrt_plist_created) { + if(H5I_dec_ref(gcplist_id)<0) + HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to decrement ref count on property list") + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_copy() */ diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 126be95..d6915ea 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -1907,6 +1907,8 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, const void UNUSED *_rt_key, void *_udata) { H5G_bt_it_ud5_t *udata = (H5G_bt_it_ud5_t *)_udata; + H5O_loc_t *parent_src_oloc = udata->src_oloc; + H5O_copy_t *cpy_info = udata->cpy_info; const H5HL_t *heap = NULL; H5G_node_t *sn = NULL; unsigned int i; /* Local index variable */ @@ -1930,17 +1932,50 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, /* copy object in this node one by one */ for(i = 0; i < sn->nsyms; i++) { H5G_entry_t *src_ent = &(sn->entry[i]); /* Convenience variable to refer to current source group entry */ - H5O_loc_t new_oloc; /* Copied object object location */ H5O_link_t lnk; /* Link to insert */ const char *name; /* Name of source object */ - - /* Set up copied object location to fill in */ - H5O_loc_reset(&new_oloc); - new_oloc.file = udata->dst_file; + H5G_entry_t tmp_src_ent; /* Temperary copy. Change will not affect the cache */ + + /* expand soft link */ + if(H5G_CACHED_SLINK == src_ent->type && cpy_info->expand_soft_link) { + H5G_stat_t statbuf; /* Information about object pointed to by soft link */ + H5G_loc_t grp_loc; /* Group location for parent of soft link */ + H5G_name_t grp_path; /* Path for parent of soft link */ + char *link_name; /* Pointer to value of soft link */ + + /* Make a temporary copy, so that it will not change the info in the cache */ + HDmemcpy(&tmp_src_ent, src_ent, sizeof(H5G_entry_t)); + src_ent = &tmp_src_ent; + + /* Set up group location for soft link to start in */ + H5G_name_reset(&grp_path); + grp_loc.path = &grp_path; + grp_loc.oloc = parent_src_oloc; + + /* Get pointer to link value in local heap */ + link_name = (char *)H5HL_offset_into(f, heap, src_ent->cache.slink.lval_offset); + + /* Check if the object pointed by the soft link exists in the source file */ + /* (It would be more efficient to make a specialized traversal callback, + * but this is good enough for now... -QAK) + */ + if(H5G_get_objinfo(&grp_loc, link_name, TRUE, &statbuf, H5AC_ind_dxpl_id) >= 0) { +#if H5_SIZEOF_UINT64_T > H5_SIZEOF_LONG + src_ent->header = (((haddr_t)statbuf.objno[1]) << (8 * sizeof(long))) | (haddr_t)statbuf.objno[0]; +#else + src_ent->header = statbuf.objno[0]; +#endif + } /* end if */ + } /* if ((H5G_CACHED_SLINK == src_ent->type)... */ /* Check if object in source group is a hard link */ if(H5F_addr_defined(src_ent->header)) { - H5O_loc_t src_oloc; /* Temporary object location for source object */ + H5O_loc_t new_oloc; /* Copied object object location */ + H5O_loc_t src_oloc; /* Temporary object location for source object */ + + /* Set up copied object location to fill in */ + H5O_loc_reset(&new_oloc); + new_oloc.file = udata->dst_file; /* Build temporary object location for source */ src_oloc.file = f; @@ -1948,8 +1983,7 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, src_oloc.addr = src_ent->header; /* Copy the shared object from source to destination */ - /* (Increments link count on destination) */ - if(H5O_copy_header_map(&src_oloc, &new_oloc, dxpl_id, udata->cpy_option, udata->map_list) < 0) + if(H5O_copy_header_map(&src_oloc, &new_oloc, dxpl_id, cpy_info, TRUE) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, H5B_ITER_ERROR, "unable to copy object") /* Construct link information for eventual insertion */ diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index c8db6e3..98e3516 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -224,11 +224,11 @@ typedef struct H5G_bt_it_ud4_t { /* Data passed to B-tree iteration for copying copy symblol table content */ typedef struct H5G_bt_it_ud5_t { - haddr_t src_heap_addr; /* heap address of the source symbol table */ - H5F_t *dst_file; /* File of destination group */ - H5O_stab_t *dst_stab; /* symbol table info for destination group */ - H5SL_t *map_list; /* skip list to map copied object addresses */ - unsigned cpy_option; /* cpy options */ + H5O_loc_t *src_oloc; /* source object location */ + haddr_t src_heap_addr; /* heap address of the source symbol table */ + H5F_t *dst_file; /* File of destination group */ + H5O_stab_t *dst_stab; /* symbol table info for destination group */ + H5O_copy_t *cpy_info; /* Information for copy operation */ } H5G_bt_it_ud5_t; /* Typedef for path traversal operations */ diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index d3b00e3..e498671 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -130,7 +130,7 @@ H5_DLL H5G_t *H5G_open(H5G_loc_t *loc, hid_t dxpl_id); H5_DLL herr_t H5G_close(H5G_t *grp); H5_DLL herr_t H5G_insert(H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc, hid_t dxpl_id, struct H5P_genplist_t *oc_plist); -H5_DLL herr_t H5G_get_objinfo(H5G_loc_t *loc, const char *name, +H5_DLL herr_t H5G_get_objinfo(const H5G_loc_t *loc, const char *name, hbool_t follow_link, H5G_stat_t *statbuf/*out*/, hid_t dxpl_id); H5_DLL H5F_t *H5G_insertion_file(H5G_loc_t *loc, const char *name, hid_t dxpl_id); H5_DLL herr_t H5G_free_grp_name(H5G_t *grp); diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index 361c85d..fd322a6 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -115,13 +115,13 @@ typedef herr_t (*H5G_iterate_t)(hid_t group, const char *name, void *op_data); /* Flags for object copy (H5Gcopy) */ -#define H5G_COPY_CREATE_INTERMEDIATE_GROUP_FLAG (0x0001u) /* Create missing groups when create a group */ -#define H5G_COPY_SHALLOW_HIERARCHY_FLAG (0x0002u) /* Copy only immediate members */ -#define H5G_COPY_EXPAND_SOFT_LINK_FLAG (0x0004u) /* Expand soft links into new objects */ -#define H5G_COPY_EXPAND_EXT_LINK_FLAG (0x0008u) /* Expand external links into new objects */ -#define H5G_COPY_EXPAND_OBJ_REFERENCE_FLAG (0x0010u) /* Copy objects that are pointed by references */ -#define H5G_COPY_WITHOUT_ATTR_FLAG (0x0020u) /* Copy object without copying attributes */ -#define H5G_COPY_ALL (0x003Fu) /* All object copying flags (for internal range checking) */ +#define H5G_COPY_CREATE_INTERMEDIATE_GROUP_FLAG (0x0001u) /* Create missing groups when create a group */ +#define H5G_COPY_SHALLOW_HIERARCHY_FLAG (0x0002u) /* Copy only immediate members */ +#define H5G_COPY_EXPAND_SOFT_LINK_FLAG (0x0004u) /* Expand soft links into new objects */ +#define H5G_COPY_EXPAND_EXT_LINK_FLAG (0x0008u) /* Expand external links into new objects */ +#define H5G_COPY_EXPAND_OBJ_REFERENCE_FLAG (0x0010u) /* Copy objects that are pointed by references */ +#define H5G_COPY_WITHOUT_ATTR_FLAG (0x0020u) /* Copy object without copying attributes */ +#define H5G_COPY_ALL (0x003Fu) /* All object copying flags (for internal checking) */ H5_DLL hid_t H5Gcreate(hid_t loc_id, const char *name, size_t size_hint); H5_DLL hid_t H5Gopen(hid_t loc_id, const char *name); @@ -222,9 +222,9 @@ static herr_t H5O_iterate_real(const H5O_loc_t *loc, const H5O_msg_class_t *type static H5G_obj_t H5O_obj_type_real(H5O_t *oh); static const H5O_obj_class_t *H5O_obj_class(H5O_t *oh); static void * H5O_copy_mesg_file(const H5O_msg_class_t *type, H5F_t *file_src, void *mesg_src, - H5F_t *file_dst, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata); + H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata); static herr_t H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, - hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list); + hid_t dxpl_id, H5O_copy_t *cpy_info); static herr_t H5O_copy_free_addrmap_cb(void *item, void *key, void *op_data); @@ -4034,7 +4034,7 @@ H5O_loc_copy(H5O_loc_t *dst, const H5O_loc_t *src, H5_copy_depth_t depth) */ static void * H5O_copy_mesg_file(const H5O_msg_class_t *type, H5F_t *file_src, void *native_src, - H5F_t *file_dst, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata) + H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata) { void *ret_value; @@ -4046,9 +4046,9 @@ H5O_copy_mesg_file(const H5O_msg_class_t *type, H5F_t *file_src, void *native_sr HDassert(file_src); HDassert(native_src); HDassert(file_dst); - HDassert(map_list); + HDassert(cpy_info); - if(NULL == (ret_value = (type->copy_file)(file_src, native_src, file_dst, dxpl_id, cpy_option, map_list, udata))) + if(NULL == (ret_value = (type->copy_file)(file_src, native_src, file_dst, dxpl_id, cpy_info, udata))) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to copy object header message to file") done: @@ -4070,7 +4070,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, unsigned cpy_option, H5SL_t *map_list) + hid_t dxpl_id, H5O_copy_t *cpy_info) { H5O_addr_map_t *addr_map = NULL; /* Address mapping of object copied */ H5O_t *oh_src = NULL; /* Object header for source object */ @@ -4083,7 +4083,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, const H5O_msg_class_t *copy_type; /* Type of message to use for copying */ const H5O_obj_class_t *obj_class; /* Type of object we are copying */ void *udata = NULL; /* User data for passing to message callbacks */ - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5O_copy_header_real) @@ -4091,7 +4091,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, HDassert(oloc_src->file); HDassert(H5F_addr_defined(oloc_src->addr)); HDassert(oloc_dst->file); - HDassert(map_list); + HDassert(cpy_info); /* Get source object header */ if(NULL == (oh_src = H5AC_protect(oloc_src->file, dxpl_id, H5AC_OHDR, oloc_src->addr, NULL, NULL, H5AC_READ))) @@ -4198,6 +4198,8 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, HDassert(copy_type); if(copy_type->pre_copy_file) { + hbool_t deleted = FALSE; /* Flag to indicate that the message should be deleted from the destination */ + /* * Decode the message if necessary. If the message is shared then do * a shared message, ignoring the message type. @@ -4210,8 +4212,23 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, } /* end if (NULL == mesg_src->native) */ /* Perform "pre copy" operation on messge */ - if((copy_type->pre_copy_file)(oloc_src->file, mesg_src->type, mesg_src->native, udata) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to perform 'post copy' operation on message") + if((copy_type->pre_copy_file)(oloc_src->file, mesg_src->type, mesg_src->native, &deleted, cpy_info, 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 */ + if(deleted) { + /* Change ID of destination message to NULL */ + mesg_dst->type = H5O_MSG_NULL; + + /* Clear message data to 0 */ + HDmemset(mesg_dst->raw, 0, mesg_dst->raw_size); + + /* Clear message flags */ + mesg_dst->flags = 0; + + /* Mark message as dirty */ + mesg_dst->dirty = TRUE; + } /* end if */ } /* end if */ } /* end for */ @@ -4222,10 +4239,13 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, mesg_dst = &(oh_dst->mesg[mesgno]); /* Check for shared message to operate on */ - if (mesg_src->flags & H5O_FLAG_SHARED) + /* (Use destination message, in case the message has been removed (i.e + * converted to a nil message) in the destination -QAK) + */ + if (mesg_dst->flags & H5O_FLAG_SHARED) copy_type = H5O_MSG_SHARED; else - copy_type = mesg_src->type; + copy_type = mesg_dst->type; /* copy this message into destination file */ HDassert(copy_type); @@ -4244,12 +4264,12 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, /* Copy the source message */ if(H5O_CONT_ID == mesg_src->type->id) { if((mesg_dst->native = H5O_copy_mesg_file(copy_type, oloc_src->file, mesg_src->native, - oloc_dst->file, dxpl_id, cpy_option, map_list, oh_dst->chunk)) == NULL) + oloc_dst->file, dxpl_id, cpy_info, oh_dst->chunk)) == NULL) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message") } /* end if */ else { if((mesg_dst->native = H5O_copy_mesg_file(copy_type, oloc_src->file, mesg_src->native, - oloc_dst->file, dxpl_id, cpy_option, map_list, udata)) == NULL) + oloc_dst->file, dxpl_id, cpy_info, udata)) == NULL) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message") } /* end else */ @@ -4278,7 +4298,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, 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 */ - if(H5SL_insert(map_list, addr_map, &(addr_map->src_addr)) < 0) + if(H5SL_insert(cpy_info->map_list, addr_map, &(addr_map->src_addr)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list") /* "post copy" loop over messages, to fix up any messages which require a complete @@ -4287,27 +4307,30 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, for(mesgno = 0; mesgno < oh_src->nmesgs; mesgno++) { /* Set up convenience variables */ mesg_src = &(oh_src->mesg[mesgno]); + mesg_dst = &(oh_dst->mesg[mesgno]); /* Check for shared message to operate on */ - if(mesg_src->flags & H5O_FLAG_SHARED) + /* (Use destination message, in case the message has been removed (i.e + * converted to a nil message) in the destination -QAK) + */ + if(mesg_dst->flags & H5O_FLAG_SHARED) copy_type = H5O_MSG_SHARED; else - copy_type = mesg_src->type; + copy_type = mesg_dst->type; HDassert(copy_type); if(copy_type->post_copy_file && mesg_src->native) { hbool_t modified = FALSE; /* Get destination message */ - mesg_dst = &(oh_dst->mesg[mesgno]); HDassert(mesg_dst->type == mesg_src->type); /* Make certain the destination's native info is available */ LOAD_NATIVE(oloc_dst->file, dxpl_id, mesg_dst, FAIL) /* Perform "post copy" operation on messge */ - if((copy_type->post_copy_file)(oloc_src->file, mesg_src->native, oloc_dst, - mesg_dst->native, &modified, dxpl_id, cpy_option, map_list) < 0) + if((copy_type->post_copy_file)(oloc_src, mesg_src->native, oloc_dst, + mesg_dst->native, &modified, dxpl_id, cpy_info) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to perform 'post copy' operation on message") /* Mark message and header as dirty if the destination message was modified */ @@ -4369,7 +4392,7 @@ done: */ herr_t H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, - hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list) + hid_t dxpl_id, H5O_copy_t *cpy_info, hbool_t inc_depth) { H5O_addr_map_t *addr_map; /* Address mapping of object copied */ hbool_t inc_link; /* Whether to increment the link count for the object */ @@ -4381,19 +4404,28 @@ H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, HDassert(oloc_src); HDassert(oloc_dst); HDassert(oloc_dst->file); - HDassert(map_list); + HDassert(cpy_info); /* Look up the address of the object to copy in the skip list */ - addr_map = (H5O_addr_map_t *)H5SL_search(map_list, &(oloc_src->addr)); + addr_map = (H5O_addr_map_t *)H5SL_search(cpy_info->map_list, &(oloc_src->addr)); /* Check if address is already in list of objects copied */ if(addr_map == NULL) { /* Copy object for the first time */ + /* Check for incrementing the depth of copy */ + /* (Can't do this for all copies, since shared datatypes should always be copied) */ + if(inc_depth) + cpy_info->curr_depth++; + /* Copy object referred to */ - if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, cpy_option, map_list) < 0) + if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, cpy_info) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") + /* Check for incrementing the depth of copy */ + if(inc_depth) + cpy_info->curr_depth--; + /* When an object is copied for the first time, increment it's link */ inc_link = TRUE; } /* end if */ @@ -4470,10 +4502,10 @@ H5O_copy_free_addrmap_cb(void *item, void UNUSED *key, void UNUSED *op_data) *------------------------------------------------------------------------- */ herr_t -H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, - unsigned cpy_option) +H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, + hid_t dxpl_id, unsigned cpy_option) { - H5SL_t *map_list = NULL; /* Skip list to hold address mappings */ + H5O_copy_t cpy_info; /* Information for copying object */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(H5O_copy_header, FAIL) @@ -4483,17 +4515,35 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, hid_t d HDassert(H5F_addr_defined(oloc_src->addr)); HDassert(oloc_dst->file); + /* Convert copy flags into copy struct */ + HDmemset(&cpy_info, 0, sizeof(H5O_copy_t)); + if((cpy_option & H5G_COPY_SHALLOW_HIERARCHY_FLAG) > 0) { + cpy_info.copy_shallow = TRUE; + cpy_info.max_depth = 1; + } /* end if */ + else + cpy_info.max_depth = -1; /* Current default is for full, recursive hier. copy */ + cpy_info.curr_depth = 0; + if((cpy_option & H5G_COPY_EXPAND_SOFT_LINK_FLAG) > 0) + cpy_info.expand_soft_link = TRUE; + if((cpy_option & H5G_COPY_EXPAND_EXT_LINK_FLAG) > 0) + cpy_info.expand_ext_link = TRUE; + if((cpy_option & H5G_COPY_EXPAND_OBJ_REFERENCE_FLAG) > 0) + cpy_info.expand_obj_ref = TRUE; + if((cpy_option & H5G_COPY_WITHOUT_ATTR_FLAG) > 0) + cpy_info.copy_without_attr = TRUE; + /* Create a skip list to keep track of which objects are copied */ - if((map_list = H5SL_create(H5SL_TYPE_HADDR, 0.5, 16)) == NULL) + if((cpy_info.map_list = H5SL_create(H5SL_TYPE_HADDR, 0.5, 16)) == NULL) 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_option, map_list) < 0) + if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, &cpy_info) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") done: - if(map_list) - H5SL_destroy(map_list, H5O_copy_free_addrmap_cb, NULL); + if(cpy_info.map_list) + H5SL_destroy(cpy_info.map_list, H5O_copy_free_addrmap_cb, NULL); FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_copy_header() */ diff --git a/src/H5Oattr.c b/src/H5Oattr.c index eefc28b..d13216b 100644 --- a/src/H5Oattr.c +++ b/src/H5Oattr.c @@ -37,8 +37,10 @@ static herr_t H5O_attr_reset (void *_mesg); static herr_t H5O_attr_free (void *mesg); static herr_t H5O_attr_delete (H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link); static herr_t H5O_attr_link(H5F_t *f, hid_t dxpl_id, const void *_mesg); +static herr_t H5O_attr_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type, + void *mesg_src, hbool_t *deleted, const H5O_copy_t *cpy_info, void *udata); static void *H5O_attr_copy_file(H5F_t *file_src, void *native_src, - H5F_t *file_dst, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata); + H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata); static herr_t H5O_attr_debug (H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int indent, int fwidth); @@ -57,7 +59,7 @@ const H5O_msg_class_t H5O_MSG_ATTR[1] = {{ H5O_attr_link, /* link method */ NULL, /* get share method */ NULL, /* set share method */ - NULL, /* pre copy native value to file */ + H5O_attr_pre_copy_file, /* pre copy native value to file */ H5O_attr_copy_file, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_attr_debug /* debug the message */ @@ -635,6 +637,42 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_attr_pre_copy_file + * + * Purpose: Perform any necessary actions before copying message between + * files for attribute messages. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * Monday, June 26, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_attr_pre_copy_file(H5F_t UNUSED *file_src, const H5O_msg_class_t UNUSED *type, + void UNUSED *native_src, hbool_t *deleted, const H5O_copy_t *cpy_info, + void UNUSED *udata) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_attr_pre_copy_file) + + /* check args */ + HDassert(deleted); + HDassert(cpy_info); + + /* If we are not copying attributes into the destination file, indicate + * that this message should be deleted. + */ + if(cpy_info->copy_without_attr) + *deleted = TRUE; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O_attr_pre_copy_file() */ + + +/*------------------------------------------------------------------------- * Function: H5O_attr_copy_file * * Purpose: Copies a message from _MESG to _DEST in file @@ -654,7 +692,7 @@ done: */ static void * H5O_attr_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst, - hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void UNUSED *udata) + hid_t dxpl_id, H5O_copy_t *cpy_info, void UNUSED *udata) { H5A_t *attr_src = (H5A_t *)native_src; H5A_t *attr_dst = NULL; @@ -674,7 +712,8 @@ H5O_attr_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst, /* check args */ HDassert(attr_src); HDassert(file_dst); - HDassert(map_list); + HDassert(cpy_info); + HDassert(!cpy_info->copy_without_attr); /* Allocate space for the destination message */ if(NULL == (attr_dst = H5FL_CALLOC(H5A_t))) @@ -718,7 +757,7 @@ H5O_attr_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst, dst_oloc->file = file_dst; /* Copy the shared object from source to destination */ - if(H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, cpy_option, map_list) < 0) + if(H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, cpy_info, FALSE) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object") /* Reset shared message information */ diff --git a/src/H5Ocont.c b/src/H5Ocont.c index c4c8af3..6cb5735 100644 --- a/src/H5Ocont.c +++ b/src/H5Ocont.c @@ -42,7 +42,7 @@ static size_t H5O_cont_size(const H5F_t *f, const void *_mesg); static herr_t H5O_cont_free(void *mesg); static herr_t H5O_cont_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link); static void *H5O_cont_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, - hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata); + hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata); static herr_t H5O_cont_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int indent, int fwidth); @@ -260,7 +260,7 @@ done: */ static void * H5O_cont_copy_file(H5F_t UNUSED *file_src, void *mesg_src, H5F_t UNUSED *file_dst, - hid_t UNUSED dxpl_id, UNUSED unsigned cpy_option, H5SL_t UNUSED *map_list, void *udata) + hid_t UNUSED dxpl_id, H5O_copy_t UNUSED *cpy_info, void *udata) { H5O_cont_t *cont_src = (H5O_cont_t *) mesg_src; H5O_chunk_t *chunk = (H5O_chunk_t *)udata; diff --git a/src/H5Odtype.c b/src/H5Odtype.c index 9f44924..93470c5 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -32,13 +32,13 @@ static size_t H5O_dtype_size (const H5F_t *f, const void *_mesg); static herr_t H5O_dtype_reset (void *_mesg); static herr_t H5O_dtype_free (void *_mesg); static herr_t H5O_dtype_get_share (H5F_t *f, const void *_mesg, - H5O_shared_t *sh); + H5O_shared_t *sh); static herr_t H5O_dtype_set_share (H5F_t *f, void *_mesg, - const H5O_shared_t *sh); + const H5O_shared_t *sh); static herr_t H5O_dtype_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type, - void *mesg_src, void *_udata); + void *mesg_src, hbool_t *deleted, const H5O_copy_t *cpy_info, void *_udata); static herr_t H5O_dtype_debug (H5F_t *f, hid_t dxpl_id, const void *_mesg, - FILE * stream, int indent, int fwidth); + FILE * stream, int indent, int fwidth); /* This message derives from H5O message class */ const H5O_msg_class_t H5O_MSG_DTYPE[1] = {{ @@ -1216,7 +1216,9 @@ H5O_dtype_set_share(H5F_t UNUSED *f, void *_mesg/*in,out*/, *------------------------------------------------------------------------- */ static herr_t -H5O_dtype_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t UNUSED *type, void *mesg_src, void *_udata) +H5O_dtype_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t UNUSED *type, + void *mesg_src, hbool_t UNUSED *deleted, const H5O_copy_t UNUSED *cpy_info, + void *_udata) { H5T_t *dt_src = (H5T_t *)mesg_src; /* Source datatype */ H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; /* Dataset copying user data */ diff --git a/src/H5Oefl.c b/src/H5Oefl.c index 2fef999..afa46f1 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -34,7 +34,7 @@ static void *H5O_efl_copy(const void *_mesg, void *_dest, unsigned update_flags) static size_t H5O_efl_size(const H5F_t *f, const void *_mesg); static herr_t H5O_efl_reset(void *_mesg); static void *H5O_efl_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, - hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata); + hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata); static herr_t H5O_efl_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int indent, int fwidth); @@ -436,7 +436,7 @@ done: */ static void * H5O_efl_copy_file(H5F_t UNUSED *file_src, void *mesg_src, H5F_t *file_dst, - hid_t dxpl_id, UNUSED unsigned cpy_option, H5SL_t UNUSED *map_list, void UNUSED *_udata) + hid_t dxpl_id, H5O_copy_t UNUSED *cpy_info, void UNUSED *_udata) { H5O_efl_t *efl_src = (H5O_efl_t *) mesg_src; H5O_efl_t *efl_dst = NULL; diff --git a/src/H5Olayout.c b/src/H5Olayout.c index ffebfc6..b6008c8 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -40,7 +40,7 @@ static herr_t H5O_layout_reset(void *_mesg); static herr_t H5O_layout_free(void *_mesg); static herr_t H5O_layout_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link); static void *H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, - hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata); + hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata); static herr_t H5O_layout_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int indent, int fwidth); @@ -622,7 +622,7 @@ done: */ static void * H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, hid_t dxpl_id, - UNUSED unsigned cpy_option, H5SL_t UNUSED *map_list, void *_udata) + H5O_copy_t UNUSED *cpy_info, void *_udata) { H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; /* Dataset copying user data */ H5O_layout_t *layout_src = (H5O_layout_t *) mesg_src; diff --git a/src/H5Olinfo.c b/src/H5Olinfo.c index a14be2a..1b84191 100644 --- a/src/H5Olinfo.c +++ b/src/H5Olinfo.c @@ -40,6 +40,8 @@ static herr_t H5O_linfo_encode(H5F_t *f, uint8_t *p, const void *_mesg); static void *H5O_linfo_copy(const void *_mesg, void *_dest, unsigned update_flags); static size_t H5O_linfo_size(const H5F_t *f, const void *_mesg); static herr_t H5O_linfo_free(void *_mesg); +static void *H5O_linfo_copy_file(H5F_t *file_src, void *native_src, + H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata); static herr_t H5O_linfo_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int indent, int fwidth); @@ -59,7 +61,7 @@ const H5O_msg_class_t H5O_MSG_LINFO[1] = {{ NULL, /*get share method */ NULL, /*set share method */ NULL, /* pre copy native value to file */ - NULL, /* copy native value to file */ + H5O_linfo_copy_file, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_linfo_debug /*debug the message */ }}; @@ -266,6 +268,57 @@ H5O_linfo_free(void *mesg) /*------------------------------------------------------------------------- + * Function: H5O_linfo_copy_file + * + * Purpose: Copies a message from _MESG to _DEST in file + * + * Return: Success: Ptr to _DEST + * + * Failure: NULL + * + * Programmer: Quincey Koziol + * June 26, 2006 + * + *------------------------------------------------------------------------- + */ +static void * +H5O_linfo_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t UNUSED *file_dst, + hid_t UNUSED dxpl_id, H5O_copy_t *cpy_info, void UNUSED *udata) +{ + H5O_linfo_t *linfo_src = (H5O_linfo_t *) native_src; + H5O_linfo_t *linfo_dst = NULL; + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_linfo_copy_file) + + /* check args */ + HDassert(linfo_src); + HDassert(cpy_info); + + /* Copy the source message */ + if(NULL == (linfo_dst = H5O_linfo_copy(linfo_src, NULL, FALSE))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "memory allocation failed") + + /* If we are performing a 'shallow hierarchy' copy, and the links in this + * group won't be included in the destination, reset the link count for + * this group. + */ + if(cpy_info->max_depth >= 0 && cpy_info->curr_depth >= cpy_info->max_depth) + linfo_dst->nlinks = 0; + + /* Set return value */ + ret_value = linfo_dst; + +done: + if(!ret_value) + if(linfo_dst) + H5FL_FREE(H5O_linfo_t, linfo_dst); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O_linfo_copy_file() */ + + +/*------------------------------------------------------------------------- * Function: H5O_linfo_debug * * Purpose: Prints debugging info for a message. diff --git a/src/H5Olink.c b/src/H5Olink.c index 464f96b..bc45326 100644 --- a/src/H5Olink.c +++ b/src/H5Olink.c @@ -43,12 +43,14 @@ static size_t H5O_link_size(const H5F_t *f, const void *_mesg); static herr_t H5O_link_reset(void *_mesg); static herr_t H5O_link_free(void *_mesg); static herr_t H5O_link_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link); +static herr_t H5O_link_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type, + void *mesg_src, hbool_t *deleted, const H5O_copy_t *cpy_info, void *udata); static void *H5O_link_copy_file(H5F_t *file_src, void *native_src, - H5F_t *file_dst, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata); -static herr_t H5O_link_post_copy_file(H5F_t *file_src, const void *mesg_src, H5O_loc_t *dst_oloc, - void *mesg_dst, hbool_t *modified, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list); + H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata); +static herr_t H5O_link_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc, + void *mesg_dst, hbool_t *modified, hid_t dxpl_id, H5O_copy_t *cpy_info); static herr_t H5O_link_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, - FILE * stream, int indent, int fwidth); + FILE * stream, int indent, int fwidth); /* This message derives from H5O message class */ const H5O_msg_class_t H5O_MSG_LINK[1] = {{ @@ -65,7 +67,7 @@ const H5O_msg_class_t H5O_MSG_LINK[1] = {{ NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ - NULL, /* pre copy native value to file */ + H5O_link_pre_copy_file, /* pre copy native value to file */ H5O_link_copy_file, /* copy native value to file */ H5O_link_post_copy_file, /* post copy native value to file */ H5O_link_debug /*debug the message */ @@ -463,6 +465,44 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_link_pre_copy_file + * + * Purpose: Perform any necessary actions before copying message between + * files for link messages. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * Monday, June 26, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_link_pre_copy_file(H5F_t UNUSED *file_src, const H5O_msg_class_t UNUSED *type, + void UNUSED *native_src, hbool_t *deleted, const H5O_copy_t *cpy_info, + void UNUSED *udata) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_link_pre_copy_file) + + /* check args */ + HDassert(deleted); + HDassert(cpy_info); + + /* If we are performing a 'shallow hierarchy' copy, and this link won't + * be included in the final group, indicate that it should be deleted + * in the destination object header before performing any other actions + * on it. + */ + if(cpy_info->max_depth >= 0 && cpy_info->curr_depth >= cpy_info->max_depth) + *deleted = TRUE; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O_link_pre_copy_file() */ + + +/*------------------------------------------------------------------------- * Function: H5O_link_copy_file * * Purpose: Copies a message from _MESG to _DEST in file @@ -478,7 +518,7 @@ done: */ static void * H5O_link_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t UNUSED *file_dst, -hid_t UNUSED dxpl_id, UNUSED unsigned cpy_option, H5SL_t UNUSED *map_list, void UNUSED *udata) + hid_t UNUSED dxpl_id, H5O_copy_t UNUSED *cpy_info, void UNUSED *udata) { H5O_link_t *link_src = (H5O_link_t *) native_src; H5O_link_t *link_dst = NULL; @@ -489,6 +529,8 @@ hid_t UNUSED dxpl_id, UNUSED unsigned cpy_option, H5SL_t UNUSED *map_list, void /* check args */ HDassert(link_src); HDassert(file_dst); + HDassert(cpy_info); + HDassert(cpy_info->max_depth < 0 || cpy_info->curr_depth < cpy_info->max_depth); /* Allocate space for the destination stab */ if(NULL == (link_dst = H5FL_MALLOC(H5O_link_t))) @@ -543,10 +585,11 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O_link_post_copy_file(H5F_t *file_src, const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst, - hbool_t *modified, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list) +H5O_link_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst, + hbool_t *modified, hid_t dxpl_id, H5O_copy_t *cpy_info) { - const H5O_link_t *link_src = (const H5O_link_t *)mesg_src; + H5O_link_t *link_src = (H5O_link_t *)mesg_src; /* Casting away const OK... -QAK */ + H5O_link_t tmp_link_src; H5O_link_t *link_dst = (H5O_link_t *)mesg_dst; herr_t ret_value = SUCCEED; /* Return value */ @@ -559,7 +602,42 @@ H5O_link_post_copy_file(H5F_t *file_src, const void *mesg_src, H5O_loc_t *dst_ol HDassert(dst_oloc->file); HDassert(link_dst); HDassert(modified && *modified == FALSE); - HDassert(map_list); + HDassert(cpy_info); + HDassert(cpy_info->max_depth < 0 || cpy_info->curr_depth < cpy_info->max_depth); + + /* Expand soft link */ + if(H5G_LINK_SOFT == link_src->type && cpy_info->expand_soft_link) { + H5G_stat_t statbuf; /* Information about object pointed to by soft link */ + H5G_loc_t grp_loc; /* Group location for parent of soft link */ + H5G_name_t grp_path; /* Path for parent of soft link */ + + /* Make a temporary copy, so that it will not change the info in the cache */ + HDmemcpy(&tmp_link_src, link_src, sizeof(H5O_link_t)); + link_src = &tmp_link_src; + + /* Set up group location for soft link to start in */ + H5G_name_reset(&grp_path); + grp_loc.path = &grp_path; + grp_loc.oloc = (H5O_loc_t *)parent_src_oloc; /* Casting away const OK... -QAK */ + + /* Check if the object pointed by the soft link exists in the source file */ + /* (It would be more efficient to make a specialized traversal callback, + * but this is good enough for now... -QAK) + */ + if(H5G_get_objinfo(&grp_loc, link_src->u.soft.name, TRUE, &statbuf, H5AC_ind_dxpl_id) >= 0) { + /* Convert temp. copy of source soft link to hard link */ +#if H5_SIZEOF_UINT64_T > H5_SIZEOF_LONG + link_src->u.hard.addr = (((haddr_t)statbuf.objno[1]) << (8 * sizeof(long))) | (haddr_t)statbuf.objno[0]; +#else + link_src->u.hard.addr = statbuf.objno[0]; +#endif + link_src->type = H5G_LINK_HARD; + + /* Convert destination link to hard link */ + link_dst->type = H5G_LINK_HARD; + link_dst->u.soft.name = H5MM_xfree(link_dst->u.soft.name); + } /* end if */ + } /* if ((H5G_CACHED_SLINK == src_ent->type)... */ /* Additional "deep copy" for each kind of link */ switch(link_src->type) { @@ -571,7 +649,7 @@ H5O_link_post_copy_file(H5F_t *file_src, const void *mesg_src, H5O_loc_t *dst_ol /* Build temporary object location for source */ H5O_loc_reset(&src_oloc); - src_oloc.file = file_src; + src_oloc.file = parent_src_oloc->file; HDassert(H5F_addr_defined(link_src->u.hard.addr)); src_oloc.addr = link_src->u.hard.addr; @@ -580,8 +658,7 @@ H5O_link_post_copy_file(H5F_t *file_src, const void *mesg_src, H5O_loc_t *dst_ol new_oloc.file = dst_oloc->file; /* Copy the shared object from source to destination */ - /* (Increments link count on destination) */ - if(H5O_copy_header_map(&src_oloc, &new_oloc, dxpl_id, cpy_option, map_list) < 0) + if(H5O_copy_header_map(&src_oloc, &new_oloc, dxpl_id, cpy_info, TRUE) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") /* Update link information with new destination object's address */ diff --git a/src/H5Opkg.h b/src/H5Opkg.h index ec453f7..cdcfe0f 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -24,7 +24,6 @@ /* Other private headers needed by this file */ #include "H5ACprivate.h" /* Metadata cache */ -#include "H5SLprivate.h" /* Skip lists */ /* * Align messages on 8-byte boundaries because we would like to copy the @@ -73,9 +72,9 @@ struct H5O_msg_class_t { herr_t (*link)(H5F_t *, hid_t, const void *); /* Increment any links in file reference by this message */ herr_t (*get_share)(H5F_t*, const void*, struct H5O_shared_t*); /* Get shared information */ herr_t (*set_share)(H5F_t*, void*, const struct H5O_shared_t*); /* Set shared information */ - herr_t (*pre_copy_file)(H5F_t *, const H5O_msg_class_t *, void *, void *); /*"pre copy" action when copying native value to file */ - void *(*copy_file)(H5F_t *, void *, H5F_t *, hid_t, unsigned, H5SL_t *, void *); /*copy native value to file */ - herr_t (*post_copy_file)(H5F_t *, const void *, H5O_loc_t *, void *, hbool_t *, hid_t, unsigned, H5SL_t *); /*"post copy" action when copying native value to file */ + herr_t (*pre_copy_file)(H5F_t *, const H5O_msg_class_t *, void *, hbool_t *, const H5O_copy_t *, void *); /*"pre copy" action when copying native value to file */ + void *(*copy_file)(H5F_t *, void *, H5F_t *, hid_t, H5O_copy_t *, void *); /*copy native value to file */ + herr_t (*post_copy_file)(const H5O_loc_t *, const void *, H5O_loc_t *, void *, hbool_t *, hid_t, H5O_copy_t *); /*"post copy" action when copying native value to file */ herr_t (*debug)(H5F_t*, hid_t, const void*, FILE*, int, int); }; diff --git a/src/H5Opline.c b/src/H5Opline.c index d27cfb2..9658e07 100644 --- a/src/H5Opline.c +++ b/src/H5Opline.c @@ -37,9 +37,9 @@ static size_t H5O_pline_size (const H5F_t *f, const void *_mesg); static herr_t H5O_pline_reset (void *_mesg); static herr_t H5O_pline_free (void *_mesg); static herr_t H5O_pline_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type, - void *mesg_src, void *_udata); + void *mesg_src, hbool_t *deleted, const H5O_copy_t *cpy_info, void *_udata); static herr_t H5O_pline_debug (H5F_t *f, hid_t dxpl_id, const void *_mesg, - FILE * stream, int indent, int fwidth); + FILE * stream, int indent, int fwidth); /* This message derives from H5O message class */ const H5O_msg_class_t H5O_MSG_PLINE[1] = {{ @@ -441,7 +441,9 @@ H5O_pline_free (void *mesg) *------------------------------------------------------------------------- */ static herr_t -H5O_pline_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t UNUSED *type, void *mesg_src, void *_udata) +H5O_pline_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t UNUSED *type, + void *mesg_src, hbool_t UNUSED *deleted, const H5O_copy_t UNUSED *cpy_info, + void *_udata) { H5O_pline_t *pline_src = (H5O_pline_t *)mesg_src; /* Source datatype */ H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; /* Dataset copying user data */ diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index a0f2bbd..ee3f5da 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -36,6 +36,7 @@ /* Private headers needed by this file */ #include "H5Fprivate.h" /* File access */ +#include "H5SLprivate.h" /* Skip lists */ #include "H5Tprivate.h" /* Datatype functions */ #include "H5Zprivate.h" /* I/O pipeline filters */ @@ -65,6 +66,18 @@ typedef struct H5O_loc_t { haddr_t addr; /* File address of object header */ } H5O_loc_t; +/* Settings/flags for copying an object */ +typedef struct H5O_copy_t { + hbool_t copy_shallow; /* Flag to perform shallow hierarchy copy */ + hbool_t expand_soft_link; /* Flag to expand soft links */ + hbool_t expand_ext_link; /* Flag to expand external links */ + hbool_t expand_obj_ref; /* Flag to expand object references */ + hbool_t copy_without_attr; /* Flag to not copy attributes */ + int curr_depth; /* Current depth in hierarchy copied */ + int max_depth; /* Maximum depth in hierarchy to copy */ + H5SL_t *map_list; /* Skip list to hold address mappings */ +} H5O_copy_t; + /* Header message IDs */ #define H5O_NULL_ID 0x0000 /* Null Message. */ #define H5O_SDSPACE_ID 0x0001 /* Simple Dataspace Message. */ @@ -347,7 +360,7 @@ H5_DLL H5G_obj_t H5O_obj_type(H5O_loc_t *loc, hid_t dxpl_id); H5_DLL herr_t H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, unsigned cpy_option); H5_DLL herr_t H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, - hid_t dxpl_id, unsigned cpy_option, struct H5SL_t *map_list); + hid_t dxpl_id, H5O_copy_t *cpy_info, hbool_t inc_depth); H5_DLL herr_t H5O_debug_id(unsigned type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, int indent, int fwidth); H5_DLL herr_t H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int fwidth); diff --git a/src/H5Oshared.c b/src/H5Oshared.c index ccdb61c..dc5ea6f 100644 --- a/src/H5Oshared.c +++ b/src/H5Oshared.c @@ -43,9 +43,9 @@ static size_t H5O_shared_size (const H5F_t*, const void *_mesg); static herr_t H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link); static herr_t H5O_shared_link(H5F_t *f, hid_t dxpl_id, const void *_mesg); static herr_t H5O_shared_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type, - void *mesg_src, void *_udata); + void *mesg_src, hbool_t *deleted, const H5O_copy_t *cpy_info, void *_udata); static void *H5O_shared_copy_file(H5F_t *file_src, void *native_src, - H5F_t *file_dst, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata); + H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata); static herr_t H5O_shared_debug (H5F_t*, hid_t dxpl_id, const void*, FILE*, int, int); /* This message derives from H5O message class */ @@ -429,7 +429,7 @@ done: */ static void * H5O_shared_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst, - hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void UNUSED *udata) + hid_t dxpl_id, H5O_copy_t *cpy_info, void UNUSED *udata) { H5O_shared_t *shared_src = (H5O_shared_t *)native_src; H5O_shared_t *shared_dst = NULL; @@ -440,7 +440,7 @@ H5O_shared_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst, /* check args */ HDassert(shared_src); HDassert(file_dst); - HDassert(map_list); + HDassert(cpy_info); /* Allocate space for the destination message */ if(NULL == (shared_dst = H5MM_malloc(sizeof(H5O_shared_t)))) @@ -451,7 +451,7 @@ H5O_shared_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst, shared_dst->oloc.file = file_dst; /* Copy the shared object from source to destination */ - if(H5O_copy_header_map(&(shared_src->oloc), &(shared_dst->oloc), dxpl_id, cpy_option, map_list) < 0) + if(H5O_copy_header_map(&(shared_src->oloc), &(shared_dst->oloc), dxpl_id, cpy_info, FALSE) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object") /* Set return value */ @@ -482,28 +482,30 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O_shared_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type, void *native_src, void *udata) +H5O_shared_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type, + void *native_src, hbool_t *deleted, const H5O_copy_t *cpy_info, + void *udata) { H5O_shared_t *shared_src = (H5O_shared_t *)native_src; void *mesg_native = NULL; - hid_t dxpl_id = H5AC_dxpl_id; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_shared_pre_copy_file) + /* check args */ + HDassert(file_src); + HDassert(type); + if(type->pre_copy_file) { - if((mesg_native = H5O_read_real(&(shared_src->oloc), type, 0, NULL, dxpl_id)) == NULL) + /* Go get the actual shared message */ + if((mesg_native = H5O_read_real(&(shared_src->oloc), type, 0, NULL, H5AC_dxpl_id)) == NULL) HGOTO_ERROR(H5E_OHDR, H5E_READERROR, FAIL, "unable to load object header") /* Perform "pre copy" operation on messge */ - if((type->pre_copy_file)(file_src, type, mesg_native, udata) < 0) + if((type->pre_copy_file)(file_src, type, mesg_native, deleted, cpy_info, udata) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to perform 'pre copy' operation on message") } /* end of if */ - /* check args */ - HDassert(file_src); - HDassert(type); - done: if(mesg_native) H5O_free_real(type, mesg_native); diff --git a/src/H5Ostab.c b/src/H5Ostab.c index 241bd94..7516afd 100644 --- a/src/H5Ostab.c +++ b/src/H5Ostab.c @@ -44,9 +44,9 @@ static size_t H5O_stab_size(const H5F_t *f, const void *_mesg); static herr_t H5O_stab_free(void *_mesg); static herr_t H5O_stab_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link); static void *H5O_stab_copy_file(H5F_t *file_src, void *native_src, - H5F_t *file_dst, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata); -static herr_t H5O_stab_post_copy_file(H5F_t *file_src, const void *mesg_src, H5O_loc_t *dst_oloc, - void *mesg_dst, hbool_t *modified, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list); + H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata); +static herr_t H5O_stab_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc, + void *mesg_dst, hbool_t *modified, hid_t dxpl_id, H5O_copy_t *cpy_info); static herr_t H5O_stab_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int indent, int fwidth); @@ -312,7 +312,7 @@ done: */ static void * H5O_stab_copy_file(H5F_t *file_src, void *native_src, H5F_t *file_dst, - hid_t dxpl_id, UNUSED unsigned cpy_option, H5SL_t UNUSED *map_list, void UNUSED *udata) + hid_t dxpl_id, H5O_copy_t UNUSED *cpy_info, void UNUSED *udata) { H5O_stab_t *stab_src = (H5O_stab_t *) native_src; H5O_stab_t *stab_dst = NULL; @@ -362,12 +362,13 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O_stab_post_copy_file(H5F_t *file_src, const void *mesg_src, H5O_loc_t *dst_oloc, -void *mesg_dst, hbool_t UNUSED *modified, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list) +H5O_stab_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc, + void *mesg_dst, hbool_t UNUSED *modified, hid_t dxpl_id, H5O_copy_t *cpy_info) { H5G_bt_it_ud5_t udata; /* B-tree user data */ const H5O_stab_t *stab_src = (const H5O_stab_t *)mesg_src; H5O_stab_t *stab_dst = (H5O_stab_t *)mesg_dst; + H5F_t *file_src = parent_src_oloc->file; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_stab_post_copy_file) @@ -378,14 +379,18 @@ void *mesg_dst, hbool_t UNUSED *modified, hid_t dxpl_id, unsigned cpy_option, H5 HDassert(H5F_addr_defined(dst_oloc->addr)); HDassert(dst_oloc->file); HDassert(stab_dst); - HDassert(map_list); + HDassert(cpy_info); + + /* If we are performing a 'shallow hierarchy' copy, get out now */ + if(cpy_info->max_depth >= 0 && cpy_info->curr_depth >= cpy_info->max_depth) + HGOTO_DONE(SUCCEED) /* Set up B-tree iteration user data */ - udata.map_list = map_list; + udata.src_oloc = (H5O_loc_t *)parent_src_oloc; /* Casting away const OK - QAK */ udata.src_heap_addr = stab_src->heap_addr; udata.dst_file = dst_oloc->file; udata.dst_stab = stab_dst; - udata.cpy_option = cpy_option; + udata.cpy_info = cpy_info; /* Iterate over objects in group, copying them */ if((H5B_iterate(file_src, dxpl_id, H5B_SNODE, H5G_node_copy, stab_src->btree_addr, &udata)) < 0) |