summaryrefslogtreecommitdiffstats
path: root/src/H5Gent.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Gent.c')
-rw-r--r--src/H5Gent.c85
1 files changed, 82 insertions, 3 deletions
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;