diff options
Diffstat (limited to 'src/H5Gobj.c')
-rw-r--r-- | src/H5Gobj.c | 888 |
1 files changed, 534 insertions, 354 deletions
diff --git a/src/H5Gobj.c b/src/H5Gobj.c index 4cf99ef..960061f 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -22,11 +22,18 @@ * *------------------------------------------------------------------------- */ + +/****************/ +/* Module Setup */ +/****************/ + #define H5F_PACKAGE /*suppress error about including H5Fpkg */ -#define H5G_PACKAGE /*suppress error about including H5Gpkg */ +#define H5G_PACKAGE /*suppress error about including H5Gpkg */ -/* Packages needed by this file... */ +/***********/ +/* Headers */ +/***********/ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ @@ -37,29 +44,164 @@ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property Lists */ -/* Private typedefs */ -/* User data for converting link messages to symbol table */ +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + +/* User data for object header iterator when converting link messages to dense + * link storage + */ typedef struct { H5F_t *f; /* Pointer to file for insertion */ - haddr_t btree_addr; /* Address of symbol table B-tree */ - haddr_t heap_addr; /* Address of symbol table local heap */ hid_t dxpl_id; /* DXPL during insertion */ -} H5G_obj_ud1_t; + H5O_linfo_t *linfo; /* Pointer to link info */ +} H5G_obj_oh_it_ud1_t; -/* User data for looking up an object in a group */ +/* User data for link iterator when converting dense link storage to link + * messages + */ typedef struct { - H5O_link_t *lnk; /* Link information to set for object */ - H5O_loc_t *oloc; /* Object location to set */ -} H5G_obj_ud2_t; + H5O_link_t *lnk_table; /* Array of links to convert */ + size_t nlinks; /* Number of links converted */ + size_t alloc_links; /* Size of link table */ +} H5G_obj_lnk_it_ud1_t; -/* Private macros */ +/* User data for symbol table iterator when converting old-format group to + * a new-format group + */ +typedef struct { + H5O_loc_t *grp_oloc; /* Pointer to group for insertion */ + hid_t dxpl_id; /* DXPL during insertion */ +} H5G_obj_stab_it_ud1_t; -/* PRIVATE PROTOTYPES */ -#ifdef H5_GROUP_REVISION -static herr_t -H5G_obj_link_to_stab_cb(const void *_mesg, unsigned idx, void *_udata); -#endif /* H5_GROUP_REVISION */ +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ +static herr_t H5G_obj_link_to_dense_cb(const void *_mesg, unsigned idx, + void *_udata); + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*------------------------------------------------------------------------- + * Function: H5G_obj_cmp_name_inc + * + * Purpose: Callback routine for comparing two link names, in + * increasing alphabetic order + * + * Return: An integer less than, equal to, or greater than zero if the + * first argument is considered to be respectively less than, + * equal to, or greater than the second. If two members compare + * as equal, their order in the sorted array is undefined. + * (i.e. same as strcmp()) + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Sep 5 2005 + * + *------------------------------------------------------------------------- + */ +int +H5G_obj_cmp_name_inc(const void *lnk1, const void *lnk2) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_obj_cmp_name_inc) + + FUNC_LEAVE_NOAPI(HDstrcmp(((const H5O_link_t *)lnk1)->name, ((const H5O_link_t *)lnk2)->name)) +} /* end H5G_obj_cmp_name_inc() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_obj_cmp_name_dec + * + * Purpose: Callback routine for comparing two link names, in + * decreasing alphabetic order + * + * Return: An integer less than, equal to, or greater than zero if the + * second argument is considered to be respectively less than, + * equal to, or greater than the first. If two members compare + * as equal, their order in the sorted array is undefined. + * (i.e. opposite strcmp()) + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Sep 25 2006 + * + *------------------------------------------------------------------------- + */ +int +H5G_obj_cmp_name_dec(const void *lnk1, const void *lnk2) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_obj_cmp_name_dec) + + FUNC_LEAVE_NOAPI(HDstrcmp(((const H5O_link_t *)lnk2)->name, ((const H5O_link_t *)lnk1)->name)) +} /* end H5G_obj_cmp_name_dec() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_obj_release_table + * + * Purpose: Release table containing a list of links for a group + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Sep 6, 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_obj_release_table(H5G_link_table_t *ltable) +{ + size_t u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_obj_release_table) + + /* Sanity check */ + HDassert(ltable); + + /* Release link info, if any */ + if(ltable->nlinks > 0) { + /* Free link message information */ + for(u = 0; u < ltable->nlinks; u++) + if(H5O_reset(H5O_LINK_ID, &(ltable->lnks[u])) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link message") + + /* Free table of links */ + H5MM_xfree(ltable->lnks); + } /* end if */ + else + HDassert(ltable->lnks == NULL); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_obj_release_table() */ /*------------------------------------------------------------------------- @@ -76,21 +218,12 @@ H5G_obj_link_to_stab_cb(const void *_mesg, unsigned idx, void *_udata); *------------------------------------------------------------------------- */ herr_t -H5G_obj_create(H5F_t *f, hid_t dxpl_id, -#ifdef H5_GROUP_REVISION - H5O_ginfo_t *ginfo, -#endif /* H5_GROUP_REVISION */ +H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, H5O_loc_t *oloc/*out*/) { -#ifdef H5_GROUP_REVISION H5O_linfo_t linfo; /* Link information */ - H5O_link_t lnk; /* Temporary link message info for computing message size */ - char null_char = '\0'; /* Character for creating null string */ - size_t ginfo_size; /* Size of the group info message */ - size_t linfo_size; /* Size of the link info message */ - size_t link_size; /* Size of a link message */ -#endif /* H5_GROUP_REVISION */ size_t hdr_size; /* Size of object header to request */ + hbool_t use_latest_format; /* Flag indicating the new group format should be used */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_obj_create, FAIL) @@ -99,34 +232,49 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, * Check arguments. */ HDassert(f); -#ifdef H5_GROUP_REVISION HDassert(ginfo); -#endif /* H5_GROUP_REVISION */ HDassert(oloc); -#ifdef H5_GROUP_REVISION - /* Initialize message information */ - linfo.nlinks = 0; - - /* Calculate message size infomation, for creating group's object header */ - linfo_size = H5O_mesg_size(H5O_LINFO_ID, f, &linfo); - HDassert(linfo_size); - - ginfo_size = H5O_mesg_size(H5O_GINFO_ID, f, ginfo); - HDassert(ginfo_size); - - lnk.type = H5L_LINK_HARD; - lnk.name = &null_char; - link_size = H5O_mesg_size(H5O_LINK_ID, f, &lnk); - HDassert(link_size); - - /* Compute size of header to use for creation */ - hdr_size = linfo_size + - ginfo_size + - (ginfo->est_num_entries * (link_size + ginfo->est_name_len)); -#else /* H5_GROUP_REVISION */ - hdr_size = 4 + 2 * H5F_SIZEOF_ADDR(f); -#endif /* H5_GROUP_REVISION */ + /* Check for using the latest version of the group format */ +/* XXX: add more checks for creating "new format" groups when needed */ + if(f->shared->latest_format || ginfo->track_corder) + use_latest_format = TRUE; + else + use_latest_format = FALSE; + + /* Check if we should be using the latest version of the group format */ + if(use_latest_format) { + H5O_linfo_t def_linfo = H5G_CRT_LINK_INFO_DEF; /* Default link info */ + H5O_link_t lnk; /* Temporary link message info for computing message size */ + char null_char = '\0'; /* Character for creating null string */ + size_t ginfo_size; /* Size of the group info message */ + size_t linfo_size; /* Size of the link info message */ + size_t link_size; /* Size of a link message */ + + /* Initialize message information */ + HDmemcpy(&linfo, &def_linfo, sizeof(H5O_linfo_t)); + + /* Calculate message size infomation, for creating group's object header */ + linfo_size = H5O_mesg_size(H5O_LINFO_ID, f, &linfo, (size_t)0); + HDassert(linfo_size); + + ginfo_size = H5O_mesg_size(H5O_GINFO_ID, f, ginfo, (size_t)0); + HDassert(ginfo_size); + + lnk.type = H5L_TYPE_HARD; + lnk.corder = 0; + lnk.corder_valid = ginfo->track_corder; + lnk.name = &null_char; + link_size = H5O_mesg_size(H5O_LINK_ID, f, &lnk, (size_t)ginfo->est_name_len); + HDassert(link_size); + + /* Compute size of header to use for creation */ + hdr_size = linfo_size + + ginfo_size + + (ginfo->est_num_entries * link_size); + } /* end if */ + else + hdr_size = 4 + 2 * H5F_SIZEOF_ADDR(f); /* * Create symbol table object header. It has a zero link count @@ -136,24 +284,23 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, if(H5O_create(f, dxpl_id, hdr_size, oloc/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create header") -#ifdef H5_GROUP_REVISION - /* Insert link info message */ - if(H5O_modify(oloc, H5O_LINFO_ID, H5O_NEW_MESG, 0, 0, &linfo, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message") + /* Check for format of group to create */ + if(use_latest_format) { + /* Insert link info message */ + if(H5O_modify(oloc, H5O_LINFO_ID, H5O_NEW_MESG, 0, 0, &linfo, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message") - /* Insert group info message */ - if(H5O_modify(oloc, H5O_GINFO_ID, H5O_NEW_MESG, H5O_FLAG_CONSTANT, H5O_UPDATE_TIME, ginfo, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message") -#else /* H5_GROUP_REVISION */ - { + /* Insert group info message */ + if(H5O_modify(oloc, H5O_GINFO_ID, H5O_NEW_MESG, H5O_FLAG_CONSTANT, H5O_UPDATE_TIME, ginfo, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message") + } /* end if */ + else { H5O_stab_t stab; /* Symbol table message */ /* The group doesn't currently have a 'stab' message, go create one */ - if(H5G_stab_create(oloc, &stab, dxpl_id) < 0) + if(H5G_stab_create(oloc, dxpl_id, ginfo, &stab) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create symbol table") - - } -#endif /* H5_GROUP_REVISION */ + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -250,13 +397,12 @@ H5G_obj_ent_encode(H5F_t *f, uint8_t **pp, const H5O_loc_t *oloc) FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5G_obj_ent_encode() */ -#ifdef H5_GROUP_REVISION /*------------------------------------------------------------------------- - * Function: H5G_obj_link_to_stab_cb + * Function: H5G_obj_link_to_dense_cb * - * Purpose: Callback routine for converting 'link' messages to symbol table - * form. + * Purpose: Callback routine for converting 'link' messages to "dense" + * link storage form. * * Return: Non-negative on success/Negative on failure * @@ -267,32 +413,61 @@ H5G_obj_ent_encode(H5F_t *f, uint8_t **pp, const H5O_loc_t *oloc) *------------------------------------------------------------------------- */ static herr_t -H5G_obj_link_to_stab_cb(const void *_mesg, unsigned UNUSED idx, void *_udata) +H5G_obj_link_to_dense_cb(const void *_mesg, unsigned UNUSED idx, void *_udata) { const H5O_link_t *lnk = (const H5O_link_t *)_mesg; /* Pointer to link */ - H5G_obj_ud1_t *udata = (H5G_obj_ud1_t *)_udata; /* 'User data' passed in */ - H5G_bt_ud1_t bt_udata; /* Data to pass through B-tree */ + H5G_obj_oh_it_ud1_t *udata = (H5G_obj_oh_it_ud1_t *)_udata; /* 'User data' passed in */ herr_t ret_value = H5O_ITER_CONT; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5G_obj_link_to_stab_cb) + FUNC_ENTER_NOAPI_NOINIT(H5G_obj_link_to_dense_cb) /* check arguments */ HDassert(lnk); HDassert(udata); - /* Construct user data to pass through B-tree routines */ - bt_udata.common.name = lnk->name; - bt_udata.common.heap_addr = udata->heap_addr; - bt_udata.lnk = lnk; + /* Insert link into dense link storage */ + if(H5G_dense_insert(udata->f, udata->dxpl_id, udata->linfo, lnk) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert link into dense storage") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_obj_link_to_dense_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_obj_stab_to_new_cb + * + * Purpose: Callback routine for converting "symbol table" link storage to + * "new format" storage (either link messages or "dense" storage). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Sept 16 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_obj_stab_to_new_cb(const H5O_link_t *lnk, void *_udata) +{ + H5G_obj_stab_it_ud1_t *udata = (H5G_obj_stab_it_ud1_t *)_udata; /* 'User data' passed in */ + herr_t ret_value = H5B_ITER_CONT; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_obj_stab_to_new_cb) + + /* check arguments */ + HDassert(lnk); + HDassert(udata); - /* Insert entry into symbol table */ - if(H5B_insert(udata->f, udata->dxpl_id, H5B_SNODE, udata->btree_addr, &bt_udata) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry") + /* 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) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_ITER_ERROR, "can't insert link into group") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_obj_link_to_stab_cb() */ -#endif /* H5_GROUP_REVISION */ +} /* end H5G_obj_stab_to_new_cb() */ /*------------------------------------------------------------------------- @@ -300,8 +475,9 @@ done: * * Purpose: Insert a new symbol into the group described by GRP_OLOC. * file F. The name of the new symbol is NAME and its symbol - * table entry is OBJ_LNK. Optionally, increment the reference - * count for the object the link points to with INC_LINK. + * table entry is OBJ_LNK. Increment the reference + * count for the object the link points if OBJ_LNK is a hard link + * and ADJ_LINK is true. * * Return: Non-negative on success/Negative on failure * @@ -313,13 +489,12 @@ done: */ herr_t H5G_obj_insert(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, - hbool_t inc_link, hid_t dxpl_id) + hbool_t adj_link, hid_t dxpl_id) { -#ifdef H5_GROUP_REVISION H5O_linfo_t linfo; /* Link info message */ - htri_t linfo_exists; /* Whether the link info is present */ - hbool_t use_stab; /* Whether to use symbol table for insertions or not */ -#endif /* H5_GROUP_REVISION */ + H5O_ginfo_t ginfo; /* Group info message */ + hbool_t use_old_format; /* Whether to use 'old format' (symbol table) for insertions or not */ + hbool_t use_new_dense = FALSE; /* Whether to use "dense" form of 'new format' group */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_obj_insert, FAIL) @@ -329,99 +504,145 @@ H5G_obj_insert(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, HDassert(name && *name); HDassert(obj_lnk); -#ifdef H5_GROUP_REVISION /* Check if we have information about the number of objects in this group */ - if((linfo_exists = H5O_exists(grp_oloc, H5O_LINFO_ID, 0, dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for link info") - if(linfo_exists) { - htri_t stab_exists; /* Whether the symbol table info is present */ - - /* Get the number of objects in this group */ - if(NULL == H5O_read(grp_oloc, H5O_LINFO_ID, 0, &linfo, dxpl_id)) - HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link info") - - /* Check if there is already a 'stab' message */ - if((stab_exists = H5O_exists(grp_oloc, H5O_STAB_ID, 0, dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for symbol table") - if(stab_exists) - use_stab = TRUE; + /* (by attempting to get the link info message for this group) */ + if(H5O_read(grp_oloc, H5O_LINFO_ID, 0, &linfo, dxpl_id)) { + size_t link_msg_size; /* Size of new link message in the file */ + + /* Using the new format for groups */ + use_old_format = FALSE; + + /* Get the group info */ + if(NULL == H5O_read(grp_oloc, H5O_GINFO_ID, 0, &ginfo, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get group info") + + /* Check for tracking creation order on this group's links */ + if(ginfo.track_corder) { + /* Set the creation order for the new link & indicate that it's valid */ + obj_lnk->corder = linfo.max_corder; + obj_lnk->corder_valid = TRUE; + + /* Increment the max. creation order used in the group */ + linfo.max_corder++; + } /* end if */ + + /* Get the link's message size */ + if((link_msg_size = H5O_raw_size(H5O_LINK_ID, grp_oloc->file, obj_lnk)) == 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGETSIZE, FAIL, "can't get link size") + + /* If there's still a small enough number of links, use the 'link' message */ + /* (If the encoded form of the link is too large to fit into an object + * header message, convert to using dense link storage instead of link messages) + */ + if(H5F_addr_defined(linfo.link_fheap_addr)) + use_new_dense = TRUE; + else if(linfo.nlinks < ginfo.max_compact && link_msg_size < H5O_MAX_SIZE) + use_new_dense = FALSE; else { - H5O_ginfo_t ginfo; /* Group info message */ - size_t link_msg_size; /* Size of link message in the file */ + H5G_obj_oh_it_ud1_t udata; /* User data for iteration */ - /* Get the link message size */ - if((link_msg_size = H5O_raw_size(H5O_LINK_ID, grp_oloc->file, obj_lnk)) == 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGETSIZE, FAIL, "can't get link size") + /* The group doesn't currently have "dense" storage for links */ + if(H5G_dense_create(grp_oloc->file, dxpl_id, &linfo) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create 'dense' form of new format group") - /* Get the group info */ - if(NULL == H5O_read(grp_oloc, H5O_GINFO_ID, 0, &ginfo, dxpl_id)) - HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get group info") + /* Set up user data for object header message iteration */ + udata.f = grp_oloc->file; + udata.dxpl_id = dxpl_id; + udata.linfo = &linfo; - /* If there's still a small enough number of links, use the 'link' message */ - /* (If the encoded form of the link is too large to fit into an object - * header message, convert to using symbol table instead of link messages) - */ - if(linfo.nlinks < ginfo.max_compact && link_msg_size < H5O_MAX_SIZE) - use_stab = FALSE; - else { - H5G_obj_ud1_t udata; /* User data for iteration */ - H5O_stab_t stab; /* Symbol table message */ - - /* The group doesn't currently have a 'stab' message, go create one */ - if(H5G_stab_create(grp_oloc, &stab, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create symbol table") - - /* Set up user data for object header message iteration */ - udata.f = grp_oloc->file; - udata.btree_addr = stab.btree_addr; - udata.heap_addr = stab.heap_addr; - udata.dxpl_id = dxpl_id; - - /* Iterate over the 'link' messages, inserting them into the symbol table */ - if(H5O_iterate(grp_oloc, H5O_LINK_ID, H5G_obj_link_to_stab_cb, &udata, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over links") - - /* Remove all the 'link' messages */ - if(H5O_remove(grp_oloc, H5O_LINK_ID, H5O_ALL, FALSE, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete link messages") - - use_stab = TRUE; - } /* end else */ + /* Iterate over the 'link' messages, inserting them into the dense link storage */ + if(H5O_iterate(grp_oloc, H5O_LINK_ID, H5G_obj_link_to_dense_cb, &udata, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over links") + + /* Remove all the 'link' messages */ + if(H5O_remove(grp_oloc, H5O_LINK_ID, H5O_ALL, FALSE, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete link messages") + + use_new_dense = TRUE; } /* end else */ } /* end if */ - else - use_stab = TRUE; -#endif /* H5_GROUP_REVISION */ + else { + /* Clear error stack from not finding the link info message */ + H5E_clear_stack(NULL); + + /* Check for new-style link information */ + if(obj_lnk->cset != H5T_CSET_ASCII || obj_lnk->type > H5L_TYPE_BUILTIN_MAX) { + H5O_linfo_t new_linfo = H5G_CRT_LINK_INFO_DEF; /* Link information */ + H5O_ginfo_t new_ginfo = H5G_CRT_GROUP_INFO_DEF; /* Group information */ + H5G_obj_stab_it_ud1_t udata; /* User data for iteration */ + H5G_link_iterate_t lnk_op; /* Link operator */ + + /* Convert group to "new format" group, in order to hold the information */ + + /* Insert link info message */ + if(H5O_modify(grp_oloc, H5O_LINFO_ID, H5O_NEW_MESG, 0, 0, &new_linfo, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message") + + /* Insert group info message */ + if(H5O_modify(grp_oloc, H5O_GINFO_ID, H5O_NEW_MESG, H5O_FLAG_CONSTANT, 0, &new_ginfo, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message") + + /* Set up user data for iteration */ + udata.grp_oloc = grp_oloc; + udata.dxpl_id = dxpl_id; + + /* Build iterator operator */ + lnk_op.lib_op = H5G_obj_stab_to_new_cb; + + /* Iterate through all links in "old format" group and insert them into new format */ + if(H5G_stab_iterate(grp_oloc, H5_ITER_NATIVE, 0, TRUE, 0, NULL, lnk_op, &udata, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over old format links") + + /* Remove the symbol table message from the group */ + if(H5O_remove(grp_oloc, H5O_STAB_ID, 0, FALSE, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete old format link storage") + + /* Recursively call this routine to insert the new link, since the + * 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) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert link into group") + + /* Done with insertion now */ + HGOTO_DONE(SUCCEED) + } /* end if */ + else + use_old_format = TRUE; + } /* end if */ - /* Insert into symbol table or create link object */ -#ifdef H5_GROUP_REVISION - if(use_stab) { -#endif /* H5_GROUP_REVISION */ + /* 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) - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry") -#ifdef H5_GROUP_REVISION + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry into symbol table") } /* end if */ else { - /* Insert with link message */ - if(H5G_link_insert(grp_oloc, obj_lnk, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry") + if(use_new_dense) { + /* Insert into dense link storage */ + if(H5G_dense_insert(grp_oloc->file, dxpl_id, &linfo, obj_lnk) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert link into dense storage") + } /* end if */ + else { + /* Insert with link message */ + if(H5G_link_insert(grp_oloc, obj_lnk, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert link as link message") + } /* end else */ } /* end else */ /* Increment the number of objects in this group */ - if(linfo_exists) { + if(!use_old_format) { linfo.nlinks++; if(H5O_modify(grp_oloc, H5O_LINFO_ID, 0, 0, H5O_UPDATE_TIME, &linfo, dxpl_id) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't update link info message") } /* end if */ -#endif /* H5_GROUP_REVISION */ - /* Increment link count on object, if appropriate */ - if(inc_link) { + /* Increment link count on object, if requested and it's a hard link */ + if(adj_link && obj_lnk->type == H5L_TYPE_HARD) { H5O_loc_t obj_oloc; /* Object location */ H5O_loc_reset(&obj_oloc); - /* Convert to object location */ + /* Create temporary object location */ obj_oloc.file = grp_oloc->file; obj_oloc.addr = obj_lnk->u.hard.addr; @@ -451,51 +672,59 @@ done: *------------------------------------------------------------------------- */ herr_t -H5G_obj_iterate(hid_t loc_id, const char *name, int skip, int *last_obj, - H5G_iterate_t op, void *op_data, hid_t dxpl_id) +H5G_obj_iterate(hid_t loc_id, const char *name, H5_iter_order_t order, + int skip, int *last_lnk, H5G_iterate_t op, void *op_data, hid_t dxpl_id) { -#ifdef H5_GROUP_REVISION - htri_t stab_exists; /* Whether the symbol table info is present */ -#endif /* H5_GROUP_REVISION */ - hid_t gid = -1; /* ID of group to iterate over */ - H5G_t *grp; /* Pointer to group data structure to iterate over */ - herr_t ret_value; /* Return value */ + H5O_linfo_t linfo; /* Link info message */ + H5G_link_iterate_t lnk_op; /* Link operator */ + hid_t gid = -1; /* ID of group to iterate over */ + H5G_t *grp; /* Pointer to group data structure to iterate over */ + herr_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5G_obj_iterate, FAIL) /* Sanity check */ HDassert(name); - HDassert(last_obj); + HDassert(last_lnk); HDassert(op); /* * Open the group on which to operate. We also create a group ID which * we can pass to the application-defined operator. */ - if((gid = H5Gopen (loc_id, name)) < 0) + if((gid = H5Gopen(loc_id, name)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") if((grp = H5I_object(gid)) == NULL) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "bad group ID") -#ifdef H5_GROUP_REVISION - /* Check if we have information about the number of objects in this group */ - if((stab_exists = H5O_exists(&(grp->oloc), H5O_STAB_ID, 0, dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for symbol table") - - /* If the symbol table doesn't exist, iterate over link messages */ - if(!stab_exists) { - /* Get the object's name from the link messages */ - if((ret_value = H5G_link_iterate(&(grp->oloc), gid, skip, last_obj, op, op_data, dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over links") + /* Set up link operator */ + lnk_op.app_op = op; + + /* Attempt to get the link info for this group */ + if(H5O_read(&(grp->oloc), H5O_LINFO_ID, 0, &linfo, dxpl_id)) { + /* Check for going out of bounds */ + if(skip > 0 && (size_t)skip >= linfo.nlinks) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "index out of bound") + + if(H5F_addr_defined(linfo.link_fheap_addr)) { + /* Iterate over the links in the group, building a table of the link messages */ + if((ret_value = H5G_dense_iterate(grp->oloc.file, dxpl_id, order, gid, &linfo, FALSE, skip, last_lnk, lnk_op, op_data)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over links") + } /* end if */ + else { + /* Get the object's name from the link messages */ + if((ret_value = H5G_link_iterate(&(grp->oloc), dxpl_id, &linfo, order, gid, FALSE, skip, last_lnk, lnk_op, op_data)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over links") + } /* end else */ } /* end if */ else { -#endif /* H5_GROUP_REVISION */ + /* Clear error stack from not finding the link info message */ + H5E_clear_stack(NULL); + /* Iterate over symbol table */ - if((ret_value = H5G_stab_iterate(&(grp->oloc), gid, skip, last_obj, op, op_data, dxpl_id)) < 0) + if((ret_value = H5G_stab_iterate(&(grp->oloc), order, gid, FALSE, skip, last_lnk, lnk_op, op_data, dxpl_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over symbol table") -#ifdef H5_GROUP_REVISION } /* end else */ -#endif /* H5_GROUP_REVISION */ done: if(gid > 0) @@ -521,9 +750,7 @@ done: herr_t H5G_obj_count(H5O_loc_t *oloc, hsize_t *num_objs, hid_t dxpl_id) { -#ifdef H5_GROUP_REVISION - htri_t linfo_exists; /* Whether the link info is present */ -#endif /* H5_GROUP_REVISION */ + H5O_linfo_t linfo; /* Link info message */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_obj_count, FAIL) @@ -532,30 +759,19 @@ H5G_obj_count(H5O_loc_t *oloc, hsize_t *num_objs, hid_t dxpl_id) HDassert(oloc); HDassert(num_objs); -#ifdef H5_GROUP_REVISION - /* Check if we have information about the number of objects in this group */ - if((linfo_exists = H5O_exists(oloc, H5O_LINFO_ID, 0, dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for link info") - - /* If the link info exists, then it has the number of objects in the group */ - if(linfo_exists > 0) { - H5O_linfo_t linfo; /* Link info message */ - - /* Get the link info for this group */ - if(NULL == H5O_read(oloc, H5O_LINFO_ID, 0, &linfo, dxpl_id)) - HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link info") - + /* Attempt to get the link info for this group */ + if(H5O_read(oloc, H5O_LINFO_ID, 0, &linfo, dxpl_id)) { /* Set the number of objects */ *num_objs = linfo.nlinks; } /* end if */ else { -#endif /* H5_GROUP_REVISION */ + /* Clear error stack from not finding the link info message */ + H5E_clear_stack(NULL); + /* Get the number of objects in this group by iterating over symbol table */ if(H5G_stab_count(oloc, num_objs, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "can't count objects") -#ifdef H5_GROUP_REVISION } /* end else */ -#endif /* H5_GROUP_REVISION */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -568,8 +784,7 @@ done: * Purpose: Private function for H5Gget_objname_by_idx. * Returns the name of objects in the group by giving index. * - * Return: Success: Non-negative - * + * Return: Success: Non-negative, length of name * Failure: Negative * * Programmer: Raymond Lu @@ -578,37 +793,38 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5G_obj_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name, size_t size, hid_t dxpl_id) +H5G_obj_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name, size_t size, + hid_t dxpl_id) { -#ifdef H5_GROUP_REVISION - htri_t stab_exists; /* Whether the symbol table info is present */ -#endif /* H5_GROUP_REVISION */ - ssize_t ret_value; /* Return value */ + H5O_linfo_t linfo; /* Link info message */ + ssize_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5G_obj_get_name_by_idx, FAIL) /* Sanity check */ HDassert(oloc); -#ifdef H5_GROUP_REVISION - /* Check if we have information about the number of objects in this group */ - if((stab_exists = H5O_exists(oloc, H5O_STAB_ID, 0, dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for symbol table") - - /* If the symbol table doesn't exist, search link messages */ - if(!stab_exists) { - /* Get the object's name from the link messages */ - if((ret_value = H5G_link_get_name_by_idx(oloc, idx, name, size, dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate name") + /* Attempt to get the link info for this group */ + if(H5O_read(oloc, H5O_LINFO_ID, 0, &linfo, dxpl_id)) { + if(H5F_addr_defined(linfo.link_fheap_addr)) { + /* Get the object's name from the dense link storage */ + if((ret_value = H5G_dense_get_name_by_idx(oloc->file, dxpl_id, &linfo, idx, name, size)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate name") + } /* end if */ + else { + /* Get the object's name from the link messages */ + if((ret_value = H5G_link_get_name_by_idx(oloc, dxpl_id, &linfo, idx, name, size)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate name") + } /* end else */ } /* end if */ else { -#endif /* H5_GROUP_REVISION */ + /* Clear error stack from not finding the link info message */ + H5E_clear_stack(NULL); + /* Get the object's name from the symbol table */ if((ret_value = H5G_stab_get_name_by_idx(oloc, idx, name, size, dxpl_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate name") -#ifdef H5_GROUP_REVISION } /* end else */ -#endif /* H5_GROUP_REVISION */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -633,35 +849,35 @@ done: H5G_obj_t H5G_obj_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id) { -#ifdef H5_GROUP_REVISION - htri_t stab_exists; /* Whether the symbol table info is present */ -#endif /* H5_GROUP_REVISION */ - H5G_obj_t ret_value; /* Return value */ + H5O_linfo_t linfo; /* Link info message */ + H5G_obj_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5G_obj_get_type_by_idx, H5G_UNKNOWN) /* Sanity check */ HDassert(oloc); -#ifdef H5_GROUP_REVISION - /* Check if we have information about the number of objects in this group */ - if((stab_exists = H5O_exists(oloc, H5O_STAB_ID, 0, dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5G_UNKNOWN, "unable to check for symbol table") - - /* If the symbol table doesn't exist, search link messages */ - if(!stab_exists) { - /* Get the object's type from the link messages */ - if((ret_value = H5G_link_get_type_by_idx(oloc, idx, dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5G_UNKNOWN, "can't locate type") + /* Attempt to get the link info for this group */ + if(H5O_read(oloc, H5O_LINFO_ID, 0, &linfo, dxpl_id)) { + if(H5F_addr_defined(linfo.link_fheap_addr)) { + /* Get the object's name from the dense link storage */ + if((ret_value = H5G_dense_get_type_by_idx(oloc->file, dxpl_id, &linfo, idx)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5G_UNKNOWN, "can't locate type") + } /* end if */ + else { + /* Get the object's type from the link messages */ + if((ret_value = H5G_link_get_type_by_idx(oloc, dxpl_id, &linfo, idx)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5G_UNKNOWN, "can't locate type") + } /* end else */ } /* end if */ else { -#endif /* H5_GROUP_REVISION */ + /* Clear error stack from not finding the link info message */ + H5E_clear_stack(NULL); + /* Get the object's type from the symbol table */ if((ret_value = H5G_stab_get_type_by_idx(oloc, idx, dxpl_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5G_UNKNOWN, "can't locate type") -#ifdef H5_GROUP_REVISION } /* end else */ -#endif /* H5_GROUP_REVISION */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -672,10 +888,10 @@ done: * Function: H5G_obj_remove * * Purpose: Remove an object from a group. - * (Needs to hand up the type of the object removed) * - * Return: Success: Non-negative + * Note: Needs to hand up the type of the object removed * + * Return: Success: Non-negative * Failure: Negative * * Programmer: Quincey Koziol @@ -686,151 +902,116 @@ done: herr_t H5G_obj_remove(H5O_loc_t *oloc, const char *name, H5G_obj_t *obj_type, hid_t dxpl_id) { -#ifdef H5_GROUP_REVISION - htri_t linfo_exists; /* Whether the link info is present */ - H5O_linfo_t linfo; /* Link info message */ - htri_t stab_exists; /* Whether the symbol table info is present */ - hbool_t use_stab; /* Whether to use symbol table for deletions or not */ -#endif /* H5_GROUP_REVISION */ - H5G_obj_t ret_value; /* Return value */ + H5O_linfo_t linfo; /* Link info message */ + hbool_t use_old_format; /* Whether to use 'old format' (symbol table) for deletion or not */ + hbool_t use_new_dense = FALSE; /* Whether to use "dense" form of 'new format' group */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_obj_remove, FAIL) /* Sanity check */ HDassert(oloc); + HDassert(name && *name); HDassert(obj_type); -#ifdef H5_GROUP_REVISION - /* Check if we have information about the number of objects in this group */ - if((stab_exists = H5O_exists(oloc, H5O_STAB_ID, 0, dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for symbol table") - - /* Check if we have information about the number of objects in this group */ - if((linfo_exists = H5O_exists(oloc, H5O_LINFO_ID, 0, dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for link info message") - if(linfo_exists) { - H5O_ginfo_t ginfo; /* Group info message */ - - /* Get the number of objects in this group */ - if(NULL == H5O_read(oloc, H5O_LINFO_ID, 0, &linfo, dxpl_id)) - HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link info") + /* Attempt to get the link info for this group */ + if(H5O_read(oloc, H5O_LINFO_ID, 0, &linfo, dxpl_id)) { + /* Using the new format for groups */ + use_old_format = FALSE; /* Check for deleting enough links from group to go back to link messages */ - if(stab_exists) { + if(H5F_addr_defined(linfo.link_fheap_addr)) { + H5O_ginfo_t ginfo; /* Group info message */ + /* Get the group info */ if(NULL == H5O_read(oloc, H5O_GINFO_ID, 0, &ginfo, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get group info") - /* Switch from symbol table back to link messages */ + /* Check if we should switch from dense storage back to link messages */ if(linfo.nlinks <= ginfo.min_dense) { - H5G_bt_it_ud4_t udata; - H5O_stab_t stab; /* Info about local heap & B-tree */ - H5O_link_t *lnk_table; /* Array of links to convert */ + H5G_link_table_t ltable; /* Table of links */ hbool_t can_convert = TRUE; /* Whether converting to link messages is possible */ size_t u; /* Local index */ - /* Get the B-tree & local heap info */ - if(NULL == H5O_read(oloc, H5O_STAB_ID, 0, &stab, dxpl_id)) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address") - - /* Allocate space for the link table */ - H5_CHECK_OVERFLOW(linfo.nlinks, /* From: */ hsize_t, /* To: */size_t); - if(NULL == (lnk_table = H5MM_malloc(sizeof(H5O_link_t) * (size_t)linfo.nlinks))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for link table") - - /* Build udata to pass through H5B_iterate() */ - udata.heap_addr = stab.heap_addr; - udata.lnk_table = lnk_table; - udata.nlinks = 0; - H5_CHECK_OVERFLOW(linfo.nlinks, hsize_t, size_t); - udata.max_links = (size_t)linfo.nlinks; - - /* Iterate over the group members, building a table of equivalent link messages */ - if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, - H5G_node_stab_convert, stab.btree_addr, &udata)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over entries") + /* Build the table of links for this group */ + if(H5G_dense_build_table(oloc->file, dxpl_id, &linfo, H5_ITER_NATIVE, <able) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over links") /* Inspect links in table for ones that can't be converted back * into link message form (currently only links which can't fit * into an object header message) */ for(u = 0; u < linfo.nlinks; u++) - if(H5O_mesg_size(H5O_LINK_ID, oloc->file, &(lnk_table[u])) >= H5O_MAX_SIZE) { + if(H5O_mesg_size(H5O_LINK_ID, oloc->file, &(ltable.lnks[u]), (size_t)0) >= H5O_MAX_SIZE) { can_convert = FALSE; break; } /* end if */ /* If ok, insert links as link messages */ if(can_convert) { - for(u = 0; u < linfo.nlinks; u++) { - /* Insert link message into group */ - if(H5O_modify(oloc, H5O_LINK_ID, H5O_NEW_MESG, 0, H5O_UPDATE_TIME, &(lnk_table[u]), dxpl_id) < 0) + /* Insert link messages into group */ + for(u = 0; u < linfo.nlinks; u++) + if(H5O_modify(oloc, H5O_LINK_ID, H5O_NEW_MESG, 0, H5O_UPDATE_TIME, &(ltable.lnks[u]), dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message") - } /* end for */ - /* Remove the 'stab' message */ - if(H5O_remove(oloc, H5O_STAB_ID, H5O_ALL, FALSE, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete symbol table message") + /* Remove the dense storage */ + if(H5G_dense_delete(oloc->file, dxpl_id, &linfo, FALSE) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete dense link storage") - use_stab = FALSE; + use_new_dense = FALSE; } /* end if */ else - use_stab = TRUE; - - /* Release memory for link names (and memory for soft link values) */ - for(u = 0; u < linfo.nlinks; u++) { - H5MM_xfree(lnk_table[u].name); - if(lnk_table[u].type == H5L_LINK_SOFT) - H5MM_xfree(lnk_table[u].u.soft.name); - else if(lnk_table[u].type >= H5L_LINK_UD_MIN) { - if(lnk_table[u].u.ud.size > 0) - H5MM_xfree(lnk_table[u].u.ud.udata); - } /* end if */ - } /* end for */ + use_new_dense = TRUE; - /* Release memory for link table */ - H5MM_xfree(lnk_table); + /* Free link table information */ + if(H5G_obj_release_table(<able) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") } /* end if */ else - use_stab = TRUE; + use_new_dense = TRUE; } /* end if */ else - use_stab = FALSE; + use_new_dense = FALSE; } /* end if */ - else - use_stab = TRUE; -#endif /* H5_GROUP_REVISION */ + else { + H5E_clear_stack(NULL); /* Clear error stack from not finding the link info message */ + use_old_format = TRUE; + } /* end else */ /* If the symbol table doesn't exist, search link messages */ -#ifdef H5_GROUP_REVISION - if(!use_stab) { - /* Remove object from the link messages */ - if((ret_value = H5G_link_remove(oloc, name, obj_type, dxpl_id)) < 0) + if(use_old_format) { + /* Remove object from the symbol table */ + if(H5G_stab_remove(oloc, name, obj_type, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't remove object") } /* end if */ else { -#endif /* H5_GROUP_REVISION */ - /* Remove object from the symbol table */ - if((ret_value = H5G_stab_remove(oloc, name, obj_type, dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't remove object") -#ifdef H5_GROUP_REVISION + if(use_new_dense) { + /* Remove object from the dense link storage */ + if(H5G_dense_remove(oloc->file, dxpl_id, &linfo, name, obj_type) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't remove object") + } /* end if */ + else { + /* Remove object from the link messages */ + if(H5G_link_remove(oloc, name, obj_type, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't remove object") + } /* end else */ } /* end else */ -#endif /* H5_GROUP_REVISION */ -#ifdef H5_GROUP_REVISION - /* Decrement the number of objects in this group */ - if(linfo_exists) { + /* Update link info for a new-style group */ + if(!use_old_format) { + /* Decrement # of links in group */ linfo.nlinks--; - if(H5O_modify(oloc, H5O_LINFO_ID, 0, 0, H5O_UPDATE_TIME, &linfo, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't update link info message") - /* Remove the symbol table, if we are using one and the number of links drops to zero */ - if(linfo.nlinks == 0 && use_stab) { - if(H5O_remove(oloc, H5O_STAB_ID, H5O_ALL, FALSE, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete symbol table message") + /* Remove the dense link storage, if we are using it and the number of links drops to zero */ + if(linfo.nlinks == 0 && use_new_dense) { + if(H5G_dense_delete(oloc->file, dxpl_id, &linfo, FALSE) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete dense link storage") } /* end if */ + + /* Update link info in the object header */ + if(H5O_modify(oloc, H5O_LINFO_ID, 0, 0, H5O_UPDATE_TIME, &linfo, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't update link info message") } /* end if */ -#endif /* H5_GROUP_REVISION */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -854,9 +1035,7 @@ herr_t H5G_obj_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk, hid_t dxpl_id) { -#ifdef H5_GROUP_REVISION - htri_t stab_exists; /* Whether the symbol table info is present */ -#endif /* H5_GROUP_REVISION */ + H5O_linfo_t linfo; /* Link info message */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_obj_lookup, FAIL) @@ -865,29 +1044,30 @@ H5G_obj_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk, HDassert(grp_oloc && grp_oloc->file); HDassert(name && *name); -#ifdef H5_GROUP_REVISION - /* Check if we have information about the number of objects in this group */ - if((stab_exists = H5O_exists(grp_oloc, H5O_STAB_ID, 0, dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for symbol table") - - /* If the symbol table doesn't exist, search link messages */ - if(!stab_exists) { - /* Get the object's info from the link messages */ - if(H5G_link_lookup(grp_oloc, name, lnk, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object") + /* Attempt to get the link info message for this group */ + if(H5O_read(grp_oloc, H5O_LINFO_ID, 0, &linfo, dxpl_id)) { + /* Check for dense link storage */ + if(H5F_addr_defined(linfo.link_fheap_addr)) { + /* Get the object's info from the dense link storage */ + if(H5G_dense_lookup(grp_oloc->file, dxpl_id, &linfo, name, lnk) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object") + } /* end if */ + else { + /* Get the object's info from the link messages */ + if(H5G_link_lookup(grp_oloc, name, lnk, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object") + } /* end else */ } /* end if */ else { -#endif /* H5_GROUP_REVISION */ + /* Clear error stack from not finding the link info message */ + H5E_clear_stack(NULL); + /* Get the object's info from the symbol table */ if(H5G_stab_lookup(grp_oloc, name, lnk, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object") -#ifdef H5_GROUP_REVISION } /* end else */ -#endif /* H5_GROUP_REVISION */ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_obj_lookup() */ - - |