diff options
author | jbj <devnull@localhost> | 2004-10-16 01:31:54 +0000 |
---|---|---|
committer | jbj <devnull@localhost> | 2004-10-16 01:31:54 +0000 |
commit | d03f220fde879509cab2ac1c73b71b7efb52b737 (patch) | |
tree | 1e34bfadac0a6618d0e9a7933bad90063a785acf /db/hash | |
parent | 2dc699bfe049b9319ea3719f604d25940ff52004 (diff) | |
download | rpm-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.c | 183 | ||||
-rw-r--r-- | db/hash/hash.src | 10 | ||||
-rw-r--r-- | db/hash/hash_auto.c | 1707 | ||||
-rw-r--r-- | db/hash/hash_autop.c | 486 | ||||
-rw-r--r-- | db/hash/hash_conv.c | 11 | ||||
-rw-r--r-- | db/hash/hash_dup.c | 65 | ||||
-rw-r--r-- | db/hash/hash_func.c | 8 | ||||
-rw-r--r-- | db/hash/hash_meta.c | 53 | ||||
-rw-r--r-- | db/hash/hash_method.c | 20 | ||||
-rw-r--r-- | db/hash/hash_open.c | 131 | ||||
-rw-r--r-- | db/hash/hash_page.c | 148 | ||||
-rw-r--r-- | db/hash/hash_rec.c | 349 | ||||
-rw-r--r-- | db/hash/hash_reclaim.c | 10 | ||||
-rw-r--r-- | db/hash/hash_stat.c | 343 | ||||
-rw-r--r-- | db/hash/hash_stub.c | 47 | ||||
-rw-r--r-- | db/hash/hash_upgrade.c | 14 | ||||
-rw-r--r-- | db/hash/hash_verify.c | 27 |
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); |