Resolve conflicts.
authorjbj <devnull@localhost>
Mon, 15 Oct 2001 03:54:05 +0000 (03:54 +0000)
committerjbj <devnull@localhost>
Mon, 15 Oct 2001 03:54:05 +0000 (03:54 +0000)
CVS patchset: 5111
CVS date: 2001/10/15 03:54:05

16 files changed:
db/dist/configure.ac
db/dist/pubdef.in
db/docs/api_java/dbt_bulk_class.html
db/docs/ref/transapp/faq.html
db/hash/hash_verify.c
db/include/log.h
db/log/log.c
db/log/log_rec.c
db/mp/mp_fopen.c
db/os/os_map.c
db/test/bigfile001.tcl
db/test/bigfile002.tcl
db/test/env009.tcl
db/test/rpc003.tcl
db/test/test095.tcl
db/test/test096.tcl

index c19a4b7..104606a 100644 (file)
@@ -1,4 +1,4 @@
-# Id: configure.ac,v 11.100 2001/07/10 15:13:48 bostic Exp 
+# Id: configure.ac,v 11.116 2001/10/11 20:29:35 bostic Exp 
 # Process this file with autoconf to produce a configure script.
 
 PACKAGE=db
@@ -19,7 +19,6 @@ AC_MSG_RESULT(no)
 # Substitution variables.
 AC_SUBST(ADDITIONAL_INCS)
 AC_SUBST(ADDITIONAL_LANG)
-AC_SUBST(ADDITIONAL_LIBS)
 AC_SUBST(ADDITIONAL_OBJS)
 AC_SUBST(ADDITIONAL_PROGS)
 AC_SUBST(BUILD_TARGET)
@@ -39,7 +38,6 @@ AC_SUBST(INSTALLER)
 AC_SUBST(INSTALL_LIBS)
 AC_SUBST(INSTALL_TARGET)
 AC_SUBST(JAR)
-AC_SUBST(JAVAC)
 AC_SUBST(JAVACFLAGS)
 AC_SUBST(LDFLAGS)
 AC_SUBST(LIBJSO_LIBS)
@@ -50,14 +48,15 @@ AC_SUBST(LIBTSO_LIBS)
 AC_SUBST(LIBXSO_LIBS)
 AC_SUBST(MAKEFILE_CC)
 AC_SUBST(MAKEFILE_CCLINK)
+AC_SUBST(MAKEFILE_SOLINK)
 AC_SUBST(MAKEFILE_CXX)
 AC_SUBST(MAKEFILE_CXXLINK)
+AC_SUBST(MAKEFILE_XSOLINK)
 AC_SUBST(POSTLINK)
 AC_SUBST(RPC_CLIENT_OBJS)
 AC_SUBST(RPM_POST_INSTALL)
 AC_SUBST(RPM_POST_UNINSTALL)
 AC_SUBST(SOFLAGS)
-AC_SUBST(SOLINK)
 AC_SUBST(SOSUFFIX)
 AC_SUBST(TEST_LIBS)
 AC_SUBST(db_cv_path_embedix_install)
@@ -147,32 +146,43 @@ fi
 # Don't override anything if it's already set from the environment.
 optimize_def="-O"
 case "$host_os" in
-aix4.*)           optimize_def="-O2"
-          CC=${CC-"xlc_r"}
-          CPPFLAGS="-D_THREAD_SAFE $CPPFLAGS"
-          LIBTSO_LIBS="\$(LIBS)";;
-bsdi3*)           CC=${CC-"shlicc2"}
-          optimize_def="-O2"
-          LIBS="-lipc $LIBS";;
-bsdi*)    optimize_def="-O2";;
-freebsd*)  optimize_def="-O2"
-          CPPFLAGS="-D_THREAD_SAFE $CPPFLAGS"
-           LIBS="-pthread";;
-hpux*)    CPPFLAGS="-D_REENTRANT $CPPFLAGS";;
-irix*)    optimize_def="-O2"
-          CPPFLAGS="-D_SGI_MP_SOURCE $CPPFLAGS";;
-linux*)           optimize_def="-O2"
-          CPPFLAGS="-D_GNU_SOURCE -D_REENTRANT $CPPFLAGS";;
-mpeix*)           CPPFLAGS="-D_POSIX_SOURCE -D_SOCKET_SOURCE $CPPFLAGS"
-          LIBS="-lsocket -lsvipc $LIBS";;
-osf*)     CPPFLAGS="-D_REENTRANT $CPPFLAGS";;
-*qnx)     AC_DEFINE(HAVE_QNX)
-          AH_TEMPLATE(HAVE_QNX, [Define if building on QNX.]);;
-sco3.2v4*) CC=${CC-"cc -belf"}
-          LIBS="-lsocket -lnsl_s $LIBS";;
-sco*)     CC=${CC-"cc -belf"}
-          LIBS="-lsocket -lnsl $LIBS";;
-solaris*)  CPPFLAGS="-D_REENTRANT $CPPFLAGS";;
+aix4.3.[12])
+       optimize_def="-O2"
+       CC=${CC-"xlc_r"}
+       CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE"
+       LIBTSO_LIBS="\$(LIBS)";;
+aix4.3.3)
+       optimize_def="-O2"
+       CC=${CC-"xlc_r"}
+       CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE"
+       LDFLAGS="$LDFLAGS -pthread"
+       LIBTSO_LIBS="\$(LIBS)";;
+bsdi3*)        optimize_def="-O2"
+       CC=${CC-"shlicc2"}
+       LIBS="$LIBS -lipc";;
+bsdi*) optimize_def="-O2";;
+freebsd*)
+       optimize_def="-O2"
+       CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE"
+       LDFLAGS="$LDFLAGS -pthread";;
+hpux*) CPPFLAGS="$CPPFLAGS -D_REENTRANT";;
+irix*) optimize_def="-O2"
+       CPPFLAGS="$CPPFLAGS -D_SGI_MP_SOURCE";;
+linux*)        optimize_def="-O2"
+       CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE -D_REENTRANT";;
+mpeix*)        CPPFLAGS="$CPPFLAGS -D_POSIX_SOURCE -D_SOCKET_SOURCE"
+       LIBS="$LIBS -lsocket -lsvipc";;
+osf*)  CPPFLAGS="$CPPFLAGS -D_REENTRANT"
+       LDFLAGS="$LDFLAGS -pthread";;
+*qnx)  AC_DEFINE(HAVE_QNX)
+       AH_TEMPLATE(HAVE_QNX, [Define if building on QNX.]);;
+sco3.2v4*)
+       CC=${CC-"cc -belf"}
+       LIBS="$LIBS -lsocket -lnsl_s";;
+sco*)  CC=${CC-"cc -belf"}
+       LIBS="$LIBS -lsocket -lnsl";;
+solaris*)
+       CPPFLAGS="$CPPFLAGS -D_REENTRANT";;
 esac
 
 # Set CFLAGS/CXXFLAGS.  We MUST set the flags before we call autoconf
@@ -204,8 +214,8 @@ AC_PROG_CC
 # Because of shared library building, the ${CC} used for config tests
 # may be different than the ${CC} we want to put in the Makefile.
 # The latter is known as ${MAKEFILE_CC} in this script.
-MAKEFILE_CC=${CC}
-MAKEFILE_CCLINK="\$(CC)"
+MAKEFILE_CC="${CC}"
+MAKEFILE_CCLINK="${CC}"
 MAKEFILE_CXX="nocxx"
 MAKEFILE_CXXLINK="nocxx"
 
@@ -219,15 +229,17 @@ MAKEFILE_CXXLINK="nocxx"
 if test "$db_cv_cxx" = "yes"; then
        if test "$GCC" != "yes"; then
                case "$host_os" in
-               aix*)           AC_CHECK_TOOL(CCC, xlC_r);;
+               aix*)           AC_CHECK_TOOL(CCC, xlC_r)
+                               LIBXSO_LIBS="-lC_r $LIBXSO_LIBS"
+                               LIBS="-lC_r $LIBS";;
                hpux*)          AC_CHECK_TOOL(CCC, aCC);;
                osf*)           AC_CHECK_TOOL(CCC, cxx);;
                solaris*)       AC_CHECK_TOOL(CCC, CC);;
                esac
        fi
        AC_PROG_CXX
-       MAKEFILE_CXX=${CXX}
-       MAKEFILE_CXXLINK="\$(CXX)"
+       MAKEFILE_CXX="${CXX}"
+       MAKEFILE_CXXLINK="${CXX}"
 fi
 
 # Do some gcc specific configuration.
@@ -242,19 +254,37 @@ CCC=CXX
 AC_PROG_LIBTOOL
 
 LIBTOOL="\$(SHELL) ./libtool"
-SOSUFFIX=`sed -e '/^library_names_spec=/!d' -e 's/.*\.\([[a-zA-Z0-9_]]*\).*/\1/' ./libtool`
 SOFLAGS="-rpath \$(libdir)"
 
-SAVE_CC="${MAKEFILE_CC}"
-SAVE_CXX="${MAKEFILE_CXX}"
-MAKEFILE_CC="\$(LIBTOOL) --mode=compile ${SAVE_CC}"
-MAKEFILE_CXX="\$(LIBTOOL) --mode=compile ${SAVE_CXX}"
-MAKEFILE_CCLINK="\$(LIBTOOL) --mode=link ${SAVE_CC}"
-MAKEFILE_CXXLINK="\$(LIBTOOL) --mode=link ${SAVE_CXX}"
+AC_MSG_CHECKING([SOSUFFIX from libtool])
+# $library_names_spec is a snippet of shell that may
+# defined in terms of $versuffix, $release, $libname.
+# All we want is to eval it and grab the suffix used
+# for shared objects.
+versuffix=""
+release=""
+libname=libfoo
+eval library_names=\"$library_names_spec\"
+SOSUFFIX=`echo "$library_names" | sed -e 's/.*\.\([[a-zA-Z0-9_]]*\).*/\1/'`
+AC_MSG_RESULT($SOSUFFIX)
+
+if test "$SOSUFFIX" = '' ; then
+       SOSUFFIX=so
+       if test "$enable_shared" = "yes"; then
+               AC_MSG_WARN([libtool may not know about this architecture.])
+               AC_MSG_WARN([assuming .$SOSUFFIX suffix for dynamic libraries.])
+       fi
+fi
 
-SOLINK="\$(LIBTOOL) --mode=link ${SAVE_CC} -avoid-version"
 INSTALLER="\$(LIBTOOL) --mode=install cp"
 
+MAKEFILE_CC="\$(LIBTOOL) --mode=compile ${MAKEFILE_CC}"
+MAKEFILE_SOLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CCLINK} -avoid-version"
+MAKEFILE_CCLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CCLINK}"
+MAKEFILE_CXX="\$(LIBTOOL) --mode=compile ${MAKEFILE_CXX}"
+MAKEFILE_XSOLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CXXLINK} -avoid-version"
+MAKEFILE_CXXLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CXXLINK}"
+
 # Configure for shared libraries, static libraries, or both.  If both are
 # configured, build the utilities and example programs with shared versions.
 #
@@ -262,28 +292,25 @@ INSTALLER="\$(LIBTOOL) --mode=install cp"
 # instead of .o
 if test "$enable_shared" = "no"; then
        DEFAULT_LIB="\$(libdb)"
-       DEFAULT_LIB_CXX="\$(libcxx)"
-       DEFAULT_INSTALL="install_static"
        POSTLINK="@true"
        o=".o"
 fi
 if test "$enable_shared" = "yes"; then
        DEFAULT_LIB="\$(libso_target)"
-       DEFAULT_LIB_CXX="\$(libxso_target)"
-       DEFAULT_INSTALL="${DEFAULT_INSTALL} install_shared"
        POSTLINK="\$(LIBTOOL) --mode=execute true"
        o=".lo"
 fi
+INSTALL_LIBS="$DEFAULT_LIB"
 
 # Optional C++ API.
 if test "$db_cv_cxx" = "yes"; then
        if test "$enable_shared" = "no"; then
-               DEFAULT_INSTALL="${DEFAULT_INSTALL} install_static_cxx"
+               DEFAULT_LIB_CXX="\$(libcxx)"
        fi
        if test "$enable_shared" = "yes"; then
-               ADDITIONAL_LIBS="$ADDITIONAL_LIBS \$(libxso_target)"
-               DEFAULT_INSTALL="${DEFAULT_INSTALL} install_shared_cxx"
+               DEFAULT_LIB_CXX="\$(libxso_target)"
        fi
+       INSTALL_LIBS="$INSTALL_LIBS $DEFAULT_LIB_CXX"
 
        # Fill in C++ library for Embedix.
        EMBEDIX_ECD_CXX='<OPTION db-extra>\
@@ -314,60 +341,17 @@ if test "$db_cv_java" = "yes"; then
                AC_MSG_ERROR([Java requires shared libraries])
        fi
 
-       AC_CHECK_TOOL(JAVAC, javac, nojavac)
-       if test "$JAVAC" = "nojavac"; then
-               AC_MSG_ERROR([no javac compiler in PATH])
-       fi
-       AC_CHECK_TOOL(JAR, jar, nojar)
-       if test "$JAR" = "nojar"; then
-               AC_MSG_ERROR([no jar utility in PATH])
-       fi
-       AC_PATH_PROG(JAVACABS, javac, nojavac)
-       ADDITIONAL_LIBS="$ADDITIONAL_LIBS \$(libjso_target)"
-       ADDITIONAL_LANG="$ADDITIONAL_LANG java"
-       DEFAULT_INSTALL="${DEFAULT_INSTALL} install_java"
-
-# find the include directory relative to the javac executable
-       while ls -ld "$JAVACABS" 2>/dev/null | grep " -> " >/dev/null; do
-               AC_MSG_CHECKING(symlink for $JAVACABS)
-               JAVACLINK=`ls -ld $JAVACABS | sed 's/.* -> //'`
-               case "$JAVACLINK" in
-               /*) JAVACABS="$JAVACLINK";;
-# 'X' avoids triggering unwanted echo options.
-               *) JAVACABS=`echo "X$JAVACABS" | sed -e 's/^X//' -e 's:[[^/]]*$::'`"$JAVACLINK";;
-               esac
-               AC_MSG_RESULT($JAVACABS)
-       done
-       JTOPDIR=`echo "$JAVACABS" | sed -e 's://*:/:g' -e 's:/[[^/]]*$::'`
-       case "$host_os" in
-               darwin*)        JTOPDIR=`echo "$JTOPDIR" | sed -e s:/[[^/]]*$::'`
-                               JNIHEADERDIR="$JTOPDIR/Headers";;
-               *)              JNIHEADERDIR="$JTOPDIR/include";;
-       esac
-       if test -f "$JNIHEADERDIR/jni.h"; then
-               CPPFLAGS="$CPPFLAGSS -I$JNIHEADERDIR"
-       else
-               JTOPDIR=`echo "$JTOPDIR" | sed -e 's:/[[^/]]*$::'`
-               if test -f "$JTOPDIR/include/jni.h"; then
-                       CPPFLAGS="$CPPFLAGS -I$JTOPDIR/include"
-               else
-                       AC_MSG_ERROR([cannot find java include files])
-               fi
-       fi
-
-# get the likely subdirectories for system specific java includes
-       case "$host_os" in
-       solaris*)       JINCSUBDIRS="solaris";;
-       linux*)         JINCSUBDIRS="linux genunix";;
-       *)              JINCSUBDIRS="genunix";;
-       esac
+       AC_PROG_JAVAC
+       AC_PROG_JAR
+        AC_JNI_INCLUDE_DIR
 
-       for JINCSUBDIR in $JINCSUBDIRS
+       for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS
        do
-               if test -d "$JTOPDIR/include/$JINCSUBDIR"; then
-                       CPPFLAGS="$CPPFLAGS -I$JTOPDIR/include/$JINCSUBDIR"
-               fi
+               CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR"
        done
+
+       ADDITIONAL_LANG="$ADDITIONAL_LANG java"
+       INSTALL_LIBS="$INSTALL_LIBS \$(libjso_target)"
 else
        JAVAC=nojavac
 fi
@@ -405,11 +389,6 @@ if test "$db_cv_dump185" = "yes"; then
        ADDITIONAL_PROGS="db_dump185 $ADDITIONAL_PROGS"
 fi
 
-# test servers, example programs.
-# Include -lpthread if the library exists.
-AC_CHECK_LIB(rt, sched_yield, TEST_LIBS="-lrt $TEST_LIBS")
-AC_CHECK_LIB(pthread, pthread_create, TEST_LIBS="-lpthread $TEST_LIBS")
-
 # Checks for system/compiler characteristics.
 AC_C_BIGENDIAN
 AC_C_CONST
@@ -425,17 +404,40 @@ AC_CHECK_MEMBERS([struct stat.st_blksize])
 # Check for C types.
 AM_TYPES
 
-# Check for ANSI C exit success/failure values.
-AC_EGREP_CPP(yes, [
-    #include <stdlib.h>
-    #ifdef EXIT_SUCCESS
-    yes
-    #endif], [
-    AC_DEFINE(HAVE_EXIT_SUCCESS)
-    AH_TEMPLATE(HAVE_EXIT_SUCCESS, [
-        Define if you have EXIT_SUCCESS/EXIT_FAILURE #defines.])])
-
-# Check for mutexes.  We do this here because it changes $LIBS.
+AC_CACHE_CHECK([for ANSI C exit success/failure values], db_cv_exit_defines, [
+AC_TRY_COMPILE([#include <stdlib.h>], return (EXIT_SUCCESS);,
+    [db_cv_exit_defines=yes], [db_cv_exit_defines=no])])
+if test "$db_cv_exit_defines" = yes; then
+       AC_DEFINE(HAVE_EXIT_SUCCESS)
+       AH_TEMPLATE(HAVE_EXIT_SUCCESS, [
+           Define if you have EXIT_SUCCESS/EXIT_FAILURE #defines.])
+fi
+
+# Test for sched_yield, the test programs use it.
+# We do this here because it changes $LIBS.
+AC_MSG_CHECKING([for sched_yield in current configuration])
+AC_TRY_LINK([#include <sched.h>],(void)sched_yield();,
+    AC_MSG_RESULT(yes), [
+       AC_MSG_RESULT(no)
+       AC_MSG_CHECKING([for sched_yield in -lrt])
+       saved_libs=$LIBS
+       LIBS="$LIBS -lrt"
+       AC_TRY_LINK([#include <sched.h>],(void)sched_yield();,
+           AC_MSG_RESULT(yes), LIBS="$saved_libs"; AC_MSG_RESULT(no))])
+
+# Test for a pthreads library, the test programs use it.
+# We do this here because it changes $LIBS.
+#
+# XXX
+# We can't do checking similar to the above because the Solaris C library
+# includes pthread interfaces which are not thread-safe.  For that reason
+# we always add -lpthread if we can find a pthread library.  Also we can't
+# depend on any specific call existing (pthread_create, for example), as
+# it may be #defined in an include file -- OSF/1 (Tru64) has this problem.
+AC_CHECK_LIB(pthread, main, TEST_LIBS="$TEST_LIBS -lpthread")
+
+# Check for mutexes.
+# We do this here because it changes $LIBS.
 AM_DEFINE_MUTEXES
 
 # Checks for system functions for which we have replacements.
@@ -456,7 +458,7 @@ LIBOBJS="$tmp"
 
 # Check for system functions we optionally use.
 AC_CHECK_FUNCS(_fstati64 getuid pstat_getdynamic sched_yield select strtoul)
-AC_CHECK_FUNCS(sysconf yield)
+AC_CHECK_FUNCS(gettimeofday clock_gettime sysconf yield)
 
 # Pread/pwrite.
 #
@@ -569,17 +571,17 @@ CREATE_LIST="Makefile
 # file.  If the user has requested unique names, use the file that does
 # DB_VERSION_UNIQUE_NAME substitution.
 if test "$db_cv_uniquename" = "yes"; then
-    CREATE_LIST="${CREATE_LIST}
+    CREATE_LIST="$CREATE_LIST
     db.h:$srcdir/../include/db.in:$srcdir/../include_auto/rpc_defs.in:$srcdir/../include_auto/global_uext.in"
 else
-    CREATE_LIST="${CREATE_LIST}
+    CREATE_LIST="$CREATE_LIST
     db.h:$srcdir/../include/db.in:$srcdir/../include_auto/rpc_defs.in:$srcdir/../include_auto/global_ext.in"
 fi
 
 # Create the function prototype include files.  If the user has requested
 # unique names, use the files that do DB_VERSION_UNIQUE_NAME substitution.
 if test "$db_cv_uniquename" = "yes"; then
-    CREATE_LIST="${CREATE_LIST}
+    CREATE_LIST="$CREATE_LIST
     db_ext.h:$srcdir/../include_auto/db_ext.in
     btree_ext.h:$srcdir/../include_auto/btree_ext.in
     clib_ext.h:$srcdir/../include_auto/clib_ext.in
@@ -593,6 +595,7 @@ if test "$db_cv_uniquename" = "yes"; then
     mutex_ext.h:$srcdir/../include_auto/mutex_ext.in
     os_ext.h:$srcdir/../include_auto/os_ext.in
     qam_ext.h:$srcdir/../include_auto/qam_ext.in
+    rep_ext.h:$srcdir/../include_auto/rep_ext.in
     rpc_client_ext.h:$srcdir/../include_auto/rpc_client_ext.in
     rpc_server_ext.h:$srcdir/../include_auto/rpc_server_ext.in
     tcl_ext.h:$srcdir/../include_auto/tcl_ext.in
@@ -601,21 +604,21 @@ if test "$db_cv_uniquename" = "yes"; then
 fi
 if test "$db_cv_compat185" = "yes"; then
        if test "$db_cv_uniquename" = "yes"; then
-               CREATE_LIST="${CREATE_LIST}
+               CREATE_LIST="$CREATE_LIST
 db_185.h:$srcdir/../include/db_185.in:$srcdir/../include_auto/db185_uext.in
 db185_int.h:$srcdir/../db185/db185_int.in:$srcdir/../include_auto/db185_uext.in"
        else
-               CREATE_LIST="${CREATE_LIST}
+               CREATE_LIST="$CREATE_LIST
 db_185.h:$srcdir/../include/db_185.in:$srcdir/../include_auto/db185_ext.in
 db185_int.h:$srcdir/../db185/db185_int.in:$srcdir/../include_auto/db185_ext.in"
        fi
 fi
 if test "$db_cv_embedix" = "yes"; then
-       CREATE_LIST="${CREATE_LIST} db.ecd:../dist/db.ecd.in"
+       CREATE_LIST="$CREATE_LIST db.ecd:../dist/db.ecd.in"
 fi
 if test "$db_cv_rpm" = "yes"; then
-       CREATE_LIST="${CREATE_LIST} db.spec:../dist/db.spec.in"
+       CREATE_LIST="$CREATE_LIST db.spec:../dist/db.spec.in"
 fi
 
-AC_CONFIG_FILES(${CREATE_LIST})
+AC_CONFIG_FILES($CREATE_LIST)
 AC_OUTPUT
index 4656874..3197d96 100644 (file)
@@ -1,8 +1,8 @@
 # Name
-# C == Java case value
 # D == documentation
 # I == include file
-# J == Java constant
+# C == Java case value (declared and initialized)
+# J == Java constant (declared only)
 DB_AFTER               D I J
 DB_AGGRESSIVE          D I J
 DB_ALREADY_ABORTED     * I *
@@ -20,10 +20,12 @@ DB_AM_SWAP          * I *
 DB_AM_TXN              * I *
 DB_AM_VERIFYING                * I *
 DB_APPEND              D I J
+DB_APPLY_LOGREG                * I *
 DB_ARCH_ABS            D I J
 DB_ARCH_DATA           D I J
 DB_ARCH_LOG            D I J
 DB_BEFORE              D I J
+DB_BROADCAST_EID       D I J
 DB_BTREE               * I C
 DB_BTREEMAGIC          * I *
 DB_BTREEOLDVER         * I *
@@ -34,6 +36,7 @@ DB_CACHED_COUNTS      D I J
 DB_CDB_ALLDB           D I J
 DB_CHECKPOINT          D I J
 DB_CLIENT              D I J
+DB_CL_WRITER           * I *
 DB_COMMIT              * I *
 DB_CONFIG              D * *
 DB_CONSUME             D I J
@@ -62,10 +65,15 @@ DB_ENV_CDB_ALLDB    * I *
 DB_ENV_CREATE          * I *
 DB_ENV_DBLOCAL         * I *
 DB_ENV_LOCKDOWN                * I *
+DB_ENV_NOLOCKING       * I *
 DB_ENV_NOMMAP          * I *
+DB_ENV_NOPANIC         * I *
 DB_ENV_OPEN_CALLED     * I *
-DB_ENV_PANIC_OK                * I *
 DB_ENV_PRIVATE         * I *
+DB_ENV_REGION_INIT     * I *
+DB_ENV_REP_CLIENT      * I *
+DB_ENV_REP_LOGSONLY    * I *
+DB_ENV_REP_MASTER      * I *
 DB_ENV_RPCCLIENT       * I *
 DB_ENV_RPCCLIENT_GIVEN * I *
 DB_ENV_STANDALONE      * I *
@@ -73,6 +81,7 @@ DB_ENV_SYSTEM_MEM     * I *
 DB_ENV_THREAD          * I *
 DB_ENV_TXN_NOSYNC      * I *
 DB_ENV_USER_ALLOC      * I *
+DB_ENV_YIELDCPU                * I *
 DB_EXCL                        D I J
 DB_EXTENT              * I *
 DB_FAST_STAT           D I J
@@ -83,6 +92,7 @@ DB_FLUSH              D I J
 DB_FORCE               D I J
 DB_GET_BOTH            D I J
 DB_GET_BOTHC           * I *
+DB_GET_BOTH_RANGE      D I J
 DB_GET_RECNO           D I J
 DB_HASH                        * I C
 DB_HASHMAGIC           * I *
@@ -95,6 +105,7 @@ DB_INIT_LOCK         D I J
 DB_INIT_LOG            D I J
 DB_INIT_MPOOL          D I J
 DB_INIT_TXN            D I J
+DB_INVALID_EID         * I *
 DB_JAVA_CALLBACK       * I *
 DB_JOINENV             D I J
 DB_JOIN_ITEM           D I J
@@ -110,7 +121,10 @@ DB_LOCK_DEADLOCK   D I C
 DB_LOCK_DEFAULT                D I J
 DB_LOCK_DIRTY          * I *
 DB_LOCK_DUMP           * I *
+DB_LOCK_EXPIRE         D I J
+DB_LOCK_FREE_LOCKER    * I *
 DB_LOCK_GET            D I J
+DB_LOCK_GET_TIMEOUT    D I J
 DB_LOCK_INHERIT                * I *
 DB_LOCK_IREAD          * I J
 DB_LOCK_IWR            * I J
@@ -126,25 +140,32 @@ DB_LOCK_OLDEST            D I J
 DB_LOCK_PUT            D I J
 DB_LOCK_PUT_ALL                D I J
 DB_LOCK_PUT_OBJ                D I J
+DB_LOCK_PUT_READ       * I *
 DB_LOCK_RANDOM         D I J
 DB_LOCK_READ           * I J
 DB_LOCK_RECORD         * I *
+DB_LOCK_SET_TIMEOUT    * I *
 DB_LOCK_SWITCH         * I *
+DB_LOCK_TIMEOUT                D I J
 DB_LOCK_UPGRADE                * I *
 DB_LOCK_UPGRADE_WRITE  * I *
 DB_LOCK_WAIT           * I *
 DB_LOCK_WRITE          * I J
 DB_LOCK_WWRITE         * I *
 DB_LOCK_YOUNGEST       D I J
+DB_LOGC_BUF_SIZE       * I *
 DB_LOGFILEID_INVALID   * I *
 DB_LOGMAGIC            * I *
 DB_LOGOLDVER           * I *
 DB_LOGVERSION          * I *
+DB_LOG_DISK            * I *
+DB_LOG_LOCKED          * I *
+DB_LOG_SILENT_ERR      * I *
 DB_LSTAT_ABORTED       * I *
 DB_LSTAT_ERR           * I *
+DB_LSTAT_EXPIRED       * I *
 DB_LSTAT_FREE          * I *
 DB_LSTAT_HELD          * I *
-DB_LSTAT_NOGRANT       * I *
 DB_LSTAT_PENDING       * I *
 DB_LSTAT_WAITING       * I *
 DB_MAX_PAGES           * I *
@@ -155,7 +176,6 @@ DB_MPOOL_DIRTY              D I *
 DB_MPOOL_DISCARD       D I *
 DB_MPOOL_LAST          D I *
 DB_MPOOL_NEW           D I *
-DB_MPOOL_NEW_GROUP     * I *
 DB_MULTIPLE            D I J
 DB_MULTIPLE_INIT       D I *
 DB_MULTIPLE_KEY                D I J
@@ -167,15 +187,17 @@ DB_NEXT                   D I J
 DB_NEXT_DUP            D I J
 DB_NEXT_NODUP          D I J
 DB_NODUPDATA           D I J
+DB_NOLOCKING           D I J
 DB_NOMMAP              D I J
 DB_NOORDERCHK          D I J
 DB_NOOVERWRITE         D I J
+DB_NOPANIC             D I J
 DB_NOSERVER            D I C
 DB_NOSERVER_HOME       D I C
 DB_NOSERVER_ID         D I C
 DB_NOSYNC              D I J
 DB_NOTFOUND            D I C
-DB_ODDFILESIZE         * I *
+DB_ODDFILESIZE         D I J
 DB_OK_BTREE            * I *
 DB_OK_HASH             * I *
 DB_OK_QUEUE            * I *
@@ -186,6 +208,7 @@ DB_OPFLAGS_MASK             * I *
 DB_ORDERCHKONLY                D I J
 DB_PAGE_LOCK           * I *
 DB_PAGE_NOTFOUND       D I C
+DB_PANIC_ENVIRONMENT   D I J
 DB_POSITION            D I J
 DB_POSITIONI           * I *
 DB_PREV                        D I J
@@ -206,8 +229,19 @@ DB_RECORD_LOCK             * I *
 DB_RECOVER             D I J
 DB_RECOVER_FATAL       D I J
 DB_REDO                        * I *
+DB_REGION_INIT         D I J
 DB_REGION_MAGIC                * I *
 DB_RENUMBER            D I J
+DB_REP_CLIENT          D I J
+DB_REP_DUPMASTER       D I C
+DB_REP_HOLDELECTION    D I C
+DB_REP_LOGSONLY                D I J
+DB_REP_MASTER          D I J
+DB_REP_NEWMASTER       D I C
+DB_REP_NEWSITE         D I C
+DB_REP_OUTDATED                D I C
+DB_REP_PERMANENT       D I J
+DB_REP_UNAVAIL         D I J
 DB_REVSPLITOFF         D I J
 DB_RE_DELIMITER                * I *
 DB_RE_FIXEDLEN         * I *
@@ -219,9 +253,13 @@ DB_RUNRECOVERY             D I C
 DB_SALVAGE             D I J
 DB_SECONDARY_BAD       D I C
 DB_SET                 D I J
+DB_SET_LOCK_TIMEOUT    D I J
 DB_SET_RANGE           D I J
 DB_SET_RECNO           D I J
+DB_SET_TXN_NOW         * I *
+DB_SET_TXN_TIMEOUT     D I J
 DB_SNAPSHOT            D I J
+DB_STAT_CLEAR          D I J
 DB_SURPRISE_KID                * I *
 DB_SWAPBYTES           * I *
 DB_SYSTEM_MEM          D I J
@@ -233,9 +271,11 @@ DB_TEST_POSTSYNC   * I *
 DB_TEST_PREDESTROY     * I *
 DB_TEST_PREOPEN                * I *
 DB_THREAD              D I J
+DB_TIMEOUT             * I *
 DB_TRUNCATE            D I J
 DB_TXNVERSION          * I *
 DB_TXN_ABORT           D I C
+DB_TXN_APPLY           * I *
 DB_TXN_BACKWARD_ROLL   D I C
 DB_TXN_CKP             * I *
 DB_TXN_FORWARD_ROLL    D I C
@@ -265,3 +305,4 @@ DB_WRITECURSOR              D I J
 DB_WRITELOCK           * I *
 DB_XA_CREATE           D I J
 DB_XIDDATASIZE         D I J
+DB_YIELDCPU            D I J
index 26738c7..51bb116 100644 (file)
@@ -14,7 +14,7 @@
 <h1>DbMultipleDataIterator</h1>
 </td>
 <td align=right>
-<a href="../api_java/java_index.html"><img src="../images/api.gif" alt="API"></a><a href="../reftoc.html"><img src="../images/ref.gif" alt="Ref"></a>
+<a href="../api_java/c_index.html"><img src="../images/api.gif" alt="API"></a><a href="../reftoc.html"><img src="../images/ref.gif" alt="Ref"></a>
 </td></tr></table>
 <hr size=1 noshade>
 <tt>
@@ -85,7 +85,7 @@ more data are available, and true otherwise.
 </dl>
 </tt>
 <table width="100%"><tr><td><br></td><td align=right>
-<a href="../api_java/java_index.html"><img src="../images/api.gif" alt="API"></a><a href="../reftoc.html"><img src="../images/ref.gif" alt="Ref"></a>
+<a href="../api_java/c_index.html"><img src="../images/api.gif" alt="API"></a><a href="../reftoc.html"><img src="../images/ref.gif" alt="Ref"></a>
 </td></tr></table>
 <p><font size=1><a href="http://www.sleepycat.com">Copyright Sleepycat Software</a></font>
 </body>
index da331ce..c41ba28 100644 (file)
@@ -1,4 +1,4 @@
-<!--Id: faq.so,v 10.2 2001/07/06 13:15:47 bostic Exp -->
+<!--Id: faq.so,v 10.3 2001/10/13 19:56:25 bostic Exp -->
 <!--Copyright 1997-2001 by Sleepycat Software, Inc.-->
 <!--All rights reserved.-->
 <html>
@@ -11,7 +11,7 @@
 <a name="2"><!--meow--></a>
 <table width="100%"><tr valign=top>
 <td><h3><dl><dt>Berkeley DB Reference Guide:<dd>Berkeley DB Transactional Data Store Applications</dl></h3></td>
-<td align=right><a href="../../ref/transapp/throughput.html"><img src="../../images/prev.gif" alt="Prev"></a><a href="../../reftoc.html"><img src="../../images/ref.gif" alt="Ref"></a><a href="../../ref/xa/intro.html"><img src="../../images/next.gif" alt="Next"></a>
+<td align=right><a href="../../ref/transapp/throughput.html"><img src="../../images/prev.gif" alt="Prev"></a><a href="../../reftoc.html"><img src="../../images/ref.gif" alt="Ref"></a><a href="../../ref/rep/intro.html"><img src="../../images/next.gif" alt="Next"></a>
 </td></tr></table>
 <p>
 <h1 align=center>Transaction FAQ</h1>
@@ -28,11 +28,11 @@ errors are errors like <a href="../../ref/program/errorret.html#DB_NOTFOUND">DB_
 searched-for key item is not present in the database.  Applications may
 want to explicitly test for and handle this error, or, in the case where
 the absence of a key implies the enclosing transaction should fail,
-simply call <a href="../../api_c/txn_abort.html">txn_abort</a>.  Unexpected but recoverable errors are
+simply call <a href="../../api_c/txn_abort.html">DB_TXN-&gt;abort</a>.  Unexpected but recoverable errors are
 errors like <a href="../../ref/program/errorret.html#DB_LOCK_DEADLOCK">DB_LOCK_DEADLOCK</a>, which indicates that an operation
 has been selected to resolve a deadlock, or a system error such as EIO,
 which likely indicates that the filesystem has no available disk space.
-Applications must immediately call <a href="../../api_c/txn_abort.html">txn_abort</a> when these returns
+Applications must immediately call <a href="../../api_c/txn_abort.html">DB_TXN-&gt;abort</a> when these returns
 occur, as it is not possible to proceed otherwise.  The only
 unrecoverable error is <a href="../../ref/program/errorret.html#DB_RUNRECOVERY">DB_RUNRECOVERY</a>, which indicates that the
 system must stop and recovery must be run.
@@ -79,7 +79,7 @@ unlikely failure scenario, but a possible one.
 <p>See <a href="../../ref/transapp/reclimit.html">Berkeley DB recoverability</a>
 for more detailed information.
 </ol>
-<table width="100%"><tr><td><br></td><td align=right><a href="../../ref/transapp/throughput.html"><img src="../../images/prev.gif" alt="Prev"></a><a href="../../reftoc.html"><img src="../../images/ref.gif" alt="Ref"></a><a href="../../ref/xa/intro.html"><img src="../../images/next.gif" alt="Next"></a>
+<table width="100%"><tr><td><br></td><td align=right><a href="../../ref/transapp/throughput.html"><img src="../../images/prev.gif" alt="Prev"></a><a href="../../reftoc.html"><img src="../../images/ref.gif" alt="Ref"></a><a href="../../ref/rep/intro.html"><img src="../../images/next.gif" alt="Next"></a>
 </td></tr></table>
 <p><font size=1><a href="http://www.sleepycat.com">Copyright Sleepycat Software</a></font>
 </body>
index 2472149..f0d4533 100644 (file)
@@ -4,13 +4,13 @@
  * Copyright (c) 1999-2001
  *     Sleepycat Software.  All rights reserved.
  *
- * Id: hash_verify.c,v 1.39 2001/07/02 01:05:39 bostic Exp 
+ * Id: hash_verify.c,v 1.41 2001/07/25 21:59:31 krinsky Exp 
  */
 
 #include "db_config.h"
 
 #ifndef lint
-static const char revid[] = "Id: hash_verify.c,v 1.39 2001/07/02 01:05:39 bostic Exp ";
+static const char revid[] = "Id: hash_verify.c,v 1.41 2001/07/25 21:59:31 krinsky Exp ";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -401,6 +401,7 @@ __ham_vrfy_structure(dbp, vdp, meta_pgno, flags)
        u_int32_t flags;
 {
        DB *pgset;
+       DB_MPOOLFILE *mpf;
        HMETA *m;
        PAGE *h;
        VRFY_PAGEINFO *pip;
@@ -408,9 +409,10 @@ __ham_vrfy_structure(dbp, vdp, meta_pgno, flags)
        db_pgno_t pgno;
        u_int32_t bucket, spares_entry;
 
-       ret = isbad = 0;
-       h = NULL;
+       mpf = dbp->mpf;
        pgset = vdp->pgset;
+       h = NULL;
+       ret = isbad = 0;
 
        if ((ret = __db_vrfy_pgset_get(pgset, meta_pgno, &p)) != 0)
                return (ret);
@@ -423,7 +425,7 @@ __ham_vrfy_structure(dbp, vdp, meta_pgno, flags)
                return (ret);
 
        /* Get the meta page;  we'll need it frequently. */
-       if ((ret = memp_fget(dbp->mpf, &meta_pgno, 0, &m)) != 0)
+       if ((ret = mpf->get(mpf, &meta_pgno, 0, &m)) != 0)
                return (ret);
 
        /* Loop through bucket by bucket. */
@@ -492,9 +494,9 @@ __ham_vrfy_structure(dbp, vdp, meta_pgno, flags)
                goto err;
        }
 
-err:   if ((t_ret = memp_fput(dbp->mpf, m, 0)) != 0)
+err:   if ((t_ret = mpf->put(mpf, m, 0)) != 0)
                return (t_ret);
-       if (h != NULL && (t_ret = memp_fput(dbp->mpf, h, 0)) != 0)
+       if (h != NULL && (t_ret = mpf->put(mpf, h, 0)) != 0)
                return (t_ret);
        return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD: ret);
 }
@@ -712,16 +714,19 @@ __ham_vrfy_hashing(dbp, nentries, m, thisbucket, pgno, flags, hfunc)
        u_int32_t (*hfunc) __P((DB *, const void *, u_int32_t));
 {
        DBT dbt;
+       DB_MPOOLFILE *mpf;
        PAGE *h;
        db_indx_t i;
        int ret, t_ret, isbad;
        u_int32_t hval, bucket;
 
+       mpf = dbp->mpf;
        ret = isbad = 0;
+
        memset(&dbt, 0, sizeof(DBT));
        F_SET(&dbt, DB_DBT_REALLOC);
 
-       if ((ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0)
+       if ((ret = mpf->get(mpf, &pgno, 0, &h)) != 0)
                return (ret);
 
        for (i = 0; i < nentries; i += 2) {
@@ -751,7 +756,7 @@ __ham_vrfy_hashing(dbp, nentries, m, thisbucket, pgno, flags, hfunc)
 
 err:   if (dbt.data != NULL)
                __os_free(dbp->dbenv, dbt.data, 0);
-       if ((t_ret = memp_fput(dbp->mpf, h, 0)) != 0)
+       if ((t_ret = mpf->put(mpf, h, 0)) != 0)
                return (t_ret);
 
        return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
@@ -839,7 +844,7 @@ keydata:                    memcpy(buf, HKEYDATA_DATA(hk), len);
                                dbt.size = len;
                                dbt.data = buf;
                                if ((ret = __db_prdbt(&dbt,
-                                   0, " ", handle, callback, 0, NULL)) != 0)
+                                   0, " ", handle, callback, 0, vdp)) != 0)
                                        err_ret = ret;
                                break;
                        case H_OFFPAGE:
@@ -853,11 +858,11 @@ keydata:                  memcpy(buf, HKEYDATA_DATA(hk), len);
                                    dpgno, &dbt, &buf, flags)) != 0) {
                                        err_ret = ret;
                                        (void)__db_prdbt(&unkdbt, 0, " ",
-                                           handle, callback, 0, NULL);
+                                           handle, callback, 0, vdp);
                                        break;
                                }
                                if ((ret = __db_prdbt(&dbt,
-                                   0, " ", handle, callback, 0, NULL)) != 0)
+                                   0, " ", handle, callback, 0, vdp)) != 0)
                                        err_ret = ret;
                                break;
                        case H_OFFDUP:
@@ -870,7 +875,7 @@ keydata:                    memcpy(buf, HKEYDATA_DATA(hk), len);
                                /* UNKNOWN iff pgno is bad or we're a key. */
                                if (!IS_VALID_PGNO(dpgno) || (i % 2 == 0)) {
                                        if ((ret = __db_prdbt(&unkdbt, 0, " ",
-                                           handle, callback, 0, NULL)) != 0)
+                                           handle, callback, 0, vdp)) != 0)
                                                err_ret = ret;
                                } else if ((ret = __db_salvage_duptree(dbp,
                                    vdp, dpgno, &dbt, handle, callback,
@@ -913,7 +918,7 @@ keydata:                    memcpy(buf, HKEYDATA_DATA(hk), len);
                                        dbt.size = dlen;
                                        dbt.data = buf;
                                        if ((ret = __db_prdbt(&dbt, 0, " ",
-                                           handle, callback, 0, NULL)) != 0)
+                                           handle, callback, 0, vdp)) != 0)
                                                err_ret = ret;
                                        tlen += sizeof(db_indx_t);
                                }
@@ -943,6 +948,7 @@ int __ham_meta2pgset(dbp, vdp, hmeta, flags, pgset)
        u_int32_t flags;
        DB *pgset;
 {
+       DB_MPOOLFILE *mpf;
        PAGE *h;
        db_pgno_t pgno;
        u_int32_t bucket, totpgs;
@@ -956,6 +962,7 @@ int __ham_meta2pgset(dbp, vdp, hmeta, flags, pgset)
 
        DB_ASSERT(pgset != NULL);
 
+       mpf = dbp->mpf;
        totpgs = 0;
 
        /*
@@ -972,7 +979,7 @@ int __ham_meta2pgset(dbp, vdp, hmeta, flags, pgset)
                 * Safely walk the list of pages in this bucket.
                 */
                for (;;) {
-                       if ((ret = memp_fget(dbp->mpf, &pgno, 0, &h)) != 0)
+                       if ((ret = mpf->get(mpf, &pgno, 0, &h)) != 0)
                                return (ret);
                        if (TYPE(h) == P_HASH) {
 
@@ -981,12 +988,12 @@ int __ham_meta2pgset(dbp, vdp, hmeta, flags, pgset)
                                 * pgset.
                                 */
                                if (++totpgs > vdp->last_pgno) {
-                                       (void)memp_fput(dbp->mpf, h, 0);
+                                       (void)mpf->put(mpf, h, 0);
                                        return (DB_VERIFY_BAD);
                                }
                                if ((ret =
                                    __db_vrfy_pgset_inc(pgset, pgno)) != 0) {
-                                       (void)memp_fput(dbp->mpf, h, 0);
+                                       (void)mpf->put(mpf, h, 0);
                                        return (ret);
                                }
 
@@ -994,7 +1001,7 @@ int __ham_meta2pgset(dbp, vdp, hmeta, flags, pgset)
                        } else
                                pgno = PGNO_INVALID;
 
-                       if ((ret = memp_fput(dbp->mpf, h, 0)) != 0)
+                       if ((ret = mpf->put(mpf, h, 0)) != 0)
                                return (ret);
 
                        /* If the new pgno is wonky, go onto the next bucket. */
index a19a656..9331ebb 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 1996-2001
  *     Sleepycat Software.  All rights reserved.
  *
- * Id: log.h,v 11.26 2001/07/05 18:41:03 bostic Exp 
+ * Id: log.h,v 11.35 2001/10/09 18:13:26 ubell Exp 
  */
 
 #ifndef _LOG_H_
@@ -28,7 +28,7 @@ struct __log_persist; typedef struct __log_persist LOGP;
  * The per-process table that maps log file-id's to DB structures.
  */
 typedef        struct __db_entry {
-       TAILQ_HEAD(dblist, __db) dblist; /* Associated DB structures. */
+       TAILQ_HEAD(dblist, __db) dblist;/* Associated DB structures. */
        u_int32_t refcount;             /* Reference counted. */
        u_int32_t count;                /* Number of ops on a deleted db. */
        int       deleted;              /* File was not found during open. */
@@ -47,7 +47,7 @@ struct __db_log {
  * to be stored elsewhere on architectures unable to support mutexes in heap
  * memory, e.g., HP/UX 9.
  */
-       MUTEX     *mutexp;              /* Mutex for thread protection. */
+       DB_MUTEX  *mutexp;              /* Mutex for thread protection. */
 
        DB_ENTRY *dbentry;              /* Recovery file-id mapping. */
 #define        DB_GROW_SIZE    64
@@ -62,25 +62,15 @@ struct __db_log {
        u_int32_t lfname;               /* Log file "name". */
        DB_FH     lfh;                  /* Log file handle. */
 
-       DB_LSN    c_lsn;                /* Cursor: current LSN. */
-       DBT       c_dbt;                /* Cursor: return DBT structure. */
-       DB_FH     c_fh;                 /* Cursor: file handle. */
-       u_int32_t c_off;                /* Cursor: previous record offset. */
-       u_int32_t c_len;                /* Cursor: current record length. */
-       u_int32_t r_file;               /* Cursor: current read file */
-       u_int32_t r_off;                /* Cursor: offset of read buffer. */
-       u_int32_t r_size;               /* Cursor: size of data in read buf. */
-
        u_int8_t *bufp;                 /* Region buffer. */
-       u_int8_t *readbufp;             /* Read buffer. */
 
 /* These fields are not protected. */
        DB_ENV   *dbenv;                /* Reference to error information. */
        REGINFO   reginfo;              /* Region information. */
 
 #define        DBLOG_RECOVER           0x01    /* We are in recovery. */
-#define        DBLOG_FORCE_OPEN        0x02    /* Force the db open even
-                                        * if it appears to be deleted.
+#define        DBLOG_FORCE_OPEN        0x02    /* Force the DB open even if it appears
+                                        * to be deleted.
                                         */
        u_int32_t flags;
 };
@@ -120,14 +110,24 @@ struct __log {
        DB_LSN    lsn;                  /* LSN at current file offset. */
 
        /*
-        * The s_lsn LSN is the last LSN that we know is on disk, not just
-        * written, but synced.
+        * The f_lsn LSN is the LSN (returned to the user) that "owns" the
+        * first byte of the buffer.  If the record associated with the LSN
+        * spans buffers, it may not reflect the physical file location of
+        * the first byte of the buffer.
         */
-       DB_LSN    s_lsn;                /* LSN of the last sync. */
-
+       DB_LSN    f_lsn;                /* LSN of first byte in the buffer. */
+       size_t    b_off;                /* Current offset in the buffer. */
+       u_int32_t w_off;                /* Current write offset in the file. */
        u_int32_t len;                  /* Length of the last record. */
 
-       u_int32_t w_off;                /* Current write offset in the file. */
+       /*
+        * The s_lsn LSN is the last LSN that we know is on disk, not just
+        * written, but synced.  This field only is protected by the
+        * flush mutex rather than by the region mutex.
+        */
+       int       in_flush;             /* Log flush in progress. */
+       DB_MUTEX  flush;                /* Mutex for flushing. */
+       DB_LSN    s_lsn;                /* LSN of the last sync. */
 
        DB_LSN    chkpt_lsn;            /* LSN of the last checkpoint. */
        time_t    chkpt;                /* Time of the last checkpoint. */
@@ -135,17 +135,31 @@ struct __log {
        DB_LOG_STAT stat;               /* Log statistics. */
 
        /*
-        * The f_lsn LSN is the LSN (returned to the user) that "owns" the
-        * first byte of the buffer.  If the record associated with the LSN
-        * spans buffers, it may not reflect the physical file location of
-        * the first byte of the buffer.
+        * The waiting_lsn is used by the replication system.  It is the
+        * first LSN that we are holding without putting in the log, because
+        * we received one or more log records out of order.
         */
-       DB_LSN    f_lsn;                /* LSN of first byte in the buffer. */
-       size_t    b_off;                /* Current offset in the buffer. */
+       DB_LSN  waiting_lsn;            /* First log record after a gap. */
 
-       roff_t    buffer_off;           /* Log buffer offset. */
+       /*
+        * The ready_lsn is also used by the replication system.  It is the
+        * next LSN we expect to receive.  It's normally equal to "lsn",
+        * except at the beginning of a log file, at which point it's set
+        * to the LSN of the first record of the new file (after the
+        * header), rather than to 0.
+        */
+       DB_LSN  ready_lsn;
+
+
+       roff_t    buffer_off;           /* Log buffer offset in the region. */
        u_int32_t buffer_size;          /* Log buffer size. */
 
+       u_int32_t  ncommit;             /* Number of txns waiting to commit. */
+
+       DB_LSN    t_lsn;                /* LSN of first commit */
+       SH_TAILQ_HEAD(__commit) commits;/* list of txns waiting to commit. */
+       SH_TAILQ_HEAD(__free) free_commits;/* free list of commit structs. */
+
 #ifdef MUTEX_SYSTEM_RESOURCES
 #define        LG_MAINT_SIZE   (sizeof(roff_t) * DB_MAX_HANDLES)
 
@@ -154,6 +168,20 @@ struct __log {
 };
 
 /*
+ * __db_commit structure --
+ *     One of these is allocated for each transaction waiting
+ * to commit.
+ */
+struct __db_commit {
+       DB_MUTEX        mutex;          /* Mutex for txn to wait on. */
+       DB_LSN          lsn;            /* LSN of commit record. */
+       SH_TAILQ_ENTRY  links;          /* Either on free or waiting list. */
+
+#define        DB_COMMIT_FLUSH         0x0001  /* Flush the log when you wake up. */
+       u_int32_t       flags;
+};
+
+/*
  * FNAME --
  *     File name and id.
  */
@@ -199,6 +227,13 @@ typedef enum {
        DB_LV_OLD_UNREADABLE
 } logfile_validity;
 
+/*
+ * Boolean macro that returns whether or not a specified log_put flags
+ * value indicates that the log should be sync'ed to disk.
+ */
+#define        FLUSH_ON_FLAG(flags)                                            \
+    ((flags) == DB_COMMIT || (flags) == DB_FLUSH || (flags) == DB_CHECKPOINT)
+
 #include "log_auto.h"
 #include "log_ext.h"
 #endif /* _LOG_H_ */
index 024cf5b..0385943 100644 (file)
@@ -7,7 +7,7 @@
 #include "db_config.h"
 
 #ifndef lint
-static const char revid[] = "Id: log.c,v 11.56 2001/07/05 14:24:45 bostic Exp ";
+static const char revid[] = "Id: log.c,v 11.69 2001/10/02 01:33:40 bostic Exp ";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -19,20 +19,12 @@ static const char revid[] = "Id: log.c,v 11.56 2001/07/05 14:24:45 bostic Exp ";
 #include <unistd.h>
 #endif
 
-#ifdef  HAVE_RPC
-#include "db_server.h"
-#endif
-
 #include "db_int.h"
 #include "log.h"
 #include "db_dispatch.h"
 #include "txn.h"
 #include "txn_auto.h"
 
-#ifdef HAVE_RPC
-#include "rpc_client_ext.h"
-#endif
-
 static int __log_init __P((DB_ENV *, DB_LOG *));
 static int __log_recover __P((DB_LOG *));
 static size_t __log_region_size __P((DB_ENV *));
@@ -50,16 +42,10 @@ __log_open(dbenv)
        DB_LOG *dblp;
        LOG *lp;
        int ret;
-       u_int8_t *readbufp;
-
-       readbufp = NULL;
 
        /* Create/initialize the DB_LOG structure. */
        if ((ret = __os_calloc(dbenv, 1, sizeof(DB_LOG), &dblp)) != 0)
                return (ret);
-       if ((ret = __os_calloc(dbenv, 1, dbenv->lg_bsize, &readbufp)) != 0)
-               goto err;
-       ZERO_LSN(dblp->c_lsn);
        dblp->dbenv = dbenv;
 
        /* Join/create the log region. */
@@ -73,17 +59,14 @@ __log_open(dbenv)
            dbenv, &dblp->reginfo, __log_region_size(dbenv))) != 0)
                goto err;
 
-       dblp->readbufp = readbufp;
-
        /* If we created the region, initialize it. */
-       if (F_ISSET(&dblp->reginfo, REGION_CREATE) &&
-           (ret = __log_init(dbenv, dblp)) != 0)
-               goto err;
+       if (F_ISSET(&dblp->reginfo, REGION_CREATE))
+               if ((ret = __log_init(dbenv, dblp)) != 0)
+                       goto err;
 
        /* Set the local addresses. */
        lp = dblp->reginfo.primary =
            R_ADDR(&dblp->reginfo, dblp->reginfo.rp->primary);
-       dblp->bufp = R_ADDR(&dblp->reginfo, lp->buffer_off);
 
        /*
         * If the region is threaded, then we have to lock both the handles
@@ -99,12 +82,22 @@ __log_open(dbenv)
                        goto err;
        }
 
-       R_UNLOCK(dbenv, &dblp->reginfo);
+       /* Initialize the rest of the structure. */
+       dblp->bufp = R_ADDR(&dblp->reginfo, lp->buffer_off);
 
-       dblp->r_file = 0;
-       dblp->r_off = 0;
-       dblp->r_size = 0;
+       /*
+        * Set the handle -- we may be about to run recovery, which allocates
+        * log cursors.  Log cursors require logging be already configured,
+        * and the handle being set is what demonstrates that.
+        */
        dbenv->lg_handle = dblp;
+
+       /* If we created the region, run recovery. */
+       if (F_ISSET(&dblp->reginfo, REGION_CREATE))
+               if ((ret = __log_recover(dblp)) != 0)
+                       goto err;
+
+       R_UNLOCK(dbenv, &dblp->reginfo);
        return (0);
 
 err:   if (dblp->reginfo.addr != NULL) {
@@ -114,11 +107,11 @@ err:      if (dblp->reginfo.addr != NULL) {
                (void)__db_r_detach(dbenv, &dblp->reginfo, 0);
        }
 
-       if (readbufp != NULL)
-               __os_free(dbenv, readbufp, dbenv->lg_bsize);
        if (dblp->mutexp != NULL)
                __db_mutex_free(dbenv, &dblp->reginfo, dblp->mutexp);
+
        __os_free(dbenv, dblp, sizeof(*dblp));
+
        return (ret);
 }
 
@@ -155,6 +148,12 @@ __log_init(dbenv, dblp)
        /* Initialize LOG LSNs. */
        region->lsn.file = 1;
        region->lsn.offset = 0;
+       region->waiting_lsn.file = 1;
+       region->waiting_lsn.offset = 0;
+       region->ready_lsn.file = 1;
+       region->ready_lsn.offset = 0;
+       region->t_lsn.file = 1;
+       region->t_lsn.offset = 0;
 
 #ifdef  MUTEX_SYSTEM_RESOURCES
        /* Allocate room for the txn maintenance info and initialize it. */
@@ -165,6 +164,11 @@ __log_init(dbenv, dblp)
        region->maint_off = R_OFFSET(&dblp->reginfo, addr);
 #endif
 
+       if ((ret = __db_shmutex_init(dbenv, &region->flush, 0,
+           0, &dblp->reginfo,
+           (REGMAINT *)R_ADDR(&dblp->reginfo, region->maint_off))) != 0)
+               return (ret);
+
        /* Initialize the buffer. */
        if ((ret =
            __db_shalloc(dblp->reginfo.addr, dbenv->lg_bsize, 0, &p)) != 0) {
@@ -174,8 +178,12 @@ mem_err:   __db_err(dbenv, "Unable to allocate memory for the log buffer");
        region->buffer_size = dbenv->lg_bsize;
        region->buffer_off = R_OFFSET(&dblp->reginfo, p);
 
-       /* Try and recover any previous log files before releasing the lock. */
-       return (__log_recover(dblp));
+       /* Initialize the commit Queue. */
+       SH_TAILQ_INIT(&region->free_commits);
+       SH_TAILQ_INIT(&region->commits);
+       region->ncommit = 0;
+
+       return (0);
 }
 
 /*
@@ -187,12 +195,15 @@ __log_recover(dblp)
        DB_LOG *dblp;
 {
        DBT dbt;
+       DB_ENV *dbenv;
+       DB_LOGC *logc;
        DB_LSN lsn;
        LOG *lp;
        int cnt, found_checkpoint, ret;
        u_int32_t chk;
        logfile_validity status;
 
+       logc = NULL;
        lp = dblp->reginfo.primary;
 
        /*
@@ -227,17 +238,25 @@ __log_recover(dblp)
        lsn.file = cnt;
        lsn.offset = 0;
 
-       /* Set the cursor.  Shouldn't fail;  leave error messages on. */
-       memset(&dbt, 0, sizeof(dbt));
-       if ((ret = __log_get(dblp, &lsn, &dbt, DB_SET, 0)) != 0)
+       /*
+        * Allocate a cursor and set it to the first record.  This shouldn't
+        * fail, leave error messages on.
+        */
+       dbenv = dblp->dbenv;
+       if ((ret = dbenv->log_cursor(dbenv, &logc, 0)) != 0)
                return (ret);
+       F_SET(logc, DB_LOG_LOCKED);
+       memset(&dbt, 0, sizeof(dbt));
+       if ((ret = logc->get(logc, &lsn, &dbt, DB_SET)) != 0)
+               goto err;
 
        /*
-        * Read to the end of the file, saving checkpoints.  This will fail
-        * at some point, so turn off error messages.
+        * Read to the end of the file, looking for checkpoints.  This will
+        * fail at some point, so turn off error messages.
         */
+       F_SET(logc, DB_LOG_SILENT_ERR);
        found_checkpoint = 0;
-       while (__log_get(dblp, &lsn, &dbt, DB_NEXT, 1) == 0) {
+       while (logc->get(logc, &lsn, &dbt, DB_NEXT) == 0) {
                if (dbt.size < sizeof(u_int32_t))
                        continue;
                memcpy(&chk, dbt.data, sizeof(u_int32_t));
@@ -246,6 +265,7 @@ __log_recover(dblp)
                        found_checkpoint = 1;
                }
        }
+       F_CLR(logc, DB_LOG_SILENT_ERR);
 
        /*
         * We now know where the end of the log is.  Set the first LSN that
@@ -254,11 +274,11 @@ __log_recover(dblp)
         */
        lp->lsn = lsn;
        lp->s_lsn = lsn;
-       lp->lsn.offset += dblp->c_len;
-       lp->s_lsn.offset += dblp->c_len;
+       lp->lsn.offset += logc->c_len;
+       lp->s_lsn.offset += logc->c_len;
 
        /* Set up the current buffer information, too. */
-       lp->len = dblp->c_len;
+       lp->len = logc->c_len;
        lp->b_off = 0;
        lp->w_off = lp->lsn.offset;
 
@@ -270,16 +290,17 @@ __log_recover(dblp)
                lsn.file = cnt;
                lsn.offset = 0;
 
-               /* Set the cursor.  Shouldn't fail, leave error messages on. */
-               if ((ret = __log_get(dblp, &lsn, &dbt, DB_SET, 0)) != 0)
-                       return (ret);
+               /* Set the cursor; shouldn't fail, leave error messages on. */
+               if ((ret = logc->get(logc, &lsn, &dbt, DB_SET)) != 0)
+                       goto err;
 
                /*
-                * Read to the end of the file, saving checkpoints.  Again,
-                * this can fail if there are no checkpoints in any log file,
-                * so turn error messages off.
+                * Read to the end of the file, looking for checkpoints.  This
+                * can fail if there are no checkpoints in any log file, so we
+                * turn off error messages.
                 */
-               while (__log_get(dblp, &lsn, &dbt, DB_PREV, 1) == 0) {
+               F_SET(logc, DB_LOG_SILENT_ERR);
+               while (logc->get(logc, &lsn, &dbt, DB_PREV) == 0) {
                        if (dbt.size < sizeof(u_int32_t))
                                continue;
                        memcpy(&chk, dbt.data, sizeof(u_int32_t));
@@ -289,24 +310,22 @@ __log_recover(dblp)
                                break;
                        }
                }
+               F_CLR(logc, DB_LOG_SILENT_ERR);
        }
 
        /* If we never find a checkpoint, that's okay, just 0 it out. */
        if (!found_checkpoint)
 skipsearch:    ZERO_LSN(lp->chkpt_lsn);
 
-       /*
-        * Reset the cursor lsn to the beginning of the log, so that an
-        * initial call to DB_NEXT does the right thing.
-        */
-       ZERO_LSN(dblp->c_lsn);
-
        if (FLD_ISSET(dblp->dbenv->verbose, DB_VERB_RECOVERY))
                __db_err(dblp->dbenv,
                    "Finding last valid log LSN: file: %lu offset %lu",
                    (u_long)lp->lsn.file, (u_long)lp->lsn.offset);
 
-       return (0);
+err:   if (logc != NULL)
+               (void)logc->close(logc, 0);
+
+       return (ret);
 }
 
 /*
@@ -560,20 +579,22 @@ err:      __os_freestr(dblp->dbenv, fname);
 }
 
 /*
- * __log_close --
- *     Internal version of log_close: only called from dbenv_refresh.
+ * __log_dbenv_refresh --
+ *     Clean up after the log system on a close or failed open.  Called only
+ * from __dbenv_refresh.  (Formerly called __log_close.)
  *
- * PUBLIC: int __log_close __P((DB_ENV *));
+ * PUBLIC: int __log_dbenv_refresh __P((DB_ENV *));
  */
 int
-__log_close(dbenv)
+__log_dbenv_refresh(dbenv)
        DB_ENV *dbenv;
 {
        DB_LOG *dblp;
+       u_int32_t buffer_size;
        int ret, t_ret;
 
-       ret = 0;
        dblp = dbenv->lg_handle;
+       buffer_size = ((LOG *)dblp->reginfo.primary)->buffer_size;
 
        /* We may have opened files as part of XA; if so, close them. */
        F_SET(dblp, DBLOG_RECOVER);
@@ -590,16 +611,9 @@ __log_close(dbenv)
        if (F_ISSET(&dblp->lfh, DB_FH_VALID) &&
            (t_ret = __os_closehandle(&dblp->lfh)) != 0 && ret == 0)
                ret = t_ret;
-       if (dblp->c_dbt.data != NULL)
-               __os_free(dbenv, dblp->c_dbt.data, dblp->c_dbt.ulen);
-       if (F_ISSET(&dblp->c_fh, DB_FH_VALID) &&
-           (t_ret = __os_closehandle(&dblp->c_fh)) != 0 && ret == 0)
-               ret = t_ret;
        if (dblp->dbentry != NULL)
                __os_free(dbenv, dblp->dbentry,
                    (dblp->dbentry_cnt * sizeof(DB_ENTRY)));
-       if (dblp->readbufp != NULL)
-               __os_free(dbenv, dblp->readbufp, dbenv->lg_bsize);
 
        __os_free(dbenv, dblp, sizeof(*dblp));
 
@@ -608,30 +622,30 @@ __log_close(dbenv)
 }
 
 /*
- * log_stat --
+ * __log_stat --
  *     Return log statistics.
  *
- * EXTERN: int log_stat __P((DB_ENV *, DB_LOG_STAT **));
+ * PUBLIC: int __log_stat __P((DB_ENV *, DB_LOG_STAT **, u_int32_t));
  */
 int
-log_stat(dbenv, statp)
+__log_stat(dbenv, statp, flags)
        DB_ENV *dbenv;
        DB_LOG_STAT **statp;
+       u_int32_t flags;
 {
        DB_LOG *dblp;
        DB_LOG_STAT *stats;
        LOG *region;
        int ret;
 
-#ifdef HAVE_RPC
-       if (F_ISSET(dbenv, DB_ENV_RPCCLIENT))
-               return (__dbcl_log_stat(dbenv, statp));
-#endif
-
        PANIC_CHECK(dbenv);
-       ENV_REQUIRES_CONFIG(dbenv, dbenv->lg_handle, "log_stat", DB_INIT_LOG);
+       ENV_REQUIRES_CONFIG(dbenv,
+           dbenv->lg_handle, "DB_ENV->log_stat", DB_INIT_LOG);
 
        *statp = NULL;
+       if ((ret = __db_fchk(dbenv,
+           "DB_ENV->log_stat", flags, DB_STAT_CLEAR)) != 0)
+               return (ret);
 
        dblp = dbenv->lg_handle;
        region = dblp->reginfo.primary;
@@ -642,6 +656,8 @@ log_stat(dbenv, statp)
        /* Copy out the global statistics. */
        R_LOCK(dbenv, &dblp->reginfo);
        *stats = region->stat;
+       if (LF_ISSET(DB_STAT_CLEAR))
+               memset(&region->stat, 0, sizeof(region->stat));
 
        stats->st_magic = region->persist.magic;
        stats->st_version = region->persist.version;
@@ -651,6 +667,10 @@ log_stat(dbenv, statp)
 
        stats->st_region_wait = dblp->reginfo.rp->mutex.mutex_set_wait;
        stats->st_region_nowait = dblp->reginfo.rp->mutex.mutex_set_nowait;
+       if (LF_ISSET(DB_STAT_CLEAR)) {
+               dblp->reginfo.rp->mutex.mutex_set_wait = 0;
+               dblp->reginfo.rp->mutex.mutex_set_nowait = 0;
+       }
        stats->st_regsize = dblp->reginfo.rp->size;
 
        stats->st_cur_file = region->lsn.file;
@@ -724,3 +744,151 @@ __log_region_destroy(dbenv, infop)
        COMPQUIET(dbenv, NULL);
        COMPQUIET(infop, NULL);
 }
+
+/*
+ * __log_vtruncate
+ *     This is a virtual truncate.  We set up the log indicators to
+ * make everyone believe that the given record is the last one in the
+ * log.  Returns with the next valid LSN (i.e., the LSN of the next
+ * record to be written). This is used in replication to discard records
+ * in the log file that do not agree with the master.
+ *
+ * PUBLIC: int __log_vtruncate __P((DB_ENV *, DB_LSN *, DB_LSN *));
+ */
+int
+__log_vtruncate(dbenv, lsn, ckplsn)
+       DB_ENV *dbenv;
+       DB_LSN *lsn, *ckplsn;
+{
+       DBT log_dbt;
+       DB_FH fh;
+       DB_LOG *dblp;
+       DB_LOGC *logc;
+       LOG *lp;
+       u_int32_t bytes, c_len;
+       int fn, ret, t_ret;
+       char *fname;
+
+       /* Need to find out the length of this soon-to-be-last record. */
+       if ((ret = dbenv->log_cursor(dbenv, &logc, 0)) != 0)
+               return (ret);
+       memset(&log_dbt, 0, sizeof(log_dbt));
+       ret = logc->get(logc, lsn, &log_dbt, DB_SET);
+       c_len = logc->c_len;
+       if ((t_ret = logc->close(logc, 0)) != 0 && ret == 0)
+               ret = t_ret;
+       if (ret != 0)
+               return (ret);
+
+       /* Now do the truncate. */
+       dblp = (DB_LOG *)dbenv->lg_handle;
+       lp = (LOG *)dblp->reginfo.primary;
+
+       R_LOCK(dbenv, &dblp->reginfo);
+       lp->lsn = *lsn;
+       lp->len = c_len;
+       lp->lsn.offset += lp->len;
+       lp->chkpt_lsn = *ckplsn;
+
+       /*
+        * I am going to assume that the number of bytes written since
+        * the last checkpoint doesn't exceed a 32-bit number.
+        */
+       DB_ASSERT(lp->lsn.file >= ckplsn->file);
+       bytes = 0;
+       if (ckplsn->file != lp->lsn.file) {
+               bytes = lp->persist.lg_max - ckplsn->offset;
+               if (lp->lsn.file > ckplsn->file + 1)
+                       bytes += lp->persist.lg_max *
+                           (lp->lsn.file - ckplsn->file - 1);
+               bytes += lp->lsn.offset;
+       } else
+               bytes = lp->lsn.offset - ckplsn->offset;
+
+       lp->stat.st_wc_mbytes += bytes / MEGABYTE;
+       lp->stat.st_wc_bytes += bytes % MEGABYTE;
+
+       /*
+        * If the saved lsn is greater than our new end of log, reset it
+        * to our current end of log.
+        */
+       if (log_compare(&lp->s_lsn, lsn) > 0)
+               lp->s_lsn = lp->lsn;
+
+       /*
+        * If the new end of log is in the middle of the
+        * buffer, don't change the w_off.  If the new end
+        * is before the w_off then reset w_off to the new
+        * end of log.
+        */
+       if (lp->w_off >= lp->lsn.offset) {
+               lp->w_off = lp->lsn.offset;
+               lp->b_off = 0;
+       } else
+               lp->b_off = lp->lsn.offset - lp->w_off;
+
+       ZERO_LSN(lp->waiting_lsn);
+       lp->ready_lsn = lp->lsn;
+       lp->f_lsn = lp->lsn;
+
+       /* Now throw away any extra log files that we have around. */
+       for (fn = lp->lsn.file + 1;; fn++) {
+               if (__log_name(dblp, fn, &fname, &fh, DB_OSO_RDONLY) != 0)
+                       break;
+               (void)__os_closehandle(&fh);
+               if ((ret = __os_unlink(dbenv, fname)) != 0)
+                       break;
+               __os_freestr(dbenv, fname);
+       }
+       R_UNLOCK(dbenv, &dblp->reginfo);
+       return (ret);
+}
+
+/*
+ * __log_is_outdated --
+ *     Used by the replication system to identify if a client's logs
+ * are too old.  The log represented by dbenv is compared to the file
+ * number passed in fnum.  If the log file fnum does not exist and is
+ * lower-numbered than the current logs, the we return *outdatedp non
+ * zero, else we return it 0.
+ *
+ * PUBLIC:  int __log_is_outdated __P((DB_ENV *dbenv,
+ * PUBLIC:     u_int32_t fnum, int *outdatedp));
+ */
+int
+__log_is_outdated(dbenv, fnum, outdatedp)
+       DB_ENV *dbenv;
+       u_int32_t fnum;
+       int *outdatedp;
+{
+       DB_LOG *dblp;
+       LOG *lp;
+       char *name;
+       int ret;
+       u_int32_t cfile;
+
+       dblp = dbenv->lg_handle;
+       *outdatedp = 0;
+
+       if ((ret = __log_name(dblp, fnum, &name, NULL, 0)) != 0)
+               return (ret);
+
+       /* If the file exists, we're just fine. */
+       if (__os_exists(name, NULL) == 0)
+               goto out;
+
+       /*
+        * It didn't exist, decide if the file number is too big or
+        * too little.  If it's too little, then we need to indicate
+        * that the LSN is outdated.
+        */
+       R_LOCK(dbenv, &dblp->reginfo);
+       lp = (LOG *)dblp->reginfo.primary;
+       cfile = lp->lsn.file;
+       R_UNLOCK(dbenv, &dblp->reginfo);
+
+       if (cfile > fnum)
+               *outdatedp = 1;
+out:   __os_freestr(dbenv, name);
+       return (ret);
+}
index ab178a1..f45f3fe 100644 (file)
@@ -36,7 +36,7 @@
 #include "db_config.h"
 
 #ifndef lint
-static const char revid[] = "Id: log_rec.c,v 11.60 2001/06/12 01:49:05 bostic Exp ";
+static const char revid[] = "Id: log_rec.c,v 11.67 2001/10/10 02:57:41 margo Exp ";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -52,8 +52,9 @@ static const char revid[] = "Id: log_rec.c,v 11.60 2001/06/12 01:49:05 bostic Ex
 
 static int __log_check_master __P((DB_ENV *, u_int8_t *, char *));
 static int __log_do_open __P((DB_ENV *, DB_LOG *,
-    u_int8_t *, char *, DBTYPE, int32_t, db_pgno_t));
-static int __log_open_file __P((DB_ENV *, DB_LOG *, __log_register_args *));
+    u_int8_t *, char *, DBTYPE, int32_t, db_pgno_t, u_int32_t));
+static int __log_open_file __P((DB_ENV *,
+    DB_LOG *, __log_register_args *, u_int32_t));
 
 /*
  * PUBLIC: int __log_register_recover
@@ -72,6 +73,7 @@ __log_register_recover(dbenv, dbtp, lsnp, op, info)
        DB *dbp;
        __log_register_args *argp;
        int do_rem, ret, t_ret;
+       u_int32_t flags;
 
        logp = dbenv->lg_handle;
        dbp = NULL;
@@ -81,6 +83,8 @@ __log_register_recover(dbenv, dbtp, lsnp, op, info)
 #endif
        COMPQUIET(lsnp, NULL);
 
+       flags = 0;
+
        if ((ret = __log_register_read(dbenv, dbtp->data, &argp)) != 0)
                goto out;
 
@@ -95,7 +99,17 @@ __log_register_recover(dbenv, dbtp, lsnp, op, info)
                 */
                if (op == DB_TXN_OPENFILES)
                        F_SET(logp, DBLOG_FORCE_OPEN);
-               ret = __log_open_file(dbenv, logp, argp);
+               /*
+                * If we are applying a log_register record in replication,
+                * we may be doing so out-of-order with respect to
+                * a crdel_fileopen record that came before us in the log
+                * but were in a still-uncommitted transaction.  Let the
+                * underlying log_register know, so that it can postpone
+                * opening the file until it actually exists.
+                */
+               if (op == DB_TXN_APPLY)
+                       flags = DB_APPLY_LOGREG;
+               ret = __log_open_file(dbenv, logp, argp, flags);
                F_CLR(logp, DBLOG_FORCE_OPEN);
                if (ret == ENOENT || ret == EINVAL) {
                        if ((op == DB_TXN_OPENFILES || op == DB_TXN_POPENFILES)
@@ -124,8 +138,7 @@ __log_register_recover(dbenv, dbtp, lsnp, op, info)
                        if (dbe->refcount != 1) {
                                __db_err(dbenv,
                                    "Improper file close. LSN: %lu/%lu.",
-                                   (u_long)logp->c_lsn.file,
-                                   (u_long)logp->c_lsn.offset);
+                                   (u_long)lsnp->file, (u_long)lsnp->offset);
                                ret = EINVAL;
                                goto out;
                        }
@@ -133,7 +146,7 @@ __log_register_recover(dbenv, dbtp, lsnp, op, info)
                        ret = __db_txnlist_close(info,
                            argp->fileid, dbe->count);
                        if ((dbp = TAILQ_FIRST(&dbe->dblist)) != NULL)
-                               (void)log_unregister(dbenv, dbp);
+                               (void)dbenv->log_unregister(dbenv, dbp);
                        do_rem = 1;
                }
                MUTEX_THREAD_UNLOCK(dbenv, logp->mutexp);
@@ -158,7 +171,7 @@ __log_register_recover(dbenv, dbtp, lsnp, op, info)
                 * closed and has therefore not been reopened yet.  If
                 * so, we need to try to open it.
                 */
-               ret = __log_open_file(dbenv, logp, argp);
+               ret = __log_open_file(dbenv, logp, argp, 0);
                if (ret == ENOENT || ret == EINVAL) {
                        if (argp->name.size != 0 && (ret =
                            __db_txnlist_delete(dbenv, info,
@@ -180,10 +193,11 @@ out:      if (argp != NULL)
  *     non-zero on error.
  */
 static int
-__log_open_file(dbenv, lp, argp)
+__log_open_file(dbenv, lp, argp, flags)
        DB_ENV *dbenv;
        DB_LOG *lp;
        __log_register_args *argp;
+       u_int32_t flags;
 {
        DB_ENTRY *dbe;
        DB *dbp;
@@ -231,14 +245,14 @@ __log_open_file(dbenv, lp, argp)
 
        MUTEX_THREAD_UNLOCK(dbenv, lp->mutexp);
        if (0) {
-reopen:                (void)log_unregister(dbp->dbenv, dbp);
+reopen:                (void)dbenv->log_unregister(dbenv, dbp);
                (void)__log_rem_logid(lp, dbp, argp->fileid);
                dbp->close(dbp, 0);
        }
 
        return (__log_do_open(dbenv, lp,
            argp->uid.data, argp->name.data,
-           argp->ftype, argp->fileid, argp->meta_pgno));
+           argp->ftype, argp->fileid, argp->meta_pgno, flags));
 }
 
 /*
@@ -246,16 +260,17 @@ reopen:           (void)log_unregister(dbp->dbenv, dbp);
  *     Must be called when a metadata page changes.
  *
  * PUBLIC: int __log_reopen_file __P((DB_ENV *,
- * PUBLIC:     char *, int32_t, u_int8_t *, db_pgno_t));
+ * PUBLIC:     char *, int32_t, u_int8_t *, db_pgno_t, u_int32_t));
  *
  */
 int
-__log_reopen_file(dbenv, name, ndx, fileid, meta_pgno)
+__log_reopen_file(dbenv, name, ndx, fileid, meta_pgno, flags)
        DB_ENV *dbenv;
        char *name;
        int32_t ndx;
        u_int8_t *fileid;
        db_pgno_t meta_pgno;
+       u_int32_t flags;
 {
        DB *dbp;
        DB_LOG *logp;
@@ -298,11 +313,12 @@ __log_reopen_file(dbenv, name, ndx, fileid, meta_pgno)
        if ((ret = __db_fileid_to_db(dbenv, &dbp, ndx, 0)) != 0)
                goto out;
        ftype = dbp->type;
-       (void)log_unregister(dbenv, dbp);
+       (void)dbenv->log_unregister(dbenv, dbp);
        (void)__log_rem_logid(logp, dbp, ndx);
        (void)dbp->close(dbp, 0);
 
-       ret = __log_do_open(dbenv, logp, fileid, name, ftype, ndx, meta_pgno);
+       ret = __log_do_open(dbenv,
+           logp, fileid, name, ftype, ndx, meta_pgno, flags);
 
        if (tmp_name != NULL)
                __os_free(dbenv, tmp_name, 0);
@@ -316,7 +332,7 @@ out:        return (ret);
  * is not protected by the thread mutex.
  */
 static int
-__log_do_open(dbenv, lp, uid, name, ftype, ndx, meta_pgno)
+__log_do_open(dbenv, lp, uid, name, ftype, ndx, meta_pgno, flags)
        DB_ENV *dbenv;
        DB_LOG *lp;
        u_int8_t *uid;
@@ -324,6 +340,7 @@ __log_do_open(dbenv, lp, uid, name, ftype, ndx, meta_pgno)
        DBTYPE ftype;
        int32_t ndx;
        db_pgno_t meta_pgno;
+       u_int32_t flags;
 {
        DB *dbp;
        int ret;
@@ -348,8 +365,8 @@ __log_do_open(dbenv, lp, uid, name, ftype, ndx, meta_pgno)
        if (meta_pgno != PGNO_BASE_MD)
                memcpy(dbp->fileid, uid, DB_FILE_ID_LEN);
        dbp->type = ftype;
-       if ((ret = __db_dbopen(dbp,
-            name, DB_ODDFILESIZE, __db_omode("rw----"), meta_pgno)) == 0) {
+       if ((ret = __db_dbopen(dbp, name,
+            flags | DB_ODDFILESIZE, __db_omode("rw----"), meta_pgno)) == 0) {
                /*
                 * Verify that we are opening the same file that we were
                 * referring to when we wrote this log record.
@@ -361,14 +378,21 @@ __log_do_open(dbenv, lp, uid, name, ftype, ndx, meta_pgno)
                        memset(zeroid, 0, DB_FILE_ID_LEN);
                        if (memcmp(dbp->fileid, zeroid, DB_FILE_ID_LEN) != 0)
                                goto not_right;
-                       memcpy(dbp->fileid, uid, DB_FILE_ID_LEN);
+skipopen:              memcpy(dbp->fileid, uid, DB_FILE_ID_LEN);
                }
-               if (IS_RECOVERING(dbenv)) {
-                       (void)log_register(dbp->dbenv, dbp, name);
+               if (IS_RECOVERING(dbenv) || LF_ISSET(DB_APPLY_LOGREG)) {
+                       /*
+                        * If DB_APPLY_LOGREG is set, we want to register this
+                        * log file with a specific fileid, but we don't want
+                        * to log anything.  Pass the flag down into
+                        * the log_register code.
+                        */
+                       (void)__log_register_int(dbp->dbenv, dbp, name, flags);
                        (void)__log_add_logid(dbenv, lp, dbp, ndx);
                }
                return (0);
-       }
+       } else if (ret == ENOENT && LF_ISSET(DB_APPLY_LOGREG))
+               goto skipopen;
 
 not_right:
        (void)dbp->close(dbp, 0);
@@ -534,7 +558,7 @@ __db_fileid_to_db(dbenv, dbpp, ndx, inc)
                 */
                if ((ret = __log_do_open(dbenv, logp,
                    fname->ufid, name, fname->s_type,
-                   ndx, fname->meta_pgno)) != 0)
+                   ndx, fname->meta_pgno, 0)) != 0)
                        return (ret);
 
                *dbpp = TAILQ_FIRST(&logp->dbentry[ndx].dblist);
@@ -589,7 +613,7 @@ __log_close_files(dbenv)
        for (i = 0; i < logp->dbentry_cnt; i++) {
                dbe = &logp->dbentry[i];
                while ((dbp = TAILQ_FIRST(&dbe->dblist)) != NULL) {
-                       (void)log_unregister(dbenv, dbp);
+                       (void)dbenv->log_unregister(dbenv, dbp);
                        TAILQ_REMOVE(&dbe->dblist, dbp, links);
                        (void)dbp->close(dbp, dbp->mpf == NULL ? DB_NOSYNC : 0);
                }
@@ -617,6 +641,9 @@ __log_rem_logid(logp, dbp, ndx)
 
        MUTEX_THREAD_LOCK(logp->dbenv, logp->mutexp);
        if (--logp->dbentry[ndx].refcount == 0) {
+               if (dbp == NULL &&
+                   (xdbp = TAILQ_FIRST(&logp->dbentry[ndx].dblist)) != NULL)
+                       (void)xdbp->close(xdbp, 0);
                TAILQ_INIT(&logp->dbentry[ndx].dblist);
                logp->dbentry[ndx].deleted = 0;
        } else if (dbp != NULL)
index 1db717f..b585117 100644 (file)
@@ -7,7 +7,7 @@
 #include "db_config.h"
 
 #ifndef lint
-static const char revid[] = "Id: mp_fopen.c,v 11.54 2001/07/02 01:05:42 bostic Exp ";
+static const char revid[] = "Id: mp_fopen.c,v 11.60 2001/10/04 21:26:56 bostic Exp ";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -16,20 +16,23 @@ static const char revid[] = "Id: mp_fopen.c,v 11.54 2001/07/02 01:05:42 bostic E
 #include <string.h>
 #endif
 
-#ifdef  HAVE_RPC
-#include "db_server.h"
-#endif
-
 #include "db_int.h"
 #include "db_shash.h"
 #include "mp.h"
 
-#ifdef HAVE_RPC
-#include "rpc_client_ext.h"
-#endif
-
-static int __memp_mf_open __P((DB_MPOOL *, const char *,
-    size_t, db_pgno_t, DB_MPOOL_FINFO *, u_int32_t, MPOOLFILE **));
+static int  __memp_fclose __P((DB_MPOOLFILE *, u_int32_t));
+static int  __memp_fopen __P((DB_MPOOLFILE *,
+               const char *, u_int32_t, int, size_t));
+static int  __memp_mf_open __P((DB_MPOOLFILE *,
+               const char *, size_t, db_pgno_t, u_int32_t, MPOOLFILE **));
+static void __memp_last_pgno __P((DB_MPOOLFILE *, db_pgno_t *));
+static void __memp_refcnt __P((DB_MPOOLFILE *, db_pgno_t *));
+static int  __memp_set_clear_len __P((DB_MPOOLFILE *, u_int32_t));
+static int  __memp_set_fileid __P((DB_MPOOLFILE *, u_int8_t *));
+static int  __memp_set_ftype __P((DB_MPOOLFILE *, int));
+static int  __memp_set_lsn_offset __P((DB_MPOOLFILE *, int32_t));
+static int  __memp_set_pgcookie __P((DB_MPOOLFILE *, DBT *));
+static void __memp_set_unlink __P((DB_MPOOLFILE *, int));
 
 /*
  * MEMP_FREMOVE --
@@ -44,107 +47,161 @@ static int __memp_mf_open __P((DB_MPOOL *, const char *,
        F_SET(mfp, MP_DEADFILE);                                        \
 }
 
+/* Initialization methods cannot be called after open is called. */
+#define        MPF_ILLEGAL_AFTER_OPEN(dbmfp, name)                             \
+       if (F_ISSET(dbmfp, MP_OPEN_CALLED))                             \
+               return (__db_mi_open((dbmfp)->dbmp->dbenv, name, 1));
+
 /*
- * memp_fopen --
- *     Open a backing file for the memory pool.
+ * __memp_fcreate --
+ *     Create a DB_MPOOLFILE handle.
  *
- * EXTERN: int memp_fopen __P((DB_ENV *, const char *,
- * EXTERN:     u_int32_t, int, size_t, DB_MPOOL_FINFO *, DB_MPOOLFILE **));
+ * PUBLIC: int __memp_fcreate __P((DB_ENV *, DB_MPOOLFILE **, u_int32_t));
  */
 int
-memp_fopen(dbenv, path, flags, mode, pagesize, finfop, retp)
+__memp_fcreate(dbenv, retp, flags)
        DB_ENV *dbenv;
-       const char *path;
-       u_int32_t flags;
-       int mode;
-       size_t pagesize;
-       DB_MPOOL_FINFO *finfop;
        DB_MPOOLFILE **retp;
+       u_int32_t flags;
 {
        DB_MPOOL *dbmp;
+       DB_MPOOLFILE *dbmfp;
        int ret;
 
-#ifdef HAVE_RPC
-       if (F_ISSET(dbenv, DB_ENV_RPCCLIENT))
-               return (__dbcl_memp_fopen(dbenv, path, flags,
-                   mode, pagesize, finfop, retp));
-#endif
-
        PANIC_CHECK(dbenv);
        ENV_REQUIRES_CONFIG(dbenv,
-           dbenv->mp_handle, "memp_fopen", DB_INIT_MPOOL);
+           dbenv->mp_handle, "memp_fcreate", DB_INIT_MPOOL);
 
        dbmp = dbenv->mp_handle;
 
        /* Validate arguments. */
-       if ((ret = __db_fchk(dbenv, "memp_fopen", flags,
-           DB_CREATE |
-           DB_NOMMAP | DB_ODDFILESIZE | DB_RDONLY | DB_TRUNCATE)) != 0)
+       if ((ret = __db_fchk(dbenv, "memp_fcreate", flags, 0)) != 0)
                return (ret);
 
-       /* Require a non-zero pagesize. */
-       if (pagesize == 0 ||
-           (finfop != NULL && finfop->clear_len > pagesize)) {
-               __db_err(dbenv, "memp_fopen: illegal page size.");
-               return (EINVAL);
+       /* Allocate and initialize the per-process structure. */
+       if ((ret = __os_calloc(dbenv, 1, sizeof(DB_MPOOLFILE), &dbmfp)) != 0)
+               return (ret);
+       if ((ret = __os_calloc(dbenv, 1, sizeof(DB_FH), &dbmfp->fhp)) != 0) {
+               __os_free(dbenv, dbmfp, sizeof(DB_MPOOLFILE));
+               return (ret);
        }
 
-       return (__memp_fopen(dbmp,
-           NULL, path, flags, mode, pagesize, 1, finfop, retp));
+       /* Allocate and initialize a mutex if necessary. */
+       if (F_ISSET(dbenv, DB_ENV_THREAD)) {
+               if ((ret = __db_mutex_alloc(
+                   dbenv, dbmp->reginfo, 0, &dbmfp->mutexp)) != 0)
+                       return (ret);
+
+               if ((ret = __db_shmutex_init(dbenv, dbmfp->mutexp, 0,
+                   MUTEX_THREAD, dbmp->reginfo,
+                   (REGMAINT *)R_ADDR(dbmp->reginfo,
+                   ((MPOOL *)dbmp->reginfo->primary)->maint_off))) != 0) {
+                       __db_mutex_free(dbenv, dbmp->reginfo, dbmfp->mutexp);
+                       return (ret);
+               }
+       }
+
+       dbmfp->ref = 1;
+       dbmfp->lsn_offset = -1;
+       dbmfp->dbmp = dbmp;
+
+       dbmfp->close = __memp_fclose;
+       dbmfp->get = __memp_fget;
+       dbmfp->last_pgno = __memp_last_pgno;
+       dbmfp->open = __memp_fopen;
+       dbmfp->put = __memp_fput;
+       dbmfp->refcnt = __memp_refcnt;
+       dbmfp->set = __memp_fset;
+       dbmfp->set_clear_len = __memp_set_clear_len;
+       dbmfp->set_fileid = __memp_set_fileid;
+       dbmfp->set_ftype = __memp_set_ftype;
+       dbmfp->set_lsn_offset = __memp_set_lsn_offset;
+       dbmfp->set_pgcookie = __memp_set_pgcookie;
+       dbmfp->set_unlink = __memp_set_unlink;
+       dbmfp->sync = __memp_fsync;
+
+       /* Add the file to the environment's list of files. */
+       MUTEX_THREAD_LOCK(dbenv, dbmp->mutexp);
+       TAILQ_INSERT_TAIL(&dbmp->dbmfq, dbmfp, q);
+       MUTEX_THREAD_UNLOCK(dbenv, dbmp->mutexp);
+
+       *retp = dbmfp;
+       return (0);
 }
 
 /*
- * __memp_set_unlink -- set unlink on last close flag.
- *
- * PUBLIC: void __memp_set_unlink __P((DB_MPOOLFILE *));
+ * __memp_set_clear_len --
+ *     Set the clear length.
  */
-void
-__memp_set_unlink(dbmpf)
-       DB_MPOOLFILE *dbmpf;
+static int
+__memp_set_clear_len(dbmfp, clear_len)
+       DB_MPOOLFILE *dbmfp;
+       u_int32_t clear_len;
 {
-       DB_MPOOL *dbmp;
-       dbmp = dbmpf->dbmp;
+       MPF_ILLEGAL_AFTER_OPEN(dbmfp, "set_clear_len");
 
-       R_LOCK(dbmp->dbenv, dbmp->reginfo);
-       F_SET(dbmpf->mfp, MP_UNLINK);
-       R_UNLOCK(dbmp->dbenv, dbmp->reginfo);
+       dbmfp->clear_len = clear_len;
+       return (0);
 }
 
 /*
- * __memp_clear_unlink -- clear unlink on last close flag.
- *
- * PUBLIC: void __memp_clear_unlink __P((DB_MPOOLFILE *));
+ * __memp_set_fileid --
+ *     Set the file ID.
  */
-void
-__memp_clear_unlink(dbmpf)
-       DB_MPOOLFILE *dbmpf;
+static int
+__memp_set_fileid(dbmfp, fileid)
+       DB_MPOOLFILE *dbmfp;
+       u_int8_t *fileid;
 {
-       DB_MPOOL *dbmp;
-       dbmp = dbmpf->dbmp;
+       MPF_ILLEGAL_AFTER_OPEN(dbmfp, "set_fileid");
 
-       /*
-        * This bit is protected in the queue code because the metapage
-        * is locked so we can avoid geting the region lock.
-        * If this gets used from other than the queue code, we cannot.
-        */
-       if (!F_ISSET(dbmpf->mfp, MP_UNLINK))
-               return;
-       R_LOCK(dbmp->dbenv, dbmp->reginfo);
-       F_CLR(dbmpf->mfp, MP_UNLINK);
-       R_UNLOCK(dbmp->dbenv, dbmp->reginfo);
+       dbmfp->fileid = fileid;
+       return (0);
 }
 
 /*
- * __memp_refcount -- return the current refcount
- *
- * PUBLIC: void __memp_refcount __P((DB_MPOOLFILE *, db_pgno_t *));
+ * __memp_set_ftype --
+ *     Set the file type (as registered).
  */
-void
-__memp_refcount(dbmpf, cntp)
-       DB_MPOOLFILE *dbmpf;
-       db_pgno_t *cntp;
+static int
+__memp_set_ftype(dbmfp, ftype)
+       DB_MPOOLFILE *dbmfp;
+       int ftype;
 {
-       *cntp = dbmpf->mfp->mpf_cnt;
+       MPF_ILLEGAL_AFTER_OPEN(dbmfp, "set_ftype");
+
+       dbmfp->ftype = ftype;
+       return (0);
+}
+
+/*
+ * __memp_set_lsn_offset --
+ *     Set the page's LSN offset.
+ */
+static int
+__memp_set_lsn_offset(dbmfp, lsn_offset)
+       DB_MPOOLFILE *dbmfp;
+       int32_t lsn_offset;
+{
+       MPF_ILLEGAL_AFTER_OPEN(dbmfp, "set_lsn_offset");
+
+       dbmfp->lsn_offset = lsn_offset;
+       return (0);
+}
+
+/*
+ * __memp_set_pgcookie --
+ *     Set the pgin/pgout cookie.
+ */
+static int
+__memp_set_pgcookie(dbmfp, pgcookie)
+       DB_MPOOLFILE *dbmfp;
+       DBT *pgcookie;
+{
+       MPF_ILLEGAL_AFTER_OPEN(dbmfp, "set_pgcookie");
+
+       dbmfp->pgcookie = pgcookie;
+       return (0);
 }
 
 /*
@@ -157,25 +214,82 @@ const char * chroot_prefix = NULL;
 
 /*
  * __memp_fopen --
+ *     Open a backing file for the memory pool.
+ */
+static int
+__memp_fopen(dbmfp, path, flags, mode, pagesize)
+       DB_MPOOLFILE *dbmfp;
+       const char *path;
+       u_int32_t flags;
+       int mode;
+       size_t pagesize;
+{
+       DB_ENV *dbenv;
+       DB_MPOOL *dbmp;
+       int ret;
+
+       dbmp = dbmfp->dbmp;
+       dbenv = dbmp->dbenv;
+
+       PANIC_CHECK(dbenv);
+
+       /* Validate arguments. */
+       if ((ret = __db_fchk(dbenv, "memp_fopen", flags,
+           DB_CREATE | DB_EXTENT |
+           DB_NOMMAP | DB_ODDFILESIZE | DB_RDONLY | DB_TRUNCATE)) != 0)
+               return (ret);
+
+       /*
+        * Require a non-zero, power-of-two pagesize, smaller than the
+        * clear length.
+        */
+       if (pagesize == 0 || !POWER_OF_TWO(pagesize)) {
+               __db_err(dbenv,
+                   "memp_fopen: page sizes must be a power-of-2");
+               return (EINVAL);
+       }
+       if (dbmfp->clear_len > pagesize) {
+               __db_err(dbenv,
+                   "memp_fopen: clear length larger than page size.");
+               return (EINVAL);
+       }
+
+       /* Read-only checks, and local flag. */
+       if (LF_ISSET(DB_RDONLY)) {
+               if (path == NULL) {
+                       __db_err(dbenv,
+                           "memp_fopen: temporary files can't be readonly");
+                       return (EINVAL);
+               }
+               F_SET(dbmfp, MP_READONLY);
+       }
+
+       if ((ret = __memp_fopen_int(
+           dbmfp, NULL, path, flags, mode, pagesize, 1)) != 0)
+               return (ret);
+
+       F_SET(dbmfp, MP_OPEN_CALLED);
+       return (0);
+}
+
+/*
+ * __memp_fopen_int --
  *     Open a backing file for the memory pool; internal version.
  *
- * PUBLIC: int __memp_fopen __P((DB_MPOOL *, MPOOLFILE *, const char *,
- * PUBLIC:    u_int32_t, int, size_t, int, DB_MPOOL_FINFO *, DB_MPOOLFILE **));
+ * PUBLIC: int __memp_fopen_int __P((DB_MPOOLFILE *,
+ * PUBLIC:     MPOOLFILE *, const char *, u_int32_t, int, size_t, int));
  */
 int
-__memp_fopen(dbmp, mfp, path, flags, mode, pagesize, needlock, finfop, retp)
-       DB_MPOOL *dbmp;
+__memp_fopen_int(dbmfp, mfp, path, flags, mode, pagesize, needlock)
+       DB_MPOOLFILE *dbmfp;
        MPOOLFILE *mfp;
        const char *path;
        u_int32_t flags;
        int mode, needlock;
        size_t pagesize;
-       DB_MPOOL_FINFO *finfop;
-       DB_MPOOLFILE **retp;
 {
        DB_ENV *dbenv;
-       DB_MPOOLFILE *dbmfp;
-       DB_MPOOL_FINFO finfo;
+       DB_MPOOL *dbmp;
        db_pgno_t last_pgno;
        size_t maxmap;
        u_int32_t mbytes, bytes, oflags;
@@ -183,51 +297,14 @@ __memp_fopen(dbmp, mfp, path, flags, mode, pagesize, needlock, finfop, retp)
        u_int8_t idbuf[DB_FILE_ID_LEN];
        char *rpath, *rpath_orig;
 
+       dbmp = dbmfp->dbmp;
        dbenv = dbmp->dbenv;
        ret = 0;
        rpath = NULL;
 
-       /*
-        * If mfp is provided, we take the DB_MPOOL_FINFO information from
-        * the mfp.  We don't bother initializing everything, because some
-        * of them are expensive to acquire.  If no mfp is provided and the
-        * finfop argument is NULL, we default the values.
-        */
-       if (finfop == NULL) {
-               memset(&finfo, 0, sizeof(finfo));
-               if (mfp != NULL) {
-                       finfo.ftype = mfp->ftype;
-                       finfo.pgcookie = NULL;
-                       finfo.fileid = NULL;
-                       finfo.lsn_offset = mfp->lsn_off;
-                       finfo.clear_len = mfp->clear_len;
-               } else {
-                       finfo.ftype = 0;
-                       finfo.pgcookie = NULL;
-                       finfo.fileid = NULL;
-                       finfo.lsn_offset = -1;
-                       finfo.clear_len = 0;
-               }
-               finfop = &finfo;
-       }
-
-       /* Allocate and initialize the per-process structure. */
-       if ((ret = __os_calloc(dbenv, 1, sizeof(DB_MPOOLFILE), &dbmfp)) != 0)
-               return (ret);
-       dbmfp->dbmp = dbmp;
-       dbmfp->ref = 1;
-       if (LF_ISSET(DB_RDONLY))
-               F_SET(dbmfp, MP_READONLY);
-
-       if (path == NULL) {
-               if (LF_ISSET(DB_RDONLY)) {
-                       __db_err(dbenv,
-                           "memp_fopen: temporary files can't be readonly");
-                       ret = EINVAL;
-                       goto err;
-               }
+       if (path == NULL)
                last_pgno = 0;
-       else {
+       else {
                /* Get the real name for this file and open it. */
                if ((ret = __db_appname(dbenv,
                    DB_APP_DATA, NULL, path, 0, NULL, &rpath)) != 0)
@@ -245,7 +322,7 @@ if (chroot_prefix) {
                if (LF_ISSET(DB_RDONLY))
                        oflags |= DB_OSO_RDONLY;
                if ((ret =
-                  __os_open(dbenv, rpath, oflags, mode, &dbmfp->fh)) != 0) {
+                  __os_open(dbenv, rpath, oflags, mode, dbmfp->fhp)) != 0) {
                        if (!LF_ISSET(DB_EXTENT))
                                __db_err(dbenv,
                                    "%s: %s", rpath, db_strerror(ret));
@@ -266,7 +343,7 @@ if (chroot_prefix) {
                 * offsets are 64-bits, and they pay us a lot of money.
                 */
                if ((ret = __os_ioinfo(dbenv, rpath,
-                   &dbmfp->fh, &mbytes, &bytes, NULL)) != 0) {
+                   dbmfp->fhp, &mbytes, &bytes, NULL)) != 0) {
                        __db_err(dbenv, "%s: %s", rpath, db_strerror(ret));
                        goto err;
                }
@@ -274,23 +351,21 @@ if (chroot_prefix) {
                /*
                 * If we're doing a verify, we might have to cope with
                 * a truncated file;  if the file size is not a multiple
-                * of the page size, round down to a page--we'll
+                * of the page size, round down to a page -- we'll
                 * take care of the partial page outside the memp system.
                 */
-
-               /* Page sizes have to be a power-of-two, ignore mbytes. */
                if (bytes % pagesize != 0) {
                        if (LF_ISSET(DB_ODDFILESIZE))
                                /*
-                                * If we're doing a verify, we might
-                                * have to cope with a truncated file;
-                                * round down, we'll worry about the partial
-                                * page outside the memp system.
+                                * During verify or recovery, we might have
+                                * to cope with a truncated file; round down,
+                                * we'll worry about the partial page outside
+                                * the memp system.
                                 */
                                bytes -= (bytes % pagesize);
                        else {
                                __db_err(dbenv,
-               "%s: file size not a multiple of the pagesize",
+                       "%s: file size not a multiple of the pagesize",
                                    rpath);
                                ret = EINVAL;
                                goto err;
@@ -309,10 +384,10 @@ if (chroot_prefix) {
                 * don't use timestamps, otherwise there'd be no chance of any
                 * other process joining the party.
                 */
-               if (finfop->fileid == NULL) {
+               if (dbmfp->fileid == NULL) {
                        if ((ret = __os_fileid(dbenv, rpath, 0, idbuf)) != 0)
                                goto err;
-                       finfop->fileid = idbuf;
+                       dbmfp->fileid = idbuf;
                }
        }
 
@@ -325,32 +400,17 @@ if (chroot_prefix) {
                R_LOCK(dbenv, dbmp->reginfo);
        if (mfp == NULL)
                ret = __memp_mf_open(
-                   dbmp, path, pagesize, last_pgno, finfop, flags, &mfp);
+                   dbmfp, path, pagesize, last_pgno, flags, &mfp);
        else {
                ++mfp->mpf_cnt;
                ret = 0;
        }
+       dbmfp->mfp = mfp;
        if (needlock)
                R_UNLOCK(dbenv, dbmp->reginfo);
        if (ret != 0)
                goto err;
 
-       if (F_ISSET(dbenv, DB_ENV_THREAD)) {
-               if ((ret = __db_mutex_alloc(
-                   dbenv, dbmp->reginfo, 0, &dbmfp->mutexp)) != 0)
-                       goto err;
-
-               if ((ret = __db_shmutex_init(dbenv, dbmfp->mutexp, 0,
-                   MUTEX_THREAD, dbmp->reginfo,
-                   (REGMAINT *)R_ADDR(dbmp->reginfo,
-                   ((MPOOL *)dbmp->reginfo->primary)->maint_off))) != 0)
-                       goto err;
-
-               /* XXX: KEITH: CLOSE THE FILE ON FAILURE? */
-       }
-
-       dbmfp->mfp = mfp;
-
        /*
         * If a file:
         *      + is read-only
@@ -379,7 +439,7 @@ if (chroot_prefix) {
                        F_CLR(mfp, MP_CAN_MMAP);
                if (path == NULL)
                        F_CLR(mfp, MP_CAN_MMAP);
-               if (finfop->ftype != 0)
+               if (dbmfp->ftype != 0)
                        F_CLR(mfp, MP_CAN_MMAP);
                if (LF_ISSET(DB_NOMMAP) || F_ISSET(dbenv, DB_ENV_NOMMAP))
                        F_CLR(mfp, MP_CAN_MMAP);
@@ -393,7 +453,7 @@ if (chroot_prefix) {
        if (F_ISSET(mfp, MP_CAN_MMAP)) {
                dbmfp->len = (size_t)mbytes * MEGABYTE + bytes;
                if (__os_mapfile(dbenv, rpath,
-                   &dbmfp->fh, dbmfp->len, 1, &dbmfp->addr) != 0) {
+                   dbmfp->fhp, dbmfp->len, 1, &dbmfp->addr) != 0) {
                        dbmfp->addr = NULL;
                        F_CLR(mfp, MP_CAN_MMAP);
                }
@@ -401,26 +461,12 @@ if (chroot_prefix) {
        if (rpath != NULL)
                __os_freestr(dbenv, rpath_orig);
 
-       MUTEX_THREAD_LOCK(dbenv, dbmp->mutexp);
-       TAILQ_INSERT_TAIL(&dbmp->dbmfq, dbmfp, q);
-       MUTEX_THREAD_UNLOCK(dbenv, dbmp->mutexp);
-
-       *retp = dbmfp;
        return (0);
 
-err:   /*
-        * Note that we do not have to free the thread mutex, because we
-        * never get to here after we have successfully allocated it.
-        */
-       if (rpath != NULL)
+err:   if (rpath != NULL)
                __os_freestr(dbenv, rpath_orig);
-       if (F_ISSET(&dbmfp->fh, DB_FH_VALID))
-               (void)__os_closehandle(&dbmfp->fh);
-       if (dbmfp != NULL) {
-               if (dbmfp->mutexp != NULL)
-                       __db_mutex_free(dbenv, dbmp->reginfo, dbmfp->mutexp);
-               __os_free(dbenv, dbmfp, sizeof(DB_MPOOLFILE));
-       }
+       if (F_ISSET(dbmfp->fhp, DB_FH_VALID))
+               (void)__os_closehandle(dbmfp->fhp);
        return (ret);
 }
 
@@ -429,15 +475,15 @@ err:      /*
  *     Open an MPOOLFILE.
  */
 static int
-__memp_mf_open(dbmp, path, pagesize, last_pgno, finfop, flags, retp)
-       DB_MPOOL *dbmp;
+__memp_mf_open(dbmfp, path, pagesize, last_pgno, flags, retp)
+       DB_MPOOLFILE *dbmfp;
        const char *path;
        size_t pagesize;
        db_pgno_t last_pgno;
-       DB_MPOOL_FINFO *finfop;
        u_int32_t flags;
        MPOOLFILE **retp;
 {
+       DB_MPOOL *dbmp;
        MPOOL *mp;
        MPOOLFILE *mfp;
        int ret;
@@ -445,6 +491,8 @@ __memp_mf_open(dbmp, path, pagesize, last_pgno, finfop, flags, retp)
 
 #define        ISTEMPORARY     (path == NULL)
 
+       dbmp = dbmfp->dbmp;
+
        /*
         * If not creating a temporary file, walk the list of MPOOLFILE's,
         * looking for a matching file.  Files backed by temporary files
@@ -472,13 +520,13 @@ __memp_mf_open(dbmp, path, pagesize, last_pgno, finfop, flags, retp)
                    mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) {
                        if (F_ISSET(mfp, MP_DEADFILE | MP_TEMP))
                                continue;
-                       if (memcmp(finfop->fileid, R_ADDR(dbmp->reginfo,
+                       if (memcmp(dbmfp->fileid, R_ADDR(dbmp->reginfo,
                            mfp->fileid_off), DB_FILE_ID_LEN) == 0) {
                                if (LF_ISSET(DB_TRUNCATE)) {
                                        MEMP_FREMOVE(mfp);
                                        continue;
                                }
-                               if (finfop->clear_len != mfp->clear_len ||
+                               if (dbmfp->clear_len != mfp->clear_len ||
                                    pagesize != mfp->stat.st_pagesize) {
                                        __db_err(dbmp->dbenv,
                                    "%s: page size or clear length changed",
@@ -492,8 +540,8 @@ __memp_mf_open(dbmp, path, pagesize, last_pgno, finfop, flags, retp)
                                 * an application created a hash subdatabase
                                 * in a database that was previously all btree.
                                 */
-                               if (finfop->ftype != 0)
-                                       mfp->ftype = finfop->ftype;
+                               if (dbmfp->ftype != 0)
+                                       mfp->ftype = dbmfp->ftype;
 
                                ++mfp->mpf_cnt;
 
@@ -512,9 +560,9 @@ __memp_mf_open(dbmp, path, pagesize, last_pgno, finfop, flags, retp)
        /* Initialize the structure. */
        memset(mfp, 0, sizeof(MPOOLFILE));
        mfp->mpf_cnt = 1;
-       mfp->ftype = finfop->ftype;
-       mfp->lsn_off = finfop->lsn_offset;
-       mfp->clear_len = finfop->clear_len;
+       mfp->ftype = dbmfp->ftype;
+       mfp->lsn_off = dbmfp->lsn_offset;
+       mfp->clear_len = dbmfp->clear_len;
 
        /*
         * If the user specifies DB_MPOOL_LAST or DB_MPOOL_NEW on a memp_fget,
@@ -537,7 +585,7 @@ __memp_mf_open(dbmp, path, pagesize, last_pgno, finfop, flags, retp)
                if ((ret = __memp_alloc(dbmp, dbmp->reginfo,
                    NULL, DB_FILE_ID_LEN, &mfp->fileid_off, &p)) != 0)
                        goto err;
-               memcpy(p, finfop->fileid, DB_FILE_ID_LEN);
+               memcpy(p, dbmfp->fileid, DB_FILE_ID_LEN);
 
                F_SET(mfp, MP_CAN_MMAP);
                if (LF_ISSET(DB_EXTENT))
@@ -545,15 +593,15 @@ __memp_mf_open(dbmp, path, pagesize, last_pgno, finfop, flags, retp)
        }
 
        /* Copy the page cookie into shared memory. */
-       if (finfop->pgcookie == NULL || finfop->pgcookie->size == 0) {
+       if (dbmfp->pgcookie == NULL || dbmfp->pgcookie->size == 0) {
                mfp->pgcookie_len = 0;
                mfp->pgcookie_off = 0;
        } else {
                if ((ret = __memp_alloc(dbmp, dbmp->reginfo,
-                   NULL, finfop->pgcookie->size, &mfp->pgcookie_off, &p)) != 0)
+                   NULL, dbmfp->pgcookie->size, &mfp->pgcookie_off, &p)) != 0)
                        goto err;
-               memcpy(p, finfop->pgcookie->data, finfop->pgcookie->size);
-               mfp->pgcookie_len = finfop->pgcookie->size;
+               memcpy(p, dbmfp->pgcookie->data, dbmfp->pgcookie->size);
+               mfp->pgcookie_len = dbmfp->pgcookie->size;
        }
 
        /* Prepend the MPOOLFILE to the list of MPOOLFILE's. */
@@ -576,35 +624,122 @@ mem_err: __db_err(dbmp->dbenv,
 }
 
 /*
+ * __memp_last_pgno --
+ *     Return the page number of the last page in the file.
+ *
+ * XXX
+ * Undocumented interface: DB private.
+ */
+static void
+__memp_last_pgno(dbmfp, pgnoaddr)
+       DB_MPOOLFILE *dbmfp;
+       db_pgno_t *pgnoaddr;
+{
+       DB_ENV *dbenv;
+       DB_MPOOL *dbmp;
+
+       dbmp = dbmfp->dbmp;
+       dbenv = dbmp->dbenv;
+
+       R_LOCK(dbenv, dbmp->reginfo);
+       *pgnoaddr = dbmfp->mfp->last_pgno;
+       R_UNLOCK(dbenv, dbmp->reginfo);
+}
+
+/*
+ * __memp_refcnt --
+ *     Return the current reference count.
+ *
+ * XXX
+ * Undocumented interface: DB private.
+ */
+static void
+__memp_refcnt(dbmfp, cntp)
+       DB_MPOOLFILE *dbmfp;
+       db_pgno_t *cntp;
+{
+       DB_ENV *dbenv;
+       DB_MPOOL *dbmp;
+
+       dbmp = dbmfp->dbmp;
+       dbenv = dbmp->dbenv;
+
+       R_LOCK(dbenv, dbmp->reginfo);
+       *cntp = dbmfp->mfp->mpf_cnt;
+       R_UNLOCK(dbenv, dbmp->reginfo);
+}
+
+/*
+ * __memp_set_unlink --
+ *     Set unlink on last close flag.
+ *
+ * XXX
+ * Undocumented interface: DB private.
+ */
+static void
+__memp_set_unlink(dbmpf, set)
+       DB_MPOOLFILE *dbmpf;
+       int set;
+{
+       DB_MPOOL *dbmp;
+
+       dbmp = dbmpf->dbmp;
+
+       if (set) {
+               R_LOCK(dbmp->dbenv, dbmp->reginfo);
+               F_SET(dbmpf->mfp, MP_UNLINK);
+               R_UNLOCK(dbmp->dbenv, dbmp->reginfo);
+       } else {
+               /*
+                * This bit is protected in the queue code because the metapage
+                * is locked, so we can avoid getting the region lock.  If this
+                * gets used from other than the queue code, we cannot.
+                */
+               if (F_ISSET(dbmpf->mfp, MP_UNLINK)) {
+                       R_LOCK(dbmp->dbenv, dbmp->reginfo);
+                       F_CLR(dbmpf->mfp, MP_UNLINK);
+                       R_UNLOCK(dbmp->dbenv, dbmp->reginfo);
+               }
+       }
+}
+
+/*
  * memp_fclose --
  *     Close a backing file for the memory pool.
- *
- * EXTERN: int memp_fclose __P((DB_MPOOLFILE *));
  */
-int
-memp_fclose(dbmfp)
+static int
+__memp_fclose(dbmfp, flags)
        DB_MPOOLFILE *dbmfp;
+       u_int32_t flags;
 {
        DB_ENV *dbenv;
+       int ret;
 
        dbenv = dbmfp->dbmp->dbenv;
 
        PANIC_CHECK(dbenv);
 
-#ifdef HAVE_RPC
-       if (F_ISSET(dbenv, DB_ENV_RPCCLIENT))
-               return (__dbcl_memp_fclose(dbmfp));
-#endif
+       /*
+        * XXX
+        * DB_MPOOL_DISCARD: Undocumented flag: DB private.
+        */
+       if (flags != 0 && (ret = __db_fchk(dbenv,
+           "DB_MPOOLFILE->close", flags, DB_MPOOL_DISCARD)) != 0)
+               return (ret);
 
-       return (__memp_fclose(dbmfp, 1));
+       return (__memp_fclose_int(dbmfp, flags, 1));
 }
 
 /*
- * PUBLIC: int __memp_fclose __P((DB_MPOOLFILE *, int));
+ * __memp_fclose_int --
+ *     Internal version of __memp_fclose.
+ *
+ * PUBLIC: int __memp_fclose_int __P((DB_MPOOLFILE *, u_int32_t, int));
  */
 int
-__memp_fclose(dbmfp, needlock)
+__memp_fclose_int(dbmfp, flags, needlock)
        DB_MPOOLFILE *dbmfp;
+       u_int32_t flags;
        int needlock;
 {
        DB_ENV *dbenv;
@@ -668,8 +803,8 @@ __memp_fclose(dbmfp, needlock)
                __db_err(dbenv, "%s: %s", __memp_fn(dbmfp), db_strerror(ret));
 
        /* Close the file; temporary files may not yet have been created. */
-       if (F_ISSET(&dbmfp->fh, DB_FH_VALID) &&
-           (t_ret = __os_closehandle(&dbmfp->fh)) != 0) {
+       if (F_ISSET(dbmfp->fhp, DB_FH_VALID) &&
+           (t_ret = __os_closehandle(dbmfp->fhp)) != 0) {
                __db_err(dbenv, "%s: %s", __memp_fn(dbmfp), db_strerror(t_ret));
                if (ret == 0)
                        ret = t_ret;
@@ -689,11 +824,13 @@ __memp_fclose(dbmfp, needlock)
         * MPOOLFILE as dead so that even the dirty ones just get discarded
         * when we try to flush them.
         */
+       if ((mfp = dbmfp->mfp) == NULL)
+               goto done;
        if (needlock)
                R_LOCK(dbenv, dbmp->reginfo);
-       mfp = dbmfp->mfp;
-       if (--mfp->mpf_cnt == 0) {
-               if (F_ISSET(mfp, MP_TEMP | MP_UNLINK))
+       if (--mfp->mpf_cnt == 0 || LF_ISSET(DB_MPOOL_DISCARD)) {
+               if (LF_ISSET(DB_MPOOL_DISCARD) ||
+                   F_ISSET(mfp, MP_TEMP | MP_UNLINK))
                        MEMP_FREMOVE(mfp);
                if (F_ISSET(mfp, MP_UNLINK)) {
                        if ((t_ret = __db_appname(dbmp->dbenv,
@@ -701,7 +838,7 @@ __memp_fclose(dbmfp, needlock)
                            mfp->path_off), 0, NULL, &rpath)) != 0 && ret == 0)
                                ret = t_ret;
                        if (t_ret == 0 && (t_ret =
-                           __os_unlink(dbmp->dbenv, rpath) != 0 && ret == 0))
+                           __os_unlink(dbmp->dbenv, rpath) != 0) && ret == 0)
                                ret = t_ret;
                        __os_free(dbenv, rpath, 0);
                }
@@ -711,7 +848,8 @@ __memp_fclose(dbmfp, needlock)
        if (needlock)
                R_UNLOCK(dbenv, dbmp->reginfo);
 
-       /* Discard the DB_MPOOLFILE structure. */
+done:  /* Discard the DB_MPOOLFILE structure. */
+       __os_free(dbenv, dbmfp->fhp, sizeof(DB_FH));
        __os_free(dbenv, dbmfp, sizeof(DB_MPOOLFILE));
 
        return (ret);
@@ -749,35 +887,6 @@ __memp_mf_discard(dbmp, mfp)
 }
 
 /*
- * __memp_fremove --
- *     Remove an underlying file from the system.
- *
- * PUBLIC: int __memp_fremove __P((DB_MPOOLFILE *));
- */
-int
-__memp_fremove(dbmfp)
-       DB_MPOOLFILE *dbmfp;
-{
-       DB_ENV *dbenv;
-       DB_MPOOL *dbmp;
-       MPOOLFILE *mfp;
-
-       dbmp = dbmfp->dbmp;
-       dbenv = dbmp->dbenv;
-       mfp = dbmfp->mfp;
-
-       PANIC_CHECK(dbenv);
-
-       R_LOCK(dbenv, dbmp->reginfo);
-
-       MEMP_FREMOVE(mfp);
-
-       R_UNLOCK(dbenv, dbmp->reginfo);
-
-       return (0);
-}
-
-/*
  * __memp_fn --
  *     On errors we print whatever is available as the file name.
  *
index e8eb891..c7b5972 100644 (file)
@@ -8,7 +8,7 @@
 #include "db_config.h"
 
 #ifndef lint
-static const char revid[] = "Id: os_map.c,v 11.34 2001/04/10 20:44:34 bostic Exp ";
+static const char revid[] = "Id: os_map.c,v 11.37 2001/10/04 21:27:57 bostic Exp ";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -160,7 +160,7 @@ __os_r_sysattach(dbenv, infop, rp)
         */
        if (ret == 0 && F_ISSET(infop, REGION_CREATE))
                ret = __os_finit(dbenv,
-                   &fh, rp->size, DB_GLOBAL(db_region_init));
+                   &fh, rp->size, F_ISSET(dbenv, DB_ENV_REGION_INIT) ? 1 : 0);
 
        /* Map the file in. */
        if (ret == 0)
@@ -299,11 +299,19 @@ __os_unmapfile(dbenv, addr, len)
 #ifdef HAVE_MMAP
 #ifdef HAVE_MUNLOCK
        if (F_ISSET(dbenv, DB_ENV_LOCKDOWN))
-               (void)munlock(addr, len);
+               while (munlock(addr, len) != 0 && __os_get_errno() == EINTR)
+                       ;
 #else
        COMPQUIET(dbenv, NULL);
 #endif
-       return (munmap(addr, len) ? __os_get_errno() : 0);
+       {
+               int ret;
+
+               while ((ret = munmap(addr, len)) != 0 &&
+                   __os_get_errno() == EINTR)
+                       ;
+               return (ret ? __os_get_errno() : 0);
+       }
 #else
        COMPQUIET(dbenv, NULL);
 
index e5dcbd7..810745a 100644 (file)
@@ -3,12 +3,13 @@
 # Copyright (c) 2001
 #      Sleepycat Software.  All rights reserved.
 #
-# Id: bigfile001.tcl,v 11.3 2001/05/22 16:20:40 krinsky Exp 
+# Id: bigfile001.tcl,v 11.5 2001/08/03 18:02:53 sandstro Exp 
 #
-# Big file test.
-# Create a database greater than 4 GB in size.  Close, verify.  Grow
-# the database somewhat.  Close, reverify.  Lather, rinse, repeat.
-# Since it will not work on all systems, this test is not run by default.
+# TEST bigfile001
+# TEST Create a database greater than 4 GB in size.  Close, verify.
+#      Grow the database somewhat.  Close, reverify.  Lather, rinse,
+#      repeat.  Since it will not work on all systems, this test is
+#      not run by default.
 proc bigfile001 { method \
     { itemsize 4096 } { nitems 1048576 } { growby 5000 } { growtms 2 } args } {
        source ./include.tcl
@@ -24,7 +25,7 @@ proc bigfile001 { method \
        # factor, and page size doesn't matter much.  Use a 50MB
        # cache;  that should be manageable, and will help
        # performance.
-       set dbname TESTDIR/big.db
+       set dbname $testdir/big.db
 
        set db [eval {berkdb_open -create} {-pagesize 65536 \
            -cachesize {0 50000000 0}} $omethod $args $dbname]
index 4ea869c..395535e 100644 (file)
@@ -3,12 +3,12 @@
 # Copyright (c) 2001
 #      Sleepycat Software.  All rights reserved.
 #
-# Id: bigfile002.tcl,v 11.2 2001/07/02 01:08:45 bostic Exp 
+# Id: bigfile002.tcl,v 11.4 2001/08/03 18:31:15 sandstro Exp 
 #
-# Big file test #2.
-# This one should be faster and not require so much disk space, although it
-# doesn't test as extensively.
-# Create an mpool file with 1K pages.  Dirty page 6000000.  Sync.
+# TEST bigfile002
+# TEST This one should be faster and not require so much disk space,
+#      although it doesn't test as extensively.  Create an mpool file
+#      with 1K pages.  Dirty page 6000000.  Sync.
 proc bigfile002 { args } {
        source ./include.tcl
 
@@ -19,7 +19,7 @@ proc bigfile002 { args } {
        env_cleanup $testdir
 
        # Create env.
-       set env [berkdb env -create -home TESTDIR]
+       set env [berkdb env -create -home $testdir]
        error_check_good valid_env [is_valid_env $env] TRUE
 
        # Create the file.
index 4e73f21..40dba37 100644 (file)
@@ -3,12 +3,12 @@
 # Copyright (c) 1999-2001
 #      Sleepycat Software.  All rights reserved.
 #
-# Id: env009.tcl,v 11.1 2001/05/23 16:47:32 sue Exp 
+# Id: env009.tcl,v 11.2 2001/08/03 16:39:24 bostic Exp 
 #
-# Env Test 9
-# Test calls to all the various stat functions.
-# We have several sprinkled throughout the test suite, but
-# this will ensure that we run all of them at least once.
+# TEST env009
+# TEST Test calls to all the various stat functions.  We have several
+# TEST sprinkled throughout the test suite, but this will ensure that
+# TEST we run all of them at least once.
 proc env009 { } {
        source ./include.tcl
 
index f468daa..e5ad7d4 100644 (file)
@@ -3,7 +3,7 @@
 # Copyright (c) 1996-2003
 #      Sleepycat Software.  All rights reserved.
 #
-# Id: rpc003.tcl,v 11.4 2001/07/02 01:08:46 bostic Exp 
+# Id: rpc003.tcl,v 11.5 2001/08/29 19:07:42 sue Exp 
 #
 # Test RPC and secondary indices.
 proc rpc003 { } {
@@ -133,7 +133,7 @@ proc rpc003 { } {
                    [eval {$pdb associate} "" $sdb] 0
                lappend sdbs $sdb
        }
-       check_secondaries $pdb $sdbs $nentries keys data "Rpc003.f"
+       check_secondaries $pdb $sdbs $nentries keys data "Rpc003.h"
 
        foreach sdb $sdbs {
                error_check_good secondary_close [$sdb close] 0
index ec5e4f0..da6334c 100644 (file)
@@ -3,11 +3,10 @@
 # Copyright (c) 2000-2001
 #      Sleepycat Software.  All rights reserved.
 #
-# Id: test095.tcl,v 11.6 2001/05/21 17:09:10 krinsky Exp 
-#
-# DB Test 95 {access method}
-# Bulk get test.
+# Id: test095.tcl,v 11.13 2001/10/11 18:08:40 sandstro Exp 
 #
+# TEST test095
+# TEST Bulk get test. [#2934]
 proc test095 { method {nsets 1000} {noverflows 25} {tnum 95} args } {
        source ./include.tcl
        set args [convert_args $method $args]
@@ -63,24 +62,32 @@ proc test095 { method {nsets 1000} {noverflows 25} {tnum 95} args } {
                t95_cgettest $db $tnum d [expr 100] 1
                t95_cgettest $db $tnum e [expr 10 * 8192] 0
 
-               set m [expr 4000 * $noverflows]
-               puts "\tTest0$tnum.f: Growing\
-                   database with $noverflows overflow sets (max item size $m)"
+               # Run invalid flag combination tests
+               # Sync and reopen test file so errors won't be sent to stderr
+               error_check_good db_sync [$db sync] 0
+               set noerrdb [eval berkdb_open_noerr $dargs $testfile]
+               t95_flagtest $noerrdb $tnum f [expr 8192]
+               t95_cflagtest $noerrdb $tnum g [expr 100]
+               error_check_good noerrdb_close [$noerrdb close] 0
+
+               # Set up for overflow tests
+               set max [expr 4000 * $noverflows]
+               puts "\tTest0$tnum.h: Growing\
+           database with $noverflows overflow sets (max item size $max)"
                t95_populate $db $did $noverflows 4000
 
                # Run overflow get tests.
-               t95_gettest $db $tnum g [expr 10 * 8192] 1
-               t95_gettest $db $tnum h [expr $m * 2] 1
-               t95_gettest $db $tnum i [expr $m * $noverflows * 2] 0
+               t95_gettest $db $tnum i [expr 10 * 8192] 1
+               t95_gettest $db $tnum j [expr $max * 2] 1
+               t95_gettest $db $tnum k [expr $max * $noverflows * 2] 0
 
-               # Run cursor get tests.
-               t95_cgettest $db $tnum j [expr 10 * 8192] 1
-               t95_cgettest $db $tnum k [expr $m * 2] 0
+               # Run overflow cursor get tests.
+               t95_cgettest $db $tnum l [expr 10 * 8192] 1
+               t95_cgettest $db $tnum m [expr $max * 2] 0
 
                error_check_good db_close [$db close] 0
                close $did
        }
-
 }
 
 proc t95_gettest { db tnum letter bufsize expectfail } {
@@ -89,7 +96,14 @@ proc t95_gettest { db tnum letter bufsize expectfail } {
 proc t95_cgettest { db tnum letter bufsize expectfail } {
        t95_gettest_body $db $tnum $letter $bufsize $expectfail 1
 }
+proc t95_flagtest { db tnum letter bufsize } {
+       t95_flagtest_body $db $tnum $letter $bufsize 0
+}
+proc t95_cflagtest { db tnum letter bufsize } {
+       t95_flagtest_body $db $tnum $letter $bufsize 1
+}
 
+# Basic get test
 proc t95_gettest_body { db tnum letter bufsize expectfail usecursor } {
        global errorCode
 
@@ -159,6 +173,52 @@ proc t95_gettest_body { db tnum letter bufsize expectfail usecursor } {
        }
 }
 
+# Test of invalid flag combinations for -multi
+proc t95_flagtest_body { db tnum letter bufsize usecursor } {
+       global errorCode
+
+       if { $usecursor == 0 } {
+               set action "db get -multi "
+       } else {
+               set action "dbc get -multi "
+       }
+       puts "\tTest0$tnum.$letter: $action with invalid flag combinations"
+
+       # Cursor for $usecursor.
+       if { $usecursor != 0 } {
+               set getcurs [$db cursor]
+               error_check_good getcurs [is_valid_cursor $getcurs $db] TRUE
+       }
+
+       if { $usecursor == 0 } {
+               # Disallowed flags for basic -multi get
+               set badflags [list consume consume_wait {rmw some_key}]
+
+               foreach flag $badflags {
+                       catch {eval $db get -multi $bufsize -$flag} ret
+                       error_check_good \
+                           db:get:multi:$flag [is_substr $errorCode EINVAL] 1
+               }
+       } else {
+               # Disallowed flags for cursor -multi get
+               set cbadflags [list last get_recno join_item \
+                   {multi_key 1000} prev prevnodup]
+
+               set dbc [$db cursor]
+               $dbc get -first
+               foreach flag $cbadflags {
+                       catch {eval $dbc get -multi $bufsize -$flag} ret
+                       error_check_good dbc:get:multi:$flag \
+                               [is_substr $errorCode EINVAL] 1
+               }
+               error_check_good dbc_close [$dbc close] 0
+       }
+       if { $usecursor != 0 } {
+               error_check_good getcurs_close [$getcurs close] 0
+       }
+       puts "\t\tTest0$tnum.$letter completed"
+}
+
 # Verify that a passed-in list of key/data pairs all match the predicted
 # structure (e.g. {{thing1 thing1.0}}, {{key2 key2.0} {key2 key2.1}}).
 proc t95_verify { res multiple_keys } {
index b94416e..aff0090 100644 (file)
@@ -3,10 +3,10 @@
 # Copyright (c) 1999-2001
 #      Sleepycat Software.  All rights reserved.
 #
-# Id: test096.tcl,v 11.8 2001/07/09 14:49:16 dda Exp 
+# Id: test096.tcl,v 11.9 2001/08/03 16:39:49 bostic Exp 
 #
-# Access Method Test 96
-# Test of db->truncate method.
+# TEST test096
+# TEST Db->truncate test.
 proc test096 { method {pagesize 512} {nentries 1000} {ndups 19} args} {
        global fixed_len
        source ./include.tcl