Update to db 2.3.10.
authordrepper <drepper>
Tue, 30 Sep 1997 16:23:24 +0000 (16:23 +0000)
committerdrepper <drepper>
Tue, 30 Sep 1997 16:23:24 +0000 (16:23 +0000)
65 files changed:
db2/Makefile
db2/btree/bt_close.c
db2/btree/bt_conv.c
db2/btree/bt_cursor.c
db2/btree/bt_put.c
db2/btree/bt_rec.c
db2/btree/bt_recno.c
db2/btree/btree.src
db2/btree/btree_auto.c
db2/clib/getlong.c
db2/db.h
db2/db/db.c
db2/db/db_auto.c
db2/db/db_conv.c
db2/db/db_pr.c
db2/db/db_ret.c
db2/db/db_thread.c
db2/db_185.h
db2/db_int.h
db2/hash/hash.c
db2/hash/hash_auto.c
db2/hash/hash_conv.c
db2/hash/hash_dup.c
db2/hash/hash_func.c
db2/hash/hash_page.c
db2/hash/hash_rec.c
db2/include/btree.h
db2/include/btree_ext.h
db2/include/db.h.src
db2/include/db_185.h.src
db2/include/db_cxx.h
db2/include/db_ext.h
db2/include/db_int.h.src
db2/include/db_page.h
db2/include/db_shash.h
db2/include/hash_ext.h
db2/include/lock.h
db2/include/log.h
db2/include/log_ext.h
db2/include/mp.h
db2/include/shqueue.h
db2/include/txn.h
db2/lock/lock.c
db2/lock/lock_deadlock.c
db2/log/log.c
db2/log/log_archive.c
db2/log/log_auto.c
db2/log/log_get.c
db2/log/log_put.c
db2/log/log_register.c
db2/mp/mp_bh.c
db2/mp/mp_fget.c
db2/mp/mp_fopen.c
db2/mp/mp_fput.c
db2/mp/mp_fset.c
db2/mp/mp_open.c
db2/mutex/mutex.c
db2/os/db_os_dir.c
db2/progs/db_checkpoint/db_checkpoint.c
db2/progs/db_deadlock/db_deadlock.c
db2/progs/db_dump185/db_dump185.c
db2/progs/db_load/db_load.c
db2/progs/db_recover/db_recover.c
db2/txn/txn.c
db2/txn/txn_auto.c

index a75dc5a..e6b35aa 100644 (file)
@@ -19,7 +19,7 @@
 #
 #      Sub-makefile for libdb.
 #
-#      The code is lifted straight from the db 2.3.6 distribution
+#      The code is lifted straight from the db 2.3.10 distribution
 #      with minimal changes.
 #
 
index 7044599..7dd7139 100644 (file)
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_close.c   10.23 (Sleepycat) 9/2/97";
+static const char sccsid[] = "@(#)bt_close.c   10.24 (Sleepycat) 9/17/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -150,7 +150,7 @@ __bam_upstat(dbp)
 
        /*
         * We use a no-op log call to log the update of the statistics onto the
-        * metadata page.  The dbp->close() call isn't transaction protected to
+        * metadata page.  The Db->close call isn't transaction protected to
         * start with, and I'm not sure what undoing a statistics update means,
         * anyway.
         */
index c9d5d1b..c89493c 100644 (file)
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_conv.c    10.4 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)bt_conv.c    10.5 (Sleepycat) 9/15/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -21,12 +21,11 @@ static const char sccsid[] = "@(#)bt_conv.c 10.4 (Sleepycat) 9/3/97";
 #include "btree.h"
 
 /*
- * __bam_pgin, __bam_pgout --
- *     Convert host-specific page layout to/from the host-independent
- *     format stored on disk.
+ * __bam_pgin --
+ *     Convert host-specific page layout from the host-independent format
+ *     stored on disk.
  *
  * PUBLIC: int __bam_pgin __P((db_pgno_t, void *, DBT *));
- * PUBLIC: int __bam_pgout __P((db_pgno_t, void *, DBT *));
  */
 int
 __bam_pgin(pg, pp, cookie)
@@ -39,9 +38,17 @@ __bam_pgin(pg, pp, cookie)
        pginfo = (DB_PGINFO *)cookie->data;
        if (!pginfo->needswap)
                return (0);
-       return (pg == PGNO_METADATA ? __bam_mswap(pp) : __db_pgin(pg, pp));
+       return (pg == PGNO_METADATA ?
+           __bam_mswap(pp) : __db_pgin(pg, pginfo->db_pagesize, pp));
 }
 
+/*
+ * __bam_pgout --
+ *     Convert host-specific page layout to the host-independent format
+ *     stored on disk.
+ *
+ * PUBLIC: int __bam_pgout __P((db_pgno_t, void *, DBT *));
+ */
 int
 __bam_pgout(pg, pp, cookie)
        db_pgno_t pg;
@@ -53,7 +60,8 @@ __bam_pgout(pg, pp, cookie)
        pginfo = (DB_PGINFO *)cookie->data;
        if (!pginfo->needswap)
                return (0);
-       return (pg == PGNO_METADATA ? __bam_mswap(pp) : __db_pgout(pg, pp));
+       return (pg == PGNO_METADATA ?
+           __bam_mswap(pp) : __db_pgout(pg, pginfo->db_pagesize, pp));
 }
 
 /*
index efae556..a1266bc 100644 (file)
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_cursor.c  10.27 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)bt_cursor.c  10.33 (Sleepycat) 9/24/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -81,7 +81,10 @@ __bam_cursor(dbp, txn, dbcp)
        dbc->c_get = __bam_c_get;
        dbc->c_put = __bam_c_put;
 
-       /* All cursor structures hang off the main DB structure. */
+       /*
+        * All cursors are queued from the master DB structure.  Add the
+        * cursor to that queue.
+        */
        DB_THREAD_LOCK(dbp);
        TAILQ_INSERT_HEAD(&dbp->curs_queue, dbc, links);
        DB_THREAD_UNLOCK(dbp);
@@ -99,31 +102,53 @@ __bam_c_close(dbc)
        DBC *dbc;
 {
        DB *dbp;
-       CURSOR *cp;
        int ret;
 
        DEBUG_LWRITE(dbc->dbp, dbc->txn, "bam_c_close", NULL, NULL, 0);
 
        GETHANDLE(dbc->dbp, dbc->txn, &dbp, ret);
+
+       ret = __bam_c_iclose(dbp, dbc);
+
+       PUTHANDLE(dbp);
+       return (ret);
+}
+
+/*
+ * __bam_c_iclose --
+ *     Close a single cursor -- internal version.
+ *
+ * PUBLIC: int __bam_c_iclose __P((DB *, DBC *));
+ */
+int
+__bam_c_iclose(dbp, dbc)
+       DB *dbp;
+       DBC *dbc;
+{
+       CURSOR *cp;
+       int ret;
+
        cp = dbc->internal;
 
-       /* If a cursor key was deleted do the actual deletion.  */
-       ret = F_ISSET(cp, C_DELETED) ?  __bam_c_physdel(dbp, cp, NULL) : 0;
+       /* If a cursor key was deleted, perform the actual deletion.  */
+       ret = F_ISSET(cp, C_DELETED) ? __bam_c_physdel(dbp, cp, NULL) : 0;
 
        /* Discard any lock if we're not inside a transaction. */
-       if (dbp->txn == NULL && cp->lock != LOCK_INVALID)
+       if (cp->lock != LOCK_INVALID)
                (void)__BT_TLPUT(dbp, cp->lock);
 
-       /* Remove the cursor from the queue. */
-       DB_THREAD_LOCK(dbp);
-       TAILQ_REMOVE(&dbp->curs_queue, dbc, links);
-       DB_THREAD_UNLOCK(dbp);
+       /*
+        * All cursors are queued from the master DB structure.  Remove the
+        * cursor from that queue.
+        */
+       DB_THREAD_LOCK(dbc->dbp);
+       TAILQ_REMOVE(&dbc->dbp->curs_queue, dbc, links);
+       DB_THREAD_UNLOCK(dbc->dbp);
 
        /* Discard the structures. */
-       FREE(cp, sizeof(CURSOR));
+       FREE(dbc->internal, sizeof(CURSOR));
        FREE(dbc, sizeof(DBC));
 
-       PUTHANDLE(dbp);
        return (ret);
 }
 
@@ -235,27 +260,22 @@ __bam_get(argdbp, txn, key, data, flags)
        if ((ret = __db_getchk(argdbp, key, data, flags)) != 0)
                return (ret);
 
-       /* Build a cursor. */
+       /* Build an internal cursor. */
        memset(&cp, 0, sizeof(cp));
        cp.dbc = &dbc;
        cp.pgno = cp.dpgno = PGNO_INVALID;
        cp.lock = LOCK_INVALID;
+       cp.flags = C_INTERNAL;
 
+       /* Build an external cursor. */
        memset(&dbc, 0, sizeof(dbc));
        dbc.dbp = argdbp;
        dbc.txn = txn;
        dbc.internal = &cp;
 
        /* Get the key. */
-       if ((ret = __bam_c_get(&dbc,
-           key, data, LF_ISSET(DB_SET_RECNO) ? DB_SET_RECNO : DB_SET)) != 0)
-               return (ret);
-
-       /* Discard any lock, the cursor didn't really exist. */
-       if (cp.lock != LOCK_INVALID)
-               (void)__BT_TLPUT(argdbp, cp.lock);
-
-       return (0);
+       return(__bam_c_get(&dbc,
+           key, data, LF_ISSET(DB_SET_RECNO) ? DB_SET_RECNO : DB_SET));
 }
 
 /*
@@ -275,8 +295,7 @@ __bam_c_get(dbc, key, data, flags)
        int exact, ret;
 
        DEBUG_LREAD(dbc->dbp, dbc->txn, "bam_c_get",
-           flags == DB_SET || flags == DB_SET_RANGE ? key : NULL,
-           NULL, flags);
+           flags == DB_SET || flags == DB_SET_RANGE ? key : NULL, NULL, flags);
 
        cp = dbc->internal;
 
@@ -399,6 +418,10 @@ __bam_c_get(dbc, key, data, flags)
        /* Release the pinned page. */
        ret = memp_fput(dbp->mpf, cp->page, 0);
 
+       /* Internal cursors don't hold locks. */
+       if (F_ISSET(cp, C_INTERNAL) && cp->lock != LOCK_INVALID)
+               (void)__BT_TLPUT(dbp, cp->lock);
+
        ++t->lstat.bt_get;
 
        if (0) {
@@ -864,7 +887,7 @@ __bam_c_prev(dbp, cp)
         * If at the beginning of the page, move to any previous one.
         *
         * !!!
-         * This code handles empty pages and pages with only deleted entries.
+        * This code handles empty pages and pages with only deleted entries.
         */
        for (;;) {
                if (indx == 0) {
@@ -1472,8 +1495,7 @@ __bam_c_physdel(dbp, cp, h)
                 *      empty the current page of duplicates, we don't need to
                 *      touch the parent page.
                 */
-               if (PREV_PGNO(h) != PGNO_INVALID ||
-                   (h != NULL && pgno == h->pgno))
+               if (prev_pgno != PGNO_INVALID || (h != NULL && pgno == h->pgno))
                        goto done;
 
                /*
index 0f0b1e7..af09f76 100644 (file)
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_put.c     10.24 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)bt_put.c     10.25 (Sleepycat) 9/17/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -99,7 +99,7 @@ __bam_put(argdbp, txn, key, data, flags)
        t = dbp->internal;
 
 retry: /*
-        * Find the location at which to insert.  The call to bt_lookup()
+        * Find the location at which to insert.  The call to __bam_lookup
         * leaves the returned page pinned.
         */
        if ((ret = __bam_lookup(dbp, key, &exact)) != 0) {
index 07a3d93..9aeb395 100644 (file)
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_rec.c     10.13 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)bt_rec.c     10.14 (Sleepycat) 9/6/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -298,11 +298,10 @@ __bam_split_recover(logp, dbtp, lsnp, redo, info)
                        goto done;
 
                /* Allocate and initialize new left/right child pages. */
-               if ((_lp = (PAGE *)malloc(file_dbp->pgsize)) == NULL)
-                       goto nomem;
-               if ((_rp = (PAGE *)malloc(file_dbp->pgsize)) == NULL) {
-nomem:                 __set_errno(ENOMEM);
-                       __db_err(file_dbp->dbenv, "%s", strerror(errno));
+               if ((_lp = (PAGE *)malloc(file_dbp->pgsize)) == NULL ||
+                   (_rp = (PAGE *)malloc(file_dbp->pgsize)) == NULL) {
+                       ret = ENOMEM;
+                       __db_err(file_dbp->dbenv, "%s", strerror(ret));
                        goto out;
                }
                if (rootsplit) {
@@ -668,7 +667,7 @@ __bam_cadjust_recover(logp, dbtp, lsnp, redo, info)
        REC_INTRO(__bam_cadjust_read);
 
        if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
-               __set_errno(__db_pgerr(file_dbp, argp->pgno));
+               (void)__db_pgerr(file_dbp, argp->pgno);
                pagep = NULL;
                goto out;
        }
index 42ef9cc..f7c5cff 100644 (file)
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_recno.c   10.15 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)bt_recno.c   10.19 (Sleepycat) 9/20/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -76,7 +76,7 @@ __ram_open(dbp, type, dbinfo)
 
        /* Allocate and initialize the private RECNO structure. */
        if ((rp = (RECNO *)calloc(1, sizeof(*rp))) == NULL)
-               return (errno);
+               return (ENOMEM);
 
        if (dbinfo != NULL) {
                /*
@@ -150,7 +150,7 @@ err:        /* If we mmap'd a source file, discard it. */
 
        /* If we allocated room for key/data return, discard it. */
        t = dbp->internal;
-       if (t->bt_rkey.data != NULL)
+       if (t != NULL && t->bt_rkey.data != NULL)
                free(t->bt_rkey.data);
 
        FREE(rp, sizeof(*rp));
@@ -193,7 +193,10 @@ __ram_cursor(dbp, txn, dbcp)
        dbc->c_get = __ram_c_get;
        dbc->c_put = __ram_c_put;
 
-       /* All cursor structures hang off the main DB structure. */
+       /*
+        * All cursors are queued from the master DB structure.  Add the
+        * cursor to that queue.
+        */
        DB_THREAD_LOCK(dbp);
        TAILQ_INSERT_HEAD(&dbp->curs_queue, dbc, links);
        DB_THREAD_UNLOCK(dbp);
@@ -382,16 +385,29 @@ static int
 __ram_c_close(dbc)
        DBC *dbc;
 {
-       DB *dbp;
-
        DEBUG_LWRITE(dbc->dbp, dbc->txn, "ram_c_close", NULL, NULL, 0);
 
-       dbp = dbc->dbp;
+       return (__ram_c_iclose(dbc->dbp, dbc));
+}
 
-       /* Remove the cursor from the queue. */
-       DB_THREAD_LOCK(dbp);
-       TAILQ_REMOVE(&dbp->curs_queue, dbc, links);
-       DB_THREAD_UNLOCK(dbp);
+/*
+ * __ram_c_iclose --
+ *     Close a single cursor -- internal version.
+ *
+ * PUBLIC: int __ram_c_iclose __P((DB *, DBC *));
+ */
+int
+__ram_c_iclose(dbp, dbc)
+       DB *dbp;
+       DBC *dbc;
+{
+       /*
+        * All cursors are queued from the master DB structure.  Remove the
+        * cursor from that queue.
+        */
+       DB_THREAD_LOCK(dbc->dbp);
+       TAILQ_REMOVE(&dbc->dbp->curs_queue, dbc, links);
+       DB_THREAD_UNLOCK(dbc->dbp);
 
        /* Discard the structures. */
        FREE(dbc->internal, sizeof(RCURSOR));
index 50cc0dd..7c8c4b1 100644 (file)
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)btree.src    10.3 (Sleepycat) 8/17/97";
+static const char sccsid[] = "@(#)btree.src    10.4 (Sleepycat) 8/27/97";
 #endif /* not lint */
 
 PREFIX bam
@@ -88,7 +88,7 @@ END
 
 /*
  * BTREE-adj: used to log the adjustment of an index.
- * 
+ *
  * pgno:       the page modified.
  * lsn:                the page's original lsn.
  * indx:       the index adjusted.
@@ -106,7 +106,7 @@ END
 
 /*
  * BTREE-cadjust: used to adjust the count change in an internal page.
- * 
+ *
  * pgno:       the page modified.
  * lsn:                the page's original lsn.
  * indx:       the index to be adjusted.
@@ -124,7 +124,7 @@ END
 
 /*
  * BTREE-cdel: used to log the intent-to-delete of a cursor record.
- * 
+ *
  * pgno:       the page modified.
  * lsn:                the page's original lsn.
  * indx:       the index to be deleted.
index e6b7225..353ee7b 100644 (file)
@@ -119,7 +119,7 @@ __bam_pg_alloc_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __bam_pg_alloc_read(dbtp->data, &argp)) != 0)
+       if ((ret = __bam_pg_alloc_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]bam_pg_alloc: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -284,7 +284,7 @@ __bam_pg_free_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __bam_pg_free_read(dbtp->data, &argp)) != 0)
+       if ((ret = __bam_pg_free_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]bam_pg_free: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -479,7 +479,7 @@ __bam_split_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __bam_split_read(dbtp->data, &argp)) != 0)
+       if ((ret = __bam_split_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]bam_split: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -672,7 +672,7 @@ __bam_rsplit_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __bam_rsplit_read(dbtp->data, &argp)) != 0)
+       if ((ret = __bam_rsplit_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]bam_rsplit: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -848,7 +848,7 @@ __bam_adj_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __bam_adj_read(dbtp->data, &argp)) != 0)
+       if ((ret = __bam_adj_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]bam_adj: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -1007,7 +1007,7 @@ __bam_cadjust_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __bam_cadjust_read(dbtp->data, &argp)) != 0)
+       if ((ret = __bam_cadjust_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]bam_cadjust: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -1157,7 +1157,7 @@ __bam_cdel_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __bam_cdel_read(dbtp->data, &argp)) != 0)
+       if ((ret = __bam_cdel_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]bam_cdel: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
index 0cc8567..85f4e8c 100644 (file)
@@ -18,7 +18,6 @@ static const char sccsid[] = "@(#)getlong.c   10.2 (Sleepycat) 5/1/97";
 #endif
 
 #include "db.h"
-#include "db_int.h"
 #include "clib_ext.h"
 
 /*
index c80d8e3..6911002 100644 (file)
--- a/db2/db.h
+++ b/db2/db.h
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *     Sleepycat Software.  All rights reserved.
  *
- *     @(#)db.h.src    10.71 (Sleepycat) 9/4/97
+ *     @(#)db.h.src    10.77 (Sleepycat) 9/24/97
  */
 
 #ifndef _DB_H_
@@ -67,8 +67,8 @@
 
 #define        DB_VERSION_MAJOR        2
 #define        DB_VERSION_MINOR        3
-#define        DB_VERSION_PATCH        6
-#define        DB_VERSION_STRING       "Sleepycat Software: DB 2.3.6: (9/4/97)"
+#define        DB_VERSION_PATCH        10
+#define        DB_VERSION_STRING       "Sleepycat Software: DB 2.3.10: (9/24/97)"
 
 typedef        u_int32_t       db_pgno_t;      /* Page number type. */
 typedef        u_int16_t       db_indx_t;      /* Page offset type. */
@@ -339,7 +339,7 @@ struct __db_ilock {                 /* Internal DB access method lock. */
 
 /* DB access method description structure. */
 struct __db {
-       void    *mutex                /* Synchronization for free threading */
+       void    *mutexp;                /* Synchronization for free threading */
        DBTYPE   type;                  /* DB access method. */
        DB_ENV  *dbenv;                 /* DB_ENV structure. */
        DB_ENV  *mp_dbenv;              /* DB_ENV for local mpool creation. */
@@ -641,11 +641,11 @@ extern "C" {
 #endif
 int    memp_close __P((DB_MPOOL *));
 int    memp_fclose __P((DB_MPOOLFILE *));
-int    memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, unsigned long, void *));
+int    memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, int, void *));
 int    memp_fopen __P((DB_MPOOL *, const char *,
            int, int, int, size_t, int, DBT *, u_int8_t *, DB_MPOOLFILE **));
-int    memp_fput __P((DB_MPOOLFILE *, void *, unsigned long));
-int    memp_fset __P((DB_MPOOLFILE *, void *, unsigned long));
+int    memp_fput __P((DB_MPOOLFILE *, void *, int));
+int    memp_fset __P((DB_MPOOLFILE *, void *, int));
 int    memp_fsync __P((DB_MPOOLFILE *));
 int    memp_open __P((const char *, int, int, DB_ENV *, DB_MPOOL **));
 int    memp_register __P((DB_MPOOL *, int,
@@ -698,7 +698,7 @@ extern "C" {
 #endif
 int      txn_abort __P((DB_TXN *));
 int      txn_begin __P((DB_TXNMGR *, DB_TXN *, DB_TXN **));
-int      txn_checkpoint __P((const DB_TXNMGR *, long, long));
+int      txn_checkpoint __P((const DB_TXNMGR *, int, int));
 int      txn_commit __P((DB_TXN *));
 int      txn_close __P((DB_TXNMGR *));
 u_int32_t txn_id __P((DB_TXN *));
index 8dad5fe..9ebe73c 100644 (file)
@@ -44,7 +44,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db.c 10.38 (Sleepycat) 9/2/97";
+static const char sccsid[] = "@(#)db.c 10.41 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -137,7 +137,13 @@ db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp)
        }
        dbp->dbenv = dbenv;
 
-       /* Convert the dbinfo flags. */
+       /* Convert the db_open(3) flags. */
+       if (LF_ISSET(DB_RDONLY))
+               F_SET(dbp, DB_AM_RDONLY);
+       if (LF_ISSET(DB_THREAD))
+               F_SET(dbp, DB_AM_THREAD);
+
+       /* Convert the dbinfo structure flags. */
        if (dbinfo != NULL) {
                /*
                 * !!!
@@ -160,23 +166,6 @@ db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp)
                        F_SET(dbp, DB_RE_SNAPSHOT);
        }
 
-       /* Set based on the open(2) flags. */
-       if (LF_ISSET(DB_RDONLY))
-               F_SET(dbp, DB_AM_RDONLY);
-
-       /* Check threading fields. */
-       if (LF_ISSET(DB_THREAD)) {
-               if ((dbp->mutex =
-                   (db_mutex_t *)malloc(sizeof(db_mutex_t))) == NULL) {
-                       __db_err(dbenv, "%s", strerror(ENOMEM));
-                       ret = ENOMEM;
-                       goto err;
-               }
-               __db_mutex_init(dbp->mutex, 0);
-
-               F_SET(dbp, DB_AM_THREAD);
-       }
-
        /*
         * Always set the master and initialize the queues, so we can
         * use these fields without checking the thread bit.
@@ -190,7 +179,7 @@ db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp)
         * Set based on the dbenv fields, although no logging or transactions
         * are possible for temporary files.
         */
-       if (dbp->dbenv != NULL) {
+       if (dbenv != NULL) {
                if (dbenv->lk_info != NULL)
                        F_SET(dbp, DB_AM_LOCKING);
                if (fname != NULL && dbenv->lg_info != NULL)
@@ -274,8 +263,8 @@ open_retry: if (LF_ISSET(DB_CREATE)) {
                 * sizes, we limit the default pagesize to 16K.
                 */
                if (dbp->pgsize == 0) {
-                       if ((ret = __db_stat(dbp->dbenv,
-                           real_name, fd, NULL, &io)) != 0)
+                       if ((ret =
+                           __db_stat(dbenv, real_name, fd, NULL, &io)) != 0)
                                goto err;
                        if (io < 512)
                                io = 512;
@@ -573,6 +562,15 @@ empty:     /*
            0, &pgcookie, dbp->lock.fileid, &dbp->mpf)) != 0)
                goto err;
 
+       /*
+        * XXX
+        * Truly spectacular layering violation.  We need a per-thread mutex
+        * that lives in shared memory (thanks, HP-UX!) and so we acquire a
+        * pointer to the mpool one.
+        */
+       if (F_ISSET(dbp, DB_AM_THREAD))
+               dbp->mutexp = dbp->mpf->mutexp;
+
        /* Get a log file id. */
        if (F_ISSET(dbp, DB_AM_LOGGING) &&
            (ret = log_register(dbenv->lg_info,
@@ -672,7 +670,9 @@ db_close(dbp, flags)
        DB *tdbp;
        int ret, t_ret;
 
-       ret = 0;
+       /* Validate arguments. */
+       if ((ret = __db_fchk(dbp->dbenv, "db_close", flags, DB_NOSYNC)) != 0)
+               return (ret);
 
        /* Sync the underlying file. */
        if (!LF_ISSET(DB_NOSYNC) &&
@@ -685,10 +685,26 @@ db_close(dbp, flags)
         */
        for (tdbp = LIST_FIRST(&dbp->handleq);
            tdbp != NULL; tdbp = LIST_NEXT(tdbp, links)) {
-
                while ((dbc = TAILQ_FIRST(&tdbp->curs_queue)) != NULL)
-                       if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0)
-                               ret = t_ret;
+                       switch (tdbp->type) {
+                       case DB_BTREE:
+                               if ((t_ret =
+                                   __bam_c_iclose(tdbp, dbc)) != 0 && ret == 0)
+                                       ret = t_ret;
+                               break;
+                       case DB_HASH:
+                               if ((t_ret =
+                                   __ham_c_iclose(tdbp, dbc)) != 0 && ret == 0)
+                                       ret = t_ret;
+                               break;
+                       case DB_RECNO:
+                               if ((t_ret =
+                                   __ram_c_iclose(tdbp, dbc)) != 0 && ret == 0)
+                                       ret = t_ret;
+                               break;
+                       default:
+                               abort();
+                       }
 
                switch (tdbp->type) {
                case DB_BTREE:
@@ -706,7 +722,6 @@ db_close(dbp, flags)
                default:
                        abort();
                }
-
        }
 
        /* Sync the memory pool. */
@@ -722,10 +737,6 @@ db_close(dbp, flags)
            (t_ret = memp_close(dbp->mp)) != 0 && ret == 0)
                ret = t_ret;
 
-       /* Discard the mutex. */
-       if (dbp->mutex != NULL)
-               FREE(dbp->mutex, sizeof(db_mutex_t));
-
        /* Discard the log file id. */
        if (F_ISSET(dbp, DB_AM_LOGGING))
                (void)log_unregister(dbp->dbenv->lg_info, dbp->log_fileid);
index 4684f1a..6922504 100644 (file)
@@ -141,7 +141,7 @@ __db_addrem_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __db_addrem_read(dbtp->data, &argp)) != 0)
+       if ((ret = __db_addrem_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]db_addrem: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -331,7 +331,7 @@ __db_split_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __db_split_read(dbtp->data, &argp)) != 0)
+       if ((ret = __db_split_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]db_split: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -526,7 +526,7 @@ __db_big_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __db_big_read(dbtp->data, &argp)) != 0)
+       if ((ret = __db_big_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]db_big: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -693,7 +693,7 @@ __db_ovref_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __db_ovref_read(dbtp->data, &argp)) != 0)
+       if ((ret = __db_ovref_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]db_ovref: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -854,7 +854,7 @@ __db_relink_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __db_relink_read(dbtp->data, &argp)) != 0)
+       if ((ret = __db_relink_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]db_relink: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -1017,7 +1017,7 @@ __db_addpage_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __db_addpage_read(dbtp->data, &argp)) != 0)
+       if ((ret = __db_addpage_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]db_addpage: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -1192,7 +1192,7 @@ __db_debug_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __db_debug_read(dbtp->data, &argp)) != 0)
+       if ((ret = __db_debug_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]db_debug: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -1347,7 +1347,7 @@ __db_noop_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __db_noop_read(dbtp->data, &argp)) != 0)
+       if ((ret = __db_noop_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]db_noop: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
index 6608005..8eccc2e 100644 (file)
@@ -44,7 +44,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_conv.c    10.5 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)db_conv.c    10.7 (Sleepycat) 9/21/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -58,28 +58,34 @@ static const char sccsid[] = "@(#)db_conv.c 10.5 (Sleepycat) 9/3/97";
 #include "db_swap.h"
 #include "db_am.h"
 
-static int __db_convert __P((db_pgno_t, void *, int));
+static int __db_convert __P((db_pgno_t, void *, size_t, int));
 
 /*
- * __db_pgin, __db_pgout --
+ * __db_pgin --
  *
- * PUBLIC: int __db_pgin __P((db_pgno_t, void *));
- * PUBLIC: int __db_pgout __P((db_pgno_t, void *));
+ * PUBLIC: int __db_pgin __P((db_pgno_t, size_t, void *));
  */
 int
-__db_pgin(pg, pp)
+__db_pgin(pg, pagesize, pp)
        db_pgno_t pg;
+       size_t pagesize;
        void *pp;
 {
-       return (__db_convert(pg, pp, 1));
+       return (__db_convert(pg, pp, pagesize, 1));
 }
 
+/*
+ * __db_pgout --
+ *
+ * PUBLIC: int __db_pgout __P((db_pgno_t, size_t, void *));
+ */
 int
-__db_pgout(pg, pp)
+__db_pgout(pg, pagesize, pp)
        db_pgno_t pg;
+       size_t pagesize;
        void *pp;
 {
-       return (__db_convert(pg, pp, 0));
+       return (__db_convert(pg, pp, pagesize, 0));
 }
 
 /*
@@ -87,19 +93,19 @@ __db_pgout(pg, pp)
  *     Actually convert a page.
  */
 static int
-__db_convert(pg, pp, pgin)
+__db_convert(pg, pp, pagesize, pgin)
        db_pgno_t pg;                   /* Unused, but left for the future. */
        void *pp;
+       size_t pagesize;
        int pgin;
 {
        BINTERNAL *bi;
        BKEYDATA *bk;
        BOVERFLOW *bo;
-       HKEYDATA *hk;
        PAGE *h;
        RINTERNAL *ri;
-       db_indx_t i;
-       u_int8_t *p;
+       db_indx_t i, len, tmp;
+       u_int8_t *p, *end;
 
        h = pp;
        if (pgin) {
@@ -118,24 +124,42 @@ __db_convert(pg, pp, pgin)
                        if (pgin)
                                M_16_SWAP(h->inp[i]);
 
-                       hk = GET_HKEYDATA(h, i);
-                       switch (hk->type) {
+                       switch (HPAGE_TYPE(h, i)) {
                        case H_KEYDATA:
                                break;
                        case H_DUPLICATE:
+                               len = LEN_HKEYDATA(h, pagesize, i);
+                               p = HKEYDATA_DATA(P_ENTRY(h, i));
+                               for (end = p + len; p < end;) {
+                                       if (pgin) {
+                                               P_16_SWAP(p);
+                                               memcpy(&tmp,
+                                                   p, sizeof(db_indx_t));
+                                               p += sizeof(db_indx_t);
+                                       } else {
+                                               memcpy(&tmp,
+                                                   p, sizeof(db_indx_t));
+                                               SWAP16(p);
+                                       }
+                                       p += tmp;
+                                       SWAP16(p);
+                               }
+                               break;
+                       case H_OFFDUP:
+                               p = HOFFPAGE_PGNO(P_ENTRY(h, i));
+                               SWAP32(p);                      /* pgno */
+                               break;
                        case H_OFFPAGE:
-                               p = (u_int8_t *)hk + sizeof(u_int8_t);
-                               ++p;
-                               SWAP32(p);                      /* tlen */
+                               p = HOFFPAGE_PGNO(P_ENTRY(h, i));
                                SWAP32(p);                      /* pgno */
-                               SWAP16(p);                      /* offset */
-                               SWAP16(p);                      /* len */
+                               SWAP32(p);                      /* tlen */
                                break;
                        }
 
-                       if (!pgin)
-                               M_16_SWAP(h->inp[i]);
                }
+               if (!pgin)
+                       for (i = 0; i < NUM_ENT(h); i++)
+                               M_16_SWAP(h->inp[i]);
                break;
        case P_LBTREE:
        case P_LRECNO:
index f86fd67..09d8057 100644 (file)
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_pr.c      10.16 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)db_pr.c      10.17 (Sleepycat) 9/15/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -184,7 +184,7 @@ __db_prbtree(dbp)
        BTMETA *mp;
        BTREE *t;
        DB_LOCK lock;
-       EPG *sp;
+       EPG *epg;
        FILE *fp;
        RECNO *rp;
        db_pgno_t i;
@@ -230,8 +230,8 @@ __db_prbtree(dbp)
                    (u_long)rp->re_emap, (u_long)rp->re_msize);
        }
        (void)fprintf(fp, "stack:");
-       for (sp = t->bt_stack; sp < t->bt_sp; ++sp)
-               (void)fprintf(fp, " %lu", (u_long)sp->page->pgno);
+       for (epg = t->bt_stack; epg < t->bt_sp; ++epg)
+               (void)fprintf(fp, " %lu", (u_long)epg->page->pgno);
        (void)fprintf(fp, "\n");
        (void)fprintf(fp, "ovflsize: %lu\n", (u_long)t->bt_ovflsize);
        (void)fflush(fp);
@@ -367,20 +367,15 @@ __db_prpage(h, all)
 {
        BINTERNAL *bi;
        BKEYDATA *bk;
-       HKEYDATA *hkd;
        HOFFPAGE a_hkd;
        FILE *fp;
        RINTERNAL *ri;
        db_indx_t dlen, len, i;
        db_pgno_t pgno;
-       u_int8_t *p;
        int deleted, ret;
        const char *s;
-
-       bi = NULL;                              /* XXX: Shut the compiler up. */
-       bk = NULL;
-       hkd = NULL;
-       ri = NULL;
+       u_int8_t *ep, *hk, *p;
+       void *sp;
 
        fp = __db_prinit(NULL);
 
@@ -450,22 +445,18 @@ __db_prpage(h, all)
                deleted = 0;
                switch (TYPE(h)) {
                case P_HASH:
-                       hkd = GET_HKEYDATA(h, i);
-                       break;
                case P_IBTREE:
-                       bi = GET_BINTERNAL(h, i);
-                       break;
                case P_IRECNO:
-                       ri = GET_RINTERNAL(h, i);
+                       sp = P_ENTRY(h, i);
                        break;
                case P_LBTREE:
-                       bk = GET_BKEYDATA(h, i);
+                       sp = P_ENTRY(h, i);
                        deleted = i % 2 == 0 &&
                            B_DISSET(GET_BKEYDATA(h, i + O_INDX)->type);
                        break;
                case P_LRECNO:
                case P_DUPLICATE:
-                       bk = GET_BKEYDATA(h, i);
+                       sp = P_ENTRY(h, i);
                        deleted = B_DISSET(GET_BKEYDATA(h, i)->type);
                        break;
                default:
@@ -478,11 +469,11 @@ __db_prpage(h, all)
                    deleted ? "D" : " ", (u_long)i, (u_long)h->inp[i]);
                switch (TYPE(h)) {
                case P_HASH:
-                       switch (hkd->type) {
+                       hk = sp;
+                       switch (HPAGE_PTYPE(hk)) {
                        case H_OFFDUP:
                                memcpy(&pgno,
-                                   (u_int8_t *)hkd + SSZ(HOFFDUP, pgno),
-                                   sizeof(db_pgno_t));
+                                   HOFFDUP_PGNO(hk), sizeof(db_pgno_t));
                                fprintf(fp,
                                    "%4lu [offpage dups]\n", (u_long)pgno);
                                break;
@@ -499,7 +490,8 @@ __db_prpage(h, all)
                                        len = 1;
 
                                fprintf(fp, "Duplicates:\n");
-                               for (p = hkd->data; p < hkd->data + len;) {
+                               for (p = HKEYDATA_DATA(hk),
+                                   ep = p + len; p < ep;) {
                                        memcpy(&dlen, p, sizeof(db_indx_t));
                                        p += sizeof(db_indx_t);
                                        fprintf(fp, "\t\t");
@@ -509,13 +501,13 @@ __db_prpage(h, all)
                                break;
                        case H_KEYDATA:
                                if (i != 0)
-                                       __db_pr(hkd->data,
+                                       __db_pr(HKEYDATA_DATA(hk),
                                            LEN_HKEYDATA(h, 0, i));
                                else
-                                       fprintf(fp, "%s\n", hkd->data);
+                                       fprintf(fp, "%s\n", HKEYDATA_DATA(hk));
                                break;
                        case H_OFFPAGE:
-                               memcpy(&a_hkd, hkd, HOFFPAGE_SIZE);
+                               memcpy(&a_hkd, hk, HOFFPAGE_SIZE);
                                fprintf(fp,
                                    "overflow: total len: %4lu page: %4lu\n",
                                    (u_long)a_hkd.tlen, (u_long)a_hkd.pgno);
@@ -523,6 +515,7 @@ __db_prpage(h, all)
                        }
                        break;
                case P_IBTREE:
+                       bi = sp;
                        fprintf(fp, "count: %4lu pgno: %4lu ",
                            (u_long)bi->nrecs, (u_long)bi->pgno);
                        switch (B_TYPE(bi->type)) {
@@ -541,12 +534,14 @@ __db_prpage(h, all)
                        }
                        break;
                case P_IRECNO:
+                       ri = sp;
                        fprintf(fp, "entries %4lu pgno %4lu\n",
                            (u_long)ri->nrecs, (u_long)ri->pgno);
                        break;
                case P_LBTREE:
                case P_LRECNO:
                case P_DUPLICATE:
+                       bk = sp;
                        switch (B_TYPE(bk->type)) {
                        case B_KEYDATA:
                                __db_pr(bk->data, bk->len);
@@ -582,13 +577,9 @@ __db_isbad(h, die)
 {
        BINTERNAL *bi;
        BKEYDATA *bk;
-       HKEYDATA *hkd;
        FILE *fp;
        db_indx_t i;
-
-       bi = NULL;                              /* XXX: Shut the compiler up. */
-       bk = NULL;
-       hkd = NULL;
+       int type;
 
        fp = __db_prinit(NULL);
 
@@ -618,13 +609,13 @@ __db_isbad(h, die)
                }
                switch (TYPE(h)) {
                case P_HASH:
-                       hkd = GET_HKEYDATA(h, i);
-                       if (hkd->type != H_OFFDUP &&
-                           hkd->type != H_DUPLICATE &&
-                           hkd->type != H_KEYDATA &&
-                           hkd->type != H_OFFPAGE) {
+                       type = HPAGE_TYPE(h, i);
+                       if (type != H_OFFDUP &&
+                           type != H_DUPLICATE &&
+                           type != H_KEYDATA &&
+                           type != H_OFFPAGE) {
                                fprintf(fp, "ILLEGAL HASH TYPE: %lu\n",
-                                   (u_long)hkd->type);
+                                   (u_long)type);
                                goto bad;
                        }
                        break;
index baf0665..ee2bc82 100644 (file)
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_ret.c     10.6 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)db_ret.c     10.7 (Sleepycat) 9/15/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -46,18 +46,19 @@ __db_ret(dbp, h, indx, dbt, memp, memsize)
        HOFFPAGE ho;
        BOVERFLOW *bo;
        u_int32_t len;
-       void *data, *hk;
+       u_int8_t *hk;
+       void *data;
 
        switch (TYPE(h)) {
        case P_HASH:
                hk = P_ENTRY(h, indx);
-               if (((HKEYDATA *)hk)->type == H_OFFPAGE) {
+               if (HPAGE_PTYPE(hk) == H_OFFPAGE) {
                        memcpy(&ho, hk, sizeof(HOFFPAGE));
                        return (__db_goff(dbp, dbt,
                            ho.tlen, ho.pgno, memp, memsize));
                }
                len = LEN_HKEYDATA(h, dbp->pgsize, indx);
-               data = ((HKEYDATA *)hk)->data;
+               data = HKEYDATA_DATA(hk);
                break;
        case P_DUPLICATE:
        case P_LBTREE:
index e956e80..170baf5 100644 (file)
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_thread.c  8.11 (Sleepycat) 8/18/97";
+static const char sccsid[] = "@(#)db_thread.c  8.12 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -42,7 +42,7 @@ __db_gethandle(dbp, am_func, dbpp)
        DB *ret_dbp;
        int ret, t_ret;
 
-       if ((ret = __db_mutex_lock((db_mutex_t *)dbp->mutex, -1,
+       if ((ret = __db_mutex_lock((db_mutex_t *)dbp->mutexp, -1,
            dbp->dbenv == NULL ? NULL : dbp->dbenv->db_yield)) != 0)
                return (ret);
 
@@ -75,7 +75,7 @@ err:          if (ret_dbp != NULL)
                        FREE(ret_dbp, sizeof(*ret_dbp));
        }
        if ((t_ret =
-           __db_mutex_unlock((db_mutex_t *)dbp->mutex, -1)) != 0 && ret == 0)
+           __db_mutex_unlock((db_mutex_t *)dbp->mutexp, -1)) != 0 && ret == 0)
                ret = t_ret;
        return (ret);
 }
@@ -94,13 +94,13 @@ __db_puthandle(dbp)
        int ret;
 
        master = dbp->master;
-       if ((ret = __db_mutex_lock((db_mutex_t *)master->mutex, -1,
+       if ((ret = __db_mutex_lock((db_mutex_t *)master->mutexp, -1,
            dbp->dbenv == NULL ? NULL : dbp->dbenv->db_yield)) != 0)
                return (ret);
 
        LIST_INSERT_HEAD(&master->handleq, dbp, links);
 
-       return (__db_mutex_unlock((db_mutex_t *)master->mutex, -1));
+       return (__db_mutex_unlock((db_mutex_t *)master->mutexp, -1));
 }
 
 /*
index 650d365..b6a4d0a 100644 (file)
@@ -36,7 +36,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     @(#)db_185.h.src        8.3 (Sleepycat) 7/27/97
+ *     @(#)db_185.h.src        8.4 (Sleepycat) 9/16/97
  */
 
 #ifndef _DB_185_H_
 
 #endif
 
+/*
+ * XXX
+ * SGI/IRIX already has a pgno_t.
+ */
+#ifdef sgi
+#define        pgno_t  db_pgno_t
+#endif
+
 #define        MAX_PAGE_NUMBER 0xffffffff      /* >= # of pages in a file */
 typedef u_int32_t      pgno_t;
 #define        MAX_PAGE_OFFSET 65535           /* >= # of bytes in a page */
index a088c69..56dfddb 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *     Sleepycat Software.  All rights reserved.
  *
- *     @(#)db_int.h.src        10.28 (Sleepycat) 8/20/97
+ *     @(#)db_int.h.src        10.30 (Sleepycat) 9/23/97
  */
 
 #ifndef _DB_INTERNAL_H_
 
 #define        DB_MINCACHE     10              /* Minimum cached pages */
 
-/* Handle `errno' in the presence of multi-threading correctly.  On some
-   systems we need a special macro to do this right.  */
-#ifndef __set_errno
-# define __set_errno(val) (errno) = (val)
-#endif
-
 /*
  * Aligning items to particular sizes or in pages or memory.  ALIGNP is a
  * separate macro, as we've had to cast the pointer to different integral
@@ -94,7 +88,7 @@
 
 /* Structure used to print flag values. */
 typedef struct __fn {
-       u_int32_t mask;                 /* Flag value. */
+       u_int32_t   mask;               /* Flag value. */
        const char *name;               /* Flag name. */
 } FN;
 
@@ -183,11 +177,11 @@ typedef struct _db_mutex_t {
 /* Lock/unlock a DB thread. */
 #define        DB_THREAD_LOCK(dbp)                                             \
        (F_ISSET(dbp, DB_AM_THREAD) ?                                   \
-           __db_mutex_lock((db_mutex_t *)(dbp)->mutex,  -1,            \
+           __db_mutex_lock((db_mutex_t *)(dbp)->mutexp,  -1,           \
                (dbp)->dbenv == NULL ? NULL : (dbp)->dbenv->db_yield) : 0)
 #define        DB_THREAD_UNLOCK(dbp)                                           \
        (F_ISSET(dbp, DB_AM_THREAD) ?                                   \
-           __db_mutex_unlock((db_mutex_t *)(dbp)->mutex,  -1) : 0)
+           __db_mutex_unlock((db_mutex_t *)(dbp)->mutexp,  -1) : 0)
 
 /* Btree/recno local statistics structure. */
 struct __db_bt_lstat;  typedef struct __db_bt_lstat DB_BTREE_LSTAT;
@@ -312,14 +306,6 @@ typedef struct __dbpginfo {
  * Transactions and recovery.
  *******************************************************/
 /*
- * The locker id space is divided between the transaction manager and the lock
- * manager.  Lockid's start at 0 and go to MAX_LOCKER_ID.  Txn Id's start at
- * MAX_LOCKER_ID + 1 and go up to MAX_TXNID.
- */
-#define        MAX_LOCKER_ID   0x0fffffff
-#define        MAX_TXNID       0xffffffff
-
-/*
  * Out of band value for a lock.  The locks are returned to callers as offsets
  * into the lock regions.  Since the RLAYOUT structure begins all regions, an
  * offset of 0 is guaranteed not to be a valid lock.
index 6d8c400..d986e08 100644 (file)
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash.c       10.25 (Sleepycat) 8/24/97";
+static const char sccsid[] = "@(#)hash.c       10.27 (Sleepycat) 9/15/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -573,8 +573,6 @@ __ham_c_close(cursor)
        DBC *cursor;
 {
        DB  *ldbp;
-       HTAB *hashp;
-       HASH_CURSOR *hcp;
        int ret;
 
        DEBUG_LWRITE(cursor->dbp, cursor->txn, "ham_c_close", NULL, NULL, 0);
@@ -590,8 +588,32 @@ __ham_c_close(cursor)
        if (F_ISSET(cursor->dbp, DB_AM_THREAD) &&
            (ret = __db_gethandle(cursor->dbp, __ham_hdup, &ldbp)) != 0)
                return (ret);
-       hashp = (HTAB *)ldbp->internal;
-       hcp = (HASH_CURSOR *)cursor->internal;
+
+       ret = __ham_c_iclose(ldbp, cursor);
+
+       if (F_ISSET(ldbp, DB_AM_THREAD))
+               __db_puthandle(ldbp);
+       return (ret);
+}
+/*
+ * __ham_c_iclose --
+ *
+ * Internal cursor close routine; assumes it is being passed the correct
+ * handle, rather than getting and putting a handle.
+ *
+ * PUBLIC: int __ham_c_iclose __P((DB *, DBC *));
+ */
+int
+__ham_c_iclose(dbp, dbc)
+       DB *dbp;
+       DBC *dbc;
+{
+       HASH_CURSOR *hcp;
+       HTAB *hashp;
+       int ret;
+
+       hashp = (HTAB *)dbp->internal;
+       hcp = (HASH_CURSOR *)dbc->internal;
        ret = __ham_item_done(hashp, hcp, 0);
 
        if (hcp->big_key)
@@ -602,19 +624,16 @@ __ham_c_close(cursor)
        /*
         * All cursors (except the default ones) are linked off the master.
         * Therefore, when we close the cursor, we have to remove it from
-        * the master, not the local one.  When we are closing the file in
-        * its entirety, then we clear the THREAD bit and the master and
-        * local are identical, so we remove the correct one.
+        * the master, not the local one.
+        * XXX I am always removing from the master; what about local cursors?
         */
-       DB_THREAD_LOCK(cursor->dbp);
-       TAILQ_REMOVE(&cursor->dbp->curs_queue, cursor, links);
-       DB_THREAD_UNLOCK(cursor->dbp);
-
-       if (F_ISSET(cursor->dbp, DB_AM_THREAD))
-               __db_puthandle(ldbp);
+       DB_THREAD_LOCK(dbc->dbp);
+       TAILQ_REMOVE(&dbc->dbp->curs_queue, dbc, links);
+       DB_THREAD_UNLOCK(dbc->dbp);
 
        FREE(hcp, sizeof(HASH_CURSOR));
-       FREE(cursor, sizeof(DBC));
+       FREE(dbc, sizeof(DBC));
+
        return (ret);
 }
 
@@ -695,10 +714,9 @@ __ham_c_del(cursor, flags)
                        hcp->dndx = 0;                          /* Case 2 */
                        hcp->dpgno = PGNO(hcp->dpagep);
                        if (ppgno == PGNO_INVALID)
-                               memcpy(P_ENTRY(hcp->pagep,
-                                   H_DATAINDEX(hcp->bndx)) +
-                                   SSZ(HOFFDUP, pgno), &hcp->dpgno,
-                                   sizeof(db_pgno_t));
+                               memcpy(HOFFDUP_PGNO(P_ENTRY(hcp->pagep,
+                                   H_DATAINDEX(hcp->bndx))),
+                                   &hcp->dpgno, sizeof(db_pgno_t));
                        F_SET(hcp, H_DELETED);
                } else                                  /* Case 1 */
                        F_SET(hcp, H_DELETED);
@@ -1051,18 +1069,17 @@ __ham_dup_return(hashp, hcp, val, flags)
        DBT *val;
        int flags;
 {
-       HKEYDATA *hk;
        PAGE *pp;
        DBT *myval, tmp_val;
        db_indx_t ndx;
        db_pgno_t pgno;
-       u_int8_t type;
+       u_int8_t *hk, type;
        int indx, ret;
        db_indx_t len;
 
        /* Check for duplicate and return the first one. */
        ndx = H_DATAINDEX(hcp->bndx);
-       type = GET_HKEYDATA(hcp->pagep, ndx)->type;
+       type = HPAGE_TYPE(hcp->pagep, ndx);
        pp = hcp->pagep;
        myval = val;
 
@@ -1088,7 +1105,8 @@ __ham_dup_return(hashp, hcp, val, flags)
                                hcp->dndx = 0;
                                hcp->dup_off = 0;
                                do {
-                                       memcpy(&len, hk->data + hcp->dup_off,
+                                       memcpy(&len,
+                                           HKEYDATA_DATA(hk) + hcp->dup_off,
                                            sizeof(db_indx_t));
                                        hcp->dup_off += DUP_SIZE(len);
                                        hcp->dndx++;
@@ -1096,15 +1114,15 @@ __ham_dup_return(hashp, hcp, val, flags)
                                hcp->dup_off -= DUP_SIZE(len);
                                hcp->dndx--;
                        } else {
-                               memcpy(&len, hk->data, sizeof(db_indx_t));
+                               memcpy(&len,
+                                   HKEYDATA_DATA(hk), sizeof(db_indx_t));
                                hcp->dup_off = 0;
                                hcp->dndx = 0;
                        }
                        hcp->dup_len = len;
                } else if (type == H_OFFDUP) {
                        F_SET(hcp, H_ISDUP);
-                       memcpy(&pgno,
-                           P_ENTRY(hcp->pagep, ndx) + SSZ(HOFFDUP, pgno),
+                       memcpy(&pgno, HOFFDUP_PGNO(P_ENTRY(hcp->pagep, ndx)),
                            sizeof(db_pgno_t));
                        if (flags == DB_LAST || flags == DB_PREV) {
                                indx = (int)hcp->dndx;
@@ -1166,7 +1184,7 @@ __ham_overwrite(hashp, hcp, nval)
        DBT *nval;
 {
        DBT *myval, tmp_val;
-       HKEYDATA *hk;
+       u_int8_t *hk;
 
        if (F_ISSET(hashp->dbp, DB_AM_DUP))
                return (__ham_add_dup(hashp, hcp, nval, DB_KEYLAST));
@@ -1176,10 +1194,9 @@ __ham_overwrite(hashp, hcp, nval)
                F_SET(&tmp_val, DB_DBT_PARTIAL);
                tmp_val.doff = 0;
                hk = H_PAIRDATA(hcp->pagep, hcp->bndx);
-               if (hk->type == H_OFFPAGE)
+               if (HPAGE_PTYPE(hk) == H_OFFPAGE)
                        memcpy(&tmp_val.dlen,
-                           (u_int8_t *)hk + SSZ(HOFFPAGE, tlen),
-                           sizeof(u_int32_t));
+                           HOFFPAGE_TLEN(hk), sizeof(u_int32_t));
                else
                        tmp_val.dlen = LEN_HDATA(hcp->pagep,
                            hashp->hdr->pagesize,hcp->bndx);
@@ -1207,10 +1224,10 @@ __ham_lookup(hashp, hcp, key, sought, mode)
        u_int32_t sought;
        db_lockmode_t mode;
 {
-       HKEYDATA *hk;
        db_pgno_t pgno;
        u_int32_t tlen;
        int match, ret, t_ret;
+       u_int8_t *hk;
 
        /*
         * Set up cursor so that we're looking for space to add an item
@@ -1229,14 +1246,12 @@ __ham_lookup(hashp, hcp, key, sought, mode)
                        break;
 
                hk = H_PAIRKEY(hcp->pagep, hcp->bndx);
-               switch (hk->type) {
+               switch (HPAGE_PTYPE(hk)) {
                case H_OFFPAGE:
-                       memcpy(&tlen, (u_int8_t *)hk + SSZ(HOFFPAGE, tlen),
-                           sizeof(u_int32_t));
+                       memcpy(&tlen, HOFFPAGE_TLEN(hk), sizeof(u_int32_t));
                        if (tlen == key->size) {
                                memcpy(&pgno,
-                                   (u_int8_t *)hk + SSZ(HOFFPAGE, pgno),
-                                   sizeof(db_pgno_t));
+                                   HOFFPAGE_PGNO(hk), sizeof(db_pgno_t));
                                match = __db_moff(hashp->dbp, key, pgno);
                                if (match == 0) {
                                        F_SET(hcp, H_OK);
@@ -1247,7 +1262,8 @@ __ham_lookup(hashp, hcp, key, sought, mode)
                case H_KEYDATA:
                        if (key->size == LEN_HKEY(hcp->pagep,
                            hashp->hdr->pagesize, hcp->bndx) &&
-                           memcmp(key->data, hk->data, key->size) == 0) {
+                           memcmp(key->data,
+                           HKEYDATA_DATA(hk), key->size) == 0) {
                                F_SET(hcp, H_OK);
                                return (0);
                        }
index f8ab80c..2279de9 100644 (file)
@@ -138,7 +138,7 @@ __ham_insdel_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __ham_insdel_read(dbtp->data, &argp)) != 0)
+       if ((ret = __ham_insdel_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]ham_insdel: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -335,7 +335,7 @@ __ham_newpage_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __ham_newpage_read(dbtp->data, &argp)) != 0)
+       if ((ret = __ham_newpage_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]ham_newpage: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -498,7 +498,7 @@ __ham_splitmeta_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __ham_splitmeta_read(dbtp->data, &argp)) != 0)
+       if ((ret = __ham_splitmeta_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]ham_splitmeta: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -659,7 +659,7 @@ __ham_splitdata_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __ham_splitdata_read(dbtp->data, &argp)) != 0)
+       if ((ret = __ham_splitdata_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]ham_splitdata: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -851,7 +851,7 @@ __ham_replace_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __ham_replace_read(dbtp->data, &argp)) != 0)
+       if ((ret = __ham_replace_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]ham_replace: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -1053,7 +1053,7 @@ __ham_newpgno_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __ham_newpgno_read(dbtp->data, &argp)) != 0)
+       if ((ret = __ham_newpgno_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]ham_newpgno: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -1218,7 +1218,7 @@ __ham_ovfl_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __ham_ovfl_read(dbtp->data, &argp)) != 0)
+       if ((ret = __ham_ovfl_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]ham_ovfl: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
index 22901af..9cebe72 100644 (file)
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash_conv.c  10.3 (Sleepycat) 6/21/97";
+static const char sccsid[] = "@(#)hash_conv.c  10.4 (Sleepycat) 9/15/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -20,12 +20,11 @@ static const char sccsid[] = "@(#)hash_conv.c       10.3 (Sleepycat) 6/21/97";
 #include "hash.h"
 
 /*
- * __h_pgin, __ham_pgout --
- *     Convert host-specific page layout to/from the host-independent
- *     format stored on disk.
+ * __ham_pgin --
+ *     Convert host-specific page layout from the host-independent format
+ *     stored on disk.
  *
  * PUBLIC: int __ham_pgin __P((db_pgno_t, void *, DBT *));
- * PUBLIC: int __ham_pgout __P((db_pgno_t, void *, DBT *));
  */
 int
 __ham_pgin(pg, pp, cookie)
@@ -49,9 +48,17 @@ __ham_pgin(pg, pp, cookie)
 
        if (!pginfo->needswap)
                return (0);
-       return (pg == PGNO_METADATA ? __ham_mswap(pp) : __db_pgin(pg, pp));
+       return (pg == PGNO_METADATA ?
+           __ham_mswap(pp) : __db_pgin(pg, pginfo->db_pagesize, pp));
 }
 
+/*
+ * __ham_pgout --
+ *     Convert host-specific page layout to the host-independent format
+ *     stored on disk.
+ *
+ * PUBLIC: int __ham_pgout __P((db_pgno_t, void *, DBT *));
+ */
 int
 __ham_pgout(pg, pp, cookie)
        db_pgno_t pg;
@@ -63,7 +70,8 @@ __ham_pgout(pg, pp, cookie)
        pginfo = (DB_PGINFO *)cookie->data;
        if (!pginfo->needswap)
                return (0);
-       return (pg == PGNO_METADATA ? __ham_mswap(pp) : __db_pgout(pg, pp));
+       return (pg == PGNO_METADATA ?
+           __ham_mswap(pp) : __db_pgout(pg, pginfo->db_pagesize, pp));
 }
 
 /*
index c9590fa..71bd1c5 100644 (file)
@@ -42,7 +42,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash_dup.c   10.6 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)hash_dup.c   10.7 (Sleepycat) 9/15/97";
 #endif /* not lint */
 
 /*
@@ -99,9 +99,9 @@ __ham_add_dup(hashp, hcp, nval, flags)
        int flags;
 {
        DBT pval, tmp_val;
-       HKEYDATA *hk;
        u_int32_t del_len, new_size;
        int ret;
+       u_int8_t *hk;
 
        if (flags == DB_CURRENT && hcp->dpgno == PGNO_INVALID)
                del_len = hcp->dup_len;
@@ -128,8 +128,8 @@ __ham_add_dup(hashp, hcp, nval, flags)
         * the addition of the new item will make the set large, or
         * if there isn't enough room on this page to add the next item.
         */
-       if (hk->type != H_OFFDUP &&
-           (hk->type == H_OFFPAGE || ISBIG(hashp, new_size) ||
+       if (HPAGE_PTYPE(hk) != H_OFFDUP &&
+           (HPAGE_PTYPE(hk) == H_OFFPAGE || ISBIG(hashp, new_size) ||
            DUP_SIZE(nval->size) - del_len > P_FREESPACE(hcp->pagep))) {
 
                if ((ret = __ham_dup_convert(hashp, hcp)) != 0)
@@ -139,16 +139,17 @@ __ham_add_dup(hashp, hcp, nval, flags)
        }
 
        /* There are two separate cases here: on page and off page. */
-       if (hk->type != H_OFFDUP) {
-               if (hk->type != H_DUPLICATE) {
-                       hk->type = H_DUPLICATE;
+       if (HPAGE_PTYPE(hk) != H_OFFDUP) {
+               if (HPAGE_PTYPE(hk) != H_DUPLICATE) {
+                       HPAGE_PTYPE(hk) = H_DUPLICATE;
                        pval.flags = 0;
-                       pval.data = hk->data;
+                       pval.data = HKEYDATA_DATA(hk);
                        pval.size = LEN_HDATA(hcp->pagep, hashp->hdr->pagesize,
                            hcp->bndx);
-                       if ((ret = __ham_make_dup(&pval, &tmp_val, &hcp->big_data,
-                           &hcp->big_datalen)) != 0 ||
-                           (ret = __ham_replpair(hashp, hcp, &tmp_val, 1)) != 0)
+                       if ((ret =
+                           __ham_make_dup(&pval, &tmp_val, &hcp->big_data,
+                           &hcp->big_datalen)) != 0 || (ret =
+                           __ham_replpair(hashp, hcp, &tmp_val, 1)) != 0)
                                return (ret);
                }
 
@@ -187,8 +188,7 @@ __ham_add_dup(hashp, hcp, nval, flags)
 
        /* If we get here, then we're on duplicate pages. */
        if (hcp->dpgno == PGNO_INVALID) {
-               memcpy(&hcp->dpgno,
-                   (u_int8_t *)hk + SSZ(HOFFDUP, pgno), sizeof(db_pgno_t));
+               memcpy(&hcp->dpgno, HOFFDUP_PGNO(hk), sizeof(db_pgno_t));
                hcp->dndx = 0;
        }
 
@@ -259,14 +259,13 @@ __ham_dup_convert(hashp, hcp)
         * Now put the duplicates onto the new page.
         */
        dbt.flags = 0;
-       switch (((HKEYDATA *)H_PAIRDATA(hcp->pagep, hcp->bndx))->type) {
+       switch (HPAGE_PTYPE(H_PAIRDATA(hcp->pagep, hcp->bndx))) {
        case H_KEYDATA:
                /* Simple case, one key on page; move it to dup page. */
                dndx = 0;
                dbt.size =
                    LEN_HDATA(hcp->pagep, hashp->hdr->pagesize, hcp->bndx);
-               dbt.data =
-                   ((HKEYDATA *)H_PAIRDATA(hcp->pagep, hcp->bndx))->data;
+               dbt.data = HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx));
                ret = __db_pitem(hashp->dbp, hcp->dpagep,
                    (u_int32_t)dndx, BKEYDATA_SIZE(dbt.size), NULL, &dbt);
                if (ret == 0)
@@ -289,7 +288,7 @@ __ham_dup_convert(hashp, hcp)
                        __ham_dirty_page(hashp, hcp->dpagep);
                break;
        case H_DUPLICATE:
-               p = ((HKEYDATA *)H_PAIRDATA(hcp->pagep, hcp->bndx))->data;
+               p = HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx));
                pend = p +
                    LEN_HDATA(hcp->pagep, hashp->hdr->pagesize, hcp->bndx);
 
@@ -366,24 +365,23 @@ __ham_check_move(hashp, hcp, add_len)
 {
        DBT k, d;
        DB_LSN new_lsn;
-       HKEYDATA *hk;
        PAGE *next_pagep;
        db_pgno_t next_pgno;
        int rectype, ret;
        u_int32_t new_datalen, old_len;
+       u_int8_t *hk;
 
        /*
         * Check if we can do whatever we need to on this page.  If not,
         * then we'll have to move the current element to a new page.
         */
-
        hk = H_PAIRDATA(hcp->pagep, hcp->bndx);
 
        /*
         * If the item is already off page duplicates or an offpage item,
         * then we know we can do whatever we need to do in-place
         */
-       if (hk->type == H_OFFDUP || hk->type == H_OFFPAGE)
+       if (HPAGE_PTYPE(hk) == H_OFFDUP || HPAGE_PTYPE(hk) == H_OFFPAGE)
                return (0);
 
        old_len =
@@ -443,22 +441,25 @@ __ham_check_move(hashp, hcp, add_len)
                rectype = PUTPAIR;
                k.flags = 0;
                d.flags = 0;
-               if (H_PAIRKEY(hcp->pagep, hcp->bndx)->type == H_OFFPAGE) {
+               if (HPAGE_PTYPE(
+                   H_PAIRKEY(hcp->pagep, hcp->bndx)) == H_OFFPAGE) {
                        rectype |= PAIR_KEYMASK;
                        k.data = H_PAIRKEY(hcp->pagep, hcp->bndx);
                        k.size = HOFFPAGE_SIZE;
                } else {
-                       k.data = H_PAIRKEY(hcp->pagep, hcp->bndx)->data;
+                       k.data =
+                           HKEYDATA_DATA(H_PAIRKEY(hcp->pagep, hcp->bndx));
                        k.size = LEN_HKEY(hcp->pagep,
                            hashp->hdr->pagesize, hcp->bndx);
                }
 
-               if (hk->type == H_OFFPAGE) {
+               if (HPAGE_PTYPE(hk) == H_OFFPAGE) {
                        rectype |= PAIR_DATAMASK;
                        d.data = H_PAIRDATA(hcp->pagep, hcp->bndx);
                        d.size = HOFFPAGE_SIZE;
                } else {
-                       d.data = H_PAIRDATA(hcp->pagep, hcp->bndx)->data;
+                       d.data =
+                           HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx));
                        d.size = LEN_HDATA(hcp->pagep,
                            hashp->hdr->pagesize, hcp->bndx);
                }
index 2ef47af..1bf12c4 100644 (file)
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash_func.c  10.6 (Sleepycat) 7/26/97";
+static const char sccsid[] = "@(#)hash_func.c  10.7 (Sleepycat) 9/16/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -64,7 +64,7 @@ static const char sccsid[] = "@(#)hash_func.c 10.6 (Sleepycat) 7/26/97";
  *
  * PUBLIC: u_int32_t __ham_func2 __P((const void *, u_int32_t));
  */
-#define        dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
+#define        DCHARHASH(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
 
 u_int32_t
 __ham_func2(key, len)
@@ -81,7 +81,7 @@ __ham_func2(key, len)
                c = *k++;
                if (!c && k > e)
                        break;
-               dcharhash(h, c);
+               DCHARHASH(h, c);
        }
        return (h);
 }
index 68c31b1..8ba42da 100644 (file)
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash_page.c  10.18 (Sleepycat) 8/21/97";
+static const char sccsid[] = "@(#)hash_page.c  10.24 (Sleepycat) 9/17/97";
 #endif /* not lint */
 
-
 /*
  * PACKAGE:  hashing
  *
@@ -85,7 +84,7 @@ static const char sccsid[] = "@(#)hash_page.c 10.18 (Sleepycat) 8/21/97";
 static int __ham_lock_bucket __P((DB *, HASH_CURSOR *, db_lockmode_t));
 
 #ifdef DEBUG_SLOW
-static void     account_page(HTAB *, db_pgno_t, int);
+static void  __account_page(HTAB *, db_pgno_t, int);
 #endif
 
 /*
@@ -121,7 +120,7 @@ __ham_item(hashp, cursorp, mode)
                 * pointer to be the beginning of the datum.
                 */
                memcpy(&cursorp->dup_len,
-                   H_PAIRDATA(cursorp->pagep, cursorp->bndx)->data +
+                   HKEYDATA_DATA(H_PAIRDATA(cursorp->pagep, cursorp->bndx)) +
                    cursorp->dup_off, sizeof(db_indx_t));
        else if (F_ISSET(cursorp, H_ISDUP)) {
                /* Make sure we're not about to run off the page. */
@@ -326,8 +325,8 @@ __ham_item_prev(hashp, cursorp, mode)
                                else {
                                        HASH_CURSOR *h;
                                        h = cursorp;
-                                       memcpy(&h->dup_len,
-                                           H_PAIRDATA(h->pagep, h->bndx)->data
+                                       memcpy(&h->dup_len, HKEYDATA_DATA(
+                                           H_PAIRDATA(h->pagep, h->bndx))
                                            + h->dup_off - sizeof(db_indx_t),
                                            sizeof(db_indx_t));
                                        cursorp->dup_off -=
@@ -481,7 +480,7 @@ __ham_putitem(p, dbt, type)
        } else {
                off = HOFFSET(p) - HKEYDATA_SIZE(dbt->size);
                HOFFSET(p) = p->inp[n] = off;
-               PUT_HKEYDATA(GET_HKEYDATA(p, n), dbt->data, dbt->size, type);
+               PUT_HKEYDATA(P_ENTRY(p, n), dbt->data, dbt->size, type);
        }
 
        /* Adjust page info. */
@@ -524,24 +523,24 @@ __ham_del_pair(hashp, cursorp)
         * entry referring to the big item.
         */
        ret = 0;
-       if (H_PAIRKEY(p, ndx)->type == H_OFFPAGE) {
-               memcpy(&pgno, (u_int8_t *)GET_HOFFPAGE(p, H_KEYINDEX(ndx)) +
-                   SSZ(HOFFPAGE, pgno), sizeof(db_pgno_t));
+       if (HPAGE_PTYPE(H_PAIRKEY(p, ndx)) == H_OFFPAGE) {
+               memcpy(&pgno, HOFFPAGE_PGNO(P_ENTRY(p, H_KEYINDEX(ndx))),
+                   sizeof(db_pgno_t));
                ret = __db_doff(hashp->dbp, pgno, __ham_del_page);
        }
 
        if (ret == 0)
-               switch (H_PAIRDATA(p, ndx)->type) {
+               switch (HPAGE_PTYPE(H_PAIRDATA(p, ndx))) {
                case H_OFFPAGE:
                        memcpy(&pgno,
-                           (u_int8_t *)GET_HOFFPAGE(p, H_DATAINDEX(ndx)) +
-                           SSZ(HOFFPAGE, pgno), sizeof(db_pgno_t));
+                           HOFFPAGE_PGNO(P_ENTRY(p, H_DATAINDEX(ndx))),
+                           sizeof(db_pgno_t));
                        ret = __db_doff(hashp->dbp, pgno, __ham_del_page);
                        break;
                case H_OFFDUP:
                        memcpy(&pgno,
-                           (u_int8_t *)GET_HOFFDUP(p, H_DATAINDEX(ndx)) +
-                           SSZ(HOFFDUP, pgno), sizeof(db_pgno_t));
+                           HOFFDUP_PGNO(P_ENTRY(p, H_DATAINDEX(ndx))),
+                           sizeof(db_pgno_t));
                        ret = __db_ddup(hashp->dbp, pgno, __ham_del_page);
                        break;
                }
@@ -706,13 +705,12 @@ __ham_replpair(hashp, hcp, dbt, make_dup)
        DBT *dbt;
        u_int32_t make_dup;
 {
-       DBT old_dbt, tmp;
+       DBT old_dbt, tdata, tmp;
        DB_LSN  new_lsn;
-       HKEYDATA *hk;
        u_int32_t len;
        int32_t change;
        int is_big, ret, type;
-       u_int8_t *beg, *dest, *end, *src;
+       u_int8_t *beg, *dest, *end, *hk, *src;
 
        /*
         * Big item replacements are handled in generic code.
@@ -738,11 +736,10 @@ __ham_replpair(hashp, hcp, dbt, make_dup)
        change = dbt->size - dbt->dlen;
 
        hk = H_PAIRDATA(hcp->pagep, hcp->bndx);
-       is_big = hk->type == H_OFFPAGE;
+       is_big = HPAGE_PTYPE(hk) == H_OFFPAGE;
 
        if (is_big)
-               memcpy(&len, (u_int8_t *)hk + SSZ(HOFFPAGE, tlen),
-                   sizeof(u_int32_t));
+               memcpy(&len, HOFFPAGE_TLEN(hk), sizeof(u_int32_t));
        else
                len = LEN_HKEYDATA(hcp->pagep,
                    hashp->dbp->pgsize, H_DATAINDEX(hcp->bndx));
@@ -770,13 +767,14 @@ __ham_replpair(hashp, hcp, dbt, make_dup)
                    &tmp, &hcp->big_key, &hcp->big_keylen)) != 0)
                        return (ret);
 
-               type = hk->type;
                if (dbt->doff == 0 && dbt->dlen == len) {
                        ret = __ham_del_pair(hashp, hcp);
                        if (ret == 0)
-                           ret = __ham_add_el(hashp, hcp, &tmp, dbt, type);
+                           ret = __ham_add_el(hashp,
+                               hcp, &tmp, dbt, H_KEYDATA);
                } else {                                        /* Case B */
-                       DBT tdata;
+                       type = HPAGE_PTYPE(hk) != H_OFFPAGE ?
+                           HPAGE_PTYPE(hk) : H_KEYDATA;
                        tdata.flags = 0;
                        F_SET(&tdata, DB_DBT_MALLOC | DB_DBT_INTERNAL);
 
@@ -824,7 +822,7 @@ err:                free(tmp.data);
         * Set up pointer into existing data. Do it before the log
         * message so we can use it inside of the log setup.
         */
-       beg = H_PAIRDATA(hcp->pagep, hcp->bndx)->data;
+       beg = HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx));
        beg += dbt->doff;
 
        /*
@@ -885,11 +883,11 @@ __ham_onpage_replace(pagep, pgsize, ndx, off, change, dbt)
                if (off < 0)
                        len = pagep->inp[ndx] - HOFFSET(pagep);
                else if ((u_int32_t)off >= LEN_HKEYDATA(pagep, pgsize, ndx)) {
-                       len = GET_HKEYDATA(pagep, ndx)->data +
+                       len = HKEYDATA_DATA(P_ENTRY(pagep, ndx)) +
                            LEN_HKEYDATA(pagep, pgsize, ndx) - src;
                        zero_me = 1;
                } else
-                       len = (GET_HKEYDATA(pagep, ndx)->data + off) - src;
+                       len = (HKEYDATA_DATA(P_ENTRY(pagep, ndx)) + off) - src;
                dest = src - change;
                memmove(dest, src, len);
                if (zero_me)
@@ -901,7 +899,7 @@ __ham_onpage_replace(pagep, pgsize, ndx, off, change, dbt)
                HOFFSET(pagep) -= change;
        }
        if (off >= 0)
-               memcpy(GET_HKEYDATA(pagep, ndx)->data + off,
+               memcpy(HKEYDATA_DATA(P_ENTRY(pagep, ndx)) + off,
                    dbt->data, dbt->size);
        else
                memcpy(P_ENTRY(pagep, ndx), dbt->data, dbt->size);
@@ -1319,7 +1317,7 @@ __ham_new_page(hashp, addr, type, pp)
                return (ret);
 
 #ifdef DEBUG_SLOW
-       account_page(hashp, addr, 1);
+       __account_page(hashp, addr, 1);
 #endif
        /* This should not be necessary because page-in should do it. */
        P_INIT(pagep,
@@ -1398,7 +1396,7 @@ __ham_put_page(dbp, pagep, is_dirty)
        int32_t is_dirty;
 {
 #ifdef DEBUG_SLOW
-       account_page((HTAB *)dbp->cookie,
+       __account_page((HTAB *)dbp->cookie,
            ((BKT *)((char *)pagep - sizeof(BKT)))->pgno, -1);
 #endif
        return (memp_fput(dbp->mpf, pagep, (is_dirty ? DB_MPOOL_DIRTY : 0)));
@@ -1432,7 +1430,7 @@ __ham_get_page(dbp, addr, pagep)
        ret = memp_fget(dbp->mpf, &addr, DB_MPOOL_CREATE, pagep);
 #ifdef DEBUG_SLOW
        if (*pagep != NULL)
-               account_page((HTAB *)dbp->internal, addr, 1);
+               __account_page((HTAB *)dbp->internal, addr, 1);
 #endif
        return (ret);
 }
@@ -1523,11 +1521,11 @@ __ham_overflow_page(dbp, type, pp)
 #ifdef DEBUG
 /*
  * PUBLIC: #ifdef DEBUG
- * PUBLIC: int bucket_to_page __P((HTAB *, int));
+ * PUBLIC: int __bucket_to_page __P((HTAB *, int));
  * PUBLIC: #endif
  */
 int
-bucket_to_page(hashp, n)
+__bucket_to_page(hashp, n)
        HTAB *hashp;
        int n;
 {
@@ -1735,7 +1733,7 @@ __ham_dpair(dbp, p, pndx)
 
 #ifdef DEBUG_SLOW
 static void
-account_page(hashp, pgno, inout)
+__account_page(hashp, pgno, inout)
        HTAB *hashp;
        db_pgno_t pgno;
        int inout;
@@ -1767,7 +1765,8 @@ account_page(hashp, pgno, inout)
                last--;
        }
        for (i = 0; i < last; i++, list[i].times++)
-               if (list[i].times > 20 && !is_bitmap_pgno(hashp, list[i].pgno))
+               if (list[i].times > 20 &&
+                   !__is_bitmap_pgno(hashp, list[i].pgno))
                        (void)fprintf(stderr,
                            "Warning: pg %lu has been out for %d times\n",
                            (u_long)list[i].pgno, list[i].times);
index 81d9bb5..1b30be3 100644 (file)
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash_rec.c   10.12 (Sleepycat) 8/22/97";
+static const char sccsid[] = "@(#)hash_rec.c   10.13 (Sleepycat) 9/15/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -364,11 +364,11 @@ __ham_replace_recover(logp, dbtp, lsnp, redo, info)
        DB *mdbp, *file_dbp;
        DB_MPOOLFILE *mpf;
        DBT dbt;
-       HKEYDATA *hk;
        HTAB *hashp;
        PAGE *pagep;
        int32_t grow;
        int change, cmp_n, cmp_p, getmeta, ret;
+       u_int8_t *hk;
 
        getmeta = 0;
        hashp = NULL;                           /* XXX: shut the compiler up. */
@@ -421,11 +421,11 @@ __ham_replace_recover(logp, dbtp, lsnp, redo, info)
                __ham_onpage_replace(pagep,
                    file_dbp->pgsize, argp->ndx, argp->off, grow, &dbt);
                if (argp->makedup) {
-                       hk = GET_HKEYDATA(pagep, argp->ndx);
+                       hk = P_ENTRY(pagep, argp->ndx);
                        if (redo)
-                               hk->type = H_DUPLICATE;
+                               HPAGE_PTYPE(hk) = H_DUPLICATE;
                        else
-                               hk->type = H_KEYDATA;
+                               HPAGE_PTYPE(hk) = H_KEYDATA;
                }
        }
 
@@ -738,7 +738,7 @@ __ham_ovfl_recover(logp, dbtp, lsnp, redo, info)
        DBT *dbtp;
        DB_LSN *lsnp;
        int redo;
-        void *info;
+       void *info;
 {
        __ham_ovfl_args *argp;
        DB *mdbp, *file_dbp;
index 5cf4224..878096b 100644 (file)
@@ -43,7 +43,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     @(#)btree.h     10.16 (Sleepycat) 8/24/97
+ *     @(#)btree.h     10.17 (Sleepycat) 9/23/97
  */
 
 /* Forward structure declarations. */
@@ -181,6 +181,12 @@ struct __cursor {
 #define        C_DELETED       0x0001
 #define        C_REPLACE       0x0002
 #define        C_REPLACE_SETUP 0x0004
+
+       /*
+        * Internal cursor held for DB->get; don't hold locks unless involved
+        * in a TXN.
+        */
+#define        C_INTERNAL      0x0008
        u_int32_t        flags;
 };
 
index dab0f5b..9133c58 100644 (file)
@@ -8,6 +8,7 @@ int __bam_pgin __P((db_pgno_t, void *, DBT *));
 int __bam_pgout __P((db_pgno_t, void *, DBT *));
 int __bam_mswap __P((PAGE *));
 int __bam_cursor __P((DB *, DB_TXN *, DBC **));
+int __bam_c_iclose __P((DB *, DBC *));
 int __bam_get __P((DB *, DB_TXN *, DBT *, DBT *, int));
 int __bam_ovfl_chk __P((DB *, CURSOR *, u_int32_t, int));
 int __bam_ca_delete __P((DB *, db_pgno_t, u_int32_t, CURSOR *));
@@ -51,6 +52,7 @@ int __bam_cdel_recover
 int __ram_open __P((DB *, DBTYPE, DB_INFO *));
 int __ram_cursor __P((DB *, DB_TXN *, DBC **));
 int __ram_close __P((DB *));
+int __ram_c_iclose __P((DB *, DBC *));
 void __ram_ca __P((DB *, db_recno_t, ca_recno_arg));
 int __ram_getno __P((DB *, const DBT *, db_recno_t *, int));
 int __ram_snapshot __P((DB *));
index f9b29fa..63d9603 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *     Sleepycat Software.  All rights reserved.
  *
- *     @(#)db.h.src    10.67 (Sleepycat) 8/25/97
+ *     @(#)db.h.src    10.77 (Sleepycat) 9/24/97
  */
 
 #ifndef _DB_H_
@@ -67,8 +67,8 @@
 
 #define        DB_VERSION_MAJOR        2
 #define        DB_VERSION_MINOR        3
-#define        DB_VERSION_PATCH        4
-#define        DB_VERSION_STRING       "Sleepycat Software: DB 2.3.4: (8/20/97)"
+#define        DB_VERSION_PATCH        10
+#define        DB_VERSION_STRING       "Sleepycat Software: DB 2.3.10: (9/24/97)"
 
 typedef        u_int32_t       db_pgno_t;      /* Page number type. */
 typedef        u_int16_t       db_indx_t;      /* Page offset type. */
@@ -329,6 +329,7 @@ struct __db_info {
 #define        DB_NEEDSPLIT            ( -9)   /* Page needs to be split. */
 #define        DB_REGISTERED           (-10)   /* Entry was previously registered. */
 #define        DB_SWAPBYTES            (-11)   /* Database needs byte swapping. */
+#define DB_TXN_CKP             (-12)   /* Encountered ckp record in log. */
 
 struct __db_ilock {                    /* Internal DB access method lock. */
        db_pgno_t       pgno;           /* Page being locked. */
@@ -338,7 +339,7 @@ struct __db_ilock {                 /* Internal DB access method lock. */
 
 /* DB access method description structure. */
 struct __db {
-       void    *mutex                /* Synchronization for free threading */
+       void    *mutexp;                /* Synchronization for free threading */
        DBTYPE   type;                  /* DB access method. */
        DB_ENV  *dbenv;                 /* DB_ENV structure. */
        DB_ENV  *mp_dbenv;              /* DB_ENV for local mpool creation. */
@@ -640,11 +641,11 @@ extern "C" {
 #endif
 int    memp_close __P((DB_MPOOL *));
 int    memp_fclose __P((DB_MPOOLFILE *));
-int    memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, unsigned long, void *));
+int    memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, int, void *));
 int    memp_fopen __P((DB_MPOOL *, const char *,
            int, int, int, size_t, int, DBT *, u_int8_t *, DB_MPOOLFILE **));
-int    memp_fput __P((DB_MPOOLFILE *, void *, unsigned long));
-int    memp_fset __P((DB_MPOOLFILE *, void *, unsigned long));
+int    memp_fput __P((DB_MPOOLFILE *, void *, int));
+int    memp_fset __P((DB_MPOOLFILE *, void *, int));
 int    memp_fsync __P((DB_MPOOLFILE *));
 int    memp_open __P((const char *, int, int, DB_ENV *, DB_MPOOL **));
 int    memp_register __P((DB_MPOOL *, int,
@@ -697,7 +698,7 @@ extern "C" {
 #endif
 int      txn_abort __P((DB_TXN *));
 int      txn_begin __P((DB_TXNMGR *, DB_TXN *, DB_TXN **));
-int      txn_checkpoint __P((const DB_TXNMGR *, long, long));
+int      txn_checkpoint __P((const DB_TXNMGR *, int, int));
 int      txn_commit __P((DB_TXN *));
 int      txn_close __P((DB_TXNMGR *));
 u_int32_t txn_id __P((DB_TXN *));
index 52fb3a0..3fbca8b 100644 (file)
@@ -36,7 +36,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     @(#)db_185.h.src        8.3 (Sleepycat) 7/27/97
+ *     @(#)db_185.h.src        8.4 (Sleepycat) 9/16/97
  */
 
 #ifndef _DB_185_H_
 @u_int32_decl@
 #endif
 
+/*
+ * XXX
+ * SGI/IRIX already has a pgno_t.
+ */
+#ifdef sgi
+#define        pgno_t  db_pgno_t
+#endif
+
 #define        MAX_PAGE_NUMBER 0xffffffff      /* >= # of pages in a file */
 typedef u_int32_t      pgno_t;
 #define        MAX_PAGE_OFFSET 65535           /* >= # of bytes in a page */
index 506aed8..611d967 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 1997
  *     Sleepycat Software.  All rights reserved.
  *
- *     @(#)db_cxx.h    10.7 (Sleepycat) 8/22/97
+ *     @(#)db_cxx.h    10.8 (Sleepycat) 9/20/97
  */
 
 #ifndef _DB_CXX_H_
@@ -303,9 +303,9 @@ class _exported DbMpoolFile
 {
 public:
     int close();
-    int get(db_pgno_t *pgnoaddr, unsigned long flags, void *pagep);
-    int put(void *pgaddr, unsigned long flags);
-    int set(void *pgaddr, unsigned long flags);
+    int get(db_pgno_t *pgnoaddr, int flags, void *pagep);
+    int put(void *pgaddr, int flags);
+    int set(void *pgaddr, int flags);
     int sync();
 
     static int open(DbMpool *mp, const char *file,
@@ -391,7 +391,7 @@ class _exported DbTxnMgr
 friend DbEnv;
 public:
     int begin(DbTxn *pid, DbTxn **tid);
-    int checkpoint(long kbyte, long min) const;
+    int checkpoint(int kbyte, int min) const;
     int close();
     int stat(DB_TXN_STAT **statp, void *(*db_malloc)(size_t));
 
index 1cccb47..b18b10f 100644 (file)
@@ -57,8 +57,8 @@ int __db_noop_print
 int __db_noop_read __P((void *, __db_noop_args **));
 int __db_init_print __P((DB_ENV *));
 int __db_init_recover __P((DB_ENV *));
-int __db_pgin __P((db_pgno_t, void *));
-int __db_pgout __P((db_pgno_t, void *));
+int __db_pgin __P((db_pgno_t, size_t, void *));
+int __db_pgout __P((db_pgno_t, size_t, void *));
 int __db_dispatch __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
 int __db_add_recovery __P((DB_ENV *,
    int (*)(DB_LOG *, DBT *, DB_LSN *, int, void *), u_int32_t));
index b60e500..ebadb35 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *     Sleepycat Software.  All rights reserved.
  *
- *     @(#)db_int.h.src        10.28 (Sleepycat) 8/20/97
+ *     @(#)db_int.h.src        10.30 (Sleepycat) 9/23/97
  */
 
 #ifndef _DB_INTERNAL_H_
@@ -177,11 +177,11 @@ typedef struct _db_mutex_t {
 /* Lock/unlock a DB thread. */
 #define        DB_THREAD_LOCK(dbp)                                             \
        (F_ISSET(dbp, DB_AM_THREAD) ?                                   \
-           __db_mutex_lock((db_mutex_t *)(dbp)->mutex,  -1,            \
+           __db_mutex_lock((db_mutex_t *)(dbp)->mutexp,  -1,           \
                (dbp)->dbenv == NULL ? NULL : (dbp)->dbenv->db_yield) : 0)
 #define        DB_THREAD_UNLOCK(dbp)                                           \
        (F_ISSET(dbp, DB_AM_THREAD) ?                                   \
-           __db_mutex_unlock((db_mutex_t *)(dbp)->mutex,  -1) : 0)
+           __db_mutex_unlock((db_mutex_t *)(dbp)->mutexp,  -1) : 0)
 
 /* Btree/recno local statistics structure. */
 struct __db_bt_lstat;  typedef struct __db_bt_lstat DB_BTREE_LSTAT;
@@ -306,14 +306,6 @@ typedef struct __dbpginfo {
  * Transactions and recovery.
  *******************************************************/
 /*
- * The locker id space is divided between the transaction manager and the lock
- * manager.  Lockid's start at 0 and go to MAX_LOCKER_ID.  Txn Id's start at
- * MAX_LOCKER_ID + 1 and go up to MAX_TXNID.
- */
-#define        MAX_LOCKER_ID   0x0fffffff
-#define        MAX_TXNID       0xffffffff
-
-/*
  * Out of band value for a lock.  The locks are returned to callers as offsets
  * into the lock regions.  Since the RLAYOUT structure begins all regions, an
  * offset of 0 is guaranteed not to be a valid lock.
index cde7ff9..30f6072 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *     Sleepycat Software.  All rights reserved.
  *
- *     @(#)db_page.h   10.11 (Sleepycat) 9/3/97
+ *     @(#)db_page.h   10.13 (Sleepycat) 9/24/97
  */
 
 #ifndef _DB_PAGE_H_
@@ -273,6 +273,17 @@ typedef struct _db_page {
 #define        H_OFFDUP        4       /* Overflow page of duplicates. */
 
 /*
+ * !!!
+ * Items on hash pages are (potentially) unaligned, so we can never cast the
+ * (page + offset) pointer to an HKEYDATA, HOFFPAGE or HOFFDUP structure, as
+ * we do with B+tree on-page structures.  Because we frequently want the type
+ * field, it requires no alignment, and it's in the same location in all three
+ * structures, there's a pair of macros.
+ */
+#define        HPAGE_PTYPE(p)          (*(u_int8_t *)p)
+#define        HPAGE_TYPE(pg, indx)    (*P_ENTRY(pg, indx))
+
+/*
  * The first and second types are H_KEYDATA and H_DUPLICATE, represented
  * by the HKEYDATA structure:
  *
@@ -294,10 +305,7 @@ typedef struct _hkeydata {
        u_int8_t  type;         /*    00: Page type. */
        u_int8_t  data[1];      /* Variable length key/data item. */
 } HKEYDATA;
-
-/* Get a HKEYDATA item for a specific index. */
-#define        GET_HKEYDATA(pg, indx)                                          \
-       ((HKEYDATA *)P_ENTRY(pg, indx))
+#define        HKEYDATA_DATA(p)        (((u_int8_t *)p) + SSZA(HKEYDATA, data))
 
 /*
  * The length of any HKEYDATA item. Note that indx is an element index,
@@ -333,8 +341,8 @@ typedef struct _hkeydata {
 #define H_NUMPAIRS(pg)                 (NUM_ENT(pg) / 2)
 #define        H_KEYINDEX(pindx)               (2 * (pindx))
 #define        H_DATAINDEX(pindx)              ((2 * (pindx)) + 1)
-#define        H_PAIRKEY(pg, pindx)            GET_HKEYDATA(pg, H_KEYINDEX(pindx))
-#define        H_PAIRDATA(pg, pindx)           GET_HKEYDATA(pg, H_DATAINDEX(pindx))
+#define        H_PAIRKEY(pg, pindx)            P_ENTRY(pg, H_KEYINDEX(pindx))
+#define        H_PAIRDATA(pg, pindx)           P_ENTRY(pg, H_DATAINDEX(pindx))
 #define H_PAIRSIZE(pg, psize, pindx)                                   \
        (LEN_HITEM(pg, psize, H_KEYINDEX(pindx)) +                      \
        LEN_HITEM(pg, psize, H_DATAINDEX(pindx)))
@@ -355,9 +363,8 @@ typedef struct _hoffpage {
        u_int32_t tlen;         /* 08-11: Total length of item. */
 } HOFFPAGE;
 
-/* Get a HOFFPAGE item for a specific index. */
-#define        GET_HOFFPAGE(pg, indx)                                          \
-       ((HOFFPAGE *)P_ENTRY(pg, indx))
+#define        HOFFPAGE_PGNO(p)        (((u_int8_t *)p) + SSZ(HOFFPAGE, pgno))
+#define        HOFFPAGE_TLEN(p)        (((u_int8_t *)p) + SSZ(HOFFPAGE, tlen))
 
 /*
  * Page space required to add a new HOFFPAGE item to the page, with and
@@ -378,10 +385,7 @@ typedef struct _hoffdup {
        u_int8_t  unused[3];    /* 01-03: Padding, unused. */
        db_pgno_t pgno;         /* 04-07: Offpage page number. */
 } HOFFDUP;
-
-/* Get a HOFFDUP item for a specific index. */
-#define        GET_HOFFDUP(pg, indx)                                           \
-       ((HOFFDUP *)P_ENTRY(pg, indx))
+#define        HOFFDUP_PGNO(p)         (((u_int8_t *)p) + SSZ(HOFFDUP, pgno))
 
 /*
  * Page space required to add a new HOFFDUP item to the page, with and
index f695a2b..b94e0f1 100644 (file)
@@ -4,14 +4,14 @@
  * Copyright (c) 1996, 1997
  *     Sleepycat Software.  All rights reserved.
  *
- *     @(#)db_shash.h  10.1 (Sleepycat) 4/12/97
+ *     @(#)db_shash.h  10.2 (Sleepycat) 9/16/97
  */
 
 /* Hash Headers */
 typedef        SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
 
 /*
- * __db_hashlookup --
+ * HASHLOOKUP --
  *
  * Look up something in a shared memory hash table.  The "elt" argument
  * should be a key, and cmp_func must know how to compare a key to whatever
@@ -30,7 +30,7 @@ typedef       SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
  * If the element is not in the hash table, this macro exits with result
  * set to NULL.
  */
-#define        __db_hashlookup(begin, type, field, elt, r, n, hash, cmp) do {  \
+#define        HASHLOOKUP(begin, type, field, elt, r, n, hash, cmp) do {       \
        DB_HASHTAB *__bucket;                                           \
        u_int32_t __ndx;                                                \
                                                                        \
@@ -43,10 +43,10 @@ typedef     SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
 } while(0)
 
 /*
- * __db_hashinsert --
+ * HASHINSERT --
  *
  * Insert a new entry into the hash table.  This assumes that lookup has
- * failed; don't call it if you haven't already called __db_hashlookup.
+ * failed; don't call it if you haven't already called HASHLOOKUP.
  * begin: the beginning address of the hash table.
  * type: the structure type of the elements that are linked in each bucket.
  * field: the name of the field by which the "type" structures are linked.
@@ -54,7 +54,7 @@ typedef       SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
  * nelems: the number of buckets in the hash table.
  * hash_func: the hash function that operates on elements of the type of elt
  */
-#define        __db_hashinsert(begin, type, field, elt, n, hash) do {          \
+#define        HASHINSERT(begin, type, field, elt, n, hash) do {               \
        u_int32_t __ndx;                                                \
        DB_HASHTAB *__bucket;                                           \
                                                                        \
@@ -64,7 +64,7 @@ typedef       SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
 } while(0)
 
 /*
- * __db_hashremove --
+ * HASHREMOVE --
  *     Remove the entry with a key == elt.
  * begin: address of the beginning of the hash table.
  * type: the structure type of the elements that are linked in each bucket.
@@ -75,19 +75,19 @@ typedef     SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
  * cmp_func: compare elements of the type of elt with those in the table (of
  *     type "type").
  */
-#define        __db_hashremove(begin, type, field, elt, n, hash, cmp) {        \
+#define        HASHREMOVE(begin, type, field, elt, n, hash, cmp) {             \
        u_int32_t __ndx;                                                \
        DB_HASHTAB *__bucket;                                           \
        SH_TAILQ_ENTRY *__entp;                                         \
                                                                        \
        __ndx = hash(elt) % (n);                                        \
        __bucket = &begin[__ndx];                                       \
-       __db_hashlookup(begin, type, field, elt, __entp, n, hash, cmp); \
+       HASHLOOKUP(begin, type, field, elt, __entp, n, hash, cmp);      \
        SH_TAILQ_REMOVE(__bucket, __entp, field, type);                 \
 }
 
 /*
- * __db_hashremove_el --
+ * HASHREMOVE_EL --
  *     Given the object "obj" in the table, remove it.
  * begin: address of the beginning of the hash table.
  * type: the structure type of the elements that are linked in each bucket.
@@ -96,7 +96,7 @@ typedef       SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
  * nelems: the number of buckets in the hash table.
  * hash_func: the hash function that operates on elements of the type of elt
  */
-#define        __db_hashremove_el(begin, type, field, obj, n, hash) {          \
+#define        HASHREMOVE_EL(begin, type, field, obj, n, hash) {               \
        u_int32_t __ndx;                                                \
        DB_HASHTAB *__bucket;                                           \
                                                                        \
index 5ae63dc..32788c7 100644 (file)
@@ -1,6 +1,7 @@
 /* Do not edit: automatically built by dist/distrib. */
 int __ham_open __P((DB *, DB_INFO *));
 int  __ham_close __P((DB *));
+int __ham_c_iclose __P((DB *, DBC *));
 int __ham_expand_table __P((HTAB *));
 u_int32_t __ham_call_hash __P((HTAB *, u_int8_t *, int32_t));
 int __ham_init_dbt __P((DBT *, u_int32_t, void **, u_int32_t *));
@@ -96,7 +97,7 @@ int __ham_dirty_page __P((HTAB *, PAGE *));
 int __ham_get_page __P((DB *, db_pgno_t, PAGE **));
 int __ham_overflow_page __P((DB *, u_int32_t, PAGE **));
 #ifdef DEBUG
-int bucket_to_page __P((HTAB *, int));
+int __bucket_to_page __P((HTAB *, int));
 #endif
 void __ham_init_ovflpages __P((HTAB *));
 int __ham_get_cpage __P((HTAB *, HASH_CURSOR *, db_lockmode_t));
index 18d29e8..8f9e81c 100644 (file)
@@ -4,13 +4,19 @@
  * Copyright (c) 1996, 1997
  *     Sleepycat Software.  All rights reserved.
  *
- *     @(#)lock.h      10.7 (Sleepycat) 7/29/97
+ *     @(#)lock.h      10.8 (Sleepycat) 9/23/97
  */
 
 typedef struct __db_lockobj    DB_LOCKOBJ;
 
 #define DB_DEFAULT_LOCK_FILE   "__db_lock.share"
 #define DB_LOCK_DEFAULT_N      5000
+
+/*
+ * The locker id space is divided between the transaction manager and the lock
+ * manager.  Lockid's start at 0 and go to DB_LOCK_MAXID.  Txn Id's start at
+ * DB_LOCK_MAXID + 1 and go up to TXN_INVALID.
+ */
 #define DB_LOCK_MAXID          0x7fffffff
 
 /*
index 970dfd1..a9c82fa 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *     Sleepycat Software.  All rights reserved.
  *
- *     @(#)log.h       10.8 (Sleepycat) 8/18/97
+ *     @(#)log.h       10.9 (Sleepycat) 9/23/97
  */
 
 #ifndef _LOG_H_
@@ -30,11 +30,11 @@ struct __log_persist;       typedef struct __log_persist LOGP;
 /* Macros to lock/unlock the region and threads. */
 #define        LOCK_LOGTHREAD(dblp)                                            \
        if (F_ISSET(dblp, DB_AM_THREAD))                                \
-               (void)__db_mutex_lock(&(dblp)->mutex, -1,               \
+               (void)__db_mutex_lock((dblp)->mutexp, -1,               \
                    (dblp)->dbenv == NULL ? NULL : (dblp)->dbenv->db_yield)
 #define        UNLOCK_LOGTHREAD(dblp)                                          \
        if (F_ISSET(dblp, DB_AM_THREAD))                                \
-               (void)__db_mutex_unlock(&(dblp)->mutex, -1);
+               (void)__db_mutex_unlock((dblp)->mutexp, -1);
 #define        LOCK_LOGREGION(dblp)                                            \
        (void)__db_mutex_lock(&((RLAYOUT *)(dblp)->lp)->lock,           \
            (dblp)->fd, (dblp)->dbenv == NULL ? NULL : (dblp)->dbenv->db_yield)
@@ -56,7 +56,7 @@ typedef       struct __db_entry {
  */
 struct __db_log {
 /* These fields need to be protected for multi-threaded support. */
-       db_mutex_t      mutex;          /* Mutex for thread protection. */
+       db_mutex_t      *mutexp;        /* Mutex for thread protection. */
 
        DB_ENTRY *dbentry;              /* Recovery file-id mapping. */
 #define        DB_GROW_SIZE    64
@@ -86,6 +86,8 @@ struct __db_log {
        void     *addr;                 /* Address of shalloc() region. */
        int       fd;                   /* Region file descriptor. */
 
+       char     *dir;                  /* Directory argument. */
+
        u_int32_t flags;                /* Support the DB_AM_XXX flags. */
 };
 
index d5c9dd6..bc63d9d 100644 (file)
@@ -1,6 +1,6 @@
 /* Do not edit: automatically built by dist/distrib. */
-int __log_find __P((DB_ENV *, LOG *, int *));
-int __log_valid __P((DB_ENV *, LOG *, int));
+int __log_find __P((DB_LOG *, int *));
+int __log_valid __P((DB_LOG *, LOG *, int));
 int __log_register_log
     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
     DBT *, DBT *, u_int32_t, DBTYPE));
@@ -18,7 +18,7 @@ int __log_init_recover __P((DB_ENV *));
 int __log_findckp __P((DB_LOG *, DB_LSN *));
 int __log_get __P((DB_LOG *, DB_LSN *, DBT *, int, int));
 int __log_put __P((DB_LOG *, DB_LSN *, const DBT *, int));
-int __log_name __P((DB_ENV *, int, char **));
+int __log_name __P((DB_LOG *, int, char **));
 int __log_register_recover
     __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
 int __log_unregister_recover
index 1fe0c75..3b71774 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *     Sleepycat Software.  All rights reserved.
  *
- *     @(#)mp.h        10.15 (Sleepycat) 8/29/97
+ *     @(#)mp.h        10.16 (Sleepycat) 9/23/97
  */
 
 struct __bh;           typedef struct __bh BH;
@@ -99,7 +99,7 @@ struct __mpoolfile;   typedef struct __mpoolfile MPOOLFILE;
  */
 struct __db_mpool {
 /* These fields need to be protected for multi-threaded support. */
-       db_mutex_t      mutex;          /* Structure lock. */
+       db_mutex_t      *mutexp;        /* Structure lock. */
 
                                        /* List of pgin/pgout routines. */
        LIST_HEAD(__db_mpregh, __db_mpreg) dbregq;
@@ -145,7 +145,7 @@ struct __db_mpreg {
  */
 struct __db_mpoolfile {
 /* These fields need to be protected for multi-threaded support. */
-       db_mutex_t      mutex;          /* Structure lock. */
+       db_mutex_t      *mutexp;        /* Structure lock. */
 
        int        fd;                  /* Underlying file descriptor. */
 
index c3e2f4a..c596d33 100644 (file)
@@ -1,38 +1,11 @@
-/*
- * Copyright (c) 1991, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
+/*-
+ * See the file LICENSE for redistribution information.
  *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * Copyright (c) 1996, 1997
+ *     Sleepycat Software.  All rights reserved.
  *
- *     @(#)shqueue.h   8.11 (Sleepycat) 7/27/97
+ *     @(#)shqueue.h   8.12 (Sleepycat) 9/10/97
  */
-
 #ifndef        _SYS_SHQUEUE_H_
 #define        _SYS_SHQUEUE_H_
 
index f4e0999..8bb3976 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *     Sleepycat Software.  All rights reserved.
  *
- *     @(#)txn.h       10.6 (Sleepycat) 7/29/97
+ *     @(#)txn.h       10.10 (Sleepycat) 9/23/97
  */
 #ifndef        _TXN_H_
 #define        _TXN_H_
@@ -14,8 +14,9 @@
  * the region is always created group RW of the group owning the directory.
  */
 #define        DEFAULT_TXN_FILE        "__db_txn.share"
+/* TXN_MINIMUM = (DB_LOCK_MAXID + 1) but this makes compilers complain. */
+#define TXN_MINIMUM            0x80000000
 #define        TXN_INVALID             0xffffffff /* Maximum number of txn ids. */
-#define TXN_MINIMUM            0x80000000 /* First transaction id */
 
 /*
  * Transaction type declarations.
@@ -36,6 +37,7 @@ typedef struct __txn_detail {
 #define        TXN_ABORTED     2
 #define        TXN_PREPARED    3
        u_int32_t status;               /* status of the transaction */
+       SH_TAILQ_ENTRY  links;          /* free/active list */
 } TXN_DETAIL;
 
 /*
@@ -45,7 +47,7 @@ typedef struct __txn_detail {
  */
 struct __db_txnmgr {
 /* These fields need to be protected for multi-threaded support. */
-       db_mutex_t      mutex;          /* Synchronization. */
+       db_mutex_t      *mutexp;        /* Synchronization. */
                                        /* list of active transactions */
        TAILQ_HEAD(_chain, __db_txn)    txn_chain;
 
@@ -57,11 +59,14 @@ struct __db_txnmgr {
        u_int            flags;         /* DB_TXN_NOSYNC, DB_THREAD */
        size_t           reg_size;      /* how large we think the region is */
        DB_TXNREGION    *region;        /* address of shared memory region */
+       void            *mem;           /* address of the shalloc space */
 };
 
 /*
  * Layout of the shared memory region.
- *
+ * The region consists of a DB_TXNREGION structure followed by a large
+ * pool of shalloc'd memory which is used to hold TXN_DETAIL structures
+ * and thread mutexes (which are dynamically allocated).
  */
 struct __db_txnregion {
        RLAYOUT         hdr;            /* Shared memory region header. */
@@ -69,7 +74,6 @@ struct __db_txnregion {
        u_int32_t       version;        /* version number */
        u_int32_t       maxtxns;        /* maximum number of active txns */
        u_int32_t       last_txnid;     /* last transaction id given out */
-       u_int32_t       free_txn;       /* head of transaction free list */
        DB_LSN          pending_ckp;    /* last checkpoint did not finish */
        DB_LSN          last_ckp;       /* lsn of the last checkpoint */
        time_t          time_ckp;       /* time of last checkpoint */
@@ -78,20 +82,25 @@ struct __db_txnregion {
        u_int32_t       naborts;        /* number of aborted transactions */
        u_int32_t       ncommits;       /* number of committed transactions */
        u_int32_t       nbegins;        /* number of begun transactions */
-       TXN_DETAIL      table[1];       /* array of TXN structures */
+       SH_TAILQ_HEAD(_active) active_txn;      /* active transaction list */
 };
 
+/*
+ * Make the region large enough to hold N  transaction detail structures
+ * plus some space to hold thread handles and the beginning of the shalloc
+ * region.
+ */
 #define        TXN_REGION_SIZE(N)                                              \
-                       (sizeof(DB_TXNREGION) + N * sizeof(DB_TXN))
+       (sizeof(DB_TXNREGION) + N * sizeof(TXN_DETAIL) + 1000)
 
 /* Macros to lock/unlock the region and threads. */
 #define        LOCK_TXNTHREAD(tmgrp)                                           \
        if (F_ISSET(tmgrp, DB_THREAD))                                  \
-               (void)__db_mutex_lock(&(tmgrp)->mutex, -1,              \
+               (void)__db_mutex_lock((tmgrp)->mutexp, -1,              \
                    (tmgrp)->dbenv == NULL ? NULL : (tmgrp)->dbenv->db_yield)
 #define        UNLOCK_TXNTHREAD(tmgrp)                                         \
        if (F_ISSET(tmgrp, DB_THREAD))                                  \
-               (void)__db_mutex_unlock(&(tmgrp)->mutex, -1)
+               (void)__db_mutex_unlock((tmgrp)->mutexp, -1)
 
 #define        LOCK_TXNREGION(tmgrp)                                           \
        (void)__db_mutex_lock(&(tmgrp)->region->hdr.lock,(tmgrp)->fd,   \
index 8fc9133..a2a3b20 100644 (file)
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)lock.c       10.31 (Sleepycat) 8/17/97";
+static const char sccsid[] = "@(#)lock.c       10.36 (Sleepycat) 9/24/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -201,7 +201,7 @@ lock_open(path, flags, mode, dbenv, ltp)
         * Create the lock table structure.
         */
        if ((lt = (DB_LOCKTAB *)calloc(1, sizeof(DB_LOCKTAB))) == NULL) {
-               __db_err(dbenv, "%s", strerror(errno));
+               __db_err(dbenv, "%s", strerror(ENOMEM));
                return (ENOMEM);
        }
        lt->dbenv = dbenv;
@@ -319,8 +319,10 @@ lock_vec(lt, locker, flags, list, nlist, elistp)
                case DB_LOCK_GET:
                        ret = __lock_get_internal(lt, locker, flags,
                            list[i].obj, list[i].mode, &lp);
-                       if (ret == 0)
+                       if (ret == 0) {
                                list[i].lock = LOCK_TO_OFFSET(lt, lp);
+                               lt->region->nrequests++;
+                       }
                        break;
                case DB_LOCK_PUT:
                        lp = OFFSET_TO_LOCK(lt, list[i].lock);
@@ -351,7 +353,7 @@ lock_vec(lt, locker, flags, list, nlist, elistp)
                case DB_LOCK_PUT_OBJ:
 
                        /* Look up the object in the hash table. */
-                       __db_hashlookup(lt->hashtab, __db_lockobj, links,
+                       HASHLOOKUP(lt->hashtab, __db_lockobj, links,
                            list[i].obj, sh_obj, lt->region->table_size,
                            __lock_ohash, __lock_cmp);
                        if (sh_obj == NULL) {
@@ -596,8 +598,8 @@ __lock_put_internal(lt, lockp, do_all)
 
        /* Check if object should be reclaimed. */
        if (SH_TAILQ_FIRST(&sh_obj->holders, __db_lock) == NULL) {
-               __db_hashremove_el(lt->hashtab, __db_lockobj, links, sh_obj,
-                   lt->region->table_size, __lock_lhash);
+               HASHREMOVE_EL(lt->hashtab, __db_lockobj,
+                   links, sh_obj, lt->region->table_size, __lock_lhash);
                __db_shalloc_free(lt->mem, SH_DBT_PTR(&sh_obj->lockobj));
                SH_TAILQ_INSERT_HEAD(&lt->region->free_objs, sh_obj, links,
                    __db_lockobj);
@@ -676,8 +678,12 @@ __lock_get_internal(lt, locker, flags, obj, lock_mode, lockp)
         * Now we have a lock and an object and we need to see if we should
         * grant the lock.  We use a FIFO ordering so we can only grant a
         * new lock if it does not conflict with anyone on the holders list
-        * OR anyone on the waiters list.  In case of conflict, we put the
-        * new lock on the end of the waiters list.
+        * OR anyone on the waiters list.  The reason that we don't grant if
+        * there's a conflict is that this can lead to starvation (a writer
+        * waiting on a popularly read item will never ben granted).  The
+        * downside of this is that a waiting reader can prevent an upgrade
+        * from reader to writer, which is not uncommon.  In case of conflict,
+        * we put the new lock on the end of the waiters list.
         */
        for (lp = SH_TAILQ_FIRST(&sh_obj->holders, __db_lock);
            lp != NULL;
@@ -1042,7 +1048,7 @@ __lock_dump_locker(lt, op)
 
        ptr = SH_DBT_PTR(&op->lockobj);
        memcpy(&locker, ptr, sizeof(u_int32_t));
-       printf("L %lu", (u_long)locker);
+       printf("L %lx", (u_long)locker);
 
        lp = SH_LIST_FIRST(&op->heldby, __db_lock);
        if (lp == NULL) {
@@ -1095,7 +1101,7 @@ __lock_is_locked(lt, locker, dbt, mode)
        lrp = lt->region;
 
        /* Look up the object in the hash table. */
-       __db_hashlookup(lt->hashtab, __db_lockobj, links,
+       HASHLOOKUP(lt->hashtab, __db_lockobj, links,
            dbt, sh_obj, lrp->table_size, __lock_ohash, __lock_cmp);
        if (sh_obj == NULL)
                return (0);
@@ -1171,7 +1177,7 @@ __lock_printlock(lt, lp, ispgno)
                stat = "UNKNOWN";
                break;
        }
-       printf("\t%lu\t%s\t%lu\t%s\t",
+       printf("\t%lx\t%s\t%lu\t%s\t",
            (u_long)lp->holder, mode, (u_long)lp->refcount, stat);
 
        lockobj = (DB_LOCKOBJ *)((u_int8_t *)lp + lp->obj);
@@ -1243,11 +1249,11 @@ __lock_getobj(lt, locker, dbt, type, objp)
 
        /* Look up the object in the hash table. */
        if (type == DB_LOCK_OBJTYPE) {
-               __db_hashlookup(lt->hashtab, __db_lockobj, links, dbt, sh_obj,
+               HASHLOOKUP(lt->hashtab, __db_lockobj, links, dbt, sh_obj,
                    lrp->table_size, __lock_ohash, __lock_cmp);
                obj_size = dbt->size;
        } else {
-               __db_hashlookup(lt->hashtab, __db_lockobj, links, locker,
+               HASHLOOKUP(lt->hashtab, __db_lockobj, links, locker,
                    sh_obj, lrp->table_size, __lock_locker_hash,
                    __lock_locker_cmp);
                obj_size = sizeof(locker);
@@ -1288,8 +1294,8 @@ __lock_getobj(lt, locker, dbt, type, objp)
                sh_obj->lockobj.size = obj_size;
                sh_obj->lockobj.off = SH_PTR_TO_OFF(&sh_obj->lockobj, p);
 
-               __db_hashinsert(lt->hashtab, __db_lockobj, links, sh_obj,
-                   lrp->table_size, __lock_lhash);
+               HASHINSERT(lt->hashtab,
+                   __db_lockobj, links, sh_obj, lrp->table_size, __lock_lhash);
 
                if (type == DB_LOCK_LOCKER)
                        lrp->nlockers++;
@@ -1325,8 +1331,8 @@ __lock_freeobj(lt, obj)
        DB_LOCKTAB *lt;
        DB_LOCKOBJ *obj;
 {
-       __db_hashremove_el(lt->hashtab, __db_lockobj, links,
-           obj, lt->region->table_size, __lock_lhash);
+       HASHREMOVE_EL(lt->hashtab,
+           __db_lockobj, links, obj, lt->region->table_size, __lock_lhash);
        __db_shalloc_free(lt->mem, SH_DBT_PTR(&obj->lockobj));
        SH_TAILQ_INSERT_HEAD(&lt->region->free_objs, obj, links, __db_lockobj);
 }
index f753958..f947f90 100644 (file)
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
        Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)lock_deadlock.c      10.20 (Sleepycat) 8/21/97";
+static const char sccsid[] = "@(#)lock_deadlock.c      10.21 (Sleepycat) 9/6/97";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -300,8 +300,8 @@ retry:      count = lt->region->nlockers;
                        for (lp = SH_TAILQ_FIRST(&op->holders, __db_lock);
                            lp != NULL;
                            lp = SH_TAILQ_NEXT(lp, links, __db_lock)) {
-                               if ((__set_errno(__lock_getobj(lt, lp->holder,
-                                   NULL, DB_LOCK_LOCKER, &lockerp))) != 0) {
+                               if (__lock_getobj(lt, lp->holder,
+                                   NULL, DB_LOCK_LOCKER, &lockerp) != 0) {
                                        __db_err(dbenv,
                                            "warning unable to find object");
                                        continue;
@@ -472,8 +472,7 @@ __dd_debug(dbenv, idmap, bitmap, nlockers)
         * Alloc space to print 10 bytes per item waited on.
         */
        if ((msgbuf = (char *)malloc((nlockers + 1) * 10 + 64)) == NULL) {
-               __set_errno(ENOMEM);
-               __db_err(dbenv, "%s", strerror(errno));
+               __db_err(dbenv, "%s", strerror(ENOMEM));
                return;
        }
 
index d3e5183..893c1ee 100644 (file)
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)log.c        10.25 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)log.c        10.27 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -29,7 +29,7 @@ static const char sccsid[] = "@(#)log.c       10.25 (Sleepycat) 8/27/97";
 #include "txn_auto.h"
 #include "common_ext.h"
 
-static int __log_recover __P((DB_ENV *, DB_LOG *));
+static int __log_recover __P((DB_LOG *));
 
 /*
  * log_open --
@@ -70,14 +70,15 @@ log_open(path, flags, mode, dbenv, lpp)
        if ((dblp = (DB_LOG *)calloc(1, sizeof(DB_LOG))) == NULL)
                return (ENOMEM);
 
+       if (path != NULL && (dblp->dir = strdup(path)) == NULL) {
+               free(dblp);
+               return (ENOMEM);
+       }
+
        dblp->dbenv = dbenv;
        dblp->lfd = -1;
        ZERO_LSN(dblp->c_lsn);
        dblp->c_fd = -1;
-       if (LF_ISSET(DB_THREAD)) {
-               F_SET(dblp, DB_AM_THREAD);
-               (void)__db_mutex_init(&dblp->mutex, -1);
-       }
 
        /*
         * The log region isn't fixed size because we store the registered
@@ -114,7 +115,7 @@ retry:      if (LF_ISSET(DB_CREATE)) {
 
                        newregion = 1;
                } else if (ret != EEXIST)
-                       return (ret);
+                       goto err;
        }
 
        /* If we didn't or couldn't create the region, try and join it. */
@@ -129,7 +130,7 @@ retry:      if (LF_ISSET(DB_CREATE)) {
                        (void)__db_sleep(1, 0);
                        goto retry;
                }
-               return (ret);
+               goto err;
        }
 
        /* Set up the common information. */
@@ -137,19 +138,49 @@ retry:    if (LF_ISSET(DB_CREATE)) {
        dblp->addr = (u_int8_t *)dblp->maddr + sizeof(LOG);
        dblp->fd = fd;
 
+       /* Initialize thread information. */
+       if (LF_ISSET(DB_THREAD)) {
+               F_SET(dblp, DB_AM_THREAD);
+
+               if (!newregion)
+                       LOCK_LOGREGION(dblp);
+               if ((ret = __db_shalloc(dblp->addr,
+                   sizeof(db_mutex_t), MUTEX_ALIGNMENT, &dblp->mutexp)) == 0)
+                       (void)__db_mutex_init(dblp->mutexp, -1);
+               if (!newregion)
+                       UNLOCK_LOGREGION(dblp);
+               if (ret != 0) {
+                       (void)log_close(dblp);
+                       if (newregion)
+                               (void)log_unlink(path, 1, dbenv);
+                       return (ret);
+               }
+       }
+
        /*
         * If doing recovery, try and recover any previous log files
         * before releasing the lock.
         */
        if (newregion) {
-               if ((ret = __log_recover(dbenv, dblp)) != 0) {
-                       log_unlink(path, 1, dbenv);
+               ret = __log_recover(dblp);
+               UNLOCK_LOGREGION(dblp);
+
+               if (ret != 0) {
+                       (void)log_close(dblp);
+                       (void)log_unlink(path, 1, dbenv);
                        return (ret);
                }
-               UNLOCK_LOGREGION(dblp);
        }
        *lpp = dblp;
        return (0);
+
+err:   /*
+        * We never get here with an allocated thread-mutex, so we do
+        * not have to worry about freeing it.
+        */
+       FREE(dblp, sizeof(DB_LOG));
+       return (ret);
+
 }
 
 /*
@@ -157,8 +188,7 @@ retry:      if (LF_ISSET(DB_CREATE)) {
  *     Recover a log.
  */
 static int
-__log_recover(dbenv, dblp)
-       DB_ENV *dbenv;
+__log_recover(dblp)
        DB_LOG *dblp;
 {
        DBT dbt;
@@ -173,14 +203,14 @@ __log_recover(dbenv, dblp)
         * Find a log file.  If none exist, we simply return, leaving
         * everything initialized to a new log.
         */
-       if ((ret = __log_find(dbenv, lp, &cnt)) != 0)
+       if ((ret = __log_find(dblp, &cnt)) != 0)
                return (ret);
        if (cnt == 0)
                return (0);
 
        /* We have a log file name, find the last one. */
        while (cnt < MAXLFNAME)
-               if (__log_valid(dbenv, lp, ++cnt) != 0) {
+               if (__log_valid(dblp, lp, ++cnt) != 0) {
                        --cnt;
                        break;
                }
@@ -263,7 +293,7 @@ __log_recover(dbenv, dblp)
                lp->c_lsn.offset = 0;
        }
 
-       __db_err(dbenv,
+       __db_err(dblp->dbenv,
            "Recovering the log: last valid LSN: file: %lu offset %lu",
            (u_long)lp->lsn.file, (u_long)lp->lsn.offset);
 
@@ -277,12 +307,11 @@ __log_recover(dbenv, dblp)
  * __log_find --
  *     Try to find a log file.
  *
- * PUBLIC: int __log_find __P((DB_ENV *, LOG *, int *));
+ * PUBLIC: int __log_find __P((DB_LOG *, int *));
  */
 int
-__log_find(dbenv, lp, valp)
-       DB_ENV *dbenv;
-       LOG *lp;
+__log_find(dblp, valp)
+       DB_LOG *dblp;
        int *valp;
 {
        int cnt, fcnt, logval, ret;
@@ -290,7 +319,7 @@ __log_find(dbenv, lp, valp)
        char **names, *p, *q;
 
        /* Find the directory name. */
-       if ((ret = __log_name(dbenv, 1, &p)) != 0)
+       if ((ret = __log_name(dblp, 1, &p)) != 0)
                return (ret);
        if ((q = __db_rpath(p)) == NULL)
                dir = PATH_DOT;
@@ -300,7 +329,7 @@ __log_find(dbenv, lp, valp)
        }
 
        /* Get the list of file names. */
-       ret = __db_dir(dbenv, dir, &names, &fcnt);
+       ret = __db_dir(dblp->dbenv, dir, &names, &fcnt);
        FREES(p);
        if (ret != 0)
                return (ret);
@@ -314,14 +343,14 @@ __log_find(dbenv, lp, valp)
                if (strncmp(names[cnt], "log.", sizeof("log.") - 1) == 0) {
                        logval = atoi(names[cnt] + 4);
                        if (logval != 0 &&
-                           __log_valid(dbenv, lp, logval) == 0) {
+                           __log_valid(dblp, dblp->lp, logval) == 0) {
                                *valp = logval;
                                break;
                        }
                }
 
        /* Discard the list. */
-       __db_dirf(dbenv, names, fcnt);
+       __db_dirf(dblp->dbenv, names, fcnt);
 
        return (ret);
 }
@@ -330,11 +359,11 @@ __log_find(dbenv, lp, valp)
  * log_valid --
  *     Validate a log file.
  *
- * PUBLIC: int __log_valid __P((DB_ENV *, LOG *, int));
+ * PUBLIC: int __log_valid __P((DB_LOG *, LOG *, int));
  */
 int
-__log_valid(dbenv, lp, cnt)
-       DB_ENV *dbenv;
+__log_valid(dblp, lp, cnt)
+       DB_LOG *dblp;
        LOG *lp;
        int cnt;
 {
@@ -343,7 +372,7 @@ __log_valid(dbenv, lp, cnt)
        int fd, ret;
        char *p;
 
-       if ((ret = __log_name(dbenv, cnt, &p)) != 0)
+       if ((ret = __log_name(dblp, cnt, &p)) != 0)
                return (ret);
 
        fd = -1;
@@ -357,7 +386,7 @@ __log_valid(dbenv, lp, cnt)
                        ret = EIO;
                if (fd != -1) {
                        (void)__db_close(fd);
-                       __db_err(dbenv,
+                       __db_err(dblp->dbenv,
                            "Ignoring log file: %s: %s", p, strerror(ret));
                }
                goto err;
@@ -365,14 +394,14 @@ __log_valid(dbenv, lp, cnt)
        (void)__db_close(fd);
 
        if (persist.magic != DB_LOGMAGIC) {
-               __db_err(dbenv,
+               __db_err(dblp->dbenv,
                    "Ignoring log file: %s: magic number %lx, not %lx",
                    p, (u_long)persist.magic, (u_long)DB_LOGMAGIC);
                ret = EINVAL;
                goto err;
        }
        if (persist.version < DB_LOGOLDVER || persist.version > DB_LOGVERSION) {
-               __db_err(dbenv,
+               __db_err(dblp->dbenv,
                    "Ignoring log file: %s: unsupported log version %lu",
                    p, (u_long)persist.version);
                ret = EINVAL;
@@ -401,6 +430,13 @@ log_close(dblp)
 
        ret = 0;
 
+       /* Discard the per-thread pointer. */
+       if (dblp->mutexp != NULL) {
+               LOCK_LOGREGION(dblp);
+               __db_shalloc_free(dblp->addr, dblp->mutexp);
+               UNLOCK_LOGREGION(dblp);
+       }
+
        /* Close the region. */
        if ((t_ret =
            __db_rclose(dblp->dbenv, dblp->fd, dblp->maddr)) != 0 && ret == 0)
@@ -414,10 +450,12 @@ log_close(dblp)
        if (dblp->c_fd != -1 &&
            (t_ret = __db_close(dblp->c_fd)) != 0 && ret == 0)
                ret = t_ret;
-
-       /* Free the structure. */
        if (dblp->dbentry != NULL)
                FREE(dblp->dbentry, (dblp->dbentry_cnt * sizeof(DB_ENTRY)));
+       if (dblp->dir != NULL)
+               FREES(dblp->dir);
+
+       /* Free the structure. */
        FREE(dblp, sizeof(DB_LOG));
 
        return (ret);
index 0d6c3f2..6904a2c 100644 (file)
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)log_archive.c        10.23 (Sleepycat) 8/23/97";
+static const char sccsid[] = "@(#)log_archive.c        10.26 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -27,18 +27,18 @@ static const char sccsid[] = "@(#)log_archive.c     10.23 (Sleepycat) 8/23/97";
 #include "clib_ext.h"
 #include "common_ext.h"
 
-static int absname __P((char *, char *, char **));
-static int build_data __P((DB_LOG *, char *, char ***, void *(*)(size_t)));
-static int cmpfunc __P((const void *, const void *));
-static int usermem __P((char ***, void *(*)(size_t)));
+static int __absname __P((char *, char *, char **));
+static int __build_data __P((DB_LOG *, char *, char ***, void *(*)(size_t)));
+static int __cmpfunc __P((const void *, const void *));
+static int __usermem __P((char ***, void *(*)(size_t)));
 
 /*
  * log_archive --
  *     Supporting function for db_archive(1).
  */
 int
-log_archive(logp, listp, flags, db_malloc)
-       DB_LOG *logp;
+log_archive(dblp, listp, flags, db_malloc)
+       DB_LOG *dblp;
        char ***listp;
        int flags;
        void *(*db_malloc) __P((size_t));
@@ -54,10 +54,10 @@ log_archive(logp, listp, flags, db_malloc)
 #define        OKFLAGS (DB_ARCH_ABS | DB_ARCH_DATA | DB_ARCH_LOG)
        if (flags != 0) {
                if ((ret =
-                   __db_fchk(logp->dbenv, "log_archive", flags, OKFLAGS)) != 0)
+                   __db_fchk(dblp->dbenv, "log_archive", flags, OKFLAGS)) != 0)
                        return (ret);
                if ((ret =
-                   __db_fcchk(logp->dbenv,
+                   __db_fcchk(dblp->dbenv,
                        "log_archive", flags, DB_ARCH_DATA, DB_ARCH_LOG)) != 0)
                        return (ret);
        }
@@ -68,7 +68,7 @@ log_archive(logp, listp, flags, db_malloc)
         * but that's just not possible.
         */
        if (LF_ISSET(DB_ARCH_ABS)) {
-               __set_errno(0);
+               __set_errno (0);
                if ((pref = getcwd(buf, sizeof(buf))) == NULL)
                        return (errno == 0 ? ENOMEM : errno);
        } else
@@ -76,19 +76,19 @@ log_archive(logp, listp, flags, db_malloc)
 
        switch (LF_ISSET(~DB_ARCH_ABS)) {
        case DB_ARCH_DATA:
-               return (build_data(logp, pref, listp, db_malloc));
+               return (__build_data(dblp, pref, listp, db_malloc));
        case DB_ARCH_LOG:
                memset(&rec, 0, sizeof(rec));
-               if (F_ISSET(logp, DB_AM_THREAD))
+               if (F_ISSET(dblp, DB_AM_THREAD))
                        F_SET(&rec, DB_DBT_MALLOC);
-               if ((ret = log_get(logp, &stable_lsn, &rec, DB_LAST)) != 0)
+               if ((ret = log_get(dblp, &stable_lsn, &rec, DB_LAST)) != 0)
                        return (ret);
-               if (F_ISSET(logp, DB_AM_THREAD))
+               if (F_ISSET(dblp, DB_AM_THREAD))
                        free(rec.data);
                fnum = stable_lsn.file;
                break;
        case 0:
-               if ((ret = __log_findckp(logp, &stable_lsn)) != 0) {
+               if ((ret = __log_findckp(dblp, &stable_lsn)) != 0) {
                        if (ret != DB_NOTFOUND)
                                return (ret);
                        *listp = NULL;
@@ -108,7 +108,7 @@ log_archive(logp, listp, flags, db_malloc)
 
        /* Build an array of the file names. */
        for (n = 0; fnum > 0; --fnum) {
-               if ((ret = __log_name(logp->dbenv, fnum, &name)) != 0)
+               if ((ret = __log_name(dblp, fnum, &name)) != 0)
                        goto err;
                if (__db_exists(name, NULL) != 0)
                        break;
@@ -123,7 +123,7 @@ log_archive(logp, listp, flags, db_malloc)
                }
 
                if (LF_ISSET(DB_ARCH_ABS)) {
-                       if ((ret = absname(pref, name, &array[n])) != 0)
+                       if ((ret = __absname(pref, name, &array[n])) != 0)
                                goto err;
                        FREES(name);
                } else if ((p = __db_rpath(name)) != NULL) {
@@ -146,10 +146,10 @@ log_archive(logp, listp, flags, db_malloc)
        }
 
        /* Sort the list. */
-       qsort(array, (size_t)n, sizeof(char *), cmpfunc);
+       qsort(array, (size_t)n, sizeof(char *), __cmpfunc);
 
        /* Rework the memory. */
-       if ((ret = usermem(&array, db_malloc)) != 0)
+       if ((ret = __usermem(&array, db_malloc)) != 0)
                goto err;
 
        *listp = array;
@@ -164,12 +164,12 @@ err:      if (array != NULL) {
 }
 
 /*
- * build_data --
+ * __build_data --
  *     Build a list of datafiles for return.
  */
 static int
-build_data(logp, pref, listp, db_malloc)
-       DB_LOG *logp;
+__build_data(dblp, pref, listp, db_malloc)
+       DB_LOG *dblp;
        char *pref, ***listp;
        void *(*db_malloc) __P((size_t));
 {
@@ -187,19 +187,19 @@ build_data(logp, pref, listp, db_malloc)
        array[0] = NULL;
 
        memset(&rec, 0, sizeof(rec));
-       if (F_ISSET(logp, DB_AM_THREAD))
+       if (F_ISSET(dblp, DB_AM_THREAD))
                F_SET(&rec, DB_DBT_MALLOC);
-       for (n = 0, ret = log_get(logp, &lsn, &rec, DB_FIRST);
-           ret == 0; ret = log_get(logp, &lsn, &rec, DB_NEXT)) {
+       for (n = 0, ret = log_get(dblp, &lsn, &rec, DB_FIRST);
+           ret == 0; ret = log_get(dblp, &lsn, &rec, DB_NEXT)) {
                if (rec.size < sizeof(rectype)) {
                        ret = EINVAL;
-                       __db_err(logp->dbenv, "log_archive: bad log record");
+                       __db_err(dblp->dbenv, "log_archive: bad log record");
                        goto lg_free;
                }
 
                memcpy(&rectype, rec.data, sizeof(rectype));
                if (rectype != DB_log_register) {
-                       if (F_ISSET(logp, DB_AM_THREAD)) {
+                       if (F_ISSET(dblp, DB_AM_THREAD)) {
                                free(rec.data);
                                rec.data = NULL;
                        }
@@ -207,7 +207,7 @@ build_data(logp, pref, listp, db_malloc)
                }
                if ((ret = __log_register_read(rec.data, &argp)) != 0) {
                        ret = EINVAL;
-                       __db_err(logp->dbenv,
+                       __db_err(dblp->dbenv,
                            "log_archive: unable to read log record");
                        goto lg_free;
                }
@@ -231,7 +231,7 @@ lg_free:            if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
                array[++n] = NULL;
                free(argp);
 
-               if (F_ISSET(logp, DB_AM_THREAD)) {
+               if (F_ISSET(dblp, DB_AM_THREAD)) {
                        free(rec.data);
                        rec.data = NULL;
                }
@@ -245,7 +245,7 @@ lg_free:            if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
        }
 
        /* Sort the list. */
-       qsort(array, (size_t)n, sizeof(char *), cmpfunc);
+       qsort(array, (size_t)n, sizeof(char *), __cmpfunc);
 
        /*
         * Build the real pathnames, discarding nonexistent files and
@@ -268,7 +268,7 @@ lg_free:            if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
                }
 
                /* Get the real name. */
-               if ((ret = __db_appname(logp->dbenv,
+               if ((ret = __db_appname(dblp->dbenv,
                    DB_APP_DATA, NULL, array[last], NULL, &real_name)) != 0)
                        goto err2;
 
@@ -284,7 +284,7 @@ lg_free:            if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
                FREES(array[last]);
                array[last] = NULL;
                if (pref != NULL) {
-                       ret = absname(pref, real_name, &array[last]);
+                       ret = __absname(pref, real_name, &array[last]);
                        FREES(real_name);
                        if (ret != 0)
                                goto err2;
@@ -302,7 +302,7 @@ lg_free:            if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
        array[last] = NULL;
 
        /* Rework the memory. */
-       if ((ret = usermem(&array, db_malloc)) != 0)
+       if ((ret = __usermem(&array, db_malloc)) != 0)
                goto err1;
 
        *listp = array;
@@ -327,11 +327,11 @@ err1:     if (array != NULL) {
 }
 
 /*
- * absname --
+ * __absname --
  *     Return an absolute path name for the file.
  */
 static int
-absname(pref, name, newnamep)
+__absname(pref, name, newnamep)
        char *pref, *name, **newnamep;
 {
        size_t l_pref, l_name;
@@ -355,12 +355,12 @@ absname(pref, name, newnamep)
 }
 
 /*
- * usermem --
+ * __usermem --
  *     Create a single chunk of memory that holds the returned information.
  *     If the user has their own malloc routine, use it.
  */
 static int
-usermem(listp, func)
+__usermem(listp, func)
        char ***listp;
        void *(*func) __P((size_t));
 {
@@ -406,7 +406,7 @@ usermem(listp, func)
 }
 
 static int
-cmpfunc(p1, p2)
+__cmpfunc(p1, p2)
        const void *p1, *p2;
 {
        return (strcmp(*((char **)p1), *((char **)p2)));
index 5940008..ea88a7b 100644 (file)
@@ -121,7 +121,7 @@ __log_register_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __log_register_read(dbtp->data, &argp)) != 0)
+       if ((ret = __log_register_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]log_register: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -269,7 +269,7 @@ __log_unregister_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __log_unregister_read(dbtp->data, &argp)) != 0)
+       if ((ret = __log_unregister_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]log_unregister: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
index 54a58c7..3f6df6c 100644 (file)
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)log_get.c    10.17 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)log_get.c    10.19 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -145,7 +145,7 @@ __log_get(dblp, alsn, dbt, flags, silent)
                 * Find any log file.  Note, we may have only entered records
                 * in the buffer, and not yet written a log file.
                 */
-               if ((ret = __log_find(dblp->dbenv, lp, &cnt)) != 0) {
+               if ((ret = __log_find(dblp, &cnt)) != 0) {
                        __db_err(dblp->dbenv,
        "log_get: unable to find the first record: no log files found.");
                        goto err2;
@@ -157,7 +157,7 @@ __log_get(dblp, alsn, dbt, flags, silent)
 
                /* Now go backwards to find the smallest one. */
                for (; cnt > 1; --cnt)
-                       if (__log_valid(dblp->dbenv, NULL, cnt) != 0) {
+                       if (__log_valid(dblp, NULL, cnt) != 0) {
                                ++cnt;
                                break;
                        }
@@ -223,7 +223,7 @@ retry:
         * Acquire a file descriptor.
         */
        if (dblp->c_fd == -1) {
-               if ((ret = __log_name(dblp->dbenv, nlsn.file, &np)) != 0)
+               if ((ret = __log_name(dblp, nlsn.file, &np)) != 0)
                        goto err1;
                if ((ret = __db_fdopen(np, DB_RDONLY | DB_SEQUENTIAL,
                    DB_RDONLY | DB_SEQUENTIAL, 0, &dblp->c_fd)) != 0) {
@@ -319,6 +319,7 @@ retry:
            &dblp->c_dbt.data, &dblp->c_dbt.ulen, NULL)) != 0)
                goto err1;
        free(tbuf);
+       tbuf = NULL;
 
 cksum: if (hdr.cksum != __ham_func4(dbt->data, dbt->size)) {
                if (!silent)
index db31f9b..225595f 100644 (file)
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)log_put.c    10.12 (Sleepycat) 8/20/97";
+static const char sccsid[] = "@(#)log_put.c    10.14 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -416,7 +416,7 @@ log_file(dblp, lsn, namep, len)
 
        LOCK_LOGREGION(dblp);
 
-       ret = __log_name(dblp->dbenv, lsn->file, &p);
+       ret = __log_name(dblp, lsn->file, &p);
 
        UNLOCK_LOGREGION(dblp);
 
@@ -453,14 +453,14 @@ __log_newfd(dblp)
 
        /* Get the path of the new file and open it. */
        dblp->lfname = dblp->lp->lsn.file;
-       if ((ret = __log_name(dblp->dbenv, dblp->lfname, &p)) != 0)
+       if ((ret = __log_name(dblp, dblp->lfname, &p)) != 0)
                return (ret);
        if ((ret = __db_fdopen(p,
            DB_CREATE | DB_SEQUENTIAL,
            DB_CREATE | DB_SEQUENTIAL,
            dblp->lp->persist.mode, &dblp->lfd)) != 0)
                __db_err(dblp->dbenv,
-                   "log_put: %s: %s", p, strerror(errno));
+                   "log_put: %s: %s", p, strerror(ret));
        FREES(p);
        return (ret);
 }
@@ -469,16 +469,17 @@ __log_newfd(dblp)
  * __log_name --
  *     Return the log name for a particular file.
  *
- * PUBLIC: int __log_name __P((DB_ENV *, int, char **));
+ * PUBLIC: int __log_name __P((DB_LOG *, int, char **));
  */
 int
-__log_name(dbenv, fn, np)
-       DB_ENV *dbenv;
-       int fn;
-       char **np;
+__log_name(dblp, fileno, namep)
+       DB_LOG *dblp;
+       char **namep;
+       int fileno;
 {
        char name[sizeof(LFNAME) + 10];
 
-       (void)snprintf(name, sizeof(name), LFNAME, fn);
-       return (__db_appname(dbenv, DB_APP_LOG, NULL, name, NULL, np));
+       (void)snprintf(name, sizeof(name), LFNAME, fileno);
+       return (__db_appname(dblp->dbenv,
+           DB_APP_LOG, dblp->dir, name, NULL, namep));
 }
index 582eab9..859b1e5 100644 (file)
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)log_register.c       10.10 (Sleepycat) 8/20/97";
+static const char sccsid[] = "@(#)log_register.c       10.11 (Sleepycat) 9/15/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -190,8 +190,13 @@ log_unregister(dblp, fid)
        SH_TAILQ_REMOVE(&dblp->lp->fq, fnp, q, __fname);
        __db_shalloc_free(dblp->addr, fnp);
 
-       /* Remove from the process local table. */
-       __log_rem_logid(dblp, fid);
+       /*
+        * Remove from the process local table.  If this operation is taking
+        * place during recovery, then the logid was never added to the table,
+        * so do not remove it.
+        */
+       if (!F_ISSET(dblp, DB_AM_RECOVER))
+               __log_rem_logid(dblp, fid);
 
 ret1:  UNLOCK_LOGREGION(dblp);
 
index 3d0d053..fb6bc96 100644 (file)
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_bh.c      10.15 (Sleepycat) 8/29/97";
+static const char sccsid[] = "@(#)mp_bh.c      10.16 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -55,7 +55,7 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep)
         * If we find a descriptor on the file that's not open for writing, we
         * try and upgrade it to make it writeable.
         */
-       LOCKHANDLE(dbmp, &dbmp->mutex);
+       LOCKHANDLE(dbmp, dbmp->mutexp);
        for (dbmfp = TAILQ_FIRST(&dbmp->dbmfq);
            dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q))
                if (dbmfp->mfp == mfp) {
@@ -64,7 +64,7 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep)
                                return (0);
                        break;
                }
-       UNLOCKHANDLE(dbmp, &dbmp->mutex);
+       UNLOCKHANDLE(dbmp, dbmp->mutexp);
        if (dbmfp != NULL)
                goto found;
 
@@ -75,12 +75,12 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep)
         * nothing we can do.
         */
        if (mfp->ftype != 0) {
-               LOCKHANDLE(dbmp, &dbmp->mutex);
+               LOCKHANDLE(dbmp, dbmp->mutexp);
                for (mpreg = LIST_FIRST(&dbmp->dbregq);
                    mpreg != NULL; mpreg = LIST_NEXT(mpreg, q))
                        if (mpreg->ftype == mfp->ftype)
                                break;
-               UNLOCKHANDLE(dbmp, &dbmp->mutex);
+               UNLOCKHANDLE(dbmp, dbmp->mutexp);
                if (mpreg == NULL)
                        return (0);
        }
@@ -135,19 +135,19 @@ __memp_pgread(dbmfp, bhp, can_create)
         * Seek to the page location.
         */
        ret = 0;
-       LOCKHANDLE(dbmp, &dbmfp->mutex);
+       LOCKHANDLE(dbmp, dbmfp->mutexp);
        if (dbmfp->fd == -1 || (ret =
            __db_lseek(dbmfp->fd, pagesize, bhp->pgno, 0, SEEK_SET)) != 0) {
                if (!can_create) {
                        if (dbmfp->fd == -1)
                                ret = EINVAL;
-                       UNLOCKHANDLE(dbmp, &dbmfp->mutex);
+                       UNLOCKHANDLE(dbmp, dbmfp->mutexp);
                        __db_err(dbmp->dbenv,
                            "%s: page %lu doesn't exist, create flag not set",
                            dbmfp->path, (u_long)bhp->pgno);
                        goto err;
                }
-               UNLOCKHANDLE(dbmp, &dbmfp->mutex);
+               UNLOCKHANDLE(dbmp, dbmfp->mutexp);
 
                /* Clear any uninitialized data. */
                memset(bhp->buf, 0, pagesize);
@@ -159,7 +159,7 @@ __memp_pgread(dbmfp, bhp, can_create)
         * any valid data is preserved.
         */
        ret = __db_read(dbmfp->fd, bhp->buf, pagesize, &nr);
-       UNLOCKHANDLE(dbmp, &dbmfp->mutex);
+       UNLOCKHANDLE(dbmp, dbmfp->mutexp);
        if (ret != 0)
                goto err;
 
@@ -268,10 +268,10 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
        }
 
        /* Temporary files may not yet have been created. */
-       LOCKHANDLE(dbmp, &dbmfp->mutex);
+       LOCKHANDLE(dbmp, dbmfp->mutexp);
        if (dbmfp->fd == -1 && ((ret = __db_appname(dbenv, DB_APP_TMP,
            NULL, NULL, &dbmfp->fd, NULL)) != 0 || dbmfp->fd == -1)) {
-               UNLOCKHANDLE(dbmp, &dbmfp->mutex);
+               UNLOCKHANDLE(dbmp, dbmfp->mutexp);
                __db_err(dbenv, "unable to create temporary backing file");
                goto err;
        }
@@ -282,7 +282,7 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
                fail = "seek";
        else if ((ret = __db_write(dbmfp->fd, bhp->buf, pagesize, &nw)) != 0)
                fail = "write";
-       UNLOCKHANDLE(dbmp, &dbmfp->mutex);
+       UNLOCKHANDLE(dbmp, dbmfp->mutexp);
        if (ret != 0) {
                /*
                 * XXX
@@ -380,7 +380,7 @@ __memp_pg(dbmfp, bhp, is_pgin)
        dbmp = dbmfp->dbmp;
        mfp = dbmfp->mfp;
 
-       LOCKHANDLE(dbmp, &dbmp->mutex);
+       LOCKHANDLE(dbmp, dbmp->mutexp);
 
        ftype = mfp->ftype;
        for (mpreg = LIST_FIRST(&dbmp->dbregq);
@@ -394,7 +394,7 @@ __memp_pg(dbmfp, bhp, is_pgin)
                        dbt.data = ADDR(dbmp, mfp->pgcookie_off);
                        dbtp = &dbt;
                }
-               UNLOCKHANDLE(dbmp, &dbmp->mutex);
+               UNLOCKHANDLE(dbmp, dbmp->mutexp);
 
                if (is_pgin) {
                        if (mpreg->pgin != NULL && (ret =
@@ -408,11 +408,11 @@ __memp_pg(dbmfp, bhp, is_pgin)
        }
 
        if (mpreg == NULL)
-               UNLOCKHANDLE(dbmp, &dbmp->mutex);
+               UNLOCKHANDLE(dbmp, dbmp->mutexp);
 
        return (0);
 
-err:   UNLOCKHANDLE(dbmp, &dbmp->mutex);
+err:   UNLOCKHANDLE(dbmp, dbmp->mutexp);
        __db_err(dbmp->dbenv, "%s: %s failed for page %lu",
            dbmfp->path, is_pgin ? "pgin" : "pgout", (u_long)bhp->pgno);
        return (ret);
index 418802a..a0364e9 100644 (file)
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_fget.c    10.22 (Sleepycat) 8/19/97";
+static const char sccsid[] = "@(#)mp_fget.c    10.25 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -35,7 +35,7 @@ int
 memp_fget(dbmfp, pgnoaddr, flags, addrp)
        DB_MPOOLFILE *dbmfp;
        db_pgno_t *pgnoaddr;
-       u_long flags;
+       int flags;
        void *addrp;
 {
        BH *bhp, *tbhp;
@@ -293,7 +293,7 @@ found:              /* Increment the reference count. */
                        __db_err(dbmp->dbenv,
                            "%s: too many references to page %lu",
                            dbmfp->path, bhp->pgno);
-                       ret = EAGAIN;
+                       ret = EINVAL;
                        goto err;
                }
                ++bhp->ref;
@@ -337,9 +337,9 @@ found:              /* Increment the reference count. */
                ++mfp->stat.st_cache_hit;
        }
 
-mapret:        LOCKHANDLE(dbmp, &dbmfp->mutex);
+mapret:        LOCKHANDLE(dbmp, dbmfp->mutexp);
        ++dbmfp->pinref;
-       UNLOCKHANDLE(dbmp, &dbmfp->mutex);
+       UNLOCKHANDLE(dbmp, dbmfp->mutexp);
 
        if (0) {
 err:           /*
index 1a770bf..5ab8077 100644 (file)
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_fopen.c   10.25 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)mp_fopen.c   10.27 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -28,8 +28,8 @@ static const char sccsid[] = "@(#)mp_fopen.c  10.25 (Sleepycat) 8/27/97";
 #include "common_ext.h"
 
 static int __memp_mf_close __P((DB_MPOOL *, DB_MPOOLFILE *));
-static int __memp_mf_open __P((DB_MPOOL *, DB_MPOOLFILE *,
-    int, int, size_t, int, DBT *, u_int8_t *, int, MPOOLFILE **));
+static int __memp_mf_open __P((DB_MPOOL *,
+    DB_MPOOLFILE *, int, size_t, int, DBT *, u_int8_t *, int, MPOOLFILE **));
 
 /*
  * memp_fopen --
@@ -97,7 +97,6 @@ __memp_fopen(dbmp, path,
                    path == NULL ? TEMPORARY : path, strerror(ENOMEM));
                return (ENOMEM);
        }
-       LOCKINIT(dbmp, &dbmfp->mutex);
        dbmfp->dbmp = dbmp;
        dbmfp->fd = -1;
        if (LF_ISSET(DB_RDONLY))
@@ -141,14 +140,21 @@ __memp_fopen(dbmp, path,
                }
        }
 
-       /* Find/allocate the shared file object. */
+       /*
+        * Find/allocate the shared file objects.  This includes allocating
+        * space for the per-process thread lock.
+        */
        if (needlock)
                LOCKREGION(dbmp);
-       ret = __memp_mf_open(dbmp, dbmfp, ftype,
-           F_ISSET(dbmfp, MP_READONLY), pagesize,
+       ret = __memp_mf_open(dbmp, dbmfp, ftype, pagesize,
            lsn_offset, pgcookie, fileid, F_ISSET(dbmfp, MP_PATH_TEMP), &mfp);
+       if (ret == 0 &&
+           F_ISSET(dbmp, MP_LOCKHANDLE) && (ret =
+           __memp_ralloc(dbmp, sizeof(db_mutex_t), NULL, &dbmfp->mutexp)) == 0)
+               LOCKINIT(dbmp, dbmfp->mutexp);
        if (needlock)
                UNLOCKREGION(dbmp);
+
        if (ret != 0)
                goto err;
 
@@ -156,11 +162,11 @@ __memp_fopen(dbmp, path,
 
        /*
         * If a file:
-        *
         *      + is read-only
+        *      + isn't temporary
         *      + doesn't require any pgin/pgout support
-        *      + is less than mp_mmapsize bytes in size.
-        *      + and the DB_NOMMAP flag wasn't set
+        *      + the DB_NOMMAP flag wasn't set
+        *      + and is less than mp_mmapsize bytes in size
         *
         * we can mmap it instead of reading/writing buffers.  Don't do error
         * checking based on the mmap call failure.  We want to do normal I/O
@@ -176,11 +182,20 @@ __memp_fopen(dbmp, path,
         * flatly impossible.  Hope that mmap fails if the file is too large.
         */
 #define        DB_MAXMMAPSIZE  (10 * 1024 * 1024)      /* 10 Mb. */
+       if (mfp->can_mmap) {
+               if (!F_ISSET(dbmfp, MP_READONLY))
+                       mfp->can_mmap = 0;
+               if (path == NULL)
+                       mfp->can_mmap = 0;
+               if (ftype != 0)
+                       mfp->can_mmap = 0;
+               if (LF_ISSET(DB_NOMMAP))
+                       mfp->can_mmap = 0;
+               if (size > (dbenv == NULL || dbenv->mp_mmapsize == 0 ?
+                   DB_MAXMMAPSIZE : (off_t)dbenv->mp_mmapsize))
+                       mfp->can_mmap = 0;
+       }
        dbmfp->addr = NULL;
-       mfp->can_mmap = F_ISSET(dbmfp, MP_READONLY) &&
-           ftype == 0 && !LF_ISSET(DB_NOMMAP) && path != NULL &&
-           size <= (dbenv == NULL || dbenv->mp_mmapsize == 0 ?
-           DB_MAXMMAPSIZE : (off_t)dbenv->mp_mmapsize);
        if (mfp->can_mmap) {
                dbmfp->len = size;
                if (__db_mmap(dbmfp->fd, dbmfp->len, 1, 1, &dbmfp->addr) != 0) {
@@ -189,14 +204,18 @@ __memp_fopen(dbmp, path,
                }
        }
 
-       LOCKHANDLE(dbmp, &dbmp->mutex);
+       LOCKHANDLE(dbmp, dbmp->mutexp);
        TAILQ_INSERT_TAIL(&dbmp->dbmfq, dbmfp, q);
-       UNLOCKHANDLE(dbmp, &dbmp->mutex);
+       UNLOCKHANDLE(dbmp, dbmp->mutexp);
 
        *retp = dbmfp;
        return (0);
 
-err:   if (F_ISSET(dbmfp, MP_PATH_ALLOC))
+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 (F_ISSET(dbmfp, MP_PATH_ALLOC))
                FREES(dbmfp->path);
        if (dbmfp->fd != -1)
                (void)__db_close(dbmfp->fd);
@@ -211,10 +230,10 @@ err:      if (F_ISSET(dbmfp, MP_PATH_ALLOC))
  */
 static int
 __memp_mf_open(dbmp, dbmfp,
-    ftype, readonly, pagesize, lsn_offset, pgcookie, fileid, istemp, retp)
+    ftype, pagesize, lsn_offset, pgcookie, fileid, istemp, retp)
        DB_MPOOL *dbmp;
        DB_MPOOLFILE *dbmfp;
-       int ftype, readonly, lsn_offset, istemp;
+       int ftype, lsn_offset, istemp;
        size_t pagesize;
        DBT *pgcookie;
        u_int8_t *fileid;
@@ -255,13 +274,8 @@ __memp_mf_open(dbmp, dbmfp,
                                mfp = NULL;
                                goto ret1;
                        }
-                       /*
-                        * Found it: increment the reference count and update
-                        * the mmap-able status.
-                        */
+                       /* Found it: increment the reference count. */
                        ++mfp->ref;
-                       if (!readonly)
-                               mfp->can_mmap = 0;
                        goto ret1;
                }
 
@@ -273,6 +287,7 @@ alloc:      if ((ret = __memp_ralloc(dbmp, sizeof(MPOOLFILE), NULL, &mfp)) != 0)
        memset(mfp, 0, sizeof(MPOOLFILE));
        mfp->ref = 1;
        mfp->ftype = ftype;
+       mfp->can_mmap = 1;
        mfp->lsn_off = lsn_offset;
        mfp->stat.st_pagesize = pagesize;
 
@@ -343,9 +358,9 @@ memp_fclose(dbmfp)
                    dbmfp->path, (u_long)dbmfp->pinref);
 
        /* Remove the DB_MPOOLFILE structure from the list. */
-       LOCKHANDLE(dbmp, &dbmp->mutex);
+       LOCKHANDLE(dbmp, dbmp->mutexp);
        TAILQ_REMOVE(&dbmp->dbmfq, dbmfp, q);
-       UNLOCKHANDLE(dbmp, &dbmp->mutex);
+       UNLOCKHANDLE(dbmp, dbmp->mutexp);
 
        /* Close the underlying MPOOLFILE. */
        (void)__memp_mf_close(dbmp, dbmfp);
@@ -362,11 +377,16 @@ memp_fclose(dbmfp)
                        t_ret = ret;
        }
 
-       /* Potentially allocated path. */
+       /* Free memory. */
        if (F_ISSET(dbmfp, MP_PATH_ALLOC))
                FREES(dbmfp->path);
+       if (dbmfp->mutexp != NULL) {
+               LOCKREGION(dbmp);
+               __db_shalloc_free(dbmp->addr, dbmfp->mutexp);
+               UNLOCKREGION(dbmp);
+       }
 
-       /* Free the DB_MPOOLFILE structure. */
+       /* Discard the DB_MPOOLFILE structure. */
        FREE(dbmfp, sizeof(DB_MPOOLFILE));
 
        return (ret);
index 5fac8ae..9ea7cd9 100644 (file)
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_fput.c    10.10 (Sleepycat) 7/20/97";
+static const char sccsid[] = "@(#)mp_fput.c    10.12 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -31,7 +31,7 @@ int
 memp_fput(dbmfp, pgaddr, flags)
        DB_MPOOLFILE *dbmfp;
        void *pgaddr;
-       u_long flags;
+       int flags;
 {
        BH *bhp;
        DB_MPOOL *dbmp;
@@ -58,14 +58,14 @@ memp_fput(dbmfp, pgaddr, flags)
        }
 
        /* Decrement the pinned reference count. */
-       LOCKHANDLE(dbmp, &dbmfp->mutex);
+       LOCKHANDLE(dbmp, dbmfp->mutexp);
        if (dbmfp->pinref == 0)
                __db_err(dbmp->dbenv,
                    "%s: put: more blocks returned than retrieved",
                    dbmfp->path);
        else
                --dbmfp->pinref;
-       UNLOCKHANDLE(dbmp, &dbmfp->mutex);
+       UNLOCKHANDLE(dbmp, dbmfp->mutexp);
 
        /*
         * If we're mapping the file, there's nothing to do.  Because we can
index 588085a..a3a3dce 100644 (file)
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_fset.c    10.8 (Sleepycat) 8/19/97";
+static const char sccsid[] = "@(#)mp_fset.c    10.9 (Sleepycat) 9/20/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -30,7 +30,7 @@ int
 memp_fset(dbmfp, pgaddr, flags)
        DB_MPOOLFILE *dbmfp;
        void *pgaddr;
-       u_long flags;
+       int flags;
 {
        BH *bhp;
        DB_MPOOL *dbmp;
index 257ce1b..f622b1e 100644 (file)
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_open.c    10.12 (Sleepycat) 7/6/97";
+static const char sccsid[] = "@(#)mp_open.c    10.13 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -56,7 +56,6 @@ memp_open(path, flags, mode, dbenv, retp)
        /* Create and initialize the DB_MPOOL structure. */
        if ((dbmp = (DB_MPOOL *)calloc(1, sizeof(DB_MPOOL))) == NULL)
                return (ENOMEM);
-       LOCKINIT(dbmp, &dbmp->mutex);
        LIST_INIT(&dbmp->dbregq);
        TAILQ_INIT(&dbmp->dbmfq);
 
@@ -68,6 +67,17 @@ memp_open(path, flags, mode, dbenv, retp)
                F_SET(dbmp, MP_ISPRIVATE);
 
        /*
+        * XXX
+        * HP-UX won't permit mutexes to live in anything but shared memory.
+        * So, we have to instantiate the shared mpool region file on that
+        * architecture, regardless.  If this turns out to be a performance
+        * problem, we could probably use anonymous memory instead.
+        */
+#if defined(__hppa)
+       F_CLR(dbmp, MP_ISPRIVATE);
+#endif
+
+       /*
         * Map in the region.  We do locking regardless, as portions of it are
         * implemented in common code (if we put the region in a file, that is).
         */
@@ -79,12 +89,22 @@ memp_open(path, flags, mode, dbenv, retp)
        /*
         * If there's concurrent access, then we have to lock the region.
         * If it's threaded, then we have to lock both the handles and the
-        * region.
+        * region, and we need to allocate a mutex for that purpose.
         */
        if (!F_ISSET(dbmp, MP_ISPRIVATE))
                F_SET(dbmp, MP_LOCKREGION);
-       if (LF_ISSET(DB_THREAD))
+       if (LF_ISSET(DB_THREAD)) {
                F_SET(dbmp, MP_LOCKHANDLE | MP_LOCKREGION);
+               LOCKREGION(dbmp);
+               ret = __memp_ralloc(dbmp,
+                   sizeof(db_mutex_t), NULL, &dbmp->mutexp);
+               UNLOCKREGION(dbmp);
+               if (ret != 0) {
+                       (void)memp_close(dbmp);
+                       goto err;
+               }
+               LOCKINIT(dbmp, dbmp->mutexp);
+       }
 
        *retp = dbmp;
        return (0);
@@ -119,11 +139,18 @@ memp_close(dbmp)
                if ((t_ret = memp_fclose(dbmfp)) != 0 && ret == 0)
                        ret = t_ret;
 
+       /* Discard thread mutex. */
+       if (F_ISSET(dbmp, MP_LOCKHANDLE)) {
+               LOCKREGION(dbmp);
+               __db_shalloc_free(dbmp->addr, dbmp->mutexp);
+               UNLOCKREGION(dbmp);
+       }
+
        /* Close the region. */
        if ((t_ret = __memp_rclose(dbmp)) && ret == 0)
                ret = t_ret;
 
-       /* Free the structure. */
+       /* Discard the structure. */
        FREE(dbmp, sizeof(DB_MPOOL));
 
        return (ret);
@@ -168,9 +195,9 @@ memp_register(dbmp, ftype, pgin, pgout)
         * the most recent registry in the case of multiple entries, so
         * we don't have to check for multiple registries.
         */
-       LOCKHANDLE(dbmp, &dbmp->mutex);
+       LOCKHANDLE(dbmp, dbmp->mutexp);
        LIST_INSERT_HEAD(&dbmp->dbregq, mpr, q);
-       UNLOCKHANDLE(dbmp, &dbmp->mutex);
+       UNLOCKHANDLE(dbmp, dbmp->mutexp);
 
        return (0);
 }
index b23f738..5315b2d 100644 (file)
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mutex.c      10.22 (Sleepycat) 8/21/97";
+static const char sccsid[] = "@(#)mutex.c      10.25 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
index 6dabd62..1206e3f 100644 (file)
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_os_dir.c  10.8 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)db_os_dir.c  10.10 (Sleepycat) 9/17/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -60,9 +60,11 @@ __db_dir(dbenv, dir, namesp, cntp)
        struct _finddata_t fdata;
        long dirhandle;
        int finished;
+       char filespec[MAX_PATH];
 
-       if ((dirhandle = _findfirst(dir, &fdata)) == -1) {
-               __db_err(dbenv, "%s: %s", dir, strerror(errno));
+       (void)snprintf(filespec, sizeof(filespec), "%s/*", dir);
+       if ((dirhandle = _findfirst(filespec, &fdata)) == -1) {
+               __db_err(dbenv, "%s: %s", filespec, strerror(errno));
                return (errno);
        }
 
index 4f9b79a..b2a692b 100644 (file)
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
        Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_checkpoint.c      10.11 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)db_checkpoint.c      10.12 (Sleepycat) 9/4/97";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -22,6 +22,7 @@ static const char sccsid[] = "@(#)db_checkpoint.c     10.11 (Sleepycat) 8/27/97";
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <time.h>
 #include <unistd.h>
 #endif
@@ -59,7 +60,7 @@ main(argc, argv)
        DB_ENV *dbenv;
        time_t now;
        long kbytes, minutes, seconds;
-       int ch, rval, verbose;
+       int ch, eval, verbose;
        char *home, *logfile;
 
        home = logfile = NULL;
@@ -110,7 +111,7 @@ main(argc, argv)
         * to wake up when a checkpoint is necessary.  If we have a "kbytes"
         * field set, then we'll check every 30 seconds.
         */
-       rval = 0;
+       eval = 0;
        seconds = kbytes != 0 ? 30 : minutes * 60;
        while (!interrupted) {
                (void)__db_sleep(seconds, 0);
@@ -119,23 +120,25 @@ main(argc, argv)
                        (void)time(&now);
                        printf("checkpoint: %s", ctime(&now));
                }
-               rval = txn_checkpoint(dbenv->tx_info, kbytes, minutes);
-               if (rval < 0)
-                       break;
+               errno = txn_checkpoint(dbenv->tx_info, kbytes, minutes);
 
-               while (rval > 0) {
+               while (errno == DB_INCOMPLETE) {
                        if (verbose)
                                __db_err(dbenv,
                                    "checkpoint did not finish, retrying");
                        (void)__db_sleep(2, 0);
-                       rval = txn_checkpoint(dbenv->tx_info, 0, 0);
+                       errno = txn_checkpoint(dbenv->tx_info, 0, 0);
                }
-               if (rval < 0)
+
+               if (errno != 0) {
+                       eval = 1;
+                       __db_err(dbenv, "checkpoint: %s", strerror(errno));
                        break;
+               }
        }
 
        if (logfile != NULL && logpid(logfile, 0))
-               rval = 1;
+               eval = 1;
 
        if (interrupted) {
                (void)signal(interrupted, SIG_DFL);
@@ -143,7 +146,7 @@ main(argc, argv)
                /* NOTREACHED */
        }
 
-       return (db_appexit(dbenv) || rval ? 1 : 0);
+       return (db_appexit(dbenv) || eval ? 1 : 0);
 }
 
 /*
index 09004f5..ec2b53d 100644 (file)
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
        Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_deadlock.c        10.14 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)db_deadlock.c        10.15 (Sleepycat) 9/4/97";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
index 6e2d95b..5ec7673 100644 (file)
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
        Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_dump185.c 10.7 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)db_dump185.c 10.8 (Sleepycat) 9/21/97";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -192,7 +192,7 @@ main(argc, argv)
 
        if ((dbp = dbopen(argv[0], O_RDONLY, 0, DB_BTREE, NULL)) == NULL) {
                if ((dbp = dbopen(argv[0], O_RDONLY, 0, DB_HASH, NULL)) == NULL)
-                       return (1);
+                       err(1, "%s", argv[0]);
                db_185_hash(dbp, pflag);
        } else
                db_185_btree(dbp, pflag);
index 6f69216..a1ebfa8 100644 (file)
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
        Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_load.c    10.12 (Sleepycat) 8/28/97";
+static const char sccsid[] = "@(#)db_load.c    10.13 (Sleepycat) 9/15/97";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -59,7 +59,7 @@ main(argc, argv)
        char **clist, **clp, *home;
 
        /* Allocate enough room for configuration arguments. */
-       if ((clp = clist = calloc(argc + 1, sizeof(char *))) == NULL)
+       if ((clp = clist = (char **)calloc(argc + 1, sizeof(char *))) == NULL)
                err(1, NULL);
 
        home = NULL;
index d17c4b0..55b9b49 100644 (file)
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
        Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_recover.c 10.14 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)db_recover.c 10.15 (Sleepycat) 9/21/97";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -24,6 +24,7 @@ static const char sccsid[] = "@(#)db_recover.c        10.14 (Sleepycat) 8/27/97";
 #endif
 
 #include "db_int.h"
+#include "shqueue.h"
 #include "txn.h"
 #include "common_ext.h"
 #include "clib_ext.h"
index cb700dc..9a0d626 100644 (file)
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)txn.c        10.24 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)txn.c        10.30 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 
-/*
- * This file contains the top level routines of the transaction library.
- * It assumes that a lock manager and log manager that conform to the db_log(3)
- * and db_lock(3) interfaces exist.
- */
-
 #ifndef NO_SYSTEM_INCLUDES
 #include <sys/types.h>
 #include <sys/mman.h>
@@ -87,10 +81,12 @@ static int __txn_undo __P((DB_TXN *));
 static int __txn_validate_region __P((DB_TXNMGR *));
 
 /*
+ * This file contains the top level routines of the transaction library.
+ * It assumes that a lock manager and log manager that conform to the db_log(3)
+ * and db_lock(3) interfaces exist.
+ *
  * Create and initialize a transaction region in shared memory.
- * 0 means, success.
- * +1 means that the db_create failed, so we did not create the region.
- * -1 means that we got some sort of system error.
+ * Return 0 on success, errno on failure.
  */
 static int
 __txn_create(dbenv, path, mode)
@@ -99,9 +95,8 @@ __txn_create(dbenv, path, mode)
        u_int mode;
 {
        DB_TXNREGION *txn_region;
-       TXN_DETAIL *txnp;
        time_t now;
-       int fd, i, maxtxns, ret;
+       int fd, maxtxns, ret;
 
        maxtxns = dbenv->tx_max != 0 ? dbenv->tx_max : 1000;
        (void)time(&now);
@@ -120,17 +115,12 @@ __txn_create(dbenv, path, mode)
        /* XXX If we ever do more types of locking and logging, this changes. */
        txn_region->logtype = 0;
        txn_region->locktype = 0;
-       txn_region->free_txn = 0;
        txn_region->time_ckp = now;
        ZERO_LSN(txn_region->last_ckp);
        ZERO_LSN(txn_region->pending_ckp);
-
-       for (txnp = &txn_region->table[0], i = 0; i < maxtxns; i++, txnp++) {
-               ZERO_LSN(txnp->begin_lsn);
-               txnp->status = TXN_UNALLOC;
-               txnp->txnid = i + 1;
-       }
-       txn_region->table[maxtxns - 1].txnid = TXN_INVALID;
+       SH_TAILQ_INIT(&txn_region->active_txn);
+       __db_shalloc_init((void *)&txn_region[1],
+           TXN_REGION_SIZE(maxtxns) - sizeof(DB_TXNREGION));
 
        /* Unlock the region. */
        (void)__db_mutex_unlock(&txn_region->hdr.lock, fd);
@@ -140,7 +130,6 @@ __txn_create(dbenv, path, mode)
                (void)txn_unlink(path, 1 /* force */, dbenv);
                return (ret);
        }
-
        return (0);
 }
 
@@ -199,7 +188,7 @@ retry1:     if ((ret = __db_ropen(dbenv, DB_APP_NONE, path, DEFAULT_TXN_FILE,
 
        /* Now, create the transaction manager structure and set its fields. */
        if ((tmgrp = (DB_TXNMGR *)malloc(sizeof(DB_TXNMGR))) == NULL) {
-               __db_err(dbenv, "txn_open: %s", strerror(errno));
+               __db_err(dbenv, "txn_open: %s", strerror(ENOMEM));
                ret = ENOMEM;
                goto out;
        }
@@ -211,9 +200,18 @@ retry1:    if ((ret = __db_ropen(dbenv, DB_APP_NONE, path, DEFAULT_TXN_FILE,
        tmgrp->reg_size = txn_regionp->hdr.size;
        tmgrp->fd = fd;
        tmgrp->flags = LF_ISSET(DB_TXN_NOSYNC | DB_THREAD);
+       tmgrp->mem = &txn_regionp[1];
+       tmgrp->mutexp = NULL;
        TAILQ_INIT(&tmgrp->txn_chain);
-       if (LF_ISSET(DB_THREAD))
-               __db_mutex_init(&tmgrp->mutex, -1);
+       if (LF_ISSET(DB_THREAD)) {
+               LOCK_TXNREGION(tmgrp);
+               if ((ret = __db_shalloc(tmgrp->mem, sizeof(db_mutex_t), 
+                   MUTEX_ALIGNMENT, &tmgrp->mutexp)) == 0)
+                       __db_mutex_init(tmgrp->mutexp, -1);
+               UNLOCK_TXNREGION(tmgrp);
+               if (ret != 0)
+                       goto out;
+       }
        *mgrpp = tmgrp;
        return (0);
 
@@ -221,8 +219,14 @@ out:       if (txn_regionp != NULL)
                (void)__db_rclose(dbenv, fd, txn_regionp);
        if (flags & DB_CREATE)
                (void)txn_unlink(path, 1, dbenv);
-       if (tmgrp != NULL)
+       if (tmgrp != NULL) {
+               if (tmgrp->mutexp != NULL) {
+                       LOCK_TXNREGION(tmgrp);
+                       __db_shalloc_free(tmgrp->mem, tmgrp->mutexp);
+                       UNLOCK_TXNREGION(tmgrp);
+               }
                free(tmgrp);
+       }
        return (ret);
 }
 
@@ -239,30 +243,20 @@ txn_begin(tmgrp, parent, txnpp)
 {
        TXN_DETAIL *txnp;
        DB_TXN *retp;
-       int id, index, ret;
+       int id, ret;
 
        LOCK_TXNREGION(tmgrp);
 
-       if ((ret = __txn_validate_region(tmgrp)) != 0) {
-               UNLOCK_TXNREGION(tmgrp);
-               return (ret);
-       }
-
-       /* Remove element from free list. */
-       if (tmgrp->region->free_txn == TXN_INVALID &&
-           (ret = __txn_grow_region(tmgrp)) != 0) {
-               UNLOCK_TXNREGION(tmgrp);
-               return (ret);
-       }
-
-       index = tmgrp->region->free_txn;
-       txnp = &tmgrp->region->table[index];
-       tmgrp->region->free_txn = txnp->txnid;
+       if ((ret = __txn_validate_region(tmgrp)) != 0)
+               goto err;
 
-       if (txnp->status != TXN_UNALLOC) {
-               UNLOCK_TXNREGION(tmgrp);
-               return (EINVAL);
-       }
+       /* Allocate a new transaction detail structure. */
+       if ((ret = __db_shalloc(tmgrp->mem, sizeof(TXN_DETAIL), 0, &txnp)) != 0
+           && ret == ENOMEM && (ret = __txn_grow_region(tmgrp)) == 0)
+               ret = __db_shalloc(tmgrp->mem, sizeof(TXN_DETAIL), 0, &txnp);
+               
+       if (ret != 0)
+               goto err;
 
        /* Make sure that last_txnid is not going to wrap around. */
        if (tmgrp->region->last_txnid == TXN_INVALID)
@@ -270,18 +264,20 @@ txn_begin(tmgrp, parent, txnpp)
 
        if ((retp = (DB_TXN *)malloc(sizeof(DB_TXN))) == NULL) {
                __db_err(tmgrp->dbenv, "txn_begin : %s", strerror(ENOMEM));
-               UNLOCK_TXNREGION(tmgrp);
-               return (ENOMEM);
+               ret = ENOMEM;
+               goto err1;
        }
 
        id = ++tmgrp->region->last_txnid;
        tmgrp->region->nbegins++;
 
        txnp->txnid = id;
-       txnp->last_lock = 0;
-       txnp->status = TXN_RUNNING;
        ZERO_LSN(txnp->last_lsn);
        ZERO_LSN(txnp->begin_lsn);
+       txnp->last_lock = 0;
+       txnp->status = TXN_RUNNING;
+       SH_TAILQ_INSERT_HEAD(&tmgrp->region->active_txn,
+           txnp, links, __txn_detail);
 
        UNLOCK_TXNREGION(tmgrp);
 
@@ -297,8 +293,9 @@ txn_begin(tmgrp, parent, txnpp)
 
                /* Deallocate transaction. */
                LOCK_TXNREGION(tmgrp);
-               txnp->txnid = tmgrp->region->free_txn;
-               tmgrp->region->free_txn = txnp - &tmgrp->region->table[0];
+               SH_TAILQ_REMOVE(&tmgrp->region->active_txn,
+                   txnp, links, __txn_detail);
+               __db_shalloc_free(tmgrp->mem, txnp);
                UNLOCK_TXNREGION(tmgrp);
                free (retp);
                return (ret);
@@ -310,6 +307,12 @@ txn_begin(tmgrp, parent, txnpp)
 
        *txnpp  = retp;
        return (0);
+
+err1:
+       __db_shalloc_free(tmgrp->mem, txnp);
+err:
+       UNLOCK_TXNREGION(tmgrp);
+       return (ret);
 }
 
 /* The db_txn(3) man page describes txn_commit. */
@@ -362,16 +365,15 @@ txn_prepare(txnp)
        int ret;
        TXN_DETAIL *tp;
 
-       ret = 0;
        if ((ret = __txn_check_running(txnp)) != 0)
                return (ret);
 
-       if (txnp->mgrp->dbenv->lg_info) {
-               ret = log_flush(txnp->mgrp->dbenv->lg_info, &txnp->last_lsn);
-               if (ret)
+       if (txnp->mgrp->dbenv->lg_info != NULL) {
+               if ((ret = log_flush(txnp->mgrp->dbenv->lg_info,
+                   &txnp->last_lsn)) != 0)
                        __db_err(txnp->mgrp->dbenv,
                            "txn_prepare: log_flush failed %s\n",
-                           strerror(errno));
+                           strerror(ret));
                return (ret);
        }
 
@@ -420,12 +422,19 @@ txn_close(tmgrp)
            ret == 0)
                ret = t_ret;
 
+       if (tmgrp->mutexp != NULL) {
+               LOCK_TXNREGION(tmgrp);
+               __db_shalloc_free(tmgrp->mem, tmgrp->mutexp);
+               UNLOCK_TXNREGION(tmgrp);
+       }
+
        if ((t_ret = __db_rclose(tmgrp->dbenv, tmgrp->fd, tmgrp->region)) != 0
            && ret == 0)
                ret = t_ret;
 
        if (ret == 0)
                free (tmgrp);
+
        return (ret);
 }
 
@@ -499,9 +508,8 @@ __txn_end(txnp, is_commit)
        /* End the transaction. */
        LOCK_TXNREGION(mgr);
        tp = (TXN_DETAIL *)((u_int8_t *)mgr->region + txnp->off);
-       tp->status = TXN_UNALLOC;
-       tp->txnid = mgr->region->free_txn;
-       mgr->region->free_txn = tp - &mgr->region->table[0];
+       SH_TAILQ_REMOVE(&mgr->region->active_txn, tp, links, __txn_detail);
+       __db_shalloc_free(mgr->mem, tp);
        if (is_commit)
                mgr->region->ncommits++;
        else
@@ -515,8 +523,9 @@ __txn_end(txnp, is_commit)
 
 
 /*
- * Undo the transaction with id txnid.  Returns 0 on success and sets
- * errno and returns -1 on failure.
+ * __txn_undo --
+ *     Undo the transaction with id txnid.  Returns 0 on success and
+ *     errno on failure.
  */
 static int
 __txn_undo(txnp)
@@ -576,12 +585,12 @@ __txn_undo(txnp)
 int
 txn_checkpoint(mgr, kbytes, minutes)
        const DB_TXNMGR *mgr;
-       long kbytes, minutes;
+       int kbytes, minutes;
 {
        TXN_DETAIL *txnp;
        DB_LSN ckp_lsn, last_ckp;
        DB_LOG *dblp;
-       u_int32_t bytes_written, i;
+       u_int32_t bytes_written;
        time_t last_ckp_time, now;
        int ret;
 
@@ -638,16 +647,16 @@ do_ckp:
        if (!IS_ZERO_LSN(mgr->region->pending_ckp))
                ckp_lsn = mgr->region->pending_ckp;
        else
-               for (txnp = &mgr->region->table[0], i = 0;
-                   i < mgr->region->maxtxns; i++, txnp++) {
+               for (txnp =
+                   SH_TAILQ_FIRST(&mgr->region->active_txn, __txn_detail);
+                   txnp != NULL;
+                   txnp = SH_TAILQ_NEXT(txnp, links, __txn_detail)) {
 
                        /*
-                        * Look through the transaction table for the LSN of
-                        * the transaction that is in-use (e.g., not
-                        * TXN_UNALLOC) and whose begin lsn is the lowest.
+                        * Look through the active transactions for the
+                        * lowest begin lsn.
                         */
-                       if (txnp->status != TXN_UNALLOC &&
-                           !IS_ZERO_LSN(txnp->begin_lsn) &&
+                       if (!IS_ZERO_LSN(txnp->begin_lsn) &&
                            log_compare(&txnp->begin_lsn, &ckp_lsn) < 0)
                                ckp_lsn = txnp->begin_lsn;
                }
@@ -707,6 +716,7 @@ __txn_validate_region(tp)
                return (ret);
 
        tp->reg_size = tp->region->hdr.size;
+       tp->mem = &tp->region[1];
 
        return (0);
 }
@@ -715,9 +725,9 @@ static int
 __txn_grow_region(tp)
        DB_TXNMGR *tp;
 {
-       TXN_DETAIL *tx;
        size_t incr;
-       u_int32_t i, oldmax;
+       u_int32_t oldmax;
+       u_int8_t *curaddr;
        int ret;
 
        oldmax = tp->region->maxtxns;
@@ -729,19 +739,17 @@ __txn_grow_region(tp)
        if ((ret = __db_rremap(tp->dbenv, tp->region,
            tp->reg_size, tp->reg_size + incr, tp->fd, &tp->region)) != 0)
                return (ret);
+
+       /* Throw the new space on the free list. */
+       curaddr = (u_int8_t *)tp->region + tp->reg_size;
+       tp->mem = &tp->region[1];
        tp->reg_size += incr;
 
-       /*
-        * Initialize all the new transactions and up the transaction count.
-        */
-       for (i = 0, tx = &tp->region->table[oldmax]; i < oldmax; i++, tx++) {
-               ZERO_LSN(tx->begin_lsn);
-               tx->status = TXN_UNALLOC;
-               tx->txnid = oldmax + i + 1;
-       }
-       tp->region->free_txn = oldmax;
+       *((size_t *)curaddr) = incr - sizeof(size_t);
+       curaddr += sizeof(size_t);
+       __db_shalloc_free(tp->mem, curaddr);
+
        tp->region->maxtxns = 2 * oldmax;
-       tp->region->table[tp->region->maxtxns - 1].txnid = TXN_INVALID;
 
        return (0);
 }
@@ -753,8 +761,9 @@ txn_stat(mgr, statp, db_malloc)
        void *(*db_malloc) __P((size_t));
 {
        DB_TXN_STAT *stats;
+       TXN_DETAIL *txnp;
        size_t nbytes;
-       u_int32_t i, nactive, ndx;
+       u_int32_t nactive, ndx;
 
        LOCK_TXNREGION(mgr);
        nactive = mgr->region->nbegins -
@@ -789,17 +798,17 @@ txn_stat(mgr, statp, db_malloc)
                stats->st_nactive = nactive + 200;
        stats->st_txnarray = (DB_TXN_ACTIVE *)&stats[1];
 
-       for (ndx = 0, i = 0; i < mgr->region->maxtxns; i++)
-               if (mgr->region->table[i].status != TXN_UNALLOC) {
-                       stats->st_txnarray[ndx].txnid =
-                           mgr->region->table[i].txnid;
-                       stats->st_txnarray[ndx].lsn =
-                           mgr->region->table[i].begin_lsn;
-                       ndx++;
+       ndx = 0;
+       for (txnp = SH_TAILQ_FIRST(&mgr->region->active_txn, __txn_detail);
+           txnp != NULL;
+           txnp = SH_TAILQ_NEXT(txnp, links, __txn_detail)) {
+               stats->st_txnarray[ndx].txnid = txnp->txnid;
+               stats->st_txnarray[ndx].lsn = txnp->begin_lsn;
+               ndx++;
 
-                       if (ndx >= stats->st_nactive)
-                               break;
-               }
+               if (ndx >= stats->st_nactive)
+                       break;
+       }
 
        UNLOCK_TXNREGION(mgr);
        *statp = stats;
index c7f277e..baef733 100644 (file)
@@ -92,7 +92,7 @@ __txn_regop_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __txn_regop_read(dbtp->data, &argp)) != 0)
+       if ((ret = __txn_regop_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]txn_regop: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,
@@ -221,7 +221,7 @@ __txn_ckp_print(notused1, dbtp, lsnp, notused3, notused4)
        notused3 = 0;
        notused4 = NULL;
 
-       if((ret = __txn_ckp_read(dbtp->data, &argp)) != 0)
+       if ((ret = __txn_ckp_read(dbtp->data, &argp)) != 0)
                return (ret);
        printf("[%lu][%lu]txn_ckp: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
            (u_long)lsnp->file,