diff options
author | Robb Matzke <matzke@llnl.gov> | 1998-02-25 20:31:17 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1998-02-25 20:31:17 (GMT) |
commit | ad73f18f5e759c4bd3d12c331659a24b54d0c39a (patch) | |
tree | 660a8bb32cc118a647757c5ae2321cf9b1ca9073 | |
parent | c543632ba5cd609d2e6303fa9cf55685568fa851 (diff) | |
download | hdf5-ad73f18f5e759c4bd3d12c331659a24b54d0c39a.zip hdf5-ad73f18f5e759c4bd3d12c331659a24b54d0c39a.tar.gz hdf5-ad73f18f5e759c4bd3d12c331659a24b54d0c39a.tar.bz2 |
[svn-r298] Changes since 19980219
----------------------
./html/Files.html
./src/H5C.c
./src/H5Cpublic.h
./src/H5Ffamily.c
./src/H5Fprivate.h
./src/H5Fsplit.c
./test/tstab.c
Added file-access property functions.
The split driver takes file extensions as properties.
./src/H5A.c
./src/H5Aprivate.h
Added some comments. Changed H5A_destroy() to call the free
function on all the atoms that are destroyed. This fixes a bug
where the file boot block isn't updated if the file isn't
closed before calling exit().
Removed extra `*' and `&' from some places.
./src/H5AC.c
Replaced an occurrence of NO_ADDR with NULL.
./src/H5Odtype.c
./src/H5T.c
./src/H5Tconv.c
./src/H5Tpkg.h
Data types of compound members are pointers.
./H5private.h
Some changes to make lseek64() work on Irix 5.3 where header
files don't realize that `long long' works.
./acconfig.h
./configure.in
Removed definition for PHDF5 since it looks like everyone is
useing HAVE_PARALLEL now.
./configure.in
./src/H5detec.c
Added checks for gethostname() and getpwuid().
-rw-r--r-- | acconfig.h | 3 | ||||
-rwxr-xr-x | configure | 27 | ||||
-rw-r--r-- | configure.in | 13 | ||||
-rw-r--r-- | src/H5A.c | 681 | ||||
-rw-r--r-- | src/H5AC.c | 2 | ||||
-rw-r--r-- | src/H5Aprivate.h | 28 | ||||
-rw-r--r-- | src/H5C.c | 1392 | ||||
-rw-r--r-- | src/H5Cpublic.h | 78 | ||||
-rw-r--r-- | src/H5Ffamily.c | 5 | ||||
-rw-r--r-- | src/H5Fprivate.h | 2 | ||||
-rw-r--r-- | src/H5MM.c | 5 | ||||
-rw-r--r-- | src/H5Odtype.c | 8 | ||||
-rw-r--r-- | src/H5T.c | 58 | ||||
-rw-r--r-- | src/H5Tconv.c | 22 | ||||
-rw-r--r-- | src/H5Tpkg.h | 2 | ||||
-rw-r--r-- | src/H5config.h.in | 9 | ||||
-rw-r--r-- | src/H5detect.c | 46 | ||||
-rw-r--r-- | src/H5private.h | 23 | ||||
-rw-r--r-- | test/tstab.c | 25 |
19 files changed, 1993 insertions, 436 deletions
@@ -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 @@ -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" @@ -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; + } + } +} @@ -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; @@ -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; @@ -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 */ |