summaryrefslogtreecommitdiff
path: root/db2
diff options
context:
space:
mode:
Diffstat (limited to 'db2')
-rw-r--r--db2/Makefile2
-rw-r--r--db2/btree/bt_close.c4
-rw-r--r--db2/btree/bt_conv.c22
-rw-r--r--db2/btree/bt_cursor.c76
-rw-r--r--db2/btree/bt_put.c4
-rw-r--r--db2/btree/bt_rec.c13
-rw-r--r--db2/btree/bt_recno.c38
-rw-r--r--db2/btree/btree.src8
-rw-r--r--db2/btree/btree_auto.c14
-rw-r--r--db2/clib/getlong.c1
-rw-r--r--db2/db.h16
-rw-r--r--db2/db/db.c73
-rw-r--r--db2/db/db_auto.c16
-rw-r--r--db2/db/db_conv.c68
-rw-r--r--db2/db/db_pr.c63
-rw-r--r--db2/db/db_ret.c9
-rw-r--r--db2/db/db_thread.c10
-rw-r--r--db2/db_185.h10
-rw-r--r--db2/db_int.h22
-rw-r--r--db2/hash/hash.c90
-rw-r--r--db2/hash/hash_auto.c14
-rw-r--r--db2/hash/hash_conv.c22
-rw-r--r--db2/hash/hash_dup.c49
-rw-r--r--db2/hash/hash_func.c6
-rw-r--r--db2/hash/hash_page.c69
-rw-r--r--db2/hash/hash_rec.c12
-rw-r--r--db2/include/btree.h8
-rw-r--r--db2/include/btree_ext.h2
-rw-r--r--db2/include/db.h.src17
-rw-r--r--db2/include/db_185.h.src10
-rw-r--r--db2/include/db_cxx.h10
-rw-r--r--db2/include/db_ext.h4
-rw-r--r--db2/include/db_int.h.src14
-rw-r--r--db2/include/db_page.h32
-rw-r--r--db2/include/db_shash.h22
-rw-r--r--db2/include/hash_ext.h3
-rw-r--r--db2/include/lock.h8
-rw-r--r--db2/include/log.h10
-rw-r--r--db2/include/log_ext.h6
-rw-r--r--db2/include/mp.h6
-rw-r--r--db2/include/shqueue.h37
-rw-r--r--db2/include/txn.h27
-rw-r--r--db2/lock/lock.c40
-rw-r--r--db2/lock/lock_deadlock.c9
-rw-r--r--db2/log/log.c104
-rw-r--r--db2/log/log_archive.c76
-rw-r--r--db2/log/log_auto.c4
-rw-r--r--db2/log/log_get.c9
-rw-r--r--db2/log/log_put.c23
-rw-r--r--db2/log/log_register.c11
-rw-r--r--db2/mp/mp_bh.c32
-rw-r--r--db2/mp/mp_fget.c10
-rw-r--r--db2/mp/mp_fopen.c78
-rw-r--r--db2/mp/mp_fput.c8
-rw-r--r--db2/mp/mp_fset.c4
-rw-r--r--db2/mp/mp_open.c41
-rw-r--r--db2/mutex/mutex.c2
-rw-r--r--db2/os/db_os_dir.c8
-rw-r--r--db2/progs/db_checkpoint/db_checkpoint.c25
-rw-r--r--db2/progs/db_deadlock/db_deadlock.c2
-rw-r--r--db2/progs/db_dump185/db_dump185.c4
-rw-r--r--db2/progs/db_load/db_load.c4
-rw-r--r--db2/progs/db_recover/db_recover.c3
-rw-r--r--db2/txn/txn.c195
-rw-r--r--db2/txn/txn_auto.c4
65 files changed, 924 insertions, 719 deletions
diff --git a/db2/Makefile b/db2/Makefile
index a75dc5aef1..e6b35aa51b 100644
--- a/db2/Makefile
+++ b/db2/Makefile
@@ -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.
#
diff --git a/db2/btree/bt_close.c b/db2/btree/bt_close.c
index 7044599dd2..7dd7139c66 100644
--- a/db2/btree/bt_close.c
+++ b/db2/btree/bt_close.c
@@ -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.
*/
diff --git a/db2/btree/bt_conv.c b/db2/btree/bt_conv.c
index c9d5d1bc3e..c89493cbed 100644
--- a/db2/btree/bt_conv.c
+++ b/db2/btree/bt_conv.c
@@ -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));
}
/*
diff --git a/db2/btree/bt_cursor.c b/db2/btree/bt_cursor.c
index efae556030..a1266bcd3c 100644
--- a/db2/btree/bt_cursor.c
+++ b/db2/btree/bt_cursor.c
@@ -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;
/*
diff --git a/db2/btree/bt_put.c b/db2/btree/bt_put.c
index 0f0b1e7126..af09f76d41 100644
--- a/db2/btree/bt_put.c
+++ b/db2/btree/bt_put.c
@@ -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) {
diff --git a/db2/btree/bt_rec.c b/db2/btree/bt_rec.c
index 07a3d93c74..9aeb395f27 100644
--- a/db2/btree/bt_rec.c
+++ b/db2/btree/bt_rec.c
@@ -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;
}
diff --git a/db2/btree/bt_recno.c b/db2/btree/bt_recno.c
index 42ef9cc30d..f7c5cffdc6 100644
--- a/db2/btree/bt_recno.c
+++ b/db2/btree/bt_recno.c
@@ -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));
diff --git a/db2/btree/btree.src b/db2/btree/btree.src
index 50cc0dd0ff..7c8c4b125f 100644
--- a/db2/btree/btree.src
+++ b/db2/btree/btree.src
@@ -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.
diff --git a/db2/btree/btree_auto.c b/db2/btree/btree_auto.c
index e6b72252e5..353ee7bc27 100644
--- a/db2/btree/btree_auto.c
+++ b/db2/btree/btree_auto.c
@@ -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,
diff --git a/db2/clib/getlong.c b/db2/clib/getlong.c
index 0cc8567081..85f4e8c9e2 100644
--- a/db2/clib/getlong.c
+++ b/db2/clib/getlong.c
@@ -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"
/*
diff --git a/db2/db.h b/db2/db.h
index c80d8e3633..6911002ed5 100644
--- 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 *));
diff --git a/db2/db/db.c b/db2/db/db.c
index 8dad5febe8..9ebe73cf6e 100644
--- a/db2/db/db.c
+++ b/db2/db/db.c
@@ -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);
diff --git a/db2/db/db_auto.c b/db2/db/db_auto.c
index 4684f1a39f..6922504383 100644
--- a/db2/db/db_auto.c
+++ b/db2/db/db_auto.c
@@ -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,
diff --git a/db2/db/db_conv.c b/db2/db/db_conv.c
index 6608005b66..8eccc2e602 100644
--- a/db2/db/db_conv.c
+++ b/db2/db/db_conv.c
@@ -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:
diff --git a/db2/db/db_pr.c b/db2/db/db_pr.c
index f86fd6770a..09d8057da4 100644
--- a/db2/db/db_pr.c
+++ b/db2/db/db_pr.c
@@ -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;
diff --git a/db2/db/db_ret.c b/db2/db/db_ret.c
index baf0665446..ee2bc82f87 100644
--- a/db2/db/db_ret.c
+++ b/db2/db/db_ret.c
@@ -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:
diff --git a/db2/db/db_thread.c b/db2/db/db_thread.c
index e956e809d9..170baf5345 100644
--- a/db2/db/db_thread.c
+++ b/db2/db/db_thread.c
@@ -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));
}
/*
diff --git a/db2/db_185.h b/db2/db_185.h
index 650d365a60..b6a4d0a12a 100644
--- a/db2/db_185.h
+++ b/db2/db_185.h
@@ -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_
@@ -72,6 +72,14 @@
#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 */
diff --git a/db2/db_int.h b/db2/db_int.h
index a088c693a8..56dfddb73f 100644
--- a/db2/db_int.h
+++ b/db2/db_int.h
@@ -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_
@@ -25,12 +25,6 @@
#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.
diff --git a/db2/hash/hash.c b/db2/hash/hash.c
index 6d8c40057d..d986e08087 100644
--- a/db2/hash/hash.c
+++ b/db2/hash/hash.c
@@ -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);
}
diff --git a/db2/hash/hash_auto.c b/db2/hash/hash_auto.c
index f8ab80c8ee..2279de9668 100644
--- a/db2/hash/hash_auto.c
+++ b/db2/hash/hash_auto.c
@@ -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,
diff --git a/db2/hash/hash_conv.c b/db2/hash/hash_conv.c
index 22901af950..9cebe72390 100644
--- a/db2/hash/hash_conv.c
+++ b/db2/hash/hash_conv.c
@@ -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));
}
/*
diff --git a/db2/hash/hash_dup.c b/db2/hash/hash_dup.c
index c9590fa49d..71bd1c5eb0 100644
--- a/db2/hash/hash_dup.c
+++ b/db2/hash/hash_dup.c
@@ -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);
}
diff --git a/db2/hash/hash_func.c b/db2/hash/hash_func.c
index 2ef47afb57..1bf12c4948 100644
--- a/db2/hash/hash_func.c
+++ b/db2/hash/hash_func.c
@@ -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);
}
diff --git a/db2/hash/hash_page.c b/db2/hash/hash_page.c
index 68c31b14f9..8ba42da1a4 100644
--- a/db2/hash/hash_page.c
+++ b/db2/hash/hash_page.c
@@ -47,10 +47,9 @@
#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);
diff --git a/db2/hash/hash_rec.c b/db2/hash/hash_rec.c
index 81d9bb5ea8..1b30be337d 100644
--- a/db2/hash/hash_rec.c
+++ b/db2/hash/hash_rec.c
@@ -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;
diff --git a/db2/include/btree.h b/db2/include/btree.h
index 5cf4224ae6..878096b7b2 100644
--- a/db2/include/btree.h
+++ b/db2/include/btree.h
@@ -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;
};
diff --git a/db2/include/btree_ext.h b/db2/include/btree_ext.h
index dab0f5be4e..9133c58c6b 100644
--- a/db2/include/btree_ext.h
+++ b/db2/include/btree_ext.h
@@ -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 *));
diff --git a/db2/include/db.h.src b/db2/include/db.h.src
index f9b29fa2af..63d9603dba 100644
--- a/db2/include/db.h.src
+++ b/db2/include/db.h.src
@@ -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 *));
diff --git a/db2/include/db_185.h.src b/db2/include/db_185.h.src
index 52fb3a0da1..3fbca8bfda 100644
--- a/db2/include/db_185.h.src
+++ b/db2/include/db_185.h.src
@@ -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_
@@ -72,6 +72,14 @@
@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 */
diff --git a/db2/include/db_cxx.h b/db2/include/db_cxx.h
index 506aed845c..611d967ef9 100644
--- a/db2/include/db_cxx.h
+++ b/db2/include/db_cxx.h
@@ -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));
diff --git a/db2/include/db_ext.h b/db2/include/db_ext.h
index 1cccb47617..b18b10ff7f 100644
--- a/db2/include/db_ext.h
+++ b/db2/include/db_ext.h
@@ -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));
diff --git a/db2/include/db_int.h.src b/db2/include/db_int.h.src
index b60e5002e5..ebadb35d36 100644
--- a/db2/include/db_int.h.src
+++ b/db2/include/db_int.h.src
@@ -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.
diff --git a/db2/include/db_page.h b/db2/include/db_page.h
index cde7ff9f2e..30f6072fc3 100644
--- a/db2/include/db_page.h
+++ b/db2/include/db_page.h
@@ -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
diff --git a/db2/include/db_shash.h b/db2/include/db_shash.h
index f695a2bafa..b94e0f1d41 100644
--- a/db2/include/db_shash.h
+++ b/db2/include/db_shash.h
@@ -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; \
\
diff --git a/db2/include/hash_ext.h b/db2/include/hash_ext.h
index 5ae63dc6ad..32788c7b8a 100644
--- a/db2/include/hash_ext.h
+++ b/db2/include/hash_ext.h
@@ -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));
diff --git a/db2/include/lock.h b/db2/include/lock.h
index 18d29e8740..8f9e81c0fa 100644
--- a/db2/include/lock.h
+++ b/db2/include/lock.h
@@ -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
/*
diff --git a/db2/include/log.h b/db2/include/log.h
index 970dfd153a..a9c82fa04d 100644
--- a/db2/include/log.h
+++ b/db2/include/log.h
@@ -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. */
};
diff --git a/db2/include/log_ext.h b/db2/include/log_ext.h
index d5c9dd6e72..bc63d9dac8 100644
--- a/db2/include/log_ext.h
+++ b/db2/include/log_ext.h
@@ -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
diff --git a/db2/include/mp.h b/db2/include/mp.h
index 1fe0c752a9..3b71774484 100644
--- a/db2/include/mp.h
+++ b/db2/include/mp.h
@@ -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. */
diff --git a/db2/include/shqueue.h b/db2/include/shqueue.h
index c3e2f4aecc..c596d33e92 100644
--- a/db2/include/shqueue.h
+++ b/db2/include/shqueue.h
@@ -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_
diff --git a/db2/include/txn.h b/db2/include/txn.h
index f4e0999b36..8bb3976c1c 100644
--- a/db2/include/txn.h
+++ b/db2/include/txn.h
@@ -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, \
diff --git a/db2/lock/lock.c b/db2/lock/lock.c
index 8fc91334a7..a2a3b208f2 100644
--- a/db2/lock/lock.c
+++ b/db2/lock/lock.c
@@ -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);
}
diff --git a/db2/lock/lock_deadlock.c b/db2/lock/lock_deadlock.c
index f753958b21..f947f901c3 100644
--- a/db2/lock/lock_deadlock.c
+++ b/db2/lock/lock_deadlock.c
@@ -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;
}
diff --git a/db2/log/log.c b/db2/log/log.c
index d3e5183588..893c1ee402 100644
--- a/db2/log/log.c
+++ b/db2/log/log.c
@@ -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);
diff --git a/db2/log/log_archive.c b/db2/log/log_archive.c
index 0d6c3f2bea..6904a2c726 100644
--- a/db2/log/log_archive.c
+++ b/db2/log/log_archive.c
@@ -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)));
diff --git a/db2/log/log_auto.c b/db2/log/log_auto.c
index 59400087ca..ea88a7bff9 100644
--- a/db2/log/log_auto.c
+++ b/db2/log/log_auto.c
@@ -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,
diff --git a/db2/log/log_get.c b/db2/log/log_get.c
index 54a58c75fc..3f6df6c33c 100644
--- a/db2/log/log_get.c
+++ b/db2/log/log_get.c
@@ -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)
diff --git a/db2/log/log_put.c b/db2/log/log_put.c
index db31f9b0e1..225595f33e 100644
--- a/db2/log/log_put.c
+++ b/db2/log/log_put.c
@@ -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));
}
diff --git a/db2/log/log_register.c b/db2/log/log_register.c
index 582eab9408..859b1e5bcb 100644
--- a/db2/log/log_register.c
+++ b/db2/log/log_register.c
@@ -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);
diff --git a/db2/mp/mp_bh.c b/db2/mp/mp_bh.c
index 3d0d053b5f..fb6bc96ae7 100644
--- a/db2/mp/mp_bh.c
+++ b/db2/mp/mp_bh.c
@@ -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);
diff --git a/db2/mp/mp_fget.c b/db2/mp/mp_fget.c
index 418802a3b9..a0364e92c3 100644
--- a/db2/mp/mp_fget.c
+++ b/db2/mp/mp_fget.c
@@ -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: /*
diff --git a/db2/mp/mp_fopen.c b/db2/mp/mp_fopen.c
index 1a770bfdf0..5ab807701c 100644
--- a/db2/mp/mp_fopen.c
+++ b/db2/mp/mp_fopen.c
@@ -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);
diff --git a/db2/mp/mp_fput.c b/db2/mp/mp_fput.c
index 5fac8ae76b..9ea7cd9d0d 100644
--- a/db2/mp/mp_fput.c
+++ b/db2/mp/mp_fput.c
@@ -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
diff --git a/db2/mp/mp_fset.c b/db2/mp/mp_fset.c
index 588085a358..a3a3dcef9c 100644
--- a/db2/mp/mp_fset.c
+++ b/db2/mp/mp_fset.c
@@ -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;
diff --git a/db2/mp/mp_open.c b/db2/mp/mp_open.c
index 257ce1b9e9..f622b1ed26 100644
--- a/db2/mp/mp_open.c
+++ b/db2/mp/mp_open.c
@@ -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);
}
diff --git a/db2/mutex/mutex.c b/db2/mutex/mutex.c
index b23f738ad7..5315b2d3fe 100644
--- a/db2/mutex/mutex.c
+++ b/db2/mutex/mutex.c
@@ -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
diff --git a/db2/os/db_os_dir.c b/db2/os/db_os_dir.c
index 6dabd62049..1206e3faa7 100644
--- a/db2/os/db_os_dir.c
+++ b/db2/os/db_os_dir.c
@@ -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);
}
diff --git a/db2/progs/db_checkpoint/db_checkpoint.c b/db2/progs/db_checkpoint/db_checkpoint.c
index 4f9b79a7ba..b2a692bba9 100644
--- a/db2/progs/db_checkpoint/db_checkpoint.c
+++ b/db2/progs/db_checkpoint/db_checkpoint.c
@@ -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);
}
/*
diff --git a/db2/progs/db_deadlock/db_deadlock.c b/db2/progs/db_deadlock/db_deadlock.c
index 09004f58b3..ec2b53dee7 100644
--- a/db2/progs/db_deadlock/db_deadlock.c
+++ b/db2/progs/db_deadlock/db_deadlock.c
@@ -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
diff --git a/db2/progs/db_dump185/db_dump185.c b/db2/progs/db_dump185/db_dump185.c
index 6e2d95bee0..5ec7673f1b 100644
--- a/db2/progs/db_dump185/db_dump185.c
+++ b/db2/progs/db_dump185/db_dump185.c
@@ -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);
diff --git a/db2/progs/db_load/db_load.c b/db2/progs/db_load/db_load.c
index 6f69216777..a1ebfa8a11 100644
--- a/db2/progs/db_load/db_load.c
+++ b/db2/progs/db_load/db_load.c
@@ -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;
diff --git a/db2/progs/db_recover/db_recover.c b/db2/progs/db_recover/db_recover.c
index d17c4b0c76..55b9b49a79 100644
--- a/db2/progs/db_recover/db_recover.c
+++ b/db2/progs/db_recover/db_recover.c
@@ -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"
diff --git a/db2/txn/txn.c b/db2/txn/txn.c
index cb700dc037..9a0d626c3e 100644
--- a/db2/txn/txn.c
+++ b/db2/txn/txn.c
@@ -43,16 +43,10 @@
#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;
diff --git a/db2/txn/txn_auto.c b/db2/txn/txn_auto.c
index c7f277ed0f..baef7333c7 100644
--- a/db2/txn/txn_auto.c
+++ b/db2/txn/txn_auto.c
@@ -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,