diff options
Diffstat (limited to 'src/H5G.c')
-rw-r--r-- | src/H5G.c | 190 |
1 files changed, 139 insertions, 51 deletions
@@ -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))) |