summaryrefslogtreecommitdiffstats
path: root/src/H5A.c
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1998-02-25 20:31:17 (GMT)
committerRobb Matzke <matzke@llnl.gov>1998-02-25 20:31:17 (GMT)
commitad73f18f5e759c4bd3d12c331659a24b54d0c39a (patch)
tree660a8bb32cc118a647757c5ae2321cf9b1ca9073 /src/H5A.c
parentc543632ba5cd609d2e6303fa9cf55685568fa851 (diff)
downloadhdf5-ad73f18f5e759c4bd3d12c331659a24b54d0c39a.zip
hdf5-ad73f18f5e759c4bd3d12c331659a24b54d0c39a.tar.gz
hdf5-ad73f18f5e759c4bd3d12c331659a24b54d0c39a.tar.bz2
[svn-r298] Changes since 19980219
---------------------- ./html/Files.html ./src/H5C.c ./src/H5Cpublic.h ./src/H5Ffamily.c ./src/H5Fprivate.h ./src/H5Fsplit.c ./test/tstab.c Added file-access property functions. The split driver takes file extensions as properties. ./src/H5A.c ./src/H5Aprivate.h Added some comments. Changed H5A_destroy() to call the free function on all the atoms that are destroyed. This fixes a bug where the file boot block isn't updated if the file isn't closed before calling exit(). Removed extra `*' and `&' from some places. ./src/H5AC.c Replaced an occurrence of NO_ADDR with NULL. ./src/H5Odtype.c ./src/H5T.c ./src/H5Tconv.c ./src/H5Tpkg.h Data types of compound members are pointers. ./H5private.h Some changes to make lseek64() work on Irix 5.3 where header files don't realize that `long long' works. ./acconfig.h ./configure.in Removed definition for PHDF5 since it looks like everyone is useing HAVE_PARALLEL now. ./configure.in ./src/H5detec.c Added checks for gethostname() and getpwuid().
Diffstat (limited to 'src/H5A.c')
-rw-r--r--src/H5A.c681
1 files changed, 354 insertions, 327 deletions
diff --git a/src/H5A.c b/src/H5A.c
index f7f7449..988c881 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -1,17 +1,17 @@
/****************************************************************************
- * NCSA HDF *
- * Software Development Group *
- * National Center for Supercomputing Applications *
- * University of Illinois at Urbana-Champaign *
- * 605 E. Springfield, Champaign IL 61820 *
- * *
- * For conditions of distribution and use, see the accompanying *
- * hdf/COPYING file. *
- * *
+ * NCSA HDF *
+ * Software Development Group *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * *
+ * For conditions of distribution and use, see the accompanying *
+ * hdf/COPYING file. *
+ * *
****************************************************************************/
#ifdef RCSID
-static char RcsId[] = "@(#)$Revision$";
+static char RcsId[] = "@(#)$Revision$";
#endif
/* $Id$ */
@@ -39,16 +39,16 @@ static char RcsId[] = "@(#)$Revision$";
H5A_release_atom_node - Releases an atom node (uses the atom free list)
EXPORTED ROUTINES
Atom Functions:
- H5A_register - Register an object in a group and get an atom for it
- H5A_object - Get the object for an atom
- H5A_group - Get the group for an atom
- H5A_remove - Remove an atom from a group
- H5A_search - Search a group for a particular object
+ H5A_register - Register an object in a group and get an atom for it
+ H5A_object - Get the object for an atom
+ H5A_group - Get the group for an atom
+ H5A_remove - Remove an atom from a group
+ H5A_search - Search a group for a particular object
Atom Group Functions:
H5A_init_group - Initialize a group to store atoms in
H5A_destroy_group - Destroy an atomic group
Atom Group Cleanup:
- H5Ashutdown - Terminate various static buffers.
+ H5Ashutdown - Terminate various static buffers.
AUTHOR
Quincey Koziol
@@ -62,35 +62,33 @@ static char RcsId[] = "@(#)$Revision$";
#include <H5private.h>
#include <H5Aprivate.h>
#include <H5Eprivate.h>
+#include <H5MMprivate.h>
-#define PABLO_MASK H5A_mask
+#define PABLO_MASK H5A_mask
/*-------------------- Locally scoped variables -----------------------------*/
#ifdef ATOMS_ARE_CACHED
/* Array of pointers to atomic groups */
-static hid_t atom_id_cache[ATOM_CACHE_SIZE] =
-{-1, -1, -1, -1};
-static void * atom_obj_cache[ATOM_CACHE_SIZE] =
-{NULL};
+static hid_t atom_id_cache[ATOM_CACHE_SIZE] = {-1, -1, -1, -1};
+static void *atom_obj_cache[ATOM_CACHE_SIZE];
#endif
/* Array of pointers to atomic groups */
-static atom_group_t *atom_group_list[MAXGROUP] =
-{NULL};
+static atom_group_t *atom_group_list[MAXGROUP];
/* Pointer to the atom node free list */
-static atom_info_t *atom_free_list = NULL;
+static atom_info_t *atom_free_list = NULL;
/* Interface initialialization? */
-static hbool_t interface_initialize_g = FALSE;
+static hbool_t interface_initialize_g = FALSE;
#define INTERFACE_INIT H5A_init_interface
-static herr_t H5A_init_interface(void);
+static herr_t H5A_init_interface(void);
/*--------------------- Local function prototypes ---------------------------*/
-static atom_info_t *H5A_find_atom(hid_t atm);
-static atom_info_t *H5A_get_atom_node(void);
-static herr_t H5A_release_atom_node(atom_info_t *atm);
+static atom_info_t *H5A_find_atom(hid_t atm);
+static atom_info_t *H5A_get_atom_node(void);
+static herr_t H5A_release_atom_node(atom_info_t *atm);
/*--------------------------------------------------------------------------
NAME
@@ -105,14 +103,14 @@ DESCRIPTION
static herr_t
H5A_init_interface(void)
{
- herr_t ret_value = SUCCEED;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER(H5A_init_interface, FAIL);
/* Registers the cleanup routine with the exit chain */
ret_value = H5_add_exit(&H5A_term_interface);
FUNC_LEAVE(ret_value);
-} /* H5E_init_interface */
+}
/******************************************************************************
NAME
@@ -130,136 +128,180 @@ H5A_init_interface(void)
RETURNS
Returns SUCCEED if successful and FAIL otherwise
-*******************************************************************************/
+******************************************************************************/
intn
-H5A_init_group(group_t grp, /* IN: Group to initialize */
- intn hash_size, /* IN: Minimum hash table size to use for group */
- uintn reserved, /* IN: Number of hash table entries to reserve */
- herr_t (*free_func) (void *) /* IN: Function to call when releasing ref counted objects */
+H5A_init_group(group_t grp, /* IN: Group to initialize */
+ intn hash_size, /* IN: Minimum hash table size to use for group */
+ uintn reserved, /* IN: Number of hash table entries to reserve */
+ herr_t (*free_func) (void *) /* IN: Function to call when releasing ref counted objects */
)
{
- atom_group_t *grp_ptr = NULL; /* ptr to the atomic group */
- intn ret_value = SUCCEED;
+ atom_group_t *grp_ptr = NULL; /* ptr to the atomic group */
+ intn ret_value = SUCCEED;
FUNC_ENTER(H5A_init_group, FAIL);
- if ((grp <= BADGROUP || grp >= MAXGROUP) && hash_size > 0)
- HGOTO_DONE(FAIL);
+ if ((grp <= BADGROUP || grp >= MAXGROUP) && hash_size > 0) {
+ HGOTO_DONE(FAIL);
+ }
#ifdef HASH_SIZE_POWER_2
- /* If anyone knows a faster test for a power of two, please change this silly code -QAK */
- if (!(hash_size == 2 || hash_size == 4 || hash_size == 8 || hash_size == 16
- || hash_size == 32 || hash_size == 64 || hash_size == 128 || hash_size == 256
- || hash_size == 512 || hash_size == 1024 || hash_size == 2048
- || hash_size == 4096 || hash_size == 8192 || hash_size == 16374
- || hash_size == 32768 || hash_size == 65536 || hash_size == 131072
- || hash_size == 262144 || hash_size == 524288 || hash_size == 1048576
- || hash_size == 2097152 || hash_size == 4194304 || hash_size == 8388608
- || hash_size == 16777216 || hash_size == 33554432 || hash_size == 67108864
- || hash_size == 134217728 || hash_size == 268435456))
- HGOTO_DONE(FAIL);
+ /*
+ * If anyone knows a faster test for a power of two, please change this
+ * silly code -QAK
+ */
+ if (!(hash_size == 2 || hash_size == 4 || hash_size == 8 ||
+ hash_size == 16 || hash_size == 32 || hash_size == 64 ||
+ hash_size == 128 || hash_size == 256 || hash_size == 512 ||
+ hash_size == 1024 || hash_size == 2048 || hash_size == 4096 ||
+ hash_size == 8192 || hash_size == 16374 || hash_size == 32768 ||
+ hash_size == 65536 || hash_size == 131072 || hash_size == 262144 ||
+ hash_size == 524288 || hash_size == 1048576 ||
+ hash_size == 2097152 || hash_size == 4194304 ||
+ hash_size == 8388608 || hash_size == 16777216 ||
+ hash_size == 33554432 || hash_size == 67108864 ||
+ hash_size == 134217728 || hash_size == 268435456))
+ HGOTO_DONE(FAIL);
#endif /* HASH_SIZE_POWER_2 */
- if (atom_group_list[grp] == NULL) { /* Allocate the group information */
- grp_ptr = (atom_group_t *) HDcalloc(1, sizeof(atom_group_t));
- if (grp_ptr == NULL)
- HGOTO_DONE(FAIL);
- atom_group_list[grp] = grp_ptr;
+ if (atom_group_list[grp] == NULL) {
+ /* Allocate the group information */
+ grp_ptr = H5MM_xcalloc(1, sizeof(atom_group_t));
+ atom_group_list[grp] = grp_ptr;
+ } else {
+ /* Get the pointer to the existing group */
+ grp_ptr = atom_group_list[grp];
+ }
+
+
+ if (grp_ptr->count == 0) {
+ /* Initialize the atom group structure */
+ grp_ptr->hash_size = hash_size;
+ grp_ptr->reserved = reserved;
+ grp_ptr->wrapped = 0;
+ grp_ptr->atoms = 0;
+ grp_ptr->nextid = reserved;
+ grp_ptr->free_func = free_func;
+ grp_ptr->atom_list = H5MM_xcalloc(hash_size, sizeof(atom_info_t *));
}
- /* end if */
- else /* Get the pointer to the existing group */
- grp_ptr = atom_group_list[grp];
-
- if (grp_ptr->count == 0) { /* Initialize the atom group structure */
- grp_ptr->hash_size = hash_size;
- grp_ptr->reserved = reserved;
- grp_ptr->wrapped = 0;
- grp_ptr->atoms = 0;
- grp_ptr->nextid = reserved;
- grp_ptr->free_func = free_func;
- if ((grp_ptr->atom_list = (atom_info_t **) HDcalloc(hash_size, sizeof(atom_info_t *))) == NULL)
- HGOTO_DONE(FAIL);
- } /* end if */
+
/* Increment the count of the times this group has been initialized */
grp_ptr->count++;
#ifdef QAK
- printf("%s: group ID=%d, count=%d, current # of active atoms=%d\n", FUNC, grp, grp_ptr->count, grp_ptr->atoms);
+ printf("%s: group ID=%d, count=%d, current # of active atoms=%d\n",
+ FUNC, grp, grp_ptr->count, grp_ptr->atoms);
#endif /* QAK */
+
done:
- if (ret_value == FAIL) { /* Error condition cleanup */
- if (grp_ptr != NULL) {
- if (grp_ptr->atom_list != NULL)
- HDfree(grp_ptr->atom_list);
- HDfree(grp_ptr);
- } /* end if */
- } /* end if */
+ if (ret_value == FAIL) {
+ /* Error condition cleanup */
+ if (grp_ptr != NULL) {
+ H5MM_xfree (grp_ptr->atom_list);
+ H5MM_xfree (grp_ptr);
+ }
+ }
+
/* Normal function cleanup */
FUNC_LEAVE(ret_value);
-} /* end H5A_init_group() */
-
-/******************************************************************************
- NAME
- H5A_destroy_group - Destroy an atomic group
-
- DESCRIPTION
- Destroys an atomic group which atoms are stored in. If the group still
- has atoms which are registered, this routine fails. If there have been
- multiple initializations of the group, this routine just decrements the
- count of initializations and does not check the atoms out-standing.
-
- RETURNS
- Returns SUCCEED if successful and FAIL otherwise
+}
-*******************************************************************************/
-intn
-H5A_destroy_group(group_t grp /* IN: Group to destroy */
-)
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_destroy_group
+ *
+ * Purpose: Decrements the reference count on an entire group of atoms.
+ * 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 atoms involves calling
+ * the free-func for each atom object and then adding the atom
+ * struct to the atom free list.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Unknown
+ *
+ * Modifications:
+ *
+ * Robb Matzke, 25 Feb 1998
+ * Atoms are freed when a group is destroyed.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5A_destroy_group(group_t grp)
{
- atom_group_t *grp_ptr = NULL; /* ptr to the atomic group */
- intn ret_value = SUCCEED;
+ atom_group_t *grp_ptr = NULL; /* ptr to the atomic group */
+ atom_info_t *cur=NULL, *next=NULL;
+ intn ret_value = SUCCEED;
+ intn i;
FUNC_ENTER(H5A_destroy_group, FAIL);
if (grp <= BADGROUP || grp >= MAXGROUP)
- HGOTO_DONE(FAIL);
+ HGOTO_DONE(FAIL);
grp_ptr = atom_group_list[grp];
if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_DONE(FAIL);
+ HGOTO_DONE(FAIL);
#ifdef QAK
- printf("%s: group ID=%d, count=%d, current # of active atoms=%d\n", FUNC, grp, grp_ptr->count, grp_ptr->atoms);
+ printf("%s: group ID=%d, count=%d, current # of active atoms=%d\n",
+ FUNC, grp, grp_ptr->count, grp_ptr->atoms);
#endif /* QAK */
- /* Decrement the number of users of the atomic group */
+ /*
+ * 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 ((--(grp_ptr->count)) == 0) {
+
#ifdef ATOMS_ARE_CACHED
- {
- uintn i;
-
- for (i = 0; i < ATOM_CACHE_SIZE; i++)
- if (ATOM_TO_GROUP(atom_id_cache[i]) == grp) {
- atom_id_cache[i] = (-1);
- atom_obj_cache[i] = NULL;
- } /* end if */
- } /* end block */
+ /*
+ * Remove atoms from the global atom cache.
+ */
+ for (i=0; i<ATOM_CACHE_SIZE; i++) {
+ if (ATOM_TO_GROUP(atom_id_cache[i]) == grp) {
+ atom_id_cache[i] = (-1);
+ atom_obj_cache[i] = NULL;
+ }
+ }
#endif /* ATOMS_ARE_CACHED */
- HDfree(grp_ptr->atom_list);
- } /* end if */
- done:
- if (ret_value == FAIL) { /* Error condition cleanup */
- } /* end if */
- /* Normal function cleanup */
+ /*
+ * Free all objects.
+ */
+ if (grp_ptr->free_func) {
+ for (i=0; i<grp_ptr->hash_size; i++) {
+ for (cur=grp_ptr->atom_list[i]; cur; cur=next) {
+ /* Free the object */
+ (grp_ptr->free_func)(cur->obj_ptr);
+
+ /* Add atom struct to free list */
+ next = cur->next;
+ cur->next = atom_free_list;
+ atom_free_list = cur;
+ }
+ }
+ }
+
+ /* Free local cache and reset group */
+ H5MM_xfree(grp_ptr->atom_list);
+ HDmemset (grp_ptr, 0, sizeof(grp_ptr));
+ }
+
+ done:
FUNC_LEAVE(ret_value);
-} /* end H5A_destroy_group() */
+}
/******************************************************************************
NAME
H5A_register - Register an object in a group and get an atom for it.
DESCRIPTION
- Registers an object in a group and returns an atom for it. This routine
+ Registers an object in a group and returns an atom for it. This routine
does _not_ check for unique-ness of the objects, if you register an object
twice, you will get two different atoms for it. This routine does make
certain that each atom in a group is unique. Atoms are created by getting
@@ -275,35 +317,35 @@ H5A_register(group_t grp, /* IN: Group to register the object in */
void *object /* IN: Object to attach to atom */
)
{
- atom_group_t *grp_ptr = NULL; /* ptr to the atomic group */
- atom_info_t *atm_ptr = NULL; /* ptr to the new atom */
- hid_t atm_id; /* new atom ID */
- uintn hash_loc; /* new item's hash table location */
- hid_t ret_value = SUCCEED;
+ atom_group_t *grp_ptr = NULL; /* ptr to the atomic group */
+ atom_info_t *atm_ptr = NULL; /* ptr to the new atom */
+ hid_t atm_id; /* new atom ID */
+ uintn hash_loc; /* new item's hash table location */
+ hid_t ret_value = SUCCEED;
FUNC_ENTER(H5A_register, FAIL);
if (grp <= BADGROUP || grp >= MAXGROUP)
- HGOTO_DONE(FAIL);
+ HGOTO_DONE(FAIL);
grp_ptr = atom_group_list[grp];
if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_DONE(FAIL);
+ HGOTO_DONE(FAIL);
if ((atm_ptr = H5A_get_atom_node()) == NULL)
- HGOTO_DONE(FAIL);
+ HGOTO_DONE(FAIL);
/* Create the atom & it's ID */
atm_id = MAKE_ATOM(grp, grp_ptr->nextid);
atm_ptr->id = atm_id;
- atm_ptr->count = 1; /* reference count all objects (even if no 'free' function defined */
+ atm_ptr->count = 1; /*initial reference count*/
atm_ptr->obj_ptr = object;
atm_ptr->next = NULL;
/* hash bucket already full, prepend to front of chain */
hash_loc = grp_ptr->nextid % (uintn) grp_ptr->hash_size;
if (grp_ptr->atom_list[hash_loc] != NULL)
- atm_ptr->next = grp_ptr->atom_list[hash_loc];
+ atm_ptr->next = grp_ptr->atom_list[hash_loc];
/* Insert into the group */
grp_ptr->atom_list[hash_loc] = atm_ptr;
@@ -316,36 +358,42 @@ H5A_register(group_t grp, /* IN: Group to register the object in */
* handed out.
*/
if (grp_ptr->nextid > (uintn) ATOM_MASK || grp_ptr->wrapped != 0) {
- if (grp_ptr->wrapped == 0) {
- grp_ptr->wrapped = 1; /* set the "wrapped around" flag if it isn't already */
- grp_ptr->nextid = grp_ptr->reserved; /* re-start the ID counter */
- } /* end if */
- do {
- hid_t next_atom = MAKE_ATOM(grp, grp_ptr->nextid); /* new atom to check for */
- atom_info_t *curr_atm; /* ptr to the current atom */
-
- curr_atm = grp_ptr->atom_list[(uintn) ATOM_TO_LOC(grp_ptr->nextid, grp_ptr->hash_size)];
- if (curr_atm == NULL) /* Ha! this is not likely... */
- break;
-
- while (curr_atm != NULL) {
- if (curr_atm->id == next_atom)
- break;
- curr_atm = curr_atm->next;
- } /* end while */
- if (curr_atm == NULL) /* must not have found a match */
- break;
- grp_ptr->nextid++;
- } while (grp_ptr->nextid <= (uintn) ATOM_MASK);
- if (grp_ptr->nextid > (uintn) ATOM_MASK) /* All the atoms are gone! */
- HGOTO_DONE(FAIL);
- } /* end if */
+ if (grp_ptr->wrapped == 0) {
+ /* set the "wrapped around" flag if it isn't already */
+ grp_ptr->wrapped = 1;
+ /* re-start the ID counter */
+ grp_ptr->nextid = grp_ptr->reserved;
+ }
+
+ do {
+ /* new atom to check for */
+ hid_t next_atom = MAKE_ATOM(grp, grp_ptr->nextid);
+ atom_info_t *curr_atm; /* ptr to the current atom */
+ hash_loc = ATOM_TO_LOC (grp_ptr->nextid, grp_ptr->hash_size);
+
+ curr_atm = grp_ptr->atom_list[hash_loc];
+ if (curr_atm == NULL) break; /* Ha! this is not likely... */
+
+ while (curr_atm != NULL) {
+ if (curr_atm->id == next_atom) break;
+ curr_atm = curr_atm->next;
+ }
+ if (curr_atm == NULL) break; /* must not have found a match */
+ grp_ptr->nextid++;
+ } while (grp_ptr->nextid <= (uintn) ATOM_MASK);
+
+ if (grp_ptr->nextid > (uintn) ATOM_MASK) {
+ /* All the atoms are gone! */
+ HGOTO_DONE(FAIL);
+ }
+ }
ret_value = atm_id;
done:
- if (ret_value == FAIL) { /* Error condition cleanup */
-
- } /* end if */
+ if (ret_value == FAIL) {
+ /* Error condition cleanup */
+ }
+
/* Normal function cleanup */
FUNC_LEAVE(ret_value);
}
@@ -353,7 +401,7 @@ H5A_register(group_t grp, /* IN: Group to register the object in */
/******************************************************************************
NAME
H5A_inc_ref - Adds a reference to a reference counted atom.
- IN: Atom to increment reference count for
+ IN: Atom to increment reference count for
DESCRIPTION
Increments the number of references outstanding for an atom. This will
fail if the group is not a reference counted group.
@@ -365,22 +413,24 @@ H5A_register(group_t grp, /* IN: Group to register the object in */
hid_t
H5A_inc_ref(hid_t atm)
{
- group_t grp = ATOM_TO_GROUP(atm); /* Group the object is in */
- atom_group_t *grp_ptr = NULL; /* ptr to the atomic group */
- atom_info_t *atm_ptr = NULL; /* ptr to the new atom */
- hid_t ret_value = FAIL;
+ group_t grp = ATOM_TO_GROUP(atm); /* object's group */
+ atom_group_t *grp_ptr = NULL; /* ptr to the atomic group*/
+ atom_info_t *atm_ptr = NULL; /* ptr to the new atom */
+ hid_t ret_value = FAIL;
FUNC_ENTER(H5A_inc_ref, FAIL);
grp_ptr = atom_group_list[grp];
if (grp_ptr == NULL || grp_ptr->count <= 0 || grp_ptr->free_func == NULL) {
- HRETURN(FAIL);
+ HRETURN(FAIL);
}
+
/* General lookup of the atom */
- if ((atm_ptr = H5A_find_atom(atm)) != NULL) {
- atm_ptr->count++;
- ret_value = atm;
+ if (NULL!=(atm_ptr = H5A_find_atom(atm))) {
+ atm_ptr->count++;
+ ret_value = atm;
}
+
FUNC_LEAVE(ret_value);
}
@@ -396,48 +446,50 @@ H5A_inc_ref(hid_t atm)
*******************************************************************************/
void *
-H5A_object(hid_t atm /* IN: Atom to retrieve object for */
-)
+H5A_object(hid_t atm)
{
#ifdef ATOMS_ARE_CACHED
- uintn i; /* local counter */
+ uintn i; /* local counter */
#endif /* ATOMS_ARE_CACHED */
- atom_info_t *atm_ptr = NULL; /* ptr to the new atom */
- void * ret_value = NULL;
+ atom_info_t *atm_ptr = NULL; /* ptr to the new atom */
+ void *ret_value = NULL;
FUNC_ENTER(H5A_object, NULL);
#ifdef ATOMS_ARE_CACHED
- /* Look for the atom in the cache first */
- for (i = 0; i < ATOM_CACHE_SIZE; i++)
- if (atom_id_cache[i] == atm) {
- ret_value = atom_obj_cache[i];
- if (i > 0) { /* Implement a simple "move forward" caching scheme */
- hid_t t_atom = atom_id_cache[i - 1];
- void * t_obj = atom_obj_cache[i - 1];
-
- atom_id_cache[i - 1] = atom_id_cache[i];
- atom_obj_cache[i - 1] = atom_obj_cache[i];
- atom_id_cache[i] = t_atom;
- atom_obj_cache[i] = t_obj;
- } /* end if */
- HGOTO_DONE(ret_value);
- } /* end if */
-#endif /* ATOMS_ARE_CACHED */
+ /*
+ * Look for the atom in the cache first. Implement a simple "move
+ * forward" caching scheme by swapping the found cache item with the
+ * previous cache item. This gradually migrates used cache items toward
+ * the front of the cache and unused items toward the end. For instance,
+ * finding `e' in the cache results in:
+ *
+ * Before: a b c d e f g h i j
+ * | | | X | | | | |
+ * After: a b c e d f g h i j
+ */
+ for (i=0; i<ATOM_CACHE_SIZE; i++)
+ if (atom_id_cache[i] == atm) {
+ ret_value = atom_obj_cache[i];
+ if (i > 0) {
+ hid_t t_atom = atom_id_cache[i-1];
+ void *t_obj = atom_obj_cache[i-1];
+ atom_id_cache[i-1] = atom_id_cache[i];
+ atom_obj_cache[i-1] = atom_obj_cache[i];
+ atom_id_cache[i] = t_atom;
+ atom_obj_cache[i] = t_obj;
+ }
+ HGOTO_DONE(ret_value);
+ }
+#endif /* ATOMS_ARE_CACHED */
/* General lookup of the atom */
- if ((atm_ptr = H5A_find_atom(atm)) == NULL)
- HGOTO_DONE(NULL);
+ if ((atm_ptr = H5A_find_atom(atm)) == NULL) HGOTO_DONE(NULL);
/* Check if we've found the correct atom */
- if (atm_ptr != NULL)
- ret_value = atm_ptr->obj_ptr;
+ if (atm_ptr != NULL) ret_value = atm_ptr->obj_ptr;
done:
- if (ret_value == NULL) { /* Error condition cleanup */
-
- } /* end if */
- /* Normal function cleanup */
FUNC_LEAVE(ret_value);
}
@@ -453,22 +505,19 @@ H5A_object(hid_t atm /* IN: Atom to retrieve object for */
*******************************************************************************/
group_t
-H5A_group(hid_t atm /* IN: Atom to retrieve group for */
-)
+H5A_group(hid_t atm)
{
- group_t ret_value = BADGROUP;
+ group_t ret_value = BADGROUP;
FUNC_ENTER(H5A_group, BADGROUP);
ret_value = ATOM_TO_GROUP(atm);
- if (ret_value <= BADGROUP || ret_value >= MAXGROUP)
- HGOTO_DONE(BADGROUP);
+ if (ret_value <= BADGROUP || ret_value >= MAXGROUP) {
+ HGOTO_DONE(BADGROUP);
+ }
+
done:
- if (ret_value == BADGROUP) { /* Error condition cleanup */
-
- } /* end if */
- /* Normal function cleanup */
FUNC_LEAVE(ret_value);
}
@@ -484,73 +533,66 @@ H5A_group(hid_t atm /* IN: Atom to retrieve group for */
*******************************************************************************/
void *
-H5A_remove(hid_t atm /* IN: Atom to remove */
-)
+H5A_remove(hid_t atm)
{
- atom_group_t *grp_ptr = NULL; /* ptr to the atomic group */
- atom_info_t *curr_atm, /* ptr to the current atom */
- *last_atm; /* ptr to the last atom */
- group_t grp; /* atom's atomic group */
- uintn hash_loc; /* atom's hash table location */
+ atom_group_t *grp_ptr = NULL;/* ptr to the atomic group */
+ atom_info_t *curr_atm, /* ptr to the current atom */
+ *last_atm; /* ptr to the last atom */
+ group_t grp; /* atom's atomic group */
+ uintn hash_loc; /* atom's hash table location */
#ifdef ATOMS_ARE_CACHED
- uintn i; /* local counting variable */
-#endif /* ATOMS_ARE_CACHED */
- void * ret_value = NULL;
+ uintn i; /* local counting variable */
+#endif
+ void * ret_value = NULL;
FUNC_ENTER(H5A_remove, NULL);
grp = ATOM_TO_GROUP(atm);
- if (grp <= BADGROUP || grp >= MAXGROUP)
- HGOTO_DONE(NULL);
+ if (grp <= BADGROUP || grp >= MAXGROUP) HGOTO_DONE(NULL);
grp_ptr = atom_group_list[grp];
- if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_DONE(NULL);
+ if (grp_ptr == NULL || grp_ptr->count <= 0) HGOTO_DONE(NULL);
/* Get the location in which the atom is located */
hash_loc = (uintn) ATOM_TO_LOC(atm, grp_ptr->hash_size);
curr_atm = grp_ptr->atom_list[hash_loc];
- if (curr_atm == NULL)
- HGOTO_DONE(NULL);
+ if (curr_atm == NULL) HGOTO_DONE(NULL);
last_atm = NULL;
while (curr_atm != NULL) {
- if (curr_atm->id == atm)
- break;
- last_atm = curr_atm;
- curr_atm = curr_atm->next;
- } /* end while */
+ if (curr_atm->id == atm) break;
+ last_atm = curr_atm;
+ curr_atm = curr_atm->next;
+ }
if (curr_atm != NULL) {
- if (last_atm == NULL) /* atom is the first the chain */
- grp_ptr->atom_list[hash_loc] = curr_atm->next;
- else
- last_atm->next = curr_atm->next;
- ret_value = curr_atm->obj_ptr;
- H5A_release_atom_node(curr_atm);
+ if (last_atm == NULL) {
+ /* atom is the first the chain */
+ grp_ptr->atom_list[hash_loc] = curr_atm->next;
+ } else {
+ last_atm->next = curr_atm->next;
+ }
+ ret_value = curr_atm->obj_ptr;
+ H5A_release_atom_node(curr_atm);
+ } else {
+ /* couldn't find the atom in the proper place */
+ HGOTO_DONE(NULL);
}
- /* end if */
- else /* couldn't find the atom in the proper place */
- HGOTO_DONE(NULL);
#ifdef ATOMS_ARE_CACHED
/* Delete object from cache */
for (i = 0; i < ATOM_CACHE_SIZE; i++)
- if (atom_id_cache[i] == atm) {
- atom_id_cache[i] = (-1);
- atom_obj_cache[i] = NULL;
- break; /* we assume there is only one instance in the cache */
- } /* end if */
-#endif /* ATOMS_ARE_CACHED */
+ if (atom_id_cache[i] == atm) {
+ atom_id_cache[i] = (-1);
+ atom_obj_cache[i] = NULL;
+ break; /* we assume there is only one instance in the cache */
+ }
+#endif /* ATOMS_ARE_CACHED */
/* Decrement the number of atoms in the group */
(grp_ptr->atoms)--;
done:
- if (ret_value == NULL) { /* Error condition cleanup */
-
- } /* end if */
- /* Normal function cleanup */
FUNC_LEAVE(ret_value);
}
@@ -564,7 +606,7 @@ H5A_remove(hid_t atm /* IN: Atom to remove */
* if the reference count for the atom reaches 0 and a free
* function has been defined at group creation time.
*
- * Return: Success: New reference count.
+ * Return: Success: New reference count.
*
* Failure: FAIL
*
@@ -572,7 +614,7 @@ H5A_remove(hid_t atm /* IN: Atom to remove */
*
* Modifications:
*
- * Robb Matzke, 19 Feb 1998
+ * Robb Matzke, 19 Feb 1998
* It is no longer an error when the reference count of an item reaches
* zero and no `free' function has been defined. The object is still
* removed from the list.
@@ -583,32 +625,32 @@ intn
H5A_dec_ref(hid_t atm)
{
group_t grp = ATOM_TO_GROUP(atm); /* Group the object is in */
- atom_group_t *grp_ptr = NULL; /* ptr to the atomic group */
- atom_info_t *atm_ptr = NULL; /* ptr to the new atom */
- const void * obj; /* object to call 'free' function with */
+ atom_group_t *grp_ptr = NULL; /* ptr to the atomic group */
+ atom_info_t *atm_ptr = NULL; /* ptr to the new atom */
+ void * obj; /* object to call 'free' function with */
intn ret_value = FAIL;
FUNC_ENTER(H5A_dec_ref, FAIL);
grp_ptr = atom_group_list[grp];
if (grp_ptr == NULL || grp_ptr->count <= 0) {
- HRETURN(FAIL);
+ HRETURN(FAIL);
}
/* General lookup of the atom */
if ((atm_ptr = H5A_find_atom(atm)) != NULL) {
- /* Decrement the reference count */
- ret_value = --(atm_ptr->count);
+ /* Decrement the reference count */
+ ret_value = --(atm_ptr->count);
- /* If the reference count is zero, remove the object from the group */
- if (0 == atm_ptr->count && (obj = H5A_remove(atm)) != NULL) {
- /*
+ /* If the reference count is zero, remove the object from the group */
+ if (0 == atm_ptr->count && (obj = H5A_remove(atm)) != NULL) {
+ /*
* call the user's 'free' function for the atom's information,
* otherwise just leak memory.
*/
- if (*grp_ptr->free_func) (*grp_ptr->free_func)((void *)obj);
- }
- ret_value = SUCCEED;
+ if (grp_ptr->free_func) (grp_ptr->free_func)(obj);
+ }
+ ret_value = SUCCEED;
}
FUNC_LEAVE(ret_value);
}
@@ -628,40 +670,36 @@ H5A_dec_ref(hid_t atm)
*******************************************************************************/
void *
-H5A_search(group_t grp, /* IN: Group to search for the object in */
+H5A_search(group_t grp, /* IN: Group to search for the object in */
H5Asearch_func_t func, /* IN: Ptr to the comparison function */
const void *key /* IN: pointer to key to compare against */
)
{
- atom_group_t *grp_ptr = NULL; /* ptr to the atomic group */
- atom_info_t *atm_ptr = NULL; /* ptr to the new atom */
- intn i; /* local counting variable */
- void * ret_value = NULL;
+ atom_group_t *grp_ptr = NULL; /* ptr to the atomic group */
+ atom_info_t *atm_ptr = NULL; /* ptr to the new atom */
+ intn i; /* local counting variable */
+ void * ret_value = NULL;
FUNC_ENTER(H5A_search, NULL);
if (grp <= BADGROUP || grp >= MAXGROUP)
- HGOTO_DONE(NULL);
+ HGOTO_DONE(NULL);
grp_ptr = atom_group_list[grp];
if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_DONE(NULL);
+ HGOTO_DONE(NULL);
/* Start at the beginning of the array */
for (i = 0; i < grp_ptr->hash_size; i++) {
- atm_ptr = grp_ptr->atom_list[i];
- while (atm_ptr != NULL) {
- if ((*func) (atm_ptr->obj_ptr, key))
- HGOTO_DONE(atm_ptr->obj_ptr); /* found the item we are looking for */
- atm_ptr = atm_ptr->next;
- } /* end while */
- } /* end for */
+ atm_ptr = grp_ptr->atom_list[i];
+ while (atm_ptr != NULL) {
+ if ((*func) (atm_ptr->obj_ptr, key))
+ HGOTO_DONE(atm_ptr->obj_ptr); /* found the item we are looking for */
+ atm_ptr = atm_ptr->next;
+ }
+ }
done:
- if (ret_value == NULL) { /* Error condition cleanup */
-
- } /* end if */
- /* Normal function cleanup */
FUNC_LEAVE(ret_value);
}
@@ -676,51 +714,45 @@ H5A_search(group_t grp, /* IN: Group to search for the object in */
Returns atom ptr if successful and NULL otherwise
*******************************************************************************/
-static atom_info_t *
-H5A_find_atom(hid_t atm /* IN: Atom to retrieve atom for */
-)
+static atom_info_t *
+H5A_find_atom(hid_t atm)
{
- atom_group_t *grp_ptr = NULL; /* ptr to the atomic group */
- atom_info_t *atm_ptr = NULL; /* ptr to the new atom */
- group_t grp; /* atom's atomic group */
- uintn hash_loc; /* atom's hash table location */
- atom_info_t *ret_value = NULL;
+ atom_group_t *grp_ptr = NULL; /* ptr to the atomic group */
+ atom_info_t *atm_ptr = NULL; /* ptr to the new atom */
+ group_t grp; /* atom's atomic group */
+ uintn hash_loc; /* atom's hash table location */
+ atom_info_t *ret_value = NULL;
FUNC_ENTER(H5A_find_atom, NULL);
grp = ATOM_TO_GROUP(atm);
if (grp <= BADGROUP || grp >= MAXGROUP)
- HGOTO_DONE(NULL);
+ HGOTO_DONE(NULL);
grp_ptr = atom_group_list[grp];
if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_DONE(NULL);
+ HGOTO_DONE(NULL);
/* Get the location in which the atom is located */
hash_loc = (uintn) ATOM_TO_LOC(atm, grp_ptr->hash_size);
atm_ptr = grp_ptr->atom_list[hash_loc];
if (atm_ptr == NULL)
- HGOTO_DONE(NULL);
+ HGOTO_DONE(NULL);
while (atm_ptr != NULL) {
- if (atm_ptr->id == atm)
- break;
- atm_ptr = atm_ptr->next;
- } /* end while */
+ if (atm_ptr->id == atm) break;
+ atm_ptr = atm_ptr->next;
+ }
ret_value = atm_ptr;
#ifdef ATOMS_ARE_CACHED
- atom_id_cache[ATOM_CACHE_SIZE - 1] = atm;
- atom_obj_cache[ATOM_CACHE_SIZE - 1] = atm_ptr->obj_ptr;
+ atom_id_cache[ATOM_CACHE_SIZE-1] = atm;
+ atom_obj_cache[ATOM_CACHE_SIZE-1] = atm_ptr->obj_ptr;
#endif /* ATOMS_ARE_CACHED */
done:
- if (ret_value == NULL) { /* Error condition cleanup */
-
- } /* end if */
- /* Normal function cleanup */
FUNC_LEAVE(ret_value);
-} /* end H5A_find_atom() */
+}
/******************************************************************************
NAME
@@ -734,30 +766,22 @@ H5A_find_atom(hid_t atm /* IN: Atom to retrieve atom for */
Returns atom ptr if successful and NULL otherwise
*******************************************************************************/
-static atom_info_t *
+static atom_info_t *
H5A_get_atom_node(void)
{
- atom_info_t *ret_value = NULL;
+ atom_info_t *ret_value = NULL;
FUNC_ENTER(H5A_get_atom_node, NULL);
if (atom_free_list != NULL) {
- ret_value = atom_free_list;
- atom_free_list = atom_free_list->next;
+ ret_value = atom_free_list;
+ atom_free_list = atom_free_list->next;
+ } else {
+ ret_value = H5MM_xmalloc(sizeof(atom_info_t));
}
- /* end if */
- else {
- if ((ret_value = (atom_info_t *) HDmalloc(sizeof(atom_info_t))) == NULL)
- HGOTO_DONE(NULL);
- } /* end else */
-
- done:
- if (ret_value == NULL) { /* Error condition cleanup */
- } /* end if */
- /* Normal function cleanup */
FUNC_LEAVE(ret_value);
-} /* end H5A_get_atom_node() */
+}
/******************************************************************************
NAME
@@ -780,7 +804,7 @@ H5A_release_atom_node(atom_info_t *atm)
atom_free_list = atm;
FUNC_LEAVE(SUCCEED);
-} /* end H5A_release_atom_node() */
+}
/*--------------------------------------------------------------------------
NAME
@@ -802,20 +826,23 @@ H5A_release_atom_node(atom_info_t *atm)
void
H5A_term_interface(void)
{
- atom_info_t *curr;
- intn i;
+ atom_info_t *curr;
+ intn i;
/* Release the free-list if it exists */
if (atom_free_list != NULL) {
- while (atom_free_list != NULL) {
- curr = atom_free_list;
- atom_free_list = atom_free_list->next;
- HDfree(curr);
- } /* end while */
- } /* end if */
- for (i = 0; i < (intn) MAXGROUP; i++)
- if (atom_group_list[i] != NULL) {
- HDfree(atom_group_list[i]);
- atom_group_list[i] = NULL;
- } /* end if */
-} /* end H5A_term_interface() */
+ while (atom_free_list != NULL) {
+ curr = atom_free_list;
+ atom_free_list = atom_free_list->next;
+ HDfree(curr);
+ }
+ }
+
+ /* Release all groups */
+ for (i = 0; i < (intn) MAXGROUP; i++) {
+ if (atom_group_list[i] != NULL) {
+ HDfree(atom_group_list[i]);
+ atom_group_list[i] = NULL;
+ }
+ }
+}