summaryrefslogtreecommitdiffstats
path: root/src/H5I.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5I.c')
-rw-r--r--src/H5I.c1258
1 files changed, 943 insertions, 315 deletions
diff --git a/src/H5I.c b/src/H5I.c
index ecf3169..bf378ee 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -16,13 +16,14 @@
* FILE: H5I.c - Internal storage routines for handling "IDs"
*
* REMARKS: ID's which allow objects (void *'s currently) to be bundled
- * into "groups" for more general storage.
+ * into "types" for more general storage.
*
- * DESIGN: The groups are stored in an array of pointers to store each
- * group in an element. Each "group" node contains a link to a
- * hash table to manage the IDs in each group. The allowed
- * "groups" are stored in an enum (called group_t) in
- * H5Ipublic.h.
+ * DESIGN: The types are stored in an array of pointers to store each
+ * type in an element. Each "type" node contains a link to a
+ * hash table to manage the IDs in each type. Allowed types are
+ * values within the range 1 to MAX_NUM_TYPES and are given out
+ * at run-time. Types used by the library are stored in global
+ * variables defined in H5Ipublic.h.
*
* AUTHOR: Quincey Koziol
*
@@ -30,6 +31,7 @@
* 1/3/96 - Starting writing specs & coding prototype
* 1/7/96 - Finished coding prototype
* 6/10/97 - Moved into HDF5 library
+ * 5/18/04 - Expanded to allow registration of new types at run-time
*/
#define H5I_PACKAGE /*suppress error about including H5Ipkg */
@@ -80,8 +82,8 @@ static int interface_initialize_g = 0;
# define H5I_LOC(a,s) (((hid_t)(a)&ID_MASK)%(s))
#endif
-/* Combine a Group number and an atom index into an atom */
-#define H5I_MAKE(g,i) ((((hid_t)(g)&GROUP_MASK)<<ID_BITS)| \
+/* Combine a Type number and an atom index into an atom */
+#define H5I_MAKE(g,i) ((((hid_t)(g)&TYPE_MASK)<<ID_BITS)| \
((hid_t)(i)&ID_MASK))
/* Local typedefs */
@@ -94,9 +96,9 @@ typedef struct H5I_id_info_t {
struct H5I_id_info_t *next; /* link to next atom (in case of hash-clash)*/
} H5I_id_info_t;
-/* ID group structure used */
+/* ID type structure used */
typedef struct {
- unsigned count; /*# of times this group has been initialized*/
+ unsigned count; /*# of times this type has been initialized*/
unsigned reserved; /*# of IDs to reserve for constant IDs */
unsigned wrapped; /*whether the id count has wrapped around */
size_t hash_size; /*sizeof the hash table to store the IDs in */
@@ -104,12 +106,21 @@ typedef struct {
unsigned nextid; /*ID to use for the next atom */
H5I_free_t free_func; /*release object method */
H5I_id_info_t **id_list; /*pointer to an array of ptrs to IDs */
-} H5I_id_group_t;
+} H5I_id_type_t;
+
/*-------------------- Locally scoped variables -----------------------------*/
-/* Array of pointers to atomic groups */
-static H5I_id_group_t *H5I_id_group_list_g[H5I_NGROUPS];
+/* Array of pointers to atomic types */
+static H5I_id_type_t *H5I_id_type_list_g[MAX_NUM_TYPES];
+
+/* Variable to keep track of the number of types allocated. Its value is the */
+/* next type ID to be handed out, so it is always one greater than the number */
+/* of types. */
+/* Starts at 1 instead of 0 because it makes trace output look nicer. If more */
+/* types (or IDs within a type) are needed, adjust TYPE_BITS in H5Ipkg.h */
+/* and/or increase size of hid_t */
+static H5I_type_t H5I_next_type = (H5I_type_t) H5I_NTYPES;
/* Declare a free list to manage the H5I_id_info_t struct */
H5FL_DEFINE_STATIC(H5I_id_info_t);
@@ -120,7 +131,7 @@ static H5I_id_info_t *H5I_find_id(hid_t id);
static hid_t H5I_get_file_id(hid_t obj_id);
static int H5I_get_ref(hid_t id);
#ifdef H5I_DEBUG_OUTPUT
-static herr_t H5I_debug(H5I_type_t grp);
+static herr_t H5I_debug(H5I_type_t type);
#endif /* H5I_DEBUG_OUTPUT */
@@ -144,12 +155,6 @@ H5I_init_interface(void)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5I_init_interface);
- /*
- * Make certain the ID types don't overflow the number of bits allocated
- * for them in an ID.
- */
- assert(H5I_NGROUPS<=(1<<GROUP_BITS));
-
FUNC_LEAVE_NOAPI(SUCCEED);
}
@@ -159,7 +164,7 @@ H5I_init_interface(void)
*
* Purpose: Terminate the H5I interface: release all memory, reset all
* global variables to initial values. This only happens if all
- * groups have been destroyed from other interfaces.
+ * types have been destroyed from other interfaces.
*
* Return: Success: Positive if any action was taken that might
* affect some other interface; zero otherwise.
@@ -175,25 +180,25 @@ H5I_init_interface(void)
int
H5I_term_interface(void)
{
- H5I_id_group_t *grp_ptr;
- H5I_type_t grp;
+ H5I_id_type_t *type_ptr;
+ H5I_type_t type;
int n=0;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5I_term_interface);
if (interface_initialize_g) {
- /* How many groups are still being used? */
- for (grp=(H5I_type_t)0; grp<H5I_NGROUPS; H5_INC_ENUM(H5I_type_t,grp)) {
- if ((grp_ptr=H5I_id_group_list_g[grp]) && grp_ptr->id_list)
+ /* How many types are still being used? */
+ for (type=(H5I_type_t)0; type<H5I_next_type; H5_INC_ENUM(H5I_type_t,type)) {
+ if ((type_ptr=H5I_id_type_list_g[type]) && type_ptr->id_list)
n++;
}
- /* If no groups are used then clean up */
+ /* If no types are used then clean up */
if (0==n) {
- for (grp=(H5I_type_t)0; grp<H5I_NGROUPS; H5_INC_ENUM(H5I_type_t,grp)) {
- grp_ptr = H5I_id_group_list_g[grp];
- H5MM_xfree(grp_ptr);
- H5I_id_group_list_g[grp] = NULL;
+ for (type=(H5I_type_t)0; type<H5I_next_type; H5_INC_ENUM(H5I_type_t,type)) {
+ type_ptr = H5I_id_type_list_g[type];
+ H5MM_xfree(type_ptr);
+ H5I_id_type_list_g[type] = NULL;
}
}
@@ -202,31 +207,69 @@ H5I_term_interface(void)
}
FUNC_LEAVE_NOAPI(n);
}
-
-
/*-------------------------------------------------------------------------
- * Function: H5I_init_group
- *
- * Purpose: Initialize an ID group whose ID number is specified by GRP,
- * If the group has already been initialized, this routine just
- * increments the count of number of initializations and returns
- * without trying to change the size of the hash table. A
- * specific number (RESERVED) of group entries may be reserved
- * to enable "constant" values to be handed out which are valid
- * IDs in the group, but which do not map to any data structures
- * and are not allocated dynamicly later. HASH_SIZE is the
- * minimum hash table size to use for the group. FREE_FUNC is
+ * Function: H5Iregister_type
+ *
+ * Purpose: Public interface to H5I_register_type. Creates a new type
+ * of ID's to give out. A specific number (RESERVED) of type
+ * entries may be reserved to enable "constant" values to be handed
+ * out which are valid IDs in the type, but which do not map to any
+ * data structures and are not allocated dynamically later. HASH_SIZE is
+ * the minimum hash table size to use for the type. FREE_FUNC is
* called with an object pointer when the object is removed from
- * the group.
+ * the type.
*
- * Return: Success: Non-negative
+ * Return: Success: Type ID of the new type
*
- * Failure: Negative
+ * Failure: H5I_BADID
*
- * Programmer: Robb Matzke
- * Friday, February 19, 1999
+ * Programmers: Nathaniel Furrer
+ * James Laird
+ * Friday, April 30, 2004
*
* Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5I_type_t H5Iregister_type(size_t hash_size, unsigned reserved, H5I_free_t free_func)
+{
+ H5I_type_t ret_value;
+ FUNC_ENTER_API(H5Iregister_type, H5I_BADID);
+
+ /* Call H5I_register_type with a value of 0 to get a new type */
+ ret_value = H5I_register_type(0, hash_size, reserved, free_func);
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_register_type
+ *
+ * Purpose: Creates a new type of ID's to give out. A specific number
+ * (RESERVED) of type entries may be reserved to enable "constant"
+ * values to be handed out which are valid IDs in the type, but
+ * which do not map to any data structures and are not allocated
+ * dynamically later. TYPE_ID is the H5I_type_t value of the type
+ * to be initialized. If this value is zero, a new type is created.
+ * If this value is one of the library types, that type is
+ * initialized or its reference count is incremented (if it is already
+ * initialized). HASH_SIZE is the minimum hash table size to
+ * use for the type. FREE_FUNC is called with an object pointer
+ * when the object is removed from the type.
+ *
+ * Return: Success: Type ID of the new type
+ * Failure: H5I_BADID
+ *
+ * Programmers: Nathaniel Furrer
+ * James Laird
+ * Friday, April 30, 2004
+ *
+ * Modifications: The initialization section of this function was formerly
+ * H5I_init_type, programmed by Robb Matzke on February 19,
+ * 1999.
+ *
* Bill Wendling, 2000-05-05
* Instead of the ugly test of whether hash_size is a power of
* two, I placed it in a macro POWER_OF_TWO which uses the fact
@@ -238,68 +281,142 @@ H5I_term_interface(void)
*
*-------------------------------------------------------------------------
*/
-int
-H5I_init_group(H5I_type_t grp, size_t hash_size, unsigned reserved,
- H5I_free_t free_func)
+
+H5I_type_t H5I_register_type(H5I_type_t type_id, size_t hash_size, unsigned reserved, H5I_free_t free_func)
{
- H5I_id_group_t *grp_ptr = NULL; /*ptr to the atomic group*/
- int ret_value = SUCCEED; /*return value */
+ H5I_type_t ret_value; /* type ID to return */
+ H5I_id_type_t *type_ptr = NULL; /*ptr to the atomic type*/
+ int i;
+ int done;
+
+ FUNC_ENTER_NOAPI(H5I_register_type, H5I_BADID);
- FUNC_ENTER_NOAPI(H5I_init_group, FAIL);
+ /* Check that type_id is either a library type or zero */
+ if(type_id < 0 || type_id >= H5I_NTYPES)
+ {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, H5I_BADID, "invalid type ID");
+ }
+
+ if(type_id == 0) /* Generate a new H5I_type_t value */
+ {
+ /* Increment the number of types*/
+ if (H5I_next_type < MAX_NUM_TYPES)
+ {
+ ret_value = H5I_next_type;
+ H5I_next_type++;
+ }
+ else
+ {
+ done = 0;
+ /* Look for a free type to give out */
+ for(i = H5I_NTYPES; i < MAX_NUM_TYPES && done==0; i++)
+ {
+ if(H5I_id_type_list_g[i] == NULL)
+ {
+ /* Found a free type ID */
+ ret_value = i;
+ done = 1;
+ }
+ }
+
+ /* Verify that we found a type to give out */
+ if(done == 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5I_BADID, "Maximum number of ID types exceeded.");
+ }
+ }
+ else /* type_id is a library type; use this value. */
+ {
+ ret_value = type_id;
+ }
+
+ /* Initialize the type */
/* Check arguments */
- if ((grp <= H5I_BADID || grp >= H5I_NGROUPS) && hash_size > 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
#ifdef HASH_SIZE_POWER_2
if (!POWER_OF_TWO(hash_size) || hash_size == 1)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid hash size");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, H5I_BADID, "invalid hash size");
#endif /* HASH_SIZE_POWER_2 */
- if (H5I_id_group_list_g[grp] == NULL) {
- /* Allocate the group information for new group */
- if (NULL==(grp_ptr = H5MM_calloc(sizeof(H5I_id_group_t))))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- H5I_id_group_list_g[grp] = grp_ptr;
+ if (H5I_id_type_list_g[ret_value] == NULL) {
+ /* Allocate the type information for new type */
+ if (NULL==(type_ptr = H5MM_calloc(sizeof(H5I_id_type_t))))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, H5I_BADID, "memory allocation failed");
+ H5I_id_type_list_g[ret_value] = type_ptr;
} else {
- /* Get the pointer to the existing group */
- grp_ptr = H5I_id_group_list_g[grp];
+ /* Get the pointer to the existing type */
+ type_ptr = H5I_id_type_list_g[ret_value];
}
- if (grp_ptr->count == 0) {
- /* Initialize the ID group structure for new groups */
- grp_ptr->hash_size = hash_size;
- grp_ptr->reserved = reserved;
- grp_ptr->wrapped = 0;
- grp_ptr->ids = 0;
- grp_ptr->nextid = reserved;
- grp_ptr->free_func = free_func;
- grp_ptr->id_list = H5MM_calloc(hash_size*sizeof(H5I_id_info_t *));
- if (NULL==grp_ptr->id_list)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ if (type_ptr->count == 0) {
+ /* Initialize the ID type structure for new types */
+ type_ptr->hash_size = hash_size;
+ type_ptr->reserved = reserved;
+ type_ptr->wrapped = 0;
+ type_ptr->ids = 0;
+ type_ptr->nextid = reserved;
+ type_ptr->free_func = free_func;
+ type_ptr->id_list = H5MM_calloc(hash_size*sizeof(H5I_id_info_t *));
+ if (NULL==type_ptr->id_list)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, H5I_BADID, "memory allocation failed");
}
-
- /* Increment the count of the times this group has been initialized */
- grp_ptr->count++;
-done:
- if (ret_value<0) {
- /* Error condition cleanup */
- if (grp_ptr != NULL) {
- H5MM_xfree(grp_ptr->id_list);
- H5MM_xfree(grp_ptr);
+ /* Increment the count of the times this type has been initialized */
+ type_ptr->count++;
+
+ done:
+ if(ret_value == H5I_BADID) /* Clean up on error */
+ {
+ if (type_ptr != NULL)
+ {
+ H5MM_xfree(type_ptr->id_list);
+ H5MM_xfree(type_ptr);
+ }
}
- }
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value);
}
-
+/*-------------------------------------------------------------------------
+ * Function: H5Inmembers
+ *
+ * Purpose: Returns the number of members in a type. Public interface to
+ * H5I_nmembers.
+ *
+ * Return: Success: Number of members; zero if the type is empty
+ * or has been deleted.
+ *
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * Nathaniel Furrer
+ * Friday, April 23, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int H5Inmembers(H5I_type_t type)
+{
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Inmembers, FAIL);
+
+ if( H5I_IS_LIB_TYPE( type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
+ }
+
+ ret_value = H5I_nmembers(type);
+
+ done:
+ FUNC_LEAVE_API(ret_value);
+}
/*-------------------------------------------------------------------------
* Function: H5I_nmembers
*
- * Purpose: Returns the number of members in a group.
+ * Purpose: Returns the number of members in a type.
*
- * Return: Success: Number of members; zero if the group is empty
+ * Return: Success: Number of members; zero if the type is empty
* or has been deleted.
*
* Failure: Negative
@@ -312,9 +429,9 @@ done:
*-------------------------------------------------------------------------
*/
int
-H5I_nmembers(H5I_type_t grp)
+H5I_nmembers(H5I_type_t type)
{
- H5I_id_group_t *grp_ptr = NULL;
+ H5I_id_type_t *type_ptr = NULL;
H5I_id_info_t *cur=NULL;
int n=0;
unsigned i;
@@ -322,13 +439,13 @@ H5I_nmembers(H5I_type_t grp)
FUNC_ENTER_NOAPI(H5I_nmembers, FAIL);
- if (grp<=H5I_BADID || grp>=H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
- if (NULL==(grp_ptr=H5I_id_group_list_g[grp]) || grp_ptr->count<=0)
+ if (type<=H5I_BADID || type>=H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ if (NULL==(type_ptr=H5I_id_type_list_g[type]) || type_ptr->count<=0)
HGOTO_DONE(0);
- for (i=0; i<grp_ptr->hash_size; i++)
- for (cur=grp_ptr->id_list[i]; cur; cur=cur->next)
+ for (i=0; i<type_ptr->hash_size; i++)
+ for (cur=type_ptr->id_list[i]; cur; cur=cur->next)
n++;
/* Set return value */
@@ -338,11 +455,45 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
}
-
/*-------------------------------------------------------------------------
- * Function: H5I_clear_group
+ * Function: H5Iclear_type
*
- * Purpose: Removes all objects from the group, calling the free
+ * Purpose: Removes all objects from the type, calling the free
+ * function for each object regardless of the reference count.
+ * Public interface to H5I_clear_type.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: James Laird
+ * Nathaniel Furrer
+ * Friday, April 23, 2004
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+herr_t H5Iclear_type(H5I_type_t type, hbool_t force)
+{
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Iclear_type, FAIL);
+
+ if( H5I_IS_LIB_TYPE( type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
+ }
+
+ ret_value = H5I_clear_type(type, force);
+
+ done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_clear_type
+ *
+ * Purpose: Removes all objects from the type, calling the free
* function for each object regardless of the reference count.
*
* Return: Success: Non-negative
@@ -368,9 +519,9 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5I_clear_group(H5I_type_t grp, hbool_t force)
+H5I_clear_type(H5I_type_t type, hbool_t force)
{
- H5I_id_group_t *grp_ptr = NULL; /* ptr to the atomic group */
+ H5I_id_type_t *type_ptr = NULL; /* ptr to the atomic type */
H5I_id_info_t *cur=NULL; /* Current node being worked with */
H5I_id_info_t *next=NULL; /* Next node in list */
H5I_id_info_t *last=NULL; /* Last node seen */
@@ -379,22 +530,22 @@ H5I_clear_group(H5I_type_t grp, hbool_t force)
unsigned delete_node; /* Flag to indicate node should be removed from linked list */
unsigned i;
- FUNC_ENTER_NOAPI(H5I_clear_group, FAIL);
+ FUNC_ENTER_NOAPI(H5I_clear_type, FAIL);
- if (grp <= H5I_BADID || grp >= H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
- grp_ptr = H5I_id_group_list_g[grp];
- if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid group");
+ type_ptr = H5I_id_type_list_g[type];
+ if (type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
/*
- * Call free method for all objects in group regardless of their reference
+ * Call free method for all objects in type regardless of their reference
* counts. Ignore the return value from from the free method and remove
- * object from group regardless if FORCE is non-zero.
+ * object from type regardless if FORCE is non-zero.
*/
- for (i=0; i<grp_ptr->hash_size; i++) {
- for (cur=grp_ptr->id_list[i]; cur; cur=next) {
+ for (i=0; i<type_ptr->hash_size; i++) {
+ for (cur=type_ptr->id_list[i]; cur; cur=next) {
/*
* Do nothing to the object if the reference count is larger than
* one and forcing is off.
@@ -405,12 +556,12 @@ H5I_clear_group(H5I_type_t grp, hbool_t force)
} /* end if */
/* Check for a 'free' function and call it, if it exists */
- if (grp_ptr->free_func && (grp_ptr->free_func)(cur->obj_ptr)<0) {
+ if (type_ptr->free_func && (type_ptr->free_func)(cur->obj_ptr)<0) {
if (force) {
#ifdef H5I_DEBUG
if (H5DEBUG(I)) {
- fprintf(H5DEBUG(I), "H5I: free grp=%d obj=0x%08lx "
- "failure ignored\n", (int)grp,
+ fprintf(H5DEBUG(I), "H5I: free type=%d obj=0x%08lx "
+ "failure ignored\n", (int)type,
(unsigned long)(cur->obj_ptr));
} /* end if */
#endif /*H5I_DEBUG*/
@@ -430,8 +581,8 @@ H5I_clear_group(H5I_type_t grp, hbool_t force)
/* Check if we should delete this node or not */
if(delete_node) {
- /* Decrement the number of IDs in the group */
- (grp_ptr->ids)--;
+ /* Decrement the number of IDs in the type */
+ (type_ptr->ids)--;
/* Advance to next node */
next = cur->next;
@@ -442,7 +593,7 @@ H5I_clear_group(H5I_type_t grp, hbool_t force)
/* make an H5I call, which could potentially change the */
/* order of the nodes on the list - QAK) */
last=NULL;
- tmp=grp_ptr->id_list[i];
+ tmp=type_ptr->id_list[i];
while(tmp!=cur) {
assert(tmp!=NULL);
last=tmp;
@@ -452,8 +603,8 @@ H5I_clear_group(H5I_type_t grp, hbool_t force)
/* Delete the node from the list */
if(last==NULL) {
/* Node at head of list, just advance the list head to next node */
- assert(grp_ptr->id_list[i]==cur);
- grp_ptr->id_list[i] = next;
+ assert(type_ptr->id_list[i]==cur);
+ type_ptr->id_list[i] = next;
} /* end if */
else {
/* Node in middle of list, jump over it */
@@ -475,71 +626,126 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
}
-
/*-------------------------------------------------------------------------
- * Function: H5I_destroy_group
+ * Function: H5Idestroy_type
*
- * Purpose: Decrements the reference count on an entire group of IDs.
- * If the group reference count becomes zero then the group is
- * destroyed along with all atoms in that group regardless of
- * their reference counts. Destroying IDs involves calling
- * the free-func for each ID's object and then adding the ID
- * struct to the ID free list.
+ * Purpose: Destroys a type along with all atoms in that type
+ * regardless of their reference counts. Destroying IDs
+ * involves calling the free-func for each ID's object and
+ * then adding the ID struct to the ID free list. Public
+ * interface to H5I_destroy_type.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Zero on success/Negative on failure
*
- * Programmer: Unknown
+ * Programmer: Nathaniel Furrer
+ * James Laird
*
* Modifications:
*
- * Robb Matzke, 25 Feb 1998
- * IDs are freed when a group is destroyed.
+ *-------------------------------------------------------------------------
+ */
+herr_t H5Idestroy_type(H5I_type_t type)
+{
+ herr_t ret_value;
+
+ FUNC_ENTER_API(H5Idestroy_type, FAIL);
+
+ if( H5I_IS_LIB_TYPE( type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
+ }
+
+ ret_value = H5I_destroy_type(type);
+
+ done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_destroy_type
+ *
+ * Purpose: Destroys a type along with all atoms in that type
+ * regardless of their reference counts. Destroying IDs
+ * involves calling the free-func for each ID's object and
+ * then adding the ID struct to the ID free list.
+ *
+ * Return: Zero on success/Negative on failure
+ *
+ * Programmer: Nathaniel Furrer
+ * James Laird
+ *
+ * Modifications:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5I_destroy_group(H5I_type_t grp)
+herr_t H5I_destroy_type(H5I_type_t type)
{
- H5I_id_group_t *grp_ptr = NULL; /* ptr to the atomic group */
- int ret_value = SUCCEED;
+ herr_t ret_value = FAIL;
+ H5I_id_type_t *type_ptr = NULL; /* ptr to the atomic type */
- FUNC_ENTER_NOAPI(H5I_destroy_group, FAIL);
+ FUNC_ENTER_NOAPI(H5I_destroy_type, FAIL);
- if (grp <= H5I_BADID || grp >= H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
-
- grp_ptr = H5I_id_group_list_g[grp];
- if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid group");
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
- /*
- * Decrement the number of users of the atomic group. If this is the
- * last user of the group then release all atoms from the group. The
- * free function is invoked for each atom being freed.
- */
- if (1==grp_ptr->count) {
- H5I_clear_group(grp, TRUE);
- H5E_clear(NULL); /*don't care about errors*/
- H5MM_xfree(grp_ptr->id_list);
- HDmemset (grp_ptr, 0, sizeof(*grp_ptr));
- } else {
- --(grp_ptr->count);
- }
-
- done:
- FUNC_LEAVE_NOAPI(ret_value);
+ type_ptr = H5I_id_type_list_g[type];
+ if (type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
+
+ H5I_clear_type(type, TRUE);
+ H5E_clear(NULL); /*don't care about errors*/
+ H5MM_xfree(type_ptr->id_list);
+
+ H5MM_free(type_ptr);
+ H5I_id_type_list_g[type] = NULL;
+ ret_value = 0;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Iregister
+ *
+ * Purpose: Public interface to H5I_register.
+ *
+ * Return: Success: New object id.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Nathaniel Furrer
+ * James Laird
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t H5Iregister(H5I_type_t type, void *object)
+{
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Iregister, H5I_INVALID_HID);
+
+ if( H5I_IS_LIB_TYPE( type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
+ }
+
+ ret_value = H5I_register(type, object);
+
+ done:
+ FUNC_LEAVE_API(ret_value);
}
-
/*-------------------------------------------------------------------------
* Function: H5I_register
*
- * Purpose: Registers an OBJECT in a GROUP and returns an ID for it.
+ * Purpose: Registers an OBJECT in a TYPE and returns an ID for it.
* This routine does _not_ check for unique-ness of the objects,
* if you register an object twice, you will get two different
* IDs for it. This routine does make certain that each ID in a
- * group is unique. IDs are created by getting a unique number
- * for the group the ID is in and incorporating the group into
+ * type is unique. IDs are created by getting a unique number
+ * for the type the ID is in and incorporating the type into
* the ID which is returned to the user.
*
* Return: Success: New object id.
@@ -553,9 +759,9 @@ H5I_destroy_group(H5I_type_t grp)
*-------------------------------------------------------------------------
*/
hid_t
-H5I_register(H5I_type_t grp, void *object)
+H5I_register(H5I_type_t type, void *object)
{
- H5I_id_group_t *grp_ptr=NULL; /*ptr to the group */
+ H5I_id_type_t *type_ptr=NULL; /*ptr to the type */
H5I_id_info_t *id_ptr=NULL; /*ptr to the new ID information */
hid_t new_id; /*new ID */
unsigned hash_loc; /*new item's hash table location*/
@@ -567,61 +773,61 @@ H5I_register(H5I_type_t grp, void *object)
FUNC_ENTER_NOAPI(H5I_register, FAIL);
/* Check arguments */
- if (grp <= H5I_BADID || grp >= H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
- grp_ptr = H5I_id_group_list_g[grp];
- if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid group");
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ type_ptr = H5I_id_type_list_g[type];
+ if (type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
if ((id_ptr = H5FL_MALLOC(H5I_id_info_t)) == NULL)
HGOTO_ERROR(H5E_ATOM, H5E_NOSPACE, FAIL, "memory allocation failed");
/* Create the struct & it's ID */
- new_id = H5I_MAKE(grp, grp_ptr->nextid);
+ new_id = H5I_MAKE(type, type_ptr->nextid);
id_ptr->id = new_id;
id_ptr->count = 1; /*initial reference count*/
id_ptr->obj_ptr = object;
id_ptr->next = NULL;
/* hash bucket already full, prepend to front of chain */
- hash_loc = grp_ptr->nextid % (unsigned) grp_ptr->hash_size;
- if (grp_ptr->id_list[hash_loc] != NULL)
- id_ptr->next = grp_ptr->id_list[hash_loc];
+ hash_loc = type_ptr->nextid % (unsigned) type_ptr->hash_size;
+ if (type_ptr->id_list[hash_loc] != NULL)
+ id_ptr->next = type_ptr->id_list[hash_loc];
- /* Insert into the group */
- grp_ptr->id_list[hash_loc] = id_ptr;
- grp_ptr->ids++;
- grp_ptr->nextid++;
+ /* Insert into the type */
+ type_ptr->id_list[hash_loc] = id_ptr;
+ type_ptr->ids++;
+ type_ptr->nextid++;
/*
* This next section of code checks for the 'nextid' getting too large and
* wrapping around, thus necessitating checking for duplicate IDs being
* handed out.
*/
- if (grp_ptr->nextid > (unsigned)ID_MASK) {
- grp_ptr->wrapped = 1;
- grp_ptr->nextid = grp_ptr->reserved;
+ if (type_ptr->nextid > (unsigned)ID_MASK) {
+ type_ptr->wrapped = 1;
+ type_ptr->nextid = type_ptr->reserved;
}
/*
* If we've wrapped around then we need to check for duplicate id's being
* handed out.
*/
- if (grp_ptr->wrapped) {
+ if (type_ptr->wrapped) {
/*
* Make sure we check all available ID's. If we're about at the end
* of the range then wrap around and check the beginning values. If
* we check all possible values and didn't find any free ones *then*
* we can fail.
*/
- for (i=grp_ptr->reserved; i<ID_MASK; i++) {
+ for (i=type_ptr->reserved; i<ID_MASK; i++) {
/* Handle end of range by wrapping to beginning */
- if (grp_ptr->nextid>(unsigned)ID_MASK)
- grp_ptr->nextid = grp_ptr->reserved;
+ if (type_ptr->nextid>(unsigned)ID_MASK)
+ type_ptr->nextid = type_ptr->reserved;
/* new ID to check for */
- next_id = H5I_MAKE(grp, grp_ptr->nextid);
- hash_loc = H5I_LOC (grp_ptr->nextid, grp_ptr->hash_size);
- curr_id = grp_ptr->id_list[hash_loc];
+ next_id = H5I_MAKE(type, type_ptr->nextid);
+ hash_loc = H5I_LOC (type_ptr->nextid, type_ptr->hash_size);
+ curr_id = type_ptr->id_list[hash_loc];
if (curr_id == NULL)
break; /* Ha! this is not likely... */
@@ -632,12 +838,12 @@ H5I_register(H5I_type_t grp, void *object)
}
if (!curr_id)
break; /* must not have found a match */
- grp_ptr->nextid++;
+ type_ptr->nextid++;
}
if (i>=(unsigned)ID_MASK)
/* All the IDs are gone! */
- HGOTO_ERROR(H5E_ATOM, H5E_NOIDS, FAIL, "no IDs available in group");
+ HGOTO_ERROR(H5E_ATOM, H5E_NOIDS, FAIL, "no IDs available in type");
}
ret_value = new_id;
@@ -680,12 +886,48 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
}
-
+/*-------------------------------------------------------------------------
+ * Function: H5Iobject_verify
+ *
+ * Purpose: Find an object pointer for the specified ID, verifying that
+ * its in a particular type. Public interface to
+ * H5I_object_verify.
+ *
+ * Return: Success: Non-null object pointer associated with the
+ * specified ID.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Nathaniel Furrer
+ * James Laird
+ * Friday, April 23, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *H5Iobject_verify(hid_t id, H5I_type_t id_type)
+{
+ void * ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Iobject_verify, NULL);
+
+ if( H5I_IS_LIB_TYPE( id_type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type");
+ }
+
+ ret_value = H5I_object_verify(id, id_type);
+
+ done:
+ FUNC_LEAVE_API(ret_value);
+}
+
/*-------------------------------------------------------------------------
* Function: H5I_object_verify
*
* Purpose: Find an object pointer for the specified ID, verifying that
- * its in a particular group.
+ * its in a particular type.
*
* Return: Success: Non-null object pointer associated with the
* specified ID.
@@ -707,10 +949,10 @@ H5I_object_verify(hid_t id, H5I_type_t id_type)
FUNC_ENTER_NOAPI(H5I_object_verify, NULL);
- assert(id_type>=H5I_FILE && id_type<H5I_NGROUPS);
+ assert(id_type>=1 && id_type<H5I_next_type);
- /* Verify that the group of the ID is correct & lookup the ID */
- if(id_type == H5I_GRP(id) && NULL!=(id_ptr = H5I_find_id(id))) {
+ /* Verify that the type of the ID is correct & lookup the ID */
+ if(id_type == H5I_TYPE(id) && NULL!=(id_ptr = H5I_find_id(id))) {
/* Get the object pointer to return */
ret_value = id_ptr->obj_ptr;
} /* end if */
@@ -723,12 +965,12 @@ done:
/*-------------------------------------------------------------------------
* Function: H5I_get_type
*
- * Purpose: Given an object ID return the group (type) to which it
+ * Purpose: Given an object ID return the type to which it
* belongs. The ID need not be the ID of an object which
- * currently exists because the group number (type) is encoded
+ * currently exists because the type number is encoded
* in the object ID.
*
- * Return: Success: A valid group number (type)
+ * Return: Success: A valid type number
*
* Failure: H5I_BADID, a negative value.
*
@@ -747,9 +989,9 @@ H5I_get_type(hid_t id)
FUNC_ENTER_NOAPI(H5I_get_type, H5I_BADID);
if (id>0)
- ret_value = H5I_GRP(id);
+ ret_value = H5I_TYPE(id);
- assert(ret_value>=H5I_BADID && ret_value<H5I_NGROUPS);
+ assert(ret_value>=H5I_BADID && ret_value<H5I_next_type);
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -759,12 +1001,12 @@ done:
/*-------------------------------------------------------------------------
* Function: H5Iget_type
*
- * Purpose: The public version of H5I_get_type(), obtains a group number
- * (type) when given an ID. The ID need not be the ID of an
- * object which currently exists because the group number is
+ * Purpose: The public version of H5I_get_type(), obtains a type number
+ * when given an ID. The ID need not be the ID of an
+ * object which currently exists because the type number is
* encoded as part of the ID.
*
- * Return: Success: Group number (type)
+ * Return: Success: Type number
*
* Failure: H5I_BADID, a negative value
*
@@ -772,7 +1014,7 @@ done:
*
* Modifications:
* Robb Matzke, 1999-08-23
- * Also fails if the ID has a valid group but no longer exists
+ * Also fails if the ID has a valid type but no longer exists
* in the ID tables.
*-------------------------------------------------------------------------
*/
@@ -786,7 +1028,7 @@ H5Iget_type(hid_t id)
ret_value = H5I_get_type(id);
- if (ret_value <= H5I_BADID || ret_value >= H5I_NGROUPS || NULL==H5I_object(id))
+ if (ret_value <= H5I_BADID || ret_value >= H5I_next_type || NULL==H5I_object(id))
HGOTO_DONE(H5I_BADID);
done:
@@ -849,47 +1091,120 @@ H5I_get_file_id(hid_t obj_id)
{
H5G_entry_t *ent;
hid_t ret_value;
+ H5I_type_t type;
FUNC_ENTER_NOAPI_NOINIT(H5I_get_file_id);
/* Get object type */
- switch(H5I_GRP(obj_id)) {
- case H5I_FILE:
- ret_value = obj_id;
-
- /* Increment reference count on atom. */
- if (H5I_inc_ref(ret_value)<0)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed");
+ type = H5I_TYPE(obj_id);
+ if(type == H5I_FILE)
+ {
+ ret_value = obj_id;
+
+ /* Increment reference count on atom. */
+ if (H5I_inc_ref(ret_value)<0)
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed");
+ }
+ else if(type == H5I_DATATYPE)
+ {
+ if((ent = H5G_loc(obj_id))==NULL)
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "not a named datatype");
+ ret_value = H5F_get_id(ent->file);
+ }
+ else if(type == H5I_GROUP || type == H5I_DATASET || type == H5I_ATTR)
+ {
+ if((ent = H5G_loc(obj_id))==NULL)
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "can't get symbol table info");
+ ret_value = H5F_get_id(ent->file);
+ }
+ else
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid object ID");
- break;
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
- case H5I_DATATYPE:
- if((ent = H5G_loc(obj_id))==NULL)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "not a named datatype");
- ret_value = H5F_get_id(ent->file);
- break;
+/*-------------------------------------------------------------------------
+ * Function: H5Iremove_verify
+ *
+ * Purpose: Removes the specified ID from its type, first checking that the
+ * type of the ID and the type type are the same. Public interface to
+ * H5I_remove_verify.
+ *
+ * Return: Success: A pointer to the object that was removed, the
+ * same pointer which would have been found by
+ * calling H5I_object().
+ *
+ * Failure: NULL
+ *
+ * Programmer: James Laird
+ * Nathaniel Furrer
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *H5Iremove_verify(hid_t id, H5I_type_t id_type)
+{
+ void * ret_value; /* Return value */
- case H5I_GROUP:
- case H5I_DATASET:
- case H5I_ATTR:
- if((ent = H5G_loc(obj_id))==NULL)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "can't get symbol table info");
- ret_value = H5F_get_id(ent->file);
- break;
+ FUNC_ENTER_API(H5Iremove_verify, NULL);
+
+ if( H5I_IS_LIB_TYPE( id_type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type");
+ }
+
+ /* Remove the id */
+ ret_value = H5I_remove_verify(id, id_type);
+
+ done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_remove_verify
+ *
+ * Purpose: Removes the specified ID from its type, first checking that
+ * the ID's type is the same as the ID type supplied as an argument
+ *
+ * Return: Success: A pointer to the object that was removed, the
+ * same pointer which would have been found by
+ * calling H5I_object().
+ *
+ * Failure: NULL
+ *
+ * Programmer: James Laird
+ * Nat Furrer
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5I_remove_verify(hid_t id, H5I_type_t id_type)
+{
+ void * ret_value = NULL; /*return value */
+
+ FUNC_ENTER_NOAPI(H5I_remove_verify, NULL);
- default:
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid object ID");
- }
+ /* Argument checking will be performed by H5I_remove() */
+
+ /* Verify that the type of the ID is correct */
+ if(id_type == H5I_TYPE(id))
+ {
+ ret_value = H5I_remove(id);
+ }
done:
FUNC_LEAVE_NOAPI(ret_value);
}
-
+
/*-------------------------------------------------------------------------
* Function: H5I_remove
*
- * Purpose: Removes the specified ID from its group.
+ * Purpose: Removes the specified ID from its type.
*
* Return: Success: A pointer to the object that was removed, the
* same pointer which would have been found by
@@ -906,26 +1221,26 @@ done:
void *
H5I_remove(hid_t id)
{
- H5I_id_group_t *grp_ptr = NULL;/*ptr to the atomic group */
+ H5I_id_type_t *type_ptr = NULL;/*ptr to the atomic type */
H5I_id_info_t *curr_id; /*ptr to the current atom */
H5I_id_info_t *last_id; /*ptr to the last atom */
- H5I_type_t grp; /*atom's atomic group */
+ H5I_type_t type; /*atom's atomic type */
unsigned hash_loc; /*atom's hash table location */
void * ret_value = NULL; /*return value */
FUNC_ENTER_NOAPI(H5I_remove, NULL);
/* Check arguments */
- grp = H5I_GRP(id);
- if (grp <= H5I_BADID || grp >= H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid group number");
- grp_ptr = H5I_id_group_list_g[grp];
- if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid group");
+ type = H5I_TYPE(id);
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid type number");
+ type_ptr = H5I_id_type_list_g[type];
+ if (type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type");
/* Get the bucket in which the ID is located */
- hash_loc = (unsigned) H5I_LOC(id, grp_ptr->hash_size);
- curr_id = grp_ptr->id_list[hash_loc];
+ hash_loc = (unsigned) H5I_LOC(id, type_ptr->hash_size);
+ curr_id = type_ptr->id_list[hash_loc];
if (curr_id == NULL)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "invalid ID");
@@ -940,7 +1255,7 @@ H5I_remove(hid_t id)
if (curr_id != NULL) {
if (last_id == NULL) {
/* ID is the first in the chain */
- grp_ptr->id_list[hash_loc] = curr_id->next;
+ type_ptr->id_list[hash_loc] = curr_id->next;
} else {
last_id->next = curr_id->next;
}
@@ -951,14 +1266,14 @@ H5I_remove(hid_t id)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "invalid ID");
}
- /* Decrement the number of IDs in the group */
- (grp_ptr->ids)--;
+ /* Decrement the number of IDs in the type */
+ (type_ptr->ids)--;
done:
FUNC_LEAVE_NOAPI(ret_value);
}
-
+
/*-------------------------------------------------------------------------
* Function: H5Idec_ref
*
@@ -1001,10 +1316,10 @@ done:
* Function: H5I_dec_ref
*
* Purpose: Decrements the number of references outstanding for an ID.
- * This will fail if the group is not a reference counted group.
- * The ID group's 'free' function will be called for the ID
+ * This will fail if the type is not a reference counted type.
+ * The ID type's 'free' function will be called for the ID
* if the reference count for the ID reaches 0 and a free
- * function has been defined at group creation time.
+ * function has been defined at type creation time.
*
* Return: Success: New reference count.
*
@@ -1025,8 +1340,8 @@ done:
*
* Robb Matzke, 19 Feb 1999
* If the free method is defined and fails then the object is not
- * removed from the group and its reference count is not decremented.
- * The group number is now passed to the free method.
+ * removed from the type and its reference count is not decremented.
+ * The type number is now passed to the free method.
*
* Raymond, 11 Dec 2001
* If the freeing function fails, return failure instead of reference
@@ -1038,8 +1353,8 @@ done:
int
H5I_dec_ref(hid_t id)
{
- H5I_type_t grp; /*group the object is in*/
- H5I_id_group_t *grp_ptr; /*ptr to the group */
+ H5I_type_t type; /*type the object is in*/
+ H5I_id_type_t *type_ptr; /*ptr to the type */
H5I_id_info_t *id_ptr; /*ptr to the new ID */
int ret_value; /* Return value */
@@ -1049,29 +1364,29 @@ H5I_dec_ref(hid_t id)
assert(id>=0);
/* Check arguments */
- grp = H5I_GRP(id);
- if (grp <= H5I_BADID || grp >= H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
- grp_ptr = H5I_id_group_list_g[grp];
- if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
+ type = H5I_TYPE(id);
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ type_ptr = H5I_id_type_list_g[type];
+ if (type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
/* General lookup of the ID */
if ((id_ptr=H5I_find_id(id))==NULL)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID");
/*
- * If this is the last reference to the object then invoke the group's
+ * If this is the last reference to the object then invoke the type's
* free method on the object. If the free method is undefined or
- * successful then remove the object from the group; otherwise leave
- * the object in the group without decrementing the reference
+ * successful then remove the object from the type; otherwise leave
+ * the object in the type without decrementing the reference
* count. If the reference count is more than one then decrement the
* reference count without calling the free method.
*
* Beware: the free method may call other H5I functions.
*/
if (1==id_ptr->count) {
- if (!grp_ptr->free_func || (grp_ptr->free_func)(id_ptr->obj_ptr)>=0) {
+ if (!type_ptr->free_func || (type_ptr->free_func)(id_ptr->obj_ptr)>=0) {
H5I_remove(id);
ret_value = 0;
} else {
@@ -1141,8 +1456,8 @@ done:
int
H5I_inc_ref(hid_t id)
{
- H5I_type_t grp; /*group the object is in*/
- H5I_id_group_t *grp_ptr; /*ptr to the group */
+ H5I_type_t type; /*type the object is in*/
+ H5I_id_type_t *type_ptr; /*ptr to the type */
H5I_id_info_t *id_ptr; /*ptr to the ID */
int ret_value; /* Return value */
@@ -1152,12 +1467,12 @@ H5I_inc_ref(hid_t id)
assert(id>=0);
/* Check arguments */
- grp = H5I_GRP(id);
- if (grp <= H5I_BADID || grp >= H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
- grp_ptr = H5I_id_group_list_g[grp];
- if (!grp_ptr || grp_ptr->count<=0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid group");
+ type = H5I_TYPE(id);
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ type_ptr = H5I_id_type_list_g[type];
+ if (!type_ptr || type_ptr->count<=0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
/* General lookup of the ID */
if (NULL==(id_ptr=H5I_find_id(id)))
@@ -1226,8 +1541,8 @@ done:
static int
H5I_get_ref(hid_t id)
{
- H5I_type_t grp; /*group the object is in*/
- H5I_id_group_t *grp_ptr; /*ptr to the group */
+ H5I_type_t type; /*type the object is in*/
+ H5I_id_type_t *type_ptr; /*ptr to the type */
H5I_id_info_t *id_ptr; /*ptr to the ID */
int ret_value; /* Return value */
@@ -1237,12 +1552,12 @@ H5I_get_ref(hid_t id)
assert(id>=0);
/* Check arguments */
- grp = H5I_GRP(id);
- if (grp <= H5I_BADID || grp >= H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
- grp_ptr = H5I_id_group_list_g[grp];
- if (!grp_ptr || grp_ptr->count<=0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid group");
+ type = H5I_TYPE(id);
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ type_ptr = H5I_id_type_list_g[type];
+ if (!type_ptr || type_ptr->count<=0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
/* General lookup of the ID */
if (NULL==(id_ptr=H5I_find_id(id)))
@@ -1255,11 +1570,323 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5I_get_ref() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Iinc_type_ref
+ *
+ * Purpose: Increments the number of references outstanding for an ID type.
+ *
+ * Return: Success: New reference count
+ * Failure: Negative
+ *
+ * Programmer: Nat Furrer
+ * James Laird
+ * April 30, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5Iinc_type_ref(H5I_type_t type)
+{
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Iinc_type_ref, FAIL);
+ H5TRACE1("Is","It",type);
+
+ /* Check arguments */
+ if (type<=0 || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID type");
+
+ if( H5I_IS_LIB_TYPE( type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
+ }
+
+ /* Do actual increment operation */
+ if((ret_value = H5I_inc_type_ref(type))<0)
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID type ref count");
+
+done:
+ FUNC_LEAVE_API(ret_value);
+} /* end H5Iinc_ref() */
+
/*-------------------------------------------------------------------------
+ * Function: H5I_inc_type_ref
+ *
+ * Purpose: Increment the reference count for an ID type.
+ *
+ * Return: Success: The new reference count.
+ *
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * Nat Furrer
+ * Friday, April 30, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5I_inc_type_ref(H5I_type_t type)
+{
+ H5I_id_type_t *type_ptr; /* ptr to the type */
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5I_inc_type_ref, FAIL);
+
+ /* Sanity check */
+ assert(type>0 && type < H5I_next_type);
+
+ /* Check arguments */
+ type_ptr = H5I_id_type_list_g[type];
+ if (!type_ptr )
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
+
+ /* Set return value */
+ ret_value=++(type_ptr->count);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Idec_type_ref
+ *
+ * Purpose: Decrements the reference count on an entire type of IDs.
+ * If the type reference count becomes zero then the type is
+ * destroyed along with all atoms in that type regardless of
+ * their reference counts. Destroying IDs involves calling
+ * the free-func for each ID's object and then adding the ID
+ * struct to the ID free list. Public interface to
+ * H5I_dec_type_ref.
+ * Returns the number of references to the type on success; a
+ * return value of 0 means that the type will have to be
+ * re-initialized before it can be used again (and should probably
+ * be set to H5I_UNINIT).
+ *
+ * Return: Number of references to type on success/Negative on failure
+ *
+ * Programmer: Nathaniel Furrer
+ * James Laird
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t H5Idec_type_ref(H5I_type_t type)
+{
+ herr_t ret_value;
+
+ FUNC_ENTER_API(H5Idec_type_ref, FAIL);
+
+ if( H5I_IS_LIB_TYPE( type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
+ }
+
+ ret_value = H5I_dec_type_ref(type);
+
+ done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_dec_type_ref
+ *
+ * Purpose: Decrements the reference count on an entire type of IDs.
+ * If the type reference count becomes zero then the type is
+ * destroyed along with all atoms in that type regardless of
+ * their reference counts. Destroying IDs involves calling
+ * the free-func for each ID's object and then adding the ID
+ * struct to the ID free list.
+ * Returns the number of references to the type on success; a
+ * return value of 0 means that the type will have to be
+ * re-initialized before it can be used again (and should probably
+ * be set to H5I_UNINIT).
+ *
+ * Return: Number of references to type on success/Negative on failure
+ *
+ * Programmer: Unknown
+ *
+ * Modifications:
+ *
+ * Robb Matzke, 25 Feb 1998
+ * IDs are freed when a type is destroyed.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5I_dec_type_ref(H5I_type_t type)
+{
+ H5I_id_type_t *type_ptr = NULL; /* ptr to the atomic type */
+ herr_t ret_value = FAIL;
+
+ FUNC_ENTER_NOAPI(H5I_dec_type_ref, FAIL);
+
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+
+ type_ptr = H5I_id_type_list_g[type];
+ if (type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
+
+ /*
+ * Decrement the number of users of the atomic type. If this is the
+ * last user of the type then release all atoms from the type and
+ * free all memory it used. The free function is invoked for each atom
+ * being freed.
+ */
+ if (1==type_ptr->count)
+ {
+ H5I_destroy_type(type);
+ ret_value = 0;
+ }
+ else
+ {
+ --(type_ptr->count);
+ ret_value = type_ptr->count;
+ }
+
+ done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Iget_type_ref
+ *
+ * Purpose: Retrieves the number of references outstanding for a type.
+ *
+ * Return: Success: Reference count
+ * Failure: Negative
+ *
+ * Programmer: Nat Furrer
+ * James Laird
+ * April 30, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5Iget_type_ref(H5I_type_t type)
+{
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Iget_type_ref, FAIL);
+ H5TRACE1("Is","It",type);
+
+ /* Check arguments */
+ if (type<=0 || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID type");
+
+ if( H5I_IS_LIB_TYPE( type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
+ }
+
+ /* Do actual retrieve operation */
+ if((ret_value = H5I_get_type_ref(type))<0)
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID type ref count");
+
+done:
+ FUNC_LEAVE_API(ret_value);
+} /* end H5Iget_ref() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_get_type_ref
+ *
+ * Purpose: Retrieve the reference count for an ID type.
+ *
+ * Return: Success: The reference count.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Nat Furrer
+ * James Laird
+ * April 30, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5I_get_type_ref(H5I_type_t type)
+{
+ H5I_id_type_t *type_ptr; /*ptr to the type */
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5I_get_type_ref, FAIL);
+
+ /* Sanity check */
+ assert(type>=0);
+
+ /* Check arguments */
+ type_ptr = H5I_id_type_list_g[type];
+ if (!type_ptr )
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
+
+ /* Set return value */
+ ret_value=type_ptr->count;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5I_get_ref() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Isearch
+ *
+ * Purpose: Apply function FUNC to each member of type TYPE and return a
+ * pointer to the first object for which FUNC returns non-zero.
+ * The FUNC should take a pointer to the object and the KEY as
+ * arguments and return non-zero to terminate the search (zero
+ * to continue). Public interface to H5I_search.
+ *
+ * Limitation: Currently there is no way to start searching from where a
+ * previous search left off.
+ *
+ * Return: Success: The first object in the type for which FUNC
+ * returns non-zero. NULL if FUNC returned zero
+ * for every object in the type.
+ *
+ * Failure: NULL
+ *
+ * Programmer: James Laird
+ * Nathaniel Furrer
+ * Friday, April 23, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key)
+{
+ void * ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Isearch, NULL);
+
+ if( H5I_IS_LIB_TYPE( type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type");
+ }
+
+ ret_value = H5I_search(type, func, key);
+
+ done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+/*-------------------------------------------------------------------------
* Function: H5I_search
*
- * Purpose: Apply function FUNC to each member of group GRP and return a
+ * Purpose: Apply function FUNC to each member of type TYPE and return a
* pointer to the first object for which FUNC returns non-zero.
* The FUNC should take a pointer to the object and the KEY as
* arguments and return non-zero to terminate the search (zero
@@ -1268,9 +1895,9 @@ done:
* Limitation: Currently there is no way to start searching from where a
* previous search left off.
*
- * Return: Success: The first object in the group for which FUNC
+ * Return: Success: The first object in the type for which FUNC
* returns non-zero. NULL if FUNC returned zero
- * for every object in the group.
+ * for every object in the type.
*
* Failure: NULL
*
@@ -1282,9 +1909,9 @@ done:
*-------------------------------------------------------------------------
*/
void *
-H5I_search(H5I_type_t grp, H5I_search_func_t func, void *key)
+H5I_search(H5I_type_t type, H5I_search_func_t func, void *key)
{
- H5I_id_group_t *grp_ptr = NULL; /*ptr to the group */
+ H5I_id_type_t *type_ptr = NULL; /*ptr to the type */
H5I_id_info_t *id_ptr = NULL; /*ptr to the new ID */
H5I_id_info_t *next_id = NULL; /*ptr to the next ID */
unsigned i; /*counter */
@@ -1293,15 +1920,15 @@ H5I_search(H5I_type_t grp, H5I_search_func_t func, void *key)
FUNC_ENTER_NOAPI(H5I_search, NULL);
/* Check arguments */
- if (grp <= H5I_BADID || grp >= H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid group number");
- grp_ptr = H5I_id_group_list_g[grp];
- if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid group");
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid type number");
+ type_ptr = H5I_id_type_list_g[type];
+ if (type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type");
/* Start at the beginning of the array */
- for (i=0; i<grp_ptr->hash_size; i++) {
- id_ptr = grp_ptr->id_list[i];
+ for (i=0; i<type_ptr->hash_size; i++) {
+ id_ptr = type_ptr->id_list[i];
while (id_ptr) {
next_id= id_ptr->next; /* Protect against ID being deleted in callback */
if ((*func)(id_ptr->obj_ptr, id_ptr->id, key))
@@ -1334,24 +1961,25 @@ done:
static H5I_id_info_t *
H5I_find_id(hid_t id)
{
- H5I_id_group_t *grp_ptr; /*ptr to the group */
+ H5I_id_type_t *type_ptr; /*ptr to the type */
H5I_id_info_t *last_id; /*ptr to the last ID */
H5I_id_info_t *id_ptr; /*ptr to the new ID */
- H5I_type_t grp; /*ID's group */
+ H5I_type_t type; /*ID's type */
unsigned hash_loc; /*bucket pointer */
H5I_id_info_t *ret_value = NULL; /*return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5I_find_id);
/* Check arguments */
- grp = H5I_GRP(id);
- assert(grp > H5I_BADID && grp < H5I_NGROUPS);
- grp_ptr = H5I_id_group_list_g[grp];
- assert(grp_ptr && grp_ptr->count > 0);
+ type = H5I_TYPE(id);
+ assert(type > H5I_BADID && type < H5I_next_type);
+ type_ptr = H5I_id_type_list_g[type];
+
+ assert(type_ptr && type_ptr->count > 0);
/* Get the bucket in which the ID is located */
- hash_loc = (unsigned)H5I_LOC(id, grp_ptr->hash_size);
- id_ptr = grp_ptr->id_list[hash_loc];
+ hash_loc = (unsigned)H5I_LOC(id, type_ptr->hash_size);
+ id_ptr = type_ptr->id_list[hash_loc];
/* Scan the bucket's linked list for a match */
last_id=NULL;
@@ -1360,8 +1988,8 @@ H5I_find_id(hid_t id)
/* If we found an object, move it to the front of the list, if it isn't there already */
if(last_id!=NULL) {
last_id->next=id_ptr->next;
- id_ptr->next=grp_ptr->id_list[hash_loc];
- grp_ptr->id_list[hash_loc]=id_ptr;
+ id_ptr->next=type_ptr->id_list[hash_loc];
+ type_ptr->id_list[hash_loc]=id_ptr;
} /* end if */
break;
} /* end if */
@@ -1435,7 +2063,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5I_debug
*
- * Purpose: Dump the contents of a group to stderr for debugging.
+ * Purpose: Dump the contents of a type to stderr for debugging.
*
* Return: Success: Non-negative
*
@@ -1453,9 +2081,9 @@ done:
*/
#ifdef H5I_DEBUG_OUTPUT
static herr_t
-H5I_debug(H5I_type_t grp)
+H5I_debug(H5I_type_t type)
{
- H5I_id_group_t *grp_ptr;
+ H5I_id_type_t *type_ptr;
H5I_id_info_t *cur;
H5G_entry_t *ent = NULL;
int is, js;
@@ -1464,21 +2092,21 @@ H5I_debug(H5I_type_t grp)
FUNC_ENTER_NOAPI(H5I_debug, FAIL);
- fprintf(stderr, "Dumping group %d\n", (int)grp);
- grp_ptr = H5I_id_group_list_g[grp];
+ fprintf(stderr, "Dumping ID type %d\n", (int)type);
+ type_ptr = H5I_id_type_list_g[type];
/* Header */
- fprintf(stderr, " count = %u\n", grp_ptr->count);
- fprintf(stderr, " reserved = %u\n", grp_ptr->reserved);
- fprintf(stderr, " wrapped = %u\n", grp_ptr->wrapped);
- fprintf(stderr, " hash_size = %lu\n", (unsigned long)grp_ptr->hash_size);
- fprintf(stderr, " ids = %u\n", grp_ptr->ids);
- fprintf(stderr, " nextid = %u\n", grp_ptr->nextid);
+ fprintf(stderr, " count = %u\n", type_ptr->count);
+ fprintf(stderr, " reserved = %u\n", type_ptr->reserved);
+ fprintf(stderr, " wrapped = %u\n", type_ptr->wrapped);
+ fprintf(stderr, " hash_size = %lu\n", (unsigned long)type_ptr->hash_size);
+ fprintf(stderr, " ids = %u\n", type_ptr->ids);
+ fprintf(stderr, " nextid = %u\n", type_ptr->nextid);
/* Cache */
fprintf(stderr, " Cache:\n");
for (is=0; is<ID_CACHE_SIZE; is++) {
- if (H5I_cache_g[is] && H5I_GRP(H5I_cache_g[is]->id)==grp) {
+ if (H5I_cache_g[is] && H5I_TYPE(H5I_cache_g[is]->id)==type) {
fprintf(stderr, " Entry-%d, ID=%lu\n",
is, (unsigned long)(H5I_cache_g[is]->id));
}
@@ -1486,15 +2114,15 @@ H5I_debug(H5I_type_t grp)
/* List */
fprintf(stderr, " List:\n");
- for (iu=0; iu<grp_ptr->hash_size; iu++) {
- for (js=0, cur=grp_ptr->id_list[iu]; cur; cur=cur->next, js++) {
+ for (iu=0; iu<type_ptr->hash_size; iu++) {
+ for (js=0, cur=type_ptr->id_list[iu]; cur; cur=cur->next, js++) {
fprintf(stderr, " #%u.%d\n", iu, js);
fprintf(stderr, " id = %lu\n", (unsigned long)(cur->id));
fprintf(stderr, " count = %u\n", cur->count);
fprintf(stderr, " obj = 0x%08lx\n", (unsigned long)(cur->obj_ptr));
/* Get the symbol table entry, so we get get the name */
- switch(grp) {
+ switch(type) {
case H5I_GROUP:
ent = H5G_entof((H5G_t*)cur->obj_ptr);
break;