summaryrefslogtreecommitdiffstats
path: root/src/H5G.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5G.c')
-rw-r--r--src/H5G.c190
1 files changed, 139 insertions, 51 deletions
diff --git a/src/H5G.c b/src/H5G.c
index 1c338e3..38fcf43 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -162,6 +162,7 @@ static size_t H5G_comp_alloc_g = 0; /*sizeof component buffer */
/* Declare a free list to manage the H5G_t struct */
H5FL_DEFINE(H5G_t);
+H5FL_DEFINE(H5G_shared_t);
/* Declare extern the PQ free list for the wrapped strings */
H5FL_BLK_EXTERN(str_buf);
@@ -180,6 +181,7 @@ static herr_t H5G_linkval(H5G_entry_t *loc, const char *name, size_t size,
char *buf/*out*/, hid_t dxpl_id);
static herr_t H5G_move(H5G_entry_t *src_loc, const char *src_name,
H5G_entry_t *dst_loc, const char *dst_name, hid_t dxpl_it);
+static H5G_t * H5G_open_oid(H5G_entry_t *ent, hid_t dxpl_id);
static herr_t H5G_unlink(H5G_entry_t *loc, const char *name, hid_t dxpl_id);
static herr_t H5G_get_num_objs(H5G_entry_t *grp, hsize_t *num_objs, hid_t dxpl_id);
static ssize_t H5G_get_objname_by_idx(H5G_entry_t *loc, hsize_t idx, char* name, size_t size, hid_t dxpl_id);
@@ -279,25 +281,31 @@ done:
hid_t
H5Gopen(hid_t loc_id, const char *name)
{
- hid_t ret_value = FAIL;
- H5G_t *grp = NULL;
+ hid_t ret_value = FAIL;
+ H5G_t *grp = NULL;
H5G_entry_t *loc = NULL;
+ H5G_entry_t ent;
+ hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open group */
FUNC_ENTER_API(H5Gopen, FAIL);
H5TRACE2("i","is",loc_id,name);
/* Check args */
if (NULL==(loc=H5G_loc(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
if (!name || !*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
-
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
+
+ /* Open the parent group, making sure it's a group */
+ if (H5G_find(loc, name, NULL, &ent/*out*/, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found");
+
/* Open the group */
- if (NULL == (grp = H5G_open(loc, name, H5AC_dxpl_id)))
- HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group");
+ if ((grp = H5G_open(&ent, H5AC_dxpl_id)) <0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group");
/* Register an atom for the group */
if ((ret_value = H5I_register(H5I_GROUP, grp)) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group");
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group");
done:
if(ret_value<0) {
@@ -381,7 +389,6 @@ H5Giterate(hid_t loc_id, const char *name, int *idx_p,
{
int idx;
H5G_bt_ud2_t udata;
- H5G_entry_t *loc = NULL;
H5G_t *grp = NULL;
herr_t ret_value;
@@ -389,27 +396,25 @@ H5Giterate(hid_t loc_id, const char *name, int *idx_p,
H5TRACE5("e","is*Isxx",loc_id,name,idx_p,op,op_data);
/* Check args */
- if (NULL==(loc=H5G_loc (loc_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
if (!name || !*name)
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified");
idx = (idx_p == NULL ? 0 : *idx_p);
if (!idx_p)
idx_p = &idx;
if (idx<0)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified");
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified");
if (!op)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified");
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified");
/*
* Open the group on which to operate. We also create a group ID which
* we can pass to the application-defined operator.
*/
- if (NULL==(grp = H5G_open (loc, name, H5AC_dxpl_id)))
- HGOTO_ERROR (H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group");
- if ((udata.group_id=H5I_register (H5I_GROUP, grp))<0) {
- H5G_close(grp);
- HGOTO_ERROR (H5E_SYM, H5E_CANTREGISTER, FAIL, "unable to register group");
+ if ((udata.group_id = H5Gopen (loc_id, name)) <0)
+ HGOTO_ERROR (H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group");
+ if ((grp=H5I_object(udata.group_id))==NULL) {
+ H5Gclose(udata.group_id);
+ HGOTO_ERROR (H5E_ATOM, H5E_BADATOM, FAIL, "bad group atom");
}
/* Build udata to pass through H5B_iterate() to H5G_node_iterate() */
@@ -1728,9 +1733,13 @@ H5G_mkroot (H5F_t *f, hid_t dxpl_id, H5G_entry_t *ent)
* never be closed.
*/
if (NULL==(f->shared->root_grp = H5FL_CALLOC (H5G_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ if (NULL==(f->shared->root_grp->shared = H5FL_CALLOC (H5G_shared_t))) {
+ H5FL_FREE(H5G_t, f->shared->root_grp);
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ }
f->shared->root_grp->ent = *ent;
- f->shared->root_grp->nref = 1;
+ f->shared->root_grp->shared->fo_count = 1;
assert (1==f->nopen_objs);
f->nopen_objs = 0;
@@ -1769,7 +1778,7 @@ H5G_create(H5G_entry_t *loc, const char *name, size_t size_hint, hid_t dxpl_id)
{
H5G_t *grp = NULL; /*new group */
H5F_t *file = NULL; /* File new group will be in */
- unsigned stab_init=0; /* Flag to indicate that the symbol stable was created successfully */
+ unsigned stab_init=0; /* Flag to indicate that the symbol table was created successfully */
H5G_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5G_create, NULL);
@@ -1780,7 +1789,10 @@ H5G_create(H5G_entry_t *loc, const char *name, size_t size_hint, hid_t dxpl_id)
/* create an open group */
if (NULL==(grp = H5FL_CALLOC(H5G_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ if (NULL==(grp->shared = H5FL_CALLOC(H5G_t)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+
/* What file is the group being added to? */
if (NULL==(file=H5G_insertion_file(loc, name, dxpl_id)))
@@ -1788,14 +1800,18 @@ H5G_create(H5G_entry_t *loc, const char *name, size_t size_hint, hid_t dxpl_id)
/* Create the group entry */
if (H5G_stab_create(file, dxpl_id, size_hint, &(grp->ent)/*out*/) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create grp");
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create grp");
stab_init=1; /* Indicate that the symbol table information is valid */
/* insert child name into parent */
if(H5G_insert(loc,name,&(grp->ent), dxpl_id)<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group");
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group");
- grp->nref = 1;
+ /* Add group to list of open objects in file */
+ if(H5FO_insert(grp->ent.file, grp->ent.header, grp->shared)<0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group into list of open objects")
+
+ grp->shared->fo_count = 1;
/* Set return value */
ret_value=grp;
@@ -1810,6 +1826,8 @@ done:
HDONE_ERROR(H5E_SYM, H5E_CANTDELETE, NULL, "unable to delete object header");
} /* end if */
if(grp!=NULL)
+ if(grp->shared != NULL)
+ H5FL_FREE(H5G_shared_t, grp->shared);
H5FL_FREE(H5G_t,grp);
} /* end if */
@@ -1911,25 +1929,47 @@ H5G_link_isa(H5G_entry_t *ent, hid_t UNUSED dxpl_id)
*-------------------------------------------------------------------------
*/
H5G_t *
-H5G_open(H5G_entry_t *loc, const char *name, hid_t dxpl_id)
+H5G_open(H5G_entry_t *ent, hid_t dxpl_id)
{
- H5G_t *grp = NULL;
- H5G_t *ret_value = NULL;
- H5G_entry_t ent; /* group symbol table entry */
+ H5G_t *grp = NULL;
+ H5G_shared_t *shared_fo=NULL;
+ H5G_t *ret_value=NULL;
FUNC_ENTER_NOAPI(H5G_open, NULL);
/* Check args */
- assert(loc);
- assert(name && *name);
+ assert(ent);
- /* Open the object, making sure it's a group */
- if (H5G_find(loc, name, NULL, &ent/*out*/, dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "group not found");
+ /* Check if group was already open */
+ if((shared_fo=H5FO_opened(ent->file, ent->header))==NULL) {
+
+ /* Clear any errors from H5FO_opened() */
+ H5E_clear_stack(NULL);
- /* Open the group object */
- if ((grp=H5G_open_oid(&ent, dxpl_id)) ==NULL)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "not found");
+ /* Open the group object */
+ if ((grp=H5G_open_oid(ent, dxpl_id)) ==NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "not found");
+
+ /* Add group to list of open objects in file */
+ if(H5FO_insert(grp->ent.file, grp->ent.header, grp->shared)<0)
+ {
+ H5FL_FREE(H5G_shared_t, grp->shared);
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group into list of open objects")
+ }
+
+ grp->shared->fo_count =1;
+ }
+ else {
+ if(NULL == (grp = H5FL_CALLOC(H5G_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for group")
+
+ /* Shallow copy (take ownership) of the group entry object */
+ if(H5G_ent_copy(&(grp->ent), ent, H5G_COPY_SHALLOW)<0)
+ HGOTO_ERROR (H5E_SYM, H5E_CANTCOPY, NULL, "can't copy group entry")
+
+ grp->shared=shared_fo;
+ shared_fo->fo_count++;
+ }
/* Set return value */
ret_value = grp;
@@ -1962,7 +2002,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-H5G_t *
+static H5G_t *
H5G_open_oid(H5G_entry_t *ent, hid_t dxpl_id)
{
H5G_t *grp = NULL;
@@ -1977,6 +2017,8 @@ H5G_open_oid(H5G_entry_t *ent, hid_t dxpl_id)
/* Open the object, making sure it's a group */
if (NULL==(grp = H5FL_CALLOC(H5G_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ if (NULL==(grp->shared = H5FL_CALLOC(H5G_t)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* Copy over (take ownership) of the group entry object */
H5G_ent_copy(&(grp->ent),ent,H5G_COPY_SHALLOW);
@@ -1988,14 +2030,16 @@ H5G_open_oid(H5G_entry_t *ent, hid_t dxpl_id)
H5O_close(&(grp->ent));
HGOTO_ERROR (H5E_SYM, H5E_CANTOPENOBJ, NULL, "not a group");
}
- grp->nref = 1;
/* Set return value */
ret_value = grp;
done:
- if (!ret_value && grp)
+ if (!ret_value && grp) {
+ if(grp->shared)
+ H5FL_FREE(H5G_shared_t, grp->shared);
H5FL_FREE(H5G_t,grp);
+ }
FUNC_LEAVE_NOAPI(ret_value);
}
@@ -2061,19 +2105,63 @@ H5G_close(H5G_t *grp)
FUNC_ENTER_NOAPI(H5G_close, FAIL);
/* Check args */
- assert(grp);
- assert(grp->nref > 0);
+ assert(grp && grp->shared);
+ assert(grp->shared->fo_count > 0);
+
+ --grp->shared->fo_count;
+
+ if (0 == grp->shared->fo_count) {
+ assert (grp!=H5G_rootof(H5G_fileof(grp)));
- if (1 == grp->nref) {
- assert (grp!=H5G_rootof(H5G_fileof(grp)));
- if (H5O_close(&(grp->ent)) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close");
- grp->nref = 0;
- H5FL_FREE (H5G_t,grp);
+ /* Remove the dataset from the list of opened objects in the file */
+ if(H5FO_delete(grp->ent.file, H5AC_dxpl_id, grp->ent.header)<0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't remove group from list of open objects")
+ if (H5O_close(&(grp->ent)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close");
+ H5FL_FREE (H5G_shared_t, grp->shared);
} else {
- --grp->nref;
+ if(H5G_free_ent_name(&(grp->ent))<0)
+ {
+ H5FL_FREE (H5G_t,grp);
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't free group entry name");
+ }
}
+ H5FL_FREE (H5G_t,grp);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_free
+ *
+ * Purpose: Free memory used by an H5G_t struct (and its H5G_shared_t).
+ * Does not close the group or decrement the reference count.
+ * Used to free memory used by the root group.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * Tuesday, September 7, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_free(H5G_t *grp)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+ FUNC_ENTER_NOAPI(H5G_free, FAIL);
+
+ assert(grp && grp->shared);
+
+ H5FL_FREE(H5G_shared_t, grp->shared);
+ H5FL_FREE(H5G_t, grp);
+
done:
FUNC_LEAVE_NOAPI(ret_value);
}
@@ -3238,8 +3326,8 @@ H5G_free_grp_name(H5G_t *grp)
FUNC_ENTER_NOAPI(H5G_free_grp_name, FAIL);
/* Check args */
- assert(grp);
- assert(grp->nref > 0);
+ assert(grp && grp->shared);
+ assert(grp->shared->fo_count > 0);
/* Get the entry for the group */
if (NULL==( ent = H5G_entof(grp)))