diff options
author | James Laird <jlaird@hdfgroup.org> | 2004-09-28 19:04:19 (GMT) |
---|---|---|
committer | James Laird <jlaird@hdfgroup.org> | 2004-09-28 19:04:19 (GMT) |
commit | 5c0011a71384223791d18028968382db43f08a6f (patch) | |
tree | 113cc1dd6c8d0ecd1996ddb8f0e9f7693f470e95 /src/H5G.c | |
parent | a841ea35292de8097b429f98af48b29f21c97893 (diff) | |
download | hdf5-5c0011a71384223791d18028968382db43f08a6f.zip hdf5-5c0011a71384223791d18028968382db43f08a6f.tar.gz hdf5-5c0011a71384223791d18028968382db43f08a6f.tar.bz2 |
[svn-r9329]
Purpose:
Feature
Description:
Datatypes and groups now use H5FO "file object" code that was previously
only used by datasets. These objects will hold a file open if the file
is closed but they have not yet been closed. If these objects are unlinked
then relinked, they will not be destroyed. If they are opened twice (even
by two different names), both IDs will "see" changes made to the object
using the other ID.
When an object is opened using two different names (e.g., if a dataset was
opened under one name, then mounted and opened under its new name), calling
H5Iget_name() on a given hid_t will return the name used to open that hid_t,
not the current name of the object (this is a feature, and a change from the
previous behavior of datasets).
Solution:
Used H5FO code that was already in place for datasets. Broke H5D_t's, H5T_t's,
and H5G_t's into a "shared" struct and a private struct. The shared structs
(H5D_shared_t, etc.) hold the object's information and are used by all IDs
that point to a given object in the file. The private structs are pointed
to by the hid_t and contain the object's group entry information (including its
name) and a pointer to the shared struct for that object.
This changed the naming of structs throughout the library (e.g., datatype->size
is now datatype->shared->size). I added an updated H5Tinit.c to windows.zip.
Platforms tested:
Visual Studio 7, sleipnir, arabica, verbena
Misc. update:
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))) |