summaryrefslogtreecommitdiff
path: root/db/hash
diff options
context:
space:
mode:
authorjbj <devnull@localhost>2004-10-16 01:31:54 +0000
committerjbj <devnull@localhost>2004-10-16 01:31:54 +0000
commitd03f220fde879509cab2ac1c73b71b7efb52b737 (patch)
tree1e34bfadac0a6618d0e9a7933bad90063a785acf /db/hash
parent2dc699bfe049b9319ea3719f604d25940ff52004 (diff)
downloadrpm-d03f220fde879509cab2ac1c73b71b7efb52b737.tar.gz
rpm-d03f220fde879509cab2ac1c73b71b7efb52b737.tar.bz2
rpm-d03f220fde879509cab2ac1c73b71b7efb52b737.zip
... and in with the New ...
CVS patchset: 7471 CVS date: 2004/10/16 01:31:54
Diffstat (limited to 'db/hash')
-rw-r--r--db/hash/hash.c183
-rw-r--r--db/hash/hash.src10
-rw-r--r--db/hash/hash_auto.c1707
-rw-r--r--db/hash/hash_autop.c486
-rw-r--r--db/hash/hash_conv.c11
-rw-r--r--db/hash/hash_dup.c65
-rw-r--r--db/hash/hash_func.c8
-rw-r--r--db/hash/hash_meta.c53
-rw-r--r--db/hash/hash_method.c20
-rw-r--r--db/hash/hash_open.c131
-rw-r--r--db/hash/hash_page.c148
-rw-r--r--db/hash/hash_rec.c349
-rw-r--r--db/hash/hash_reclaim.c10
-rw-r--r--db/hash/hash_stat.c343
-rw-r--r--db/hash/hash_stub.c47
-rw-r--r--db/hash/hash_upgrade.c14
-rw-r--r--db/hash/hash_verify.c27
17 files changed, 1748 insertions, 1864 deletions
diff --git a/db/hash/hash.c b/db/hash/hash.c
index b1a2d8703..ed96bba1a 100644
--- a/db/hash/hash.c
+++ b/db/hash/hash.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*/
/*
@@ -38,18 +38,15 @@
* 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.
+ *
+ * $Id: hash.c,v 11.199 2004/10/11 19:38:49 ubell Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: hash.c,v 11.177 2003/10/04 01:31:58 margo Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
-#include <stdlib.h>
#include <string.h>
#endif
@@ -114,7 +111,8 @@ __ham_quick_delete(dbc)
DB_ASSERT(IS_INITIALIZED(dbc));
DB_ASSERT(((HASH_CURSOR *)dbc->internal)->opd == NULL);
- ret = __ham_del_pair(dbc, 1);
+ if ((ret = __ham_c_writelock(dbc)) == 0)
+ ret = __ham_del_pair(dbc, 1);
if ((t_ret = __ham_release_meta(dbc)) != 0 && ret == 0)
ret = t_ret;
@@ -163,9 +161,7 @@ __ham_c_init(dbc)
dbc->c_am_put = __ham_c_put;
dbc->c_am_writelock = __ham_c_writelock;
- __ham_item_init(dbc);
-
- return (0);
+ return (__ham_item_init(dbc));
}
/*
@@ -181,6 +177,7 @@ __ham_c_close(dbc, root_pgno, rmroot)
DB_MPOOLFILE *mpf;
HASH_CURSOR *hcp;
HKEYDATA *dp;
+ db_lockmode_t lock_mode;
int doroot, gotmeta, ret, t_ret;
u_int32_t dirty;
@@ -195,11 +192,19 @@ __ham_c_close(dbc, root_pgno, rmroot)
if ((ret = __ham_get_meta(dbc)) != 0)
goto done;
gotmeta = 1;
- if ((ret = __ham_get_cpage(dbc, DB_LOCK_READ)) != 0)
+ lock_mode = DB_LOCK_READ;
+
+ /* To support dirty reads we must reget the write lock. */
+ if (F_ISSET(dbc->dbp, DB_AM_DIRTY) &&
+ F_ISSET((BTREE_CURSOR *)
+ dbc->internal->opd->internal, C_DELETED))
+ lock_mode = DB_LOCK_WRITE;
+
+ if ((ret = __ham_get_cpage(dbc, lock_mode)) != 0)
goto out;
dp = (HKEYDATA *)H_PAIRDATA(dbc->dbp, hcp->page, hcp->indx);
- /* If its not a dup we aborted before we changed it. */
+ /* If it's not a dup we aborted before we changed it. */
if (HPAGE_PTYPE(dp) == H_OFFDUP)
memcpy(&root_pgno,
HOFFPAGE_PGNO(dp), sizeof(db_pgno_t));
@@ -222,8 +227,8 @@ out: if (hcp->page != NULL && (t_ret =
if (gotmeta != 0 && (t_ret = __ham_release_meta(dbc)) != 0 && ret == 0)
ret = t_ret;
-done:
- __ham_item_init(dbc);
+done: if ((t_ret = __ham_item_init(dbc)) != 0 && ret == 0)
+ ret = t_ret;
return (ret);
}
@@ -359,7 +364,7 @@ __ham_c_del(dbc)
out: if (hcp->page != NULL) {
if ((t_ret = __memp_fput(mpf,
- hcp->page, ret == 0 ? DB_MPOOL_DIRTY : 0)) && ret == 0)
+ hcp->page, ret == 0 ? DB_MPOOL_DIRTY : 0)) != 0 && ret == 0)
ret = t_ret;
hcp->page = NULL;
}
@@ -380,6 +385,7 @@ __ham_c_dup(orig_dbc, new_dbc)
DBC *orig_dbc, *new_dbc;
{
HASH_CURSOR *orig, *new;
+ int ret;
orig = (HASH_CURSOR *)orig_dbc->internal;
new = (HASH_CURSOR *)new_dbc->internal;
@@ -399,16 +405,17 @@ __ham_c_dup(orig_dbc, new_dbc)
* If the old cursor held a lock and we're not in transactions, get one
* for the new one. The reason that we don't need a new lock if we're
* in a transaction is because we already hold a lock and will continue
- * to do so until commit, so there is no point in reaquiring it. We
+ * to do so until commit, so there is no point in re-acquiring it. We
* don't know if the old lock was a read or write lock, but it doesn't
* matter. We'll get a read lock. We know that this locker already
* holds a lock of the correct type, so if we need a write lock and
* request it, we know that we'll get it.
*/
- if (!LOCK_ISSET(orig->lock) || orig_dbc->txn != NULL)
- return (0);
+ if (orig_dbc->txn == NULL && LOCK_ISSET(orig->lock))
+ if ((ret = __ham_lock_bucket(new_dbc, DB_LOCK_READ)) != 0)
+ return (ret);
- return (__ham_lock_bucket(new_dbc, DB_LOCK_READ));
+ return (0);
}
static int
@@ -493,6 +500,9 @@ __ham_c_get(dbc, key, data, flags, pgnop)
ret = __ham_item(dbc, lock_type, pgnop);
break;
+ default:
+ ret = __db_unknown_flag(dbp->dbenv, "__ham_c_get", flags);
+ break;
}
/*
@@ -605,11 +615,11 @@ __ham_bulk(dbc, data, flags)
db_indx_t dup_len, dup_off, dup_tlen, indx, *inp;
db_lockmode_t lock_mode;
db_pgno_t pgno;
- int32_t *endp, key_off, *offp, *saveoff;
- u_int32_t key_size, size, space;
+ int32_t *endp, *offp, *saveoff;
+ u_int32_t key_off, key_size, pagesize, size, space;
u_int8_t *dbuf, *dp, *hk, *np, *tmp;
int is_dup, is_key;
- int need_pg, next_key, no_dup, pagesize, ret, t_ret;
+ int need_pg, next_key, no_dup, ret, t_ret;
ret = 0;
key_off = 0;
@@ -658,7 +668,7 @@ next_pg:
dbc, key_size, pgno, np)) != 0)
return (ret);
space -= key_size;
- key_off = (int32_t)(np - dbuf);
+ key_off = (u_int32_t)(np - dbuf);
np += key_size;
} else {
if (need_pg) {
@@ -667,10 +677,11 @@ next_pg:
if (space < size) {
get_key_space:
if (offp == endp) {
- data->size =
- ALIGN(size +
+ data->size = (u_int32_t)
+ DB_ALIGN(size +
pagesize, 1024);
- return (ENOMEM);
+ return
+ (DB_BUFFER_SMALL);
}
goto back_up;
}
@@ -681,8 +692,9 @@ get_key_space:
np += size;
}
key_size = LEN_HKEY(dbp, pg, pagesize, indx);
- key_off = (int32_t)(inp[indx] - HOFFSET(pg)
- + dp - dbuf + SSZA(HKEYDATA, data));
+ key_off = ((inp[indx] - HOFFSET(pg)) +
+ (u_int32_t)(dp - dbuf)) +
+ SSZA(HKEYDATA, data);
}
}
@@ -768,9 +780,10 @@ get_space:
*/
if (offp >= endp ||
F_ISSET(dbc, DBC_TRANSIENT)) {
- data->size = ALIGN(size +
+ data->size = (u_int32_t)
+ DB_ALIGN(size +
data->ulen - space, 1024);
- return (ENOMEM);
+ return (DB_BUFFER_SMALL);
}
/*
* Don't continue; we're all out
@@ -839,17 +852,18 @@ get_space:
if (space > data->ulen) {
if (!is_dup || dup_off == 0)
goto back_up;
- dup_off -= (db_indx_t)DUP_SIZE(offp[1]);
+ dup_off -= (db_indx_t)
+ DUP_SIZE((u_int32_t)offp[1]);
goto get_space;
}
if (is_key) {
- *offp-- = key_off;
- *offp-- = key_size;
+ *offp-- = (int32_t)key_off;
+ *offp-- = (int32_t)key_size;
}
if (is_dup) {
*offp-- = (int32_t)(
- inp[indx + 1] - HOFFSET(pg) +
- dp - dbuf + SSZA(HKEYDATA, data) +
+ ((inp[indx + 1] - HOFFSET(pg)) +
+ dp - dbuf) + SSZA(HKEYDATA, data) +
dup_off + sizeof(db_indx_t));
memcpy(&dup_len,
HKEYDATA_DATA(hk) + dup_off,
@@ -858,8 +872,8 @@ get_space:
*offp-- = dup_len;
} else {
*offp-- = (int32_t)(
- inp[indx + 1] - HOFFSET(pg) +
- dp - dbuf + SSZA(HKEYDATA, data));
+ ((inp[indx + 1] - HOFFSET(pg)) +
+ dp - dbuf) + SSZA(HKEYDATA, data));
*offp-- = LEN_HDATA(dbp, pg,
pagesize, indx);
}
@@ -876,14 +890,14 @@ get_space:
space -= 2 * sizeof(*offp);
if (space > data->ulen)
goto back_up;
- *offp-- = key_off;
- *offp-- = key_size;
+ *offp-- = (int32_t)key_off;
+ *offp-- = (int32_t)key_size;
}
saveoff = offp;
if ((ret = __bam_bulk_duplicates(dbc,
pgno, dbuf, is_key ? offp + 2 : NULL,
&offp, &np, &space, no_dup)) != 0) {
- if (ret == ENOMEM) {
+ if (ret == DB_BUFFER_SMALL) {
size = space;
space = 0;
if (is_key && saveoff == offp) {
@@ -910,16 +924,19 @@ get_space:
return (ret);
if (is_key) {
- *offp-- = key_off;
- *offp-- = key_size;
+ *offp-- = (int32_t)key_off;
+ *offp-- = (int32_t)key_size;
}
*offp-- = (int32_t)(np - dbuf);
- *offp-- = size;
+ *offp-- = (int32_t)size;
np += size;
space -= size;
break;
+ default:
+ /* Do nothing. */
+ break;
}
} while (next_key && (indx += 2) < NUM_ENT(pg));
@@ -973,7 +990,7 @@ get_space:
if (ret != DB_NOTFOUND)
return (ret);
}
- *offp = (u_int32_t) -1;
+ *offp = -1;
return (0);
}
@@ -1060,6 +1077,9 @@ __ham_c_put(dbc, key, data, flags, pgnop)
case DB_CURRENT:
ret = __ham_item(dbc, DB_LOCK_WRITE, pgnop);
break;
+ default:
+ ret = __db_unknown_flag(dbp->dbenv, "__ham_c_put", flags);
+ break;
}
if (*pgnop == PGNO_INVALID && ret == 0) {
@@ -1072,15 +1092,19 @@ __ham_c_put(dbc, key, data, flags, pgnop)
ret = __ham_add_dup(dbc, data, flags, pgnop);
}
-done: if (ret == 0 && F_ISSET(hcp, H_EXPAND)) {
+done: if (hcp->page != NULL) {
+ if ((t_ret = __memp_fput(mpf,
+ hcp->page, DB_MPOOL_DIRTY)) != 0 && ret == 0)
+ ret = t_ret;
+ if (t_ret == 0)
+ hcp->page = NULL;
+ }
+
+ if (ret == 0 && F_ISSET(hcp, H_EXPAND)) {
ret = __ham_expand_table(dbc);
F_CLR(hcp, H_EXPAND);
}
- if (hcp->page != NULL && (t_ret =
- __memp_fset(mpf, hcp->page, DB_MPOOL_DIRTY)) != 0 && ret == 0)
- ret = t_ret;
-
err2: if ((t_ret = __ham_release_meta(dbc)) != 0 && ret == 0)
ret = t_ret;
@@ -1104,8 +1128,8 @@ __ham_expand_table(dbc)
HASH_CURSOR *hcp;
PAGE *h;
db_pgno_t pgno, mpgno;
- u_int32_t newalloc, new_bucket, old_bucket;
- int dirty_meta, got_meta, logn, new_double, ret;
+ u_int32_t dirty_meta, logn, newalloc, new_bucket, old_bucket;
+ int got_meta, new_double, ret, t_ret;
dbp = dbc->dbp;
mpf = dbp->mpf;
@@ -1117,9 +1141,8 @@ __ham_expand_table(dbc)
mmeta = (DBMETA *) hcp->hdr;
mpgno = mmeta->pgno;
h = NULL;
- dirty_meta = 0;
+ dirty_meta = newalloc = 0;
got_meta = 0;
- newalloc = 0;
/*
* If the split point is about to increase, make sure that we
@@ -1180,7 +1203,7 @@ __ham_expand_table(dbc)
if ((ret = __ham_metagroup_log(dbp, dbc->txn,
&lsn, 0, hcp->hdr->max_bucket, mpgno, &mmeta->lsn,
hcp->hdr->dbmeta.pgno, &hcp->hdr->dbmeta.lsn,
- pgno, &lsn, newalloc)) != 0)
+ pgno, &lsn, newalloc, mmeta->last_pgno)) != 0)
goto err;
} else
LSN_NOT_LOGGED(lsn);
@@ -1231,30 +1254,31 @@ __ham_expand_table(dbc)
ret = __ham_split_page(dbc, old_bucket, new_bucket);
err: if (got_meta)
- (void)__memp_fput(mpf, mmeta, dirty_meta);
-
- if (LOCK_ISSET(metalock))
- (void)__TLPUT(dbc, metalock);
-
+ if ((t_ret =
+ __memp_fput(mpf, mmeta, dirty_meta)) != 0 && ret == 0)
+ ret = t_ret;
+ if ((t_ret = __TLPUT(dbc, metalock)) != 0 && ret == 0)
+ ret = t_ret;
if (h != NULL)
- (void)__memp_fput(mpf, h, 0);
+ if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
+ ret = t_ret;
return (ret);
}
/*
- * PUBLIC: u_int32_t __ham_call_hash __P((DBC *, u_int8_t *, int32_t));
+ * PUBLIC: u_int32_t __ham_call_hash __P((DBC *, u_int8_t *, u_int32_t));
*/
u_int32_t
__ham_call_hash(dbc, k, len)
DBC *dbc;
u_int8_t *k;
- int32_t len;
+ u_int32_t len;
{
DB *dbp;
- u_int32_t n, bucket;
HASH_CURSOR *hcp;
HASH *hashp;
+ u_int32_t n, bucket;
dbp = dbc->dbp;
hcp = (HASH_CURSOR *)dbc->internal;
@@ -1512,7 +1536,7 @@ __ham_overwrite(dbc, nval, flags)
*/
if (nval->doff > nondup_size)
newsize +=
- (nval->doff - nondup_size + nval->size);
+ ((nval->doff - nondup_size) + nval->size);
else if (nval->doff + nval->dlen > nondup_size)
newsize += nval->size -
(nondup_size - nval->doff);
@@ -1524,7 +1548,8 @@ __ham_overwrite(dbc, nval, flags)
* the onpage duplicate size in which case we need
* to convert to off-page duplicates.
*/
- if (ISBIG(hcp, hcp->dup_tlen - nondup_size + newsize)) {
+ if (ISBIG(hcp,
+ (hcp->dup_tlen - nondup_size) + newsize)) {
if ((ret = __ham_dup_convert(dbc)) != 0)
return (ret);
return (hcp->opd->c_am_put(hcp->opd,
@@ -1561,7 +1586,7 @@ __ham_overwrite(dbc, nval, flags)
/* End of original record (if there is any) */
if (nval->doff + nval->dlen < tmp_val.size) {
- len = tmp_val.size - nval->doff - nval->dlen;
+ len = (tmp_val.size - nval->doff) - nval->dlen;
memcpy(p, (u_int8_t *)tmp_val.data +
nval->doff + nval->dlen, len);
p += len;
@@ -1580,7 +1605,7 @@ __ham_overwrite(dbc, nval, flags)
tmp_val2.size = newsize;
if (dbp->dup_compare(
dbp, &tmp_val, &tmp_val2) != 0) {
- (void)__os_free(dbenv, newrec);
+ __os_free(dbenv, newrec);
return (__db_duperr(dbp, flags));
}
}
@@ -1591,7 +1616,7 @@ __ham_overwrite(dbc, nval, flags)
tmp_val2.dlen = DUP_SIZE(hcp->dup_len);
ret = __ham_replpair(dbc, &tmp_val2, 0);
- (void)__os_free(dbenv, newrec);
+ __os_free(dbenv, newrec);
/* Update cursor */
if (ret != 0)
@@ -1606,7 +1631,7 @@ __ham_overwrite(dbc, nval, flags)
} else {
/* Check whether we need to convert to off page. */
if (ISBIG(hcp,
- hcp->dup_tlen - hcp->dup_len + nval->size)) {
+ (hcp->dup_tlen - hcp->dup_len) + nval->size)) {
if ((ret = __ham_dup_convert(dbc)) != 0)
return (ret);
return (hcp->opd->c_am_put(hcp->opd,
@@ -1744,6 +1769,8 @@ found_key: F_SET(hcp, H_OK);
* duplicated, only data items are.
*/
return (__db_pgfmt(dbp->dbenv, PGNO(hcp->page)));
+ default:
+ return (__db_pgfmt(dbp->dbenv, PGNO(hcp->page)));
}
}
@@ -1998,7 +2025,8 @@ __ham_get_clist(dbp, pgno, indx, listp)
DB *ldbp;
DBC *cp;
DB_ENV *dbenv;
- int nalloc, nused, ret;
+ u_int nalloc, nused;
+ int ret;
/*
* Assume that finding anything is the exception, so optimize for
@@ -2057,7 +2085,6 @@ static int
__ham_c_writelock(dbc)
DBC *dbc;
{
- DB_ENV *dbenv;
DB_LOCK tmp_lock;
HASH_CURSOR *hcp;
int ret;
@@ -2070,14 +2097,12 @@ __ham_c_writelock(dbc)
return (0);
hcp = (HASH_CURSOR *)dbc->internal;
- if ((!LOCK_ISSET(hcp->lock) || hcp->lock_mode == DB_LOCK_READ)) {
+ ret = 0;
+ if ((!LOCK_ISSET(hcp->lock) || hcp->lock_mode != DB_LOCK_WRITE)) {
tmp_lock = hcp->lock;
- if ((ret = __ham_lock_bucket(dbc, DB_LOCK_WRITE)) != 0)
- return (ret);
- dbenv = dbc->dbp->dbenv;
- if (LOCK_ISSET(tmp_lock) &&
- (ret = __lock_put(dbenv, &tmp_lock)) != 0)
- return (ret);
+ if ((ret = __ham_lock_bucket(dbc, DB_LOCK_WRITE)) == 0
+ && tmp_lock.mode != DB_LOCK_WWRITE)
+ ret = __LPUT(dbc, tmp_lock);
}
- return (0);
+ return (ret);
}
diff --git a/db/hash/hash.src b/db/hash/hash.src
index 246ae847d..4acff5e59 100644
--- a/db/hash/hash.src
+++ b/db/hash/hash.src
@@ -1,10 +1,10 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*
- * $Id: hash.src,v 10.41 2003/11/14 05:32:37 ubell Exp $
+ * $Id: hash.src,v 10.44 2004/06/17 17:35:21 bostic Exp $
*/
/*
* Copyright (c) 1995, 1996
@@ -45,8 +45,6 @@
PREFIX __ham
DBPRIVATE
-INCLUDE #include "db_config.h"
-INCLUDE
INCLUDE #ifndef NO_SYSTEM_INCLUDES
INCLUDE #include <sys/types.h>
INCLUDE
@@ -184,6 +182,7 @@ END
* newalloc: 1 indicates that this record did the actual allocation;
* 0 indicates that the pages were already allocated from a
* previous (failed) allocation.
+ * last_pgno: the last page in the file before this op.
*/
BEGIN metagroup 29
DB fileid int32_t ld
@@ -195,6 +194,7 @@ POINTER metalsn DB_LSN * lu
ARG pgno db_pgno_t lu
POINTER pagelsn DB_LSN * lu
ARG newalloc u_int32_t lu
+ARG last_pgno db_pgno_t lu
END
/*
@@ -208,6 +208,7 @@ END
* metalsn: meta-data lsn
* start_pgno: starting page number
* num: number of allocated pages
+ * last_pgno: the last page in the file before this op.
*/
BEGIN groupalloc 32
DB fileid int32_t ld
@@ -215,6 +216,7 @@ POINTER meta_lsn DB_LSN * lu
ARG start_pgno db_pgno_t lu
ARG num u_int32_t lu
ARG free db_pgno_t lu
+ARG last_pgno db_pgno_t lu
END
/*
diff --git a/db/hash/hash_auto.c b/db/hash/hash_auto.c
index b8f217a79..49a126a75 100644
--- a/db/hash/hash_auto.c
+++ b/db/hash/hash_auto.c
@@ -1,4 +1,5 @@
/* Do not edit: automatically built by gen_rec.awk. */
+
#include "db_config.h"
#ifndef NO_SYSTEM_INCLUDES
@@ -40,33 +41,42 @@ __ham_insdel_log(dbp, txnid, ret_lsnp, flags,
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t zero, uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___ham_insdel;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -85,27 +95,23 @@ __ham_insdel_log(dbp, txnid, ret_lsnp, flags,
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -172,140 +178,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
-#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__ham_insdel_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __ham_insdel_getpgnos __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__ham_insdel_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __ham_insdel_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__ham_insdel_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __ham_insdel_args *argp;
- u_int32_t i;
- int ch;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __ham_insdel_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__ham_insdel%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\topcode: %lu\n", (u_long)argp->opcode);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
- (void)printf("\tndx: %lu\n", (u_long)argp->ndx);
- (void)printf("\tpagelsn: [%lu][%lu]\n",
- (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
- (void)printf("\tkey: ");
- for (i = 0; i < argp->key.size; i++) {
- ch = ((u_int8_t *)argp->key.data)[i];
- printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
- }
- (void)printf("\n");
- (void)printf("\tdata: ");
- for (i = 0; i < argp->data.size; i++) {
- ch = ((u_int8_t *)argp->data.data)[i];
- printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
- }
- (void)printf("\n");
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __ham_insdel_read __P((DB_ENV *, void *, __ham_insdel_args **));
*/
@@ -323,9 +236,9 @@ __ham_insdel_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__ham_insdel_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -394,33 +307,42 @@ __ham_newpage_log(dbp, txnid, ret_lsnp, flags,
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___ham_newpage;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -440,27 +362,23 @@ __ham_newpage_log(dbp, txnid, ret_lsnp, flags,
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -521,131 +439,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
-#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__ham_newpage_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __ham_newpage_getpgnos __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__ham_newpage_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __ham_newpage_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__ham_newpage_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __ham_newpage_args *argp;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __ham_newpage_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__ham_newpage%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\topcode: %lu\n", (u_long)argp->opcode);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tprev_pgno: %lu\n", (u_long)argp->prev_pgno);
- (void)printf("\tprevlsn: [%lu][%lu]\n",
- (u_long)argp->prevlsn.file, (u_long)argp->prevlsn.offset);
- (void)printf("\tnew_pgno: %lu\n", (u_long)argp->new_pgno);
- (void)printf("\tpagelsn: [%lu][%lu]\n",
- (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
- (void)printf("\tnext_pgno: %lu\n", (u_long)argp->next_pgno);
- (void)printf("\tnextlsn: [%lu][%lu]\n",
- (u_long)argp->nextlsn.file, (u_long)argp->nextlsn.offset);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __ham_newpage_read __P((DB_ENV *, void *,
* PUBLIC: __ham_newpage_args **));
@@ -664,9 +498,9 @@ __ham_newpage_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__ham_newpage_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -727,33 +561,42 @@ __ham_splitdata_log(dbp, txnid, ret_lsnp, flags, opcode, pgno, pageimage, pagels
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t zero, uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___ham_splitdata;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -770,27 +613,23 @@ __ham_splitdata_log(dbp, txnid, ret_lsnp, flags, opcode, pgno, pageimage, pagels
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -842,133 +681,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
-#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__ham_splitdata_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __ham_splitdata_getpgnos __P((DB_ENV *, DBT *,
- * PUBLIC: DB_LSN *, db_recops, void *));
- */
-int
-__ham_splitdata_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __ham_splitdata_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__ham_splitdata_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __ham_splitdata_args *argp;
- u_int32_t i;
- int ch;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __ham_splitdata_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__ham_splitdata%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\topcode: %lu\n", (u_long)argp->opcode);
- (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
- (void)printf("\tpageimage: ");
- for (i = 0; i < argp->pageimage.size; i++) {
- ch = ((u_int8_t *)argp->pageimage.data)[i];
- printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
- }
- (void)printf("\n");
- (void)printf("\tpagelsn: [%lu][%lu]\n",
- (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __ham_splitdata_read __P((DB_ENV *, void *,
* PUBLIC: __ham_splitdata_args **));
@@ -987,9 +740,9 @@ __ham_splitdata_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__ham_splitdata_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -1047,33 +800,42 @@ __ham_replace_log(dbp, txnid, ret_lsnp, flags, pgno, ndx, pagelsn, off, olditem,
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t zero, uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___ham_replace;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -1093,27 +855,23 @@ __ham_replace_log(dbp, txnid, ret_lsnp, flags, pgno, ndx, pagelsn, off, olditem,
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -1184,141 +942,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
-#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__ham_replace_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __ham_replace_getpgnos __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__ham_replace_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __ham_replace_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__ham_replace_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __ham_replace_args *argp;
- u_int32_t i;
- int ch;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __ham_replace_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__ham_replace%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
- (void)printf("\tndx: %lu\n", (u_long)argp->ndx);
- (void)printf("\tpagelsn: [%lu][%lu]\n",
- (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
- (void)printf("\toff: %ld\n", (long)argp->off);
- (void)printf("\tolditem: ");
- for (i = 0; i < argp->olditem.size; i++) {
- ch = ((u_int8_t *)argp->olditem.data)[i];
- printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
- }
- (void)printf("\n");
- (void)printf("\tnewitem: ");
- for (i = 0; i < argp->newitem.size; i++) {
- ch = ((u_int8_t *)argp->newitem.data)[i];
- printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
- }
- (void)printf("\n");
- (void)printf("\tmakedup: %lu\n", (u_long)argp->makedup);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __ham_replace_read __P((DB_ENV *, void *,
* PUBLIC: __ham_replace_args **));
@@ -1337,9 +1001,9 @@ __ham_replace_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__ham_replace_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -1411,33 +1075,42 @@ __ham_copypage_log(dbp, txnid, ret_lsnp, flags, pgno, pagelsn, next_pgno, nextls
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t zero, uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___ham_copypage;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -1457,27 +1130,23 @@ __ham_copypage_log(dbp, txnid, ret_lsnp, flags, pgno, pagelsn, next_pgno, nextls
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -1545,138 +1214,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
-#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__ham_copypage_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __ham_copypage_getpgnos __P((DB_ENV *, DBT *,
- * PUBLIC: DB_LSN *, db_recops, void *));
- */
-int
-__ham_copypage_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __ham_copypage_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__ham_copypage_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __ham_copypage_args *argp;
- u_int32_t i;
- int ch;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __ham_copypage_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__ham_copypage%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
- (void)printf("\tpagelsn: [%lu][%lu]\n",
- (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
- (void)printf("\tnext_pgno: %lu\n", (u_long)argp->next_pgno);
- (void)printf("\tnextlsn: [%lu][%lu]\n",
- (u_long)argp->nextlsn.file, (u_long)argp->nextlsn.offset);
- (void)printf("\tnnext_pgno: %lu\n", (u_long)argp->nnext_pgno);
- (void)printf("\tnnextlsn: [%lu][%lu]\n",
- (u_long)argp->nnextlsn.file, (u_long)argp->nnextlsn.offset);
- (void)printf("\tpage: ");
- for (i = 0; i < argp->page.size; i++) {
- ch = ((u_int8_t *)argp->page.data)[i];
- printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
- }
- (void)printf("\n");
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __ham_copypage_read __P((DB_ENV *, void *,
* PUBLIC: __ham_copypage_args **));
@@ -1695,9 +1273,9 @@ __ham_copypage_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__ham_copypage_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -1745,11 +1323,11 @@ __ham_copypage_read(dbenv, recbuf, argpp)
/*
* PUBLIC: int __ham_metagroup_log __P((DB *, DB_TXN *, DB_LSN *,
* PUBLIC: u_int32_t, u_int32_t, db_pgno_t, DB_LSN *, db_pgno_t, DB_LSN *,
- * PUBLIC: db_pgno_t, DB_LSN *, u_int32_t));
+ * PUBLIC: db_pgno_t, DB_LSN *, u_int32_t, db_pgno_t));
*/
int
__ham_metagroup_log(dbp, txnid, ret_lsnp, flags, bucket, mmpgno, mmetalsn, mpgno, metalsn,
- pgno, pagelsn, newalloc)
+ pgno, pagelsn, newalloc, last_pgno)
DB *dbp;
DB_TXN *txnid;
DB_LSN *ret_lsnp;
@@ -1762,37 +1340,47 @@ __ham_metagroup_log(dbp, txnid, ret_lsnp, flags, bucket, mmpgno, mmetalsn, mpgno
db_pgno_t pgno;
DB_LSN * pagelsn;
u_int32_t newalloc;
+ db_pgno_t last_pgno;
{
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___ham_metagroup;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -1806,6 +1394,7 @@ __ham_metagroup_log(dbp, txnid, ret_lsnp, flags, bucket, mmpgno, mmetalsn, mpgno
+ sizeof(*metalsn)
+ sizeof(u_int32_t)
+ sizeof(*pagelsn)
+ + sizeof(u_int32_t)
+ sizeof(u_int32_t);
if (CRYPTO_ON(dbenv)) {
npad =
@@ -1813,27 +1402,23 @@ __ham_metagroup_log(dbp, txnid, ret_lsnp, flags, bucket, mmpgno, mmetalsn, mpgno
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -1896,134 +1481,53 @@ do_malloc:
memcpy(bp, &uinttmp, sizeof(uinttmp));
bp += sizeof(uinttmp);
+ uinttmp = (u_int32_t)last_pgno;
+ memcpy(bp, &uinttmp, sizeof(uinttmp));
+ bp += sizeof(uinttmp);
+
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
-#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__ham_metagroup_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __ham_metagroup_getpgnos __P((DB_ENV *, DBT *,
- * PUBLIC: DB_LSN *, db_recops, void *));
- */
-int
-__ham_metagroup_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __ham_metagroup_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__ham_metagroup_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __ham_metagroup_args *argp;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __ham_metagroup_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__ham_metagroup%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tbucket: %lu\n", (u_long)argp->bucket);
- (void)printf("\tmmpgno: %lu\n", (u_long)argp->mmpgno);
- (void)printf("\tmmetalsn: [%lu][%lu]\n",
- (u_long)argp->mmetalsn.file, (u_long)argp->mmetalsn.offset);
- (void)printf("\tmpgno: %lu\n", (u_long)argp->mpgno);
- (void)printf("\tmetalsn: [%lu][%lu]\n",
- (u_long)argp->metalsn.file, (u_long)argp->metalsn.offset);
- (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
- (void)printf("\tpagelsn: [%lu][%lu]\n",
- (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
- (void)printf("\tnewalloc: %lu\n", (u_long)argp->newalloc);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __ham_metagroup_read __P((DB_ENV *, void *,
* PUBLIC: __ham_metagroup_args **));
@@ -2042,9 +1546,9 @@ __ham_metagroup_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__ham_metagroup_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -2087,16 +1591,21 @@ __ham_metagroup_read(dbenv, recbuf, argpp)
argp->newalloc = (u_int32_t)uinttmp;
bp += sizeof(uinttmp);
+ memcpy(&uinttmp, bp, sizeof(uinttmp));
+ argp->last_pgno = (db_pgno_t)uinttmp;
+ bp += sizeof(uinttmp);
+
*argpp = argp;
return (0);
}
/*
* PUBLIC: int __ham_groupalloc_log __P((DB *, DB_TXN *, DB_LSN *,
- * PUBLIC: u_int32_t, DB_LSN *, db_pgno_t, u_int32_t, db_pgno_t));
+ * PUBLIC: u_int32_t, DB_LSN *, db_pgno_t, u_int32_t, db_pgno_t,
+ * PUBLIC: db_pgno_t));
*/
int
-__ham_groupalloc_log(dbp, txnid, ret_lsnp, flags, meta_lsn, start_pgno, num, free)
+__ham_groupalloc_log(dbp, txnid, ret_lsnp, flags, meta_lsn, start_pgno, num, free, last_pgno)
DB *dbp;
DB_TXN *txnid;
DB_LSN *ret_lsnp;
@@ -2105,37 +1614,47 @@ __ham_groupalloc_log(dbp, txnid, ret_lsnp, flags, meta_lsn, start_pgno, num, fre
db_pgno_t start_pgno;
u_int32_t num;
db_pgno_t free;
+ db_pgno_t last_pgno;
{
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___ham_groupalloc;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -2145,6 +1664,7 @@ __ham_groupalloc_log(dbp, txnid, ret_lsnp, flags, meta_lsn, start_pgno, num, fre
+ sizeof(*meta_lsn)
+ sizeof(u_int32_t)
+ sizeof(u_int32_t)
+ + sizeof(u_int32_t)
+ sizeof(u_int32_t);
if (CRYPTO_ON(dbenv)) {
npad =
@@ -2152,27 +1672,23 @@ __ham_groupalloc_log(dbp, txnid, ret_lsnp, flags, meta_lsn, start_pgno, num, fre
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -2215,128 +1731,53 @@ do_malloc:
memcpy(bp, &uinttmp, sizeof(uinttmp));
bp += sizeof(uinttmp);
+ uinttmp = (u_int32_t)last_pgno;
+ memcpy(bp, &uinttmp, sizeof(uinttmp));
+ bp += sizeof(uinttmp);
+
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
-#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__ham_groupalloc_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __ham_groupalloc_getpgnos __P((DB_ENV *, DBT *,
- * PUBLIC: DB_LSN *, db_recops, void *));
- */
-int
-__ham_groupalloc_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __ham_groupalloc_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__ham_groupalloc_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __ham_groupalloc_args *argp;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __ham_groupalloc_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__ham_groupalloc%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tmeta_lsn: [%lu][%lu]\n",
- (u_long)argp->meta_lsn.file, (u_long)argp->meta_lsn.offset);
- (void)printf("\tstart_pgno: %lu\n", (u_long)argp->start_pgno);
- (void)printf("\tnum: %lu\n", (u_long)argp->num);
- (void)printf("\tfree: %lu\n", (u_long)argp->free);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __ham_groupalloc_read __P((DB_ENV *, void *,
* PUBLIC: __ham_groupalloc_args **));
@@ -2355,9 +1796,9 @@ __ham_groupalloc_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__ham_groupalloc_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -2386,6 +1827,10 @@ __ham_groupalloc_read(dbenv, recbuf, argpp)
argp->free = (db_pgno_t)uinttmp;
bp += sizeof(uinttmp);
+ memcpy(&uinttmp, bp, sizeof(uinttmp));
+ argp->last_pgno = (db_pgno_t)uinttmp;
+ bp += sizeof(uinttmp);
+
*argpp = argp;
return (0);
}
@@ -2413,33 +1858,42 @@ __ham_curadj_log(dbp, txnid, ret_lsnp, flags, pgno, indx, len, dup_off, add,
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___ham_curadj;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -2459,27 +1913,23 @@ __ham_curadj_log(dbp, txnid, ret_lsnp, flags, pgno, indx, len, dup_off, add,
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -2534,128 +1984,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
-#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__ham_curadj_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __ham_curadj_getpgnos __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__ham_curadj_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __ham_curadj_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__ham_curadj_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __ham_curadj_args *argp;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __ham_curadj_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__ham_curadj%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
- (void)printf("\tindx: %lu\n", (u_long)argp->indx);
- (void)printf("\tlen: %lu\n", (u_long)argp->len);
- (void)printf("\tdup_off: %lu\n", (u_long)argp->dup_off);
- (void)printf("\tadd: %ld\n", (long)argp->add);
- (void)printf("\tis_dup: %ld\n", (long)argp->is_dup);
- (void)printf("\torder: %lu\n", (u_long)argp->order);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __ham_curadj_read __P((DB_ENV *, void *, __ham_curadj_args **));
*/
@@ -2673,9 +2042,9 @@ __ham_curadj_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__ham_curadj_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -2741,33 +2110,42 @@ __ham_chgpg_log(dbp, txnid, ret_lsnp, flags, mode, old_pgno, new_pgno, old_indx,
DBT logrec;
DB_ENV *dbenv;
DB_TXNLOGREC *lr;
- DB_LSN *lsnp, null_lsn;
+ DB_LSN *lsnp, null_lsn, *rlsnp;
u_int32_t uinttmp, rectype, txn_num;
u_int npad;
u_int8_t *bp;
int is_durable, ret;
dbenv = dbp->dbenv;
+ COMPQUIET(lr, NULL);
+
rectype = DB___ham_chgpg;
npad = 0;
+ rlsnp = ret_lsnp;
+
+ ret = 0;
- is_durable = 1;
if (LF_ISSET(DB_LOG_NOT_DURABLE) ||
- F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) ||
F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
- if (F_ISSET(dbenv, DB_ENV_TXN_NOT_DURABLE) && txnid == NULL)
- return (0);
is_durable = 0;
- }
+ } else
+ is_durable = 1;
+
if (txnid == NULL) {
txn_num = 0;
- null_lsn.file = 0;
- null_lsn.offset = 0;
lsnp = &null_lsn;
+ null_lsn.file = null_lsn.offset = 0;
} else {
if (TAILQ_FIRST(&txnid->kids) != NULL &&
(ret = __txn_activekids(dbenv, rectype, txnid)) != 0)
return (ret);
+ /*
+ * We need to assign begin_lsn while holding region mutex.
+ * That assignment is done inside the DbEnv->log_put call,
+ * so pass in the appropriate memory location to be filled
+ * in by the log_put code.
+ */
+ DB_SET_BEGIN_LSNP(txnid, &rlsnp);
txn_num = txnid->txnid;
lsnp = &txnid->last_lsn;
}
@@ -2785,27 +2163,23 @@ __ham_chgpg_log(dbp, txnid, ret_lsnp, flags, mode, old_pgno, new_pgno, old_indx,
logrec.size += npad;
}
- if (!is_durable && txnid != NULL) {
+ if (is_durable || txnid == NULL) {
+ if ((ret =
+ __os_malloc(dbenv, logrec.size, &logrec.data)) != 0)
+ return (ret);
+ } else {
if ((ret = __os_malloc(dbenv,
logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
return (ret);
#ifdef DIAGNOSTIC
- goto do_malloc;
-#else
- logrec.data = &lr->data;
-#endif
- } else {
-#ifdef DIAGNOSTIC
-do_malloc:
-#endif
if ((ret =
__os_malloc(dbenv, logrec.size, &logrec.data)) != 0) {
-#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL)
- (void)__os_free(dbenv, lr);
-#endif
+ __os_free(dbenv, lr);
return (ret);
}
+#else
+ logrec.data = lr->data;
+#endif
}
if (npad > 0)
memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
@@ -2852,126 +2226,47 @@ do_malloc:
DB_ASSERT((u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
+ if (is_durable || txnid == NULL) {
+ if ((ret = __log_put(dbenv, rlsnp,(DBT *)&logrec,
+ flags | DB_LOG_NOCOPY)) == 0 && txnid != NULL) {
+ txnid->last_lsn = *rlsnp;
+ if (rlsnp != ret_lsnp)
+ *ret_lsnp = *rlsnp;
+ }
+ } else {
#ifdef DIAGNOSTIC
- if (!is_durable && txnid != NULL) {
- /*
- * We set the debug bit if we are going
- * to log non-durable transactions so
- * they will be ignored by recovery.
+ /*
+ * Set the debug bit if we are going to log non-durable
+ * transactions so they will be ignored by recovery.
*/
memcpy(lr->data, logrec.data, logrec.size);
rectype |= DB_debug_FLAG;
memcpy(logrec.data, &rectype, sizeof(rectype));
- }
-#endif
- if (!is_durable && txnid != NULL) {
+ ret = __log_put(dbenv,
+ rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
+#else
ret = 0;
- STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
-#ifdef DIAGNOSTIC
- goto do_put;
-#endif
- } else{
-#ifdef DIAGNOSTIC
-do_put:
#endif
- ret = __log_put(dbenv,
- ret_lsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
- if (ret == 0 && txnid != NULL)
- txnid->last_lsn = *ret_lsnp;
+ STAILQ_INSERT_HEAD(&txnid->logs, lr, links);
+ LSN_NOT_LOGGED(*ret_lsnp);
}
- if (!is_durable)
- LSN_NOT_LOGGED(*ret_lsnp);
#ifdef LOG_DIAGNOSTIC
if (ret != 0)
(void)__ham_chgpg_print(dbenv,
(DBT *)&logrec, ret_lsnp, NULL, NULL);
#endif
-#ifndef DIAGNOSTIC
+
+#ifdef DIAGNOSTIC
+ __os_free(dbenv, logrec.data);
+#else
if (is_durable || txnid == NULL)
-#endif
__os_free(dbenv, logrec.data);
-
+#endif
return (ret);
}
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __ham_chgpg_getpgnos __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__ham_chgpg_getpgnos(dbenv, rec, lsnp, notused1, summary)
- DB_ENV *dbenv;
- DBT *rec;
- DB_LSN *lsnp;
- db_recops notused1;
- void *summary;
-{
- TXN_RECS *t;
- int ret;
- COMPQUIET(rec, NULL);
- COMPQUIET(notused1, DB_TXN_ABORT);
-
- t = (TXN_RECS *)summary;
-
- if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)
- return (ret);
-
- t->array[t->npages].flags = LSN_PAGE_NOLOCK;
- t->array[t->npages].lsn = *lsnp;
- t->array[t->npages].fid = DB_LOGFILEID_INVALID;
- memset(&t->array[t->npages].pgdesc, 0,
- sizeof(t->array[t->npages].pgdesc));
-
- t->npages++;
-
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
- * PUBLIC: int __ham_chgpg_print __P((DB_ENV *, DBT *, DB_LSN *,
- * PUBLIC: db_recops, void *));
- */
-int
-__ham_chgpg_print(dbenv, dbtp, lsnp, notused2, notused3)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops notused2;
- void *notused3;
-{
- __ham_chgpg_args *argp;
- int ret;
-
- notused2 = DB_TXN_ABORT;
- notused3 = NULL;
-
- if ((ret = __ham_chgpg_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
- (void)printf(
- "[%lu][%lu]__ham_chgpg%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
- (u_long)lsnp->file,
- (u_long)lsnp->offset,
- (argp->type & DB_debug_FLAG) ? "_debug" : "",
- (u_long)argp->type,
- (u_long)argp->txnid->txnid,
- (u_long)argp->prev_lsn.file,
- (u_long)argp->prev_lsn.offset);
- (void)printf("\tfileid: %ld\n", (long)argp->fileid);
- (void)printf("\tmode: %ld\n", (long)argp->mode);
- (void)printf("\told_pgno: %lu\n", (u_long)argp->old_pgno);
- (void)printf("\tnew_pgno: %lu\n", (u_long)argp->new_pgno);
- (void)printf("\told_indx: %lu\n", (u_long)argp->old_indx);
- (void)printf("\tnew_indx: %lu\n", (u_long)argp->new_indx);
- (void)printf("\n");
- __os_free(dbenv, argp);
-
- return (0);
-}
-
/*
* PUBLIC: int __ham_chgpg_read __P((DB_ENV *, void *, __ham_chgpg_args **));
*/
@@ -2989,9 +2284,9 @@ __ham_chgpg_read(dbenv, recbuf, argpp)
if ((ret = __os_malloc(dbenv,
sizeof(__ham_chgpg_args) + sizeof(DB_TXN), &argp)) != 0)
return (ret);
+ bp = recbuf;
argp->txnid = (DB_TXN *)&argp[1];
- bp = recbuf;
memcpy(&argp->type, bp, sizeof(argp->type));
bp += sizeof(argp->type);
@@ -3030,92 +2325,6 @@ __ham_chgpg_read(dbenv, recbuf, argpp)
}
/*
- * PUBLIC: int __ham_init_print __P((DB_ENV *, int (***)(DB_ENV *,
- * PUBLIC: DBT *, DB_LSN *, db_recops, void *), size_t *));
- */
-int
-__ham_init_print(dbenv, dtabp, dtabsizep)
- DB_ENV *dbenv;
- int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- size_t *dtabsizep;
-{
- int ret;
-
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_insdel_print, DB___ham_insdel)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_newpage_print, DB___ham_newpage)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_splitdata_print, DB___ham_splitdata)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_replace_print, DB___ham_replace)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_copypage_print, DB___ham_copypage)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_metagroup_print, DB___ham_metagroup)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_groupalloc_print, DB___ham_groupalloc)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_curadj_print, DB___ham_curadj)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_chgpg_print, DB___ham_chgpg)) != 0)
- return (ret);
- return (0);
-}
-
-#ifdef HAVE_REPLICATION
-/*
- * PUBLIC: int __ham_init_getpgnos __P((DB_ENV *, int (***)(DB_ENV *,
- * PUBLIC: DBT *, DB_LSN *, db_recops, void *), size_t *));
- */
-int
-__ham_init_getpgnos(dbenv, dtabp, dtabsizep)
- DB_ENV *dbenv;
- int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- size_t *dtabsizep;
-{
- int ret;
-
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_insdel_getpgnos, DB___ham_insdel)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_newpage_getpgnos, DB___ham_newpage)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_splitdata_getpgnos, DB___ham_splitdata)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_replace_getpgnos, DB___ham_replace)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_copypage_getpgnos, DB___ham_copypage)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_metagroup_getpgnos, DB___ham_metagroup)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_groupalloc_getpgnos, DB___ham_groupalloc)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_curadj_getpgnos, DB___ham_curadj)) != 0)
- return (ret);
- if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
- __ham_chgpg_getpgnos, DB___ham_chgpg)) != 0)
- return (ret);
- return (0);
-}
-#endif /* HAVE_REPLICATION */
-
-/*
* PUBLIC: int __ham_init_recover __P((DB_ENV *, int (***)(DB_ENV *,
* PUBLIC: DBT *, DB_LSN *, db_recops, void *), size_t *));
*/
diff --git a/db/hash/hash_autop.c b/db/hash/hash_autop.c
new file mode 100644
index 000000000..5664ba793
--- /dev/null
+++ b/db/hash/hash_autop.c
@@ -0,0 +1,486 @@
+/* Do not edit: automatically built by gen_rec.awk. */
+
+#include "db_config.h"
+
+#ifdef HAVE_HASH
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <string.h>
+#endif
+
+#include "db_int.h"
+#include "dbinc/crypto.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_dispatch.h"
+#include "dbinc/db_am.h"
+#include "dbinc/hash.h"
+#include "dbinc/log.h"
+#include "dbinc/txn.h"
+
+/*
+ * PUBLIC: int __ham_insdel_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__ham_insdel_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __ham_insdel_args *argp;
+ u_int32_t i;
+ int ch;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __ham_insdel_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__ham_insdel%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\topcode: %lu\n", (u_long)argp->opcode);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
+ (void)printf("\tndx: %lu\n", (u_long)argp->ndx);
+ (void)printf("\tpagelsn: [%lu][%lu]\n",
+ (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
+ (void)printf("\tkey: ");
+ for (i = 0; i < argp->key.size; i++) {
+ ch = ((u_int8_t *)argp->key.data)[i];
+ printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
+ }
+ (void)printf("\n");
+ (void)printf("\tdata: ");
+ for (i = 0; i < argp->data.size; i++) {
+ ch = ((u_int8_t *)argp->data.data)[i];
+ printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
+ }
+ (void)printf("\n");
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __ham_newpage_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__ham_newpage_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __ham_newpage_args *argp;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __ham_newpage_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__ham_newpage%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\topcode: %lu\n", (u_long)argp->opcode);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tprev_pgno: %lu\n", (u_long)argp->prev_pgno);
+ (void)printf("\tprevlsn: [%lu][%lu]\n",
+ (u_long)argp->prevlsn.file, (u_long)argp->prevlsn.offset);
+ (void)printf("\tnew_pgno: %lu\n", (u_long)argp->new_pgno);
+ (void)printf("\tpagelsn: [%lu][%lu]\n",
+ (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
+ (void)printf("\tnext_pgno: %lu\n", (u_long)argp->next_pgno);
+ (void)printf("\tnextlsn: [%lu][%lu]\n",
+ (u_long)argp->nextlsn.file, (u_long)argp->nextlsn.offset);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __ham_splitdata_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__ham_splitdata_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __ham_splitdata_args *argp;
+ u_int32_t i;
+ int ch;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __ham_splitdata_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__ham_splitdata%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\topcode: %lu\n", (u_long)argp->opcode);
+ (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
+ (void)printf("\tpageimage: ");
+ for (i = 0; i < argp->pageimage.size; i++) {
+ ch = ((u_int8_t *)argp->pageimage.data)[i];
+ printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
+ }
+ (void)printf("\n");
+ (void)printf("\tpagelsn: [%lu][%lu]\n",
+ (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __ham_replace_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__ham_replace_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __ham_replace_args *argp;
+ u_int32_t i;
+ int ch;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __ham_replace_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__ham_replace%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
+ (void)printf("\tndx: %lu\n", (u_long)argp->ndx);
+ (void)printf("\tpagelsn: [%lu][%lu]\n",
+ (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
+ (void)printf("\toff: %ld\n", (long)argp->off);
+ (void)printf("\tolditem: ");
+ for (i = 0; i < argp->olditem.size; i++) {
+ ch = ((u_int8_t *)argp->olditem.data)[i];
+ printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
+ }
+ (void)printf("\n");
+ (void)printf("\tnewitem: ");
+ for (i = 0; i < argp->newitem.size; i++) {
+ ch = ((u_int8_t *)argp->newitem.data)[i];
+ printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
+ }
+ (void)printf("\n");
+ (void)printf("\tmakedup: %lu\n", (u_long)argp->makedup);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __ham_copypage_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__ham_copypage_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __ham_copypage_args *argp;
+ u_int32_t i;
+ int ch;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __ham_copypage_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__ham_copypage%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
+ (void)printf("\tpagelsn: [%lu][%lu]\n",
+ (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
+ (void)printf("\tnext_pgno: %lu\n", (u_long)argp->next_pgno);
+ (void)printf("\tnextlsn: [%lu][%lu]\n",
+ (u_long)argp->nextlsn.file, (u_long)argp->nextlsn.offset);
+ (void)printf("\tnnext_pgno: %lu\n", (u_long)argp->nnext_pgno);
+ (void)printf("\tnnextlsn: [%lu][%lu]\n",
+ (u_long)argp->nnextlsn.file, (u_long)argp->nnextlsn.offset);
+ (void)printf("\tpage: ");
+ for (i = 0; i < argp->page.size; i++) {
+ ch = ((u_int8_t *)argp->page.data)[i];
+ printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
+ }
+ (void)printf("\n");
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __ham_metagroup_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__ham_metagroup_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __ham_metagroup_args *argp;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __ham_metagroup_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__ham_metagroup%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tbucket: %lu\n", (u_long)argp->bucket);
+ (void)printf("\tmmpgno: %lu\n", (u_long)argp->mmpgno);
+ (void)printf("\tmmetalsn: [%lu][%lu]\n",
+ (u_long)argp->mmetalsn.file, (u_long)argp->mmetalsn.offset);
+ (void)printf("\tmpgno: %lu\n", (u_long)argp->mpgno);
+ (void)printf("\tmetalsn: [%lu][%lu]\n",
+ (u_long)argp->metalsn.file, (u_long)argp->metalsn.offset);
+ (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
+ (void)printf("\tpagelsn: [%lu][%lu]\n",
+ (u_long)argp->pagelsn.file, (u_long)argp->pagelsn.offset);
+ (void)printf("\tnewalloc: %lu\n", (u_long)argp->newalloc);
+ (void)printf("\tlast_pgno: %lu\n", (u_long)argp->last_pgno);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __ham_groupalloc_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__ham_groupalloc_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __ham_groupalloc_args *argp;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __ham_groupalloc_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__ham_groupalloc%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tmeta_lsn: [%lu][%lu]\n",
+ (u_long)argp->meta_lsn.file, (u_long)argp->meta_lsn.offset);
+ (void)printf("\tstart_pgno: %lu\n", (u_long)argp->start_pgno);
+ (void)printf("\tnum: %lu\n", (u_long)argp->num);
+ (void)printf("\tfree: %lu\n", (u_long)argp->free);
+ (void)printf("\tlast_pgno: %lu\n", (u_long)argp->last_pgno);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __ham_curadj_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__ham_curadj_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __ham_curadj_args *argp;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __ham_curadj_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__ham_curadj%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tpgno: %lu\n", (u_long)argp->pgno);
+ (void)printf("\tindx: %lu\n", (u_long)argp->indx);
+ (void)printf("\tlen: %lu\n", (u_long)argp->len);
+ (void)printf("\tdup_off: %lu\n", (u_long)argp->dup_off);
+ (void)printf("\tadd: %ld\n", (long)argp->add);
+ (void)printf("\tis_dup: %ld\n", (long)argp->is_dup);
+ (void)printf("\torder: %lu\n", (u_long)argp->order);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __ham_chgpg_print __P((DB_ENV *, DBT *, DB_LSN *,
+ * PUBLIC: db_recops, void *));
+ */
+int
+__ham_chgpg_print(dbenv, dbtp, lsnp, notused2, notused3)
+ DB_ENV *dbenv;
+ DBT *dbtp;
+ DB_LSN *lsnp;
+ db_recops notused2;
+ void *notused3;
+{
+ __ham_chgpg_args *argp;
+ int ret;
+
+ notused2 = DB_TXN_ABORT;
+ notused3 = NULL;
+
+ if ((ret = __ham_chgpg_read(dbenv, dbtp->data, &argp)) != 0)
+ return (ret);
+ (void)printf(
+ "[%lu][%lu]__ham_chgpg%s: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
+ (u_long)lsnp->file,
+ (u_long)lsnp->offset,
+ (argp->type & DB_debug_FLAG) ? "_debug" : "",
+ (u_long)argp->type,
+ (u_long)argp->txnid->txnid,
+ (u_long)argp->prev_lsn.file,
+ (u_long)argp->prev_lsn.offset);
+ (void)printf("\tfileid: %ld\n", (long)argp->fileid);
+ (void)printf("\tmode: %ld\n", (long)argp->mode);
+ (void)printf("\told_pgno: %lu\n", (u_long)argp->old_pgno);
+ (void)printf("\tnew_pgno: %lu\n", (u_long)argp->new_pgno);
+ (void)printf("\told_indx: %lu\n", (u_long)argp->old_indx);
+ (void)printf("\tnew_indx: %lu\n", (u_long)argp->new_indx);
+ (void)printf("\n");
+ __os_free(dbenv, argp);
+ return (0);
+}
+
+/*
+ * PUBLIC: int __ham_init_print __P((DB_ENV *, int (***)(DB_ENV *,
+ * PUBLIC: DBT *, DB_LSN *, db_recops, void *), size_t *));
+ */
+int
+__ham_init_print(dbenv, dtabp, dtabsizep)
+ DB_ENV *dbenv;
+ int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
+ size_t *dtabsizep;
+{
+ int ret;
+
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __ham_insdel_print, DB___ham_insdel)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __ham_newpage_print, DB___ham_newpage)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __ham_splitdata_print, DB___ham_splitdata)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __ham_replace_print, DB___ham_replace)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __ham_copypage_print, DB___ham_copypage)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __ham_metagroup_print, DB___ham_metagroup)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __ham_groupalloc_print, DB___ham_groupalloc)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __ham_curadj_print, DB___ham_curadj)) != 0)
+ return (ret);
+ if ((ret = __db_add_recovery(dbenv, dtabp, dtabsizep,
+ __ham_chgpg_print, DB___ham_chgpg)) != 0)
+ return (ret);
+ return (0);
+}
+#endif /* HAVE_HASH */
diff --git a/db/hash/hash_conv.c b/db/hash/hash_conv.c
index 751b87a59..a90799c7b 100644
--- a/db/hash/hash_conv.c
+++ b/db/hash/hash_conv.c
@@ -1,14 +1,13 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: hash_conv.c,v 11.16 2004/03/24 20:37:38 bostic Exp $
*/
-#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: hash_conv.c,v 11.14 2003/01/08 05:03:21 bostic Exp $";
-#endif /* not lint */
+#include "db_config.h"
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
@@ -110,7 +109,7 @@ __ham_mswap(pg)
SWAP32(p); /* h_charkey */
for (i = 0; i < NCACHED; ++i)
SWAP32(p); /* spares */
- p += 59 * sizeof(u_int32_t); /* unusued */
+ p += 59 * sizeof(u_int32_t); /* unused */
SWAP32(p); /* crypto_magic */
return (0);
}
diff --git a/db/hash/hash_dup.c b/db/hash/hash_dup.c
index 31ba9cc3d..93fc2b51f 100644
--- a/db/hash/hash_dup.c
+++ b/db/hash/hash_dup.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*/
/*
@@ -34,12 +34,11 @@
* 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.
+ *
+ * $Id: hash_dup.c,v 11.85 2004/06/03 16:32:21 margo Exp $
*/
-#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: hash_dup.c,v 11.81 2003/06/30 17:20:11 bostic Exp $";
-#endif /* not lint */
+#include "db_config.h"
/*
* PACKAGE: hashing
@@ -200,7 +199,11 @@ __ham_add_dup(dbc, nval, flags, pgnop)
case DB_AFTER:
tmp_val.doff = hcp->dup_off + DUP_SIZE(hcp->dup_len);
break;
+ default:
+ DB_ASSERT(0);
+ return (EINVAL);
}
+
/* Add the duplicate. */
ret = __ham_replpair(dbc, &tmp_val, 0);
if (ret == 0)
@@ -222,6 +225,9 @@ __ham_add_dup(dbc, nval, flags, pgnop)
hcp->dup_tlen += (db_indx_t)DUP_SIZE(nval->size);
hcp->dup_len = nval->size;
break;
+ default:
+ DB_ASSERT(0);
+ return (EINVAL);
}
ret = __ham_c_update(dbc, tmp_val.size, 1, 1);
return (ret);
@@ -477,7 +483,7 @@ __ham_check_move(dbc, add_len)
old_len =
LEN_HITEM(dbp, hcp->page, dbp->pgsize, H_DATAINDEX(hcp->indx));
- new_datalen = old_len - HKEYDATA_SIZE(0) + add_len;
+ new_datalen = (old_len - HKEYDATA_SIZE(0)) + add_len;
if (HPAGE_PTYPE(hk) != H_DUPLICATE)
new_datalen += DUP_SIZE(0);
@@ -650,7 +656,7 @@ __ham_move_offpage(dbc, pagep, ndx, pgno)
DBT old_dbt;
HOFFDUP od;
db_indx_t i, *inp;
- int32_t shrink;
+ int32_t difflen;
u_int8_t *src;
int ret;
@@ -674,18 +680,24 @@ __ham_move_offpage(dbc, pagep, ndx, pgno)
} else
LSN_NOT_LOGGED(LSN(pagep));
- shrink = LEN_HITEM(dbp, pagep, dbp->pgsize, ndx) - HOFFDUP_SIZE;
- inp = P_INP(dbp, pagep);
-
- if (shrink != 0) {
+ /*
+ * difflen is the difference in the lengths, and so may be negative.
+ * We know that the difference between two unsigned lengths from a
+ * database page will fit into an int32_t.
+ */
+ difflen =
+ (int32_t)LEN_HITEM(dbp, pagep, dbp->pgsize, ndx) -
+ (int32_t)HOFFDUP_SIZE;
+ if (difflen != 0) {
/* Copy data. */
+ inp = P_INP(dbp, pagep);
src = (u_int8_t *)(pagep) + HOFFSET(pagep);
- memmove(src + shrink, src, inp[ndx] - HOFFSET(pagep));
- HOFFSET(pagep) += shrink;
+ memmove(src + difflen, src, inp[ndx] - HOFFSET(pagep));
+ HOFFSET(pagep) += difflen;
/* Update index table. */
for (i = ndx; i < NUM_ENT(pagep); i++)
- inp[i] += shrink;
+ inp[i] += difflen;
}
/* Now copy the offdup entry onto the page. */
@@ -722,6 +734,7 @@ __ham_dsearch(dbc, dbt, offp, cmpp, flags)
i = F_ISSET(hcp, H_CONTINUE) ? hcp->dup_off: 0;
data = HKEYDATA_DATA(H_PAIRDATA(dbp, hcp->page, hcp->indx)) + i;
hcp->dup_tlen = LEN_HDATA(dbp, hcp->page, dbp->pgsize, hcp->indx);
+ len = hcp->dup_len;
while (i < hcp->dup_tlen) {
memcpy(&len, data, sizeof(db_indx_t));
data += sizeof(db_indx_t);
@@ -753,30 +766,6 @@ __ham_dsearch(dbc, dbt, offp, cmpp, flags)
F_SET(hcp, H_ISDUP);
}
-#ifdef DEBUG
-/*
- * __ham_cprint --
- * Display the current cursor list.
- *
- * PUBLIC: void __ham_cprint __P((DBC *));
- */
-void
-__ham_cprint(dbc)
- DBC *dbc;
-{
- HASH_CURSOR *cp;
-
- cp = (HASH_CURSOR *)dbc->internal;
-
- fprintf(stderr, "%#0lx->%#0lx: page: %lu index: %lu",
- P_TO_ULONG(dbc), P_TO_ULONG(cp), (u_long)cp->pgno,
- (u_long)cp->indx);
- if (F_ISSET(cp, H_DELETED))
- fprintf(stderr, " (deleted)");
- fprintf(stderr, "\n");
-}
-#endif /* DEBUG */
-
/*
* __ham_dcursor --
*
diff --git a/db/hash/hash_func.c b/db/hash/hash_func.c
index cd4b5e7b7..b117fcee3 100644
--- a/db/hash/hash_func.c
+++ b/db/hash/hash_func.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*/
/*
@@ -38,14 +38,12 @@
* 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.
+ *
+ * $Id: hash_func.c,v 11.15 2004/01/28 03:36:11 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: hash_func.c,v 11.14 2003/01/08 05:03:34 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#endif
diff --git a/db/hash/hash_meta.c b/db/hash/hash_meta.c
index 247793bbf..6d700fcc1 100644
--- a/db/hash/hash_meta.c
+++ b/db/hash/hash_meta.c
@@ -1,16 +1,14 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2003
+ * Copyright (c) 1999-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: hash_meta.c,v 11.31 2004/09/22 03:46:22 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: hash_meta.c,v 11.24 2003/09/09 16:46:10 ubell Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#endif
@@ -32,34 +30,23 @@ __ham_get_meta(dbc)
DBC *dbc;
{
DB *dbp;
- DB_ENV *dbenv;
DB_MPOOLFILE *mpf;
HASH *hashp;
HASH_CURSOR *hcp;
int ret;
dbp = dbc->dbp;
- dbenv = dbp->dbenv;
mpf = dbp->mpf;
hashp = dbp->h_internal;
hcp = (HASH_CURSOR *)dbc->internal;
- if (dbenv != NULL &&
- STD_LOCKING(dbc) && !F_ISSET(dbc, DBC_RECOVER | DBC_COMPENSATE)) {
- dbc->lock.pgno = hashp->meta_pgno;
- if ((ret = __lock_get(dbenv, dbc->locker,
- DB_NONBLOCK(dbc) ? DB_LOCK_NOWAIT : 0,
- &dbc->lock_dbt, DB_LOCK_READ, &hcp->hlock)) != 0)
- return ((ret == DB_LOCK_NOTGRANTED &&
- !F_ISSET(dbenv, DB_ENV_TIME_NOTGRANTED)) ?
- DB_LOCK_DEADLOCK : ret);
-
- }
+ if ((ret = __db_lget(dbc, 0,
+ hashp->meta_pgno, DB_LOCK_READ, 0, &hcp->hlock)) != 0)
+ return (ret);
if ((ret = __memp_fget(mpf,
- &hashp->meta_pgno, DB_MPOOL_CREATE, &(hcp->hdr))) != 0 &&
- LOCK_ISSET(hcp->hlock))
- (void)__lock_put(dbenv, &hcp->hlock);
+ &hashp->meta_pgno, DB_MPOOL_CREATE, &(hcp->hdr))) != 0)
+ (void)__LPUT(dbc, hcp->hlock);
return (ret);
}
@@ -83,12 +70,9 @@ __ham_release_meta(dbc)
(void)__memp_fput(mpf, hcp->hdr,
F_ISSET(hcp, H_DIRTY) ? DB_MPOOL_DIRTY : 0);
hcp->hdr = NULL;
- if (!F_ISSET(dbc, DBC_RECOVER | DBC_COMPENSATE) &&
- dbc->txn == NULL && LOCK_ISSET(hcp->hlock))
- (void)__lock_put(dbc->dbp->dbenv, &hcp->hlock);
F_CLR(hcp, H_DIRTY);
- return (0);
+ return (__TLPUT(dbc, hcp->hlock));
}
/*
@@ -101,8 +85,6 @@ __ham_dirty_meta(dbc)
DBC *dbc;
{
DB *dbp;
- DB_ENV *dbenv;
- DB_LOCK _tmp;
HASH *hashp;
HASH_CURSOR *hcp;
int ret;
@@ -112,20 +94,11 @@ __ham_dirty_meta(dbc)
hcp = (HASH_CURSOR *)dbc->internal;
ret = 0;
- dbenv = dbp->dbenv;
- if (STD_LOCKING(dbc) && !F_ISSET(dbc, DBC_RECOVER | DBC_COMPENSATE)) {
- dbc->lock.pgno = hashp->meta_pgno;
- if ((ret = __lock_get(dbenv, dbc->locker,
- DB_NONBLOCK(dbc) ? DB_LOCK_NOWAIT : 0,
- &dbc->lock_dbt, DB_LOCK_WRITE, &_tmp)) == 0) {
- ret = __lock_put(dbenv, &hcp->hlock);
- hcp->hlock = _tmp;
- }
- }
+
+ ret = __db_lget(dbc, LCK_COUPLE,
+ hashp->meta_pgno, DB_LOCK_WRITE, 0, &hcp->hlock);
if (ret == 0)
F_SET(hcp, H_DIRTY);
- return ((ret == DB_LOCK_NOTGRANTED &&
- !F_ISSET(dbenv, DB_ENV_TIME_NOTGRANTED)) ?
- DB_LOCK_DEADLOCK : ret);
+ return (ret);
}
diff --git a/db/hash/hash_method.c b/db/hash/hash_method.c
index 07508a3db..6b59787a6 100644
--- a/db/hash/hash_method.c
+++ b/db/hash/hash_method.c
@@ -1,16 +1,14 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2003
+ * Copyright (c) 1999-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: hash_method.c,v 11.17 2004/01/28 03:36:11 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: hash_method.c,v 11.15 2003/04/18 08:36:37 mjc Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#endif
@@ -19,11 +17,9 @@ static const char revid[] = "$Id: hash_method.c,v 11.15 2003/04/18 08:36:37 mjc
#include "dbinc/db_page.h"
#include "dbinc/hash.h"
-static int __ham_get_h_ffactor __P((DB *, u_int32_t *));
static int __ham_set_h_ffactor __P((DB *, u_int32_t));
static int __ham_set_h_hash
__P((DB *, u_int32_t(*)(DB *, const void *, u_int32_t)));
-static int __ham_get_h_nelem __P((DB *, u_int32_t *));
static int __ham_set_h_nelem __P((DB *, u_int32_t));
/*
@@ -73,9 +69,11 @@ __ham_db_close(dbp)
}
/*
- * __db_get_h_ffactor --
+ * __ham_get_h_ffactor --
+ *
+ * PUBLIC: int __ham_get_h_ffactor __P((DB *, u_int32_t *));
*/
-static int
+int
__ham_get_h_ffactor(dbp, h_ffactorp)
DB *dbp;
u_int32_t *h_ffactorp;
@@ -127,8 +125,10 @@ __ham_set_h_hash(dbp, func)
/*
* __db_get_h_nelem --
+ *
+ * PUBLIC: int __ham_get_h_nelem __P((DB *, u_int32_t *));
*/
-static int
+int
__ham_get_h_nelem(dbp, h_nelemp)
DB *dbp;
u_int32_t *h_nelemp;
diff --git a/db/hash/hash_open.c b/db/hash/hash_open.c
index a5842fd18..67b12e5eb 100644
--- a/db/hash/hash_open.c
+++ b/db/hash/hash_open.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*/
/*
@@ -38,18 +38,15 @@
* 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.
+ *
+ * $Id: hash_open.c,v 11.191 2004/06/22 18:43:38 margo Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: hash_open.c,v 11.185 2003/07/17 01:39:17 margo Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
-#include <stdlib.h>
#include <string.h>
#endif
@@ -83,14 +80,12 @@ __ham_open(dbp, txn, name, base_pgno, flags)
{
DB_ENV *dbenv;
DBC *dbc;
- DB_MPOOLFILE *mpf;
HASH_CURSOR *hcp;
HASH *hashp;
int ret, t_ret;
dbenv = dbp->dbenv;
dbc = NULL;
- mpf = dbp->mpf;
/*
* Get a cursor. If DB_CREATE is specified, we may be creating
@@ -130,17 +125,6 @@ __ham_open(dbp, txn, name, base_pgno, flags)
if (F_ISSET(&hcp->hdr->dbmeta, DB_HASH_SUBDB))
F_SET(dbp, DB_AM_SUBDB);
- /*
- * We must initialize last_pgno, it could be stale.
- * We update this without holding the meta page write
- * locked. This is ok since two threads in the code
- * must be setting it to the same value. SR #7159.
- */
- if (!F_ISSET(dbp, DB_AM_RDONLY) &&
- dbp->meta_pgno == PGNO_BASE_MD) {
- __memp_last_pgno(mpf, &hcp->hdr->dbmeta.last_pgno);
- F_SET(hcp, H_DIRTY);
- }
} else if (!IS_RECOVERING(dbenv) && !F_ISSET(dbp, DB_AM_RECOVER)) {
__db_err(dbp->dbenv,
"%s: Invalid hash meta page %d", name, base_pgno);
@@ -273,8 +257,7 @@ __ham_init_meta(dbp, meta, pgno, lsnp)
{
HASH *hashp;
db_pgno_t nbuckets;
- int i;
- int32_t l2;
+ u_int i, l2;
hashp = dbp->h_internal;
if (hashp->h_hash == NULL)
@@ -372,71 +355,75 @@ __ham_new_file(dbp, txn, fhp, name)
mpf = dbp->mpf;
meta = NULL;
page = NULL;
- memset(&pdbt, 0, sizeof(pdbt));
+ buf = NULL;
- /* Build meta-data page. */
if (name == NULL) {
+ /* Build meta-data page. */
lpgno = PGNO_BASE_MD;
- ret = __memp_fget(mpf, &lpgno, DB_MPOOL_CREATE, &meta);
+ if ((ret =
+ __memp_fget(mpf, &lpgno, DB_MPOOL_CREATE, &meta)) != 0)
+ return (ret);
+ LSN_NOT_LOGGED(lsn);
+ lpgno = __ham_init_meta(dbp, meta, PGNO_BASE_MD, &lsn);
+ meta->dbmeta.last_pgno = lpgno;
+ ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY);
+ meta = NULL;
+ if (ret != 0)
+ goto err;
+
+ /* Allocate the final hash bucket. */
+ if ((ret =
+ __memp_fget(mpf, &lpgno, DB_MPOOL_CREATE, &page)) != 0)
+ goto err;
+ P_INIT(page,
+ dbp->pgsize, lpgno, PGNO_INVALID, PGNO_INVALID, 0, P_HASH);
+ LSN_NOT_LOGGED(page->lsn);
+ ret = __memp_fput(mpf, page, DB_MPOOL_DIRTY);
+ page = NULL;
+ if (ret != 0)
+ goto err;
} else {
+ memset(&pdbt, 0, sizeof(pdbt));
+
+ /* Build meta-data page. */
pginfo.db_pagesize = dbp->pgsize;
pginfo.type = dbp->type;
pginfo.flags =
F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_SWAP));
pdbt.data = &pginfo;
pdbt.size = sizeof(pginfo);
- ret = __os_calloc(dbp->dbenv, 1, dbp->pgsize, &buf);
+ if ((ret = __os_calloc(dbp->dbenv, 1, dbp->pgsize, &buf)) != 0)
+ return (ret);
meta = (HMETA *)buf;
- }
- if (ret != 0)
- return (ret);
-
- LSN_NOT_LOGGED(lsn);
- lpgno = __ham_init_meta(dbp, meta, PGNO_BASE_MD, &lsn);
- meta->dbmeta.last_pgno = lpgno;
-
- if (name == NULL)
- ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY);
- else {
+ LSN_NOT_LOGGED(lsn);
+ lpgno = __ham_init_meta(dbp, meta, PGNO_BASE_MD, &lsn);
+ meta->dbmeta.last_pgno = lpgno;
if ((ret = __db_pgout(dbenv, PGNO_BASE_MD, meta, &pdbt)) != 0)
goto err;
- ret = __fop_write(dbenv, txn, name,
- DB_APP_DATA, fhp, dbp->pgsize, 0, 0, buf, dbp->pgsize, 1,
- F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0);
- }
- if (ret != 0)
- goto err;
- meta = NULL;
-
- /* Now allocate the final hash bucket. */
- if (name == NULL) {
- if ((ret =
- __memp_fget(mpf, &lpgno, DB_MPOOL_CREATE, &page)) != 0)
+ if ((ret = __fop_write(dbenv, txn, name, DB_APP_DATA, fhp,
+ dbp->pgsize, 0, 0, buf, dbp->pgsize, 1, F_ISSET(
+ dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0)) != 0)
goto err;
- } else {
+ meta = NULL;
+
+ /* Allocate the final hash bucket. */
#ifdef DIAGNOSTIC
- memset(buf, dbp->pgsize, 0);
+ memset(buf, 0, dbp->pgsize);
#endif
page = (PAGE *)buf;
- }
-
- P_INIT(page, dbp->pgsize, lpgno, PGNO_INVALID, PGNO_INVALID, 0, P_HASH);
- LSN_NOT_LOGGED(page->lsn);
-
- if (name == NULL)
- ret = __memp_fput(mpf, page, DB_MPOOL_DIRTY);
- else {
+ P_INIT(page,
+ dbp->pgsize, lpgno, PGNO_INVALID, PGNO_INVALID, 0, P_HASH);
+ LSN_NOT_LOGGED(page->lsn);
if ((ret = __db_pgout(dbenv, lpgno, buf, &pdbt)) != 0)
goto err;
- ret = __fop_write(dbenv, txn, name, DB_APP_DATA,
- fhp, dbp->pgsize, lpgno, 0, buf, dbp->pgsize, 1,
- F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0);
+ if ((ret = __fop_write(dbenv, txn, name, DB_APP_DATA, fhp,
+ dbp->pgsize, lpgno, 0, buf, dbp->pgsize, 1, F_ISSET(
+ dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0)) != 0)
+ goto err;
+ page = NULL;
}
- if (ret != 0)
- goto err;
- page = NULL;
-err: if (name != NULL)
+err: if (buf != NULL)
__os_free(dbenv, buf);
else {
if (meta != NULL)
@@ -521,8 +508,8 @@ __ham_new_subdb(mdbp, dbp, txn)
/* Reflect the group allocation. */
if (DBENV_LOGGING(dbenv))
if ((ret = __ham_groupalloc_log(mdbp, txn,
- &LSN(mmeta), 0, &LSN(mmeta),
- meta->spares[0], meta->max_bucket + 1, mmeta->free)) != 0)
+ &LSN(mmeta), 0, &LSN(mmeta), meta->spares[0],
+ meta->max_bucket + 1, mmeta->free, mmeta->last_pgno)) != 0)
goto err;
/* Release the new meta-data page. */
@@ -551,15 +538,13 @@ err:
if (mmeta != NULL)
if ((t_ret = __memp_fput(mpf, mmeta, 0)) != 0 && ret == 0)
ret = t_ret;
- if (LOCK_ISSET(mmlock))
- if ((t_ret = __LPUT(dbc, mmlock)) != 0 && ret == 0)
- ret = t_ret;
+ if ((t_ret = __LPUT(dbc, mmlock)) != 0 && ret == 0)
+ ret = t_ret;
if (meta != NULL)
if ((t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0)
ret = t_ret;
- if (LOCK_ISSET(metalock))
- if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)
- ret = t_ret;
+ if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)
+ ret = t_ret;
if (dbc != NULL)
if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
ret = t_ret;
diff --git a/db/hash/hash_page.c b/db/hash/hash_page.c
index c52aa7967..636767f4e 100644
--- a/db/hash/hash_page.c
+++ b/db/hash/hash_page.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*/
/*
@@ -38,14 +38,12 @@
* 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.
+ *
+ * $Id: hash_page.c,v 11.102 2004/09/22 21:14:56 ubell Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: hash_page.c,v 11.93 2003/06/30 17:20:12 bostic Exp $";
-#endif /* not lint */
-
/*
* PACKAGE: hashing
*
@@ -150,7 +148,7 @@ __ham_item_reset(dbc)
DB *dbp;
DB_MPOOLFILE *mpf;
HASH_CURSOR *hcp;
- int ret;
+ int ret, t_ret;
dbp = dbc->dbp;
mpf = dbp->mpf;
@@ -160,29 +158,33 @@ __ham_item_reset(dbc)
if (hcp->page != NULL)
ret = __memp_fput(mpf, hcp->page, 0);
- __ham_item_init(dbc);
+ if ((t_ret = __ham_item_init(dbc)) != 0 && ret == 0)
+ ret = t_ret;
+
return (ret);
}
/*
- * PUBLIC: void __ham_item_init __P((DBC *));
+ * PUBLIC: int __ham_item_init __P((DBC *));
*/
-void
+int
__ham_item_init(dbc)
DBC *dbc;
{
HASH_CURSOR *hcp;
+ int ret;
hcp = (HASH_CURSOR *)dbc->internal;
+
/*
- * If this cursor still holds any locks, we must
- * release them if we are not running with transactions.
+ * If this cursor still holds any locks, we must release them if
+ * we are not running with transactions.
*/
- (void)__TLPUT(dbc, hcp->lock);
+ ret = __TLPUT(dbc, hcp->lock);
/*
- * The following fields must *not* be initialized here
- * because they may have meaning across inits.
+ * The following fields must *not* be initialized here because they
+ * may have meaning across inits.
* hlock, hdr, split_buf, stats
*/
hcp->bucket = BUCKET_INVALID;
@@ -199,6 +201,8 @@ __ham_item_init(dbc)
hcp->pgno = PGNO_INVALID;
hcp->indx = NDX_INVALID;
hcp->page = NULL;
+
+ return (ret);
}
/*
@@ -550,8 +554,8 @@ __ham_del_pair(dbc, reclaim_page)
db_ham_mode op;
db_indx_t ndx;
db_pgno_t chg_pgno, pgno, tmp_pgno;
- int ret, t_ret;
u_int32_t order;
+ int ret, t_ret;
dbp = dbc->dbp;
mpf = dbp->mpf;
@@ -571,12 +575,12 @@ __ham_del_pair(dbc, reclaim_page)
* to remove the big item and then update the page to remove the
* entry referring to the big item.
*/
- ret = 0;
if (HPAGE_PTYPE(H_PAIRKEY(dbp, p, ndx)) == H_OFFPAGE) {
memcpy(&pgno, HOFFPAGE_PGNO(P_ENTRY(dbp, p, H_KEYINDEX(ndx))),
sizeof(db_pgno_t));
ret = __db_doff(dbc, pgno);
- }
+ } else
+ ret = 0;
if (ret == 0)
switch (HPAGE_PTYPE(H_PAIRDATA(dbp, p, ndx))) {
@@ -595,6 +599,9 @@ __ham_del_pair(dbc, reclaim_page)
*/
F_CLR(hcp, H_ISDUP);
break;
+ default:
+ /* No-op */
+ break;
}
if (ret)
@@ -834,9 +841,9 @@ __ham_replpair(dbc, dbt, make_dup)
DB_ENV *dbenv;
DB_LSN new_lsn;
HASH_CURSOR *hcp;
- int32_t change; /* XXX: Possible overflow. */
+ u_int32_t change;
u_int32_t dup_flag, len, memsize;
- int beyond_eor, is_big, ret, type;
+ int beyond_eor, is_big, is_plus, ret, type;
u_int8_t *beg, *dest, *end, *hk, *src;
void *memp;
@@ -864,7 +871,13 @@ __ham_replpair(dbc, dbt, make_dup)
* formula doesn't work, because we are essentially adding
* new bytes.
*/
- change = dbt->size - dbt->dlen;
+ if (dbt->size > dbt->dlen) {
+ change = dbt->size - dbt->dlen;
+ is_plus = 1;
+ } else {
+ change = dbt->dlen - dbt->size;
+ is_plus = 0;
+ }
hk = H_PAIRDATA(dbp, hcp->page, hcp->indx);
is_big = HPAGE_PTYPE(hk) == H_OFFPAGE;
@@ -876,10 +889,25 @@ __ham_replpair(dbc, dbt, make_dup)
dbp->pgsize, H_DATAINDEX(hcp->indx));
beyond_eor = dbt->doff + dbt->dlen > len;
- if (beyond_eor)
- change += dbt->doff + dbt->dlen - len;
+ if (beyond_eor) {
+ /*
+ * The change is beyond the end of file. If change
+ * is a positive number, we can simply add the extension
+ * to it. However, if change is negative, then we need
+ * to figure out if the extension is larger than the
+ * negative change.
+ */
+ if (is_plus)
+ change += dbt->doff + dbt->dlen - len;
+ else if (dbt->doff + dbt->dlen - len > change) {
+ /* Extension bigger than change */
+ is_plus = 1;
+ change = (dbt->doff + dbt->dlen - len) - change;
+ } else /* Extension is smaller than change. */
+ change -= (dbt->doff + dbt->dlen - len);
+ }
- if (change > (int32_t)P_FREESPACE(dbp, hcp->page) ||
+ if ((is_plus && change > P_FREESPACE(dbp, hcp->page)) ||
beyond_eor || is_big) {
/*
* Case 3 -- two subcases.
@@ -923,7 +951,7 @@ __ham_replpair(dbc, dbt, make_dup)
}
/* Now shift old data around to make room for new. */
- if (change > 0) {
+ if (is_plus) {
if ((ret = __os_realloc(dbenv,
tdata.size + change, &tdata.data)) != 0)
return (ret);
@@ -936,13 +964,19 @@ __ham_replpair(dbc, dbt, make_dup)
src = (u_int8_t *)tdata.data + dbt->doff + dbt->dlen;
if (src < end && tdata.size > dbt->doff + dbt->dlen) {
- len = tdata.size - dbt->doff - dbt->dlen;
- dest = src + change;
+ len = tdata.size - (dbt->doff + dbt->dlen);
+ if (is_plus)
+ dest = src + change;
+ else
+ dest = src - change;
memmove(dest, src, len);
}
memcpy((u_int8_t *)tdata.data + dbt->doff,
dbt->data, dbt->size);
- tdata.size += change;
+ if (is_plus)
+ tdata.size += change;
+ else
+ tdata.size -= change;
/* Now add the pair. */
ret = __ham_add_el(dbc, &tmp, &tdata, type);
@@ -970,7 +1004,7 @@ err: return (ret);
if ((ret = __ham_replace_log(dbp,
dbc->txn, &new_lsn, 0, PGNO(hcp->page),
(u_int32_t)H_DATAINDEX(hcp->indx), &LSN(hcp->page),
- (u_int32_t)dbt->doff, &old_dbt, dbt, make_dup)) != 0)
+ (int32_t)dbt->doff, &old_dbt, dbt, make_dup)) != 0)
return (ret);
} else
@@ -979,7 +1013,7 @@ err: return (ret);
LSN(hcp->page) = new_lsn; /* Structure assignment. */
__ham_onpage_replace(dbp, hcp->page, (u_int32_t)H_DATAINDEX(hcp->indx),
- (int32_t)dbt->doff, change, dbt);
+ (int32_t)dbt->doff, change, is_plus, dbt);
return (0);
}
@@ -997,15 +1031,16 @@ err: return (ret);
* dbt: the new data that gets written at beg.
*
* PUBLIC: void __ham_onpage_replace __P((DB *, PAGE *, u_int32_t,
- * PUBLIC: int32_t, int32_t, DBT *));
+ * PUBLIC: int32_t, u_int32_t, int, DBT *));
*/
void
-__ham_onpage_replace(dbp, pagep, ndx, off, change, dbt)
+__ham_onpage_replace(dbp, pagep, ndx, off, change, is_plus, dbt)
DB *dbp;
PAGE *pagep;
u_int32_t ndx;
int32_t off;
- int32_t change;
+ u_int32_t change;
+ int is_plus;
DBT *dbt;
{
db_indx_t i, *inp;
@@ -1030,15 +1065,25 @@ __ham_onpage_replace(dbp, pagep, ndx, off, change, dbt)
len = (int32_t)(
(HKEYDATA_DATA(P_ENTRY(dbp, pagep, ndx)) + off) -
src);
- dest = src - change;
- memmove(dest, src, len);
+ if (is_plus)
+ dest = src - change;
+ else
+ dest = src + change;
+ memmove(dest, src, (size_t)len);
if (zero_me)
memset(dest + len, 0, change);
/* Now update the indices. */
- for (i = ndx; i < NUM_ENT(pagep); i++)
- inp[i] -= change;
- HOFFSET(pagep) -= change;
+ for (i = ndx; i < NUM_ENT(pagep); i++) {
+ if (is_plus)
+ inp[i] -= change;
+ else
+ inp[i] += change;
+ }
+ if (is_plus)
+ HOFFSET(pagep) -= change;
+ else
+ HOFFSET(pagep) += change;
}
if (off >= 0)
memcpy(HKEYDATA_DATA(P_ENTRY(dbp, pagep, ndx)) + off,
@@ -1071,11 +1116,12 @@ __ham_split_page(dbc, obucket, nbucket)
void *big_buf;
dbp = dbc->dbp;
+ carray = NULL;
dbenv = dbp->dbenv;
mpf = dbp->mpf;
hcp = (HASH_CURSOR *)dbc->internal;
temp_pagep = old_pagep = new_pagep = NULL;
- carray = NULL;
+ npgno = PGNO_INVALID;
LOCK_INIT(block);
bucket_pgno = BUCKET_TO_PAGE(hcp, obucket);
@@ -1268,8 +1314,8 @@ err: if (old_pagep != NULL)
if (temp_pagep != NULL && PGNO(temp_pagep) != bucket_pgno)
(void)__memp_fput(mpf, temp_pagep, DB_MPOOL_DIRTY);
}
- if (LOCK_ISSET(block))
- __TLPUT(dbc, block);
+ if ((t_ret = __TLPUT(dbc, block)) != 0 && ret == 0)
+ ret = t_ret;
if (carray != NULL) /* We never knew its size. */
__os_free(dbenv, carray);
return (ret);
@@ -1554,13 +1600,19 @@ __ham_get_cpage(dbc, mode)
*/
LOCK_INIT(tmp_lock);
if (STD_LOCKING(dbc)) {
- if (hcp->lbucket != hcp->bucket && /* Case 4 */
- (ret = __TLPUT(dbc, hcp->lock)) != 0)
- return (ret);
+ if (hcp->lbucket != hcp->bucket) { /* Case 4 */
+ if ((ret = __TLPUT(dbc, hcp->lock)) != 0)
+ return (ret);
+ LOCK_INIT(hcp->lock);
+ }
+ /*
+ * See if we have the right lock. If we are doing
+ * dirty reads we assume the write lock has been downgraded.
+ */
if ((LOCK_ISSET(hcp->lock) &&
- (hcp->lock_mode == DB_LOCK_READ &&
- mode == DB_LOCK_WRITE))) {
+ ((hcp->lock_mode == DB_LOCK_READ ||
+ F_ISSET(dbp, DB_AM_DIRTY)) && mode == DB_LOCK_WRITE))) {
/* Case 3. */
tmp_lock = hcp->lock;
LOCK_INIT(hcp->lock);
@@ -1575,9 +1627,9 @@ __ham_get_cpage(dbc, mode)
if (ret == 0) {
hcp->lock_mode = mode;
hcp->lbucket = hcp->bucket;
- if (LOCK_ISSET(tmp_lock))
- /* Case 3: release the original lock. */
- ret = __lock_put(dbp->dbenv, &tmp_lock);
+ /* Case 3: release the original lock. */
+ if ((ret = __ENV_LPUT(dbp->dbenv, tmp_lock, 0)) != 0)
+ return (ret);
} else if (LOCK_ISSET(tmp_lock))
hcp->lock = tmp_lock;
}
diff --git a/db/hash/hash_rec.c b/db/hash/hash_rec.c
index b3701057e..6cd4ffe4c 100644
--- a/db/hash/hash_rec.c
+++ b/db/hash/hash_rec.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*/
/*
@@ -38,14 +38,12 @@
* 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.
+ *
+ * $Id: hash_rec.c,v 11.82 2004/09/22 03:46:22 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: hash_rec.c,v 11.76 2003/07/04 17:45:07 margo Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
@@ -92,16 +90,28 @@ __ham_insdel_recover(dbenv, dbtp, lsnp, op, info)
if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
if (DB_UNDO(op)) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
+ if (ret == DB_PAGE_NOTFOUND)
+ goto done;
+ else {
+ ret = __db_pgerr(file_dbp, argp->pgno, ret);
+ goto out;
+ }
+ }
+#ifdef HAVE_FTRUNCATE
+ /* If the page is not here then it was later truncated. */
+ if (!IS_ZERO_LSN(argp->pagelsn))
goto done;
- } else if ((ret = __memp_fget(mpf,
- &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
+#endif
+ /*
+ * This page was created by a group allocation and
+ * the file may not have been extend yet.
+ * Create the page if necessary.
+ */
+ if ((ret = __memp_fget(mpf,
+ &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) {
+ ret = __db_pgerr(file_dbp, argp->pgno, ret);
goto out;
+ }
}
cmp_n = log_compare(lsnp, &LSN(pagep));
@@ -117,8 +127,8 @@ __ham_insdel_recover(dbenv, dbtp, lsnp, op, info)
* We do this by calling __putitem with the type H_OFFPAGE instead
* of H_KEYDATA.
*/
- opcode = OPCODE_OF(argp->opcode);
+ opcode = OPCODE_OF(argp->opcode);
flags = 0;
if ((opcode == DELPAIR && cmp_n == 0 && DB_UNDO(op)) ||
(opcode == PUTPAIR && cmp_p == 0 && DB_REDO(op))) {
@@ -142,7 +152,7 @@ __ham_insdel_recover(dbenv, dbtp, lsnp, op, info)
type = H_KEYDATA;
__ham_putitem(file_dbp, pagep, &argp->data, type);
} else
- (void)__ham_reputpair(file_dbp, pagep,
+ __ham_reputpair(file_dbp, pagep,
argp->ndx, &argp->key, &argp->data);
LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn;
@@ -199,20 +209,7 @@ __ham_newpage_recover(dbenv, dbtp, lsnp, op, info)
REC_PRINT(__ham_newpage_print);
REC_INTRO(__ham_newpage_read, 1);
- if ((ret = __memp_fget(mpf, &argp->new_pgno, 0, &pagep)) != 0) {
- if (DB_UNDO(op)) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- ret = 0;
- goto ppage;
- } else if ((ret = __memp_fget(mpf,
- &argp->new_pgno, DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
+ REC_FGET(mpf, argp->new_pgno, &pagep, ppage);
/*
* There are potentially three pages we need to check: the one
@@ -249,21 +246,7 @@ __ham_newpage_recover(dbenv, dbtp, lsnp, op, info)
/* Now do the prev page. */
ppage: if (argp->prev_pgno != PGNO_INVALID) {
- if ((ret =
- __memp_fget(mpf, &argp->prev_pgno, 0, &pagep)) != 0) {
- if (DB_UNDO(op)) {
- /*
- * We are undoing and the page doesn't exist.
- * That is equivalent to having a pagelsn of 0,
- * so we would not have to undo anything. In
- * this case, don't bother creating a page.
- */
- ret = 0;
- goto npage;
- } else if ((ret = __memp_fget(mpf,
- &argp->prev_pgno, DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
+ REC_FGET(mpf, argp->prev_pgno, &pagep, npage);
cmp_n = log_compare(lsnp, &LSN(pagep));
cmp_p = log_compare(&LSN(pagep), &argp->prevlsn);
@@ -293,20 +276,7 @@ ppage: if (argp->prev_pgno != PGNO_INVALID) {
/* Now time to do the next page */
npage: if (argp->next_pgno != PGNO_INVALID) {
- if ((ret =
- __memp_fget(mpf, &argp->next_pgno, 0, &pagep)) != 0) {
- if (DB_UNDO(op)) {
- /*
- * We are undoing and the page doesn't exist.
- * That is equivalent to having a pagelsn of 0,
- * so we would not have to undo anything. In
- * this case, don't bother creating a page.
- */
- goto done;
- } else if ((ret = __memp_fget(mpf,
- &argp->next_pgno, DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
+ REC_FGET(mpf, argp->next_pgno, &pagep, done);
cmp_n = log_compare(lsnp, &LSN(pagep));
cmp_p = log_compare(&LSN(pagep), &argp->nextlsn);
@@ -365,8 +335,8 @@ __ham_replace_recover(dbenv, dbtp, lsnp, op, info)
DBT dbt;
PAGE *pagep;
u_int32_t flags;
- int32_t grow;
- int cmp_n, cmp_p, ret;
+ u_int32_t change;
+ int cmp_n, cmp_p, is_plus, ret;
u_int8_t *hk;
pagep = NULL;
@@ -375,19 +345,7 @@ __ham_replace_recover(dbenv, dbtp, lsnp, op, info)
REC_PRINT(__ham_replace_print);
REC_INTRO(__ham_replace_read, 1);
- if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
- if (DB_UNDO(op)) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- goto done;
- } else if ((ret = __memp_fget(mpf,
- &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
+ REC_FGET(mpf, argp->pgno, &pagep, done);
cmp_n = log_compare(lsnp, &LSN(pagep));
cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
@@ -395,27 +353,45 @@ __ham_replace_recover(dbenv, dbtp, lsnp, op, info)
memset(&dbt, 0, sizeof(dbt));
flags = 0;
- grow = 1;
+ /*
+ * Before we know the direction of the transformation we will
+ * determine the size differential; then once we know if we are
+ * redoing or undoing, we'll adjust the sign (is_plus) appropriately.
+ */
+ if (argp->newitem.size > argp->olditem.size) {
+ change = argp->newitem.size - argp->olditem.size;
+ is_plus = 1;
+ } else {
+ change = argp->olditem.size - argp->newitem.size;
+ is_plus = 0;
+ }
if (cmp_p == 0 && DB_REDO(op)) {
/* Reapply the change as specified. */
dbt.data = argp->newitem.data;
dbt.size = argp->newitem.size;
- grow = argp->newitem.size - argp->olditem.size;
LSN(pagep) = *lsnp;
+ /*
+ * The is_plus flag is set properly to reflect
+ * newitem.size - olditem.size.
+ */
flags = DB_MPOOL_DIRTY;
} else if (cmp_n == 0 && DB_UNDO(op)) {
/* Undo the already applied change. */
dbt.data = argp->olditem.data;
dbt.size = argp->olditem.size;
- grow = argp->olditem.size - argp->newitem.size;
+ /*
+ * Invert is_plus to reflect sign of
+ * olditem.size - newitem.size.
+ */
+ is_plus = !is_plus;
LSN(pagep) = argp->pagelsn;
flags = DB_MPOOL_DIRTY;
}
if (flags) {
__ham_onpage_replace(file_dbp, pagep,
- argp->ndx, argp->off, grow, &dbt);
+ argp->ndx, argp->off, change, is_plus, &dbt);
if (argp->makedup) {
hk = P_ENTRY(file_dbp, pagep, argp->ndx);
if (DB_REDO(op))
@@ -467,16 +443,28 @@ __ham_splitdata_recover(dbenv, dbtp, lsnp, op, info)
if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
if (DB_UNDO(op)) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
+ if (ret == DB_PAGE_NOTFOUND)
+ goto done;
+ else {
+ ret = __db_pgerr(file_dbp, argp->pgno, ret);
+ goto out;
+ }
+ }
+#ifdef HAVE_FTRUNCATE
+ /* If the page is not here then it was later truncated. */
+ if (!IS_ZERO_LSN(argp->pagelsn))
goto done;
- } else if ((ret = __memp_fget(mpf,
- &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
+#endif
+ /*
+ * This page was created by a group allocation and
+ * the file may not have been extend yet.
+ * Create the page if necessary.
+ */
+ if ((ret = __memp_fget(mpf,
+ &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) {
+ ret = __db_pgerr(file_dbp, argp->pgno, ret);
goto out;
+ }
}
cmp_n = log_compare(lsnp, &LSN(pagep));
@@ -556,20 +544,7 @@ __ham_copypage_recover(dbenv, dbtp, lsnp, op, info)
flags = 0;
/* This is the bucket page. */
- if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
- if (DB_UNDO(op)) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- ret = 0;
- goto donext;
- } else if ((ret = __memp_fget(mpf,
- &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
+ REC_FGET(mpf, argp->pgno, &pagep, donext);
cmp_n = log_compare(lsnp, &LSN(pagep));
cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
@@ -594,20 +569,7 @@ __ham_copypage_recover(dbenv, dbtp, lsnp, op, info)
pagep = NULL;
donext: /* Now fix up the "next" page. */
- if ((ret = __memp_fget(mpf, &argp->next_pgno, 0, &pagep)) != 0) {
- if (DB_UNDO(op)) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- ret = 0;
- goto do_nn;
- } else if ((ret = __memp_fget(mpf,
- &argp->next_pgno, DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
+ REC_FGET(mpf, argp->next_pgno, &pagep, do_nn);
/* For REDO just update the LSN. For UNDO copy page back. */
cmp_n = log_compare(lsnp, &LSN(pagep));
@@ -630,19 +592,7 @@ donext: /* Now fix up the "next" page. */
do_nn: if (argp->nnext_pgno == PGNO_INVALID)
goto done;
- if ((ret = __memp_fget(mpf, &argp->nnext_pgno, 0, &pagep)) != 0) {
- if (DB_UNDO(op)) {
- /*
- * We are undoing and the page doesn't exist. That
- * is equivalent to having a pagelsn of 0, so we
- * would not have to undo anything. In this case,
- * don't bother creating a page.
- */
- goto done;
- } else if ((ret = __memp_fget(mpf,
- &argp->nnext_pgno, DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- }
+ REC_FGET(mpf, argp->nnext_pgno, &pagep, done);
cmp_n = log_compare(lsnp, &LSN(pagep));
cmp_p = log_compare(&LSN(pagep), &argp->nnextlsn);
@@ -706,7 +656,7 @@ __ham_metagroup_recover(dbenv, dbtp, lsnp, op, info)
/*
* This logs the virtual create of pages pgno to pgno + bucket
- * Since the mpool page-allocation is not really able to be
+ * If HAVE_FTRUNCATE is not supported the mpool page-allocation is not
* transaction protected, we can never undo it. Even in an abort,
* we have to allocate these pages to the hash table if they
* were actually created. In particular, during disaster
@@ -725,7 +675,23 @@ __ham_metagroup_recover(dbenv, dbtp, lsnp, op, info)
if (argp->newalloc)
pgno += argp->bucket;
- if ((ret = __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &pagep)) != 0) {
+ flags = 0;
+ pagep = NULL;
+#ifndef HAVE_FTRUNCATE
+ flags = DB_MPOOL_CREATE;
+#endif
+ ret = __memp_fget(mpf, &pgno, flags, &pagep);
+
+#ifdef HAVE_FTRUNCATE
+ /* If we are undoing, then we don't want to create the page. */
+ if (ret != 0 && DB_REDO(op))
+ ret = __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &pagep);
+ else if (ret == DB_PAGE_NOTFOUND) {
+ groupgrow = 0;
+ goto do_meta;
+ }
+#endif
+ if (ret != 0) {
if (ret != ENOSPC)
goto out;
pgno = 0;
@@ -738,18 +704,32 @@ __ham_metagroup_recover(dbenv, dbtp, lsnp, op, info)
CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->pagelsn);
flags = 0;
- if ((cmp_p == 0 && DB_REDO(op)) || (cmp_n == 0 && DB_UNDO(op))) {
- /*
- * We need to make sure that we redo the allocation of the
- * pages.
- */
- if (DB_REDO(op))
- pagep->lsn = *lsnp;
- else
- pagep->lsn = argp->pagelsn;
+ if (cmp_p == 0 && DB_REDO(op)) {
+ pagep->lsn = *lsnp;
flags = DB_MPOOL_DIRTY;
}
- if ((ret = __memp_fput(mpf, pagep, flags)) != 0)
+ else if (cmp_n == 0 && DB_UNDO(op)) {
+#ifdef HAVE_FTRUNCATE
+ /* If this record allocated the pages give them back. */
+ if (argp->newalloc) {
+ if (pagep != NULL && (ret =
+ __memp_fput(mpf, pagep, DB_MPOOL_DISCARD)) != 0)
+ goto out;
+ pagep = NULL;
+ if ((ret = __memp_ftruncate(mpf, argp->pgno, 0)) != 0)
+ goto out;
+ } else
+#endif
+ {
+ /*
+ * Otherwise just roll the page back to its
+ * previous state.
+ */
+ pagep->lsn = argp->pagelsn;
+ flags = DB_MPOOL_DIRTY;
+ }
+ }
+ if (pagep != NULL && (ret = __memp_fput(mpf, pagep, flags)) != 0)
goto out;
do_meta:
@@ -786,16 +766,26 @@ do_meta:
* Now we need to fix up the spares array. Each entry in the
* spares array indicates the beginning page number for the
* indicated doubling. We need to fill this in whenever the
- * spares array is invalid, since we never reclaim pages from
- * the spares array and we have to allocate the pages to the
+ * spares array is invalid, if we never reclaim pages then
+ * we have to allocate the pages to the
* spares array in both the redo and undo cases.
*/
if (groupgrow &&
+#ifdef HAVE_FTRUNCATE
+ !DB_UNDO(op) &&
+#endif
hcp->hdr->spares[__db_log2(argp->bucket + 1) + 1] == PGNO_INVALID) {
hcp->hdr->spares[__db_log2(argp->bucket + 1) + 1] =
- argp->pgno - argp->bucket - 1;
+ (argp->pgno - argp->bucket) - 1;
did_recover = 1;
}
+#ifdef HAVE_FTRUNCATE
+ if (cmp_n == 0 && groupgrow && DB_UNDO(op)) {
+ hcp->hdr->spares[
+ __db_log2(argp->bucket + 1) + 1] = PGNO_INVALID;
+ did_recover = 1;
+ }
+#endif
/*
* Finally, we need to potentially fix up the last_pgno field
@@ -808,16 +798,18 @@ do_meta:
mmeta_flags = 0;
cmp_n = log_compare(lsnp, &mmeta->lsn);
cmp_p = log_compare(&mmeta->lsn, &argp->mmetalsn);
- if (cmp_p == 0 && DB_REDO(op)) {
+ if (cmp_p == 0 && DB_REDO(op))
mmeta->lsn = *lsnp;
- mmeta_flags = DB_MPOOL_DIRTY;
- } else if (cmp_n == 0 && DB_UNDO(op)) {
+ else if (cmp_n == 0 && DB_UNDO(op))
mmeta->lsn = argp->mmetalsn;
- mmeta_flags = DB_MPOOL_DIRTY;
- }
} else
mmeta = (DBMETA *)hcp->hdr;
+#ifdef HAVE_FTRUNCATE
+ if (cmp_n == 0 && DB_UNDO(op))
+ mmeta->last_pgno = argp->last_pgno;
+ else if (DB_REDO(op))
+#endif
if (mmeta->last_pgno < pgno)
mmeta->last_pgno = pgno;
mmeta_flags = DB_MPOOL_DIRTY;
@@ -875,13 +867,14 @@ __ham_groupalloc_recover(dbenv, dbtp, lsnp, op, info)
pgno = PGNO_BASE_MD;
if ((ret = __memp_fget(mpf, &pgno, 0, &mmeta)) != 0) {
if (DB_REDO(op)) {
- /* Page should have existed. */
ret = __db_pgerr(file_dbp, pgno, ret);
goto out;
- } else {
- ret = 0;
+ } else
goto done;
- }
+ }
+ if (ret != 0) {
+ ret = __db_pgerr(file_dbp, pgno, ret);
+ goto out;
}
cmp_n = log_compare(lsnp, &LSN(mmeta));
@@ -907,24 +900,62 @@ __ham_groupalloc_recover(dbenv, dbtp, lsnp, op, info)
}
} else if (DB_UNDO(op)) {
/*
- * Reset the last page back to its preallocation state.
+ * Fetch the last page and determine if it is in
+ * the post allocation state.
*/
+ pagep = NULL;
if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) == 0) {
+ if (log_compare(&pagep->lsn, lsnp) != 0) {
+ if ((ret = __memp_fput(mpf,
+ pagep, DB_MPOOL_DISCARD)) != 0)
+ goto out;
+ pagep = NULL;
+ }
+ } else if (ret != DB_PAGE_NOTFOUND)
+ goto out;
+#ifdef HAVE_FTRUNCATE
+ COMPQUIET(info, NULL);
+ /*
+ * If the last page was allocated then truncate back
+ * to the first page.
+ */
+ if (pagep != NULL) {
+ if ((ret =
+ __memp_fput(mpf, pagep, DB_MPOOL_DISCARD)) != 0)
+ goto out;
+ if ((ret =
+ __memp_ftruncate(mpf, argp->start_pgno, 0)) != 0)
+ goto out;
+ }
+ /*
+ * If we are rolling back the metapage, then make
+ * sure it reflects the the correct last_pgno.
+ */
+ if (cmp_n == 0) {
+ mmeta->last_pgno = argp->last_pgno;
+ modified = 1;
+ }
+ pgno = 0;
+#else
+ /*
+ * Reset the last page back to its preallocation state.
+ */
+ if (pagep != NULL) {
if (log_compare(&pagep->lsn, lsnp) == 0)
ZERO_LSN(pagep->lsn);
if ((ret =
__memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0)
goto out;
- } else if (ret != DB_PAGE_NOTFOUND)
- goto out;
+ }
/*
- * Always put the pages into the limbo list and free them later.
+ * Put the pages into the limbo list and free them later.
*/
if ((ret = __db_add_limbo(dbenv,
info, argp->fileid, argp->start_pgno, argp->num)) != 0)
goto out;
+#endif
if (cmp_n == 0) {
LSN(mmeta) = argp->meta_lsn;
modified = 1;
@@ -933,7 +964,8 @@ __ham_groupalloc_recover(dbenv, dbtp, lsnp, op, info)
/*
* In both REDO and UNDO, we have grown the file and need to make
- * sure that last_pgno is correct.
+ * sure that last_pgno is correct. If we HAVE_FTRUNCATE pgno
+ * will only be valid on REDO.
*/
if (pgno > mmeta->last_pgno) {
mmeta->last_pgno = pgno;
@@ -942,6 +974,7 @@ __ham_groupalloc_recover(dbenv, dbtp, lsnp, op, info)
done: if (ret == 0)
*lsnp = argp->prev_lsn;
+ ret = 0;
out: if (mmeta != NULL)
(void)__memp_fput(mpf, mmeta, modified ? DB_MPOOL_DIRTY : 0);
@@ -1031,9 +1064,9 @@ __ham_curadj_recover(dbenv, dbtp, lsnp, op, info)
goto done;
/*
- * Undo the adjustment by reinitializing the the cursor
- * to look like the one that was used to do the adustment,
- * then we invert the add so that undo the adjustment.
+ * Undo the adjustment by reinitializing the the cursor to look like
+ * the one that was used to do the adjustment, then we invert the
+ * add so that undo the adjustment.
*/
hcp = (HASH_CURSOR *)dbc->internal;
hcp->pgno = argp->pgno;
diff --git a/db/hash/hash_reclaim.c b/db/hash/hash_reclaim.c
index c1a127153..f0adba7c6 100644
--- a/db/hash/hash_reclaim.c
+++ b/db/hash/hash_reclaim.c
@@ -1,20 +1,16 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: hash_reclaim.c,v 11.17 2004/06/22 18:43:38 margo Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: hash_reclaim.c,v 11.15 2003/06/30 17:20:13 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
-
-#include <string.h>
#endif
#include "db_int.h"
diff --git a/db/hash/hash_stat.c b/db/hash/hash_stat.c
index 2526f0f21..a50e383af 100644
--- a/db/hash/hash_stat.c
+++ b/db/hash/hash_stat.c
@@ -1,16 +1,14 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: hash_stat.c,v 11.66 2004/09/22 03:46:22 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: hash_stat.c,v 11.52 2003/06/30 17:20:13 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
@@ -22,9 +20,9 @@ static const char revid[] = "$Id: hash_stat.c,v 11.52 2003/06/30 17:20:13 bostic
#include "dbinc/db_shash.h"
#include "dbinc/btree.h"
#include "dbinc/hash.h"
-#include "dbinc/lock.h"
#include "dbinc/mp.h"
+#ifdef HAVE_STATISTICS
static int __ham_stat_callback __P((DB *, PAGE *, void *, int *));
/*
@@ -118,6 +116,241 @@ err: if (sp != NULL)
}
/*
+ * __ham_stat_print --
+ * Display hash statistics.
+ *
+ * PUBLIC: int __ham_stat_print __P((DBC *, u_int32_t));
+ */
+int
+__ham_stat_print(dbc, flags)
+ DBC *dbc;
+ u_int32_t flags;
+{
+ static const FN fn[] = {
+ { DB_HASH_DUP, "duplicates" },
+ { DB_HASH_SUBDB, "multiple-databases" },
+ { DB_HASH_DUPSORT, "sorted duplicates" },
+ { 0, NULL }
+ };
+ DB *dbp;
+ DB_ENV *dbenv;
+ DB_HASH_STAT *sp;
+ int lorder, ret;
+ const char *s;
+
+ dbp = dbc->dbp;
+ dbenv = dbp->dbenv;
+
+ if ((ret = __ham_stat(dbc, &sp, 0)) != 0)
+ return (ret);
+
+ if (LF_ISSET(DB_STAT_ALL)) {
+ __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
+ __db_msg(dbenv, "Default Hash database information:");
+ }
+ __db_msg(dbenv, "%lx\tHash magic number", (u_long)sp->hash_magic);
+ __db_msg(dbenv,
+ "%lu\tHash version number", (u_long)sp->hash_version);
+ (void)__db_get_lorder(dbp, &lorder);
+ switch (lorder) {
+ case 1234:
+ s = "Little-endian";
+ break;
+ case 4321:
+ s = "Big-endian";
+ break;
+ default:
+ s = "Unrecognized byte order";
+ break;
+ }
+ __db_msg(dbenv, "%s\tByte order", s);
+ __db_prflags(dbenv, NULL, sp->hash_metaflags, fn, NULL, "\tFlags");
+ __db_dl(dbenv,
+ "Underlying database page size", (u_long)sp->hash_pagesize);
+ __db_dl(dbenv, "Specified fill factor", (u_long)sp->hash_ffactor);
+ __db_dl(dbenv,
+ "Number of keys in the database", (u_long)sp->hash_nkeys);
+ __db_dl(dbenv,
+ "Number of data items in the database", (u_long)sp->hash_ndata);
+
+ __db_dl(dbenv, "Number of hash buckets", (u_long)sp->hash_buckets);
+ __db_dl_pct(dbenv, "Number of bytes free on bucket pages",
+ (u_long)sp->hash_bfree, DB_PCT_PG(
+ sp->hash_bfree, sp->hash_buckets, sp->hash_pagesize), "ff");
+
+ __db_dl(dbenv,
+ "Number of overflow pages", (u_long)sp->hash_bigpages);
+ __db_dl_pct(dbenv, "Number of bytes free in overflow pages",
+ (u_long)sp->hash_big_bfree, DB_PCT_PG(
+ sp->hash_big_bfree, sp->hash_bigpages, sp->hash_pagesize), "ff");
+
+ __db_dl(dbenv,
+ "Number of bucket overflow pages", (u_long)sp->hash_overflows);
+ __db_dl_pct(dbenv,
+ "Number of bytes free in bucket overflow pages",
+ (u_long)sp->hash_ovfl_free, DB_PCT_PG(
+ sp->hash_ovfl_free, sp->hash_overflows, sp->hash_pagesize), "ff");
+
+ __db_dl(dbenv, "Number of duplicate pages", (u_long)sp->hash_dup);
+ __db_dl_pct(dbenv, "Number of bytes free in duplicate pages",
+ (u_long)sp->hash_dup_free, DB_PCT_PG(
+ sp->hash_dup_free, sp->hash_dup, sp->hash_pagesize), "ff");
+
+ __db_dl(dbenv,
+ "Number of pages on the free list", (u_long)sp->hash_free);
+
+ __os_ufree(dbenv, sp);
+
+ return (0);
+}
+
+static int
+__ham_stat_callback(dbp, pagep, cookie, putp)
+ DB *dbp;
+ PAGE *pagep;
+ void *cookie;
+ int *putp;
+{
+ DB_HASH_STAT *sp;
+ DB_BTREE_STAT bstat;
+ db_indx_t indx, len, off, tlen, top;
+ u_int8_t *hk;
+ int ret;
+
+ *putp = 0;
+ sp = cookie;
+
+ switch (pagep->type) {
+ case P_INVALID:
+ /*
+ * Hash pages may be wholly zeroed; this is not a bug.
+ * Obviously such pages have no data, so we can just proceed.
+ */
+ break;
+ case P_HASH:
+ /*
+ * We count the buckets and the overflow pages
+ * separately and tally their bytes separately
+ * as well. We need to figure out if this page
+ * is a bucket.
+ */
+ if (PREV_PGNO(pagep) == PGNO_INVALID)
+ sp->hash_bfree += P_FREESPACE(dbp, pagep);
+ else {
+ sp->hash_overflows++;
+ sp->hash_ovfl_free += P_FREESPACE(dbp, pagep);
+ }
+ top = NUM_ENT(pagep);
+ /* Correct for on-page duplicates and deleted items. */
+ for (indx = 0; indx < top; indx += P_INDX) {
+ switch (*H_PAIRDATA(dbp, pagep, indx)) {
+ case H_OFFDUP:
+ break;
+ case H_OFFPAGE:
+ case H_KEYDATA:
+ sp->hash_ndata++;
+ break;
+ case H_DUPLICATE:
+ tlen = LEN_HDATA(dbp, pagep, 0, indx);
+ hk = H_PAIRDATA(dbp, pagep, indx);
+ for (off = 0; off < tlen;
+ off += len + 2 * sizeof(db_indx_t)) {
+ sp->hash_ndata++;
+ memcpy(&len,
+ HKEYDATA_DATA(hk)
+ + off, sizeof(db_indx_t));
+ }
+ break;
+ default:
+ return (__db_pgfmt(dbp->dbenv, PGNO(pagep)));
+ }
+ }
+ sp->hash_nkeys += H_NUMPAIRS(pagep);
+ break;
+ case P_IBTREE:
+ case P_IRECNO:
+ case P_LBTREE:
+ case P_LRECNO:
+ case P_LDUP:
+ /*
+ * These are all btree pages; get a correct
+ * cookie and call them. Then add appropriate
+ * fields into our stat structure.
+ */
+ memset(&bstat, 0, sizeof(bstat));
+ if ((ret = __bam_stat_callback(dbp, pagep, &bstat, putp)) != 0)
+ return (ret);
+ sp->hash_dup++;
+ sp->hash_dup_free += bstat.bt_leaf_pgfree +
+ bstat.bt_dup_pgfree + bstat.bt_int_pgfree;
+ sp->hash_ndata += bstat.bt_ndata;
+ break;
+ case P_OVERFLOW:
+ sp->hash_bigpages++;
+ sp->hash_big_bfree += P_OVFLSPACE(dbp, dbp->pgsize, pagep);
+ break;
+ default:
+ return (__db_pgfmt(dbp->dbenv, PGNO(pagep)));
+ }
+
+ return (0);
+}
+
+/*
+ * __ham_print_cursor --
+ * Display the current cursor.
+ *
+ * PUBLIC: void __ham_print_cursor __P((DBC *));
+ */
+void
+__ham_print_cursor(dbc)
+ DBC *dbc;
+{
+ static const FN fn[] = {
+ { H_CONTINUE, "H_CONTINUE" },
+ { H_DELETED, "H_DELETED" },
+ { H_DIRTY, "H_DIRTY" },
+ { H_DUPONLY, "H_DUPONLY" },
+ { H_EXPAND, "H_EXPAND" },
+ { H_ISDUP, "H_ISDUP" },
+ { H_NEXT_NODUP, "H_NEXT_NODUP" },
+ { H_NOMORE, "H_NOMORE" },
+ { H_OK, "H_OK" },
+ { 0, NULL }
+ };
+ DB_ENV *dbenv;
+ HASH_CURSOR *cp;
+
+ dbenv = dbc->dbp->dbenv;
+ cp = (HASH_CURSOR *)dbc->internal;
+
+ STAT_ULONG("Bucket traversing", cp->bucket);
+ STAT_ULONG("Bucket locked", cp->lbucket);
+ STAT_ULONG("Duplicate set offset", cp->dup_off);
+ STAT_ULONG("Current duplicate length", cp->dup_len);
+ STAT_ULONG("Total duplicate set length", cp->dup_tlen);
+ STAT_ULONG("Bytes needed for add", cp->seek_size);
+ STAT_ULONG("Page on which we can insert", cp->seek_found_page);
+ STAT_ULONG("Order", cp->order);
+ __db_prflags(dbenv, NULL, cp->flags, fn, NULL, "\tInternal Flags");
+}
+
+#else /* !HAVE_STATISTICS */
+
+int
+__ham_stat(dbc, spp, flags)
+ DBC *dbc;
+ void *spp;
+ u_int32_t flags;
+{
+ COMPQUIET(spp, NULL);
+ COMPQUIET(flags, 0);
+
+ return (__db_stat_not_built(dbc->dbp->dbenv));
+}
+#endif
+
+/*
* __ham_traverse
* Traverse an entire hash table. We use the callback so that we
* can use this both for stat collection and for deallocation.
@@ -237,7 +470,13 @@ __ham_traverse(dbc, mode, callback, cookie, look_past_max)
goto err;
break;
case H_KEYDATA:
+ case H_DUPLICATE:
break;
+ default:
+ DB_ASSERT(0);
+ ret = EINVAL;
+ goto err;
+
}
}
@@ -254,9 +493,6 @@ __ham_traverse(dbc, mode, callback, cookie, look_past_max)
if (ret != 0)
goto err;
- if (STD_LOCKING(dbc))
- (void)__lock_put(dbp->dbenv, &hcp->lock);
-
if (hcp->page != NULL) {
if ((ret = __memp_fput(mpf, hcp->page, 0)) != 0)
return (ret);
@@ -269,92 +505,3 @@ err: if (opd != NULL &&
ret = t_ret;
return (ret);
}
-
-static int
-__ham_stat_callback(dbp, pagep, cookie, putp)
- DB *dbp;
- PAGE *pagep;
- void *cookie;
- int *putp;
-{
- DB_HASH_STAT *sp;
- DB_BTREE_STAT bstat;
- db_indx_t indx, len, off, tlen, top;
- u_int8_t *hk;
- int ret;
-
- *putp = 0;
- sp = cookie;
-
- switch (pagep->type) {
- case P_INVALID:
- /*
- * Hash pages may be wholly zeroed; this is not a bug.
- * Obviously such pages have no data, so we can just proceed.
- */
- break;
- case P_HASH:
- /*
- * We count the buckets and the overflow pages
- * separately and tally their bytes separately
- * as well. We need to figure out if this page
- * is a bucket.
- */
- if (PREV_PGNO(pagep) == PGNO_INVALID)
- sp->hash_bfree += P_FREESPACE(dbp, pagep);
- else {
- sp->hash_overflows++;
- sp->hash_ovfl_free += P_FREESPACE(dbp, pagep);
- }
- top = NUM_ENT(pagep);
- /* Correct for on-page duplicates and deleted items. */
- for (indx = 0; indx < top; indx += P_INDX) {
- switch (*H_PAIRDATA(dbp, pagep, indx)) {
- case H_OFFDUP:
- break;
- case H_OFFPAGE:
- case H_KEYDATA:
- sp->hash_ndata++;
- break;
- case H_DUPLICATE:
- tlen = LEN_HDATA(dbp, pagep, 0, indx);
- hk = H_PAIRDATA(dbp, pagep, indx);
- for (off = 0; off < tlen;
- off += len + 2 * sizeof (db_indx_t)) {
- sp->hash_ndata++;
- memcpy(&len,
- HKEYDATA_DATA(hk)
- + off, sizeof(db_indx_t));
- }
- }
- }
- sp->hash_nkeys += H_NUMPAIRS(pagep);
- break;
- case P_IBTREE:
- case P_IRECNO:
- case P_LBTREE:
- case P_LRECNO:
- case P_LDUP:
- /*
- * These are all btree pages; get a correct
- * cookie and call them. Then add appropriate
- * fields into our stat structure.
- */
- memset(&bstat, 0, sizeof(bstat));
- if ((ret = __bam_stat_callback(dbp, pagep, &bstat, putp)) != 0)
- return (ret);
- sp->hash_dup++;
- sp->hash_dup_free += bstat.bt_leaf_pgfree +
- bstat.bt_dup_pgfree + bstat.bt_int_pgfree;
- sp->hash_ndata += bstat.bt_ndata;
- break;
- case P_OVERFLOW:
- sp->hash_bigpages++;
- sp->hash_big_bfree += P_OVFLSPACE(dbp, dbp->pgsize, pagep);
- break;
- default:
- return (__db_pgfmt(dbp->dbenv, pagep->pgno));
- }
-
- return (0);
-}
diff --git a/db/hash/hash_stub.c b/db/hash/hash_stub.c
index 906331990..7bbe925c7 100644
--- a/db/hash/hash_stub.c
+++ b/db/hash/hash_stub.c
@@ -1,15 +1,15 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: hash_stub.c,v 1.10 2004/09/29 15:35:14 bostic Exp $
*/
-#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: hash_stub.c,v 1.4 2003/07/01 19:47:14 bostic Exp $";
-#endif /* not lint */
+#include "db_config.h"
+#ifndef HAVE_HASH
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#endif
@@ -121,14 +121,6 @@ __ham_c_init(dbc)
return (__db_no_hash_am(dbc->dbp->dbenv));
}
-void
-__ham_cprint(dbc)
- DBC *dbc;
-{
- COMPQUIET(dbc, NULL);
- return;
-}
-
int
__ham_db_close(dbp)
DB *dbp;
@@ -146,18 +138,6 @@ __ham_db_create(dbp)
}
int
-__ham_init_getpgnos(dbenv, dtabp, dtabsizep)
- DB_ENV *dbenv;
- int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- size_t *dtabsizep;
-{
- COMPQUIET(dbenv, NULL);
- COMPQUIET(dtabp, NULL);
- COMPQUIET(dtabsizep, NULL);
- return (0);
-}
-
-int
__ham_init_print(dbenv, dtabp, dtabsizep)
DB_ENV *dbenv;
int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
@@ -275,6 +255,13 @@ __ham_pgout(dbenv, dummydbp, pg, pp, cookie)
return (__db_no_hash_am(dbenv));
}
+void
+__ham_print_cursor(dbc)
+ DBC *dbc;
+{
+ (void)__db_no_hash_am(dbc->dbp->dbenv);
+}
+
int
__ham_quick_delete(dbc)
DBC *dbc;
@@ -322,6 +309,15 @@ __ham_stat(dbc, spp, flags)
}
int
+__ham_stat_print(dbc, flags)
+ DBC *dbc;
+ u_int32_t flags;
+{
+ COMPQUIET(flags, 0);
+ return (__db_no_hash_am(dbc->dbp->dbenv));
+}
+
+int
__ham_truncate(dbc, countp)
DBC *dbc;
u_int32_t *countp;
@@ -392,3 +388,4 @@ __ham_vrfy_structure(dbp, vdp, meta_pgno, flags)
COMPQUIET(flags, 0);
return (__db_no_hash_am(dbp->dbenv));
}
+#endif /* !HAVE_HASH */
diff --git a/db/hash/hash_upgrade.c b/db/hash/hash_upgrade.c
index 875d90f09..b626138ef 100644
--- a/db/hash/hash_upgrade.c
+++ b/db/hash/hash_upgrade.c
@@ -1,19 +1,17 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996-2003
+ * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
+ *
+ * $Id: hash_upgrade.c,v 11.35 2004/04/06 12:38:08 bostic Exp $
*/
-#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: hash_upgrade.c,v 11.33 2003/01/08 05:03:56 bostic Exp $";
-#endif /* not lint */
+#include "db_config.h"
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
-#include <limits.h>
#include <string.h>
#endif
@@ -38,8 +36,8 @@ __ham_30_hashmeta(dbp, real_name, obuf)
HASHHDR *oldmeta;
HMETA30 newmeta;
u_int32_t *o_spares, *n_spares;
- u_int32_t fillf, maxb, nelem;
- int i, max_entry, ret;
+ u_int32_t fillf, i, maxb, max_entry, nelem;
+ int ret;
dbenv = dbp->dbenv;
memset(&newmeta, 0, sizeof(newmeta));
diff --git a/db/hash/hash_verify.c b/db/hash/hash_verify.c
index 1aa09454b..fb76fbef7 100644
--- a/db/hash/hash_verify.c
+++ b/db/hash/hash_verify.c
@@ -1,18 +1,14 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2003
+ * Copyright (c) 1999-2004
* Sleepycat Software. All rights reserved.
*
- * $Id: hash_verify.c,v 1.58 2003/06/30 17:20:13 bostic Exp $
+ * $Id: hash_verify.c,v 1.62 2004/10/11 18:47:50 bostic Exp $
*/
#include "db_config.h"
-#ifndef lint
-static const char revid[] = "$Id: hash_verify.c,v 1.58 2003/06/30 17:20:13 bostic Exp $";
-#endif /* not lint */
-
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
@@ -175,6 +171,9 @@ __ham_vrfy_meta(dbp, vdp, m, pgno, flags)
err: if ((t_ret =
__db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0)
ret = t_ret;
+ if (LF_ISSET(DB_SALVAGE) &&
+ (t_ret = __db_salvage_markdone(vdp, pgno)) != 0 && ret == 0)
+ ret = t_ret;
return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
}
@@ -202,11 +201,6 @@ __ham_vrfy(dbp, vdp, h, pgno, flags)
if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
return (ret);
- /* Sanity check our flags and page type. */
- if ((ret = __db_fchk(dbp->dbenv, "__ham_vrfy",
- flags, DB_AGGRESSIVE | DB_NOORDERCHK | DB_SALVAGE)) != 0)
- goto err;
-
if (TYPE(h) != P_HASH) {
TYPE_ERR_PRINT(dbp->dbenv, "__ham_vrfy", pgno, TYPE(h));
DB_ASSERT(0);
@@ -861,7 +855,7 @@ __ham_salvage(dbp, vdp, pgno, h, handle, callback, flags)
keydata: memcpy(buf, HKEYDATA_DATA(hk), len);
dbt.size = len;
dbt.data = buf;
- if ((ret = __db_prdbt(&dbt,
+ if ((ret = __db_vrfy_prdbt(&dbt,
0, " ", handle, callback, 0, vdp)) != 0)
err_ret = ret;
break;
@@ -875,11 +869,11 @@ keydata: memcpy(buf, HKEYDATA_DATA(hk), len);
if ((ret = __db_safe_goff(dbp, vdp,
dpgno, &dbt, &buf, flags)) != 0) {
err_ret = ret;
- (void)__db_prdbt(&unkdbt, 0, " ",
+ (void)__db_vrfy_prdbt(&unkdbt, 0, " ",
handle, callback, 0, vdp);
break;
}
- if ((ret = __db_prdbt(&dbt,
+ if ((ret = __db_vrfy_prdbt(&dbt,
0, " ", handle, callback, 0, vdp)) != 0)
err_ret = ret;
break;
@@ -892,7 +886,8 @@ keydata: memcpy(buf, HKEYDATA_DATA(hk), len);
HOFFPAGE_PGNO(hk), sizeof(dpgno));
/* UNKNOWN iff pgno is bad or we're a key. */
if (!IS_VALID_PGNO(dpgno) || (i % 2 == 0)) {
- if ((ret = __db_prdbt(&unkdbt, 0, " ",
+ if ((ret =
+ __db_vrfy_prdbt(&unkdbt, 0, " ",
handle, callback, 0, vdp)) != 0)
err_ret = ret;
} else if ((ret = __db_salvage_duptree(dbp,
@@ -935,7 +930,7 @@ keydata: memcpy(buf, HKEYDATA_DATA(hk), len);
memcpy(buf, hk + tlen, dlen);
dbt.size = dlen;
dbt.data = buf;
- if ((ret = __db_prdbt(&dbt, 0, " ",
+ if ((ret = __db_vrfy_prdbt(&dbt, 0, " ",
handle, callback, 0, vdp)) != 0)
err_ret = ret;
tlen += sizeof(db_indx_t);