summaryrefslogtreecommitdiffstats
path: root/src/H5Gobj.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2006-10-02 10:24:03 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2006-10-02 10:24:03 (GMT)
commita6f6462541cc57364586f770131e2ea074d63492 (patch)
tree0debf502fb7d66f9f470edb935a62223945960d4 /src/H5Gobj.c
parent9bc29ea538b9ce2013a8cde5be230c18cf052009 (diff)
downloadhdf5-a6f6462541cc57364586f770131e2ea074d63492.zip
hdf5-a6f6462541cc57364586f770131e2ea074d63492.tar.gz
hdf5-a6f6462541cc57364586f770131e2ea074d63492.tar.bz2
[svn-r12700] Alert:
File format is not stable, don't keep files produced! Description: First stage of checkins modifying the format of groups to support creation order. Implement "dense" storage for links in groups. Try to clarify some of the symbols for the H5L API. Add the H5Pset_latest_format() flag for FAPLs, to choose to use the newest file format options (including "dense" link storage in groups) Add the H5Pset_track_creation_order() flag for GCPLs, to enable creation order tracking in groups (although no index on creation order yet). Remove --enable-group-revision configure flag, as file format issues are now handled in a backwardly/forwardly compatible way. Clean up lots of compiler warnings and other minor formatting issues. Tested on: FreeBSD/32 4.11 (sleipnir) w/threadsafe Linux/32 2.4 (heping) w/FORTRAN & C++ Linux/64 2.4 (mir) w/enable-v1.6 compa Mac OSX/32 10.4.8 (amazon) AIX 5.3 (copper) w/parallel & FORTRAN
Diffstat (limited to 'src/H5Gobj.c')
-rw-r--r--src/H5Gobj.c888
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, &ltable) < 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(&ltable) < 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() */
-
-