summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1997-10-20 23:14:35 (GMT)
committerRobb Matzke <matzke@llnl.gov>1997-10-20 23:14:35 (GMT)
commit56ad55117a89a423a9341d2f0c3912d4ad57ec6f (patch)
treedff0bada659180ac324d81a4d97f7bfb884f0ed6
parentdc4961d072249ddf39a7db7a945ea627c276d025 (diff)
downloadhdf5-56ad55117a89a423a9341d2f0c3912d4ad57ec6f.zip
hdf5-56ad55117a89a423a9341d2f0c3912d4ad57ec6f.tar.gz
hdf5-56ad55117a89a423a9341d2f0c3912d4ad57ec6f.tar.bz2
[svn-r129] Changes since 19970916
---------------------- ./config/depend.in Fixed backslashes in sed script because the H5Gnode.c dependency info was disappearing. You'll have to rerun config.status to rebuild the Makefiles unless you use gnu make. ./config/conclude.in Also removes emacs backup files, TAGS, and svf backup files. ./config/linux Grouped gcc flags and added provisions for debugging vs. production. ./html/H5.format.html Updated messages 0x0008, 0x0009, and 0x000A. ./html/storage.html Documentation describing storage schemes. ./src/Makefile.in ./test/Makefile.in New source files. ./src/H5A.c ./src/H5Apublic.h ./src/H5C.c Changed VOIDP to void* in a couple places. ./src/H5AC.c ./src/H5ACprivate.h ./src/H5B.c ./src/H5Bprivate.h ./src/H5G.c ./src/H5Gnode.c ./src/H5Gprivate.h ./src/H5H.c ./src/H5O.c Removed `const' from some variables because H5G_node_found() wanted to modify it's udata argument. Removing const there caused it to cascade to these other locations. ./src/H5AC.c ./src/H5ACprivate.h ./src/H5B.c ./src/H5Gnode.c ./src/H5Gstab.c ./src/H5H.c ./src/H5O.c Added an extra argument to H5AC_find_f() and H5AC_protect(). This arg gets passed to the load() method. Also added an extra argument to the H5AC_find() macro. ./src/H5B.c ./src/H5Bprivate.h ./src/H5Gnode.c Extra argument passed to the sizeof_rkey() method. ./src/H5Fprivate.c ./src/H5Fistore.c (new) Added indexed I/O operations. ./src/H5G.c ./src/H5Gnode.c ./src/H5Gprivate.h Beginning to add H5G_open/close and related bug fixes. ./src/H5Oprivate.h ./src/H5Oistore.c (new) Added the H5O_ISTORE messsage (0x0008) for indexed storage of objects. ./src/H5private.h Added extra braces around both sides of the FUNC_ENTER() and FUNC_LEAVE() macros so FUNC_ENTER() can appear before declarations or after executable statements the second case is used by H5G_namei() to initialize output arguments to sane values before FUNC_ENTER() might return failure. int f () { int decl1; printf ("This happens before FUNC_ENTER()\n"); FUNC_ENTER (...); int another_declaration; ./src/H5B.c ./src/H5Bprivate.h ./src/H5Gnode.c Extra arguments for key encoding and decoding. ./src/H5E.c ./src/H5Epublic.h ./src/H5Fistore.c ./src/H5Oistore.c ./src/H5Oprivate.h Indexed, chunked, sparse storage (not ready for general consumption yet). ./src/H5V.c (new) ./src/H5Vprivate.h (new) ./test/hyperslab.c (new) Vector, array, and hyperslab functions. ./src/H5B.c ./src/H5Bprivate.h ./src/H5Fistore.c ./src/H5Gnode.c ./src/H5V.c ./src/H5Vprivate.h ./test/hyperslab.c Added functionality for indexed storage. ./src/H5F.c Fixed problems with seek optimizing. Recommend we disable it until we can implement it in the file/address class since all of HDF5 must be aware of it. ./src/H5O.c Fixed comeent speling erorr :-) ./MANIFEST Added new files. ./config/conclude.in Added the word `Testing' to the test cases. So if a test program is called hyperslab then the make output will contain the line `Testing hyperslab'. ./config/linux The default file I/O library is Posix section 2 on my linux machine so I can do some I/O performance testing. ./src/H5C.c ./src/H5Cprivate.h ./src/H5Cpublic.h Added ability to set size of indexed-storage B-tree. ./src/H5D.c ./src/H5E.c ./src/H5Epublic.h ./src/H5F.c ./src/H5Fprivate.h ./src/H5G.c ./src/H5Gnode.c ./src/H5Gpkg.h ./src/H5Gprivate.h ./src/H5Gpublic.h ./src/H5Gshad.c ./src/H5Gstab.c ./test/stab.c Changed `directory' to `group' in numerous places. ./src/H5private.h The FILELIB constant can be set on the compile command-line. ./src/istore.c NEW Tests for indexed storage.
-rw-r--r--MANIFEST6
-rw-r--r--Makefile.in6
-rw-r--r--acconfig.h5
-rw-r--r--config/conclude.in4
-rw-r--r--config/linux13
-rwxr-xr-xconfigure636
-rw-r--r--configure.in18
-rw-r--r--src/H5A.c2
-rw-r--r--src/H5AC.c26
-rw-r--r--src/H5ACprivate.h10
-rw-r--r--src/H5Apublic.h2
-rw-r--r--src/H5B.c369
-rw-r--r--src/H5Bprivate.h35
-rw-r--r--src/H5C.c20
-rw-r--r--src/H5Cprivate.h2
-rw-r--r--src/H5Cpublic.h1
-rw-r--r--src/H5D.c8
-rw-r--r--src/H5Distore.c740
-rw-r--r--src/H5E.c5
-rw-r--r--src/H5Epublic.h9
-rw-r--r--src/H5F.c40
-rw-r--r--src/H5Fistore.c740
-rw-r--r--src/H5Fprivate.h11
-rw-r--r--src/H5G.c799
-rw-r--r--src/H5Gent.c2
-rw-r--r--src/H5Gnode.c81
-rw-r--r--src/H5Gpkg.h30
-rw-r--r--src/H5Gprivate.h11
-rw-r--r--src/H5Gpublic.h10
-rw-r--r--src/H5Gshad.c86
-rw-r--r--src/H5Gstab.c10
-rw-r--r--src/H5H.c21
-rw-r--r--src/H5O.c43
-rw-r--r--src/H5Oistore.c271
-rw-r--r--src/H5Oname.c14
-rw-r--r--src/H5Oprivate.h21
-rw-r--r--src/H5Osdtyp.c2
-rw-r--r--src/H5config.h.in12
-rw-r--r--src/H5private.h14
-rw-r--r--src/Makefile.in10
-rw-r--r--test/Makefile.in30
-rw-r--r--test/istore.c431
-rw-r--r--test/tstab.c12
43 files changed, 3949 insertions, 669 deletions
diff --git a/MANIFEST b/MANIFEST
index 5304b73..4767c8d 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -48,6 +48,7 @@
./src/H5Eprivate.h
./src/H5Epublic.h
./src/H5F.c
+./src/H5Fistore.c
./src/H5Fprivate.h
./src/H5Fpublic.h
./src/H5G.c
@@ -72,6 +73,7 @@
./src/H5Mpublic.h
./src/H5O.c
./src/H5Ocont.c
+./src/H5Oistore.c
./src/H5Oname.c
./src/H5Onull.c
./src/H5Oprivate.h
@@ -88,10 +90,14 @@
./src/H5T.c
./src/H5Tprivate.h
./src/H5Tpublic.h
+./src/H5V.c
+./src/H5Vprivate.h
./src/hdf5.h
./src/Makefile.in
./src/Naming-Conventions
./test/Makefile.in
+./test/hyperslab.c
+./test/istore.c
./test/testhdf5.c
./test/testhdf5.h
./test/tfile.c
diff --git a/Makefile.in b/Makefile.in
index a4ca408..3b2275a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -73,7 +73,7 @@ distclean:
(cd $$d && $(MAKE) $@) || exit 1; \
done
$(RM) config/commence config/conclude config/depend
- $(RM) config.cache config.log config.status src/config.h
+ $(RM) config.cache config.log config.status src/H5config.h
$(RM) Makefile
maintainer-clean:
@@ -82,8 +82,8 @@ maintainer-clean:
@@SETX@; for d in $(SUBDIRS); do \
(cd $$d && $(MAKE) $@) || exit 1; \
done
- $(RM) config.cache config.log config.status src/config.h
- $(RM) configure src/config.h.in
+ $(RM) config.cache config.log config.status src/H5config.h
+ $(RM) configure src/H5config.h.in
# This file does not end with the `CONCLUDE' statement since it has
diff --git a/acconfig.h b/acconfig.h
new file mode 100644
index 0000000..e5be0c8
--- /dev/null
+++ b/acconfig.h
@@ -0,0 +1,5 @@
+/* Define if the __attribute__(()) extension is present */
+/* #define HAVE_ATTRIBUTE */
+
+/* Define if the compiler understands the __FUNCTION__ keyword. */
+/* #define HAVE_FUNCTION */
diff --git a/config/conclude.in b/config/conclude.in
index b556c11..629d06c 100644
--- a/config/conclude.in
+++ b/config/conclude.in
@@ -23,7 +23,7 @@ TAGS: $(LIB_SRC)
test: $(PROGS)
@for test in $(TESTS) dummy; do \
if test $$test != dummy; then \
- echo "$$test $(TEST_FLAGS)"; \
+ echo "Testing $$test $(TEST_FLAGS)"; \
$$test $(TEST_FLAGS) || exit 1; \
fi; \
done;
@@ -68,7 +68,7 @@ clean: mostlyclean
# in the distribution.
#
distclean: clean
- $(RM) .depend TAGS
+ $(RM) .depend TAGS *~ core *.bak *.old *.new
@if test -f Makefile.in; then \
(set -x; $(RM) Makefile); \
fi
diff --git a/config/linux b/config/linux
index bf4b791..ec59f3f 100644
--- a/config/linux
+++ b/config/linux
@@ -1,6 +1,17 @@
# Site configuration -- do not distribute this file.
+CFLAGS_WARN="-Wall -Wshadow -Wpointer-arith -Wcast-qual -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs"
+
+CFLAGS_DEBUG="-g -DH5AC_DEBUG_PROTECT -DFILELIB=1 -fverbose-asm"
+CFLAGS_PROFILE="-pg"
+CFLAGS_PRODUCTION="-O3 -UH5AC_DEBUG_PROTECT -DNDEBUG -finline-functions -funroll-loops -malign-double -fomit-frame-pointer"
+
if test "x$CFLAGS" = "x"; then
- CFLAGS="-g -DH5AC_DEBUG_PROTECT -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs"
+
+ # Uncomment the following line for a production version of the library.
+ #CFLAGS="-pipe $CFLAGS_PRODUCTION $CFLAGS_WARN"
+
+ # Uncomment the following line for normal development
+ CFLAGS="-pipe $CFLAGS_DEBUG $CFLAGS_WARN"
fi
diff --git a/configure b/configure
index ba332be..daf36d3 100755
--- a/configure
+++ b/configure
@@ -2,8 +2,8 @@
# From configure.in Id: configure.in
# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.7
-# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+# Generated automatically using autoconf version 2.12
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
@@ -50,6 +50,8 @@ mandir='${prefix}/man'
# Initialize some other variables.
subdirs=
MFLAGS= MAKEFLAGS=
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
ac_prev=
for ac_option
@@ -331,7 +333,7 @@ EOF
verbose=yes ;;
-version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.7"
+ echo "configure generated by autoconf version 2.12"
exit 0 ;;
-with-* | --with-*)
@@ -433,11 +435,14 @@ do
done
# NLS nuisances.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -rf conftest* confdefs.h
@@ -496,12 +501,10 @@ fi
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='echo $CPP $CPPFLAGS 1>&5;
-$CPP $CPPFLAGS'
-ac_compile='echo ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5;
-${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5'
-ac_link='echo ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5;
-${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5'
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
# Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
@@ -543,6 +546,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
fi
echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:550: checking host system type" >&5
host_alias=$host
case "$host_alias" in
@@ -557,15 +561,16 @@ NONE)
esac
host=`$ac_config_sub $host_alias`
-host_cpu=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-host_vendor=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-host_os=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$host" 1>&6
echo $ac_n "checking for cached host""... $ac_c" 1>&6
+echo "configure:574: checking for cached host" >&5
if eval "test \"`echo '$''{'hdf5_cv_host'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -584,6 +589,7 @@ fi
echo $ac_n "checking for site config file""... $ac_c" 1>&6
+echo "configure:593: checking for site config file" >&5
site_config="none"
for f in $host $host_vendor-$host_os $host_os; do
if test -f config/$f; then
@@ -601,6 +607,7 @@ fi
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:611: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -616,7 +623,6 @@ else
fi
done
IFS="$ac_save_ifs"
- test -z "$ac_cv_prog_CC" && ac_cv_prog_CC="cc"
fi
fi
CC="$ac_cv_prog_CC"
@@ -626,8 +632,98 @@ else
echo "$ac_t""no" 1>&6
fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:640: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ ac_prog_rejected=no
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:688: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 698 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:702: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:722: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:727: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -636,7 +732,7 @@ else
yes;
#endif
EOF
-if ${CC-cc} -E conftest.c 2>&5 | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:736: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
@@ -644,29 +740,34 @@ fi
fi
echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
if test $ac_cv_prog_gcc = yes; then
GCC=yes
- if test "${CFLAGS+set}" != set; then
- echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then
+ ac_test_CFLAGS="${CFLAGS+set}"
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:751: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
echo 'void f(){}' > conftest.c
if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
- ac_cv_prog_gcc_g=yes
+ ac_cv_prog_cc_g=yes
else
- ac_cv_prog_gcc_g=no
+ ac_cv_prog_cc_g=no
fi
rm -f conftest*
fi
-echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6
- if test $ac_cv_prog_gcc_g = yes; then
- CFLAGS="-g -O"
- else
- CFLAGS="-O"
- fi
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+ if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+ elif test $ac_cv_prog_cc_g = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-O2"
fi
else
GCC=
@@ -674,7 +775,8 @@ else
fi
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-set dummy ${MAKE-make}; ac_make=$2
+echo "configure:779: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -710,11 +812,12 @@ fi
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:816: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
for ac_dir in $PATH; do
# Account for people who put trailing slashes in PATH elements.
case "$ac_dir/" in
@@ -737,7 +840,7 @@ else
;;
esac
done
- IFS="$ac_save_ifs"
+ IFS="$ac_save_IFS"
fi
if test "${ac_cv_path_install+set}" = set; then
@@ -761,6 +864,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:868: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -788,6 +892,7 @@ fi
echo $ac_n "checking for GNU Make""... $ac_c" 1>&6
+echo "configure:896: checking for GNU Make" >&5
if test "`${MAKE-make} --version -f /dev/null 2>/dev/null |\
sed -n 1p|cut -c1-8`" = "GNU Make"; then
echo "$ac_t""yes" 1>&6
@@ -802,6 +907,7 @@ fi
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:911: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@@ -816,31 +922,37 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 820 "configure"
+#line 926 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:932: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
:
else
echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 834 "configure"
+#line 943 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:949: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
:
else
echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
CPP=/lib/cpp
fi
@@ -855,51 +967,29 @@ else
fi
echo "$ac_t""$CPP" 1>&6
-# If we cannot run a trivial program, we must be cross compiling.
-echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_c_cross=yes
-else
-cat > conftest.$ac_ext <<EOF
-#line 868 "configure"
-#include "confdefs.h"
-main(){return(0);}
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- ac_cv_c_cross=no
-else
- ac_cv_c_cross=yes
-fi
-fi
-rm -fr conftest*
-fi
-
-echo "$ac_t""$ac_cv_c_cross" 1>&6
-cross_compiling=$ac_cv_c_cross
-
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:972: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 890 "configure"
+#line 977 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>
EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:985: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
rm -rf conftest*
ac_cv_header_stdc=yes
else
echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_header_stdc=no
fi
@@ -908,7 +998,7 @@ rm -f conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 912 "configure"
+#line 1002 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@@ -926,7 +1016,7 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 930 "configure"
+#line 1020 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -946,8 +1036,8 @@ if test $ac_cv_header_stdc = yes; then
if test "$cross_compiling" = yes; then
:
else
-cat > conftest.$ac_ext <<EOF
-#line 951 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 1041 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -958,15 +1048,19 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:1052: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
:
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
ac_cv_header_stdc=no
fi
-fi
rm -fr conftest*
fi
+
+fi
fi
echo "$ac_t""$ac_cv_header_stdc" 1>&6
@@ -981,19 +1075,21 @@ fi
echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:1079: checking for off_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 989 "configure"
+#line 1084 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
#include <stdlib.h>
+#include <stddef.h>
#endif
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "off_t" >/dev/null 2>&1; then
+ egrep "off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
rm -rf conftest*
ac_cv_type_off_t=yes
else
@@ -1012,19 +1108,21 @@ EOF
fi
echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:1112: checking for size_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1020 "configure"
+#line 1117 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
#include <stdlib.h>
+#include <stddef.h>
#endif
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "size_t" >/dev/null 2>&1; then
+ egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
rm -rf conftest*
ac_cv_type_size_t=yes
else
@@ -1046,58 +1144,60 @@ fi
echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:1148: checking whether byte ordering is bigendian" >&5
if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_c_bigendian=unknown
# See if sys/param.h defines the BYTE_ORDER macro.
cat > conftest.$ac_ext <<EOF
-#line 1056 "configure"
+#line 1155 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/param.h>
-int main() { return 0; }
-int t() {
+int main() {
#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
bogus endian macros
#endif
; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:1166: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
# It does; now see whether it defined to BIG_ENDIAN or not.
cat > conftest.$ac_ext <<EOF
-#line 1072 "configure"
+#line 1170 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/param.h>
-int main() { return 0; }
-int t() {
+int main() {
#if BYTE_ORDER != BIG_ENDIAN
not big endian
#endif
; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:1181: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_bigendian=yes
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_c_bigendian=no
fi
rm -f conftest*
-
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-
if test $ac_cv_c_bigendian = unknown; then
if test "$cross_compiling" = yes; then
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
-cat > conftest.$ac_ext <<EOF
-#line 1101 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 1201 "configure"
#include "confdefs.h"
main () {
/* Are we little or big endian? From Harbison&Steele. */
@@ -1110,15 +1210,19 @@ main () {
exit (u.c[sizeof (long) - 1] == 1);
}
EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:1214: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
ac_cv_c_bigendian=no
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
ac_cv_c_bigendian=yes
fi
-fi
rm -fr conftest*
fi
+
+fi
fi
echo "$ac_t""$ac_cv_c_bigendian" 1>&6
@@ -1130,14 +1234,15 @@ EOF
fi
echo $ac_n "checking size of short""... $ac_c" 1>&6
+echo "configure:1238: checking size of short" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
ac_cv_sizeof_short=2
else
-cat > conftest.$ac_ext <<EOF
-#line 1141 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 1246 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
@@ -1148,15 +1253,19 @@ main()
exit(0);
}
EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:1257: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
ac_cv_sizeof_short=`cat conftestval`
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
ac_cv_sizeof_short=0
fi
-fi
rm -fr conftest*
fi
+
+fi
echo "$ac_t""$ac_cv_sizeof_short" 1>&6
cat >> confdefs.h <<EOF
#define SIZEOF_SHORT $ac_cv_sizeof_short
@@ -1164,14 +1273,15 @@ EOF
echo $ac_n "checking size of int""... $ac_c" 1>&6
+echo "configure:1277: checking size of int" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
ac_cv_sizeof_int=4
else
-cat > conftest.$ac_ext <<EOF
-#line 1175 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 1285 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
@@ -1182,15 +1292,19 @@ main()
exit(0);
}
EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:1296: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
ac_cv_sizeof_int=`cat conftestval`
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
ac_cv_sizeof_int=0
fi
-fi
rm -fr conftest*
fi
+
+fi
echo "$ac_t""$ac_cv_sizeof_int" 1>&6
cat >> confdefs.h <<EOF
#define SIZEOF_INT $ac_cv_sizeof_int
@@ -1198,14 +1312,15 @@ EOF
echo $ac_n "checking size of long""... $ac_c" 1>&6
+echo "configure:1316: checking size of long" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
ac_cv_sizeof_long=4
else
-cat > conftest.$ac_ext <<EOF
-#line 1209 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 1324 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
@@ -1216,15 +1331,19 @@ main()
exit(0);
}
EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:1335: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
ac_cv_sizeof_long=`cat conftestval`
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
ac_cv_sizeof_long=0
fi
-fi
rm -fr conftest*
fi
+
+fi
echo "$ac_t""$ac_cv_sizeof_long" 1>&6
cat >> confdefs.h <<EOF
#define SIZEOF_LONG $ac_cv_sizeof_long
@@ -1232,14 +1351,15 @@ EOF
echo $ac_n "checking size of long long""... $ac_c" 1>&6
+echo "configure:1355: checking size of long long" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
ac_cv_sizeof_long_long=8
else
-cat > conftest.$ac_ext <<EOF
-#line 1243 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 1363 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
@@ -1250,15 +1370,19 @@ main()
exit(0);
}
EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:1374: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
ac_cv_sizeof_long_long=`cat conftestval`
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
ac_cv_sizeof_long_long=0
fi
-fi
rm -fr conftest*
fi
+
+fi
echo "$ac_t""$ac_cv_sizeof_long_long" 1>&6
cat >> confdefs.h <<EOF
#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
@@ -1266,14 +1390,15 @@ EOF
echo $ac_n "checking size of float""... $ac_c" 1>&6
+echo "configure:1394: checking size of float" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_float'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
ac_cv_sizeof_float=4
else
-cat > conftest.$ac_ext <<EOF
-#line 1277 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 1402 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
@@ -1284,15 +1409,19 @@ main()
exit(0);
}
EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:1413: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
ac_cv_sizeof_float=`cat conftestval`
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
ac_cv_sizeof_float=0
fi
-fi
rm -fr conftest*
fi
+
+fi
echo "$ac_t""$ac_cv_sizeof_float" 1>&6
cat >> confdefs.h <<EOF
#define SIZEOF_FLOAT $ac_cv_sizeof_float
@@ -1300,14 +1429,15 @@ EOF
echo $ac_n "checking size of double""... $ac_c" 1>&6
+echo "configure:1433: checking size of double" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_double'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
ac_cv_sizeof_double=8
else
-cat > conftest.$ac_ext <<EOF
-#line 1311 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 1441 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
@@ -1318,15 +1448,19 @@ main()
exit(0);
}
EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:1452: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
ac_cv_sizeof_double=`cat conftestval`
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
ac_cv_sizeof_double=0
fi
-fi
rm -fr conftest*
fi
+
+fi
echo "$ac_t""$ac_cv_sizeof_double" 1>&6
cat >> confdefs.h <<EOF
#define SIZEOF_DOUBLE $ac_cv_sizeof_double
@@ -1337,6 +1471,170 @@ EOF
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1476: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1481 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1530: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:1551: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 1558 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:1565: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+
+echo $ac_n "checking for __attribute__ extension""... $ac_c" 1>&6
+echo "configure:1592: checking for __attribute__ extension" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1594 "configure"
+#include "confdefs.h"
+
+int main() {
+int __attribute__((unused)) f(void){return 1;}
+; return 0; }
+EOF
+if { (eval echo configure:1601: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ cat >> confdefs.h <<\EOF
+#define HAVE_ATTRIBUTE 1
+EOF
+ echo "$ac_t""yes" 1>&6
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+
+echo $ac_n "checking for __FUNCTION__ extension""... $ac_c" 1>&6
+echo "configure:1616: checking for __FUNCTION__ extension" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1618 "configure"
+#include "confdefs.h"
+
+int main() {
+int f(void){return __FUNCTION__;}
+; return 0; }
+EOF
+if { (eval echo configure:1625: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ cat >> confdefs.h <<\EOF
+#define HAVE_FUNCTION 1
+EOF
+ echo "$ac_t""yes" 1>&6
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+
COMMENCE=config/commence
@@ -1380,11 +1678,25 @@ cat > confcache <<\EOF
# --recheck option to rerun configure.
#
EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(set) 2>&1 |
- sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \
- >> confcache
+ case `(ac_space=' '; set) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
if cmp -s $cache_file confcache; then
:
else
@@ -1439,7 +1751,7 @@ do
echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.7"
+ echo "$CONFIG_STATUS generated by autoconf version 2.12"
exit 0 ;;
-help | --help | --hel | --he | --h)
echo "\$ac_cs_usage"; exit 0 ;;
@@ -1503,6 +1815,42 @@ s%@ROOT@%$ROOT%g
CEOF
EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
cat >> $CONFIG_STATUS <<EOF
CONFIG_FILES=\${CONFIG_FILES-"config/depend config/commence config/conclude \
@@ -1510,14 +1858,14 @@ CONFIG_FILES=\${CONFIG_FILES-"config/depend config/commence config/conclude \
EOF
cat >> $CONFIG_STATUS <<\EOF
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile]", defaulting infile="outfile.in".
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
*) ac_file_in="${ac_file}.in" ;;
esac
- # Adjust relative srcdir, etc. for subdirectories.
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
# Remove last slash and all that follows it. Not all systems have dirname.
ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
@@ -1545,6 +1893,7 @@ for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
[/$]*) INSTALL="$ac_given_INSTALL" ;;
*) INSTALL="$ac_dots$ac_given_INSTALL" ;;
esac
+
echo creating "$ac_file"
rm -f "$ac_file"
configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
@@ -1553,14 +1902,16 @@ for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
# $configure_input" ;;
*) ac_comsub= ;;
esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
sed -e "$ac_comsub
s%@configure_input@%$configure_input%g
s%@srcdir@%$srcdir%g
s%@top_srcdir@%$top_srcdir%g
s%@INSTALL@%$INSTALL%g
-" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
fi; done
-rm -f conftest.subs
+rm -f conftest.s*
# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
# NAME is the cpp macro being defined and VALUE is the value it is being given.
@@ -1581,11 +1932,17 @@ ac_eB='$%\1#\2define\3'
ac_eC=' '
ac_eD='%g'
-CONFIG_HEADERS=${CONFIG_HEADERS-"src/H5config.h"}
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="src/H5config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile]", defaulting infile="outfile.in".
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
*) ac_file_in="${ac_file}.in" ;;
esac
@@ -1593,7 +1950,8 @@ for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
echo creating $ac_file
rm -f conftest.frag conftest.in conftest.out
- cp $ac_given_srcdir/$ac_file_in conftest.in
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
EOF
@@ -1605,7 +1963,7 @@ rm -f conftest.vals
cat > conftest.hdr <<\EOF
s/[\\&%]/\\&/g
s%[\\$`]%\\&%g
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
s%ac_d%ac_u%gp
s%ac_u%ac_e%gp
EOF
@@ -1621,8 +1979,6 @@ EOF
# Break up conftest.vals because some shells have a limit on
# the size of here documents, and old seds have small limits too.
-# Maximum number of lines to put in a single here document.
-ac_max_here_lines=12
rm -f conftest.tail
while :
@@ -1653,12 +2009,22 @@ cat >> $CONFIG_STATUS <<\EOF
echo "$ac_file is unchanged"
rm -f conftest.h
else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
rm -f $ac_file
mv conftest.h $ac_file
fi
fi; done
+EOF
+cat >> $CONFIG_STATUS <<EOF
+EOF
+cat >> $CONFIG_STATUS <<\EOF
exit 0
EOF
diff --git a/configure.in b/configure.in
index 1d7ee2f..9e7cc44 100644
--- a/configure.in
+++ b/configure.in
@@ -105,9 +105,21 @@ AC_CHECK_SIZEOF(double, 8)
dnl ----------------------------------------------------------------------
-dnl AC_FUNC_MEMCMP
-dnl AC_C_CONST
-dnl AC_C_INLINE
+dnl Check compiler characteristics
+dnl
+
+AC_C_CONST
+AC_C_INLINE
+
+AC_MSG_CHECKING(for __attribute__ extension)
+AC_TRY_COMPILE(,[int __attribute__((unused)) f(void){return 1;}],
+ AC_DEFINE(HAVE_ATTRIBUTE) AC_MSG_RESULT(yes),
+ AC_MSG_RESULT(no))
+
+AC_MSG_CHECKING(for __FUNCTION__ extension)
+AC_TRY_COMPILE(,[int f(void){return __FUNCTION__;}],
+ AC_DEFINE(HAVE_FUNCTION) AC_MSG_RESULT(yes),
+ AC_MSG_RESULT(no))
diff --git a/src/H5A.c b/src/H5A.c
index 5605c34..52622bc 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -276,7 +276,7 @@ done:
*******************************************************************************/
hid_t H5Aregister_atom(group_t grp, /* IN: Group to register the object in */
- const VOIDP object /* IN: Object to attach to atom */
+ const void *object /* IN: Object to attach to atom */
)
{
atom_group_t *grp_ptr=NULL; /* ptr to the atomic group */
diff --git a/src/H5AC.c b/src/H5AC.c
index dda2fc2..1c570e8 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -143,10 +143,12 @@ H5AC_dest (H5F_t *f)
*
* Purpose: Given an object type and the address at which that object
* is located in the file, return a pointer to the object.
- * The optional UDATA structure is passed down to the function
- * that is responsible for loading the object into memory.
- * The pointer is guaranteed to be valid until the next call
- * to an H5AC function (if you want a pointer which is valid
+ * The optional UDATA1 and UDATA2 structures are passed down to
+ * the function that is responsible for loading the object into
+ * memory.
+ *
+ * The returned pointer is guaranteed to be valid until the next
+ * call to an H5AC function (if you want a pointer which is valid
* indefinately then see H5AC_protect()).
*
* If H5AC_DEBUG_PROTECT is defined then this function also
@@ -175,7 +177,8 @@ H5AC_dest (H5F_t *f)
*-------------------------------------------------------------------------
*/
void *
-H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
+H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
+ void *udata1, void *udata2)
{
unsigned idx;
herr_t status;
@@ -228,7 +231,7 @@ H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
* Load a new thing. If it can't be loaded, then return an error
* without preempting anything.
*/
- if (NULL==(thing=(type->load)(f, addr, udata))) {
+ if (NULL==(thing=(type->load)(f, addr, udata1, udata2))) {
HRETURN_ERROR (H5E_CACHE, H5E_CANTLOAD, NULL);
}
@@ -272,7 +275,7 @@ H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
* Failure: never fails
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
@@ -604,7 +607,7 @@ H5AC_rename (H5F_t *f, const H5AC_class_t *type,
* Failure: NULL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Sep 2 1997
*
* Modifications:
@@ -612,7 +615,8 @@ H5AC_rename (H5F_t *f, const H5AC_class_t *type,
*-------------------------------------------------------------------------
*/
void *
-H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
+H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
+ void *udata1, void *udata2)
{
int idx;
void *thing = NULL;
@@ -663,7 +667,7 @@ H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
* Load a new thing. If it can't be loaded, then return an error
* without preempting anything.
*/
- if (NULL==(thing=(type->load)(f, addr, udata))) {
+ if (NULL==(thing=(type->load)(f, addr, udata1, udata2))) {
HRETURN_ERROR (H5E_CACHE, H5E_CANTLOAD, NULL);
}
}
@@ -706,7 +710,7 @@ H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Sep 2 1997
*
* Modifications:
diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h
index a028d9c..25549ff 100644
--- a/src/H5ACprivate.h
+++ b/src/H5ACprivate.h
@@ -39,7 +39,7 @@
* by the LOAD method if the DEST argument is non-zero.
*/
typedef struct H5AC_class_t {
- void *(*load)(H5F_t*, haddr_t addr, void *udata);
+ void *(*load)(H5F_t*, haddr_t addr, void *udata1, void *udata2);
herr_t (*flush)(H5F_t*, hbool_t dest, haddr_t addr, void *thing);
} H5AC_class_t;
@@ -78,9 +78,9 @@ typedef struct H5AC_t {
*/
herr_t H5AC_dest (H5F_t *f);
void *H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
- void *udata);
+ void *udata1, void *udata2);
void * H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
- void *udata);
+ void *udata1, void *udata2);
herr_t H5AC_unprotect (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
void *thing);
herr_t H5AC_flush (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
@@ -91,11 +91,11 @@ herr_t H5AC_rename (H5F_t *f, const H5AC_class_t *type, haddr_t old,
herr_t H5AC_set (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
void *thing);
-#define H5AC_find(F,TYPE,ADDR,UDATA) \
+#define H5AC_find(F,TYPE,ADDR,UDATA1,UDATA2) \
(((F)->shared->cache->slot[H5AC_HASH(F,ADDR)].type==(TYPE) && \
(F)->shared->cache->slot[H5AC_HASH(F,ADDR)].addr==(ADDR)) ? \
(F)->shared->cache->slot[H5AC_HASH(F,ADDR)].thing : \
- H5AC_find_f (F, TYPE, ADDR, UDATA))
+ H5AC_find_f (F, TYPE, ADDR, UDATA1, UDATA2))
#endif /* !_H5ACprivate_H */
diff --git a/src/H5Apublic.h b/src/H5Apublic.h
index 36cceed..efae778 100644
--- a/src/H5Apublic.h
+++ b/src/H5Apublic.h
@@ -110,7 +110,7 @@ intn H5Adestroy_group(group_t grp /* IN: Group to destroy */
*******************************************************************************/
hid_t H5Aregister_atom(group_t grp, /* IN: Group to register the object in */
- const VOIDP object /* IN: Object to attach to atom */
+ const void *object /* IN: Object to attach to atom */
);
/******************************************************************************
diff --git a/src/H5B.c b/src/H5B.c
index cb3d2bb..ccbcdb4 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -100,21 +100,23 @@
/* PRIVATE PROTOTYPES */
static haddr_t H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
+ H5B_ins_t *anchor,
uint8 *lt_key, hbool_t *lt_key_changed,
uint8 *md_key, void *udata,
uint8 *rt_key, hbool_t *rt_key_changed);
static herr_t H5B_insert_child (H5F_t *f, const H5B_class_t *type,
H5B_t *bt, intn idx, haddr_t child,
- intn anchor, void *md_key);
+ H5B_ins_t anchor, void *md_key);
static herr_t H5B_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5B_t *b);
-static H5B_t *H5B_load (H5F_t *f, haddr_t addr, void *_data);
+static H5B_t *H5B_load (H5F_t *f, haddr_t addr, void *_type, void *udata);
static herr_t H5B_decode_key (H5F_t *f, H5B_t *bt, intn idx);
+static herr_t H5B_decode_keys (H5F_t *f, H5B_t *bt, intn idx);
static size_t H5B_nodesize (H5F_t *f, const H5B_class_t *type,
size_t *total_nkey_size, size_t sizeof_rkey);
/* H5B inherits cache-like properties from H5AC */
static const H5AC_class_t H5AC_BT[1] = {{
- (void*(*)(H5F_t*,haddr_t,void*))H5B_load,
+ (void*(*)(H5F_t*,haddr_t,void*,void*))H5B_load,
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5B_flush,
}};
@@ -125,7 +127,9 @@ static interface_initialize_g = FALSE;
/*-------------------------------------------------------------------------
* Function: H5B_new
*
- * Purpose: Creates a new empty B-tree leaf node.
+ * Purpose: Creates a new empty B-tree leaf node. The UDATA pointer is
+ * passed as an argument to the sizeof_rkey() method for the
+ * B-tree.
*
* Return: Success: address of new node.
*
@@ -140,7 +144,7 @@ static interface_initialize_g = FALSE;
*-------------------------------------------------------------------------
*/
haddr_t
-H5B_new (H5F_t *f, const H5B_class_t *type)
+H5B_new (H5F_t *f, const H5B_class_t *type, void *udata)
{
H5B_t *bt=NULL;
haddr_t addr;
@@ -159,7 +163,7 @@ H5B_new (H5F_t *f, const H5B_class_t *type)
/*
* Allocate file and memory data structures.
*/
- sizeof_rkey = (type->get_sizeof_rkey)(f);
+ sizeof_rkey = (type->get_sizeof_rkey)(f, udata);
size = H5B_nodesize (f, type, &total_native_keysize, sizeof_rkey);
if ((addr = H5MF_alloc (f, size))<0) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL);
@@ -229,9 +233,9 @@ H5B_new (H5F_t *f, const H5B_class_t *type)
*-------------------------------------------------------------------------
*/
static H5B_t *
-H5B_load (H5F_t *f, haddr_t addr, void *_data)
+H5B_load (H5F_t *f, haddr_t addr, void *_type, void *udata)
{
- const H5B_class_t *type = (H5B_class_t *)_data;
+ const H5B_class_t *type = (H5B_class_t *)_type;
size_t size, total_nkey_size;
H5B_t *bt = NULL;
intn i;
@@ -247,7 +251,7 @@ H5B_load (H5F_t *f, haddr_t addr, void *_data)
assert (type->get_sizeof_rkey);
bt = H5MM_xmalloc (sizeof(H5B_t));
- bt->sizeof_rkey = (type->get_sizeof_rkey)(f);
+ bt->sizeof_rkey = (type->get_sizeof_rkey)(f, udata);
size = H5B_nodesize (f, type, &total_nkey_size, bt->sizeof_rkey);
bt->type = type;
bt->dirty = FALSE;
@@ -375,7 +379,8 @@ H5B_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5B_t *bt)
assert (bt->key[i].rkey == p);
if (bt->key[i].dirty) {
if (bt->key[i].nkey) {
- if ((bt->type->encode)(f, bt->key[i].rkey, bt->key[i].nkey)<0) {
+ if ((bt->type->encode)(f, bt, bt->key[i].rkey,
+ bt->key[i].nkey)<0) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTENCODE, FAIL);
}
}
@@ -464,21 +469,14 @@ H5B_find (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
* Perform a binary search to locate the child which contains
* the thing for which we're searching.
*/
- if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type))) {
+ if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type, udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
rt = bt->nchildren;
while (lt<rt && cmp) {
idx = (lt + rt) / 2;
-
- /* the left key */
- if (!bt->key[idx].nkey && H5B_decode_key (f, bt, idx)<0) {
- HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
- }
-
- /* the right key */
- if (!bt->key[idx+1].nkey && H5B_decode_key (f, bt, idx+1)<0) {
+ if (H5B_decode_keys (f, bt, idx)<0) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
}
@@ -522,9 +520,11 @@ done:
* Function: H5B_split
*
* Purpose: Split a single node into two nodes. If anchor is
- * H5B_ANCHOR_LT then the new node gets the right half of
- * the old node. If anchor is H5B_ANCHOR_RT then the
- * new node gets the left half of the old node.
+ * H5B_INS_RIGHT then the new node gets the right half of
+ * the old node. If anchor is H5B_INS_LEFT then the
+ * new node gets the left half of the old node. The UDATA
+ * pointer is passed to the sizeof_rkey() method but is
+ * otherwise unused.
*
* The OLD_BT argument is a pointer to a protected B-tree
* node.
@@ -543,7 +543,7 @@ done:
*/
static haddr_t
H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
- intn anchor)
+ H5B_ins_t anchor, void *udata)
{
H5B_t *new_bt=NULL, *tmp_bt=NULL;
haddr_t ret_value=FAIL, new_addr=FAIL;
@@ -558,21 +558,22 @@ H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
assert (f);
assert (type);
assert (old_addr>=0);
+ assert (H5B_INS_LEFT==anchor || H5B_INS_RIGHT==anchor);
/*
* Initialize variables.
*/
assert (old_bt->nchildren == 2*H5B_K(f,type));
recsize = old_bt->sizeof_rkey + H5F_SIZEOF_OFFSET(f);
- delta = H5B_ANCHOR_LT==anchor ? H5B_K(f,type) : 0;
+ delta = H5B_INS_RIGHT==anchor ? H5B_K(f,type) : 0;
/*
* Create the new B-tree node.
*/
- if ((new_addr = H5B_new (f, type))<0) {
+ if ((new_addr = H5B_new (f, type, udata))<0) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTINIT, FAIL);
}
- if (NULL==(new_bt=H5AC_protect (f, H5AC_BT, new_addr, type))) {
+ if (NULL==(new_bt=H5AC_protect (f, H5AC_BT, new_addr, type, udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
new_bt->level = old_bt->level;
@@ -606,12 +607,12 @@ H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
/*
* Truncate the old node.
*/
- delta = H5B_ANCHOR_LT==anchor ? 0 : H5B_K(f,type);
+ delta = H5B_INS_RIGHT==anchor ? 0 : H5B_K(f,type);
old_bt->dirty = TRUE;
old_bt->ndirty = BOUND (0, old_bt->ndirty-delta, H5B_K(f,type));
old_bt->nchildren = H5B_K(f,type);
- if (H5B_ANCHOR_RT==anchor) {
+ if (H5B_INS_LEFT==anchor) {
HDmemcpy (old_bt->page + H5B_SIZEOF_HDR(f),
old_bt->page + H5B_SIZEOF_HDR(f) + delta*recsize,
H5B_K(f,type) * recsize);
@@ -642,12 +643,13 @@ H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
/*
* Update sibling pointers.
*/
- if (H5B_ANCHOR_LT==anchor) {
+ if (H5B_INS_RIGHT==anchor) {
new_bt->left = old_addr;
new_bt->right = old_bt->right;
if (old_bt->right) {
- if (NULL==(tmp_bt=H5AC_find (f, H5AC_BT, old_bt->right, type))) {
+ if (NULL==(tmp_bt=H5AC_find (f, H5AC_BT, old_bt->right, type,
+ udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
tmp_bt->dirty = TRUE;
@@ -659,7 +661,8 @@ H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
new_bt->right = old_addr;
if (old_bt->left) {
- if (NULL==(tmp_bt=H5AC_find (f, H5AC_BT, old_bt->left, type))) {
+ if (NULL==(tmp_bt=H5AC_find (f, H5AC_BT, old_bt->left, type,
+ udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
tmp_bt->dirty = TRUE;
@@ -702,7 +705,44 @@ H5B_decode_key (H5F_t *f, H5B_t *bt, intn idx)
FUNC_ENTER (H5B_decode_key, NULL, FAIL);
bt->key[idx].nkey = bt->native + idx * bt->type->sizeof_nkey;
- if ((bt->type->decode)(f, bt->key[idx].rkey, bt->key[idx].nkey)<0) {
+ if ((bt->type->decode)(f, bt, bt->key[idx].rkey,
+ bt->key[idx].nkey)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B_decode_keys
+ *
+ * Purpose: Decode keys on either side of the specified branch.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, October 14, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5B_decode_keys (H5F_t *f, H5B_t *bt, intn idx)
+{
+ FUNC_ENTER (H5B_decode_keys, NULL, FAIL);
+
+ assert (f);
+ assert (bt);
+ assert (idx>=0 && idx<bt->nchildren);
+
+ if (!bt->key[idx].nkey && H5B_decode_key (f, bt, idx)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+ if (!bt->key[idx+1].nkey && H5B_decode_key (f, bt, idx+1)<0) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
}
@@ -741,6 +781,7 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
size_t size;
uint8 *buf;
haddr_t tmp_addr;
+ H5B_ins_t anchor = H5B_INS_ERROR;
FUNC_ENTER (H5B_insert, NULL, FAIL);
@@ -749,17 +790,18 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
*/
assert (f);
assert (type);
- assert (type->sizeof_nkey < sizeof lt_key);
+ assert (type->sizeof_nkey <= sizeof lt_key);
- child = H5B_insert_helper (f, addr, type, lt_key, &lt_key_changed,
+ child = H5B_insert_helper (f, addr, type, &anchor, lt_key, &lt_key_changed,
md_key, udata, rt_key, &rt_key_changed);
- if (child<0) {
+ if (child<0 || anchor<0) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTINIT, FAIL);
}
- if (0==child) HRETURN (addr);
+ if (H5B_INS_NOOP==anchor) HRETURN (addr);
+ assert (H5B_INS_RIGHT==anchor);
/* the current root */
- if (NULL==(bt = H5AC_find (f, H5AC_BT, addr, type))) {
+ if (NULL==(bt = H5AC_find (f, H5AC_BT, addr, type, udata))) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
level = bt->level;
@@ -771,7 +813,7 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
}
/* the new node */
- if (NULL==(bt = H5AC_find (f, H5AC_BT, child, type))) {
+ if (NULL==(bt = H5AC_find (f, H5AC_BT, child, type, udata))) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
if (!rt_key_changed) {
@@ -812,14 +854,14 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
addr = tmp_addr;
/* update the new child's left pointer */
- if (NULL==(bt=H5AC_find (f, H5AC_BT, child, type))) {
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, child, type, udata))) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
bt->dirty = TRUE;
bt->left = addr;
/* clear the old root at the old address */
- if (NULL==(bt=H5AC_find (f, H5AC_BT, new_root, type))) {
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, new_root, type, udata))) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
bt->dirty = TRUE;
@@ -830,7 +872,7 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
/* the new root */
- if (NULL==(bt = H5AC_find (f, H5AC_BT, new_root, type))) {
+ if (NULL==(bt = H5AC_find (f, H5AC_BT, new_root, type, udata))) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
bt->dirty = TRUE;
@@ -877,7 +919,7 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
*/
static herr_t
H5B_insert_child (H5F_t *f, const H5B_class_t *type, H5B_t *bt,
- intn idx, haddr_t child, intn anchor, void *md_key)
+ intn idx, haddr_t child, H5B_ins_t anchor, void *md_key)
{
size_t recsize;
intn i;
@@ -888,7 +930,7 @@ H5B_insert_child (H5F_t *f, const H5B_class_t *type, H5B_t *bt,
bt->dirty = TRUE;
recsize = bt->sizeof_rkey + H5F_SIZEOF_OFFSET(f);
- if (H5B_ANCHOR_LT==anchor) {
+ if (H5B_INS_RIGHT==anchor) {
/*
* The MD_KEY is the left key of the new node.
*/
@@ -950,6 +992,7 @@ H5B_insert_child (H5F_t *f, const H5B_class_t *type, H5B_t *bt,
FUNC_LEAVE (SUCCEED);
}
+
/*-------------------------------------------------------------------------
* Function: H5B_insert_helper
@@ -985,6 +1028,7 @@ H5B_insert_child (H5F_t *f, const H5B_class_t *type, H5B_t *bt,
*/
static haddr_t
H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
+ H5B_ins_t *parent_ins,
uint8 *lt_key, hbool_t *lt_key_changed,
uint8 *md_key, void *udata,
uint8 *rt_key, hbool_t *rt_key_changed)
@@ -992,7 +1036,7 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
H5B_t *bt=NULL, *twin=NULL, *tmp_bt=NULL;
intn lt=0, idx=-1, rt, cmp=-1;
haddr_t child_addr=0, twin_addr=0, ret_value=FAIL;
- intn anchor;
+ H5B_ins_t my_ins = H5B_INS_ERROR;
FUNC_ENTER (H5B_insert_helper, NULL, FAIL);
@@ -1005,35 +1049,30 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
assert (type->decode);
assert (type->cmp);
assert (type->new);
+ assert (parent_ins && H5B_INS_ERROR==*parent_ins);
assert (lt_key);
assert (lt_key_changed);
assert (rt_key);
assert (rt_key_changed);
+ *lt_key_changed = FALSE;
+ *rt_key_changed = FALSE;
+
/*
* Use a binary search to find the child that will receive the new
* data. When the search completes IDX points to the child that
* should get the new data.
*/
- if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type))) {
+ if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type, udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
rt = bt->nchildren;
while (lt<rt && cmp) {
idx = (lt + rt) / 2;
-
- /* left key */
- if (!bt->key[idx].nkey && H5B_decode_key (f, bt, idx)<0) {
- HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
- }
-
- /* right key */
- if (!bt->key[idx+1].nkey && H5B_decode_key (f, bt, idx+1)<0) {
- HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ if (H5B_decode_keys (f, bt, idx)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
}
-
- /* compare */
if ((cmp=(type->cmp)(f, bt->key[idx].nkey, udata,
bt->key[idx+1].nkey))<0) {
rt = idx;
@@ -1042,46 +1081,14 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
}
}
- if (cmp<0 && idx<=0) {
- /*
- * Boundary condition: the value to insert is the new minimum
- * value in the B-tree. Insert the value in the left-most node.
- */
- idx = 0;
- cmp = 0;
-
- } else if (cmp>0 && idx+1>=bt->nchildren) {
+ if (0==bt->nchildren) {
/*
- * Boundary condition: the value to insert is the new maximum
- * value in the B-tree. Insert the value in the right-most node.
+ * The value being inserted will be the only value in this tree. We
+ * must necessarily be at level zero.
*/
- idx = bt->nchildren-1;
- cmp = 0;
- }
- assert (0==cmp);
-
- /*
- * Ensure that both native keys exist since we may have made boundary
- * condition adjustments.
- */
- if (bt->nchildren) {
- if (!bt->key[idx].nkey && H5B_decode_key (f, bt, idx)<0) {
- HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
- }
- if (!bt->key[idx+1].nkey && H5B_decode_key (f, bt, idx+1)<0) {
- HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
- }
- }
-
- /*
- * If there are no children, then create a new child. This can only
- * happen at the root of the B-tree. The left and right native keys
- * are output values from the node creation function.
- */
- if (0==bt->nchildren) {
+ assert (0==bt->level);
bt->key[0].nkey = bt->native;
bt->key[1].nkey = bt->native + type->sizeof_nkey;
-
if ((child_addr=(type->new)(f, bt->key[0].nkey, udata,
bt->key[1].nkey))<0) {
bt->key[0].nkey = bt->key[1].nkey = NULL;
@@ -1091,28 +1098,142 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
bt->dirty = TRUE;
bt->ndirty = 1;
bt->child[0] = child_addr;
-
bt->key[0].dirty = TRUE;
bt->key[1].dirty = TRUE;
idx = 0;
- }
- /*
- * Insert the new data in the child B-tree node or in the data node.
- */
- if (bt->level > 0) {
- child_addr = H5B_insert_helper (f, bt->child[idx], type,
+ if (type->follow_min) {
+ child_addr = (type->insert)(f, bt->child[idx], &my_ins,
+ bt->key[idx].nkey, lt_key_changed,
+ md_key, udata,
+ bt->key[idx+1].nkey, rt_key_changed);
+ } else {
+ my_ins = H5B_INS_NOOP;
+ }
+
+ } else if (cmp<0 && idx<=0 && bt->level>0) {
+ /*
+ * The value being inserted is less than any value in this tree. Follow
+ * the minimum branch out of this node to a subtree.
+ */
+ idx = 0;
+ if (H5B_decode_keys (f, bt, idx)<0) {
+ HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+ child_addr = H5B_insert_helper (f, bt->child[idx], type, &my_ins,
bt->key[idx].nkey, lt_key_changed,
md_key, udata,
bt->key[idx+1].nkey, rt_key_changed);
- anchor = H5B_ANCHOR_LT;
+
+ } else if (cmp<0 && idx<=0 && type->follow_min) {
+ /*
+ * The value being inserted is less than any leaf node out of this
+ * current node. Follow the minimum branch to a leaf node and let the
+ * subclass handle the problem.
+ */
+ idx = 0;
+ if (H5B_decode_keys (f, bt, idx)<0) {
+ HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+ child_addr = (type->insert)(f, bt->child[idx], &my_ins,
+ bt->key[idx].nkey, lt_key_changed,
+ md_key, udata,
+ bt->key[idx+1].nkey, rt_key_changed);
+
+ } else if (cmp<0 && idx<=0) {
+ /*
+ * The value being inserted is less than any leaf node out of the
+ * current node. Create a new minimum leaf node out of this B-tree
+ * node. This node is not empty (handled above).
+ */
+ idx = 0;
+ if (H5B_decode_keys (f, bt, idx)<0) {
+ HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+ my_ins = H5B_INS_LEFT;
+ HDmemcpy (md_key, bt->key[idx].nkey, type->sizeof_nkey);
+ child_addr = (type->new)(f, bt->key[idx].nkey, udata, md_key);
+ *lt_key_changed = TRUE;
+
+ } else if (cmp>0 && idx+1>=bt->nchildren && bt->level>0) {
+ /*
+ * The value being inserted is larger than any value in this tree.
+ * Follow the maximum branch out of this node to a subtree.
+ */
+ idx = bt->nchildren - 1;
+ if (H5B_decode_keys (f, bt, idx)<0) {
+ HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+ child_addr = H5B_insert_helper (f, bt->child[idx], type, &my_ins,
+ bt->key[idx].nkey, lt_key_changed,
+ md_key, udata,
+ bt->key[idx+1].nkey, rt_key_changed);
+
+ } else if (cmp>0 && idx+1>=bt->nchildren && type->follow_max) {
+ /*
+ * The value being inserted is larger than any leaf node out of the
+ * current node. Follow the maximum branch to a leaf node and let the
+ * subclass handle the problem.
+ */
+ idx = bt->nchildren - 1;
+ if (H5B_decode_keys (f, bt, idx)<0) {
+ HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+ child_addr = (type->insert)(f, bt->child[idx], &my_ins,
+ bt->key[idx].nkey, lt_key_changed,
+ md_key, udata,
+ bt->key[idx+1].nkey, rt_key_changed);
+
+ } else if (cmp>0 && idx+1>=bt->nchildren) {
+ /*
+ * The value being inserted is larger than any leaf node out of the
+ * current node. Create a new maximum leaf node out of this B-tree
+ * node.
+ */
+ idx = bt->nchildren - 1;
+ if (H5B_decode_keys (f, bt, idx)<0) {
+ HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+ my_ins = H5B_INS_RIGHT;
+ HDmemcpy (md_key, bt->key[idx+1].nkey, type->sizeof_nkey);
+ child_addr = (type->new)(f, md_key, udata, bt->key[idx+1].nkey);
+ *rt_key_changed = TRUE;
+
+ } else if (cmp) {
+ /*
+ * We couldn't figure out which branch to follow out of this node. THIS
+ * IS A MAJOR PROBLEM THAT NEEDS TO BE FIXED --rpm.
+ */
+ assert ("INTERNAL HDF5 ERROR (see rpm)" && 0);
+
+ } else if (bt->level>0) {
+ /*
+ * Follow a branch out of this node to another subtree.
+ */
+ assert (idx>=0 && idx<bt->nchildren);
+ child_addr = H5B_insert_helper (f, bt->child[idx], type, &my_ins,
+ bt->key[idx].nkey, lt_key_changed,
+ md_key, udata,
+ bt->key[idx+1].nkey, rt_key_changed);
+
+
} else {
- child_addr = (type->insert)(f, bt->child[idx], &anchor,
+ /*
+ * Follow a branch out of this node to a leaf node of some other type.
+ */
+ assert (idx>=0 && idx<bt->nchildren);
+ child_addr = (type->insert)(f, bt->child[idx], &my_ins,
bt->key[idx].nkey, lt_key_changed,
md_key, udata,
bt->key[idx+1].nkey, rt_key_changed);
+
+ }
+
+ if (child_addr<0 || my_ins<0) {
+ /* Insertion failed */
+ HGOTO_ERROR (H5E_BTREE, H5E_CANTINSERT, FAIL);
}
- if (child_addr<0) HGOTO_ERROR (H5E_BTREE, H5E_CANTINSERT, FAIL);
+
/*
* Update the left and right keys of the current node.
@@ -1136,36 +1257,43 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
}
}
- /*
- * Insert the child, splitting the current node if necessary.
- */
- if (child_addr) {
+ if (H5B_INS_CHANGE==my_ins) {
+ /*
+ * The insertion simply changed the address for the child.
+ */
+ bt->child[idx] = child_addr;
+ bt->dirty = TRUE;
+ bt->ndirty = MAX (bt->ndirty, idx+1);
+ *parent_ins = H5B_INS_NOOP;
+
+ } else if (H5B_INS_LEFT==my_ins || H5B_INS_RIGHT==my_ins) {
/*
- * If the child split and the left node is anchored, then the new
+ * The child split. If the left node is anchored, then the new
* child node gets inserted to the right of our current position.
*/
- if (H5B_ANCHOR_LT==anchor) idx++;
+ if (H5B_INS_RIGHT==my_ins) idx++;
if (bt->nchildren==2*H5B_K(f,type)) {
/* Split the current node */
- if ((twin_addr = H5B_split (f, type, bt, addr, anchor))<0) {
+ if ((twin_addr = H5B_split (f, type, bt, addr, my_ins, udata))<0) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTSPLIT, FAIL);
}
- if (NULL==(twin=H5AC_protect (f, H5AC_BT, twin_addr, type))) {
+ if (NULL==(twin=H5AC_protect (f, H5AC_BT, twin_addr, type,
+ udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
if (idx<=H5B_K(f,type)) {
- tmp_bt = H5B_ANCHOR_LT==anchor ? bt : twin;
+ tmp_bt = H5B_INS_RIGHT==my_ins ? bt : twin;
} else {
idx -= H5B_K (f, type);
- tmp_bt = H5B_ANCHOR_LT==anchor ? twin : bt;
+ tmp_bt = H5B_INS_RIGHT==my_ins ? twin : bt;
}
} else {
tmp_bt = bt;
}
- if (H5B_insert_child (f, type, tmp_bt, idx, child_addr, anchor,
+ if (H5B_insert_child (f, type, tmp_bt, idx, child_addr, my_ins,
md_key)<0) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTINSERT, FAIL);
}
@@ -1177,7 +1305,7 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
* by the left and right node).
*/
if (twin) {
- if (H5B_ANCHOR_LT==anchor) {
+ if (H5B_INS_RIGHT==my_ins) {
if (!twin->key[0].nkey && H5B_decode_key (f, twin, 0)<0) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
}
@@ -1188,7 +1316,11 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
}
HDmemcpy (md_key, bt->key[0].nkey, type->sizeof_nkey);
}
+ *parent_ins = H5B_INS_RIGHT;
+ } else {
+ *parent_ins = H5B_INS_NOOP;
}
+
HGOTO_DONE (twin_addr);
done:
@@ -1241,7 +1373,7 @@ H5B_list (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
assert (addr>=0);
assert (udata);
- if (NULL==(bt = H5AC_find (f, H5AC_BT, addr, type))) {
+ if (NULL==(bt = H5AC_find (f, H5AC_BT, addr, type, udata))) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
@@ -1254,7 +1386,7 @@ H5B_list (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
} else {
for (/*void*/; addr>0; addr=next_addr) {
- if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type))) {
+ if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type, udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
@@ -1318,6 +1450,7 @@ H5B_nodesize (H5F_t *f, const H5B_class_t *type,
assert (f);
assert (type);
assert (sizeof_rkey>0);
+ assert (H5B_K (f, type)>0);
/*
* Total native key size.
@@ -1356,7 +1489,7 @@ H5B_nodesize (H5F_t *f, const H5B_class_t *type,
*/
herr_t
H5B_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
- intn fwidth, H5B_class_t *type)
+ intn fwidth, H5B_class_t *type, void *udata)
{
H5B_t *bt = NULL;
int i;
@@ -1376,7 +1509,7 @@ H5B_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
/*
* Load the tree node.
*/
- if (NULL==(bt=H5AC_find (f, H5AC_BT, addr, type))) {
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, addr, type, udata))) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h
index 7814eeb..05e2e56 100644
--- a/src/H5Bprivate.h
+++ b/src/H5Bprivate.h
@@ -33,11 +33,17 @@
#define H5B_K(F,TYPE) /*K value given file and Btree subclass */ \
((F)->shared->file_create_parms.btree_k[(TYPE)->id])
-#define H5B_ANCHOR_LT 0 /* left node is anchored, right is new */
-#define H5B_ANCHOR_RT 1 /* right node is anchored, left is new */
+typedef enum H5B_ins_t {
+ H5B_INS_ERROR =-1, /*error return value */
+ H5B_INS_NOOP =0, /*insert made no changes */
+ H5B_INS_LEFT =1, /*insert new node to left of cur node */
+ H5B_INS_RIGHT =2, /*insert new node to right of cur node */
+ H5B_INS_CHANGE =3 /*change child address for cur node */
+} H5B_ins_t;
typedef enum H5B_subid_t {
- H5B_SNODE_ID =0 /*B-tree is for symbol table nodes */
+ H5B_SNODE_ID =0, /*B-tree is for symbol table nodes */
+ H5B_ISTORE_ID =1 /*B-tree is for indexed object storage */
} H5B_subid_t;
@@ -48,18 +54,21 @@ typedef enum H5B_subid_t {
* has an array of K values indexed by the `id' class field below. The
* array is initialized with the HDF5_BTREE_K_DEFAULT macro.
*/
+struct H5B_t; /*forward decl*/
typedef struct H5B_class_t {
H5B_subid_t id; /*id as found in file */
size_t sizeof_nkey; /*size of native (memory) key */
- size_t (*get_sizeof_rkey)(H5F_t*);
- haddr_t (*new)(H5F_t*,void*,void*,void*);
- intn (*cmp)(H5F_t*,void*,void*,void*);
+ size_t (*get_sizeof_rkey)(H5F_t*,const void*);/*raw key size */
+ haddr_t (*new)(H5F_t*,void*,void*,void*); /*create new leaf */
+ intn (*cmp)(H5F_t*,void*,void*,void*); /*compare keys */
herr_t (*found)(H5F_t*,haddr_t,const void*,void*,const void*);
- haddr_t (*insert)(H5F_t*,haddr_t,int*,void*,hbool_t*,void*,void*,
- void*,hbool_t*);
- herr_t (*list)(H5F_t*,haddr_t,void*);
- herr_t (*decode)(H5F_t*,uint8*,void*);
- herr_t (*encode)(H5F_t*,uint8*,void*);
+ haddr_t (*insert)(H5F_t*,haddr_t,H5B_ins_t*,void*,hbool_t*,void*,void*,
+ void*,hbool_t*); /*insert new data */
+ hbool_t follow_min; /*min insert uses min leaf, not new() */
+ hbool_t follow_max; /*max insert uses max leaf, not new() */
+ herr_t (*list)(H5F_t*,haddr_t,void*); /*traverse leaf nodes */
+ herr_t (*decode)(H5F_t*,struct H5B_t*,uint8*,void*);
+ herr_t (*encode)(H5F_t*,struct H5B_t*,uint8*,void*);
} H5B_class_t;
/*
@@ -91,8 +100,8 @@ typedef struct H5B_t {
* Library prototypes.
*/
herr_t H5B_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
- intn fwidth, H5B_class_t *type);
-haddr_t H5B_new (H5F_t *f, const H5B_class_t *type);
+ intn fwidth, H5B_class_t *type, void *udata);
+haddr_t H5B_new (H5F_t *f, const H5B_class_t *type, void *udata);
herr_t H5B_find (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata);
haddr_t H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata);
herr_t H5B_list (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata);
diff --git a/src/H5C.c b/src/H5C.c
index e4b263a..67be020 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -146,7 +146,7 @@ hid_t H5C_get_default_atom(hobjtype_t type)
case H5_TEMPLATE:
if(default_file_id==FAIL)
{
- if((default_file_id=H5Aregister_atom(H5_TEMPLATE, (const VOIDP)&default_file_create))==FAIL)
+ if((default_file_id=H5Aregister_atom(H5_TEMPLATE, (const void *)&default_file_create))==FAIL)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL);
} /* end else */
HGOTO_DONE(default_file_id);
@@ -324,6 +324,9 @@ done:
Robb Matzke, 13 Aug 1997
Removed H5_BTREE_SIZE and replaced it with H5_SYM_LEAF_K and
H5_SYM_INTERN_K.
+
+ Robb Matzke, 17 Oct 1997
+ Added H5_ISTORE_K.
--------------------------------------------------------------------------*/
herr_t H5Cgetparm(hid_t tid, file_create_param_t parm, VOIDP buf)
{
@@ -365,6 +368,10 @@ herr_t H5Cgetparm(hid_t tid, file_create_param_t parm, VOIDP buf)
*(uintn *)buf = template->btree_k[H5B_SNODE_ID];
break;
+ case H5_ISTORE_K:
+ *(uintn *)buf = template->btree_k[H5B_ISTORE_ID];
+ break;
+
case H5_BOOTBLOCK_VER:
*(uint8 *)buf=template->bootblock_ver;
break;
@@ -430,6 +437,9 @@ done:
Robb Matzke, 15 Sep 1997
Fixed the power-of-two test to work with any size integer.
+
+ Robb Matzke, 17 Oct 1997
+ Added H5_ISTORE_K.
--------------------------------------------------------------------------*/
herr_t H5Csetparm(hid_t tid, file_create_param_t parm, const VOIDP buf)
{
@@ -494,6 +504,14 @@ herr_t H5Csetparm(hid_t tid, file_create_param_t parm, const VOIDP buf)
}
template->btree_k[H5B_SNODE_ID] = val;
break;
+
+ case H5_ISTORE_K:
+ val = *(const uintn *)buf;
+ if (val<2) {
+ HGOTO_ERROR (H5E_ARGS, H5E_BADRANGE, FAIL);
+ }
+ template->btree_k[H5B_ISTORE_ID] = val;
+ break;
case H5_BOOTBLOCK_VER: /* this should be range checked */
template->bootblock_ver=*(const uint8 *)buf;
diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h
index 675fba6..168b253 100644
--- a/src/H5Cprivate.h
+++ b/src/H5Cprivate.h
@@ -34,7 +34,7 @@
#define H5C_BTREE_K_DEFAULT { \
16, /* Symbol table internal nodes */ \
- 0, /* unused */ \
+ 32, /* Indexed storage intern nodes */ \
0, /* unused */ \
0, /* unused */ \
0, /* unused */ \
diff --git a/src/H5Cpublic.h b/src/H5Cpublic.h
index 08e7656..4d2fd7d 100644
--- a/src/H5Cpublic.h
+++ b/src/H5Cpublic.h
@@ -37,6 +37,7 @@ typedef enum {
H5_LENGTH_SIZE, /* (uint8) Number of bytes for lengths */
H5_SYM_LEAF_K, /* (uintn) 1/2 rank for symbol table leaf nodes */
H5_SYM_INTERN_K, /* (uintn) 1/2 rank for symbol table internal nodes */
+ H5_ISTORE_K, /* (uintn) 1/2 rank for indexed storage nodes */
H5_BOOTBLOCK_VER, /* (uint8) Version # of the boot-block format */
H5_SMALLOBJECT_VER, /* (uint8) Version # of the small-object heap format */
H5_FREESPACE_VER, /* (uint8) Version # of the free-space info format */
diff --git a/src/H5D.c b/src/H5D.c
index 6153667..7d8b2d3 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -158,7 +158,7 @@ hid_t H5D_create(hid_t owner_id, hobjtype_t type, const char *name)
/* Open (and create) a new file object */
if (NULL==(new_dset->ent = H5G_create (file, name, H5D_MINHDR_SIZE))) {
- HGOTO_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL);
+ HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
}
/* Register the new datatype and get an ID for it */
@@ -183,14 +183,14 @@ done:
Get the OID for accessing an existing HDF5 dataset object
USAGE
hoid_t H5D_find_name(grp_id, type, name)
- hid_t grp_id; IN: Atom for directory to search for dataset
+ hid_t grp_id; IN: Atom for group to search for dataset
hobjtype_t type; IN: Type of object to search for (dataset in
this case)
const char *name; IN: Name of the object to search for
RETURNS
Returns ID (atom) on success, FAIL on failure
DESCRIPTION
- This function finds for a dataset by name in a directory.
+ This function finds for a dataset by name in a group.
--------------------------------------------------------------------------*/
hid_t H5D_find_name(hid_t grp_id, hobjtype_t obj_type, const char *name)
{
@@ -215,7 +215,7 @@ hid_t H5D_find_name(hid_t grp_id, hobjtype_t obj_type, const char *name)
if(NULL==(dset=HDcalloc(1, sizeof(H5D_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
- /* Initialize file, directory, name fields */
+ /* Initialize file, group, name fields */
dset->file = file;
dset->dirty = FALSE;
diff --git a/src/H5Distore.c b/src/H5Distore.c
new file mode 100644
index 0000000..b52288c
--- /dev/null
+++ b/src/H5Distore.c
@@ -0,0 +1,740 @@
+/*
+ * Copyright (C) 1997 Spizella Software
+ * All rights reserved.
+ *
+ * Programmer: Robb Matzke <robb@arborea.spizella.com>
+ * Wednesday, October 8, 1997
+ */
+#include <H5private.h>
+#include <H5Eprivate.h>
+#include <H5Fprivate.h>
+#include <H5MFprivate.h>
+#include <H5MMprivate.h>
+#include <H5Oprivate.h>
+#include <H5Vprivate.h>
+
+typedef enum H5F_isop_t {
+ H5F_ISTORE_READ, /*read from file to memory */
+ H5F_ISTORE_WRITE /*write from memory to file */
+} H5F_isop_t;
+
+/* Does the array domain include negative indices? */
+#undef H5F_ISTORE_NEGATIVE_DOMAIN
+
+
+#define PABLO_MASK H5F_istore_mask
+
+/* Is the interface initialized? */
+static hbool_t interface_initialize_g = FALSE;
+
+/* PRIVATE PROTOTYPES */
+static size_t H5F_istore_sizeof_rkey (H5F_t *f, const void *_udata);
+static haddr_t H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata,
+ void *_rt_key);
+static intn H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata,
+ void *_rt_key);
+static herr_t H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_key,
+ void *_udata, const void *_rt_key);
+static haddr_t H5F_istore_insert (H5F_t *f, haddr_t addr, H5B_ins_t *anchor,
+ void *_lt_key, hbool_t *lt_key_changed,
+ void *_md_key, void *_udata,
+ void *_rt_key, hbool_t *rt_key_changed);
+static herr_t H5F_istore_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
+ void *_key);
+static herr_t H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
+ void *_key);
+static herr_t H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore,
+ H5F_isop_t op, size_t offset_f[],
+ size_t size[], size_t offset_m[],
+ size_t size_m[], void *buf);
+
+
+/*
+ * B-tree key. A key contains the minimum logical N-dimensional address and
+ * the logical size of the chunk to which this key refers. The
+ * fastest-varying dimension is assumed to reference individual bytes of the
+ * array, so a 100-element 1-d array of 4-byte integers would really be a 2-d
+ * array with the slow varying dimension of size 100 and the fast varying
+ * dimension of size 4 (the storage dimensionality has very little to do with
+ * the real dimensionality).
+ *
+ * Only the first few values of the OFFSET and SIZE fields are actually
+ * stored on disk, depending on the dimensionality.
+ *
+ * The storage file address is part of the B-tree and not part of the key.
+ */
+typedef struct H5F_istore_key_t {
+ size_t offset[H5O_ISTORE_NDIMS]; /*logical offset to start*/
+ size_t size[H5O_ISTORE_NDIMS]; /*logical chunk size */
+} H5F_istore_key_t;
+
+typedef struct H5F_istore_ud1_t {
+ H5F_istore_key_t key; /*key values */
+ haddr_t addr; /*file address of chunk */
+ H5O_istore_t mesg; /*storage message */
+} H5F_istore_ud1_t;
+
+/* inherits B-tree like properties from H5B */
+H5B_class_t H5B_ISTORE[1] = {{
+ H5B_ISTORE_ID, /*id */
+ sizeof (H5F_istore_key_t), /*sizeof_nkey */
+ H5F_istore_sizeof_rkey, /*get_sizeof_rkey */
+ H5F_istore_new, /*new */
+ H5F_istore_cmp, /*cmp */
+ H5F_istore_found, /*found */
+ H5F_istore_insert, /*insert */
+ FALSE, /*follow min branch? */
+ FALSE, /*follow max branch? */
+ NULL, /*list */
+ H5F_istore_decode_key, /*decode */
+ H5F_istore_encode_key, /*encode */
+}};
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_sizeof_rkey
+ *
+ * Purpose: Returns the size of a raw key for the specified UDATA. The
+ * size of the key is dependent on the number of dimensions for
+ * the object to which this B-tree points. The dimensionality
+ * of the UDATA is the only portion that's referenced here.
+ *
+ * Return: Success: Size of raw key in bytes.
+ *
+ * Failure: abort()
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5F_istore_sizeof_rkey (H5F_t *f, const void *_udata)
+{
+ const H5F_istore_ud1_t *udata = (const H5F_istore_ud1_t *)_udata;
+
+ assert (udata);
+ assert (udata->mesg.ndims>0 && udata->mesg.ndims<=H5O_ISTORE_NDIMS);
+
+ return udata->mesg.ndims * (4 + 4);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_decode_key
+ *
+ * Purpose: Decodes a raw key into a native key for the B-tree
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 10, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_istore_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
+{
+ H5F_istore_key_t *key = (H5F_istore_key_t *)_key;
+ int i;
+ int ndims = bt->sizeof_rkey / 8;
+
+ FUNC_ENTER (H5F_istore_decode_key, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (bt);
+ assert (raw);
+ assert (key);
+ assert (ndims>0 && ndims<=H5O_ISTORE_NDIMS && 8*ndims==bt->sizeof_rkey);
+
+ /* decode */
+ for (i=0; i<ndims; i++) {
+ UINT32DECODE (raw, key->offset[i]);
+ UINT32DECODE (raw, key->size[i]);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_encode_key
+ *
+ * Purpose: Encode a key from native format to raw format.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 10, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
+{
+ H5F_istore_key_t *key = (H5F_istore_key_t *)_key;
+ intn ndims = bt->sizeof_rkey / 8;
+ intn i;
+
+ FUNC_ENTER (H5F_istore_encode_key, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (bt);
+ assert (raw);
+ assert (key);
+ assert (ndims>0 && ndims<=H5O_ISTORE_NDIMS && 8*ndims==bt->sizeof_rkey);
+
+ /* encode */
+ for (i=0; i<ndims; i++) {
+ UINT32ENCODE (raw, key->offset[i]);
+ UINT32ENCODE (raw, key->size[i]);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_cmp
+ *
+ * Purpose: Compare the requested datum UDATA with the left and right
+ * keys of the B-tree.
+ *
+ * Return: Success: negative if the min_corner of UDATA is less
+ * than the min_corner of LT_KEY.
+ *
+ * positive if the min_corner of UDATA is
+ * greater than or equal the min_corner of
+ * RT_KEY.
+ *
+ * zero otherwise. The min_corner of UDATA is
+ * not necessarily contained within the address
+ * space represented by LT_KEY, but a key that
+ * would describe the UDATA min_corner address
+ * would fall lexicographically between LT_KEY
+ * and RT_KEY.
+ *
+ * Failure: FAIL (same as UDATA < LT_KEY)
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static intn
+H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
+{
+ H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
+ H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
+ H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
+
+ assert (lt_key);
+ assert (rt_key);
+ assert (udata);
+ assert (udata->mesg.ndims>0 && udata->mesg.ndims<=H5O_ISTORE_NDIMS);
+
+ if (H5V_vector_lt (udata->mesg.ndims, udata->key.offset, lt_key->offset)) {
+ return -1;
+ } else if (H5V_vector_ge (udata->mesg.ndims, udata->key.offset,
+ rt_key->offset)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_new
+ *
+ * Purpose: Adds a new entry to an i-storage B-tree. We can assume that
+ * the domain represented by UDATA doesn't intersect the domain
+ * already represented by the B-tree.
+ *
+ * Return: Success: Address of leaf, which is passed in from the
+ * UDATA pointer.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, October 14, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static haddr_t
+H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
+{
+ H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
+ H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
+ H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
+ size_t nbytes;
+ intn i;
+
+ FUNC_ENTER (H5F_istore_new, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (lt_key);
+ assert (rt_key);
+ assert (udata);
+ assert (udata->mesg.ndims>=0 && udata->mesg.ndims<H5O_ISTORE_NDIMS);
+
+ /* Allocate new storage */
+ nbytes = H5V_vector_reduce_product (udata->mesg.ndims, udata->key.size);
+ assert (nbytes>0);
+ if ((udata->addr=H5MF_alloc (f, nbytes))<0) {
+ /* Couldn't allocate new file storage */
+ HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
+ }
+
+ /* left key describes the UDATA, right key is a zero-size "edge" */
+ for (i=0; i<udata->mesg.ndims; i++) {
+ lt_key->offset[i] = udata->key.offset[i];
+ lt_key->size[i] = udata->key.size[i];
+ assert (udata->key.size[i]>0);
+
+ rt_key->offset[i] = udata->key.offset[i] + udata->key.size[i];
+ rt_key->size[i] = 0;
+ }
+
+
+ FUNC_LEAVE (udata->addr);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_found
+ *
+ * Purpose: This function is called when the B-tree search engine has
+ * found the leaf entry that points to a chunk of storage that
+ * contains the beginning of the logical address space
+ * represented by UDATA. The LT_KEY is the left key (the one
+ * that describes the chunk) and RT_KEY is the right key (the
+ * one that describes the next or last chunk).
+ *
+ * Return: Success: SUCCEED with information about the chunk
+ * returned through the UDATA argument.
+ *
+ * Failure: FAIL if not found.
+ *
+ * Programmer: Robb Matzke
+ * Thursday, October 9, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_key,
+ void *_udata, const void *_rt_key)
+{
+ H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
+ const H5F_istore_key_t *lt_key = (const H5F_istore_key_t *)_lt_key;
+ const H5F_istore_key_t *rt_key = (const H5F_istore_key_t *)_rt_key;
+ int i;
+
+ FUNC_ENTER (H5F_istore_found, NULL, FAIL);
+
+ /* Check arguments */
+ assert (f);
+ assert (addr>=0);
+ assert (udata);
+ assert (lt_key);
+ assert (rt_key);
+
+ /* Initialize return values */
+ udata->addr = addr;
+ for (i=0; i<udata->mesg.ndims; i++) {
+ udata->key.offset[i] = lt_key->offset[i];
+ udata->key.size[i] = lt_key->size[i];
+ assert (lt_key->size[i]>0);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_insert
+ *
+ * Purpose: This function is called when the B-tree insert engine finds
+ * the node to use to insert new data. The UDATA argument
+ * points to a struct that describes the logical addresses being
+ * added to the file. This function allocates space for the
+ * data and returns information through UDATA describing a
+ * file chunk to receive (part of) the data.
+ *
+ * The LT_KEY is always the key describing the chunk of file
+ * memory at address ADDR. On entry, UDATA describes the logical
+ * addresses for which storage is being requested (through the
+ * `offset' and `size' fields). On return, UDATA describes the
+ * logical addresses contained in a chunk on disk.
+ *
+ * Return: Success: SUCCEED, with UDATA containing information
+ * about the (newly allocated) chunk.
+ *
+ * If the storage address has changed then the
+ * new address is returned.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, October 9, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static haddr_t
+H5F_istore_insert (H5F_t *f, haddr_t addr, H5B_ins_t *parent_ins,
+ void *_lt_key, hbool_t *lt_key_changed,
+ void *_md_key, void *_udata,
+ void *_rt_key, hbool_t *rt_key_changed)
+{
+ H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
+ H5F_istore_key_t *md_key = (H5F_istore_key_t *)_md_key;
+ H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
+ H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
+ intn i, cmp;
+ haddr_t ret_value = 0;
+ size_t nbytes;
+
+ FUNC_ENTER (H5F_istore_insert, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (addr>=0);
+ assert (parent_ins);
+ assert (lt_key);
+ assert (lt_key_changed);
+ assert (md_key);
+ assert (udata);
+ assert (rt_key);
+ assert (rt_key_changed);
+
+ cmp = H5F_istore_cmp (f, lt_key, udata, rt_key);
+ assert (cmp<=0);
+
+ if (cmp<0) {
+ /* Negative indices not supported yet */
+ assert ("HDF5 INTERNAL ERROR -- see rpm" && 0);
+ HRETURN_ERROR (H5E_STORAGE, H5E_UNSUPPORTED, FAIL);
+
+ } else if (H5V_hyper_eq (udata->mesg.ndims,
+ udata->key.offset, udata->key.size,
+ lt_key->offset, lt_key->size)) {
+ /*
+ * Already exists. Just return the info.
+ */
+ udata->addr = addr;
+ *parent_ins = H5B_INS_NOOP;
+
+ } else if (H5V_hyper_disjointp (udata->mesg.ndims,
+ lt_key->offset, lt_key->size,
+ udata->key.offset, udata->key.size)) {
+ assert (H5V_hyper_disjointp (udata->mesg.ndims,
+ rt_key->offset, rt_key->size,
+ udata->key.offset, udata->key.size));
+
+ /*
+ * Split this node, inserting the new new node to the right of the
+ * current node. The MD_KEY is where the split occurs.
+ */
+ for (i=0, nbytes=1; i<udata->mesg.ndims; i++) {
+ assert (0==udata->key.offset[i] % udata->mesg.alignment[i]);
+ assert (udata->key.size[i] == udata->mesg.alignment[i]);
+ md_key->offset[i] = udata->key.offset[i];
+ md_key->size[i] = udata->key.size[i];
+ nbytes *= udata->key.size[i];
+ }
+
+ /*
+ * Allocate storage for the new chunk
+ */
+ if ((udata->addr=ret_value=H5MF_alloc (f, nbytes))<=0) {
+ HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
+ }
+
+ *parent_ins = H5B_INS_RIGHT;
+
+ } else {
+ assert ("HDF5 INTERNAL ERROR -- see rpm" && 0);
+ HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL);
+ }
+
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_copy_hyperslab
+ *
+ * Purpose: Reads or writes a hyperslab to disk depending on whether OP
+ * is H5F_ISTORE_READ or H5F_ISTORE_WRITE. The hyperslab
+ * storage is described with ISTORE and exists in file F. The
+ * file hyperslab begins at location OFFSET_F[] (an N-dimensional
+ * point in the domain in terms of elements) in the file and
+ * OFFSET_M[] in memory pointed to by BUF. Its size is SIZE[]
+ * elements. The dimensionality of memory is assumed to be the
+ * same as the file and the total size of the multi-dimensional
+ * memory buffer is SIZE_M[].
+ *
+ * The slowest varying dimension is always listed first in the
+ * various offset and size arrays.
+ *
+ * A `chunk' is a hyperslab of the disk array which is stored
+ * contiguously. I/O occurs in units of chunks where the size of
+ * a chunk is determined by the alignment constraints specified
+ * in ISTORE.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 17, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore, H5F_isop_t op,
+ size_t offset_f[], size_t size[],
+ size_t offset_m[], size_t size_m[], void *buf)
+{
+ intn i, carry;
+ size_t idx_cur[H5O_ISTORE_NDIMS];
+ size_t idx_min[H5O_ISTORE_NDIMS];
+ size_t idx_max[H5O_ISTORE_NDIMS];
+ size_t sub_size[H5O_ISTORE_NDIMS];
+ size_t sub_offset_f[H5O_ISTORE_NDIMS];
+ size_t sub_offset_m[H5O_ISTORE_NDIMS];
+ size_t sub_offset_ch[H5O_ISTORE_NDIMS];
+ size_t chunk_size;
+ uint8 *chunk=NULL;
+ H5F_istore_ud1_t udata;
+ herr_t status;
+ herr_t ret_value = FAIL;
+
+ FUNC_ENTER (H5F_istore_copy_hyperslab, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (istore);
+ assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
+ assert (H5F_ISTORE_READ==op || H5F_ISTORE_WRITE==op);
+ assert (size);
+ assert (size_m);
+ assert (buf);
+#ifndef NDEBUG
+ for (i=0; i<istore->ndims; i++) {
+ assert (!offset_f || offset_f[i]>=0);/*neg domains unsupported */
+ assert (!offset_m || offset_m[i]>=0);/*mem array offset never neg */
+ assert (size[i]>=0); /*size may be zero, implies no-op */
+ assert (size_m[i]>0); /*destination must exist */
+ /*hyperslab must fit in BUF*/
+ assert ((offset_m?offset_m[i]:0)+size[i]<=size_m[i]);
+ assert (istore->alignment[i]>0);
+ }
+#endif
+
+ /*
+ * Does the B-tree exist?
+ */
+ if (istore->btree_addr<=0) {
+ if (H5F_ISTORE_WRITE==op) {
+ udata.mesg.ndims = istore->ndims;
+ if ((istore->btree_addr=H5B_new (f, H5B_ISTORE, &udata))<0) {
+ /* Can't create B-tree */
+ HGOTO_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
+ }
+ } else {
+ H5V_hyper_fill (istore->ndims, size, size_m, offset_m, buf, 0);
+ HRETURN (SUCCEED);
+ }
+ }
+
+ /* Initialize indices */
+ for (i=0; i<istore->ndims; i++) {
+ idx_min[i] = (offset_f?offset_f[i]:0) / istore->alignment[i];
+ idx_max[i] = ((offset_f?offset_f[i]:0)+size[i]-1)/istore->alignment[i]+1;
+ idx_cur[i] = idx_min[i];
+ }
+
+ /* Allocate buffers */
+ for (i=0, chunk_size=1; i<istore->ndims; i++) {
+ chunk_size *= istore->alignment[i];
+ }
+ chunk = H5MM_xmalloc (chunk_size);
+
+ /* Initialize non-changing part of udata */
+ udata.mesg = *istore;
+
+ /* Loop over all chunks */
+ while (1) {
+
+ /* Read/Write chunk or create it if it doesn't exist */
+ udata.mesg.ndims = istore->ndims;
+ for (i=0; i<istore->ndims; i++) {
+ udata.key.offset[i] = idx_cur[i] * istore->alignment[i];
+ udata.key.size[i] = istore->alignment[i];
+ sub_offset_f[i] = MAX ((offset_f?offset_f[i]:0), udata.key.offset[i]);
+ sub_offset_m[i] = (offset_m?offset_m[i]:0) +
+ sub_offset_f[i] - (offset_f?offset_f[i]:0);
+ sub_size[i] = (idx_cur[i]+1)*istore->alignment[i]-sub_offset_f[i];
+ sub_offset_ch[i] = sub_offset_f[i] - udata.key.offset[i];
+ }
+ if (H5F_ISTORE_WRITE==op) {
+ status = H5B_insert (f, H5B_ISTORE, istore->btree_addr, &udata);
+ assert (status>=0);
+ } else {
+ status = H5B_find (f, H5B_ISTORE, istore->btree_addr, &udata);
+ }
+
+ /*
+ * If the operation is reading from the disk or if we are writing a
+ * partial chunk then load the chunk from disk.
+ */
+ if (H5F_ISTORE_READ==op ||
+ !H5V_hyper_eq (istore->ndims,
+ udata.key.offset, udata.key.size,
+ sub_offset_f, sub_size)) {
+ if (status>=0) {
+ if (H5F_block_read (f, udata.addr, chunk_size, chunk)<0) {
+ HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL);
+ }
+ } else {
+ HDmemset (chunk, 0, chunk_size);
+ }
+ }
+
+ /* Transfer data to/from the chunk */
+ if (H5F_ISTORE_WRITE==op) {
+ H5V_hyper_copy (istore->ndims, sub_size,
+ udata.key.size, sub_offset_ch, chunk,
+ size_m, sub_offset_m, buf);
+ if (H5F_block_write (f, udata.addr, chunk_size, chunk)<0) {
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL);
+ }
+ } else {
+ H5V_hyper_copy (istore->ndims, sub_size,
+ size_m, sub_offset_m, buf,
+ udata.key.size, sub_offset_ch, chunk);
+ }
+
+ /* Increment indices */
+ for (i=istore->ndims-1, carry=1; i>=0 && carry; --i) {
+ if (++idx_cur[i]>=idx_max[i]) idx_cur[i] = idx_min[i];
+ else carry = 0;
+ }
+ if (carry) break;
+ }
+ ret_value = SUCCEED;
+
+
+ done:
+ chunk = H5MM_xfree (chunk);
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_read
+ *
+ * Purpose: Reads a multi-dimensional buffer from (part of) an indexed raw
+ * storage array.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 15, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_istore_read (H5F_t *f, struct H5O_istore_t *istore,
+ size_t offset[], size_t size[], void *buf)
+{
+ FUNC_ENTER (H5F_istore_read, NULL, FAIL);
+
+ /* Check args */
+ assert (f);
+ assert (istore);
+ assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
+ assert (size);
+ assert (buf);
+
+ if (H5F_istore_copy_hyperslab (f, istore, H5F_ISTORE_READ,
+ offset, size, H5V_ZERO, size, buf)<0) {
+ /* hyperslab output failure */
+ HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_write
+ *
+ * Purpose: Writes a multi-dimensional buffer to (part of) an indexed raw
+ * storage array.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 15, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_istore_write (H5F_t *f, struct H5O_istore_t *istore,
+ size_t offset[], size_t size[], void *buf)
+{
+ FUNC_ENTER (H5F_istore_write, NULL, FAIL);
+
+ /* Check args */
+ assert (f);
+ assert (istore);
+ assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
+ assert (size);
+ assert (buf);
+
+ if (H5F_istore_copy_hyperslab (f, istore, H5F_ISTORE_WRITE,
+ offset, size, H5V_ZERO, size, buf)<0) {
+ /* hyperslab output failure */
+ HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
diff --git a/src/H5E.c b/src/H5E.c
index 866f8c6..80ab219 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -59,10 +59,10 @@ static const hdf_maj_error_messages_t hdf_maj_error_messages[] =
{H5E_SYM, "Symbol Table"},
{H5E_HEAP, "Heap"},
{H5E_OHDR, "Object Header"},
- {H5E_DIRECTORY, "Directory"},
{H5E_DATATYPE, "Datatype"},
{H5E_DATASPACE, "Dataspace"},
- {H5E_DATASET, "Dataset"}
+ {H5E_DATASET, "Dataset"},
+ {H5E_STORAGE, "Data Storage"},
};
static const hdf_min_error_messages_t hdf_min_error_messages[] =
@@ -104,6 +104,7 @@ static const hdf_min_error_messages_t hdf_min_error_messages[] =
{H5E_ALIGNMENT, "Alignment error"},
{H5E_BADMESG, "Unrecognized message"},
{H5E_COMPLEN, "Name component is too long"},
+ {H5E_CWG, "Problem with current working group"},
{H5E_LINK, "Link count failure"},
};
diff --git a/src/H5Epublic.h b/src/H5Epublic.h
index bde74e5..abb6e3c 100644
--- a/src/H5Epublic.h
+++ b/src/H5Epublic.h
@@ -38,10 +38,10 @@ typedef enum
H5E_SYM, /* Symbol Table */
H5E_HEAP, /* Heap */
H5E_OHDR, /* Object Header */
- H5E_DIRECTORY, /* Directory */
H5E_DATATYPE, /* Datatype */
- H5E_DATASPACE, /* Dataspace */
- H5E_DATASET /* Dataset */
+ H5E_DATASPACE, /* Dataspace */
+ H5E_DATASET, /* Dataset */
+ H5E_STORAGE /* Data storage */
}
hdf_maj_err_code_t;
@@ -102,9 +102,10 @@ typedef enum
H5E_ALIGNMENT, /* Alignment error */
H5E_BADMESG, /* Unrecognized message */
- /* Directory related errors */
+ /* Group related errors */
H5E_CANTOPENOBJ, /* Can't open object */
H5E_COMPLEN, /* Name component is too long */
+ H5E_CWG, /* Problem with current working group */
H5E_LINK /* Link count failure */
}
hdf_min_err_code_t;
diff --git a/src/H5F.c b/src/H5F.c
index 6cba7d0..dbfeeb6 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -69,7 +69,6 @@ static herr_t H5F_init_interface(void);
static H5F_t *H5F_new (H5F_file_t *shared);
static H5F_t *H5F_dest (H5F_t *f);
static herr_t H5F_flush (H5F_t *f, hbool_t invalidate);
-static herr_t H5F_close (H5F_t *f);
/*--------------------------------------------------------------------------
NAME
@@ -500,7 +499,7 @@ H5F_dest (H5F_t *f)
* block is written. This operation will fail
* if the file is already open.
*
- * Unlinking the file name from the directory hierarchy while
+ * Unlinking the file name from the group directed graph while
* the file is opened causes the file to continue to exist but
* one will not be able to upgrade the file from read-only
* access to read-write access by reopening it. Disk resources
@@ -508,13 +507,20 @@ H5F_dest (H5F_t *f)
* closed. NOTE: This paragraph probably only applies to Unix;
* deleting the file name in other OS's has undefined results.
*
+ * The CREATE_PARMS argument is optional. A null pointer will
+ * cause the default file creation parameters to be used.
+ *
* Errors:
+ * ATOM BADATOM Can't unatomize default template
+ * id.
* FILE BADVALUE Can't create file without write
* intent.
* FILE BADVALUE Can't truncate without write intent.
* FILE CANTCREATE Can't create file.
* FILE CANTCREATE Can't stat file.
* FILE CANTCREATE Can't truncate file.
+ * FILE CANTINIT Can't get default file create template
+ * id.
* FILE CANTINIT Can't write file boot block.
* FILE CANTINIT Cannot determine file size.
* FILE CANTOPENFILE Bad boot block version number.
@@ -550,7 +556,7 @@ H5F_dest (H5F_t *f)
*
*-------------------------------------------------------------------------
*/
-static H5F_t *
+H5F_t *
H5F_open (const char *name, uintn flags,
const file_create_temp_t *create_parms)
{
@@ -573,6 +579,21 @@ H5F_open (const char *name, uintn flags,
assert (name && *name);
/*
+ * If no file creation parameters are supplied then use defaults.
+ */
+ if (!create_parms) {
+ hid_t create_temp = H5C_get_default_atom (H5_TEMPLATE);
+ if (create_temp<0) {
+ /* Can't get default file create template id */
+ HRETURN_ERROR (H5E_FILE, H5E_CANTINIT, NULL);
+ }
+ if (NULL==(create_parms=H5Aatom_object (create_temp))) {
+ /* Can't unatomize default template id */
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL);
+ }
+ }
+
+ /*
* Does the file exist? If so, get the device and i-node values so we can
* compare them with other files already open. On Unix (and other systems
* with hard or soft links) it doesn't work to compare files based only on
@@ -984,11 +1005,6 @@ hid_t H5Fcreate(const char *filename, uintn flags, hid_t create_temp,
hid_t H5Fopen(const char *filename, uintn flags, hid_t access_temp)
{
H5F_t *new_file=NULL; /* file struct for new file */
- hid_t create_temp; /* file-creation template ID */
- const file_create_temp_t *f_create_parms; /* pointer to the parameters
- * to use when creating the
- * file
- */
hid_t ret_value = FAIL;
FUNC_ENTER(H5Fopen, H5F_init_interface, FAIL);
@@ -999,10 +1015,6 @@ hid_t H5Fopen(const char *filename, uintn flags, hid_t access_temp)
HGOTO_ERROR (H5E_ARGS, H5E_BADRANGE, FAIL);/*invalid file name*/
flags = flags & H5ACC_WRITE ? H5F_ACC_WRITE : 0;
- create_temp = H5C_get_default_atom (H5_TEMPLATE);
- if (NULL==(f_create_parms=H5Aatom_object(create_temp)))
- HGOTO_ERROR (H5E_ATOM, H5E_BADATOM, FAIL);/*can't unatomize template*/
-
#ifdef LATER
if (access_temp<=0)
access_temp = H5CPget_default_atom (H5_TEMPLATE);
@@ -1011,7 +1023,7 @@ hid_t H5Fopen(const char *filename, uintn flags, hid_t access_temp)
#endif
/* Open the file */
- if (NULL==(new_file=H5F_open (filename, flags, f_create_parms))) {
+ if (NULL==(new_file=H5F_open (filename, flags, NULL))) {
HGOTO_ERROR (H5E_FILE, H5E_CANTOPENFILE, FAIL); /*cant open file*/
}
@@ -1188,7 +1200,7 @@ H5Fflush (hid_t fid, hbool_t invalidate)
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5F_close (H5F_t *f)
{
herr_t ret_value = FAIL;
diff --git a/src/H5Fistore.c b/src/H5Fistore.c
new file mode 100644
index 0000000..b52288c
--- /dev/null
+++ b/src/H5Fistore.c
@@ -0,0 +1,740 @@
+/*
+ * Copyright (C) 1997 Spizella Software
+ * All rights reserved.
+ *
+ * Programmer: Robb Matzke <robb@arborea.spizella.com>
+ * Wednesday, October 8, 1997
+ */
+#include <H5private.h>
+#include <H5Eprivate.h>
+#include <H5Fprivate.h>
+#include <H5MFprivate.h>
+#include <H5MMprivate.h>
+#include <H5Oprivate.h>
+#include <H5Vprivate.h>
+
+typedef enum H5F_isop_t {
+ H5F_ISTORE_READ, /*read from file to memory */
+ H5F_ISTORE_WRITE /*write from memory to file */
+} H5F_isop_t;
+
+/* Does the array domain include negative indices? */
+#undef H5F_ISTORE_NEGATIVE_DOMAIN
+
+
+#define PABLO_MASK H5F_istore_mask
+
+/* Is the interface initialized? */
+static hbool_t interface_initialize_g = FALSE;
+
+/* PRIVATE PROTOTYPES */
+static size_t H5F_istore_sizeof_rkey (H5F_t *f, const void *_udata);
+static haddr_t H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata,
+ void *_rt_key);
+static intn H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata,
+ void *_rt_key);
+static herr_t H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_key,
+ void *_udata, const void *_rt_key);
+static haddr_t H5F_istore_insert (H5F_t *f, haddr_t addr, H5B_ins_t *anchor,
+ void *_lt_key, hbool_t *lt_key_changed,
+ void *_md_key, void *_udata,
+ void *_rt_key, hbool_t *rt_key_changed);
+static herr_t H5F_istore_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
+ void *_key);
+static herr_t H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
+ void *_key);
+static herr_t H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore,
+ H5F_isop_t op, size_t offset_f[],
+ size_t size[], size_t offset_m[],
+ size_t size_m[], void *buf);
+
+
+/*
+ * B-tree key. A key contains the minimum logical N-dimensional address and
+ * the logical size of the chunk to which this key refers. The
+ * fastest-varying dimension is assumed to reference individual bytes of the
+ * array, so a 100-element 1-d array of 4-byte integers would really be a 2-d
+ * array with the slow varying dimension of size 100 and the fast varying
+ * dimension of size 4 (the storage dimensionality has very little to do with
+ * the real dimensionality).
+ *
+ * Only the first few values of the OFFSET and SIZE fields are actually
+ * stored on disk, depending on the dimensionality.
+ *
+ * The storage file address is part of the B-tree and not part of the key.
+ */
+typedef struct H5F_istore_key_t {
+ size_t offset[H5O_ISTORE_NDIMS]; /*logical offset to start*/
+ size_t size[H5O_ISTORE_NDIMS]; /*logical chunk size */
+} H5F_istore_key_t;
+
+typedef struct H5F_istore_ud1_t {
+ H5F_istore_key_t key; /*key values */
+ haddr_t addr; /*file address of chunk */
+ H5O_istore_t mesg; /*storage message */
+} H5F_istore_ud1_t;
+
+/* inherits B-tree like properties from H5B */
+H5B_class_t H5B_ISTORE[1] = {{
+ H5B_ISTORE_ID, /*id */
+ sizeof (H5F_istore_key_t), /*sizeof_nkey */
+ H5F_istore_sizeof_rkey, /*get_sizeof_rkey */
+ H5F_istore_new, /*new */
+ H5F_istore_cmp, /*cmp */
+ H5F_istore_found, /*found */
+ H5F_istore_insert, /*insert */
+ FALSE, /*follow min branch? */
+ FALSE, /*follow max branch? */
+ NULL, /*list */
+ H5F_istore_decode_key, /*decode */
+ H5F_istore_encode_key, /*encode */
+}};
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_sizeof_rkey
+ *
+ * Purpose: Returns the size of a raw key for the specified UDATA. The
+ * size of the key is dependent on the number of dimensions for
+ * the object to which this B-tree points. The dimensionality
+ * of the UDATA is the only portion that's referenced here.
+ *
+ * Return: Success: Size of raw key in bytes.
+ *
+ * Failure: abort()
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5F_istore_sizeof_rkey (H5F_t *f, const void *_udata)
+{
+ const H5F_istore_ud1_t *udata = (const H5F_istore_ud1_t *)_udata;
+
+ assert (udata);
+ assert (udata->mesg.ndims>0 && udata->mesg.ndims<=H5O_ISTORE_NDIMS);
+
+ return udata->mesg.ndims * (4 + 4);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_decode_key
+ *
+ * Purpose: Decodes a raw key into a native key for the B-tree
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 10, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_istore_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
+{
+ H5F_istore_key_t *key = (H5F_istore_key_t *)_key;
+ int i;
+ int ndims = bt->sizeof_rkey / 8;
+
+ FUNC_ENTER (H5F_istore_decode_key, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (bt);
+ assert (raw);
+ assert (key);
+ assert (ndims>0 && ndims<=H5O_ISTORE_NDIMS && 8*ndims==bt->sizeof_rkey);
+
+ /* decode */
+ for (i=0; i<ndims; i++) {
+ UINT32DECODE (raw, key->offset[i]);
+ UINT32DECODE (raw, key->size[i]);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_encode_key
+ *
+ * Purpose: Encode a key from native format to raw format.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 10, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
+{
+ H5F_istore_key_t *key = (H5F_istore_key_t *)_key;
+ intn ndims = bt->sizeof_rkey / 8;
+ intn i;
+
+ FUNC_ENTER (H5F_istore_encode_key, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (bt);
+ assert (raw);
+ assert (key);
+ assert (ndims>0 && ndims<=H5O_ISTORE_NDIMS && 8*ndims==bt->sizeof_rkey);
+
+ /* encode */
+ for (i=0; i<ndims; i++) {
+ UINT32ENCODE (raw, key->offset[i]);
+ UINT32ENCODE (raw, key->size[i]);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_cmp
+ *
+ * Purpose: Compare the requested datum UDATA with the left and right
+ * keys of the B-tree.
+ *
+ * Return: Success: negative if the min_corner of UDATA is less
+ * than the min_corner of LT_KEY.
+ *
+ * positive if the min_corner of UDATA is
+ * greater than or equal the min_corner of
+ * RT_KEY.
+ *
+ * zero otherwise. The min_corner of UDATA is
+ * not necessarily contained within the address
+ * space represented by LT_KEY, but a key that
+ * would describe the UDATA min_corner address
+ * would fall lexicographically between LT_KEY
+ * and RT_KEY.
+ *
+ * Failure: FAIL (same as UDATA < LT_KEY)
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static intn
+H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
+{
+ H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
+ H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
+ H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
+
+ assert (lt_key);
+ assert (rt_key);
+ assert (udata);
+ assert (udata->mesg.ndims>0 && udata->mesg.ndims<=H5O_ISTORE_NDIMS);
+
+ if (H5V_vector_lt (udata->mesg.ndims, udata->key.offset, lt_key->offset)) {
+ return -1;
+ } else if (H5V_vector_ge (udata->mesg.ndims, udata->key.offset,
+ rt_key->offset)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_new
+ *
+ * Purpose: Adds a new entry to an i-storage B-tree. We can assume that
+ * the domain represented by UDATA doesn't intersect the domain
+ * already represented by the B-tree.
+ *
+ * Return: Success: Address of leaf, which is passed in from the
+ * UDATA pointer.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, October 14, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static haddr_t
+H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
+{
+ H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
+ H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
+ H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
+ size_t nbytes;
+ intn i;
+
+ FUNC_ENTER (H5F_istore_new, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (lt_key);
+ assert (rt_key);
+ assert (udata);
+ assert (udata->mesg.ndims>=0 && udata->mesg.ndims<H5O_ISTORE_NDIMS);
+
+ /* Allocate new storage */
+ nbytes = H5V_vector_reduce_product (udata->mesg.ndims, udata->key.size);
+ assert (nbytes>0);
+ if ((udata->addr=H5MF_alloc (f, nbytes))<0) {
+ /* Couldn't allocate new file storage */
+ HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
+ }
+
+ /* left key describes the UDATA, right key is a zero-size "edge" */
+ for (i=0; i<udata->mesg.ndims; i++) {
+ lt_key->offset[i] = udata->key.offset[i];
+ lt_key->size[i] = udata->key.size[i];
+ assert (udata->key.size[i]>0);
+
+ rt_key->offset[i] = udata->key.offset[i] + udata->key.size[i];
+ rt_key->size[i] = 0;
+ }
+
+
+ FUNC_LEAVE (udata->addr);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_found
+ *
+ * Purpose: This function is called when the B-tree search engine has
+ * found the leaf entry that points to a chunk of storage that
+ * contains the beginning of the logical address space
+ * represented by UDATA. The LT_KEY is the left key (the one
+ * that describes the chunk) and RT_KEY is the right key (the
+ * one that describes the next or last chunk).
+ *
+ * Return: Success: SUCCEED with information about the chunk
+ * returned through the UDATA argument.
+ *
+ * Failure: FAIL if not found.
+ *
+ * Programmer: Robb Matzke
+ * Thursday, October 9, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_key,
+ void *_udata, const void *_rt_key)
+{
+ H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
+ const H5F_istore_key_t *lt_key = (const H5F_istore_key_t *)_lt_key;
+ const H5F_istore_key_t *rt_key = (const H5F_istore_key_t *)_rt_key;
+ int i;
+
+ FUNC_ENTER (H5F_istore_found, NULL, FAIL);
+
+ /* Check arguments */
+ assert (f);
+ assert (addr>=0);
+ assert (udata);
+ assert (lt_key);
+ assert (rt_key);
+
+ /* Initialize return values */
+ udata->addr = addr;
+ for (i=0; i<udata->mesg.ndims; i++) {
+ udata->key.offset[i] = lt_key->offset[i];
+ udata->key.size[i] = lt_key->size[i];
+ assert (lt_key->size[i]>0);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_insert
+ *
+ * Purpose: This function is called when the B-tree insert engine finds
+ * the node to use to insert new data. The UDATA argument
+ * points to a struct that describes the logical addresses being
+ * added to the file. This function allocates space for the
+ * data and returns information through UDATA describing a
+ * file chunk to receive (part of) the data.
+ *
+ * The LT_KEY is always the key describing the chunk of file
+ * memory at address ADDR. On entry, UDATA describes the logical
+ * addresses for which storage is being requested (through the
+ * `offset' and `size' fields). On return, UDATA describes the
+ * logical addresses contained in a chunk on disk.
+ *
+ * Return: Success: SUCCEED, with UDATA containing information
+ * about the (newly allocated) chunk.
+ *
+ * If the storage address has changed then the
+ * new address is returned.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, October 9, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static haddr_t
+H5F_istore_insert (H5F_t *f, haddr_t addr, H5B_ins_t *parent_ins,
+ void *_lt_key, hbool_t *lt_key_changed,
+ void *_md_key, void *_udata,
+ void *_rt_key, hbool_t *rt_key_changed)
+{
+ H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
+ H5F_istore_key_t *md_key = (H5F_istore_key_t *)_md_key;
+ H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
+ H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
+ intn i, cmp;
+ haddr_t ret_value = 0;
+ size_t nbytes;
+
+ FUNC_ENTER (H5F_istore_insert, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (addr>=0);
+ assert (parent_ins);
+ assert (lt_key);
+ assert (lt_key_changed);
+ assert (md_key);
+ assert (udata);
+ assert (rt_key);
+ assert (rt_key_changed);
+
+ cmp = H5F_istore_cmp (f, lt_key, udata, rt_key);
+ assert (cmp<=0);
+
+ if (cmp<0) {
+ /* Negative indices not supported yet */
+ assert ("HDF5 INTERNAL ERROR -- see rpm" && 0);
+ HRETURN_ERROR (H5E_STORAGE, H5E_UNSUPPORTED, FAIL);
+
+ } else if (H5V_hyper_eq (udata->mesg.ndims,
+ udata->key.offset, udata->key.size,
+ lt_key->offset, lt_key->size)) {
+ /*
+ * Already exists. Just return the info.
+ */
+ udata->addr = addr;
+ *parent_ins = H5B_INS_NOOP;
+
+ } else if (H5V_hyper_disjointp (udata->mesg.ndims,
+ lt_key->offset, lt_key->size,
+ udata->key.offset, udata->key.size)) {
+ assert (H5V_hyper_disjointp (udata->mesg.ndims,
+ rt_key->offset, rt_key->size,
+ udata->key.offset, udata->key.size));
+
+ /*
+ * Split this node, inserting the new new node to the right of the
+ * current node. The MD_KEY is where the split occurs.
+ */
+ for (i=0, nbytes=1; i<udata->mesg.ndims; i++) {
+ assert (0==udata->key.offset[i] % udata->mesg.alignment[i]);
+ assert (udata->key.size[i] == udata->mesg.alignment[i]);
+ md_key->offset[i] = udata->key.offset[i];
+ md_key->size[i] = udata->key.size[i];
+ nbytes *= udata->key.size[i];
+ }
+
+ /*
+ * Allocate storage for the new chunk
+ */
+ if ((udata->addr=ret_value=H5MF_alloc (f, nbytes))<=0) {
+ HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
+ }
+
+ *parent_ins = H5B_INS_RIGHT;
+
+ } else {
+ assert ("HDF5 INTERNAL ERROR -- see rpm" && 0);
+ HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL);
+ }
+
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_copy_hyperslab
+ *
+ * Purpose: Reads or writes a hyperslab to disk depending on whether OP
+ * is H5F_ISTORE_READ or H5F_ISTORE_WRITE. The hyperslab
+ * storage is described with ISTORE and exists in file F. The
+ * file hyperslab begins at location OFFSET_F[] (an N-dimensional
+ * point in the domain in terms of elements) in the file and
+ * OFFSET_M[] in memory pointed to by BUF. Its size is SIZE[]
+ * elements. The dimensionality of memory is assumed to be the
+ * same as the file and the total size of the multi-dimensional
+ * memory buffer is SIZE_M[].
+ *
+ * The slowest varying dimension is always listed first in the
+ * various offset and size arrays.
+ *
+ * A `chunk' is a hyperslab of the disk array which is stored
+ * contiguously. I/O occurs in units of chunks where the size of
+ * a chunk is determined by the alignment constraints specified
+ * in ISTORE.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 17, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore, H5F_isop_t op,
+ size_t offset_f[], size_t size[],
+ size_t offset_m[], size_t size_m[], void *buf)
+{
+ intn i, carry;
+ size_t idx_cur[H5O_ISTORE_NDIMS];
+ size_t idx_min[H5O_ISTORE_NDIMS];
+ size_t idx_max[H5O_ISTORE_NDIMS];
+ size_t sub_size[H5O_ISTORE_NDIMS];
+ size_t sub_offset_f[H5O_ISTORE_NDIMS];
+ size_t sub_offset_m[H5O_ISTORE_NDIMS];
+ size_t sub_offset_ch[H5O_ISTORE_NDIMS];
+ size_t chunk_size;
+ uint8 *chunk=NULL;
+ H5F_istore_ud1_t udata;
+ herr_t status;
+ herr_t ret_value = FAIL;
+
+ FUNC_ENTER (H5F_istore_copy_hyperslab, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (istore);
+ assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
+ assert (H5F_ISTORE_READ==op || H5F_ISTORE_WRITE==op);
+ assert (size);
+ assert (size_m);
+ assert (buf);
+#ifndef NDEBUG
+ for (i=0; i<istore->ndims; i++) {
+ assert (!offset_f || offset_f[i]>=0);/*neg domains unsupported */
+ assert (!offset_m || offset_m[i]>=0);/*mem array offset never neg */
+ assert (size[i]>=0); /*size may be zero, implies no-op */
+ assert (size_m[i]>0); /*destination must exist */
+ /*hyperslab must fit in BUF*/
+ assert ((offset_m?offset_m[i]:0)+size[i]<=size_m[i]);
+ assert (istore->alignment[i]>0);
+ }
+#endif
+
+ /*
+ * Does the B-tree exist?
+ */
+ if (istore->btree_addr<=0) {
+ if (H5F_ISTORE_WRITE==op) {
+ udata.mesg.ndims = istore->ndims;
+ if ((istore->btree_addr=H5B_new (f, H5B_ISTORE, &udata))<0) {
+ /* Can't create B-tree */
+ HGOTO_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
+ }
+ } else {
+ H5V_hyper_fill (istore->ndims, size, size_m, offset_m, buf, 0);
+ HRETURN (SUCCEED);
+ }
+ }
+
+ /* Initialize indices */
+ for (i=0; i<istore->ndims; i++) {
+ idx_min[i] = (offset_f?offset_f[i]:0) / istore->alignment[i];
+ idx_max[i] = ((offset_f?offset_f[i]:0)+size[i]-1)/istore->alignment[i]+1;
+ idx_cur[i] = idx_min[i];
+ }
+
+ /* Allocate buffers */
+ for (i=0, chunk_size=1; i<istore->ndims; i++) {
+ chunk_size *= istore->alignment[i];
+ }
+ chunk = H5MM_xmalloc (chunk_size);
+
+ /* Initialize non-changing part of udata */
+ udata.mesg = *istore;
+
+ /* Loop over all chunks */
+ while (1) {
+
+ /* Read/Write chunk or create it if it doesn't exist */
+ udata.mesg.ndims = istore->ndims;
+ for (i=0; i<istore->ndims; i++) {
+ udata.key.offset[i] = idx_cur[i] * istore->alignment[i];
+ udata.key.size[i] = istore->alignment[i];
+ sub_offset_f[i] = MAX ((offset_f?offset_f[i]:0), udata.key.offset[i]);
+ sub_offset_m[i] = (offset_m?offset_m[i]:0) +
+ sub_offset_f[i] - (offset_f?offset_f[i]:0);
+ sub_size[i] = (idx_cur[i]+1)*istore->alignment[i]-sub_offset_f[i];
+ sub_offset_ch[i] = sub_offset_f[i] - udata.key.offset[i];
+ }
+ if (H5F_ISTORE_WRITE==op) {
+ status = H5B_insert (f, H5B_ISTORE, istore->btree_addr, &udata);
+ assert (status>=0);
+ } else {
+ status = H5B_find (f, H5B_ISTORE, istore->btree_addr, &udata);
+ }
+
+ /*
+ * If the operation is reading from the disk or if we are writing a
+ * partial chunk then load the chunk from disk.
+ */
+ if (H5F_ISTORE_READ==op ||
+ !H5V_hyper_eq (istore->ndims,
+ udata.key.offset, udata.key.size,
+ sub_offset_f, sub_size)) {
+ if (status>=0) {
+ if (H5F_block_read (f, udata.addr, chunk_size, chunk)<0) {
+ HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL);
+ }
+ } else {
+ HDmemset (chunk, 0, chunk_size);
+ }
+ }
+
+ /* Transfer data to/from the chunk */
+ if (H5F_ISTORE_WRITE==op) {
+ H5V_hyper_copy (istore->ndims, sub_size,
+ udata.key.size, sub_offset_ch, chunk,
+ size_m, sub_offset_m, buf);
+ if (H5F_block_write (f, udata.addr, chunk_size, chunk)<0) {
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL);
+ }
+ } else {
+ H5V_hyper_copy (istore->ndims, sub_size,
+ size_m, sub_offset_m, buf,
+ udata.key.size, sub_offset_ch, chunk);
+ }
+
+ /* Increment indices */
+ for (i=istore->ndims-1, carry=1; i>=0 && carry; --i) {
+ if (++idx_cur[i]>=idx_max[i]) idx_cur[i] = idx_min[i];
+ else carry = 0;
+ }
+ if (carry) break;
+ }
+ ret_value = SUCCEED;
+
+
+ done:
+ chunk = H5MM_xfree (chunk);
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_read
+ *
+ * Purpose: Reads a multi-dimensional buffer from (part of) an indexed raw
+ * storage array.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 15, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_istore_read (H5F_t *f, struct H5O_istore_t *istore,
+ size_t offset[], size_t size[], void *buf)
+{
+ FUNC_ENTER (H5F_istore_read, NULL, FAIL);
+
+ /* Check args */
+ assert (f);
+ assert (istore);
+ assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
+ assert (size);
+ assert (buf);
+
+ if (H5F_istore_copy_hyperslab (f, istore, H5F_ISTORE_READ,
+ offset, size, H5V_ZERO, size, buf)<0) {
+ /* hyperslab output failure */
+ HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_write
+ *
+ * Purpose: Writes a multi-dimensional buffer to (part of) an indexed raw
+ * storage array.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 15, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_istore_write (H5F_t *f, struct H5O_istore_t *istore,
+ size_t offset[], size_t size[], void *buf)
+{
+ FUNC_ENTER (H5F_istore_write, NULL, FAIL);
+
+ /* Check args */
+ assert (f);
+ assert (istore);
+ assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
+ assert (size);
+ assert (buf);
+
+ if (H5F_istore_copy_hyperslab (f, istore, H5F_ISTORE_WRITE,
+ offset, size, H5V_ZERO, size, buf)<0) {
+ /* hyperslab output failure */
+ HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 81f43ce..0d0a65c 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -20,7 +20,7 @@
#define _H5Fprivate_H
#include <H5Fpublic.h>
-/* Private headers needed by this file */
+/* This is a near top-level header! Try not to include much! */
#include <H5private.h>
/* Maximum size of boot-block buffer */
@@ -397,6 +397,7 @@ typedef struct H5F_t {
uintn intent; /* The flags passed to H5F_open() */
char *name; /* Name used to open file */
H5F_file_t *shared; /* The shared file info */
+ struct H5G_cwgstk_t *cwg_stack; /* CWG stack for push/pop functions */
} H5F_t;
@@ -446,12 +447,20 @@ typedef struct H5F_t {
case 2: UINT16DECODE(p,l); break; \
}
+struct H5O_istore_t; /*forward decl for prototype arguments*/
/* Private functions, not part of the publicly documented API */
void H5F_encode_length_unusual(const H5F_t *f, uint8 **p, uint8 *l);
void H5F_encode_offset_unusual(const H5F_t *f, uint8 **p, uint8 *o);
+H5F_t *H5F_open (const char *name, uintn flags,
+ const file_create_temp_t *create_parms);
+herr_t H5F_close (H5F_t *f);
herr_t H5F_block_read (H5F_t *f, haddr_t addr, size_t size, void *buf);
herr_t H5F_block_write (H5F_t *f, haddr_t addr, size_t size, void *buf);
+herr_t H5F_istore_read (H5F_t *f, struct H5O_istore_t *mesg,
+ size_t offset[], size_t size[], void *buf);
+herr_t H5F_istore_write (H5F_t *f, struct H5O_istore_t *mesg,
+ size_t offset[], size_t size[], void *buf);
herr_t H5F_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
intn fwidth);
diff --git a/src/H5G.c b/src/H5G.c
index efb7389..c251b14 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -10,15 +10,15 @@
*
* Purpose: Symbol table functions. The functions that
* begin with `H5G_stab_' don't understand the
- * directory hierarchy; they operate on a single
+ * naming system; they operate on a single
* symbol table at a time.
*
* The functions that begin with `H5G_node_' operate
* on the leaf nodes of a symbol table B-tree. They
* should be defined in the H5Gnode.c file.
*
- * The remaining functions know about the directory
- * hierarchy.
+ * The remaining functions know how to traverse the
+ * group directed graph
*
* Modifications:
*
@@ -53,6 +53,266 @@ static hbool_t interface_initialize_g = FALSE;
/*-------------------------------------------------------------------------
+ * Function: H5Gnew
+ *
+ * Purpose: Creates a new group in FILE and gives it the specified
+ * NAME. Unless NAME begins with `/' it is relative to the
+ * current working group.
+ *
+ * The optional SIZE_HINT specifies how much file space to
+ * reserve to store the names that will appear in this
+ * group (an even number of characters, counting the null
+ * terminator, is allocated for each name). If a non-positive
+ * value is supplied for the SIZE_HINT then a default size is
+ * chosen.
+ *
+ * See also: H5Gset(), H5Gpush(), H5Gpop()
+ *
+ * Errors:
+ * ARGS BADTYPE Not a file atom.
+ * ARGS BADVALUE No name given.
+ * ATOM BADATOM Can't unatomize file.
+ * SYM CANTINIT Can't close handle.
+ * SYM CANTINIT Can't create group.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, September 24, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Gnew (hid_t file, const char *name, size_t size_hint)
+{
+ H5F_t *f=NULL;
+ H5G_entry_t *grp_handle=NULL;
+
+ FUNC_ENTER (H5Gnew, NULL, FAIL);
+
+ /* Check/fix arguments */
+ if (!name || !*name) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL);/*no name given*/
+ }
+ if (H5_FILE!=H5Aatom_group (file)) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL);/*not a file atom*/
+ }
+ if (NULL==(f=H5Aatom_object (file))) {
+ HRETURN_ERROR (H5E_ATOM, H5E_BADATOM, FAIL);/*can't unatomize file*/
+ }
+
+ /* Create the group */
+ if (NULL==(grp_handle=H5G_new (f, name, size_hint))) {
+ /*can't create group*/
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
+
+ /* Close the group handle */
+ if (H5G_close (f, grp_handle)<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);/*can't close handle*/
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gset
+ *
+ * Purpose: Sets the working group for file handle FILE to the
+ * specified NAME. Unless NAME begins with a `/' it is
+ * interpretted relative to the current working group.
+ *
+ * Each file handle maintains its own notion of the current
+ * working group. That is, if a single file is opened with
+ * multiple calls to H5Fopen(), which returns multiple file
+ * handles, then each handle's current working group can be
+ * set independently of the other file handles for that file.
+ *
+ * See also: H5Gpush(), H5Gpop()
+ *
+ * Errors:
+ * ARGS BADTYPE Not a file atom.
+ * ARGS BADVALUE No name given.
+ * ATOM BADATOM Can't unatomize file.
+ * SYM CANTINIT Can't change current working group.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, September 24, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Gset (hid_t file, const char *name)
+{
+ H5F_t *f=NULL;
+
+ FUNC_ENTER (H5Gset, NULL, FAIL);
+
+ /* Check/fix arguments */
+ if (!name || !*name) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL);/*no name given*/
+ }
+ if (H5_FILE!=H5Aatom_group (file)) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL);/*not a file atom*/
+ }
+ if (NULL==(f=H5Aatom_object (file))) {
+ HRETURN_ERROR (H5E_ATOM, H5E_BADATOM, FAIL);/*can't unatomize file*/
+ }
+
+ if (H5G_set (f, name)<0) {
+ /* Can't change current working group */
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gpush
+ *
+ * Purpose: Similar to H5Gset() except the new working group is pushed
+ * on a stack.
+ *
+ * Each file handle maintains its own notion of the current
+ * working group. That is, if a single file is opened with
+ * multiple calls to H5Fopen(), which returns multiple file
+ * handles, then each handle's current working group can be
+ * set independently of the other file handles for that file.
+ *
+ * See also: H5Gset(), H5Gpop()
+ *
+ * Errors:
+ * ARGS BADTYPE Not a file atom.
+ * ARGS BADVALUE No name given.
+ * ATOM BADATOM Can't unatomize file.
+ * SYM CANTINIT Can't change current working group.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, September 24, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Gpush (hid_t file, const char *name)
+{
+ H5F_t *f=NULL;
+
+ FUNC_ENTER (H5Gpush, NULL, FAIL);
+
+ /* Check/fix arguments */
+ if (!name || !*name) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL);/*no name given*/
+ }
+ if (H5_FILE!=H5Aatom_group (file)) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL);/*not a file atom*/
+ }
+ if (NULL==(f=H5Aatom_object (file))) {
+ HRETURN_ERROR (H5E_ATOM, H5E_BADATOM, FAIL);/*can't unatomize file*/
+ }
+
+ if (H5G_push (f, name)<0) {
+ /* Can't change current working group */
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gpop
+ *
+ * Purpose: Removes the top (latest) entry from the working group stack
+ * and sets the current working group to the previous value.
+ *
+ * Each file handle maintains its own notion of the current
+ * working group. That is, if a single file is opened with
+ * multiple calls to H5Fopen(), which returns multiple file
+ * handles, then each handle's current working group can be
+ * set independently of the other file handles for that file.
+ *
+ * See also: H5Gset(), H5Gpush()
+ *
+ * Errors:
+ * ARGS BADTYPE Not a file atom.
+ * ATOM BADATOM Can't unatomize file.
+ * SYM CANTINIT Stack is empty.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL. The final entry cannot be popped from
+ * the group stack (but it can be changed
+ * with H5Gset()).
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, September 24, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Gpop (hid_t file)
+{
+ H5F_t *f=NULL;
+
+ FUNC_ENTER (H5Gpop, NULL, FAIL);
+
+ /* Check/fix arguments */
+ if (H5_FILE!=H5Aatom_group (file)) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL);/*not a file atom*/
+ }
+ if (NULL==(f=H5Aatom_object (file))) {
+ HRETURN_ERROR (H5E_ATOM, H5E_BADATOM, FAIL);/*can't unatomize file*/
+ }
+
+ if (H5G_pop (f)<0) {
+ /* Stack is empty */
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+
+
+/*
+ *-------------------------------------------------------------------------
+ *-------------------------------------------------------------------------
+ * N O A P I F U N C T I O N S B E Y O N D T H I S P O I N T
+ *-------------------------------------------------------------------------
+ *-------------------------------------------------------------------------
+ */
+
+
+
+
+
+
+
+/*-------------------------------------------------------------------------
* Function: H5G_component
*
* Purpose: Returns the pointer to the first component of the
@@ -67,7 +327,7 @@ static hbool_t interface_initialize_g = FALSE;
* Failure: Ptr to the null terminator of NAME.
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 11 1997
*
* Modifications:
@@ -102,7 +362,7 @@ H5G_component (const char *name, size_t *size_p)
* Failure: Ptr to the null terminator of NAME.
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 11 1997
*
* Modifications:
@@ -122,7 +382,7 @@ H5G_basename (const char *name, size_t *size_p)
while (s>name && '/'!=s[-1]) --s; /*skip past base name*/
/*
- * If the input was the name of the root directory `/' (or
+ * If the input was the name of the root group `/' (or
* equivalent) then return the null string.
*/
if ('/'==*s) {
@@ -142,42 +402,43 @@ H5G_basename (const char *name, size_t *size_p)
* Purpose: (Partially) translates a name to a symbol table entry.
*
* Given a name (absolute or relative) return the symbol table
- * entry for that name and for the directory that contains the
- * base name. These entries (DIR_ENT and BASE_ENT) are returned
+ * entry for that name and for the group that contains the
+ * base name. These entries (GRP_ENT and BASE_ENT) are returned
* through memory passed into the function by the caller. Either
* or both pointers may be null. Absolute names are looked up
- * relative to the root directory of file F while relative
- * names are traversed beginning at the CWD argument.
+ * relative to the root group of file F while relative
+ * names are traversed beginning at the CWG argument.
*
* Consecutive slash characters are treated like single
* slash characters. Trailing slashes are ignored. The
- * component `.' is recognized as the current directory
- * during the traversal (initially CWD), but the component
+ * component `.' is recognized as the current group
+ * during the traversal (initially CWG), but the component
* `..' is not internally recognized (it is recognized if
* such a name appears in the symbol table).
*
* If the name cannot be fully resolved, then REST will
* point to the part of NAME where the traversal failed
* (REST will always point to a relative name) and this
- * function will return null. DIR_ENT will be initialized with
- * information about the directory (or other object) at which
+ * function will return null. GRP_ENT will be initialized with
+ * information about the group (or other object) at which
* the traversal failed. However, if the name can be fully
* resolved, then REST points to the null terminator of NAME.
*
* As a special case, if the NAME is the name `/' (or
- * equivalent) then DIR_ENT is initialized to all zero
+ * equivalent) then GRP_ENT is initialized to all zero
* and a pointer to the root symbol table entry is returned.
*
* As a special case, if the NAME is the string `/foo' (or
* equivalent) and the root symbol table entry points to a
- * non-directory object with a name message with the value
- * `foo' then DIR_ENT is initialized to all zero and a pointer
+ * non-group object with a name message with the value
+ * `foo' then GRP_ENT is initialized to all zero and a pointer
* to the root symbol table entry is returned.
*
* Errors:
- * DIRECTORY COMPLEN Component is too long.
- * DIRECTORY NOTFOUND Component not found.
- * DIRECTORY NOTFOUND Root not found.
+ * SYM COMPLEN Component is too long.
+ * SYM NOTFOUND Component not found.
+ * SYM NOTFOUND No root group.
+ * SYM NOTFOUND Root not found.
*
* Return: Success: Pointer to a cached symbol table entry if the
* name can be fully resolved. The pointer is
@@ -185,11 +446,11 @@ H5G_basename (const char *name, size_t *size_p)
* is called.
*
* Failure: Null if the name could not be fully resolved.
- * REST and DIR_ENT are initialized (possibly to
+ * REST and GRP_ENT are initialized (possibly to
* zero if the failure occurred soon enough).
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 11 1997
*
* Modifications:
@@ -197,10 +458,10 @@ H5G_basename (const char *name, size_t *size_p)
*-------------------------------------------------------------------------
*/
static H5G_entry_t *
-H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
- const char **rest, H5G_entry_t *dir_ent)
+H5G_namei (H5F_t *f, H5G_entry_t *cwg, const char *name,
+ const char **rest, H5G_entry_t *grp_ent)
{
- H5G_entry_t dir; /*entry for current directory */
+ H5G_entry_t grp; /*entry for current group */
size_t nchars; /*component name length */
char comp[1024]; /*component name buffer */
hbool_t aside = FALSE; /*did we look at a name message?*/
@@ -208,7 +469,7 @@ H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
/* clear output args before FUNC_ENTER() in case it fails */
if (rest) *rest = name;
- if (dir_ent) memset (dir_ent, 0, sizeof(H5G_entry_t));
+ if (grp_ent) memset (grp_ent, 0, sizeof(H5G_entry_t));
FUNC_ENTER (H5G_namei, NULL, NULL);
@@ -216,18 +477,19 @@ H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
assert (f);
assert (f->shared->root_sym);
assert (name && *name);
- assert (cwd || '/'==*name);
+ assert (cwg || '/'==*name);
/* starting point */
if ('/'==*name) {
if (f->shared->root_sym->header<=0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL);
+ /* No root group */
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL);
}
ret_value = f->shared->root_sym;
- dir = *(f->shared->root_sym);
+ grp = *(f->shared->root_sym);
} else {
- ret_value = cwd;
- dir = *cwd;
+ ret_value = cwg;
+ grp = *cwg;
}
/* traverse the name */
@@ -241,7 +503,7 @@ H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
/*
* Advance to the next component of the name.
*/
- dir = *ret_value;
+ grp = *ret_value;
ret_value = NULL;
if (rest) *rest = name;
@@ -251,23 +513,23 @@ H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
*/
if (nchars+1 > sizeof(comp)) {
/* component is too long */
- if (dir_ent) *dir_ent = dir;
- HRETURN_ERROR (H5E_DIRECTORY, H5E_COMPLEN, NULL);
+ if (grp_ent) *grp_ent = grp;
+ HRETURN_ERROR (H5E_SYM, H5E_COMPLEN, NULL);
}
HDmemcpy (comp, name, nchars);
comp[nchars] = '\0';
- if (NULL==(ret_value=H5G_stab_find (f, NO_ADDR, &dir, comp))) {
+ if (NULL==(ret_value=H5G_stab_find (f, NO_ADDR, &grp, comp))) {
/*
* Component was not found in the current symbol table, possibly
- * because DIR isn't a symbol table. If it is the root symbol then
+ * because GRP isn't a symbol table. If it is the root symbol then
* see if it has the appropriate name field. The ASIDE variable
* prevents us from saying `/foo/foo' where the root object has
* the name `foo'.
*/
H5O_name_t mesg={0};
- if (!aside && dir.header==f->shared->root_sym->header &&
- H5O_read (f, dir.header, &dir, H5O_NAME, 0, &mesg) &&
+ if (!aside && grp.header==f->shared->root_sym->header &&
+ H5O_read (f, grp.header, &grp, H5O_NAME, 0, &mesg) &&
!HDstrcmp (mesg.s, comp)) {
H5O_reset (H5O_NAME, &mesg);
ret_value = f->shared->root_sym;
@@ -275,8 +537,8 @@ H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
} else {
/* component not found */
H5O_reset (H5O_NAME, &mesg);
- if (dir_ent) *dir_ent = dir;
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL);
+ if (grp_ent) *grp_ent = grp;
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL);
}
}
@@ -286,17 +548,17 @@ H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
/* output parameters */
if (rest) *rest = name; /*final null*/
- if (dir_ent) {
+ if (grp_ent) {
if (ret_value->header == f->shared->root_sym->header) {
- HDmemset (dir_ent, 0, sizeof(H5G_entry_t)); /*root has no parent*/
+ HDmemset (grp_ent, 0, sizeof(H5G_entry_t)); /*root has no parent*/
} else {
- *dir_ent = dir;
+ *grp_ent = grp;
}
}
/* Perhaps the root object doesn't even exist! */
if (ret_value->header<=0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL); /*root not found*/
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL); /*root not found*/
}
FUNC_LEAVE (ret_value);
@@ -306,10 +568,10 @@ H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
/*-------------------------------------------------------------------------
* Function: H5G_mkroot
*
- * Purpose: Creates the root directory if it doesn't exist; otherwise
+ * Purpose: Creates the root group if it doesn't exist; otherwise
* nothing happens. If the root symbol table entry previously
- * pointed to something other than a directory, then that object
- * is made a member of the root directory and is given a name
+ * pointed to something other than a group, then that object
+ * is made a member of the root group and is given a name
* corresponding to the object's name message (the name message
* is removed). If the root object doesn't have a name message
* then the name `Root Object' is used.
@@ -317,19 +579,21 @@ H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
* Warning: This function has a few subtleties. Be warned!
*
* Errors:
- * DIRECTORY CANTINIT Can't create root.
- * DIRECTORY CANTINIT Can't insert old root object in
- * new root directory.
- * DIRECTORY EXISTS Root directory already exists.
+ * SYM CANTINIT Can't open root object.
+ * SYM CANTINIT Can't reinsert old root object.
+ * SYM CANTINIT Cant create root.
+ * SYM EXISTS Root group already exists.
+ * SYM LINK Bad link count on old root object.
+ * SYM LINK Cant create root.
*
* Return: Success: SUCCEED
*
* Failure: FAIL. This function returns -2 if the
- * failure is because a root directory already
+ * failure is because a root group already
* exists.
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 11 1997
*
* Modifications:
@@ -356,20 +620,21 @@ H5G_mkroot (H5F_t *f, size_t size_hint)
/*
* If we already have a root object, then open it and get it's name. The
- * root object had better not already be a directory. Once the old root
+ * root object had better not already be a group. Once the old root
* object is opened and we have a HANDLE, set the dirty bit on the handle.
* This causes the handle data to be written back into f->root_sym by
* H5G_close() if something goes wrong before the old root object is
- * re-inserted back into the directory hierarchy. We might leak file
+ * re-inserted back into the group directed graph. We might leak file
* memory, but at least we don't loose the original root object.
*/
if (f->shared->root_sym->header>0) {
if (H5O_read (f, NO_ADDR, f->shared->root_sym, H5O_STAB, 0, &stab)) {
- /* root directory already exists */
- HGOTO_ERROR (H5E_DIRECTORY, H5E_EXISTS, -2);
- } else if (NULL==(handle=H5G_shadow_open (f, NULL, f->shared->root_sym))) {
+ /* root group already exists */
+ HGOTO_ERROR (H5E_SYM, H5E_EXISTS, -2);
+ } else if (NULL==(handle=H5G_shadow_open (f, NULL,
+ f->shared->root_sym))) {
/* can't open root object */
- HGOTO_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL);
+ HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
} else if (NULL==H5O_read (f, NO_ADDR, handle, H5O_NAME, 0, &name)) {
obj_name = "Root Object";
} else {
@@ -379,15 +644,15 @@ H5G_mkroot (H5F_t *f, size_t size_hint)
}
/*
- * Create the new root directory directly into the file descriptor. If
+ * Create the new root group directly into the file descriptor. If
* something goes wrong at this step, closing the `handle' will rewrite
* info back into f->root_sym because we set the dirty bit.
*/
if (H5G_stab_new (f, f->shared->root_sym, size_hint)<0) {
- HGOTO_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL); /*cant create root*/
+ HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*cant create root*/
}
if (1!=H5O_link (f, f->shared->root_sym, 1)) {
- HGOTO_ERROR (H5E_DIRECTORY, H5E_LINK, FAIL);
+ HGOTO_ERROR (H5E_SYM, H5E_LINK, FAIL);
}
/*
@@ -397,11 +662,13 @@ H5G_mkroot (H5F_t *f, size_t size_hint)
*/
if (obj_name) {
if (1!=H5O_link (f, handle, 0)) {
- HGOTO_ERROR (H5E_DIRECTORY, H5E_LINK, FAIL);
+ /* Bad link count on old root object */
+ HGOTO_ERROR (H5E_SYM, H5E_LINK, FAIL);
}
if (NULL==(ent_ptr=H5G_stab_insert (f, f->shared->root_sym, obj_name,
handle))) {
- HGOTO_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL);
+ /* Can't reinsert old root object */
+ HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
}
/*
@@ -418,10 +685,10 @@ H5G_mkroot (H5F_t *f, size_t size_hint)
done:
/*
* If the handle is closed before the H5G_stab_insert() call that
- * reinserts the root object into the directory hierarchy, then
+ * reinserts the root object into the group directed graph, then
* H5G_close() will reset f->root_sym to point to the old root symbol and
- * the new root directory (if it was created) will be unlinked from the
- * directory hierarchy (and memory leaked).
+ * the new root group (if it was created) will be unlinked from the
+ * group directed graph (and memory leaked).
*/
if (handle) H5G_close (f, handle);
H5O_reset (H5O_NAME, &name);
@@ -431,32 +698,33 @@ H5G_mkroot (H5F_t *f, size_t size_hint)
/*-------------------------------------------------------------------------
- * Function: H5G_mkdir
+ * Function: H5G_new
*
- * Purpose: Creates a new empty directory with the specified name,
+ * Purpose: Creates a new empty group with the specified name,
* opening it as an object. The name is either an absolute name
- * or is relative to the current working directory.
+ * or is relative to the current working group.
*
- * A root directory is created implicitly by this function
+ * A root group is created implicitly by this function
* when necessary. Calling this function with the name "/"
* (or any equivalent name) will result in an H5E_EXISTS
* failure.
*
* Errors:
- * DIRECTORY CANTINIT Can't create dir.
- * DIRECTORY CANTINIT Can't insert.
- * DIRECTORY CANTINIT Lookup failed.
- * DIRECTORY COMPLEN Component is too long.
- * DIRECTORY EXISTS Already exists.
- * DIRECTORY NOTFOUND Missing component.
- *
- * Return: Success: A handle to the open directory. Please call
+ * SYM CANTINIT Can't create grp.
+ * SYM CANTINIT Can't create root group.
+ * SYM CANTINIT Can't insert.
+ * SYM CANTINIT Can't open.
+ * SYM COMPLEN Component is too long.
+ * SYM EXISTS Already exists.
+ * SYM NOTFOUND Missing component.
+ *
+ * Return: Success: A handle to the open group. Please call
* H5G_close() when you're done with it.
*
* Failure: NULL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 11 1997
*
* Modifications:
@@ -464,42 +732,43 @@ H5G_mkroot (H5F_t *f, size_t size_hint)
*-------------------------------------------------------------------------
*/
H5G_entry_t *
-H5G_mkdir (H5F_t *f, const char *name, size_t size_hint)
+H5G_new (H5F_t *f, const char *name, size_t size_hint)
{
const char *rest=NULL; /*the base name */
- H5G_entry_t *cwd=NULL; /*current working directory */
- H5G_entry_t dir_ent; /*directory containing new dir */
- H5G_entry_t ent; /*new directory entry */
- H5G_entry_t *ent_ptr=NULL; /*ptr to new directory entry */
+ H5G_entry_t *cwg=NULL; /*current working group */
+ H5G_entry_t grp_ent; /*group containing new group */
+ H5G_entry_t ent; /*new group entry */
+ H5G_entry_t *ent_ptr=NULL; /*ptr to new group entry */
H5G_entry_t *ret_value=NULL; /*handle return value */
char _comp[1024]; /*name component */
size_t nchars; /*number of characters in compon*/
herr_t status; /*function return status */
- FUNC_ENTER (H5G_mkdir, NULL, NULL);
+ FUNC_ENTER (H5G_new, NULL, NULL);
/* check args */
assert (f);
assert (name && *name);
#ifndef LATER
- /* Get current working directory */
+ /* Get current working group */
H5G_shadow_sync (f->shared->root_sym);
- cwd = f->shared->root_sym;
+ cwg = f->shared->root_sym;
#endif
- assert (cwd || '/'==*name);
+ assert (cwg || '/'==*name);
/*
- * Try to create the root directory. Ignore the error if this function
- * fails because the root directory already exists.
+ * Try to create the root group. Ignore the error if this function
+ * fails because the root group already exists.
*/
if ((status=H5G_mkroot (f, H5G_SIZE_HINT))<0 && -2!=status) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ /* Can't create root group */
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL);
}
H5ECLEAR;
/* lookup name */
- if (H5G_namei (f, cwd, name, &rest, &dir_ent)) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, NULL); /*already exists*/
+ if (H5G_namei (f, cwg, name, &rest, &grp_ent)) {
+ HRETURN_ERROR (H5E_SYM, H5E_EXISTS, NULL); /*already exists*/
}
H5ECLEAR; /*it's OK that we didn't find it*/
@@ -509,10 +778,10 @@ H5G_mkdir (H5F_t *f, const char *name, size_t size_hint)
if (rest[nchars]) {
if (H5G_component (rest+nchars, NULL)) {
/* missing component */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL);
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL);
} else if (nchars+1 > sizeof _comp) {
/* component is too long */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_COMPLEN, NULL);
+ HRETURN_ERROR (H5E_SYM, H5E_COMPLEN, NULL);
} else {
/* null terminate */
HDmemcpy (_comp, rest, nchars);
@@ -521,19 +790,19 @@ H5G_mkdir (H5F_t *f, const char *name, size_t size_hint)
}
}
- /* create directory */
+ /* create group */
if (H5G_stab_new (f, &ent, size_hint)<0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't create dir*/
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL); /*can't create grp*/
}
/* insert child name into parent */
- if (NULL==(ent_ptr=H5G_stab_insert (f, &dir_ent, rest, &ent))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't insert*/
+ if (NULL==(ent_ptr=H5G_stab_insert (f, &grp_ent, rest, &ent))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL); /*can't insert*/
}
- /* open the directory */
- if (NULL==(ret_value=H5G_shadow_open (f, &dir_ent, ent_ptr))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't open*/
+ /* open the group */
+ if (NULL==(ret_value=H5G_shadow_open (f, &grp_ent, ent_ptr))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL); /*can't open*/
}
FUNC_LEAVE (ret_value);
@@ -542,9 +811,121 @@ H5G_mkdir (H5F_t *f, const char *name, size_t size_hint)
/*-------------------------------------------------------------------------
- * Function: H5G_pushd
+ * Function: H5G_set
+ *
+ * Purpose: Sets the current working group to be the specified name.
+ * This affects only the top item on the group stack for the
+ * specified file as accessed through this file handle. If the
+ * file is opened multiple times, then the current working group
+ * for this file handle is the only one that is changed.
*
- * Purpose: Pushes a new current working directory onto the stack.
+ * Errors:
+ * SYM CWG Can't open group.
+ * SYM CWG Couldn't close previous c.w.g.
+ * SYM CWG Not a group.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, September 24, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_set (H5F_t *f, const char *name)
+{
+ H5G_entry_t *handle=NULL;
+ H5O_stab_t stab_mesg;
+ herr_t ret_value=FAIL;
+
+ FUNC_ENTER (H5G_set, NULL, FAIL);
+
+ if (NULL==(handle=H5G_open (f, name))) {
+ /* Can't open group */
+ HGOTO_ERROR (H5E_SYM, H5E_CWG, FAIL);
+ }
+ if (NULL==H5O_read (f, NO_ADDR, handle, H5O_NAME, 0, &stab_mesg)) {
+ /* Not a group */
+ HGOTO_ERROR (H5E_SYM, H5E_CWG, FAIL);
+ }
+
+ /*
+ * If there is no stack then create one, otherwise close the current
+ * working group.
+ */
+ if (!f->cwg_stack) {
+ f->cwg_stack = H5MM_xcalloc (1, sizeof(H5G_cwgstk_t));
+ f->cwg_stack->handle = handle;
+ } else {
+ if (H5G_close (f, f->cwg_stack->handle)<0) {
+ /* Couldn't close previous c.w.g. */
+ HGOTO_ERROR (H5E_SYM, H5E_CWG, FAIL);
+ }
+ f->cwg_stack->handle = handle;
+ }
+ ret_value = SUCCEED;
+
+ done:
+ if (ret_value<0 && handle) {
+ H5G_close (f, handle);
+ }
+
+ FUNC_LEAVE (ret_value);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_getcwg
+ *
+ * Purpose: Returns a handle for the current working group. If there
+ * is no current working group then a pointer to the root
+ * symbol is returned but that object is not opened (and it
+ * might not even be a group).
+ *
+ * Return: Success: Ptr to open group handle with exceptions
+ * noted above.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, September 24, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5G_entry_t *
+H5G_getcwg (H5F_t *f)
+{
+ H5G_entry_t *handle=NULL;
+
+ FUNC_ENTER (H5G_getcwg, NULL, NULL);
+
+ if (f->cwg_stack && f->cwg_stack->handle) {
+ handle = f->cwg_stack->handle;
+ } else {
+ H5G_shadow_sync (f->shared->root_sym);
+ handle = f->shared->root_sym;
+ }
+
+ FUNC_LEAVE (handle);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_push
+ *
+ * Purpose: Pushes a new current working group onto the stack.
+ *
+ * Errors:
+ * SYM CWG Can't open group.
+ * SYM CWG Not a group.
*
* Return: Success: SUCCEED
*
@@ -558,31 +939,54 @@ H5G_mkdir (H5F_t *f, const char *name, size_t size_hint)
*-------------------------------------------------------------------------
*/
herr_t
-H5G_pushd (H5F_t *f, const char *name)
+H5G_push (H5F_t *f, const char *name)
{
+ H5G_entry_t *handle=NULL;
+ H5G_cwgstk_t *stack=NULL;
+ H5O_stab_t stab_mesg;
+ herr_t ret_value = FAIL;
+
FUNC_ENTER (H5G_pushd, NULL, FAIL);
-#ifndef LATER
+ if (NULL==(handle=H5G_open (f, name))) {
+ /* Can't open group */
+ HGOTO_ERROR (H5E_SYM, H5E_CWG, FAIL);
+ }
+ if (NULL==H5O_read (f, NO_ADDR, handle, H5O_NAME, 0, &stab_mesg)) {
+ /* Not a group */
+ HGOTO_ERROR (H5E_SYM, H5E_CWG, FAIL);
+ }
+
/*
- * Current working directories are not implemented yet.
+ * Push a new entry onto the stack.
*/
- if (strcmp (name, "/")) {
- HRETURN_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL);
+ stack = H5MM_xcalloc (1, sizeof(H5G_cwgstk_t));
+ stack->handle = handle;
+ stack->next = f->cwg_stack;
+ f->cwg_stack = stack;
+ ret_value = SUCCEED;
+
+ done:
+ if (ret_value<0 && handle) {
+ H5G_close (f, handle);
}
-#endif
-
+
FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
- * Function: H5G_popd
+ * Function: H5G_pop
*
- * Purpose: Pops the top current working directory off the stack.
+ * Purpose: Pops the top current working group off the stack.
+ *
+ * Errors:
+ * SYM CWG Can't close current working group.
+ * SYM CWG Stack is empty.
*
* Return: Success: SUCCEED
*
- * Failure: FAIL
+ * Failure: FAIL if the stack is empty.
*
* Programmer: Robb Matzke
* Friday, September 19, 1997
@@ -592,13 +996,24 @@ H5G_pushd (H5F_t *f, const char *name)
*-------------------------------------------------------------------------
*/
herr_t
-H5G_popd (H5F_t *f)
+H5G_pop (H5F_t *f)
{
- FUNC_ENTER (H5G_popd, NULL, FAIL);
+ H5G_cwgstk_t *stack=NULL;
+
+ FUNC_ENTER (H5G_pop, NULL, FAIL);
-#ifndef LATER
- /* CWD is not implemented yet. */
-#endif
+ if ((stack=f->cwg_stack)) {
+ if (H5G_close (f, stack->handle)<0) {
+ /* Can't close current working group */
+ HRETURN_ERROR (H5E_SYM, H5E_CWG, FAIL);
+ }
+ f->cwg_stack = stack->next;
+ stack->handle = NULL;
+ H5MM_xfree (stack);
+ } else {
+ /* Stack is empty */
+ HRETURN_ERROR (H5E_SYM, H5E_CWG, FAIL);
+ }
FUNC_LEAVE (SUCCEED);
}
@@ -612,6 +1027,21 @@ H5G_popd (H5F_t *f)
* object. The initial size of the object header can be
* supplied with the OHDR_HINT argument.
*
+ * Errors:
+ * SYM CANTINIT Bad link count.
+ * SYM CANTINIT Can't create header.
+ * SYM CANTINIT Can't create root group.
+ * SYM CANTINIT Can't insert.
+ * SYM CANTINIT Can't open object.
+ * SYM CANTINIT Cannot add/change name message.
+ * SYM CANTINIT Create the object header.
+ * SYM COMPLEN Component is too long.
+ * SYM EXISTS Already exists.
+ * SYM EXISTS Root exists.
+ * SYM LINK Bad link count.
+ * SYM LINK Link inc failure.
+ * SYM NOTFOUND Component not found.
+ *
* Return: Success: A handle for the object. Be sure to
* eventually close it.
*
@@ -629,9 +1059,9 @@ H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
{
H5G_entry_t ent; /*entry data for the new object */
H5G_entry_t *ent_ptr; /*ptr into symbol node for entry*/
- H5G_entry_t *cwd=NULL; /*ptr to CWD handle */
+ H5G_entry_t *cwg=NULL; /*ptr to c.w.g. handle */
const char *rest = NULL; /*part of name not existing yet */
- H5G_entry_t dir; /*entry for dir to contain obj */
+ H5G_entry_t grp; /*entry for group to contain obj*/
H5G_entry_t *ret_value=NULL; /*the object handle */
size_t nchars; /*number of characters in name */
char _comp[1024]; /*name component */
@@ -644,18 +1074,15 @@ H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
HDmemset (&ent, 0, sizeof(H5G_entry_t));
/*
- * Get the current working directory.
+ * Get the current working group.
*/
-#ifndef LATER
- H5G_shadow_sync (f->shared->root_sym);
- cwd = f->shared->root_sym;
-#endif
+ cwg = H5G_getcwg (f);
/*
* Look up the name -- it shouldn't exist yet.
*/
- if (H5G_namei (f, cwd, name, &rest, &dir)) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, NULL); /*already exists*/
+ if (H5G_namei (f, cwg, name, &rest, &grp)) {
+ HRETURN_ERROR (H5E_SYM, H5E_EXISTS, NULL); /*already exists*/
}
H5ECLEAR; /*it's OK that we didn't find it*/
rest = H5G_component (rest, &nchars);
@@ -667,18 +1094,18 @@ H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
* it already has as a message.
*/
if (f->shared->root_sym->header>0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, NULL); /*root exists*/
+ HRETURN_ERROR (H5E_SYM, H5E_EXISTS, NULL); /*root exists*/
}
if ((ent.header = H5O_new (f, 0, ohdr_hint))<0) {
/* can't create header */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL);
}
if (1!=H5O_link (f, &ent, 1)) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_LINK, NULL); /*bad link count*/
+ HRETURN_ERROR (H5E_SYM, H5E_LINK, NULL); /*bad link count*/
}
*(f->shared->root_sym) = ent;
- if (NULL==(ret_value=H5G_shadow_open (f, &dir, f->shared->root_sym))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ if (NULL==(ret_value=H5G_shadow_open (f, &grp, f->shared->root_sym))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL);
}
HRETURN (ret_value);
}
@@ -690,10 +1117,10 @@ H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
if (rest[nchars]) {
if (H5G_component (rest+nchars, NULL)) {
/* component not found */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL);
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL);
} else if (nchars+1 > sizeof _comp) {
/* component is too long */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_COMPLEN, NULL);
+ HRETURN_ERROR (H5E_SYM, H5E_COMPLEN, NULL);
} else {
/* null terminate */
HDmemcpy (_comp, rest, nchars);
@@ -706,7 +1133,7 @@ H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
* Create the object header.
*/
if ((ent.header = H5O_new (f, 0, ohdr_hint))<0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL);
}
@@ -721,28 +1148,29 @@ H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
name_mesg.s = rest;
if (H5O_modify (f, NO_ADDR, &ent, H5O_NAME, 0, &name_mesg)<0) {
/* cannot add/change name message */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL);
}
if (1!=H5O_link (f, &ent, 1)) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_LINK, NULL); /*bad link count*/
+ HRETURN_ERROR (H5E_SYM, H5E_LINK, NULL); /*bad link count*/
}
*(f->shared->root_sym) = ent;
- if (NULL==(ret_value=H5G_shadow_open (f, &dir, f->shared->root_sym))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ if (NULL==(ret_value=H5G_shadow_open (f, &grp, f->shared->root_sym))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL);
}
HRETURN (ret_value);
} else {
/*
- * Make sure the root directory exists. Ignore the failure if it's
- * because the directory already exists.
+ * Make sure the root group exists. Ignore the failure if it's
+ * because the group already exists.
*/
- hbool_t update_dir = (dir.header==f->shared->root_sym->header);
+ hbool_t update_grp = (grp.header==f->shared->root_sym->header);
herr_t status = H5G_mkroot (f, H5G_SIZE_HINT);
if (status<0 && -2!=status) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ /* Can't create root group */
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL);
}
H5ECLEAR;
- if (update_dir) dir = *(f->shared->root_sym);
+ if (update_grp) grp = *(f->shared->root_sym);
}
/*
@@ -750,13 +1178,13 @@ H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
* entry into a symbol table.
*/
if (H5O_link (f, &ent, 1)<0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_LINK, NULL); /*link inc failure*/
+ HRETURN_ERROR (H5E_SYM, H5E_LINK, NULL); /*link inc failure*/
}
- if (NULL==(ent_ptr=H5G_stab_insert (f, &dir, rest, &ent))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't insert*/
+ if (NULL==(ent_ptr=H5G_stab_insert (f, &grp, rest, &ent))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL); /*can't insert*/
}
- if (NULL==(ret_value=H5G_shadow_open (f, &dir, ent_ptr))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't open object*/
+ if (NULL==(ret_value=H5G_shadow_open (f, &grp, ent_ptr))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, NULL); /*can't open object*/
}
FUNC_LEAVE (ret_value);
}
@@ -776,6 +1204,11 @@ H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
* structs. The structs that are returned should be
* released by calling H5G_close().
*
+ * Errors:
+ * SYM BADVALUE Check args.
+ * SYM CANTOPENOBJ Can't open obj.
+ * SYM NOTFOUND Object not found.
+ *
* Return: Success: Ptr to a handle for the object.
*
* Failure: NULL
@@ -792,32 +1225,29 @@ H5G_open (H5F_t *f, const char *name)
{
H5G_entry_t *ent=NULL;
H5G_entry_t *ret_value=NULL;
- H5G_entry_t dir;
- H5G_entry_t *cwd=NULL;
+ H5G_entry_t grp;
+ H5G_entry_t *cwg=NULL;
FUNC_ENTER (H5G_open, NULL, NULL);
/* check args */
assert (f);
if (!name || !*name) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_BADVALUE, NULL);
+ HRETURN_ERROR (H5E_SYM, H5E_BADVALUE, NULL);
}
- /* Get CWD */
-#ifndef LATER
- H5G_shadow_sync (f->shared->root_sym);
- cwd = f->shared->root_sym;
-#endif
- assert (cwd || '/'==*name);
+ /* Get CWG */
+ cwg = H5G_getcwg (f);
+ assert (cwg || '/'==*name);
if (f->shared->root_sym->header<=0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL); /*object not found*/
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL); /*object not found*/
}
- if (NULL==(ent=H5G_namei (f, cwd, name, NULL, &dir))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL); /*object not found*/
+ if (NULL==(ent=H5G_namei (f, cwg, name, NULL, &grp))) {
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL); /*object not found*/
}
- if (NULL==(ret_value=H5G_shadow_open (f, &dir, ent))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTOPENOBJ, NULL);
+ if (NULL==(ret_value=H5G_shadow_open (f, &grp, ent))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTOPENOBJ, NULL); /*can't open obj*/
}
FUNC_LEAVE (ret_value);
@@ -830,6 +1260,9 @@ H5G_open (H5F_t *f, const char *name)
*
* Purpose: Closes an object that was open for modification.
*
+ * Errors:
+ * SYM CANTFLUSH Can't close object.
+ *
* Return: Success: SUCCEED
*
* Failure: FAIL
@@ -849,6 +1282,7 @@ H5G_close (H5F_t *f, H5G_entry_t *ent)
assert (f);
if (ent && H5G_shadow_close (f, ent)<0) {
+ /* Can't close object */
HRETURN_ERROR (H5E_SYM, H5E_CANTFLUSH, FAIL);
}
@@ -861,22 +1295,21 @@ H5G_close (H5F_t *f, H5G_entry_t *ent)
*
* Purpose: Finds an object with the specified NAME in file F. If
* the name is relative then it is interpretted relative
- * to CWD, a symbol table entry for a symbol table. On
- * successful return, DIR_ENT (if non-null) will be
- * initialized with the symbol table information for the
- * directory in which the object appears (or all zero if
- * the returned object is the root object) and ENT will
- * be initialized with the symbol table entry for the
- * object (ENT is optional when the caller is interested
- * only in the existence of the object).
+ * to the current working group. On successful return,
+ * GRP_ENT (if non-null) will be initialized with the symbol
+ * table information for the group in which the object
+ * appears (or all zero if the returned object is the root
+ * object) and ENT will be initialized with the symbol table
+ * entry for the object (ENT is optional when the caller is
+ * interested only in the existence of the object).
*
* This function will fail if the root object is
* requested and there is none.
*
* Errors:
- * DIRECTORY NOTFOUND Object not found.
+ * SYM NOTFOUND Object not found.
*
- * Return: Success: SUCCEED with DIR_ENT and ENT initialized. ENT
+ * Return: Success: SUCCEED with GRP_ENT and ENT initialized. ENT
* is intended for immediate read-only access.
* If the object that ENT refers to is open
* through the ENT entry (see H5G_open()) then
@@ -888,7 +1321,7 @@ H5G_close (H5F_t *f, H5G_entry_t *ent)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
@@ -896,23 +1329,25 @@ H5G_close (H5F_t *f, H5G_entry_t *ent)
*-------------------------------------------------------------------------
*/
herr_t
-H5G_find (H5F_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
- const char *name, H5G_entry_t *ent)
+H5G_find (H5F_t *f, const char *name, H5G_entry_t *grp_ent, H5G_entry_t *ent)
{
H5G_entry_t *ent_p = NULL;
+ H5G_entry_t *cwg = NULL;
+
FUNC_ENTER (H5G_find, NULL, FAIL);
/* check args */
assert (f);
assert (name && *name);
- assert (cwd || '/'==*name);
+ cwg = H5G_getcwg (f);
+ assert (cwg || '/'==*name);
if (f->shared->root_sym->header<=0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL); /*object not found*/
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL); /*object not found*/
}
- if (NULL==(ent_p=H5G_namei (f, cwd, name, NULL, dir_ent))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL); /*object not found*/
+ if (NULL==(ent_p=H5G_namei (f, cwg, name, NULL, grp_ent))) {
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL); /*object not found*/
}
if (ent) *ent = *ent_p;
diff --git a/src/H5Gent.c b/src/H5Gent.c
index f9ca290..b5cddce 100644
--- a/src/H5Gent.c
+++ b/src/H5Gent.c
@@ -410,7 +410,7 @@ H5G_ent_encode (H5F_t *f, uint8 **pp, H5G_entry_t *ent)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 29 1997
*
* Modifications:
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index 84dc0e5..58c924c 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -39,29 +39,32 @@
#define PABLO_MASK H5G_node_mask
/* PRIVATE PROTOTYPES */
-static herr_t H5G_node_decode_key (H5F_t *f, uint8 *raw, void *_key);
-static herr_t H5G_node_encode_key (H5F_t *f, uint8 *raw, void *_key);
+static herr_t H5G_node_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
+ void *_key);
+static herr_t H5G_node_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
+ void *_key);
static size_t H5G_node_size (H5F_t *f);
static haddr_t H5G_node_new (H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static herr_t H5G_node_flush (H5F_t *f, hbool_t destroy, haddr_t addr,
H5G_node_t *sym);
-static H5G_node_t *H5G_node_load (H5F_t *f, haddr_t addr, void *_data);
+static H5G_node_t *H5G_node_load (H5F_t *f, haddr_t addr, void *_udata1,
+ void *_udata2);
static intn H5G_node_cmp (H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static herr_t H5G_node_found (H5F_t *f, haddr_t addr,
const void *_lt_key, void *_udata,
const void *_rt_key);
-static haddr_t H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
+static haddr_t H5G_node_insert (H5F_t *f, haddr_t addr, H5B_ins_t *anchor,
void *_lt_key, hbool_t *lt_key_changed,
void *_md_key, void *_udata,
void *_rt_key, hbool_t *rt_key_changed);
static herr_t H5G_node_list (H5F_t *f, haddr_t addr, void *_udata);
-static size_t H5G_node_sizeof_rkey (H5F_t *f);
+static size_t H5G_node_sizeof_rkey (H5F_t *f, const void *_udata);
/* H5G inherits cache-like properties from H5AC */
const H5AC_class_t H5AC_SNODE[1] = {{
- (void*(*)(H5F_t*,haddr_t,void*))H5G_node_load,
+ (void*(*)(H5F_t*,haddr_t,void*,void*))H5G_node_load,
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5G_node_flush,
}};
@@ -74,6 +77,8 @@ H5B_class_t H5B_SNODE[1] = {{
H5G_node_cmp, /*cmp */
H5G_node_found, /*found */
H5G_node_insert, /*insert */
+ TRUE, /*follow min branch? */
+ TRUE, /*follow max branch? */
H5G_node_list, /*list */
H5G_node_decode_key, /*decode */
H5G_node_encode_key, /*encode */
@@ -102,7 +107,7 @@ static intn interface_initialize_g = FALSE;
*-------------------------------------------------------------------------
*/
static size_t
-H5G_node_sizeof_rkey (H5F_t *f)
+H5G_node_sizeof_rkey (H5F_t *f, const void *udata __attribute__((unused)))
{
return H5F_SIZEOF_OFFSET(f);
}
@@ -126,7 +131,7 @@ H5G_node_sizeof_rkey (H5F_t *f)
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_node_decode_key (H5F_t *f, uint8 *raw, void *_key)
+H5G_node_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
{
H5G_node_key_t *key = (H5G_node_key_t *)_key;
@@ -160,7 +165,7 @@ H5G_node_decode_key (H5F_t *f, uint8 *raw, void *_key)
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_node_encode_key (H5F_t *f, uint8 *raw, void *_key)
+H5G_node_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
{
H5G_node_key_t *key = (H5G_node_key_t *)_key;
@@ -378,12 +383,12 @@ H5G_node_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5G_node_t *sym)
*-------------------------------------------------------------------------
*/
static H5G_node_t *
-H5G_node_load (H5F_t *f, haddr_t addr, void *_udata)
+H5G_node_load (H5F_t *f, haddr_t addr, void *_udata1, void *_udata2)
{
H5G_node_t *sym = NULL;
size_t size = 0;
uint8 *buf = NULL, *p = NULL;
- H5G_ac_ud1_t *ac_udata = (H5G_ac_ud1_t*)_udata;
+ H5G_ac_ud1_t *ac_udata = (H5G_ac_ud1_t*)_udata1;
H5G_node_t *ret_value = NULL; /*for error handling*/
FUNC_ENTER (H5G_node_load, NULL, NULL);
@@ -394,6 +399,7 @@ H5G_node_load (H5F_t *f, haddr_t addr, void *_udata)
assert (f);
assert (addr>=0);
assert (ac_udata);
+ assert (NULL==_udata2);
/*
* Initialize variables.
@@ -453,21 +459,21 @@ H5G_node_load (H5F_t *f, haddr_t addr, void *_udata)
/*-------------------------------------------------------------------------
* Function: H5G_node_cmp
*
- * Purpose: Compares two keys from a B-tree node (LEFT and RIGHT)
+ * Purpose: Compares two keys from a B-tree node (LT_KEY and RT_KEY)
* against another key (not necessarily the same type)
* pointed to by UDATA.
*
* Return: Success: negative if the UDATA key is less than
- * or equal to the LEFT key.
+ * or equal to the LT_KEY
*
* positive if the UDATA key is greater
- * than the RIGHT key.
+ * than the RT_KEY.
*
* zero if the UDATA key falls between
- * the LEFT key (exclusive) and the
- * RIGHT key (inclusive).
+ * the LT_KEY (exclusive) and the
+ * RT_KEY (inclusive).
*
- * Failure: FAIL (same as LT < RT)
+ * Failure: FAIL (same as UDATA < LT_KEY)
*
* Programmer: Robb Matzke
* matzke@llnl.gov
@@ -551,13 +557,13 @@ H5G_node_found (H5F_t *f, haddr_t addr, const void *_lt_key,
assert (addr>=0);
assert (bt_udata);
- ac_udata.dir_addr = bt_udata->dir_addr;
+ ac_udata.grp_addr = bt_udata->grp_addr;
ac_udata.heap_addr = bt_udata->heap_addr;
/*
* Load the symbol table node for exclusive access.
*/
- if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata))) {
+ if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata, NULL))) {
HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
}
@@ -656,7 +662,7 @@ done:
*-------------------------------------------------------------------------
*/
static haddr_t
-H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
+H5G_node_insert (H5F_t *f, haddr_t addr, H5B_ins_t *anchor,
void *_lt_key, hbool_t *lt_key_changed,
void *_md_key, void *_udata,
void *_rt_key, hbool_t *rt_key_changed)
@@ -693,19 +699,11 @@ H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
bt_udata->entry_ptr = NULL;
/*
- * Symbol tables are always split so the new symbol table node is
- * to the right of the old one.
- */
- *anchor = H5B_ANCHOR_LT;
- *lt_key_changed = FALSE;
- *rt_key_changed = FALSE;
-
- /*
* Load the symbol node.
*/
- ac_udata.dir_addr = bt_udata->dir_addr;
+ ac_udata.grp_addr = bt_udata->grp_addr;
ac_udata.heap_addr = bt_udata->heap_addr;
- if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata))) {
+ if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata, NULL))) {
HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
}
@@ -746,12 +744,13 @@ H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
* node and return the address of the new right node (the
* left node is at the same address as the original node).
*/
+ *anchor = H5B_INS_RIGHT;
/* The right node */
if ((new_node = H5G_node_new (f, NULL, NULL, NULL))<0) {
HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
}
- if (NULL==(snrt=H5AC_find (f, H5AC_SNODE, new_node, &ac_udata))) {
+ if (NULL==(snrt=H5AC_find (f, H5AC_SNODE, new_node, &ac_udata, NULL))) {
HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
}
HDmemcpy (snrt->entry, sn->entry + H5G_NODE_K(f),
@@ -789,6 +788,7 @@ H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
} else {
/* Where to insert the new entry? */
+ *anchor = H5B_INS_NOOP;
sn->dirty = TRUE;
insert_into = sn;
insert_addr = addr;
@@ -809,7 +809,7 @@ H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
H5G_shadow_move (f, bt_udata->entry.shadow,
bt_udata->name,
insert_into->entry + idx,
- bt_udata->dir_addr);
+ bt_udata->grp_addr);
}
/* Move entries */
@@ -837,7 +837,8 @@ done:
if (H5AC_unprotect (f, H5AC_SNODE, addr, sn)<0) {
HRETURN_ERROR (H5E_SYM, H5E_PROTECT, FAIL);
}
- if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, insert_addr, &ac_udata))) {
+ if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, insert_addr, &ac_udata,
+ NULL))) {
HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
}
assert (sn==bt_udata->node_ptr);
@@ -852,7 +853,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5G_node_list
*
- * Purpose: This function gets called during a directory list operation.
+ * Purpose: This function gets called during a group list operation.
* It should fill in data in the UDATA struct.
*
* Return: Success: SUCCEED
@@ -886,9 +887,9 @@ H5G_node_list (H5F_t *f, haddr_t addr, void *_udata)
assert (addr>=0);
assert (bt_udata);
- ac_udata.dir_addr = bt_udata->dir_addr;
+ ac_udata.grp_addr = bt_udata->grp_addr;
ac_udata.heap_addr = bt_udata->heap_addr;
- if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata))) {
+ if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata, NULL))) {
HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
}
@@ -978,21 +979,21 @@ H5G_node_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
* We have absolutely no idea where the object header for the symbol table
* to which this node belongs is located. In fact, if the file is corrupt,
* there may not even be an object header for that symbol table. So we
- * supply `-1' as the directory address which causes no open objects to be
+ * supply `-1' as the group address which causes no open objects to be
* associated with the node. For that reason, we flush this node from the
* cache when we're done so if some later caller knows the header address
* they'll be able to access the open objects.
*/
- ac_udata.dir_addr = -1;
+ ac_udata.grp_addr = -1;
ac_udata.heap_addr = heap;
/*
* If we couldn't load the symbol table node, then try loading the
* B-tree node.
*/
- if (NULL==(sn=H5AC_find(f, H5AC_SNODE, addr, &ac_udata))) {
+ if (NULL==(sn=H5AC_find(f, H5AC_SNODE, addr, &ac_udata, NULL))) {
H5ECLEAR; /*discard that error*/
- status = H5B_debug (f, addr, stream, indent, fwidth, H5B_SNODE);
+ status = H5B_debug (f, addr, stream, indent, fwidth, H5B_SNODE, NULL);
if (status<0) HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
HRETURN (SUCCEED);
}
diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h
index e0d6f8d..9421541 100644
--- a/src/H5Gpkg.h
+++ b/src/H5Gpkg.h
@@ -20,7 +20,7 @@
#include <H5Gprivate.h>
#define H5G_NODE_VERS 1 /*symbol table node version number */
-#define H5G_SIZE_HINT 1024 /*default root dir size hint */
+#define H5G_SIZE_HINT 1024 /*default root grp size hint */
#define H5G_NODE_K(F) ((F)->shared->file_create_parms.sym_leaf_k)
#define H5G_NODE_SIZEOF_HDR(F) (H5G_NODE_SIZEOF_MAGIC + 4)
#define H5G_DEFAULT_ROOT_SIZE 32
@@ -44,7 +44,7 @@ struct H5G_entry_t {
* A symbol table node is a collection of symbol table entries. It can
* be thought of as the lowest level of the B-link tree that points to
* a collection of symbol table entries that belong to a specific symbol
- * table or directory.
+ * table or group.
*/
typedef struct H5G_node_t {
hbool_t dirty; /*has cache been modified? */
@@ -61,7 +61,7 @@ typedef struct H5G_node_t {
*/
struct H5G_shadow_t {
char *name; /*name for this entry */
- haddr_t dir_addr; /*hdr addr for dir containing shadow */
+ haddr_t grp_addr; /*hdr addr for group containing shadow */
uintn nrefs; /*reference counter */
H5G_entry_t entry; /*local copy of symbol table entry */
H5G_entry_t *main; /*main entry in stab node if cached */
@@ -78,6 +78,16 @@ typedef struct H5G_node_key_t {
} H5G_node_key_t;
/*
+ * Each file has a stack of open groups with the latest entry on the
+ * stack the current working group. If the stack is empty then the
+ * current working group is the root object.
+ */
+typedef struct H5G_cwgstk_t {
+ H5G_entry_t *handle; /*a handle to an open group */
+ struct H5G_cwgstk_t *next; /*next item (earlier) on stack */
+} H5G_cwgstk_t;
+
+/*
* These operations can be passed down from the H5G_stab layer to the
* H5G_node layer through the B-tree layer.
*/
@@ -96,7 +106,7 @@ typedef struct H5G_bt_ud1_t {
/* downward */
H5G_oper_t operation; /*what operation to perform */
const char *name; /*points to temporary memory */
- haddr_t dir_addr; /*symbol table header address */
+ haddr_t grp_addr; /*symbol table header address */
haddr_t heap_addr; /*symbol table heap address */
/* downward for INSERT */
@@ -119,7 +129,7 @@ typedef struct H5G_bt_ud2_t {
H5G_entry_t *entry; /*array of entries, alloc'd by caller */
char **name; /*array of string ptrs, allocd by caller*/
intn maxentries; /*size of the ADDR and NAME arrays */
- haddr_t dir_addr; /*symbol table header address */
+ haddr_t grp_addr; /*symbol table header address */
haddr_t heap_addr; /*heap address */
/* upward */
@@ -137,15 +147,15 @@ extern H5B_class_t H5B_SNODE[1];
*/
typedef struct H5G_ac_ud1_t {
haddr_t heap_addr;
- haddr_t dir_addr;
+ haddr_t grp_addr;
} H5G_ac_ud1_t;
/* The cache subclass */
extern const H5AC_class_t H5AC_SNODE[1];
/*
- * Functions that understand symbol tables but not directories. The
- * functions that understand directories are exported to the rest of
+ * Functions that understand symbol tables but not names. The
+ * functions that understand names are exported to the rest of
* the library and appear in H5Gprivate.h.
*/
haddr_t H5G_stab_new (H5F_t *f, H5G_entry_t *self, size_t init);
@@ -160,7 +170,7 @@ intn H5G_stab_list (H5F_t *f, H5G_entry_t *self, intn maxentries,
* Functions that understand shadow entries.
*/
herr_t H5G_shadow_sync (H5G_entry_t *ent);
-H5G_entry_t *H5G_shadow_open (H5F_t *f, H5G_entry_t *dir,
+H5G_entry_t *H5G_shadow_open (H5F_t *f, H5G_entry_t *grp,
H5G_entry_t *ent);
herr_t H5G_shadow_close (H5F_t *f, H5G_entry_t *ent);
hbool_t H5G_shadow_p (H5G_entry_t *ent);
@@ -170,7 +180,7 @@ herr_t H5G_shadow_assoc_node (H5F_t *f, H5G_node_t *sym,
H5G_shadow_t *H5G_shadow_list (H5F_t *f, haddr_t stab_header_addr);
herr_t H5G_shadow_move (H5F_t *f, H5G_shadow_t *shadow,
const char *new_name, H5G_entry_t *new_entry,
- haddr_t dir_addr);
+ haddr_t grp_addr);
/*
* Functions that understand symbol table entries.
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index 79666e7..4641d90 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -82,14 +82,15 @@ typedef struct H5G_entry_t H5G_entry_t;
* Library prototypes... These are the ones that other packages routinely
* call.
*/
-H5G_entry_t *H5G_mkdir (H5F_t *f, const char *name, size_t size_hint);
-herr_t H5G_pushd (H5F_t *f, const char *name);
-herr_t H5G_popd (H5F_t *f);
+H5G_entry_t *H5G_new (H5F_t *f, const char *name, size_t size_hint);
+herr_t H5G_set (H5F_t *f, const char *name);
+herr_t H5G_push (H5F_t *f, const char *name);
+herr_t H5G_pop (H5F_t *f);
H5G_entry_t *H5G_create (H5F_t *f, const char *name, size_t ohdr_hint);
H5G_entry_t *H5G_open (H5F_t *f, const char *name);
herr_t H5G_close (H5F_t *f, H5G_entry_t *ent);
-herr_t H5G_find (H5F_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
- const char *name, H5G_entry_t *ent);
+herr_t H5G_find (H5F_t *f, const char *name, H5G_entry_t *grp_ent,
+ H5G_entry_t *ent);
herr_t H5G_ent_encode (H5F_t *f, uint8 **pp, H5G_entry_t *ent);
herr_t H5G_ent_decode (H5F_t *f, uint8 **pp, H5G_entry_t *ent);
diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h
index 049c823..e546e6d 100644
--- a/src/H5Gpublic.h
+++ b/src/H5Gpublic.h
@@ -19,15 +19,19 @@
#define _H5Gpublic_H
/* Public headers needed by this file */
+#include <sys/types.h>
#include <H5public.h>
-
-/* Default root directory size */
-#define H5G_DEFAULT_ROOT SIZE 256
+#include <H5Apublic.h>
#ifdef __cplusplus
extern "C" {
#endif
+herr_t H5Gnew (hid_t file, const char *name, size_t size_hint);
+herr_t H5Gset (hid_t file, const char *name);
+herr_t H5Gpush (hid_t file, const char *name);
+herr_t H5Gpop (hid_t file);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/H5Gshad.c b/src/H5Gshad.c
index 9bf80d8..875f880 100644
--- a/src/H5Gshad.c
+++ b/src/H5Gshad.c
@@ -29,7 +29,7 @@
static hbool_t interface_initialize_g = FALSE;
typedef struct H5G_hash_t {
- haddr_t dir_addr;
+ haddr_t grp_addr;
H5G_shadow_t *head;
struct H5G_hash_t *next;
struct H5G_hash_t *prev;
@@ -81,15 +81,15 @@ H5G_shadow_check (H5F_t *f)
shadow_error = TRUE;
}
- /* Valid directory addresses */
- if (shadow->dir_addr<0 || (shadow->dir_addr==0 && idx!=0)) {
- fprintf (stderr, "dir_addr=%lu, ",
- (unsigned long)(shadow->dir_addr));
+ /* Valid group addresses */
+ if (shadow->grp_addr<0 || (shadow->grp_addr==0 && idx!=0)) {
+ fprintf (stderr, "grp_addr=%lu, ",
+ (unsigned long)(shadow->grp_addr));
shadow_error = TRUE;
- } else if (shadow->dir_addr!=hash->dir_addr) {
- fprintf (stderr, "dir_addr=%lu (not %lu), ",
- (unsigned long)(shadow->dir_addr),
- (unsigned long)(hash->dir_addr));
+ } else if (shadow->grp_addr!=hash->grp_addr) {
+ fprintf (stderr, "grp_addr=%lu (not %lu), ",
+ (unsigned long)(shadow->grp_addr),
+ (unsigned long)(hash->grp_addr));
}
/* Linked to symbol table entry */
@@ -107,9 +107,9 @@ H5G_shadow_check (H5F_t *f)
/* If an error occurred then print other info */
if (shadow_error) {
- fprintf (stderr, "idx=%u, shadow=0x%08lx, dir_addr=%lu\n",
+ fprintf (stderr, "idx=%u, shadow=0x%08lx, grp_addr=%lu\n",
idx, (unsigned long)shadow,
- (unsigned long)(shadow->dir_addr));
+ (unsigned long)(shadow->grp_addr));
nerrors++;
}
}
@@ -247,7 +247,7 @@ H5G_shadow_sync (H5G_entry_t *ent)
* Function: H5G_shadow_list
*
* Purpose: Returns a doubly linked list of shadows for the symbol
- * table whose header address is DIR_ADDR.
+ * table whose header address is GRP_ADDR.
*
* Return: Success: Ptr shadow list or null.
*
@@ -261,15 +261,15 @@ H5G_shadow_sync (H5G_entry_t *ent)
*-------------------------------------------------------------------------
*/
H5G_shadow_t *
-H5G_shadow_list (H5F_t *f, haddr_t dir_addr)
+H5G_shadow_list (H5F_t *f, haddr_t grp_addr)
{
- uintn idx = dir_addr % f->shared->nshadows;
+ uintn idx = grp_addr % f->shared->nshadows;
H5G_hash_t *bucket = NULL;
FUNC_ENTER (H5G_shadows, NULL, NULL);
for (bucket=f->shared->shadow[idx]; bucket; bucket=bucket->next) {
- if (bucket->dir_addr==dir_addr) {
+ if (bucket->grp_addr==grp_addr) {
HRETURN (bucket->head);
}
}
@@ -317,7 +317,7 @@ H5G_shadow_assoc_node (H5F_t *f, H5G_node_t *sym, H5G_ac_ud1_t *ac_udata)
H5G_shadow_check (f);
#endif
- if ((shadow=H5G_shadow_list (f, ac_udata->dir_addr))) {
+ if ((shadow=H5G_shadow_list (f, ac_udata->grp_addr))) {
heap_addr = ac_udata->heap_addr;
while (i<sym->nsyms && shadow) {
@@ -352,7 +352,7 @@ H5G_shadow_assoc_node (H5F_t *f, H5G_node_t *sym, H5G_ac_ud1_t *ac_udata)
* object, open the object (again) and return a handle
* to it.
*
- * DIR can be the null pointer if `ent' is the root entry.
+ * GRP can be the null pointer if `ent' is the root entry.
*
* Return: Success: Handle to open object
*
@@ -366,7 +366,7 @@ H5G_shadow_assoc_node (H5F_t *f, H5G_node_t *sym, H5G_ac_ud1_t *ac_udata)
*-------------------------------------------------------------------------
*/
H5G_entry_t *
-H5G_shadow_open (H5F_t *f, H5G_entry_t *dir, H5G_entry_t *ent)
+H5G_shadow_open (H5F_t *f, H5G_entry_t *grp, H5G_entry_t *ent)
{
H5G_shadow_t *shadow = NULL;
H5O_stab_t stab;
@@ -376,15 +376,15 @@ H5G_shadow_open (H5F_t *f, H5G_entry_t *dir, H5G_entry_t *ent)
uintn idx;
H5O_name_t name_mesg = {NULL};
H5G_entry_t *ret_value = NULL;
- haddr_t dir_addr;
+ haddr_t grp_addr;
FUNC_ENTER (H5G_shadow_open, NULL, NULL);
/* check args */
assert (f);
- assert (ent==f->shared->root_sym || dir);
+ assert (ent==f->shared->root_sym || grp);
assert (ent);
- dir_addr = dir ? dir->header : 0;
+ grp_addr = grp ? grp->header : 0;
if ((shadow = ent->shadow)) {
/*
@@ -396,7 +396,7 @@ H5G_shadow_open (H5F_t *f, H5G_entry_t *dir, H5G_entry_t *ent)
shadow = H5MM_xcalloc (1, sizeof(H5G_shadow_t));
- if (ent==f->shared->root_sym && 0==dir_addr) {
+ if (ent==f->shared->root_sym && 0==grp_addr) {
/*
* We're opening the root entry.
*/
@@ -411,7 +411,7 @@ H5G_shadow_open (H5F_t *f, H5G_entry_t *dir, H5G_entry_t *ent)
/*
* Some entry other than the root.
*/
- if (NULL==H5O_read (f, NO_ADDR, dir, H5O_STAB, 0, &stab)) {
+ if (NULL==H5O_read (f, NO_ADDR, grp, H5O_STAB, 0, &stab)) {
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, NULL);
}
if (NULL==(s=H5H_peek (f, stab.heap_addr, ent->name_off))) {
@@ -428,18 +428,18 @@ H5G_shadow_open (H5F_t *f, H5G_entry_t *dir, H5G_entry_t *ent)
shadow->nrefs = 1;
shadow->entry = *ent;
shadow->entry.dirty = FALSE;
- shadow->dir_addr = dir_addr;
+ shadow->grp_addr = grp_addr;
/*
* Link it into the shadow heap
*/
- idx = dir_addr % f->shared->nshadows;
+ idx = grp_addr % f->shared->nshadows;
for (hash=f->shared->shadow[idx]; hash; hash=hash->next) {
- if (hash->dir_addr==dir_addr) break;
+ if (hash->grp_addr==grp_addr) break;
}
if (!hash) {
hash = H5MM_xcalloc (1, sizeof(H5G_hash_t));
- hash->dir_addr = dir_addr;
+ hash->grp_addr = grp_addr;
hash->next = f->shared->shadow[idx];
f->shared->shadow[idx] = hash;
if (hash->next) hash->next->prev = hash;
@@ -524,7 +524,7 @@ H5G_shadow_close (H5F_t *f, H5G_entry_t *ent)
/* clean the shadow */
if (1==shadow->nrefs && ent->dirty) {
if (!shadow->main &&
- NULL==H5G_stab_find (f, shadow->dir_addr, NULL, shadow->name)) {
+ NULL==H5G_stab_find (f, shadow->grp_addr, NULL, shadow->name)) {
HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
}
assert (shadow->main);
@@ -540,9 +540,9 @@ H5G_shadow_close (H5F_t *f, H5G_entry_t *ent)
H5G_shadow_dissociate (ent);
/* find symtabs shadow list */
- idx = shadow->dir_addr % f->shared->nshadows;
+ idx = shadow->grp_addr % f->shared->nshadows;
for (hash=f->shared->shadow[idx]; hash; hash=hash->next) {
- if (hash->dir_addr==shadow->dir_addr) break;
+ if (hash->grp_addr==shadow->grp_addr) break;
}
assert (hash);
@@ -577,7 +577,7 @@ H5G_shadow_close (H5F_t *f, H5G_entry_t *ent)
* Function: H5G_shadow_move
*
* Purpose: Moves the SHADOW for some entry to correspond to a
- * NEW_ENTRY. The DIR_ADDR is the address for the directory
+ * NEW_ENTRY. The GRP_ADDR is the address for the group
* which contains NEW_ENTRY.
*
* Return: Success: SUCCEED
@@ -593,7 +593,7 @@ H5G_shadow_close (H5F_t *f, H5G_entry_t *ent)
*/
herr_t
H5G_shadow_move (H5F_t *f, H5G_shadow_t *shadow, const char *new_name,
- H5G_entry_t *new_entry, haddr_t dir_addr)
+ H5G_entry_t *new_entry, haddr_t grp_addr)
{
H5G_hash_t *hash;
uintn idx;
@@ -602,29 +602,29 @@ H5G_shadow_move (H5F_t *f, H5G_shadow_t *shadow, const char *new_name,
assert (shadow);
assert (new_entry);
- assert (dir_addr>0);
+ assert (grp_addr>0);
- if (0==shadow->dir_addr) {
+ if (0==shadow->grp_addr) {
/*
* We're moving the shadow for the root object. This simplifies things
* greatly since it implies that this is the only shadow currently
* defined for the entire file.
*/
- idx = dir_addr % f->shared->nshadows;
+ idx = grp_addr % f->shared->nshadows;
assert (NULL==f->shared->shadow[idx]); /*Nothing at new idx... */
hash = f->shared->shadow[0];
assert (hash); /*..but root idx has something. */
- assert (0==hash->dir_addr); /*..and it's the root something */
+ assert (0==hash->grp_addr); /*..and it's the root something */
assert (NULL==hash->next); /*..and just that */
assert (hash->head==shadow); /*..and exactly that */
/* Move root entry to new hash bucket */
f->shared->shadow[idx] = hash;
f->shared->shadow[0] = NULL;
- hash->dir_addr = dir_addr;
+ hash->grp_addr = grp_addr;
/* Associate SHADOW with NEW_ENTRY */
- shadow->dir_addr = dir_addr;
+ shadow->grp_addr = grp_addr;
shadow->main = new_entry;
new_entry->shadow = shadow;
@@ -636,7 +636,7 @@ H5G_shadow_move (H5F_t *f, H5G_shadow_t *shadow, const char *new_name,
/*
* Other shadows never move.
*/
- assert (shadow->dir_addr==dir_addr);
+ assert (shadow->grp_addr==grp_addr);
shadow->main = new_entry;
new_entry->shadow = shadow;
}
@@ -682,7 +682,7 @@ H5G_shadow_flush (H5F_t *f, hbool_t invalidate)
*/
if (shadow->entry.dirty) {
if (!shadow->main &&
- NULL==H5G_stab_find (f, shadow->dir_addr, NULL,
+ NULL==H5G_stab_find (f, shadow->grp_addr, NULL,
shadow->name)) {
HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
}
@@ -698,12 +698,12 @@ H5G_shadow_flush (H5F_t *f, hbool_t invalidate)
* some object before closing the file. Since this is hard to
* debug, we'll be nice and print the names here. We don't know
* the full name, but we'll print the file address (relative to
- * the boot block) of the object header for the directory that
+ * the boot block) of the object header for the group that
* contains the open object.
*/
if (invalidate) {
- fprintf (stderr, "Open object <%lu>/%s",
- (unsigned long)(shadow->dir_addr),
+ fprintf (stderr, "Warning: open object <%lu>/%s",
+ (unsigned long)(shadow->grp_addr),
shadow->name);
if (shadow->nrefs>1) {
fprintf (stderr, " (%d times)", shadow->nrefs);
diff --git a/src/H5Gstab.c b/src/H5Gstab.c
index b600e90..7acaa13 100644
--- a/src/H5Gstab.c
+++ b/src/H5Gstab.c
@@ -87,14 +87,14 @@ H5G_stab_new (H5F_t *f, H5G_entry_t *self, size_t init)
}
/* Create the B-tree */
- if ((stab.btree_addr = H5B_new (f, H5B_SNODE))<0) {
+ if ((stab.btree_addr = H5B_new (f, H5B_SNODE, NULL))<0) {
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't create B-tree*/
}
/*
* Create symbol table object header. It has a zero link count
* since nothing refers to it yet. The link count will be
- * incremented if the object is added to the directory hierarchy.
+ * incremented if the object is added to the group directed graph.
*/
if ((addr = H5O_new (f, 0, 4+2*H5F_SIZEOF_OFFSET(f)))<0) {
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't create header*/
@@ -169,7 +169,7 @@ H5G_stab_find (H5F_t *f, haddr_t addr, H5G_entry_t *self,
udata.operation = H5G_OPER_FIND;
udata.name = name;
udata.heap_addr = stab.heap_addr;
- udata.dir_addr = addr;
+ udata.grp_addr = addr;
udata.node_ptr = NULL;
/* search the B-tree */
@@ -245,7 +245,7 @@ H5G_stab_insert (H5F_t *f, H5G_entry_t *self, const char *name,
udata.operation = H5G_OPER_INSERT;
udata.name = name;
udata.heap_addr = stab.heap_addr;
- udata.dir_addr = self->header;
+ udata.grp_addr = self->header;
udata.entry = *ent;
udata.entry.name_off = -1;
udata.node_ptr = NULL;
@@ -326,7 +326,7 @@ H5G_stab_list (H5F_t *f, H5G_entry_t *self, intn maxentries,
}
udata.entry = entries;
udata.name = names;
- udata.dir_addr = self->header;
+ udata.grp_addr = self->header;
udata.heap_addr = stab.heap_addr;
udata.maxentries = maxentries;
udata.nsyms = 0;
diff --git a/src/H5H.c b/src/H5H.c
index 7724045..64809e4 100644
--- a/src/H5H.c
+++ b/src/H5H.c
@@ -45,14 +45,14 @@ typedef struct H5H_t {
} H5H_t;
/* PRIVATE PROTOTYPES */
-static H5H_t *H5H_load (H5F_t *f, haddr_t addr, void *udata);
+static H5H_t *H5H_load (H5F_t *f, haddr_t addr, void *udata1, void *udata2);
static herr_t H5H_flush (H5F_t *f, hbool_t dest, haddr_t addr, H5H_t *heap);
/*
* H5H inherits cache-like properties from H5AC
*/
static const H5AC_class_t H5AC_HEAP[1] = {{
- (void*(*)(H5F_t*,haddr_t,void*))H5H_load,
+ (void*(*)(H5F_t*,haddr_t,void*,void*))H5H_load,
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5H_flush,
}};
@@ -161,7 +161,7 @@ H5H_new (H5F_t *f, H5H_type_t heap_type, size_t size_hint)
*-------------------------------------------------------------------------
*/
static H5H_t *
-H5H_load (H5F_t *f, haddr_t addr, void *udata)
+H5H_load (H5F_t *f, haddr_t addr, void *udata1, void *udata2)
{
uint8 hdr[20], *p;
H5H_t *heap=NULL;
@@ -175,7 +175,8 @@ H5H_load (H5F_t *f, haddr_t addr, void *udata)
assert (f);
assert (addr>0);
assert (H5H_SIZEOF_HDR(f) <= sizeof hdr);
- assert (!udata);
+ assert (!udata1);
+ assert (!udata2);
if (H5F_block_read (f, addr, H5H_SIZEOF_HDR(f), hdr)<0) {
HRETURN_ERROR (H5E_HEAP, H5E_READERROR, NULL);
@@ -395,7 +396,7 @@ H5H_read (H5F_t *f, haddr_t addr, off_t offset, size_t size, void *buf)
assert (addr>0);
assert (offset>=0);
- if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL);
}
assert (offset<heap->mem_alloc);
@@ -455,7 +456,7 @@ H5H_peek (H5F_t *f, haddr_t addr, off_t offset)
assert (addr>0);
assert (offset>=0);
- if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL);
}
assert (offset<heap->mem_alloc);
@@ -536,7 +537,7 @@ H5H_insert (H5F_t *f, haddr_t addr, size_t buf_size, const void *buf)
need = buf_size;
H5H_ALIGN (need);
- if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
}
heap->dirty += 1;
@@ -686,7 +687,7 @@ H5H_write (H5F_t *f, haddr_t addr, off_t offset, size_t size,
assert (offset>=0);
assert (buf);
- if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
}
assert (offset<heap->mem_alloc);
@@ -748,7 +749,7 @@ H5H_remove (H5F_t *f, haddr_t addr, off_t offset, size_t size)
assert (offset>=0);
assert (size>0);
- if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
}
assert (offset<heap->mem_alloc);
@@ -864,7 +865,7 @@ H5H_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent, intn fwidth)
assert (indent>=0);
assert (fwidth>=0);
- if (NULL==(h=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ if (NULL==(h=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
}
diff --git a/src/H5O.c b/src/H5O.c
index 24edf84..9130de3 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -26,7 +26,7 @@
/* PRIVATE PROTOTYPES */
static herr_t H5O_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5O_t *oh);
-static H5O_t *H5O_load (H5F_t *f, haddr_t addr, void *_data);
+static H5O_t *H5O_load (H5F_t *f, haddr_t addr, void *_udata1, void *_udata2);
static intn H5O_find_in_ohdr (H5F_t *f, haddr_t addr,
const H5O_class_t **type_p, intn sequence);
static intn H5O_alloc (H5F_t *f, H5O_t *oh, const H5O_class_t *type,
@@ -36,7 +36,7 @@ static intn H5O_alloc_new_chunk (H5F_t *f, H5O_t *oh, size_t size);
/* H5O inherits cache-like properties from H5AC */
static const H5AC_class_t H5AC_OHDR[1] = {{
- (void*(*)(H5F_t*,haddr_t,void*))H5O_load,
+ (void*(*)(H5F_t*,haddr_t,void*,void*))H5O_load,
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5O_flush,
}};
@@ -45,17 +45,17 @@ static intn interface_initialize_g = FALSE;
/* ID to type mapping */
static const H5O_class_t *const message_type_g[] = {
- H5O_NULL, /*0x0000 Null */
- H5O_SIM_DIM, /*0x0001 Simple dimensionality */
+ H5O_NULL, /*0x0000 Null */
+ H5O_SIM_DIM, /*0x0001 Simple dimensionality */
NULL, /*0x0002 Data space (fiber bundle?) */
- H5O_SIM_DTYPE, /*0x0003 Simple data type */
+ H5O_SIM_DTYPE, /*0x0003 Simple data type */
NULL, /*0x0004 Compound data type */
- H5O_STD_STORE, /*0x0005 Data storage -- standard object */
+ H5O_STD_STORE, /*0x0005 Data storage -- standard object */
NULL, /*0x0006 Data storage -- compact object */
NULL, /*0x0007 Data storage -- external object */
- NULL, /*0x0008 Data storage -- indexed object */
- NULL, /*0x0009 Data storage -- chunked object */
- NULL, /*0x000A Data storage -- sparse object */
+ H5O_ISTORE, /*0x0008 Data storage -- indexed object */
+ NULL, /*0x0009 Not assigned */
+ NULL, /*0x000A Not assigned */
NULL, /*0x000B Data storage -- compressed object */
NULL, /*0x000C Attribute list */
H5O_NAME, /*0x000D Object name */
@@ -105,7 +105,7 @@ H5O_new (H5F_t *f, intn nlink, size_t size_hint)
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL);
}
- /* allocate the object header in fill in header fields */
+ /* allocate the object header and fill in header fields */
oh = H5MM_xcalloc (1, sizeof(H5O_t));
oh->dirty = TRUE;
oh->version = H5O_VERSION;
@@ -165,7 +165,7 @@ H5O_new (H5F_t *f, intn nlink, size_t size_hint)
*-------------------------------------------------------------------------
*/
static H5O_t *
-H5O_load (H5F_t *f, haddr_t addr, void *_data)
+H5O_load (H5F_t *f, haddr_t addr, void *_udata1, void *_udata2)
{
H5O_t *oh = NULL;
H5O_t *ret_value = (void*)1; /*kludge for HGOTO_ERROR*/
@@ -182,7 +182,8 @@ H5O_load (H5F_t *f, haddr_t addr, void *_data)
/* check args */
assert (f);
assert (addr>=0);
- assert (!_data);
+ assert (!_udata1);
+ assert (!_udata2);
/* allocate ohdr and init chunk list */
oh = H5MM_xcalloc (1, sizeof(H5O_t));
@@ -454,7 +455,7 @@ H5O_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5O_t *oh)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
@@ -513,7 +514,7 @@ H5O_link (H5F_t *f, H5G_entry_t *ent, intn adjust)
addr = H5G_ent_addr (ent);
/* get header */
- if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
}
@@ -600,7 +601,7 @@ H5O_read (H5F_t *f, haddr_t addr, H5G_entry_t *ent,
#endif
/* copy the message to the user-supplied buffer */
- if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL);
}
retval = (type->copy)(oh->mesg[idx].native, mesg);
@@ -643,7 +644,7 @@ H5O_find_in_ohdr (H5F_t *f, haddr_t addr, const H5O_class_t **type_p,
assert (type_p);
/* load the object header */
- if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
}
@@ -710,7 +711,7 @@ H5O_peek (H5F_t *f, haddr_t addr, const H5O_class_t *type, intn sequence)
if ((idx = H5O_find_in_ohdr (f, addr, &type, sequence))<0) {
HRETURN_ERROR (H5E_OHDR, H5E_NOTFOUND, NULL);
}
- if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL);
}
@@ -767,7 +768,7 @@ H5O_modify (H5F_t *f, haddr_t addr, H5G_entry_t *ent,
assert (mesg);
if (addr<=0) addr = H5G_ent_addr (ent);
- if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
}
@@ -842,7 +843,7 @@ H5O_modify (H5F_t *f, haddr_t addr, H5G_entry_t *ent,
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 28 1997
*
* Modifications:
@@ -865,7 +866,7 @@ H5O_remove (H5F_t *f, haddr_t addr, H5G_entry_t *ent,
if (addr<=0) addr = H5G_ent_addr (ent);
/* load the object header */
- if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
}
@@ -1309,7 +1310,7 @@ H5O_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent, intn fwidth)
assert (indent>=0);
assert (fwidth>=0);
- if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
}
diff --git a/src/H5Oistore.c b/src/H5Oistore.c
new file mode 100644
index 0000000..1ed275e
--- /dev/null
+++ b/src/H5Oistore.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 1997 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Robb Matzke <matzke@llnl.gov>
+ * Wednesday, October 8, 1997
+ */
+#include <H5private.h>
+#include <H5Eprivate.h>
+#include <H5MMprivate.h>
+#include <H5Oprivate.h>
+
+#define PABLO_MASK H5O_istore_mask
+
+/* PRIVATE PROTOTYPES */
+static void *H5O_istore_decode (H5F_t *f, size_t raw_size, const uint8 *p);
+static herr_t H5O_istore_encode (H5F_t *f, size_t size, uint8 *p,
+ const void *_mesg);
+static void *H5O_istore_copy (const void *_mesg, void *_dest);
+static size_t H5O_istore_size (H5F_t *f, const void *_mesg);
+static herr_t H5O_istore_debug (H5F_t *f, const void *_mesg, FILE *stream,
+ intn indent, intn fwidth);
+
+/* This message derives from H5O */
+const H5O_class_t H5O_ISTORE[1] = {{
+ H5O_ISTORE_ID, /*message id number */
+ "istore", /*message name for debugging */
+ sizeof(H5O_istore_t), /*native message size */
+ H5G_NOTHING_CACHED, /*symtab entry `type' field */
+ H5O_istore_decode, /*decode message */
+ H5O_istore_encode, /*encode message */
+ NULL, /*get messsage from stab entry */
+ NULL, /*put message into stab entry */
+ H5O_istore_copy, /*copy the native value */
+ H5O_istore_size, /*size of message on disk */
+ NULL, /*reset method */
+ H5O_istore_debug, /*debug the message */
+}};
+
+/* Is the interface initialized? */
+static hbool_t interface_initialize_g = FALSE;
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_istore_decode
+ *
+ * Purpose: Decode an indexed storage message and return a pointer to a
+ * new one created with malloc().
+ *
+ * Return: Success: Ptr to new message in native order.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_istore_decode (H5F_t *f, size_t raw_size, const uint8 *p)
+{
+ H5O_istore_t *mesg = NULL;
+ intn i;
+
+ FUNC_ENTER (H5O_istore_decode, NULL, NULL);
+
+ /* check args */
+ assert (f);
+ assert (p);
+
+ /* decode */
+ mesg = H5MM_xcalloc (1, sizeof(H5O_istore_t));
+ H5F_decode_offset (f, p, mesg->btree_addr);
+ mesg->ndims = *p++;
+ assert (raw_size == H5O_istore_size (f, mesg));
+
+ /* Reserved bytes */
+ p += 7;
+
+ /* Read the min_corner, max_corner, and alignment values */
+ for (i=0; i<mesg->ndims; i++) {
+ UINT32DECODE (p, mesg->alignment[i]);
+ }
+
+ FUNC_LEAVE (mesg);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_istore_encode
+ *
+ * Purpose: Encodes a message.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_istore_encode (H5F_t *f, size_t raw_size, uint8 *p, const void *_mesg)
+{
+ const H5O_istore_t *mesg = (const H5O_istore_t *)_mesg;
+ int i;
+
+ FUNC_ENTER (H5O_istore_encode, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (mesg);
+ assert (mesg->ndims>0 && mesg->ndims<=H5O_ISTORE_NDIMS);
+ assert (raw_size == H5O_istore_size (f, _mesg));
+ assert (p);
+
+ /* encode B-tree offset */
+ H5F_encode_offset (f, p, mesg->btree_addr);
+
+ /* number of dimensions */
+ *p++ = mesg->ndims;
+
+ /* reserved bytes should be zero */
+ for (i=0; i<7; i++) *p++ = 0;
+
+ /* min_corner, max_corner, and alignment */
+ for (i=0; i<mesg->ndims; i++) {
+ UINT32ENCODE (p, mesg->alignment[i]);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_istore_copy
+ *
+ * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if
+ * necessary.
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_istore_copy (const void *_mesg, void *_dest)
+{
+ const H5O_istore_t *mesg = (const H5O_istore_t *)_mesg;
+ H5O_istore_t *dest = (H5O_istore_t *)_dest;
+
+ FUNC_ENTER (H5O_istore_copy, NULL, NULL);
+
+ /* check args */
+ assert (mesg);
+ if (!dest) dest = H5MM_xcalloc (1, sizeof(H5O_istore_t));
+
+ /* copy */
+ *dest = *mesg;
+
+ FUNC_LEAVE ((void*)dest);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_istore_size
+ *
+ * Purpose: Returns the size of the raw message in bytes not counting the
+ * message type or size fields, but only the data fields. This
+ * function doesn't take into account message alignment.
+ *
+ * Return: Success: Message data size in bytes
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5O_istore_size (H5F_t *f, const void *_mesg)
+{
+ const H5O_istore_t *mesg = (const H5O_istore_t *)_mesg;
+ size_t ret_value = FAIL;
+
+ FUNC_ENTER (H5O_istore_size, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (mesg);
+ assert (mesg->ndims>0 && mesg->ndims<=H5O_ISTORE_NDIMS);
+
+ ret_value = H5F_SIZEOF_OFFSET (f) + /* B-tree address */
+ 1 + /* max dimension index */
+ 7 + /* reserved bytes */
+ mesg->ndims * 4; /* alignment */
+
+ FUNC_LEAVE (ret_value);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_istore_debug
+ *
+ * Purpose: Prints debugging info for a message.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_istore_debug (H5F_t *f, const void *_mesg, FILE *stream, intn indent,
+ intn fwidth)
+{
+ const H5O_istore_t *mesg = (const H5O_istore_t *)_mesg;
+ intn i;
+
+ FUNC_ENTER (H5O_istore_debug, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (mesg);
+ assert (stream);
+ assert (indent>=0);
+ assert (fwidth>=0);
+
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "B-tree address:",
+ (unsigned long)(mesg->btree_addr));
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Number of dimensions:",
+ (unsigned long)(mesg->ndims));
+
+ /* Alignment */
+ fprintf (stream, "%*s%-*s {", indent, "", fwidth,
+ "Alignment:");
+ for (i=0; i<mesg->ndims; i++) {
+ fprintf (stream, "%s%lu", i?", ":"",
+ (unsigned long)(mesg->alignment[i]));
+ }
+ fprintf (stream, "}\n");
+
+ FUNC_LEAVE (SUCCEED);
+}
+
diff --git a/src/H5Oname.c b/src/H5Oname.c
index 7d76fa5..9d8aa09 100644
--- a/src/H5Oname.c
+++ b/src/H5Oname.c
@@ -6,7 +6,7 @@
*
* Created: H5Oname.c
* Aug 12 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose: Object name message.
*
@@ -62,7 +62,7 @@ static hbool_t interface_initialize_g = FALSE;
* Failure: NULL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
@@ -101,7 +101,7 @@ H5O_name_decode (H5F_t *f, size_t raw_size, const uint8 *p)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
@@ -144,7 +144,7 @@ H5O_name_encode (H5F_t *f, size_t raw_size, uint8 *p, const void *_mesg)
* Failure: NULL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
@@ -184,7 +184,7 @@ H5O_name_copy (const void *_mesg, void *_dest)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
@@ -219,7 +219,7 @@ H5O_name_size (H5F_t *f, const void *_mesg)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
@@ -253,7 +253,7 @@ H5O_name_reset (void *_mesg)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 12 1997
*
* Modifications:
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 94dd764..c4ad1cb 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -115,10 +115,23 @@ typedef h5_atomic_type_t H5O_sim_dtype_t;
#define H5O_STD_STORE_ID 0x0005
extern const H5O_class_t H5O_STD_STORE[1];
-typedef struct H5O_std_store {
- haddr_t off;
- haddr_t len;
- } H5O_std_store_t;
+typedef struct H5O_std_store_t {
+ haddr_t off;
+ haddr_t len;
+} H5O_std_store_t;
+
+/*
+ * Indexed Data Storage message.
+ */
+#define H5O_ISTORE_ID 0x0008
+#define H5O_ISTORE_NDIMS 32
+extern const H5O_class_t H5O_ISTORE[1];
+
+typedef struct H5O_istore_t {
+ haddr_t btree_addr; /*file address of B-tree */
+ uintn ndims; /*num dimensions in stored data */
+ size_t alignment[H5O_ISTORE_NDIMS]; /*algn in logical space */
+} H5O_istore_t;
/*
* Object name message.
diff --git a/src/H5Osdtyp.c b/src/H5Osdtyp.c
index 367af17..0800e30 100644
--- a/src/H5Osdtyp.c
+++ b/src/H5Osdtyp.c
@@ -205,7 +205,7 @@ H5O_sim_dtype_fast (const H5G_cache_t *cache, void *mesg)
method is required for simple datatypes, as they can be cached in the
symbol-table entry)
--------------------------------------------------------------------------*/
-static herr_t
+static hbool_t
H5O_sim_dtype_cache (H5G_type_t *cache_type, H5G_cache_t *cache,
const void *mesg)
{
diff --git a/src/H5config.h.in b/src/H5config.h.in
index 20da7a1..07a0615 100644
--- a/src/H5config.h.in
+++ b/src/H5config.h.in
@@ -1,5 +1,11 @@
/* src/H5config.h.in. Generated automatically from configure.in by autoheader. */
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
/* Define to `long' if <sys/types.h> doesn't define. */
#undef off_t
@@ -13,6 +19,12 @@
byte first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
+/* Define if the __attribute__(()) extension is present */
+/* #define HAVE_ATTRIBUTE */
+
+/* Define if the compiler understands the __FUNCTION__ keyword. */
+/* #define HAVE_FUNCTION */
+
/* The number of bytes in a double. */
#undef SIZEOF_DOUBLE
diff --git a/src/H5private.h b/src/H5private.h
index f13ff59..58db166 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -63,8 +63,19 @@
#define MACIO 2
#define WINNTIO 3
#define PAGEBUFIO 4
-#define FILELIB POSIXBUFIO
+#ifndef FILELIB
+# define FILELIB POSIXBUFIO
+#endif
+
+/* Does the compiler support the __attribute__(()) syntax? */
+#ifndef HAVE_ATTRIBUTE
+# define __attribute__(X) /*void*/
+#endif
+/* Does the compiler expand __FUNCTION__? */
+#ifndef HAVE_FUNCTION
+# define __FUNCTION__ "NoFuntionName"
+#endif
/* number of members in an array */
#ifndef NELMTS
@@ -359,6 +370,7 @@ typedef off_t haddr_t;
/*
* And now for a couple non-Posix functions...
*/
+extern char *strdup (const char *s);
#define HDstrdup(S) strdup(S)
/*-------------------------------------------------------------------------
diff --git a/src/Makefile.in b/src/Makefile.in
index cebf3c1..8776376 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -14,10 +14,10 @@ LIB=libhdf5.a
PROGS=debug
# Source and object files for the library (lexicographically)...
-LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5C.c H5D.c H5Dconv.c H5E.c H5F.c H5G.c \
- H5Gent.c H5Gnode.c H5Gshad.c H5Gstab.c H5H.c H5M.c H5MF.c H5MM.c \
- H5O.c H5Ocont.c H5Oname.c H5Onull.c H5Osdtyp.c H5Osdim.c H5Ostab.c \
- H5Ostdst.c H5P.c H5T.c
+LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5C.c H5D.c H5Dconv.c H5E.c H5F.c H5Fistore.c \
+ H5G.c H5Gent.c H5Gnode.c H5Gshad.c H5Gstab.c H5H.c H5M.c H5MF.c \
+ H5MM.c H5O.c H5Ocont.c H5Oistore.c H5Oname.c H5Onull.c H5Osdtyp.c \
+ H5Osdim.c H5Ostab.c H5Ostdst.c H5P.c H5T.c H5V.c
LIB_OBJ=$(LIB_SRC:.c=.o)
@@ -35,7 +35,7 @@ PUB_HDR=H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5Cpublic.h \
PRIVATE_HDR=H5private.h H5Aprivate.h H5ACprivate.h H5Bprivate.h \
H5Cprivate.h H5Dprivate.h H5Eprivate.h H5Fprivate.h H5Gprivate.h \
H5Gpkg.h H5Hprivate.h H5Mprivate.h H5MFprivate.h H5MMprivate.h \
- H5Oprivate.h H5Pprivate.h H5Tprivate.h
+ H5Oprivate.h H5Pprivate.h H5Tprivate.h H5Vprivate.h
# How to build the programs...
debug: debug.o $(LIB)
diff --git a/test/Makefile.in b/test/Makefile.in
index 8a7d4f0..d2cbe3a 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -10,18 +10,38 @@
CPPFLAGS=-I. -I../src @CPPFLAGS@
# These are our main targets:
-PROGS=testhdf5
+PROGS=testhdf5 hyperslab istore
TESTS=$(PROGS)
-# Source and object files for programs...
-PROG_SRC=testhdf5.c tfile.c theap.c tmeta.c tohdr.c tstab.c th5t.c th5p.c th5d.c
+# Source and object files for programs... The PROG_SRC list contains all the
+# source files and is used for things like dependencies, archiving, etc. The
+# other source lists are for the individual tests, the files of which may
+# overlap with other tests.
+PROG_SRC=testhdf5.c tfile.c theap.c tmeta.c tohdr.c tstab.c th5t.c th5p.c \
+ th5d.c hyperslab.c istore.c
PROG_OBJ=$(PROG_SRC:.c=.o)
+TESTHDF5_SRC=testhdf5.c tfile.c theap.c tmeta.c tohdr.c tstab.c th5t.c \
+ th5p.c th5d.c
+TESTHDF5_OBJ=$(TESTHDF5_SRC:.c=.o)
+
+HYPERSLAB_SRC=hyperslab.c
+HYPERSLAB_OBJ=$(HYPERSLAB_SRC:.c=.o)
+
+ISTORE_SRC=istore.c
+ISTORE_OBJ=$(ISTORE_SRC:.c=.o)
+
# Private header files (not to be installed)...
PRIVATE_HDR=testhdf5.h
# How to build the programs...
-testhdf5: $(PROG_OBJ) ../src/libhdf5.a
- $(CC) $(CFLAGS) -o $@ $(PROG_OBJ) ../src/libhdf5.a $(LIBS)
+testhdf5: $(TESTHDF5_OBJ) ../src/libhdf5.a
+ $(CC) $(CFLAGS) -o $@ $(TESTHDF5_OBJ) ../src/libhdf5.a $(LIBS)
+
+hyperslab: $(HYPERSLAB_OBJ) ../src/libhdf5.a
+ $(CC) $(CFLAGS) -o $@ $(HYPERSLAB_OBJ) ../src/libhdf5.a $(LIBS)
+
+istore: $(ISTORE_OBJ) ../src/libhdf5.a
+ $(CC) $(CFLAGS) -o $@ $(ISTORE_OBJ) ../src/libhdf5.a $(LIBS)
@CONCLUDE@
diff --git a/test/istore.c b/test/istore.c
new file mode 100644
index 0000000..9f6fa1f
--- /dev/null
+++ b/test/istore.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 1997 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Robb Matzke <matzke@llnl.gov>
+ * Wednesday, October 15, 1997
+ *
+ * Purpose: Tests various aspects of indexed raw data storage.
+ */
+#include <H5private.h>
+#include <H5Fprivate.h>
+#include <H5Gprivate.h>
+#include <H5MMprivate.h>
+#include <H5Oprivate.h>
+#include <H5Vprivate.h>
+
+#define FILENAME "istore.h5"
+
+#define AT() printf (" at %s:%d in %s()...\n", \
+ __FILE__, __LINE__, __FUNCTION__);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_array
+ *
+ * Purpose: Prints the values in an array
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Friday, October 10, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+print_array (uint8 *array, size_t nx, size_t ny, size_t nz)
+{
+ int i, j, k;
+
+ for (i=0; i<nx; i++) {
+ if (nz>1) {
+ printf ("i=%d:\n", i);
+ } else {
+ printf ("%03d:", i);
+ }
+
+ for (j=0; j<ny; j++) {
+ if (nz>1) printf ("%03d:", j);
+ for (k=0; k<nz; k++) {
+ printf (" %3d", *array++);
+ }
+ if (nz>1) printf ("\n");
+ }
+ printf ("\n");
+ }
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: new_object
+ *
+ * Purpose: Creates a new object that refers to a indexed storage of raw
+ * data. No raw data is stored.
+ *
+ * Return: Success: Handle to a new open object.
+ *
+ * Failure: NULL, error message printed.
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 15, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5G_entry_t *
+new_object (H5F_t *f, const char *name, size_t ndims)
+{
+ H5G_entry_t *handle = NULL;
+ H5O_istore_t istore;
+ intn i;
+
+ /* Create the object symbol table entry and header */
+ if (NULL==(handle=H5G_create (f, name, 64))) {
+ puts ("*FAILED*");
+ if (!isatty (1)) {
+ AT ();
+ printf (" H5G_create (f, name=\"%s\") = NULL\n", name);
+ }
+ return NULL;
+ }
+
+ /* Add the indexed-storage message */
+ memset (&istore, 0, sizeof istore);
+ istore.ndims = ndims;
+ for (i=0; i<ndims; i++) istore.alignment[i] = 2;
+
+ if (H5O_modify (f, H5O_NO_ADDR, handle, H5O_ISTORE, H5O_NEW_MESG,
+ &istore)<0) {
+ printf ("*FAILED*\n");
+ if (!isatty (1)) {
+ AT();
+ printf (" H5G_modify istore message failure\n");
+ }
+ return NULL;
+ }
+
+ return handle;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_create
+ *
+ * Purpose: Creates a named object that refers to indexed storage of raw
+ * data. No raw data is stored.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 15, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_create (H5F_t *f, const char *prefix)
+{
+ H5G_entry_t *handle = NULL;
+ intn i;
+ char name[256];
+
+ printf ("%-70s", "Testing istore create");
+ fflush (stdout);
+
+ for (i=1; i<=H5O_ISTORE_NDIMS; i++) {
+ sprintf (name, "%s_%02d", prefix, i);
+ if (NULL==(handle=new_object (f, name, i))) return FAIL;
+ H5G_close (f, handle);
+ }
+
+ puts (" PASSED");
+ return SUCCEED;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_extend
+ *
+ * Purpose: Creates an empty object and then writes to it in such a way
+ * as to always extend the object's domain.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 15, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_extend (H5F_t *f, const char *prefix,
+ size_t nx, size_t ny, size_t nz)
+{
+ H5G_entry_t *handle = NULL;
+ int i, j, k, ndims, ctr;
+ uint8 *buf=NULL, *check=NULL, *whole=NULL;
+ char dims[64], s[256], name[256];
+ size_t offset[3];
+ size_t max_corner[3];
+ size_t size[3];
+ size_t whole_size[3];
+ H5O_istore_t istore;
+
+ if (!nz) {
+ if (!ny) {
+ ndims = 1;
+ ny = nz = 1;
+ sprintf (dims, "%d", nx);
+ } else {
+ ndims = 2;
+ nz = 1;
+ sprintf (dims, "%dx%d", nx, ny);
+ }
+ } else {
+ ndims = 3;
+ sprintf (dims, "%dx%dx%d", nx, ny, nz);
+ }
+
+
+ sprintf (s, "Testing istore extend: %s", dims);
+ printf ("%-70s", s);
+ fflush (stdout);
+ buf = H5MM_xmalloc (nx*ny*nz);
+ check = H5MM_xmalloc (nx*ny*nz);
+ whole = H5MM_xcalloc (nx*ny*nz, 1);
+
+ /* Build the new empty object */
+ sprintf (name, "%s_%s", prefix, dims);
+ if (NULL==(handle=new_object (f, name, ndims))) {
+ if (!isatty (1)) {
+ AT ();
+ printf (" Cannot create %d-d object `%s'\n", ndims, name);
+ }
+ goto error;
+ }
+ if (NULL==H5O_read (f, H5O_NO_ADDR, handle, H5O_ISTORE, 0, &istore)) {
+ puts ("*FAILED*");
+ if (!isatty (1)) {
+ AT ();
+ printf (" Unable to read istore message\n");
+ }
+ goto error;
+ }
+ if (ndims!=istore.ndims) {
+ puts ("*FAILED*");
+ if (!isatty (1)) {
+ AT ();
+ printf (" Header read error: istore.ndims != %d\n", ndims);
+ }
+ goto error;
+ }
+
+ whole_size[0] = nx;
+ whole_size[1] = ny;
+ whole_size[2] = nz;
+ max_corner[0] = 0;
+ max_corner[1] = 0;
+ max_corner[2] = 0;
+
+ for (ctr=0; H5V_vector_lt (ndims, max_corner, whole_size); ctr++) {
+
+ /* Size and location */
+ if (0==ctr) {
+ offset[0] = offset[1] = offset[2] = 0;
+ size[0] = size[1] = size[2] = 1;
+ } else {
+ for (i=0; i<ndims; i++) {
+ if (ctr % ndims == i) {
+ offset[i] = max_corner[i];
+ size[i] = 1;
+ if (offset[i]+size[i]>whole_size[i]) continue;
+ } else {
+ offset[i] = 0;
+ size[i] = max_corner[i];
+ }
+ }
+ }
+
+#if 0
+ if (0==ctr) printf ("\n");
+ printf (" Insert: ctr=%d, corner=(%d", ctr, offset[0]);
+ if (ndims>1) printf (",%d", offset[1]);
+ if (ndims>2) printf (",%d", offset[2]);
+ printf ("), size=(%d", size[0]);
+ if (ndims>1) printf (",%d", size[1]);
+ if (ndims>2) printf (",%d", size[2]);
+ printf (")\n");
+#endif
+
+ /* Fill the source array */
+ memset (buf, 128+ctr, size[0]*size[1]*size[2]);
+
+ /* Write to disk */
+ if (H5F_istore_write (f, &istore, offset, size, buf)<0) {
+ puts ("*FAILED*");
+ if (!isatty (1)) {
+ AT ();
+ printf (" Write failed: ctr=%d\n", ctr);
+ }
+ goto error;
+ }
+
+ /* Read from disk */
+ memset (check, 0xff, size[0]*size[1]*size[2]);
+ if (H5F_istore_read (f, &istore, offset, size, check)<0) {
+ puts ("*FAILED*");
+ if (!isatty (1)) {
+ AT ();
+ printf (" Read failed: ctr=%d\n", ctr);
+ }
+ goto error;
+ }
+ if (memcmp (buf, check, size[0]*size[1]*size[2])) {
+ puts ("*FAILED*");
+ if (!isatty (1)) {
+ AT ();
+ printf (" Read check failed: ctr=%d\n", ctr);
+ printf (" Wrote:\n");
+ print_array (buf, size[0], size[1], size[2]);
+ printf (" Read:\n");
+ print_array (buf, size[0], size[1], size[2]);
+ }
+ goto error;
+ }
+
+ /* Write to `whole' buffer for later checking */
+ H5V_hyper_copy (ndims, size,
+ whole_size, offset, whole, /*dst*/
+ size, H5V_ZERO, buf); /*src*/
+
+ /* Update max corner */
+ for (i=0; i<ndims; i++) {
+ max_corner[i] = MAX (max_corner[i], offset[i]+size[i]);
+ }
+ }
+
+ /* Update the object header */
+ H5O_modify (f, H5O_NO_ADDR, handle, H5O_ISTORE, 0, &istore);
+
+
+ /* Now read the entire array back out and check it */
+ memset (buf, 0xff, nx*ny*nz);
+ if (H5F_istore_read (f, &istore, H5V_ZERO, whole_size, buf)<0) {
+ puts ("*FAILED*");
+ if (!isatty (1)) {
+ AT ();
+ printf (" Read failed for whole array\n");
+ }
+ goto error;
+ }
+ for (i=0; i<nx; i++) {
+ for (j=0; j<ny; j++) {
+ for (k=0; k<nz; k++) {
+ if (whole[i*ny*nz + j*nz + k] != buf[i*ny*nz + j*nz + k]) {
+ puts ("*FAILED*");
+ if (!isatty (1)) {
+ AT ();
+ printf (" Check failed at i=%d", i);
+ if (ndims>1) printf (", j=%d", j);
+ if (ndims>2) printf (", k=%d\n", k);
+ printf (" Check array is:\n");
+ print_array (whole, nx, ny, nz);
+ printf (" Value read is:\n");
+ print_array (buf, nx, ny, nz);
+ }
+ goto error;
+ }
+ }
+ }
+ }
+
+ H5G_close (f, handle);
+ puts (" PASSED");
+ H5MM_xfree (buf);
+ H5MM_xfree (check);
+ H5MM_xfree (whole);
+ return SUCCEED;
+
+ error:
+ H5MM_xfree (buf);
+ H5MM_xfree (check);
+ H5MM_xfree (whole);
+ return FAIL;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: Tests indexed storage stuff.
+ *
+ * Return: Success: exit(0)
+ *
+ * Failure: exit(non-zero)
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 15, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main (void)
+{
+ H5F_t *f;
+ herr_t status;
+ int nerrors = 0;
+
+ /* Create the test file */
+ if (NULL==(f=H5F_open (FILENAME, H5F_ACC_CREAT|H5F_ACC_WRITE|H5F_ACC_TRUNC,
+ NULL))) {
+ printf ("Cannot create file %s; test aborted\n", FILENAME);
+ exit (1);
+ }
+
+ /*----------------------
+ * INDEXED STORAGE TESTS
+ *----------------------
+ */
+ status = test_create (f, "test_create_1");
+ nerrors += status<0 ? 1 : 0;
+
+ status = test_extend (f, "test_extend_1", 10, 0, 0);
+ nerrors += status<0 ? 1 : 0;
+ status = test_extend (f, "test_extend_1", 10, 10, 0);
+ nerrors += status<0 ? 1 : 0;
+ status = test_extend (f, "test_extend_1", 10, 10, 10);
+ nerrors += status<0 ? 1 : 0;
+
+
+
+
+
+ /* Close the test file and exit */
+ H5F_close (f);
+ if (nerrors) {
+ printf ("***** %d I-STORE TEST%s FAILED! *****\n",
+ nerrors, 1==nerrors?"":"S");
+ if (isatty (1)) {
+ printf ("(Redirect output to a pager or a file to see "
+ "debug output)\n");
+ }
+ exit (1);
+ }
+
+ printf ("All i-store tests passed.\n");
+ exit (0);
+}
diff --git a/test/tstab.c b/test/tstab.c
index 652029f..d2f6de4 100644
--- a/test/tstab.c
+++ b/test/tstab.c
@@ -84,7 +84,7 @@ test_1 (void)
*/
HDmemset (&dir_ent, 0, sizeof(H5G_entry_t));
HDmemset (&ent1, 0, sizeof(H5G_entry_t));
- status = H5G_find (f, NULL, &dir_ent, "/", &ent1);
+ status = H5G_find (f, "/", &dir_ent, &ent1);
CHECK_I (status, "H5G_find");
VERIFY (dir_ent.header, 0, "H5G_find");
VERIFY (ent1.header, obj1->header, "H5G_find");
@@ -107,7 +107,7 @@ test_1 (void)
/* try to read the first object */
HDmemset (&ent1, 0, sizeof(H5G_entry_t));
- status = H5G_find (f, NULL, NULL, "/Root Object", &ent1);
+ status = H5G_find (f, "/Root Object", NULL, &ent1);
CHECK_I (status, "H5G_find");
VERIFY (ent1.header, obj1->header, "H5G_find");
@@ -151,7 +151,7 @@ test_1 (void)
*/
HDmemset (&dir_ent, 0, sizeof(H5G_entry_t));
HDmemset (&ent1, 0, sizeof(H5G_entry_t));
- status = H5G_find (f, NULL, &dir_ent, "/", &ent1);
+ status = H5G_find (f, "/", &dir_ent, &ent1);
CHECK_I (status, "H5G_find");
VERIFY (dir_ent.header, 0, "H5G_find");
VERIFY (ent1.header, obj1->header, "H5G_find");
@@ -163,7 +163,7 @@ test_1 (void)
/* now as `/foo' */
HDmemset (&dir_ent, 0, sizeof(H5G_entry_t));
HDmemset (&ent1, 0, sizeof(H5G_entry_t));
- status = H5G_find (f, NULL, &dir_ent, "/foo", &ent1);
+ status = H5G_find (f, "/foo", &dir_ent, &ent1);
CHECK_I (status, "H5G_find");
VERIFY (dir_ent.header, 0, "H5G_find");
VERIFY (ent1.header, obj1->header, "H5G_find");
@@ -185,7 +185,7 @@ test_1 (void)
/* try to read the first object */
HDmemset (&ent1, 0, sizeof(H5G_entry_t));
- status = H5G_find (f, NULL, NULL, "/foo", &ent1);
+ status = H5G_find (f, "/foo", NULL, &ent1);
CHECK_I (status, "H5G_find");
VERIFY (ent1.header, obj1->header, "H5G_find");
@@ -243,7 +243,7 @@ test_2 (void)
* Create a directory that has so many entries that the root
* of the B-tree ends up splitting.
*/
- obj1 = H5G_mkdir (f, "/big", nsyms*12+2);
+ obj1 = H5G_new (f, "/big", nsyms*12+2);
CHECK_PTR (obj1, "H5G_mkdir");
H5G_close (f, obj1);
obj1 = NULL;