diff options
author | Neil Fortner <nfortne2@hdfgroup.org> | 2010-09-21 17:52:12 (GMT) |
---|---|---|
committer | Neil Fortner <nfortne2@hdfgroup.org> | 2010-09-21 17:52:12 (GMT) |
commit | 2087c6a9e49daa4d160fdbd79230bb3b36e63c30 (patch) | |
tree | a3f6011efa1a9369fd33d1fffa09365edc696ac5 | |
parent | 95bc60ceb48bf6cd508691dd94be071b190fa74a (diff) | |
download | hdf5-2087c6a9e49daa4d160fdbd79230bb3b36e63c30.zip hdf5-2087c6a9e49daa4d160fdbd79230bb3b36e63c30.tar.gz hdf5-2087c6a9e49daa4d160fdbd79230bb3b36e63c30.tar.bz2 |
[svn-r19461] Purpose: Fix bug 1864
Description:
Library versions 1.6.3 and earlier contain a bug which causes them to be unable
to perform certain operations on a group if that group's symbol table
information is not cached in the parent group's symbol table. Versions 1.8.0
to 1.8.5 did not cache this information. Modified library to cache this
information.
Tested: jam, amani, heiwa (h5committest)
-rw-r--r-- | release_docs/RELEASE.txt | 5 | ||||
-rw-r--r-- | src/H5Aint.c | 3 | ||||
-rw-r--r-- | src/H5G.c | 16 | ||||
-rw-r--r-- | src/H5Gent.c | 85 | ||||
-rw-r--r-- | src/H5Glink.c | 5 | ||||
-rw-r--r-- | src/H5Gloc.c | 5 | ||||
-rw-r--r-- | src/H5Gnode.c | 24 | ||||
-rw-r--r-- | src/H5Gobj.c | 29 | ||||
-rw-r--r-- | src/H5Goh.c | 2 | ||||
-rw-r--r-- | src/H5Gpkg.h | 41 | ||||
-rw-r--r-- | src/H5Gprivate.h | 5 | ||||
-rw-r--r-- | src/H5Groot.c | 9 | ||||
-rw-r--r-- | src/H5Gstab.c | 11 | ||||
-rw-r--r-- | src/H5Gtraverse.c | 10 | ||||
-rw-r--r-- | src/H5L.c | 8 | ||||
-rw-r--r-- | src/H5Ocopy.c | 66 | ||||
-rw-r--r-- | src/H5Opkg.h | 2 | ||||
-rw-r--r-- | src/H5Oprivate.h | 3 | ||||
-rw-r--r-- | src/H5Oshared.c | 3 | ||||
-rw-r--r-- | src/H5Ostab.c | 12 |
20 files changed, 269 insertions, 75 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 2a05771..32dcf1f 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -248,9 +248,12 @@ Bug Fixes since HDF5-1.8.0 release Library ------- + - Modified library to always cache symbol table information. Libraries + version 1.6.3 have a bug which causes them to require this + information for some operations. (NAF - 2010/09/21 - 1864) - H5Eset_auto causes a seg fault when an application uses -DH5_USE_16_API to compile with the library. The problem is fixed and the behavior - of H5Eget_auto is modified (Bug #1707). (SLU - 2010/9/21) + of H5Eget_auto is modified (Bug #1707). (SLU - 2010/9/21) - Fixed a bug that could occur when getting information for a new-style group that was previously opened through a file handle that was later closed. (NAF - 2010/09/15) diff --git a/src/H5Aint.c b/src/H5Aint.c index 30d662e..3ffc6d3 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -872,7 +872,8 @@ H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_si 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_info, FALSE) < 0) + if(H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, cpy_info, FALSE, + NULL, NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object") /* Update shared message info from named datatype info */ @@ -256,6 +256,8 @@ H5G_create_named(const H5G_loc_t *loc, const char *name, hid_t lcpl_id, /* Set up group creation info */ gcrt_info.gcpl_id = gcpl_id; + gcrt_info.cache_type = H5G_NOTHING_CACHED; + HDmemset(&gcrt_info.cache, 0, sizeof(gcrt_info.cache)); /* Set up object creation information */ ocrt_info.obj_type = H5O_TYPE_GROUP; @@ -315,6 +317,7 @@ H5Gcreate_anon(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id) { H5G_loc_t loc; H5G_t *grp = NULL; + H5G_obj_create_t gcrt_info; /* Information for group creation */ hid_t ret_value; FUNC_ENTER_API(H5Gcreate_anon, FAIL) @@ -338,8 +341,13 @@ H5Gcreate_anon(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id) if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list") + /* Set up group creation info */ + gcrt_info.gcpl_id = gcpl_id; + gcrt_info.cache_type = H5G_NOTHING_CACHED; + HDmemset(&gcrt_info.cache, 0, sizeof(gcrt_info.cache)); + /* Create the new group & get its ID */ - if(NULL == (grp = H5G_create(loc.oloc->file, gcpl_id, H5AC_dxpl_id))) + if(NULL == (grp = H5G_create(loc.oloc->file, &gcrt_info, H5AC_dxpl_id))) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") @@ -853,7 +861,7 @@ H5G_term_interface(void) *------------------------------------------------------------------------- */ H5G_t * -H5G_create(H5F_t *file, hid_t gcpl_id, hid_t dxpl_id) +H5G_create(H5F_t *file, H5G_obj_create_t *gcrt_info, hid_t dxpl_id) { H5G_t *grp = NULL; /*new group */ unsigned oloc_init = 0; /* Flag to indicate that the group object location was created successfully */ @@ -863,7 +871,7 @@ H5G_create(H5F_t *file, hid_t gcpl_id, hid_t dxpl_id) /* check args */ HDassert(file); - HDassert(gcpl_id != H5P_DEFAULT); + HDassert(gcrt_info->gcpl_id != H5P_DEFAULT); HDassert(dxpl_id != H5P_DEFAULT); /* create an open group */ @@ -873,7 +881,7 @@ H5G_create(H5F_t *file, hid_t gcpl_id, hid_t dxpl_id) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Create the group object header */ - if(H5G_obj_create(file, dxpl_id, gcpl_id, &(grp->oloc)/*out*/) < 0) + if(H5G_obj_create(file, dxpl_id, gcrt_info, &(grp->oloc)/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create group object header") oloc_init = 1; /* Indicate that the object location information is valid */ diff --git a/src/H5Gent.c b/src/H5Gent.c index a2e6159..cec788c 100644 --- a/src/H5Gent.c +++ b/src/H5Gent.c @@ -352,7 +352,8 @@ H5G_ent_reset(H5G_entry_t *ent) */ herr_t H5G_ent_convert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, const char *name, - const H5O_link_t *lnk, H5G_entry_t *ent) + const H5O_link_t *lnk, H5O_type_t obj_type, const void *crt_info, + H5G_entry_t *ent) { size_t name_offset; /* Offset of name in heap */ herr_t ret_value = SUCCEED; /* Return value */ @@ -373,13 +374,91 @@ H5G_ent_convert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, const char *name, */ name_offset = H5HL_insert(f, dxpl_id, heap, HDstrlen(name) + 1, name); if(0 == name_offset || (size_t)(-1) == name_offset) - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_INS_ERROR, "unable to insert symbol name into heap") + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert symbol name into heap") ent->name_off = name_offset; /* Build correct information for symbol table entry based on link type */ switch(lnk->type) { case H5L_TYPE_HARD: - ent->type = H5G_NOTHING_CACHED; + if(obj_type == H5O_TYPE_GROUP) { + const H5G_obj_create_t *gcrt_info = (const H5G_obj_create_t *)crt_info; + + ent->type = gcrt_info->cache_type; + if(ent->type != H5G_NOTHING_CACHED) + ent->cache = gcrt_info->cache; +#ifndef NDEBUG + else { + /* Make sure there is no stab message in the target object + */ + H5O_loc_t targ_oloc; /* Location of link target */ + htri_t stab_exists; /* Whether the target symbol table exists */ + + /* Build target object location */ + if(H5O_loc_reset(&targ_oloc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRESET, FAIL, "unable to initialize target location") + targ_oloc.file = f; + targ_oloc.addr = lnk->u.hard.addr; + + /* Check if a symbol table message exists */ + if((stab_exists = H5O_msg_exists(&targ_oloc, H5O_STAB_ID, + dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for STAB message") + + HDassert(!stab_exists); + } /* end else */ +#endif /* NDEBUG */ + } /* end if */ + else if(obj_type == H5O_TYPE_UNKNOWN){ + /* Try to retrieve symbol table information for caching */ + H5O_loc_t targ_oloc; /* Location of link target */ + H5O_t *oh; /* Link target object header */ + H5O_stab_t stab; /* Link target symbol table */ + htri_t stab_exists; /* Whether the target symbol table exists */ + + /* Build target object location */ + if(H5O_loc_reset(&targ_oloc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRESET, FAIL, "unable to initialize target location") + targ_oloc.file = f; + targ_oloc.addr = lnk->u.hard.addr; + + /* Get the object header */ + if(NULL == (oh = H5O_protect(&targ_oloc, dxpl_id, H5AC_READ))) + HGOTO_ERROR(H5E_SYM, H5E_CANTPROTECT, FAIL, "unable to protect target object header") + + /* Check if a symbol table message exists */ + if((stab_exists = H5O_msg_exists_oh(oh, H5O_STAB_ID)) < 0) { + if(H5O_unprotect(&targ_oloc, dxpl_id, oh, H5AC__NO_FLAGS_SET) + < 0) + HERROR(H5E_SYM, H5E_CANTUNPROTECT, "unable to release object header"); + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for STAB message") + } /* end if */ + + if(stab_exists) { + /* Read symbol table message */ + if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_STAB_ID, + &stab)) { + if(H5O_unprotect(&targ_oloc, dxpl_id, oh, + H5AC__NO_FLAGS_SET) < 0) + HERROR(H5E_SYM, H5E_CANTUNPROTECT, "unable to release object header"); + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read STAB message") + } /* end if */ + + /* Cache symbol table message */ + ent->type = H5G_CACHED_STAB; + ent->cache.stab.btree_addr = stab.btree_addr; + ent->cache.stab.heap_addr = stab.heap_addr; + } /* end if */ + else + /* No symbol table message, don't cache anything */ + ent->type = H5G_NOTHING_CACHED; + + if(H5O_unprotect(&targ_oloc, dxpl_id, oh, H5AC__NO_FLAGS_SET) + < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTUNPROTECT, FAIL, "unable to release object header") + } /* end else */ + else + ent->type = H5G_NOTHING_CACHED; + ent->header = lnk->u.hard.addr; break; diff --git a/src/H5Glink.c b/src/H5Glink.c index d8e87b3..0049bfd 100644 --- a/src/H5Glink.c +++ b/src/H5Glink.c @@ -491,7 +491,10 @@ H5G_link_copy_file(H5F_t *dst_file, hid_t dxpl_id, const H5O_link_t *_src_lnk, HDassert(H5F_addr_defined(tmp_src_oloc.addr)); /* Copy the shared object from source to destination */ - if(H5O_copy_header_map(&tmp_src_oloc, &new_dst_oloc, dxpl_id, cpy_info, TRUE) < 0) + /* Don't care about obj_type or udata because those are only important + * for old style groups */ + if(H5O_copy_header_map(&tmp_src_oloc, &new_dst_oloc, dxpl_id, cpy_info, + TRUE, NULL, NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") /* Copy new destination object's information for eventual insertion */ diff --git a/src/H5Gloc.c b/src/H5Gloc.c index d95d705..82b7575 100644 --- a/src/H5Gloc.c +++ b/src/H5Gloc.c @@ -609,7 +609,7 @@ done: */ herr_t H5G_loc_insert(H5G_loc_t *grp_loc, const char *name, H5G_loc_t *obj_loc, - hid_t dxpl_id) + H5O_type_t obj_type, const void *crt_info, hid_t dxpl_id) { H5O_link_t lnk; /* Link for object to insert */ herr_t ret_value = SUCCEED; /* Return value */ @@ -631,7 +631,8 @@ H5G_loc_insert(H5G_loc_t *grp_loc, const char *name, H5G_loc_t *obj_loc, lnk.u.hard.addr = obj_loc->oloc->addr; /* Insert new group into current group's symbol table */ - if(H5G_obj_insert(grp_loc->oloc, name, &lnk, TRUE, dxpl_id) < 0) + if(H5G_obj_insert(grp_loc->oloc, name, &lnk, TRUE, obj_type, crt_info, + dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert object") /* Set the name of the object location */ diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 2b793a9..5a2d736 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -640,7 +640,8 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, idx += cmp > 0 ? 1 : 0; /* Convert link information & name to symbol table entry */ - if(H5G_ent_convert(f, dxpl_id, udata->common.heap, udata->common.name, udata->lnk, &ent) < 0) + if(H5G_ent_convert(f, dxpl_id, udata->common.heap, udata->common.name, + udata->lnk, udata->obj_type, udata->crt_info, &ent) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, H5B_INS_ERROR, "unable to convert link") /* Determine where to place entry in node */ @@ -1238,6 +1239,9 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, H5O_link_t lnk; /* Link to insert */ const char *name; /* Name of source object */ H5G_entry_t tmp_src_ent; /* Temperary copy. Change will not affect the cache */ + H5O_type_t obj_type; /* Target object type */ + H5G_copy_file_ud_t *cpy_udata; /* Copy file udata */ + H5G_obj_create_t gcrt_info; /* Group creation info */ /* expand soft link */ if(H5G_CACHED_SLINK == src_ent->type && cpy_info->expand_soft_link) { @@ -1281,15 +1285,27 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, tmp_src_oloc.addr = src_ent->header; /* Copy the shared object from source to destination */ - if(H5O_copy_header_map(&tmp_src_oloc, &new_dst_oloc, dxpl_id, cpy_info, TRUE) < 0) + if(H5O_copy_header_map(&tmp_src_oloc, &new_dst_oloc, dxpl_id, + cpy_info, TRUE, &obj_type, (void **)&cpy_udata) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy object") + /* Set up object creation info for symbol table insertion. Only + * case so far is for inserting old-style groups (for caching stab + * info). */ + if(obj_type == H5O_TYPE_GROUP) { + gcrt_info.gcpl_id = H5P_DEFAULT; + gcrt_info.cache_type = cpy_udata->cache_type; + gcrt_info.cache = cpy_udata->cache; + } /* end if */ + /* Construct link information for eventual insertion */ lnk.type = H5L_TYPE_HARD; lnk.u.hard.addr = new_dst_oloc.addr; } /* ( H5F_addr_defined(src_ent->header)) */ else if(H5G_CACHED_SLINK == src_ent->type) { /* it is a soft link */ + /* Set object type to unknown */ + obj_type = H5O_TYPE_UNKNOWN; /* Construct link information for eventual insertion */ lnk.type = H5L_TYPE_SOFT; @@ -1313,7 +1329,9 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, /* Insert the new object in the destination file's group */ /* (Don't increment the link count - that's already done above for hard links) */ - if(H5G_stab_insert_real(udata->dst_file, udata->dst_stab, name, &lnk, dxpl_id) < 0) + if(H5G_stab_insert_real(udata->dst_file, udata->dst_stab, name, &lnk, + obj_type, (obj_type == H5O_TYPE_GROUP ? &gcrt_info : NULL), + dxpl_id) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5_ITER_ERROR, "unable to insert the name") /* Reset metadata tag */ diff --git a/src/H5Gobj.c b/src/H5Gobj.c index 0dcf015..ce11990 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -126,7 +126,8 @@ static herr_t H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, *------------------------------------------------------------------------- */ herr_t -H5G_obj_create(H5F_t *f, hid_t dxpl_id, hid_t gcpl_id, H5O_loc_t *oloc/*out*/) +H5G_obj_create(H5F_t *f, hid_t dxpl_id, H5G_obj_create_t *gcrt_info, + H5O_loc_t *oloc/*out*/) { H5P_genplist_t *gc_plist; /* Group creation property list */ H5O_ginfo_t ginfo; /* Group info */ @@ -143,7 +144,7 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, hid_t gcpl_id, H5O_loc_t *oloc/*out*/) HDassert(oloc); /* Get the property list */ - if(NULL == (gc_plist = (H5P_genplist_t *)H5I_object(gcpl_id))) + if(NULL == (gc_plist = (H5P_genplist_t *)H5I_object(gcrt_info->gcpl_id))) HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "not a property list") /* Get the group info property */ @@ -159,7 +160,8 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, hid_t gcpl_id, H5O_loc_t *oloc/*out*/) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get group info") /* Call the "real" group creation routine now */ - if(H5G_obj_create_real(f, dxpl_id, &ginfo, &linfo, &pline, gcpl_id, oloc) < 0) + if(H5G_obj_create_real(f, dxpl_id, &ginfo, &linfo, &pline, gcrt_info, oloc) + < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "unable to create group") done: @@ -182,11 +184,12 @@ done: */ herr_t H5G_obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, - const H5O_linfo_t *linfo, const H5O_pline_t *pline, hid_t gcpl_id, - H5O_loc_t *oloc/*out*/) + const H5O_linfo_t *linfo, const H5O_pline_t *pline, + H5G_obj_create_t *gcrt_info, H5O_loc_t *oloc/*out*/) { size_t hdr_size; /* Size of object header to request */ hbool_t use_latest_format; /* Flag indicating the new group format should be used */ + hid_t gcpl_id = gcrt_info->gcpl_id; /* Group creation property list ID */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_obj_create_real, FAIL) @@ -285,6 +288,11 @@ H5G_obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, /* The group doesn't currently have a 'stab' message, go create one */ if(H5G_stab_create(oloc, dxpl_id, ginfo, &stab) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create symbol table") + + /* Cache the symbol table information */ + gcrt_info->cache_type = H5G_CACHED_STAB; + gcrt_info->cache.stab.btree_addr = stab.btree_addr; + gcrt_info->cache.stab.heap_addr = stab.heap_addr; } /* end else */ done: @@ -421,7 +429,8 @@ H5G_obj_stab_to_new_cb(const H5O_link_t *lnk, void *_udata) /* Insert link into group */ /* (Casting away const OK - QAK) */ - if(H5G_obj_insert(udata->grp_oloc, lnk->name, (H5O_link_t *)lnk, FALSE, udata->dxpl_id) < 0) + if(H5G_obj_insert(udata->grp_oloc, lnk->name, (H5O_link_t *)lnk, FALSE, + H5O_TYPE_UNKNOWN, NULL, udata->dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5_ITER_ERROR, "can't insert link into group") done: @@ -448,7 +457,7 @@ done: */ herr_t H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, - hbool_t adj_link, hid_t dxpl_id) + hbool_t adj_link, H5O_type_t obj_type, const void *crt_info, hid_t dxpl_id) { H5O_pline_t tmp_pline; /* Pipeline message */ H5O_pline_t *pline = NULL; /* Pointer to pipeline message */ @@ -572,7 +581,8 @@ H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, * group is in the "new format" now and the link info should be * set up, etc. */ - if(H5G_obj_insert(grp_oloc, name, obj_lnk, adj_link, dxpl_id) < 0) + if(H5G_obj_insert(grp_oloc, name, obj_lnk, adj_link, obj_type, + crt_info, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert link into group") /* Done with insertion now */ @@ -585,7 +595,8 @@ H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, /* Insert into symbol table or "dense" storage */ if(use_old_format) { /* Insert into symbol table */ - if(H5G_stab_insert(grp_oloc, name, obj_lnk, dxpl_id) < 0) + if(H5G_stab_insert(grp_oloc, name, obj_lnk, obj_type, crt_info, dxpl_id) + < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry into symbol table") } /* end if */ else { diff --git a/src/H5Goh.c b/src/H5Goh.c index 4dc569c..fc7a1df 100644 --- a/src/H5Goh.c +++ b/src/H5Goh.c @@ -263,7 +263,7 @@ H5O_group_create(H5F_t *f, void *_crt_info, H5G_loc_t *obj_loc, hid_t dxpl_id) HDassert(obj_loc); /* Create the the group */ - if(NULL == (grp = H5G_create(f, crt_info->gcpl_id, dxpl_id))) + if(NULL == (grp = H5G_create(f, crt_info, dxpl_id))) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create group") /* Set up the new group's location */ diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index 82aa2e0..f9bc41e 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -200,8 +200,10 @@ typedef struct H5G_bt_common_t { */ typedef struct H5G_bt_ins_t { /* downward */ - H5G_bt_common_t common; /* Common info for B-tree user data (must be first) */ + H5G_bt_common_t common; /* Common info for B-tree user data (must be first) */ const H5O_link_t *lnk; /* Link to insert into table */ + H5O_type_t obj_type; /* Type of object being inserted */ + const void *crt_info; /* Creation info for object being inserted */ } H5G_bt_ins_t; /* @@ -331,10 +333,19 @@ typedef herr_t (*H5G_traverse_t)(H5G_loc_t *grp_loc/*in*/, const char *name, H5G_own_loc_t *own_loc/*out*/); /* Typedef for group creation operation */ -typedef struct { +typedef struct H5G_obj_create_t{ hid_t gcpl_id; /* Group creation property list */ + H5G_cache_type_t cache_type; /* Type of symbol table entry cache */ + H5G_cache_t cache; /* Cached data for symbol table entry */ } H5G_obj_create_t; +/* Callback information for copying groups */ +typedef struct H5G_copy_file_ud_t { + H5O_copy_file_ud_common_t common; /* Shared information (must be first) */ + H5G_cache_type_t cache_type; /* Type of symbol table entry cache */ + H5G_cache_t cache; /* Cached data for symbol table entry */ +} H5G_copy_file_ud_t; + /*****************************/ /* Package Private Variables */ @@ -367,7 +378,8 @@ H5FL_EXTERN(H5G_shared_t); /* * General group routines */ -H5_DLL H5G_t *H5G_create(H5F_t *file, hid_t gcpl_id, hid_t dxpl_id); +H5_DLL H5G_t *H5G_create(H5F_t *file, H5G_obj_create_t *gcrt_info, + hid_t dxpl_id); H5_DLL H5G_t *H5G_create_named(const H5G_loc_t *loc, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id); H5_DLL H5G_t *H5G_open_name(const H5G_loc_t *loc, const char *name, @@ -403,9 +415,11 @@ H5_DLL herr_t H5G_stab_create(H5O_loc_t *grp_oloc, hid_t dxpl_id, const H5O_ginfo_t *ginfo, H5O_stab_t *stab); H5_DLL herr_t H5G_stab_create_components(H5F_t *f, H5O_stab_t *stab, size_t size_hint, hid_t dxpl_id); H5_DLL herr_t H5G_stab_insert(const H5O_loc_t *grp_oloc, const char *name, - H5O_link_t *obj_lnk, hid_t dxpl_id); + H5O_link_t *obj_lnk, H5O_type_t obj_type, const void *crt_info, + hid_t dxpl_id); H5_DLL herr_t H5G_stab_insert_real(H5F_t *f, H5O_stab_t *stab, const char *name, - H5O_link_t *obj_lnk, hid_t dxpl_id); + H5O_link_t *obj_lnk, H5O_type_t obj_type, const void *crt_info, + hid_t dxpl_id); H5_DLL herr_t H5G_stab_delete(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab); H5_DLL herr_t H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op, void *op_data); @@ -443,7 +457,8 @@ H5_DLL herr_t H5G_ent_decode_vec(const H5F_t *f, const uint8_t **pp, H5_DLL herr_t H5G_ent_encode_vec(const H5F_t *f, uint8_t **pp, const H5G_entry_t *ent, unsigned n); H5_DLL herr_t H5G_ent_convert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, - const char *name, const H5O_link_t *lnk, H5G_entry_t *ent); + const char *name, const H5O_link_t *lnk, H5O_type_t obj_type, + const void *crt_info, H5G_entry_t *ent); H5_DLL herr_t H5G_ent_debug(const H5G_entry_t *ent, FILE * stream, int indent, int fwidth, const H5HL_t *heap); @@ -539,15 +554,17 @@ H5_DLL H5G_obj_t H5G_dense_get_type_by_idx(H5F_t *f, hid_t dxpl_id, #endif /* H5_NO_DEPRECATED_SYMBOLS */ /* Functions that understand group objects */ -H5_DLL herr_t H5G_obj_create(H5F_t *f, hid_t dxpl_id, hid_t gcpl_id, - H5O_loc_t *oloc/*out*/); -H5_DLL herr_t H5G_obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, - const H5O_linfo_t *linfo, const H5O_pline_t *pline, hid_t gcpl_id, +H5_DLL herr_t H5G_obj_create(H5F_t *f, hid_t dxpl_id, + H5G_obj_create_t *gcrt_info, H5O_loc_t *oloc/*out*/); +H5_DLL herr_t H5G_obj_create_real(H5F_t *f, hid_t dxpl_id, + const H5O_ginfo_t *ginfo, const H5O_linfo_t *linfo, + const H5O_pline_t *pline, H5G_obj_create_t *gcrt_info, H5O_loc_t *oloc/*out*/); H5_DLL htri_t H5G_obj_get_linfo(const H5O_loc_t *grp_oloc, H5O_linfo_t *linfo, hid_t dxpl_id); H5_DLL herr_t H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, - H5O_link_t *obj_lnk, hbool_t adj_link, hid_t dxpl_id); + H5O_link_t *obj_lnk, hbool_t adj_link, H5O_type_t obj_type, + const void *crt_info, hid_t dxpl_id); H5_DLL herr_t H5G_obj_iterate(const H5O_loc_t *grp_oloc, H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op, void *op_data, hid_t dxpl_id); @@ -576,7 +593,7 @@ H5_DLL H5RS_str_t *H5G_build_fullpath_refstr_str(H5RS_str_t *path_r, const char H5_DLL herr_t H5G_loc_root(H5F_t *f, H5G_loc_t *loc); H5_DLL herr_t H5G_loc_copy(H5G_loc_t *dst, const H5G_loc_t *src, H5_copy_depth_t depth); H5_DLL herr_t H5G_loc_insert(H5G_loc_t *grp_loc, const char *name, - H5G_loc_t *obj_loc, hid_t dxpl_id); + H5G_loc_t *obj_loc, H5O_type_t obj_type, const void *crt_info, hid_t dxpl_id); /* Testing functions */ #ifdef H5G_TESTING diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index 7b09423..05de2ba 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -141,11 +141,6 @@ typedef struct { H5G_name_t *path; /* Group hierarchy path */ } H5G_loc_t; -/* Callback information for copying groups */ -typedef struct H5G_copy_file_ud_t { - H5O_copy_file_ud_common_t common; /* Shared information (must be first) */ -} H5G_copy_file_ud_t; - typedef struct H5G_t H5G_t; typedef struct H5G_shared_t H5G_shared_t; typedef struct H5G_entry_t H5G_entry_t; diff --git a/src/H5Groot.c b/src/H5Groot.c index f754f29..a79a5dd 100644 --- a/src/H5Groot.c +++ b/src/H5Groot.c @@ -97,6 +97,7 @@ herr_t H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root) { H5G_loc_t root_loc; /* Root location information */ + H5G_obj_create_t gcrt_info; /* Root group object creation info */ htri_t stab_exists = -1; /* Whether the symbol table exists */ hbool_t sblock_dirty = FALSE; /* Whether superblock was dirtied */ hbool_t path_init = FALSE; /* Whether path was initialized */ @@ -140,7 +141,9 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root) if(create_root) { /* Create root group */ /* (Pass the FCPL which is a sub-class of the group creation property class) */ - if(H5G_obj_create(f, dxpl_id, f->shared->fcpl_id, root_loc.oloc/*out*/) < 0) + gcrt_info.gcpl_id = f->shared->fcpl_id; + gcrt_info.cache_type = H5G_NOTHING_CACHED; + if(H5G_obj_create(f, dxpl_id, &gcrt_info, root_loc.oloc/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry") if(1 != H5O_link(root_loc.oloc, 1, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "internal error (wrong link count)") @@ -156,7 +159,9 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate space for symbol table entry") /* Initialize the root group symbol table entry */ - f->shared->sblock->root_ent->type = H5G_NOTHING_CACHED; /* We will cache the stab later */ + f->shared->sblock->root_ent->type = gcrt_info.cache_type; + if(gcrt_info.cache_type != H5G_NOTHING_CACHED) + f->shared->sblock->root_ent->cache = gcrt_info.cache; f->shared->sblock->root_ent->name_off = 0; /* No name (yet) */ f->shared->sblock->root_ent->header = root_loc.oloc->addr; } /* end if */ diff --git a/src/H5Gstab.c b/src/H5Gstab.c index 0566725..7d0ad48 100644 --- a/src/H5Gstab.c +++ b/src/H5Gstab.c @@ -221,7 +221,8 @@ done: */ herr_t H5G_stab_insert_real(H5F_t *f, H5O_stab_t *stab, const char *name, - H5O_link_t *obj_lnk, hid_t dxpl_id) + H5O_link_t *obj_lnk, H5O_type_t obj_type, const void *crt_info, + hid_t dxpl_id) { H5HL_t *heap = NULL; /* Pointer to local heap */ H5G_bt_ins_t udata; /* Data to pass through B-tree */ @@ -243,6 +244,8 @@ H5G_stab_insert_real(H5F_t *f, H5O_stab_t *stab, const char *name, udata.common.name = name; udata.common.heap = heap; udata.lnk = obj_lnk; + udata.obj_type = obj_type; + udata.crt_info = crt_info; /* Insert into symbol table */ if(H5B_insert(f, dxpl_id, H5B_SNODE, stab->btree_addr, &udata) < 0) @@ -273,7 +276,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5G_stab_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, +H5G_stab_insert(const H5O_loc_t *grp_oloc, const char *name, + H5O_link_t *obj_lnk, H5O_type_t obj_type, const void *crt_info, hid_t dxpl_id) { H5O_stab_t stab; /* Symbol table message */ @@ -290,7 +294,8 @@ H5G_stab_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table") - if(H5G_stab_insert_real(grp_oloc->file, &stab, name, obj_lnk, dxpl_id) < 0) + if(H5G_stab_insert_real(grp_oloc->file, &stab, name, obj_lnk, obj_type, + crt_info, dxpl_id) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5_ITER_ERROR, "unable to insert the name") done: diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index d8cf0f3..4016068 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -735,6 +735,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, const H5O_ginfo_t *ginfo; /* Group info settings for new group */ const H5O_linfo_t *linfo; /* Link info settings for new group */ const H5O_pline_t *pline; /* Filter pipeline settings for new group */ + H5G_obj_create_t gcrt_info; /* Group creation info */ /* Check for the parent group having a group info message */ /* (OK if not found) */ @@ -788,11 +789,16 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* Create the intermediate group */ /* XXX: Should we allow user to control the group creation params here? -QAK */ - if(H5G_obj_create_real(grp_oloc.file, dxpl_id, ginfo, linfo, pline, H5P_GROUP_CREATE_DEFAULT, obj_loc.oloc/*out*/) < 0) + gcrt_info.gcpl_id = H5P_GROUP_CREATE_DEFAULT; + gcrt_info.cache_type = H5G_NOTHING_CACHED; + HDmemset(&gcrt_info.cache, 0, sizeof(gcrt_info.cache)); + if(H5G_obj_create_real(grp_oloc.file, dxpl_id, ginfo, linfo, + pline, &gcrt_info, obj_loc.oloc/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry") /* Insert new group into current group's symbol table */ - if(H5G_loc_insert(&grp_loc, H5G_comp_g, &obj_loc, dxpl_id) < 0) + if(H5G_loc_insert(&grp_loc, H5G_comp_g, &obj_loc, + H5O_TYPE_GROUP, &gcrt_info, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert intermediate group") /* Close new group */ @@ -1716,7 +1716,10 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED udata->lnk->name = (char *)name; /* Insert link into group */ - if(H5G_obj_insert(grp_loc->oloc, name, udata->lnk, TRUE, udata->dxpl_id) < 0) + if(H5G_obj_insert(grp_loc->oloc, name, udata->lnk, TRUE, + udata->ocrt_info ? udata->ocrt_info->obj_type : H5O_TYPE_UNKNOWN, + udata->ocrt_info ? udata->ocrt_info->crt_info : NULL, + udata->dxpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link for object") /* Set object's path if it has been passed in and is not set */ @@ -2418,7 +2421,8 @@ H5L_move_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name, udata->lnk->name = (char *)name; /* Insert the link into the group */ - if(H5G_obj_insert(grp_loc->oloc, name, udata->lnk, TRUE, udata->dxpl_id) < 0) + if(H5G_obj_insert(grp_loc->oloc, name, udata->lnk, TRUE, H5O_TYPE_UNKNOWN, + NULL, udata->dxpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link to object") /* If the link was a user-defined link, call its move callback if it has one */ 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") diff --git a/src/H5Opkg.h b/src/H5Opkg.h index b46af85..a14d471 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -333,6 +333,8 @@ typedef struct H5O_addr_map_t { haddr_t dst_addr; /* Address of object in destination file */ hbool_t is_locked; /* Indicate that the destination object is locked currently */ hsize_t inc_ref_count; /* Number of deferred increments to reference count */ + H5O_obj_class_t *obj_class; /* Object class */ + void *udata; /* Object class copy file udata */ } H5O_addr_map_t; /* Stack of continuation messages to interpret */ diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index cc06671..63264d8 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -701,7 +701,8 @@ H5_DLL herr_t H5O_msg_unlock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_ /* Object copying routines */ H5_DLL 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); H5_DLL herr_t H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, hid_t dxpl_id, H5F_t *file_dst, void *_dst_ref, size_t ref_count, H5R_type_t ref_type, H5O_copy_t *cpy_info); diff --git a/src/H5Oshared.c b/src/H5Oshared.c index ad7e594..68fc4ad 100644 --- a/src/H5Oshared.c +++ b/src/H5Oshared.c @@ -612,7 +612,8 @@ H5O_shared_copy_file(H5F_t UNUSED *file_src, H5F_t *file_dst, dst_oloc.file = file_dst; src_oloc.file = shared_src->file; src_oloc.addr = shared_src->u.loc.oh_addr; - if(H5O_copy_header_map(&src_oloc, &dst_oloc, dxpl_id, cpy_info, FALSE) < 0) + if(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") /* Set up destination message's shared info */ diff --git a/src/H5Ostab.c b/src/H5Ostab.c index 4829e93..e29a856 100644 --- a/src/H5Ostab.c +++ b/src/H5Ostab.c @@ -44,7 +44,7 @@ static size_t H5O_stab_size(const H5F_t *f, hbool_t disable_shared, const void * static herr_t H5O_stab_free(void *_mesg); static herr_t H5O_stab_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg); static void *H5O_stab_copy_file(H5F_t *file_src, void *native_src, - H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, void *udata, + H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, void *_udata, hid_t dxpl_id); static herr_t H5O_stab_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info); @@ -307,11 +307,12 @@ done: */ static void * H5O_stab_copy_file(H5F_t *file_src, void *native_src, H5F_t *file_dst, - hbool_t UNUSED *recompute_size, H5O_copy_t UNUSED *cpy_info, void UNUSED *udata, + hbool_t UNUSED *recompute_size, H5O_copy_t UNUSED *cpy_info, void *_udata, hid_t dxpl_id) { H5O_stab_t *stab_src = (H5O_stab_t *) native_src; H5O_stab_t *stab_dst = NULL; + H5G_copy_file_ud_t *udata = (H5G_copy_file_ud_t *)_udata; size_t size_hint; /* Local heap initial size */ void *ret_value; /* Return value */ @@ -328,7 +329,7 @@ H5O_stab_copy_file(H5F_t *file_src, void *native_src, H5F_t *file_dst, /* Get the old local heap's size and use that as the hint for the new heap */ if(H5HL_get_size(file_src, dxpl_id, stab_src->heap_addr, &size_hint) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGETSIZE, NULL, "can't query local heap size") - + /* Set copy metadata tag */ H5_BEGIN_TAG(dxpl_id, H5AC__COPIED_TAG, NULL); @@ -339,6 +340,11 @@ H5O_stab_copy_file(H5F_t *file_src, void *native_src, H5F_t *file_dst, /* Reset metadata tag */ H5_END_TAG(NULL); + /* Cache stab in udata */ + udata->cache_type = H5G_CACHED_STAB; + udata->cache.stab.btree_addr = stab_dst->btree_addr; + udata->cache.stab.heap_addr = stab_dst->heap_addr; + /* Set return value */ ret_value = stab_dst; |