summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--acconfig.h3
-rwxr-xr-xconfigure27
-rw-r--r--configure.in13
-rw-r--r--src/H5A.c681
-rw-r--r--src/H5AC.c2
-rw-r--r--src/H5Aprivate.h28
-rw-r--r--src/H5C.c1392
-rw-r--r--src/H5Cpublic.h78
-rw-r--r--src/H5Ffamily.c5
-rw-r--r--src/H5Fprivate.h2
-rw-r--r--src/H5MM.c5
-rw-r--r--src/H5Odtype.c8
-rw-r--r--src/H5T.c58
-rw-r--r--src/H5Tconv.c22
-rw-r--r--src/H5Tpkg.h2
-rw-r--r--src/H5config.h.in9
-rw-r--r--src/H5detect.c46
-rw-r--r--src/H5private.h23
-rw-r--r--test/tstab.c25
19 files changed, 1993 insertions, 436 deletions
diff --git a/acconfig.h b/acconfig.h
index 04e7f3d..83d2f17 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -4,8 +4,5 @@
/* Define if the compiler understands the __FUNCTION__ keyword. */
#undef HAVE_FUNCTION
-/* Define if we have parallel support THIS WILL GO AWAY SHORTLY!!! */
-#undef PHDF5
-
/* Define if we have parallel support */
#undef HAVE_PARALLEL
diff --git a/configure b/configure
index 9f1a1c4..8079623 100755
--- a/configure
+++ b/configure
@@ -1149,7 +1149,7 @@ fi
-for ac_func in lseek64 fseek64
+for ac_func in lseek64 fseek64 getpwuid gethostname
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:1156: checking for $ac_func" >&5
@@ -1720,16 +1720,13 @@ case "X-$PARALLEL" in
;;
X-mpio|X-yes)
- # Use MPIO. Define PHDF5 in src/H5config.h (comes from ./acconfig.h)
- # and augment the include and library search paths (it doesn't hurt
- # to have extra paths). Then check for header files and libraries.
- # Some extra source files are added to the list also so we don't have
- # to ifdef out the whole file.
+ # Use MPIO. Define HAVE_PARALLEL in src/H5config.h (comes from
+ # ./acconfig.h) and augment the include and library search paths
+ # (it doesn't hurt to have extra paths). Then check for header
+ # files and libraries. Some extra source files are added to the
+ # list also so we don't have to ifdef out the whole file.
echo "$ac_t""mpio" 1>&6
cat >> confdefs.h <<\EOF
-#define PHDF5 1
-EOF
- cat >> confdefs.h <<\EOF
#define HAVE_PARALLEL 1
EOF
@@ -1737,7 +1734,7 @@ EOF
CPPFLAGS="$CPPFLAGS $MPI_INC"
CFLAGS="$CFLAGS $MPI_LIB"
echo $ac_n "checking for main in -lmpi""... $ac_c" 1>&6
-echo "configure:1741: checking for main in -lmpi" >&5
+echo "configure:1738: checking for main in -lmpi" >&5
ac_lib_var=`echo mpi'_'main | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1745,14 +1742,14 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lmpi $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1749 "configure"
+#line 1746 "configure"
#include "confdefs.h"
int main() {
main()
; return 0; }
EOF
-if { (eval echo configure:1756: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1753: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -1779,7 +1776,7 @@ else
echo "$ac_t""no" 1>&6
fi
echo $ac_n "checking for main in -lmpio""... $ac_c" 1>&6
-echo "configure:1783: checking for main in -lmpio" >&5
+echo "configure:1780: checking for main in -lmpio" >&5
ac_lib_var=`echo mpio'_'main | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1787,14 +1784,14 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lmpio $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1791 "configure"
+#line 1788 "configure"
#include "confdefs.h"
int main() {
main()
; return 0; }
EOF
-if { (eval echo configure:1798: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1795: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
diff --git a/configure.in b/configure.in
index faa8108..a5a72fe 100644
--- a/configure.in
+++ b/configure.in
@@ -107,7 +107,7 @@ AC_TYPE_SIZE_T
dnl ----------------------------------------------------------------------
dnl Check for functions.
dnl
-AC_CHECK_FUNCS(lseek64 fseek64)
+AC_CHECK_FUNCS(lseek64 fseek64 getpwuid gethostname)
dnl ----------------------------------------------------------------------
@@ -161,13 +161,12 @@ case "X-$PARALLEL" in
;;
X-mpio|X-yes)
- # Use MPIO. Define PHDF5 in src/H5config.h (comes from ./acconfig.h)
- # and augment the include and library search paths (it doesn't hurt
- # to have extra paths). Then check for header files and libraries.
- # Some extra source files are added to the list also so we don't have
- # to ifdef out the whole file.
+ # Use MPIO. Define HAVE_PARALLEL in src/H5config.h (comes from
+ # ./acconfig.h) and augment the include and library search paths
+ # (it doesn't hurt to have extra paths). Then check for header
+ # files and libraries. Some extra source files are added to the
+ # list also so we don't have to ifdef out the whole file.
AC_MSG_RESULT(mpio)
- AC_DEFINE(PHDF5) dnl THIS WILL GO AWAY SHORTLY!!!
AC_DEFINE(HAVE_PARALLEL)
PARALLEL_SRC='$(PARALLEL_SRC)'
CPPFLAGS="$CPPFLAGS $MPI_INC"
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;
+ }
+ }
+}
diff --git a/src/H5AC.c b/src/H5AC.c
index c96eb94..4f35a25 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -109,7 +109,7 @@ H5AC_dest(H5F_t *f)
assert(f->shared->cache);
cache = f->shared->cache;
- if (H5AC_flush(f, NULL, NO_ADDR, TRUE) < 0) {
+ if (H5AC_flush(f, NULL, NULL, TRUE) < 0) {
HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL,
"unable to flush cache");
}
diff --git a/src/H5Aprivate.h b/src/H5Aprivate.h
index 8d4e6d2..e4e654f 100644
--- a/src/H5Aprivate.h
+++ b/src/H5Aprivate.h
@@ -70,29 +70,29 @@
#define H5A_GROUPID_HASHSIZE 64
/* Atom information structure used */
-typedef struct atom_info_struct_tag {
- hid_t id; /*atom ID for this info */
- uintn count; /*ref. count for this atom */
- void * *obj_ptr; /*pointer associated with the atom */
- struct atom_info_struct_tag *next;/*link to next atom (in case of hash-clash)*/
+typedef struct atom_info_t {
+ hid_t id; /*atom ID for this info */
+ uintn count; /*ref. count for this atom */
+ void *obj_ptr; /*pointer associated with the atom */
+ struct atom_info_t *next; /*link to next atom (in case of hash-clash)*/
} atom_info_t;
/* Atom group structure used */
typedef struct atom_group_struct_tag {
- uintn count; /*# of times this group has been initialized*/
- uintn reserved; /*# of atoms to reserve for constant atoms*/
- uintn wrapped; /*whether the id count has wrapped around*/
- intn hash_size; /*size of the hash table to store the atoms in*/
- uintn atoms; /*current number of atoms held */
- uintn nextid; /*atom ID to use for the next atom */
- herr_t (*free_func) (void *);/*pointer to function to call when releasing ref counted object*/
- atom_info_t **atom_list; /*pointer to an array of ptrs to atoms*/
+ uintn count; /*# of times this group has been initialized */
+ uintn reserved; /*# of atoms to reserve for constant atoms */
+ uintn wrapped; /*whether the id count has wrapped around */
+ intn hash_size; /*sizeof the hash table to store the atoms in*/
+ uintn atoms; /*current number of atoms held */
+ uintn nextid; /*atom ID to use for the next atom */
+ herr_t (*free_func)(void*);/*func to call to release object */
+ atom_info_t **atom_list; /*pointer to an array of ptrs to atoms */
} atom_group_t;
/* Private Functions in H5A.c */
intn H5A_init_group (group_t grp, intn hash_size, uintn reserved,
herr_t (*free_func)(void *));
-intn H5A_destroy_group (group_t grp);
+herr_t H5A_destroy_group (group_t grp);
hid_t H5A_register (group_t grp, void *object);
void *H5A_object (hid_t atm);
group_t H5A_group (hid_t atm);
diff --git a/src/H5C.c b/src/H5C.c
new file mode 100644
index 0000000..e62bc0a
--- /dev/null
+++ b/src/H5C.c
@@ -0,0 +1,1392 @@
+/****************************************************************************
+* 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$";
+#endif
+
+/* $Id$ */
+
+#include <stdarg.h>
+
+/* Private header files */
+#include <H5private.h> /* Generic Functions */
+#include <H5Aprivate.h> /* Atoms */
+#include <H5Bprivate.h> /* B-tree subclass names */
+#include <H5Cprivate.h> /* Template information */
+#include <H5Dprivate.h> /* Datasets */
+#include <H5Eprivate.h> /* Error handling */
+#include <H5MMprivate.h> /* Memory management */
+
+#define PABLO_MASK H5C_mask
+
+/* Is the interface initialized? */
+static hbool_t interface_initialize_g = FALSE;
+#define INTERFACE_INIT H5C_init_interface
+static herr_t H5C_init_interface(void);
+
+/* PRIVATE PROTOTYPES */
+static void H5C_term_interface(void);
+
+/*--------------------------------------------------------------------------
+NAME
+ H5C_init_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5C_init_interface()
+
+RETURNS
+ SUCCEED/FAIL
+DESCRIPTION
+ Initializes any interface-specific data or routines.
+
+--------------------------------------------------------------------------*/
+static herr_t
+H5C_init_interface(void)
+{
+ herr_t ret_value = SUCCEED;
+ intn i;
+ herr_t status;
+
+ FUNC_ENTER(H5C_init_interface, FAIL);
+
+ /*
+ * Make sure the file creation and file access default templates are
+ * initialized since this might be done at run-time instead of compile
+ * time.
+ */
+ if (H5F_init_interface ()<0) {
+ HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL,
+ "unable to initialize H5F and H5C interfaces");
+ }
+
+ assert(H5C_NCLASSES <= H5_TEMPLATE_MAX - H5_TEMPLATE_0);
+
+ /*
+ * Initialize the mappings between template classes and atom groups. We
+ * keep the two separate because template classes are publicly visible but
+ * atom groups aren't.
+ */
+ for (i = 0; i < H5C_NCLASSES; i++) {
+ status = H5A_init_group((group_t)(H5_TEMPLATE_0 +i),
+ H5A_TEMPID_HASHSIZE, 0, NULL);
+ if (status < 0) ret_value = FAIL;
+ }
+ if (ret_value < 0) {
+ HRETURN_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL,
+ "unable to initialize atom group");
+ }
+
+ /*
+ * Register cleanup function.
+ */
+ if (H5_add_exit(H5C_term_interface) < 0) {
+ HRETURN_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL,
+ "unable to install atexit function");
+ }
+
+ FUNC_LEAVE(ret_value);
+}
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5C_term_interface
+ PURPOSE
+ Terminate various H5C objects
+ USAGE
+ void H5C_term_interface()
+ RETURNS
+ SUCCEED/FAIL
+ DESCRIPTION
+ Release the atom group and any other resources allocated.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Can't report errors...
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static void
+H5C_term_interface(void)
+{
+ intn i;
+
+ for (i = 0; i < H5C_NCLASSES; i++) {
+ H5A_destroy_group((group_t)(H5_TEMPLATE_0 + i));
+ }
+}
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Ccreate
+ PURPOSE
+ Returns a copy of the default template for some class of templates.
+ USAGE
+ herr_t H5Ccreate (type)
+ H5C_class_t type; IN: Template class whose default is desired.
+ RETURNS
+ Template ID or FAIL
+
+ ERRORS
+ ARGS BADVALUE Unknown template class.
+ ATOM CANTINIT Can't register template.
+ INTERNAL UNSUPPORTED Not implemented yet.
+
+ DESCRIPTION
+ Returns a copy of the default template for some class of templates.
+--------------------------------------------------------------------------*/
+hid_t
+H5Ccreate(H5C_class_t type)
+{
+ hid_t ret_value = FAIL;
+ void *tmpl = NULL;
+
+ FUNC_ENTER(H5Ccreate, FAIL);
+
+ /* Allocate a new template and initialize it with default values */
+ switch (type) {
+ case H5C_FILE_CREATE:
+ tmpl = H5MM_xmalloc(sizeof(H5F_create_t));
+ memcpy(tmpl, &H5F_create_dflt, sizeof(H5F_create_t));
+ break;
+
+ case H5C_FILE_ACCESS:
+ tmpl = H5MM_xmalloc(sizeof(H5F_access_t));
+ memcpy(tmpl, &H5F_access_dflt, sizeof(H5F_access_t));
+ break;
+
+ case H5C_DATASET_CREATE:
+ tmpl = H5MM_xmalloc(sizeof(H5D_create_t));
+ memcpy(tmpl, &H5D_create_dflt, sizeof(H5D_create_t));
+ break;
+
+ case H5C_DATASET_XFER:
+ tmpl = H5MM_xmalloc(sizeof(H5D_xfer_t));
+ memcpy(tmpl, &H5D_xfer_dflt, sizeof(H5D_xfer_t));
+ break;
+
+ default:
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "unknown template class");
+ }
+
+ /* Atomize the new template */
+ if ((ret_value = H5C_create(type, tmpl)) < 0) {
+ HRETURN_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL,
+ "can't register template");
+ }
+ FUNC_LEAVE(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5C_create
+ *
+ * Purpose: Given a pointer to some template struct, atomize the template
+ * and return its ID. The template memory is not copied, so the
+ * caller should not free it; it will be freed by H5C_release().
+ *
+ * Return: Success: A new template ID.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, December 3, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5C_create(H5C_class_t type, void *tmpl)
+{
+ hid_t ret_value = FAIL;
+
+ FUNC_ENTER(H5C_create, FAIL);
+
+ /* check args */
+ assert(type >= 0 && type < H5C_NCLASSES);
+ assert(tmpl);
+
+ /* Atomize the new template */
+ if ((ret_value=H5A_register((group_t)(H5_TEMPLATE_0+type), tmpl)) < 0) {
+ HRETURN_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL,
+ "can't register template");
+ }
+
+ FUNC_LEAVE(ret_value);
+}
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Cclose
+ PURPOSE
+ Release access to a template object.
+ USAGE
+ herr_t H5Cclose(oid)
+ hid_t oid; IN: Template object to release access to
+ RETURNS
+ SUCCEED/FAIL
+ DESCRIPTION
+ This function releases access to a template object
+--------------------------------------------------------------------------*/
+herr_t
+H5Cclose(hid_t tid)
+{
+ H5C_class_t type;
+ void *tmpl = NULL;
+
+ FUNC_ENTER(H5Cclose, FAIL);
+
+ /* Check arguments */
+ if ((type=H5Cget_class (tid))<0 ||
+ NULL==(tmpl=H5A_object (tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
+ }
+
+ /*
+ * Chuck the object! When the reference count reaches zero then
+ * H5A_dec_ref() removes it from the group and we should free it. The
+ * free function is not registered as part of the group because it takes
+ * an extra argument.
+ */
+ if (0==H5A_dec_ref(tid)) H5C_close (type, tmpl);
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5C_close
+ *
+ * Purpose: Closes a template and frees the memory associated with the
+ * template.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, February 18, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C_close (H5C_class_t type, void *tmpl)
+{
+ FUNC_ENTER (H5C_close, FAIL);
+
+ /* Check args */
+ assert (tmpl);
+
+ /* Some templates may need to do special things */
+ switch (type) {
+ case H5C_FILE_ACCESS:
+#ifdef LATER
+ /* Need to free the COMM and INFO objects too. */
+#endif
+ break;
+
+ case H5C_FILE_CREATE:
+ case H5C_DATASET_CREATE:
+ case H5C_DATASET_XFER:
+ /*nothing to do*/
+ break;
+
+ default:
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL,
+ "unknown property list class");
+ }
+
+ /* Free the template struct and return */
+ H5MM_xfree(tmpl);
+ FUNC_LEAVE(SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cget_class
+ *
+ * Purpose: Returns the class identifier for a template.
+ *
+ * Return: Success: A template class
+ *
+ * Failure: H5C_NO_CLASS (-1)
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, December 3, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5C_class_t
+H5Cget_class(hid_t tid)
+{
+ group_t group;
+ H5C_class_t ret_value = H5C_NO_CLASS;
+
+ FUNC_ENTER(H5Cget_class, H5C_NO_CLASS);
+
+ if ((group = H5A_group(tid)) < 0 ||
+#ifndef NDEBUG
+ group >= H5_TEMPLATE_MAX ||
+#endif
+ group < H5_TEMPLATE_0) {
+ HRETURN_ERROR(H5E_ATOM, H5E_BADATOM, H5C_NO_CLASS, "not a template");
+ }
+ ret_value = (H5C_class_t)(group - H5_TEMPLATE_0);
+ FUNC_LEAVE(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cget_version
+ *
+ * Purpose: Retrieves version information for various parts of a file.
+ *
+ * BOOT: The file boot block.
+ * HEAP: The global heap.
+ * FREELIST: The global free list.
+ * STAB: The root symbol table entry.
+ * SHHDR: Shared object headers.
+ *
+ * Any (or even all) of the output arguments can be null
+ * pointers.
+ *
+ * Return: Success: SUCCEED, version information is returned
+ * through the arguments.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, January 7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cget_version(hid_t tid, int *boot /*out */ , int *heap /*out */ ,
+ int *freelist /*out */ , int *stab /*out */ , int *shhdr /*out */ )
+{
+ H5F_create_t *tmpl = NULL;
+
+ FUNC_ENTER(H5Cget_version, FAIL);
+
+ /* Check arguments */
+ if (H5C_FILE_CREATE != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file creation template");
+ }
+ /* Get values */
+ if (boot)
+ *boot = tmpl->bootblock_ver;
+ if (heap)
+ *heap = tmpl->smallobject_ver;
+ if (freelist)
+ *freelist = tmpl->freespace_ver;
+ if (stab)
+ *stab = tmpl->objectdir_ver;
+ if (shhdr)
+ *shhdr = tmpl->sharedheader_ver;
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cset_userblock
+ *
+ * Purpose: Sets the userblock size field of a file creation template.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, January 6, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cset_userblock(hid_t tid, size_t size)
+{
+ intn i;
+ H5F_create_t *tmpl = NULL;
+
+ FUNC_ENTER(H5Cset_userblock, FAIL);
+
+ /* Check arguments */
+ if (H5C_FILE_CREATE != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file creation template");
+ }
+ for (i = 8; i < 8 * sizeof(int); i++) {
+ uintn p2 = 8 == i ? 0 : 1 << i;
+ if (size == p2)
+ break;
+ }
+ if (i >= 8 * sizeof(int)) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "userblock size is not valid");
+ }
+ /* Set value */
+ tmpl->userblock_size = size;
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cget_userblock
+ *
+ * Purpose: Queries the size of a user block in a file creation template.
+ *
+ * Return: Success: SUCCEED, size returned through SIZE argument.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, January 7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cget_userblock(hid_t tid, size_t *size)
+{
+ H5F_create_t *tmpl = NULL;
+
+ FUNC_ENTER(H5Cget_userblock, FAIL);
+
+ /* Check args */
+ if (H5C_FILE_CREATE != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file creation template");
+ }
+ /* Get value */
+ if (size)
+ *size = tmpl->userblock_size;
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cset_sizes
+ *
+ * Purpose: Sets file size-of addresses and sizes. TEMPLATE
+ * should be a file creation template. A value of zero causes
+ * the property to not change.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, January 6, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cset_sizes(hid_t tid, size_t sizeof_addr, size_t sizeof_size)
+{
+ H5F_create_t *tmpl = NULL;
+
+ FUNC_ENTER(H5Cset_sizeof_addr, FAIL);
+
+ /* Check arguments */
+ if (H5C_FILE_CREATE != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file creation template");
+ }
+ if (sizeof_addr) {
+ if (sizeof_addr != 2 && sizeof_addr != 4 &&
+ sizeof_addr != 8 && sizeof_addr != 16) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "file haddr_t size is not valid");
+ }
+ }
+ if (sizeof_size) {
+ if (sizeof_size != 2 && sizeof_size != 4 &&
+ sizeof_size != 8 && sizeof_size != 16) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "file size_t size is not valid");
+ }
+ }
+ /* Set value */
+ if (sizeof_addr)
+ tmpl->sizeof_addr = sizeof_addr;
+ if (sizeof_size)
+ tmpl->sizeof_size = sizeof_size;
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cget_sizes
+ *
+ * Purpose: Returns the size of address and size quantities stored in a
+ * file according to a file creation template. Either (or even
+ * both) SIZEOF_ADDR and SIZEOF_SIZE may be null pointers.
+ *
+ * Return: Success: SUCCEED, sizes returned through arguments.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, January 7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cget_sizes(hid_t tid,
+ size_t *sizeof_addr /*out */ , size_t *sizeof_size /*out */ )
+{
+ H5F_create_t *tmpl = NULL;
+
+ FUNC_ENTER(H5Cget_sizes, FAIL);
+
+ /* Check args */
+ if (H5C_FILE_CREATE != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file creation template");
+ }
+ /* Get values */
+ if (sizeof_addr)
+ *sizeof_addr = tmpl->sizeof_addr;
+ if (sizeof_size)
+ *sizeof_size = tmpl->sizeof_size;
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cset_sym_k
+ *
+ * Purpose: IK is one half the rank of a tree that stores a symbol
+ * table for a group. Internal nodes of the symbol table are on
+ * average 75% full. That is, the average rank of the tree is
+ * 1.5 times the value of IK.
+ *
+ * LK is one half of the number of symbols that can be stored in
+ * a symbol table node. A symbol table node is the leaf of a
+ * symbol table tree which is used to store a group. When
+ * symbols are inserted randomly into a group, the group's
+ * symbol table nodes are 75% full on average. That is, they
+ * contain 1.5 times the number of symbols specified by LK.
+ *
+ * Either (or even both) of IK and LK can be zero in which case
+ * that value is left unchanged.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, January 6, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cset_sym_k(hid_t tid, int ik, int lk)
+{
+ H5F_create_t *tmpl = NULL;
+
+ FUNC_ENTER(H5Cset_sym_k, FAIL);
+
+ /* Check arguments */
+ if (H5C_FILE_CREATE != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file creation template");
+ }
+ /* Set values */
+ if (ik > 0) {
+ tmpl->btree_k[H5B_SNODE_ID] = ik;
+ }
+ if (lk > 0) {
+ tmpl->sym_leaf_k = lk;
+ }
+ FUNC_LEAVE(SUCCEED);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cget_sym_k
+ *
+ * Purpose: Retrieves the symbol table B-tree 1/2 rank (IK) and the
+ * symbol table leaf node 1/2 size (LK). See H5Cset_sym_k() for
+ * details. Either (or even both) IK and LK may be null
+ * pointers.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, January 7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cget_sym_k(hid_t tid, int *ik /*out */ , int *lk /*out */ )
+{
+ H5F_create_t *tmpl = NULL;
+
+ FUNC_ENTER(H5Cget_sym_k, FAIL);
+
+ /* Check arguments */
+ if (H5C_FILE_CREATE != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file creation template");
+ }
+ /* Get values */
+ if (ik)
+ *ik = tmpl->btree_k[H5B_SNODE_ID];
+ if (lk)
+ *lk = tmpl->sym_leaf_k;
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cset_istore_k
+ *
+ * Purpose: IK is one half the rank of a tree that stores chunked raw
+ * data. On average, such a tree will be 75% full, or have an
+ * average rank of 1.5 times the value of IK.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, January 6, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cset_istore_k(hid_t tid, int ik)
+{
+ H5F_create_t *tmpl = NULL;
+
+ FUNC_ENTER(H5Cset_istore_k, FAIL);
+
+ /* Check arguments */
+ if (H5C_FILE_CREATE != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file creation template");
+ }
+ if (ik <= 0) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "istore IK value must be positive");
+ }
+ /* Set value */
+ tmpl->btree_k[H5B_ISTORE_ID] = ik;
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cget_istore_k
+ *
+ * Purpose: Queries the 1/2 rank of an indexed storage B-tree. See
+ * H5Cset_istore_k() for details. The argument IK may be the
+ * null pointer.
+ *
+ * Return: Success: SUCCEED, size returned through IK
+ *
+ * Failure:
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, January 7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cget_istore_k(hid_t tid, int *ik /*out */ )
+{
+ H5F_create_t *tmpl = NULL;
+
+ FUNC_ENTER(H5Cget_istore_k, FAIL);
+
+ /* Check arguments */
+ if (H5C_FILE_CREATE != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file creation template");
+ }
+ /* Get value */
+ if (ik)
+ *ik = tmpl->btree_k[H5B_ISTORE_ID];
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cset_layout
+ *
+ * Purpose: Sets the layout of raw data in the file.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, January 6, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cset_layout(hid_t tid, H5D_layout_t layout)
+{
+ H5D_create_t *tmpl = NULL;
+
+ FUNC_ENTER(H5Cset_layout, FAIL);
+
+ /* Check arguments */
+ if (H5C_DATASET_CREATE != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a dataset creation template");
+ }
+ if (layout < 0 || layout >= H5D_NLAYOUTS) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL,
+ "raw data layout method is not valid");
+ }
+ /* Set value */
+ tmpl->layout = layout;
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cget_layout
+ *
+ * Purpose: Retrieves layout type of a dataset creation template.
+ *
+ * Return: Success: The layout type
+ *
+ * Failure: H5D_LAYOUT_ERROR (-1, same as FAIL)
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, January 7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5D_layout_t
+H5Cget_layout(hid_t tid)
+{
+ H5D_create_t *tmpl = NULL;
+
+ FUNC_ENTER(H5Cget_layout, H5D_LAYOUT_ERROR);
+
+ /* Check arguments */
+ if (H5C_DATASET_CREATE != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, H5D_LAYOUT_ERROR,
+ "not a dataset creation template");
+ }
+ FUNC_LEAVE(tmpl->layout);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cset_chunk
+ *
+ * Purpose: Sets the number of dimensions and the size of each chunk to
+ * the values specified. The dimensionality of the chunk should
+ * match the dimensionality of the data space.
+ *
+ * As a side effect, the layout method is changed to
+ * H5D_CHUNKED.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, January 6, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cset_chunk(hid_t tid, int ndims, const size_t dim[])
+{
+ int i;
+ H5D_create_t *tmpl = NULL;
+
+ FUNC_ENTER(H5Cset_chunk, FAIL);
+
+ /* Check arguments */
+ if (H5C_DATASET_CREATE != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a dataset creation template");
+ }
+ if (ndims <= 0) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL,
+ "chunk dimensionality must be positive");
+ }
+ if (ndims > NELMTS(tmpl->chunk_size)) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL,
+ "chunk dimensionality is too large");
+ }
+ if (!dim) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "no chunk dimensions specified");
+ }
+ for (i = 0; i < ndims; i++) {
+ if (dim[i] <= 0) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL,
+ "all chunk dimensions must be positive");
+ }
+ }
+
+ /* Set value */
+ tmpl->layout = H5D_CHUNKED;
+ tmpl->chunk_ndims = ndims;
+ for (i = 0; i < ndims; i++)
+ tmpl->chunk_size[i] = dim[i];
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cget_chunk
+ *
+ * Purpose: Retrieves the chunk size of chunked layout. The chunk
+ * dimensionality is returned and the chunk size in each
+ * dimension is returned through the DIM argument. At most
+ * MAX_NDIMS elements of DIM will be initialized.
+ *
+ * Return: Success: Positive Chunk dimensionality.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, January 7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5Cget_chunk(hid_t tid, int max_ndims, size_t dim[] /*out */ )
+{
+ int i;
+ H5D_create_t *tmpl = NULL;
+
+ FUNC_ENTER(H5Cget_chunk, FAIL);
+
+ /* Check arguments */
+ if (H5C_DATASET_CREATE != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a dataset creation template");
+ }
+ if (H5D_CHUNKED != tmpl->layout) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "not a chunked storage layout");
+ }
+ for (i = 0; i < tmpl->chunk_ndims && i < max_ndims && dim; i++) {
+ dim[i] = tmpl->chunk_size[i];
+ }
+
+ FUNC_LEAVE(tmpl->chunk_ndims);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cset_stdio
+ *
+ * Purpose: Set the low level file driver to use the functions declared
+ * in the stdio.h file: fopen(), fseek() or fseek64(), fread(),
+ * fwrite(), and fclose().
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, February 19, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cset_stdio (hid_t tid)
+{
+ H5F_access_t *tmpl = NULL;
+
+ FUNC_ENTER (H5Cset_stdio, FAIL);
+
+ /* Check arguments */
+ if (H5C_FILE_ACCESS != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file access template");
+ }
+
+ /* Set driver */
+ tmpl->driver = H5F_LOW_STDIO;
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cset_sec2
+ *
+ * Purpose: Set the low-level file driver to use the functions declared
+ * in the unistd.h file: open(), lseek() or lseek64(), read(),
+ * write(), and close().
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, February 19, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cset_sec2 (hid_t tid)
+{
+ H5F_access_t *tmpl = NULL;
+
+ FUNC_ENTER (H5Cset_sec2, FAIL);
+
+ /* Check arguments */
+ if (H5C_FILE_ACCESS != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file access template");
+ }
+
+ /* Set driver */
+ tmpl->driver = H5F_LOW_SEC2;
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cset_core
+ *
+ * Purpose: Set the low-level file driver to use malloc() and free().
+ * This driver is restricted to temporary files which are not
+ * larger than the amount of virtual memory available. The
+ * INCREMENT argument determines the file block size and memory
+ * will be allocated in multiples of INCREMENT bytes. A liberal
+ * INCREMENT results in fewer calls to realloc() and probably
+ * less memory fragmentation.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, February 19, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cset_core (hid_t tid, size_t increment)
+{
+ H5F_access_t *tmpl = NULL;
+
+ FUNC_ENTER (H5Cset_core, FAIL);
+
+ /* Check arguments */
+ if (H5C_FILE_ACCESS != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file access template");
+ }
+ if (increment<1) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "increment must be positive");
+ }
+
+ /* Set driver */
+ tmpl->driver = H5F_LOW_CORE;
+ tmpl->u.core.increment = increment;
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cset_split
+ *
+ * Purpose: Set the low-level driver to split meta data from raw data,
+ * storing meta data in one file and raw data in another file.
+ * The META_EXT and RAW_EXT are the extension (including the
+ * `.') which will be appended to the base name to form the name
+ * for the meta data file and the raw data file. The defaults
+ * are `.meta' for the meta file and `.raw' for the raw file.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, February 19, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cset_split (hid_t tid, const char *meta_ext, hid_t meta_tid,
+ const char *raw_ext, hid_t raw_tid)
+{
+ H5F_access_t *tmpl = NULL;
+ H5F_access_t *meta_tmpl = NULL;
+ H5F_access_t *raw_tmpl = NULL;
+
+ FUNC_ENTER (H5Cset_split, FAIL);
+
+ /* Check arguments */
+ if (H5C_FILE_ACCESS != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file access template");
+ }
+ if (H5C_DEFAULT!=meta_tid &&
+ (H5C_FILE_ACCESS != H5Cget_class(meta_tid) ||
+ NULL == (meta_tmpl = H5A_object(meta_tid)))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file access template");
+ }
+ if (H5C_DEFAULT!=raw_tid &&
+ (H5C_FILE_ACCESS != H5Cget_class(raw_tid) ||
+ NULL == (raw_tmpl = H5A_object(raw_tid)))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file access template");
+ }
+
+ /* Set driver */
+ tmpl->driver = H5F_LOW_SPLIT;
+ tmpl->u.split.meta_ext = H5MM_xstrdup (meta_ext);
+ tmpl->u.split.meta_access = H5C_copy (H5C_FILE_ACCESS, meta_tmpl);
+ tmpl->u.split.raw_ext = H5MM_xstrdup (raw_ext);
+ tmpl->u.split.raw_access = H5C_copy (H5C_FILE_ACCESS, raw_tmpl);
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Cset_family
+ *
+ * Purpose: Sets the low-level driver to stripe the hdf5 address space
+ * across a family of files.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, February 19, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cset_family (hid_t tid, hid_t memb_tid)
+{
+
+ H5F_access_t *tmpl = NULL;
+ H5F_access_t *memb_tmpl = NULL;
+
+ FUNC_ENTER (H5Cset_family, FAIL);
+
+ /* Check arguments */
+ if (H5C_FILE_ACCESS != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file access template");
+ }
+ if (H5C_DEFAULT!=memb_tid &&
+ (H5C_FILE_ACCESS != H5Cget_class(memb_tid) ||
+ NULL == (memb_tmpl = H5A_object(memb_tid)))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file access template");
+ }
+
+ /* Set driver */
+ tmpl->driver = H5F_LOW_FAMILY;
+ tmpl->u.fam.memb_access = H5C_copy (H5C_FILE_ACCESS, memb_tmpl);
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+
+#ifdef HAVE_PARALLEL
+/*-------------------------------------------------------------------------
+ * Function: H5Cset_mpi
+ *
+ * Signature: herr_t H5Cset_mpi(hid_t tid, MPI_Comm comm, MPI_Info info,
+ * uintn access_mode)
+ *
+ * Purpose: Store the access mode for MPIO call and the user supplied
+ * communicator and info in the access template which can then
+ * be used to open file. This function is available only in the
+ * parallel HDF5 library and is not a collective function.
+ *
+ * Parameters:
+ * hid_t tid
+ * ID of template to modify
+ * MPI_Comm comm
+ * MPI communicator to be used for file open as defined in
+ * MPI_FILE_OPEN of MPI-2. This function does not make a
+ * duplicated communicator. Any modification to comm after
+ * this function call returns may have undetermined effect
+ * to the access template. Users should call this function
+ * again to setup the template.
+ * MPI_Info info
+ * MPI info object to be used for file open as defined in
+ * MPI_FILE_OPEN of MPI-2. This function does not make a
+ * duplicated info. Any modification to info after
+ * this function call returns may have undetermined effect
+ * to the access template. Users should call this function
+ * again to setup the template.
+ * uintn access_mode
+ * File data access modes:
+ * H5ACC_INDEPENDENT
+ * Allow independent datasets access.
+ * H5ACC_COLLECTIVE
+ * Allow only collective datasets access.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Albert Cheng
+ * Feb 3, 1998
+ *
+ * Modifications:
+ *
+ * Robb Matzke, 18 Feb 1998
+ * Check all arguments before the template is updated so we don't leave
+ * the template in a bad state if something goes wrong. Also, the
+ * template data type changed to allow more generality so all the
+ * mpi-related stuff is in the `u.mpi' member. The `access_mode' will
+ * contain only mpi-related flags defined in H5Fpublic.h.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Cset_mpi (hid_t tid, MPI_Comm comm, MPI_Info info, uintn access_mode)
+{
+ H5F_access_t *tmpl = NULL;
+ MPI_Comm lcomm;
+ int mrc; /* MPI return code */
+
+ FUNC_ENTER(H5Cset_mpi, FAIL);
+
+ /* Check arguments */
+ if (H5C_FILE_ACCESS != H5Cget_class(tid) ||
+ NULL == (tmpl = H5A_object(tid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a file access template");
+ }
+
+ switch (access_mode){
+ case H5ACC_INDEPENDENT:
+ case H5ACC_COLLECTIVE:
+ /* okay */
+ break;
+
+ default:
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "invalid mpio access mode");
+ }
+
+#ifdef LATER
+ /*
+ * Need to verify comm and info contain sensible information.
+ */
+#endif
+
+
+ /*
+ * Everything looks good. Now go ahead and modify the access template.
+ */
+ tmpl->driver = H5F_LOW_MPIO;
+ tmpl->u.mpio.access_mode = access_mode;
+
+ /*
+ * Store a duplicate copy of comm so that user may freely modify comm
+ * after this call.
+ */
+ if ((mrc = MPI_Comm_dup(comm, &lcomm)) != MPI_SUCCESS) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "failure to duplicate communicator");
+ }
+ tmpl->u.mpio.comm = comm;
+
+#ifdef LATER
+ /* Need to duplicate info too but don't know a quick way to do it now */
+#endif
+ tmpl->u.mpio.info = info;
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+#endif /*HAVE_PARALLEL*/
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Ccopy
+ PURPOSE
+ Copy a template
+ USAGE
+ hid_t H5C_copy(tid)
+ hid_t tid; IN: Template object to copy
+ RETURNS
+ Returns template ID (atom) on success, FAIL on failure
+
+ ERRORS
+ ARGS BADRANGE Unknown template class.
+ ATOM BADATOM Can't unatomize template.
+ ATOM CANTREGISTER Register the atom for the new template.
+ INTERNAL UNSUPPORTED Dataset transfer properties are not implemented
+ yet.
+ INTERNAL UNSUPPORTED File access properties are not implemented yet.
+
+ DESCRIPTION
+ This function creates a new copy of a template with all the same parameter
+ settings.
+--------------------------------------------------------------------------*/
+hid_t
+H5Ccopy(hid_t tid)
+{
+ const void *tmpl = NULL;
+ void *new_tmpl = NULL;
+ H5C_class_t type;
+ hid_t ret_value = FAIL;
+ group_t group;
+
+ FUNC_ENTER(H5Ccopy, FAIL);
+
+ /* Check args */
+ if (NULL == (tmpl = H5A_object(tid)) ||
+ (type = H5Cget_class(tid)) < 0 ||
+ (group = H5A_group(tid)) < 0) {
+ HRETURN_ERROR(H5E_ATOM, H5E_BADATOM, FAIL,
+ "can't unatomize template");
+ }
+
+ /* Copy it */
+ if (NULL==(new_tmpl=H5C_copy (type, tmpl))) {
+ HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL,
+ "unable to copy template");
+ }
+
+ /* Register the atom for the new template */
+ if ((ret_value = H5A_register(group, new_tmpl)) < 0) {
+ HRETURN_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL,
+ "unable to atomize template pointer");
+ }
+ FUNC_LEAVE(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5C_copy
+ *
+ * Purpose: Creates a new template and initializes it with some other
+ * template. Copying a null pointer results in a null pointer.
+ *
+ * Return: Success: Ptr to new template
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, February 3, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5C_copy (H5C_class_t type, const void *src)
+{
+ size_t size;
+ void *dst = NULL;
+
+ FUNC_ENTER (H5C_copy, NULL);
+
+ /* How big is the template */
+ switch (type) {
+ case H5C_FILE_CREATE:
+ size = sizeof(H5F_create_t);
+ break;
+
+ case H5C_FILE_ACCESS:
+ size = sizeof(H5F_access_t);
+ break;
+
+ case H5C_DATASET_CREATE:
+ size = sizeof(H5D_create_t);
+ break;
+
+ case H5C_DATASET_XFER:
+ size = sizeof(H5D_xfer_t);
+ break;
+
+ default:
+ HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, NULL,
+ "unknown template class");
+ }
+
+ /* Create the new template */
+ if (src) {
+ dst = H5MM_xmalloc(size);
+ HDmemcpy(dst, src, size);
+ }
+
+ FUNC_LEAVE (dst);
+}
diff --git a/src/H5Cpublic.h b/src/H5Cpublic.h
new file mode 100644
index 0000000..1a147bb
--- /dev/null
+++ b/src/H5Cpublic.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+ * 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. *
+ * *
+ ****************************************************************************/
+
+/*
+ * This file contains function prototypes for each exported function in the
+ * H5C module.
+ */
+#ifndef _H5Cpublic_H
+#define _H5Cpublic_H
+
+/* Default Template for creation, access, etc. templates */
+#define H5C_DEFAULT (-2)
+
+/* Public headers needed by this file */
+#include <H5public.h>
+#include <H5Apublic.h>
+#include <H5Dpublic.h>
+
+/* Template classes */
+typedef enum H5C_class_t {
+ H5C_NO_CLASS = -1, /*error return value */
+ H5C_FILE_CREATE = 0, /*file creation template */
+ H5C_FILE_ACCESS = 1, /*file access template */
+ H5C_DATASET_CREATE = 2, /*dataset creation template */
+ H5C_DATASET_XFER = 3, /*dataset transfer template */
+
+ H5C_NCLASSES = 4 /*this must be last! */
+} H5C_class_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Public functions */
+hid_t H5Ccreate (H5C_class_t type);
+herr_t H5Cclose (hid_t tid);
+hid_t H5Ccopy (hid_t tid);
+H5C_class_t H5Cget_class (hid_t tid);
+herr_t H5Cget_version (hid_t tid, int *boot/*out*/, int *heap/*out*/,
+ int *freelist/*out*/, int *stab/*out*/,
+ int *shhdr/*out*/);
+herr_t H5Cset_userblock (hid_t tid, size_t size);
+herr_t H5Cget_userblock (hid_t tid, size_t *size);
+herr_t H5Cset_sizes (hid_t tid, size_t sizeof_addr, size_t sizeof_size);
+herr_t H5Cget_sizes (hid_t tid, size_t *sizeof_addr/*out*/,
+ size_t *sizeof_size/*out*/);
+herr_t H5Cset_sym_k (hid_t tid, int ik, int lk);
+herr_t H5Cget_sym_k (hid_t tid, int *ik/*out*/, int *lk/*out*/);
+herr_t H5Cset_istore_k (hid_t tid, int ik);
+herr_t H5Cget_istore_k (hid_t tid, int *ik/*out*/);
+herr_t H5Cset_layout (hid_t tid, H5D_layout_t layout);
+H5D_layout_t H5Cget_layout (hid_t tid);
+herr_t H5Cset_chunk (hid_t tid, int ndims, const size_t dim[]);
+int H5Cget_chunk (hid_t tid, int max_ndims, size_t dim[]/*out*/);
+herr_t H5Cset_stdio (hid_t tid);
+herr_t H5Cset_sec2 (hid_t tid);
+herr_t H5Cset_core (hid_t tid, size_t increment);
+herr_t H5Cset_split (hid_t tid, const char *meta_ext, hid_t meta_tid,
+ const char *raw_ext, hid_t raw_tid);
+herr_t H5Cset_family (hid_t tid, hid_t memb_tid);
+#ifdef HAVE_PARALLEL
+herr_t H5Cset_mpi (hid_t tid, MPI_Comm comm, MPI_Info info, uintn access_mode);
+/* herr_t H5Cget_mpi (hid_t tid, int *ik); */ /* not defined yet */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/H5Ffamily.c b/src/H5Ffamily.c
index dba22f1..b89b983 100644
--- a/src/H5Ffamily.c
+++ b/src/H5Ffamily.c
@@ -137,6 +137,7 @@ H5F_fam_open(const char *name, const H5F_access_t *access_parms,
}
}
}
+
/* Create the file descriptor */
lf = H5MM_xcalloc(1, sizeof(H5F_low_t));
lf->u.fam.name = H5MM_xstrdup(name);
@@ -186,8 +187,8 @@ H5F_fam_open(const char *name, const H5F_access_t *access_parms,
if (size != mask) {
size++;
#ifdef H5F_DEBUG
- fprintf(stderr, "HDF5-DIAG: family member size was rounded up "
- "to a power of 2");
+ fprintf(stderr, "HDF5-DIAG: family member size was "
+ "rounded up to a power of 2");
#endif
}
break;
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 7daf090..0bee571 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -243,6 +243,8 @@ typedef struct H5F_access_t {
/* Properties for the split driver */
struct {
+ char *meta_ext; /*name extension for meta file */
+ char *raw_ext; /*name extension for raw file */
struct H5F_access_t *meta_access; /*plist for meta file */
struct H5F_access_t *raw_access; /*plist for raw data file */
} split;
diff --git a/src/H5MM.c b/src/H5MM.c
index 645798e..3a1d392 100644
--- a/src/H5MM.c
+++ b/src/H5MM.c
@@ -129,13 +129,12 @@ H5MM_xrealloc(void *mem, size_t size)
*
*-------------------------------------------------------------------------
*/
-char *
+char *
H5MM_xstrdup(const char *s)
{
char *mem;
- if (!s)
- return NULL;
+ if (!s) return NULL;
mem = H5MM_xmalloc(HDstrlen(s) + 1);
HDstrcpy(mem, s);
return mem;
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index e8d57d8..e2a09a3 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -174,8 +174,8 @@ H5O_dtype_decode_helper(const uint8 **pp, H5T_t *dt)
dt->u.compnd.memb[i].perm[1] = (perm_word >> 8) & 0xff;
dt->u.compnd.memb[i].perm[2] = (perm_word >> 16) & 0xff;
dt->u.compnd.memb[i].perm[3] = (perm_word >> 24) & 0xff;
- if (H5O_dtype_decode_helper(pp, &(dt->u.compnd.memb[i].type)) < 0 ||
- H5T_COMPOUND == dt->u.compnd.memb[i].type.type) {
+ if (H5O_dtype_decode_helper(pp, dt->u.compnd.memb[i].type) < 0 ||
+ H5T_COMPOUND == dt->u.compnd.memb[i].type->type) {
for (j = 0; j <= i; j++)
H5MM_xfree(dt->u.compnd.memb[i].name);
H5MM_xfree(dt->u.compnd.memb);
@@ -397,7 +397,7 @@ H5O_dtype_encode_helper(uint8 **pp, const H5T_t *dt)
perm_word |= dt->u.compnd.memb[i].perm[j] << (8 * j);
}
UINT32ENCODE(*pp, perm_word);
- if (H5O_dtype_encode_helper(pp, &(dt->u.compnd.memb[i].type))<0) {
+ if (H5O_dtype_encode_helper(pp, dt->u.compnd.memb[i].type)<0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL,
"can't encode member type");
}
@@ -578,7 +578,7 @@ H5O_dtype_size(H5F_t *f, const void *mesg)
for (i = 0; i < dt->u.compnd.nmembs; i++) {
ret_value += ((HDstrlen(dt->u.compnd.memb[i].name) + 8) / 8) * 8;
ret_value += 12 + dt->u.compnd.memb[i].ndims * 4;
- ret_value += H5O_dtype_size(f, &(dt->u.compnd.memb[i].type));
+ ret_value += H5O_dtype_size(f, dt->u.compnd.memb[i].type);
}
break;
diff --git a/src/H5T.c b/src/H5T.c
index b34860b..e932e0f 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -1959,7 +1959,7 @@ H5Tget_member_type(hid_t type_id, int membno)
HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid member number");
}
/* Copy data type into an atom */
- if (NULL == (memb_dt = H5T_copy(&(dt->u.compnd.memb[membno].type)))) {
+ if (NULL == (memb_dt = H5T_copy(dt->u.compnd.memb[membno].type))) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to copy member data type");
}
@@ -2464,10 +2464,10 @@ H5T_create(H5T_class_t type, size_t size)
*
*-------------------------------------------------------------------------
*/
-H5T_t *
+H5T_t *
H5T_copy(const H5T_t *old_dt)
{
- H5T_t *new_dt = NULL;
+ H5T_t *new_dt=NULL, *tmp=NULL;
intn i;
char *s;
@@ -2482,13 +2482,21 @@ H5T_copy(const H5T_t *old_dt)
new_dt->locked = FALSE;
if (H5T_COMPOUND == new_dt->type) {
+ /*
+ * Copy all member fields to new type, then overwrite the
+ * name and type fields of each new member with copied values.
+ * That is, H5T_copy() is a deep copy.
+ */
new_dt->u.compnd.memb = H5MM_xmalloc(new_dt->u.compnd.nmembs *
sizeof(H5T_member_t));
HDmemcpy(new_dt->u.compnd.memb, old_dt->u.compnd.memb,
new_dt->u.compnd.nmembs * sizeof(H5T_member_t));
+
for (i = 0; i < new_dt->u.compnd.nmembs; i++) {
s = new_dt->u.compnd.memb[i].name;
new_dt->u.compnd.memb[i].name = H5MM_xstrdup(s);
+ tmp = H5T_copy (old_dt->u.compnd.memb[i].type);
+ new_dt->u.compnd.memb[i].type = tmp;
}
}
FUNC_LEAVE(new_dt);
@@ -2497,7 +2505,8 @@ H5T_copy(const H5T_t *old_dt)
/*-------------------------------------------------------------------------
* Function: H5T_close
*
- * Purpose: Frees a data type and all associated memory.
+ * Purpose: Frees a data type and all associated memory. If the data
+ * type is locked then nothing happens.
*
* Return: Success: SUCCEED
*
@@ -2513,23 +2522,25 @@ H5T_copy(const H5T_t *old_dt)
herr_t
H5T_close(H5T_t *dt)
{
- intn i;
+ intn i;
FUNC_ENTER(H5T_close, FAIL);
assert(dt);
- assert(!dt->locked);
- if (dt && H5T_COMPOUND == dt->type) {
- for (i = 0; i < dt->u.compnd.nmembs; i++) {
- H5MM_xfree(dt->u.compnd.memb[i].name);
- }
- H5MM_xfree(dt->u.compnd.memb);
- H5MM_xfree(dt);
+ if (!dt->locked) {
+ if (dt && H5T_COMPOUND == dt->type) {
+ for (i = 0; i < dt->u.compnd.nmembs; i++) {
+ H5MM_xfree(dt->u.compnd.memb[i].name);
+ }
+ H5MM_xfree(dt->u.compnd.memb);
+ H5MM_xfree(dt);
- } else if (dt) {
- H5MM_xfree(dt);
+ } else if (dt) {
+ H5MM_xfree(dt);
+ }
}
+
FUNC_LEAVE(SUCCEED);
}
@@ -2611,7 +2622,6 @@ herr_t
H5T_insert(H5T_t *parent, const char *name, off_t offset, const H5T_t *member)
{
intn i;
- H5T_t *tmp = NULL;
FUNC_ENTER(H5T_insert, FAIL);
@@ -2635,7 +2645,7 @@ H5T_insert(H5T_t *parent, const char *name, off_t offset, const H5T_t *member)
offset + member->size > parent->u.compnd.memb[i].offset) ||
(parent->u.compnd.memb[i].offset < offset &&
parent->u.compnd.memb[i].offset +
- parent->u.compnd.memb[i].type.size > offset)) {
+ parent->u.compnd.memb[i].type->size > offset)) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL,
"member overlaps with another member");
}
@@ -2648,15 +2658,13 @@ H5T_insert(H5T_t *parent, const char *name, off_t offset, const H5T_t *member)
(parent->u.compnd.nalloc *
sizeof(H5T_member_t)));
}
+
/* Add member to end of member array */
i = parent->u.compnd.nmembs;
parent->u.compnd.memb[i].name = H5MM_xstrdup(name);
parent->u.compnd.memb[i].offset = offset;
parent->u.compnd.memb[i].ndims = 0; /*defaults to scalar */
-
- tmp = H5T_copy(member);
- parent->u.compnd.memb[i].type = *tmp;
- H5MM_xfree(tmp);
+ parent->u.compnd.memb[i].type = H5T_copy (member);
parent->u.compnd.nmembs++;
FUNC_LEAVE(SUCCEED);
@@ -2693,7 +2701,7 @@ H5T_pack(H5T_t *dt)
if (H5T_COMPOUND == dt->type) {
/* Recursively pack the members */
for (i = 0; i < dt->u.compnd.nmembs; i++) {
- if (H5T_pack(&(dt->u.compnd.memb[i].type)) < 0) {
+ if (H5T_pack(dt->u.compnd.memb[i].type) < 0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to pack part of a compound data type");
}
@@ -2703,7 +2711,7 @@ H5T_pack(H5T_t *dt)
H5T_sort_by_offset(dt);
for (i = 0, offset = 0; i < dt->u.compnd.nmembs; i++) {
dt->u.compnd.memb[i].offset = offset;
- offset += dt->u.compnd.memb[i].type.size;
+ offset += H5T_get_size (dt->u.compnd.memb[i].type);
}
/* Change total size */
@@ -2880,8 +2888,8 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2)
dt2->u.compnd.memb[idx2[i]].perm[j]) HGOTO_DONE(1);
}
- tmp = H5T_cmp(&(dt1->u.compnd.memb[idx1[i]].type),
- &(dt2->u.compnd.memb[idx2[i]].type));
+ tmp = H5T_cmp(dt1->u.compnd.memb[idx1[i]].type,
+ dt2->u.compnd.memb[idx2[i]].type);
if (tmp < 0) HGOTO_DONE(-1);
if (tmp > 0) HGOTO_DONE(1);
}
@@ -3340,7 +3348,7 @@ H5T_debug(H5T_t *dt, FILE * stream)
fprintf(stream, "]");
}
fprintf(stream, " ");
- H5T_debug(&(dt->u.compnd.memb[i].type), stream);
+ H5T_debug(dt->u.compnd.memb[i].type, stream);
}
fprintf(stream, "\n");
}
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 5ef27ed..604569c 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -254,12 +254,12 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata)
}
}
if (priv->src2dst[i]>=0) {
- type = &(src->u.compnd.memb[i].type);
+ type = H5T_copy (src->u.compnd.memb[i].type);
tid = H5A_register (H5_DATATYPE, type);
assert (tid>=0);
priv->src_memb_id[priv->src2dst[i]] = tid;
- type = &(dst->u.compnd.memb[priv->src2dst[i]].type);
+ type = H5T_copy (dst->u.compnd.memb[priv->src2dst[i]].type);
tid = H5A_register (H5_DATATYPE, type);
assert (tid>=0);
priv->dst_memb_id[priv->src2dst[i]] = tid;
@@ -469,7 +469,8 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
src_memb = src->u.compnd.memb + i;
dst_memb = dst->u.compnd.memb + src2dst[i];
- if (dst_memb->type.size <= src_memb->type.size) {
+ if (H5T_get_size (dst_memb->type) <=
+ H5T_get_size (src_memb->type)) {
H5T_conv_t tconv_func = priv->memb_conv[src2dst[i]];
H5T_cdata_t *memb_cdata = priv->memb_cdata[src2dst[i]];
memb_cdata->command = H5T_CONV_CONV;
@@ -481,12 +482,12 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
bkg + dst_memb->offset);
HDmemmove (buf + offset, buf + src_memb->offset,
- dst_memb->type.size);
- offset += dst_memb->type.size;
+ H5T_get_size (dst_memb->type));
+ offset += H5T_get_size (dst_memb->type);
} else {
HDmemmove (buf + offset, buf + src_memb->offset,
- src_memb->type.size);
- offset += src_memb->type.size;
+ H5T_get_size (src_memb->type));
+ offset += H5T_get_size (src_memb->type);
}
}
@@ -501,9 +502,10 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
if (src2dst[i]<0) continue;
src_memb = src->u.compnd.memb + i;
dst_memb = dst->u.compnd.memb + src2dst[i];
- offset -= dst_memb->type.size;
+ offset -= H5T_get_size (dst_memb->type);
- if (dst_memb->type.size > src_memb->type.size) {
+ if (H5T_get_size (dst_memb->type) >
+ H5T_get_size (src_memb->type)) {
H5T_conv_t tconv_func = priv->memb_conv[src2dst[i]];
H5T_cdata_t *memb_cdata = priv->memb_cdata[src2dst[i]];
memb_cdata->command = H5T_CONV_CONV;
@@ -512,7 +514,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
buf + offset, bkg + dst_memb->offset);
}
HDmemmove (bkg+dst_memb->offset, buf+offset,
- dst_memb->type.size);
+ H5T_get_size (dst_memb->type));
}
assert (0==offset);
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 7484c92..a934b23 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -76,7 +76,7 @@ typedef struct H5T_member_t {
intn ndims; /*member dimensionality */
size_t dim[4]; /*size in each dimension */
intn perm[4]; /*index permutation */
- struct H5T_t type; /*type of this member */
+ struct H5T_t *type; /*type of this member */
} H5T_member_t;
/* The data type conversion database */
diff --git a/src/H5config.h.in b/src/H5config.h.in
index 6efe276..6f8eef1 100644
--- a/src/H5config.h.in
+++ b/src/H5config.h.in
@@ -25,9 +25,6 @@
/* Define if the compiler understands the __FUNCTION__ keyword. */
#undef HAVE_FUNCTION
-/* Define if we have parallel support THIS WILL GO AWAY SHORTLY!!! */
-#undef PHDF5
-
/* Define if we have parallel support */
#undef HAVE_PARALLEL
@@ -52,6 +49,12 @@
/* Define if you have the fseek64 function. */
#undef HAVE_FSEEK64
+/* Define if you have the gethostname function. */
+#undef HAVE_GETHOSTNAME
+
+/* Define if you have the getpwuid function. */
+#undef HAVE_GETPWUID
+
/* Define if you have the lseek64 function. */
#undef HAVE_LSEEK64
diff --git a/src/H5detect.c b/src/H5detect.c
index b8e6fb9..a66dbad 100644
--- a/src/H5detect.c
+++ b/src/H5detect.c
@@ -40,6 +40,8 @@ static const char *FileHeader = "\n\
#include <time.h>
#include <unistd.h>
+#include <H5config.h>
+
#define MAXDETECT 16
#ifndef MIN
@@ -812,11 +814,10 @@ print_header(void)
time_t now = time(NULL);
struct tm *tm = localtime(&now);
- struct passwd *pwd = getpwuid(getuid());
- char real_name[30], *comma;
+ struct passwd *pwd = NULL;
+ char real_name[30];
char host_name[256];
int i;
- size_t n;
const char *s;
static const char *month_name[] =
{
@@ -863,25 +864,38 @@ bit.\n";
/*
* The real name is the first item from the passwd gecos field.
*/
- if (pwd) {
- if ((comma = strchr(pwd->pw_gecos, ','))) {
- n = MIN(sizeof(real_name) - 1, comma - pwd->pw_gecos);
- strncpy(real_name, pwd->pw_gecos, n);
- real_name[n] = '\0';
- } else {
- strncpy(real_name, pwd->pw_gecos, sizeof(real_name));
- real_name[sizeof(real_name) - 1] = '\0';
- }
- } else {
- real_name[0] = '\0';
+#ifdef HAVE_GETPWUID
+ {
+ size_t n;
+ char *comma;
+ if ((pwd = getpwuid(getuid()))) {
+ if ((comma = strchr(pwd->pw_gecos, ','))) {
+ n = MIN(sizeof(real_name) - 1, comma - pwd->pw_gecos);
+ strncpy(real_name, pwd->pw_gecos, n);
+ real_name[n] = '\0';
+ } else {
+ strncpy(real_name, pwd->pw_gecos, sizeof(real_name));
+ real_name[sizeof(real_name) - 1] = '\0';
+ }
+ } else {
+ real_name[0] = '\0';
+ }
}
+#else
+ real_name[0] = '\0';
+#endif
/*
* The FQDM of this host or the empty string.
*/
- if (gethostname(host_name, sizeof(host_name)) < 0)
+#ifdef HAVE_GETHOSTNAME
+ if (gethostname(host_name, sizeof(host_name)) < 0) {
host_name[0] = '\0';
-
+ }
+#else
+ host_name[0] = '\0';
+#endif
+
/*
* The file header: warning, copyright notice, build information.
*/
diff --git a/src/H5private.h b/src/H5private.h
index 88187fd..dd57431 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -112,7 +112,28 @@ typedef struct {
uint64 offset; /*offset within an HDF5 file */
} haddr_t;
-#define NO_ADDR NULL
+/*
+ * We try to use lseek64() and fseek64() if they're available, but they're
+ * not Posix and thus take different arguments on different systems. These
+ * macros attempt to overcome those problems.
+ */
+#ifdef HAVE_LSEEK64
+# ifdef _MIPS_SZLONG
+ /* SGI systems */
+# if (_MIPS_SZLONG == 64)
+# define OFF64_SET(VAR,VAL) VAR=VAL
+# elif defined(_LONGLONG)
+# define OFF64_SET(VAR,VAL) VAR=VAL
+# else
+# define OFF64_SET(VAR,VAL) (VAR.hi32=VAL>>32, \
+ VAR.lo32=(int)(VAL & 0xffffffff), \
+ VAL)
+# endif
+# else
+# warn "HAVE_LSEEK64 has been turned off"
+# undef HAVE_LSEEK64
+# endif
+#endif
/*
* Some compilers have problems declaring auto variables that point
diff --git a/test/tstab.c b/test/tstab.c
index 4210db7..ca3c069 100644
--- a/test/tstab.c
+++ b/test/tstab.c
@@ -239,11 +239,28 @@ test_2(void)
/*
* File access property list.
*/
-#if 0
access_plist = H5Pcreate (H5P_FILE_ACCESS);
- H5Pset_core (access_plist, 3000000);
-#else
- access_plist = H5P_DEFAULT;
+
+#if 0
+ /* Try temporary core files */
+ H5Cset_core (access_plist, 3000000);
+#elif 0
+ /* Try a default split file but with our own name extensions */
+ H5Cset_split (access_plist, ".XX1", H5C_DEFAULT, ".XX2", H5C_DEFAULT);
+#elif 0
+ {
+ /* Try a split file with an in-core meta data part */
+ hid_t meta_access = H5Ccreate (H5C_FILE_ACCESS);
+ H5Cset_core (meta_access, 1024*1024);
+ H5Cset_split (access_plist, NULL, meta_access, NULL, H5C_DEFAULT);
+ }
+#elif 0
+ {
+ /* Try a split file with an in-core raw data part */
+ hid_t raw_access = H5Ccreate (H5C_FILE_ACCESS);
+ H5Cset_core (raw_access, 1024*1024);
+ H5Cset_split (access_plist, NULL, H5C_DEFAULT, NULL, raw_access);
+ }
#endif
/* create the file */