Commit d8c07492 authored by jimw@mysql.com's avatar jimw@mysql.com

Import BDB 4.3.28

parent c2c0cb18
/*- /*-
* $Id: LICENSE,v 11.9 2002/01/11 15:51:10 bostic Exp $ * $Id: LICENSE,v 11.12 2004/03/30 20:49:44 bostic Exp $
*/ */
The following is the license that applies to this copy of the Berkeley DB The following is the license that applies to this copy of the Berkeley DB
software. For a license to use the Berkeley DB software under conditions software. For a license to use the Berkeley DB software under conditions
other than those described here, or to purchase support for this software, other than those described here, or to purchase support for this software,
please contact Sleepycat Software by email at db@sleepycat.com, or on the please contact Sleepycat Software by email at info@sleepycat.com, or on
Web at http://www.sleepycat.com. the Web at http://www.sleepycat.com.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
/* /*
* Copyright (c) 1990-2002 * Copyright (c) 1990-2004
* Sleepycat Software. All rights reserved. * Sleepycat Software. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
......
/*- /*-
* See the file LICENSE for redistribution information. * See the file LICENSE for redistribution information.
* *
* Copyright (c) 1996-2002 * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved. * Sleepycat Software. All rights reserved.
*/ */
/* /*
...@@ -38,14 +38,12 @@ ...@@ -38,14 +38,12 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
*
* $Id: bt_compare.c,v 11.20 2004/02/21 15:54:44 bostic Exp $
*/ */
#include "db_config.h" #include "db_config.h"
#ifndef lint
static const char revid[] = "$Id: bt_compare.c,v 11.17 2002/03/27 04:30:42 bostic Exp $";
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h> #include <sys/types.h>
#endif #endif
...@@ -204,8 +202,12 @@ __bam_defpfx(dbp, a, b) ...@@ -204,8 +202,12 @@ __bam_defpfx(dbp, a, b)
return (cnt); return (cnt);
/* /*
* We know that a->size must be <= b->size, or they wouldn't be * They match up to the smaller of the two sizes.
* in this order. * Collate the longer after the shorter.
*/ */
return (a->size < b->size ? a->size + 1 : a->size); if (a->size < b->size)
return (a->size + 1);
if (b->size < a->size)
return (b->size + 1);
return (b->size);
} }
/*- /*-
* See the file LICENSE for redistribution information. * See the file LICENSE for redistribution information.
* *
* Copyright (c) 1996-2002 * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved. * Sleepycat Software. All rights reserved.
*
* $Id: bt_conv.c,v 11.15 2004/01/28 03:35:48 bostic Exp $
*/ */
#include "db_config.h" #include "db_config.h"
#ifndef lint
static const char revid[] = "$Id: bt_conv.c,v 11.13 2002/08/06 06:11:12 bostic Exp $";
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h> #include <sys/types.h>
#endif #endif
......
/*- /*-
* See the file LICENSE for redistribution information. * See the file LICENSE for redistribution information.
* *
* Copyright (c) 1996-2002 * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved. * Sleepycat Software. All rights reserved.
*
* $Id: bt_curadj.c,v 11.37 2004/03/13 14:11:33 bostic Exp $
*/ */
#include "db_config.h" #include "db_config.h"
#ifndef lint
static const char revid[] = "$Id: bt_curadj.c,v 11.30 2002/07/03 19:03:48 bostic Exp $";
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h> #include <sys/types.h>
#endif #endif
...@@ -21,30 +19,6 @@ static const char revid[] = "$Id: bt_curadj.c,v 11.30 2002/07/03 19:03:48 bostic ...@@ -21,30 +19,6 @@ static const char revid[] = "$Id: bt_curadj.c,v 11.30 2002/07/03 19:03:48 bostic
static int __bam_opd_cursor __P((DB *, DBC *, db_pgno_t, u_int32_t, u_int32_t)); static int __bam_opd_cursor __P((DB *, DBC *, db_pgno_t, u_int32_t, u_int32_t));
#ifdef DEBUG
/*
* __bam_cprint --
* Display the current internal cursor.
*
* PUBLIC: void __bam_cprint __P((DBC *));
*/
void
__bam_cprint(dbc)
DBC *dbc;
{
BTREE_CURSOR *cp;
cp = (BTREE_CURSOR *)dbc->internal;
fprintf(stderr, "\tinternal: ovflsize: %lu", (u_long)cp->ovflsize);
if (dbc->dbtype == DB_RECNO)
fprintf(stderr, " recno: %lu", (u_long)cp->recno);
if (F_ISSET(cp, C_DELETED))
fprintf(stderr, " (deleted)");
fprintf(stderr, "\n");
}
#endif
/* /*
* Cursor adjustments are logged if they are for subtransactions. This is * Cursor adjustments are logged if they are for subtransactions. This is
* because it's possible for a subtransaction to adjust cursors which will * because it's possible for a subtransaction to adjust cursors which will
...@@ -98,6 +72,19 @@ __bam_ca_delete(dbp, pgno, indx, delete) ...@@ -98,6 +72,19 @@ __bam_ca_delete(dbp, pgno, indx, delete)
dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) { dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
cp = (BTREE_CURSOR *)dbc->internal; cp = (BTREE_CURSOR *)dbc->internal;
if (cp->pgno == pgno && cp->indx == indx) { if (cp->pgno == pgno && cp->indx == indx) {
/*
* [#8032] This assert is checking
* for possible race conditions where we
* hold a cursor position without a lock.
* Unfortunately, there are paths in the
* Btree code that do not satisfy these
* conditions. None of them are known to
* be a problem, but this assert should
* be re-activated when the Btree stack
* code is re-written.
DB_ASSERT(!STD_LOCKING(dbc) ||
cp->lock_mode != DB_LOCK_NG);
*/
if (delete) if (delete)
F_SET(cp, C_DELETED); F_SET(cp, C_DELETED);
else else
...@@ -192,7 +179,10 @@ __bam_ca_di(my_dbc, pgno, indx, adjust) ...@@ -192,7 +179,10 @@ __bam_ca_di(my_dbc, pgno, indx, adjust)
if (cp->pgno == pgno && cp->indx >= indx) { if (cp->pgno == pgno && cp->indx >= indx) {
/* Cursor indices should never be negative. */ /* Cursor indices should never be negative. */
DB_ASSERT(cp->indx != 0 || adjust > 0); DB_ASSERT(cp->indx != 0 || adjust > 0);
/* [#8032]
DB_ASSERT(!STD_LOCKING(dbc) ||
cp->lock_mode != DB_LOCK_NG);
*/
cp->indx += adjust; cp->indx += adjust;
if (my_txn != NULL && dbc->txn != my_txn) if (my_txn != NULL && dbc->txn != my_txn)
found = 1; found = 1;
...@@ -203,8 +193,8 @@ __bam_ca_di(my_dbc, pgno, indx, adjust) ...@@ -203,8 +193,8 @@ __bam_ca_di(my_dbc, pgno, indx, adjust)
MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp); MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);
if (found != 0 && DBC_LOGGING(my_dbc)) { if (found != 0 && DBC_LOGGING(my_dbc)) {
if ((ret = __bam_curadj_log(dbp, my_dbc->txn, if ((ret = __bam_curadj_log(dbp, my_dbc->txn, &lsn, 0,
&lsn, 0, DB_CA_DI, pgno, 0, 0, adjust, indx, 0)) != 0) DB_CA_DI, pgno, 0, 0, (u_int32_t)adjust, indx, 0)) != 0)
return (ret); return (ret);
} }
...@@ -319,6 +309,10 @@ loop: MUTEX_THREAD_LOCK(dbenv, dbp->mutexp); ...@@ -319,6 +309,10 @@ loop: MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
continue; continue;
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp); MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
/* [#8032]
DB_ASSERT(!STD_LOCKING(dbc) ||
orig_cp->lock_mode != DB_LOCK_NG);
*/
if ((ret = __bam_opd_cursor(dbp, if ((ret = __bam_opd_cursor(dbp,
dbc, first, tpgno, ti)) !=0) dbc, first, tpgno, ti)) !=0)
return (ret); return (ret);
...@@ -388,7 +382,7 @@ loop: MUTEX_THREAD_LOCK(dbenv, dbp->mutexp); ...@@ -388,7 +382,7 @@ loop: MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
!= ti) != ti)
continue; continue;
MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp); MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
if ((ret = orig_cp->opd->c_close(orig_cp->opd)) != 0) if ((ret = __db_c_close(orig_cp->opd)) != 0)
return (ret); return (ret);
orig_cp->opd = NULL; orig_cp->opd = NULL;
orig_cp->indx = fi; orig_cp->indx = fi;
...@@ -442,6 +436,10 @@ __bam_ca_rsplit(my_dbc, fpgno, tpgno) ...@@ -442,6 +436,10 @@ __bam_ca_rsplit(my_dbc, fpgno, tpgno)
continue; continue;
if (dbc->internal->pgno == fpgno) { if (dbc->internal->pgno == fpgno) {
dbc->internal->pgno = tpgno; dbc->internal->pgno = tpgno;
/* [#8032]
DB_ASSERT(!STD_LOCKING(dbc) ||
dbc->internal->lock_mode != DB_LOCK_NG);
*/
if (my_txn != NULL && dbc->txn != my_txn) if (my_txn != NULL && dbc->txn != my_txn)
found = 1; found = 1;
} }
...@@ -506,6 +504,10 @@ __bam_ca_split(my_dbc, ppgno, lpgno, rpgno, split_indx, cleft) ...@@ -506,6 +504,10 @@ __bam_ca_split(my_dbc, ppgno, lpgno, rpgno, split_indx, cleft)
continue; continue;
cp = dbc->internal; cp = dbc->internal;
if (cp->pgno == ppgno) { if (cp->pgno == ppgno) {
/* [#8032]
DB_ASSERT(!STD_LOCKING(dbc) ||
cp->lock_mode != DB_LOCK_NG);
*/
if (my_txn != NULL && dbc->txn != my_txn) if (my_txn != NULL && dbc->txn != my_txn)
found = 1; found = 1;
if (cp->indx < split_indx) { if (cp->indx < split_indx) {
......
This diff is collapsed.
/*- /*-
* See the file LICENSE for redistribution information. * See the file LICENSE for redistribution information.
* *
* Copyright (c) 1996-2002 * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved. * Sleepycat Software. All rights reserved.
*/ */
/* /*
...@@ -38,14 +38,12 @@ ...@@ -38,14 +38,12 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
*
* $Id: bt_delete.c,v 11.49 2004/02/27 12:38:28 bostic Exp $
*/ */
#include "db_config.h" #include "db_config.h"
#ifndef lint
static const char revid[] = "$Id: bt_delete.c,v 11.44 2002/07/03 19:03:49 bostic Exp $";
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h> #include <sys/types.h>
...@@ -57,6 +55,7 @@ static const char revid[] = "$Id: bt_delete.c,v 11.44 2002/07/03 19:03:49 bostic ...@@ -57,6 +55,7 @@ static const char revid[] = "$Id: bt_delete.c,v 11.44 2002/07/03 19:03:49 bostic
#include "dbinc/db_shash.h" #include "dbinc/db_shash.h"
#include "dbinc/btree.h" #include "dbinc/btree.h"
#include "dbinc/lock.h" #include "dbinc/lock.h"
#include "dbinc/mp.h"
/* /*
* __bam_ditem -- * __bam_ditem --
...@@ -161,7 +160,7 @@ __bam_ditem(dbc, h, indx) ...@@ -161,7 +160,7 @@ __bam_ditem(dbc, h, indx)
/* Delete the item and mark the page dirty. */ /* Delete the item and mark the page dirty. */
if ((ret = __db_ditem(dbc, h, indx, nbytes)) != 0) if ((ret = __db_ditem(dbc, h, indx, nbytes)) != 0)
return (ret); return (ret);
if ((ret = mpf->set(mpf, h, DB_MPOOL_DIRTY)) != 0) if ((ret = __memp_fset(mpf, h, DB_MPOOL_DIRTY)) != 0)
return (ret); return (ret);
return (0); return (0);
...@@ -211,7 +210,7 @@ __bam_adjindx(dbc, h, indx, indx_copy, is_insert) ...@@ -211,7 +210,7 @@ __bam_adjindx(dbc, h, indx, indx_copy, is_insert)
memmove(&inp[indx], &inp[indx + O_INDX], memmove(&inp[indx], &inp[indx + O_INDX],
sizeof(db_indx_t) * (NUM_ENT(h) - indx)); sizeof(db_indx_t) * (NUM_ENT(h) - indx));
} }
if ((ret = mpf->set(mpf, h, DB_MPOOL_DIRTY)) != 0) if ((ret = __memp_fset(mpf, h, DB_MPOOL_DIRTY)) != 0)
return (ret); return (ret);
return (0); return (0);
...@@ -260,9 +259,10 @@ __bam_dpages(dbc, stack_epg) ...@@ -260,9 +259,10 @@ __bam_dpages(dbc, stack_epg)
*/ */
ret = 0; ret = 0;
for (epg = cp->sp; epg < stack_epg; ++epg) { for (epg = cp->sp; epg < stack_epg; ++epg) {
if ((t_ret = mpf->put(mpf, epg->page, 0)) != 0 && ret == 0) if ((t_ret = __memp_fput(mpf, epg->page, 0)) != 0 && ret == 0)
ret = t_ret;
if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
(void)__TLPUT(dbc, epg->lock);
} }
if (ret != 0) if (ret != 0)
goto err; goto err;
...@@ -276,7 +276,7 @@ __bam_dpages(dbc, stack_epg) ...@@ -276,7 +276,7 @@ __bam_dpages(dbc, stack_epg)
* It will deadlock here. Before we unlink the subtree, we relink the * It will deadlock here. Before we unlink the subtree, we relink the
* leaf page chain. * leaf page chain.
*/ */
if ((ret = __db_relink(dbc, DB_REM_PAGE, cp->csp->page, NULL, 1)) != 0) if ((ret = __bam_relink(dbc, cp->csp->page, NULL)) != 0)
goto err; goto err;
/* /*
...@@ -295,9 +295,11 @@ __bam_dpages(dbc, stack_epg) ...@@ -295,9 +295,11 @@ __bam_dpages(dbc, stack_epg)
pgno = PGNO(epg->page); pgno = PGNO(epg->page);
nitems = NUM_ENT(epg->page); nitems = NUM_ENT(epg->page);
if ((ret = mpf->put(mpf, epg->page, 0)) != 0) ret = __memp_fput(mpf, epg->page, 0);
if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
ret = t_ret;
if (ret != 0)
goto err_inc; goto err_inc;
(void)__TLPUT(dbc, epg->lock);
/* Free the rest of the pages in the stack. */ /* Free the rest of the pages in the stack. */
while (++epg <= cp->csp) { while (++epg <= cp->csp) {
...@@ -314,18 +316,19 @@ __bam_dpages(dbc, stack_epg) ...@@ -314,18 +316,19 @@ __bam_dpages(dbc, stack_epg)
goto err; goto err;
} }
if ((ret = __db_free(dbc, epg->page)) != 0) { ret = __db_free(dbc, epg->page);
epg->page = NULL; epg->page = NULL;
if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
ret = t_ret;
if (ret != 0)
goto err_inc; goto err_inc;
}
(void)__TLPUT(dbc, epg->lock);
} }
if (0) { if (0) {
err_inc: ++epg; err_inc: ++epg;
err: for (; epg <= cp->csp; ++epg) { err: for (; epg <= cp->csp; ++epg) {
if (epg->page != NULL) if (epg->page != NULL)
(void)mpf->put(mpf, epg->page, 0); (void)__memp_fput(mpf, epg->page, 0);
(void)__TLPUT(dbc, epg->lock); (void)__TLPUT(dbc, epg->lock);
} }
BT_STK_CLR(cp); BT_STK_CLR(cp);
...@@ -354,7 +357,7 @@ err: for (; epg <= cp->csp; ++epg) { ...@@ -354,7 +357,7 @@ err: for (; epg <= cp->csp; ++epg) {
if ((ret = if ((ret =
__db_lget(dbc, 0, pgno, DB_LOCK_WRITE, 0, &p_lock)) != 0) __db_lget(dbc, 0, pgno, DB_LOCK_WRITE, 0, &p_lock)) != 0)
goto stop; goto stop;
if ((ret = mpf->get(mpf, &pgno, 0, &parent)) != 0) if ((ret = __memp_fget(mpf, &pgno, 0, &parent)) != 0)
goto stop; goto stop;
if (NUM_ENT(parent) != 1) if (NUM_ENT(parent) != 1)
...@@ -384,7 +387,7 @@ err: for (; epg <= cp->csp; ++epg) { ...@@ -384,7 +387,7 @@ err: for (; epg <= cp->csp; ++epg) {
if ((ret = if ((ret =
__db_lget(dbc, 0, pgno, DB_LOCK_WRITE, 0, &c_lock)) != 0) __db_lget(dbc, 0, pgno, DB_LOCK_WRITE, 0, &c_lock)) != 0)
goto stop; goto stop;
if ((ret = mpf->get(mpf, &pgno, 0, &child)) != 0) if ((ret = __memp_fget(mpf, &pgno, 0, &child)) != 0)
goto stop; goto stop;
/* Log the change. */ /* Log the change. */
...@@ -423,9 +426,9 @@ err: for (; epg <= cp->csp; ++epg) { ...@@ -423,9 +426,9 @@ err: for (; epg <= cp->csp; ++epg) {
RE_NREC_SET(parent, rcnt); RE_NREC_SET(parent, rcnt);
/* Mark the pages dirty. */ /* Mark the pages dirty. */
if ((ret = mpf->set(mpf, parent, DB_MPOOL_DIRTY)) != 0) if ((ret = __memp_fset(mpf, parent, DB_MPOOL_DIRTY)) != 0)
goto stop; goto stop;
if ((ret = mpf->set(mpf, child, DB_MPOOL_DIRTY)) != 0) if ((ret = __memp_fset(mpf, child, DB_MPOOL_DIRTY)) != 0)
goto stop; goto stop;
/* Adjust the cursors. */ /* Adjust the cursors. */
...@@ -446,15 +449,125 @@ err: for (; epg <= cp->csp; ++epg) { ...@@ -446,15 +449,125 @@ err: for (; epg <= cp->csp; ++epg) {
if (0) { if (0) {
stop: done = 1; stop: done = 1;
} }
(void)__TLPUT(dbc, p_lock); if ((t_ret = __TLPUT(dbc, p_lock)) != 0 && ret == 0)
ret = t_ret;
if (parent != NULL && if (parent != NULL &&
(t_ret = mpf->put(mpf, parent, 0)) != 0 && ret == 0) (t_ret = __memp_fput(mpf, parent, 0)) != 0 && ret == 0)
ret = t_ret;
if ((t_ret = __TLPUT(dbc, c_lock)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
(void)__TLPUT(dbc, c_lock);
if (child != NULL && if (child != NULL &&
(t_ret = mpf->put(mpf, child, 0)) != 0 && ret == 0) (t_ret = __memp_fput(mpf, child, 0)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
} }
return (ret); return (ret);
} }
/*
* __bam_relink --
* Relink around a deleted page.
*
* PUBLIC: int __bam_relink __P((DBC *, PAGE *, PAGE **));
*/
int
__bam_relink(dbc, pagep, new_next)
DBC *dbc;
PAGE *pagep, **new_next;
{
DB *dbp;
PAGE *np, *pp;
DB_LOCK npl, ppl;
DB_LSN *nlsnp, *plsnp, ret_lsn;
DB_MPOOLFILE *mpf;
int ret, t_ret;
dbp = dbc->dbp;
np = pp = NULL;
LOCK_INIT(npl);
LOCK_INIT(ppl);
nlsnp = plsnp = NULL;
mpf = dbp->mpf;
ret = 0;
/*
* Retrieve and lock the one/two pages. For a remove, we may need
* two pages (the before and after). For an add, we only need one
* because, the split took care of the prev.
*/
if (pagep->next_pgno != PGNO_INVALID) {
if ((ret = __db_lget(dbc,
0, pagep->next_pgno, DB_LOCK_WRITE, 0, &npl)) != 0)
goto err;
if ((ret = __memp_fget(mpf, &pagep->next_pgno, 0, &np)) != 0) {
ret = __db_pgerr(dbp, pagep->next_pgno, ret);
goto err;
}
nlsnp = &np->lsn;
}
if (pagep->prev_pgno != PGNO_INVALID) {
if ((ret = __db_lget(dbc,
0, pagep->prev_pgno, DB_LOCK_WRITE, 0, &ppl)) != 0)
goto err;
if ((ret = __memp_fget(mpf, &pagep->prev_pgno, 0, &pp)) != 0) {
ret = __db_pgerr(dbp, pagep->prev_pgno, ret);
goto err;
}
plsnp = &pp->lsn;
}
/* Log the change. */
if (DBC_LOGGING(dbc)) {
if ((ret = __bam_relink_log(dbp, dbc->txn, &ret_lsn, 0,
pagep->pgno, &pagep->lsn, pagep->prev_pgno, plsnp,
pagep->next_pgno, nlsnp)) != 0)
goto err;
} else
LSN_NOT_LOGGED(ret_lsn);
if (np != NULL)
np->lsn = ret_lsn;
if (pp != NULL)
pp->lsn = ret_lsn;
pagep->lsn = ret_lsn;
/*
* Modify and release the two pages.
*
* !!!
* The parameter new_next gets set to the page following the page we
* are removing. If there is no following page, then new_next gets
* set to NULL.
*/
if (np != NULL) {
np->prev_pgno = pagep->prev_pgno;
if (new_next == NULL)
ret = __memp_fput(mpf, np, DB_MPOOL_DIRTY);
else {
*new_next = np;
ret = __memp_fset(mpf, np, DB_MPOOL_DIRTY);
}
if ((t_ret = __TLPUT(dbc, npl)) != 0 && ret == 0)
ret = t_ret;
if (ret != 0)
goto err;
} else if (new_next != NULL)
*new_next = NULL;
if (pp != NULL) {
pp->next_pgno = pagep->next_pgno;
ret = __memp_fput(mpf, pp, DB_MPOOL_DIRTY);
if ((t_ret = __TLPUT(dbc, ppl)) != 0 && ret == 0)
ret = t_ret;
if (ret != 0)
goto err;
}
return (0);
err: if (np != NULL)
(void)__memp_fput(mpf, np, 0);
(void)__TLPUT(dbc, npl);
if (pp != NULL)
(void)__memp_fput(mpf, pp, 0);
(void)__TLPUT(dbc, ppl);
return (ret);
}
This diff is collapsed.
/*- /*-
* See the file LICENSE for redistribution information. * See the file LICENSE for redistribution information.
* *
* Copyright (c) 1996-2002 * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved. * Sleepycat Software. All rights reserved.
*/ */
/* /*
...@@ -38,18 +38,15 @@ ...@@ -38,18 +38,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
*
* $Id: bt_open.c,v 11.92 2004/04/29 14:39:47 ubell Exp $
*/ */
#include "db_config.h" #include "db_config.h"
#ifndef lint
static const char revid[] = "$Id: bt_open.c,v 11.76 2002/09/04 19:06:42 margo Exp $";
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h> #include <sys/types.h>
#include <limits.h>
#include <string.h> #include <string.h>
#endif #endif
...@@ -61,6 +58,7 @@ static const char revid[] = "$Id: bt_open.c,v 11.76 2002/09/04 19:06:42 margo Ex ...@@ -61,6 +58,7 @@ static const char revid[] = "$Id: bt_open.c,v 11.76 2002/09/04 19:06:42 margo Ex
#include "dbinc/db_shash.h" #include "dbinc/db_shash.h"
#include "dbinc/lock.h" #include "dbinc/lock.h"
#include "dbinc/log.h" #include "dbinc/log.h"
#include "dbinc/mp.h"
#include "dbinc/fop.h" #include "dbinc/fop.h"
static void __bam_init_meta __P((DB *, BTMETA *, db_pgno_t, DB_LSN *)); static void __bam_init_meta __P((DB *, BTMETA *, db_pgno_t, DB_LSN *));
...@@ -85,10 +83,6 @@ __bam_open(dbp, txn, name, base_pgno, flags) ...@@ -85,10 +83,6 @@ __bam_open(dbp, txn, name, base_pgno, flags)
COMPQUIET(name, NULL); COMPQUIET(name, NULL);
t = dbp->bt_internal; t = dbp->bt_internal;
/* Initialize the remaining fields/methods of the DB. */
dbp->key_range = __bam_key_range;
dbp->stat = __bam_stat;
/* /*
* We don't permit the user to specify a prefix routine if they didn't * We don't permit the user to specify a prefix routine if they didn't
* also specify a comparison routine, they can't know enough about our * also specify a comparison routine, they can't know enough about our
...@@ -290,6 +284,7 @@ __bam_read_root(dbp, txn, base_pgno, flags) ...@@ -290,6 +284,7 @@ __bam_read_root(dbp, txn, base_pgno, flags)
DB_MPOOLFILE *mpf; DB_MPOOLFILE *mpf;
int ret, t_ret; int ret, t_ret;
COMPQUIET(flags, 0);
meta = NULL; meta = NULL;
t = dbp->bt_internal; t = dbp->bt_internal;
LOCK_INIT(metalock); LOCK_INIT(metalock);
...@@ -297,14 +292,14 @@ __bam_read_root(dbp, txn, base_pgno, flags) ...@@ -297,14 +292,14 @@ __bam_read_root(dbp, txn, base_pgno, flags)
ret = 0; ret = 0;
/* Get a cursor. */ /* Get a cursor. */
if ((ret = dbp->cursor(dbp, txn, &dbc, 0)) != 0) if ((ret = __db_cursor(dbp, txn, &dbc, 0)) != 0)
return (ret); return (ret);
/* Get the metadata page. */ /* Get the metadata page. */
if ((ret = if ((ret =
__db_lget(dbc, 0, base_pgno, DB_LOCK_READ, 0, &metalock)) != 0) __db_lget(dbc, 0, base_pgno, DB_LOCK_READ, 0, &metalock)) != 0)
goto err; goto err;
if ((ret = mpf->get(mpf, &base_pgno, 0, (PAGE **)&meta)) != 0) if ((ret = __memp_fget(mpf, &base_pgno, 0, &meta)) != 0)
goto err; goto err;
/* /*
...@@ -315,16 +310,18 @@ __bam_read_root(dbp, txn, base_pgno, flags) ...@@ -315,16 +310,18 @@ __bam_read_root(dbp, txn, base_pgno, flags)
* Otherwise, we'd better be in recovery or abort, in which case the * Otherwise, we'd better be in recovery or abort, in which case the
* metadata page will be created/initialized elsewhere. * metadata page will be created/initialized elsewhere.
*/ */
DB_ASSERT(meta->dbmeta.magic != 0 || if (meta->dbmeta.magic == DB_BTREEMAGIC) {
IS_RECOVERING(dbp->dbenv) || F_ISSET(dbp, DB_AM_RECOVER)); t->bt_maxkey = meta->maxkey;
t->bt_minkey = meta->minkey;
t->bt_maxkey = meta->maxkey; t->re_pad = (int)meta->re_pad;
t->bt_minkey = meta->minkey; t->re_len = meta->re_len;
t->re_pad = meta->re_pad;
t->re_len = meta->re_len; t->bt_meta = base_pgno;
t->bt_root = meta->root;
t->bt_meta = base_pgno; } else {
t->bt_root = meta->root; DB_ASSERT(IS_RECOVERING(dbp->dbenv) ||
F_ISSET(dbp, DB_AM_RECOVER));
}
/* /*
* !!! * !!!
...@@ -337,21 +334,14 @@ __bam_read_root(dbp, txn, base_pgno, flags) ...@@ -337,21 +334,14 @@ __bam_read_root(dbp, txn, base_pgno, flags)
*/ */
t->bt_lpgno = PGNO_INVALID; t->bt_lpgno = PGNO_INVALID;
/* We must initialize last_pgno, it could be stale. */
if (!LF_ISSET(DB_RDONLY) && dbp->meta_pgno == PGNO_BASE_MD) {
mpf->last_pgno(mpf, &meta->dbmeta.last_pgno);
ret = mpf->put(mpf, meta, DB_MPOOL_DIRTY);
} else
ret = mpf->put(mpf, meta, 0);
meta = NULL;
err: /* Put the metadata page back. */ err: /* Put the metadata page back. */
if (meta != NULL && (t_ret = mpf->put(mpf, meta, 0)) != 0 && ret == 0) if (meta != NULL &&
(t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0) if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
return (ret); return (ret);
} }
...@@ -408,7 +398,7 @@ __bam_init_meta(dbp, meta, pgno, lsnp) ...@@ -408,7 +398,7 @@ __bam_init_meta(dbp, meta, pgno, lsnp)
meta->maxkey = t->bt_maxkey; meta->maxkey = t->bt_maxkey;
meta->minkey = t->bt_minkey; meta->minkey = t->bt_minkey;
meta->re_len = t->re_len; meta->re_len = t->re_len;
meta->re_pad = t->re_pad; meta->re_pad = (u_int32_t)t->re_pad;
} }
/* /*
...@@ -418,8 +408,8 @@ __bam_init_meta(dbp, meta, pgno, lsnp) ...@@ -418,8 +408,8 @@ __bam_init_meta(dbp, meta, pgno, lsnp)
* This code appears more complex than it is because of the two cases (named * This code appears more complex than it is because of the two cases (named
* and unnamed). The way to read the code is that for each page being created, * and unnamed). The way to read the code is that for each page being created,
* there are three parts: 1) a "get page" chunk (which either uses malloc'd * there are three parts: 1) a "get page" chunk (which either uses malloc'd
* memory or calls mpf->get), 2) the initialization, and 3) the "put page" * memory or calls __memp_fget), 2) the initialization, and 3) the "put page"
* chunk which either does a fop write or an mpf->put. * chunk which either does a fop write or an __memp_fput.
* *
* PUBLIC: int __bam_new_file __P((DB *, DB_TXN *, DB_FH *, const char *)); * PUBLIC: int __bam_new_file __P((DB *, DB_TXN *, DB_FH *, const char *));
*/ */
...@@ -445,78 +435,84 @@ __bam_new_file(dbp, txn, fhp, name) ...@@ -445,78 +435,84 @@ __bam_new_file(dbp, txn, fhp, name)
mpf = dbp->mpf; mpf = dbp->mpf;
root = NULL; root = NULL;
meta = NULL; meta = NULL;
memset(&pdbt, 0, sizeof(pdbt)); buf = NULL;
/* Build meta-data page. */
if (name == NULL) { if (name == NULL) {
/* Build the meta-data page. */
pgno = PGNO_BASE_MD; pgno = PGNO_BASE_MD;
ret = mpf->get(mpf, &pgno, DB_MPOOL_CREATE, &meta); if ((ret =
__memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &meta)) != 0)
return (ret);
LSN_NOT_LOGGED(lsn);
__bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn);
meta->root = 1;
meta->dbmeta.last_pgno = 1;
ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY);
meta = NULL;
if (ret != 0)
goto err;
/* Build the root page. */
pgno = 1;
if ((ret =
__memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &root)) != 0)
goto err;
P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID,
LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE);
LSN_NOT_LOGGED(root->lsn);
ret = __memp_fput(mpf, root, DB_MPOOL_DIRTY);
root = NULL;
if (ret != 0)
goto err;
} else { } else {
memset(&pdbt, 0, sizeof(pdbt));
/* Build the meta-data page. */
pginfo.db_pagesize = dbp->pgsize; pginfo.db_pagesize = dbp->pgsize;
pginfo.flags = pginfo.flags =
F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_SWAP)); F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_SWAP));
pginfo.type = dbp->type; pginfo.type = dbp->type;
pdbt.data = &pginfo; pdbt.data = &pginfo;
pdbt.size = sizeof(pginfo); pdbt.size = sizeof(pginfo);
ret = __os_calloc(dbp->dbenv, 1, dbp->pgsize, &buf); if ((ret = __os_calloc(dbenv, 1, dbp->pgsize, &buf)) != 0)
return (ret);
meta = (BTMETA *)buf; meta = (BTMETA *)buf;
} LSN_NOT_LOGGED(lsn);
if (ret != 0) __bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn);
return (ret); meta->root = 1;
meta->dbmeta.last_pgno = 1;
LSN_NOT_LOGGED(lsn);
__bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn);
meta->root = 1;
meta->dbmeta.last_pgno = 1;
if (name == NULL)
ret = mpf->put(mpf, meta, DB_MPOOL_DIRTY);
else {
if ((ret = __db_pgout(dbenv, PGNO_BASE_MD, meta, &pdbt)) != 0) if ((ret = __db_pgout(dbenv, PGNO_BASE_MD, meta, &pdbt)) != 0)
goto err; goto err;
ret = __fop_write(dbenv, if ((ret = __fop_write(dbenv, txn, name, DB_APP_DATA, fhp,
txn, name, DB_APP_DATA, fhp, 0, buf, dbp->pgsize, 1); dbp->pgsize, 0, 0, buf, dbp->pgsize, 1, F_ISSET(
} dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0)) != 0)
if (ret != 0)
goto err;
meta = NULL;
/* Now build root page. */
if (name == NULL) {
pgno = 1;
if ((ret = mpf->get(mpf, &pgno, DB_MPOOL_CREATE, &root)) != 0)
goto err; goto err;
} else { meta = NULL;
/* Build the root page. */
#ifdef DIAGNOSTIC #ifdef DIAGNOSTIC
memset(buf, 0, dbp->pgsize); memset(buf, CLEAR_BYTE, dbp->pgsize);
#endif #endif
root = (PAGE *)buf; root = (PAGE *)buf;
} P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID,
LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE);
P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID, LSN_NOT_LOGGED(root->lsn);
LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE);
LSN_NOT_LOGGED(root->lsn);
if (name == NULL)
ret = mpf->put(mpf, root, DB_MPOOL_DIRTY);
else {
if ((ret = __db_pgout(dbenv, root->pgno, root, &pdbt)) != 0) if ((ret = __db_pgout(dbenv, root->pgno, root, &pdbt)) != 0)
goto err; goto err;
ret = __fop_write(dbenv, txn, if ((ret = __fop_write(dbenv, txn, name, DB_APP_DATA, fhp,
name, DB_APP_DATA, fhp, dbp->pgsize, buf, dbp->pgsize, 1); dbp->pgsize, 1, 0, buf, dbp->pgsize, 1, F_ISSET(
dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0)) != 0)
goto err;
root = NULL;
} }
if (ret != 0)
goto err;
root = NULL;
err: if (name != NULL) err: if (buf != NULL)
__os_free(dbenv, buf); __os_free(dbenv, buf);
else { else {
if (meta != NULL) if (meta != NULL)
(void)mpf->put(mpf, meta, 0); (void)__memp_fput(mpf, meta, 0);
if (root != NULL) if (root != NULL)
(void)mpf->put(mpf, root, 0); (void)__memp_fput(mpf, root, 0);
} }
return (ret); return (ret);
} }
...@@ -547,7 +543,7 @@ __bam_new_subdb(mdbp, dbp, txn) ...@@ -547,7 +543,7 @@ __bam_new_subdb(mdbp, dbp, txn)
meta = NULL; meta = NULL;
root = NULL; root = NULL;
if ((ret = mdbp->cursor(mdbp, txn, if ((ret = __db_cursor(mdbp, txn,
&dbc, CDB_LOCKING(dbenv) ? DB_WRITECURSOR : 0)) != 0) &dbc, CDB_LOCKING(dbenv) ? DB_WRITECURSOR : 0)) != 0)
return (ret); return (ret);
...@@ -555,7 +551,8 @@ __bam_new_subdb(mdbp, dbp, txn) ...@@ -555,7 +551,8 @@ __bam_new_subdb(mdbp, dbp, txn)
if ((ret = __db_lget(dbc, if ((ret = __db_lget(dbc,
0, dbp->meta_pgno, DB_LOCK_WRITE, 0, &metalock)) != 0) 0, dbp->meta_pgno, DB_LOCK_WRITE, 0, &metalock)) != 0)
goto err; goto err;
if ((ret = mpf->get(mpf, &dbp->meta_pgno, DB_MPOOL_CREATE, &meta)) != 0) if ((ret =
__memp_fget(mpf, &dbp->meta_pgno, DB_MPOOL_CREATE, &meta)) != 0)
goto err; goto err;
/* Build meta-data page. */ /* Build meta-data page. */
...@@ -582,24 +579,23 @@ __bam_new_subdb(mdbp, dbp, txn) ...@@ -582,24 +579,23 @@ __bam_new_subdb(mdbp, dbp, txn)
goto err; goto err;
/* Release the metadata and root pages. */ /* Release the metadata and root pages. */
if ((ret = mpf->put(mpf, meta, DB_MPOOL_DIRTY)) != 0) if ((ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY)) != 0)
goto err; goto err;
meta = NULL; meta = NULL;
if ((ret = mpf->put(mpf, root, DB_MPOOL_DIRTY)) != 0) if ((ret = __memp_fput(mpf, root, DB_MPOOL_DIRTY)) != 0)
goto err; goto err;
root = NULL; root = NULL;
err: err:
if (meta != NULL) if (meta != NULL)
if ((t_ret = mpf->put(mpf, meta, 0)) != 0 && ret == 0) if ((t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
if (root != NULL) if (root != NULL)
if ((t_ret = mpf->put(mpf, root, 0)) != 0 && ret == 0) if ((t_ret = __memp_fput(mpf, root, 0)) != 0 && ret == 0)
ret = t_ret;
if (LOCK_ISSET(metalock))
if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)
ret = t_ret;
if (dbc != NULL) if (dbc != NULL)
if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0) if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
return (ret); return (ret);
} }
/*- /*-
* See the file LICENSE for redistribution information. * See the file LICENSE for redistribution information.
* *
* Copyright (c) 1996-2002 * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved. * Sleepycat Software. All rights reserved.
*/ */
/* /*
...@@ -38,14 +38,12 @@ ...@@ -38,14 +38,12 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
*
* $Id: bt_put.c,v 11.80 2004/10/29 17:33:25 ubell Exp $
*/ */
#include "db_config.h" #include "db_config.h"
#ifndef lint
static const char revid[] = "$Id: bt_put.c,v 11.69 2002/08/06 06:11:12 bostic Exp $";
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h> #include <sys/types.h>
...@@ -54,7 +52,9 @@ static const char revid[] = "$Id: bt_put.c,v 11.69 2002/08/06 06:11:12 bostic Ex ...@@ -54,7 +52,9 @@ static const char revid[] = "$Id: bt_put.c,v 11.69 2002/08/06 06:11:12 bostic Ex
#include "db_int.h" #include "db_int.h"
#include "dbinc/db_page.h" #include "dbinc/db_page.h"
#include "dbinc/db_shash.h"
#include "dbinc/btree.h" #include "dbinc/btree.h"
#include "dbinc/mp.h"
static int __bam_build static int __bam_build
__P((DBC *, u_int32_t, DBT *, PAGE *, u_int32_t, u_int32_t)); __P((DBC *, u_int32_t, DBT *, PAGE *, u_int32_t, u_int32_t));
...@@ -76,6 +76,7 @@ __bam_iitem(dbc, key, data, op, flags) ...@@ -76,6 +76,7 @@ __bam_iitem(dbc, key, data, op, flags)
DBT *key, *data; DBT *key, *data;
u_int32_t op, flags; u_int32_t op, flags;
{ {
DB_ENV *dbenv;
BKEYDATA *bk, bk_tmp; BKEYDATA *bk, bk_tmp;
BTREE *t; BTREE *t;
BTREE_CURSOR *cp; BTREE_CURSOR *cp;
...@@ -90,6 +91,7 @@ __bam_iitem(dbc, key, data, op, flags) ...@@ -90,6 +91,7 @@ __bam_iitem(dbc, key, data, op, flags)
COMPQUIET(bk, NULL); COMPQUIET(bk, NULL);
dbp = dbc->dbp; dbp = dbc->dbp;
dbenv = dbp->dbenv;
mpf = dbp->mpf; mpf = dbp->mpf;
cp = (BTREE_CURSOR *)dbc->internal; cp = (BTREE_CURSOR *)dbc->internal;
t = dbp->bt_internal; t = dbp->bt_internal;
...@@ -102,10 +104,8 @@ __bam_iitem(dbc, key, data, op, flags) ...@@ -102,10 +104,8 @@ __bam_iitem(dbc, key, data, op, flags)
* anything other simple overwrite. * anything other simple overwrite.
*/ */
if (F_ISSET(dbp, DB_AM_FIXEDLEN) && if (F_ISSET(dbp, DB_AM_FIXEDLEN) &&
F_ISSET(data, DB_DBT_PARTIAL) && data->dlen != data->size) { F_ISSET(data, DB_DBT_PARTIAL) && data->size != data->dlen)
data_size = data->size; return (__db_rec_repl(dbenv, data->size, data->dlen));
goto len_err;
}
/* /*
* Figure out how much space the data will take, including if it's a * Figure out how much space the data will take, including if it's a
...@@ -119,12 +119,8 @@ __bam_iitem(dbc, key, data, op, flags) ...@@ -119,12 +119,8 @@ __bam_iitem(dbc, key, data, op, flags)
__bam_partsize(dbp, op, data, h, indx) : data->size; __bam_partsize(dbp, op, data, h, indx) : data->size;
padrec = 0; padrec = 0;
if (F_ISSET(dbp, DB_AM_FIXEDLEN)) { if (F_ISSET(dbp, DB_AM_FIXEDLEN)) {
if (data_size > t->re_len) { if (data_size > t->re_len)
len_err: __db_err(dbp->dbenv, return (__db_rec_toobig(dbenv, data_size, t->re_len));
"Length improper for fixed length record %lu",
(u_long)data_size);
return (EINVAL);
}
/* Records that are deleted anyway needn't be padded out. */ /* Records that are deleted anyway needn't be padded out. */
if (!LF_ISSET(BI_DELETED) && data_size < t->re_len) { if (!LF_ISSET(BI_DELETED) && data_size < t->re_len) {
...@@ -158,8 +154,8 @@ len_err: __db_err(dbp->dbenv, ...@@ -158,8 +154,8 @@ len_err: __db_err(dbp->dbenv,
dbp->dup_compare, &cmp)) != 0) dbp->dup_compare, &cmp)) != 0)
return (ret); return (ret);
if (cmp != 0) { if (cmp != 0) {
__db_err(dbp->dbenv, __db_err(dbenv,
"Current data differs from put data"); "Existing data sorts differently from put data");
return (EINVAL); return (EINVAL);
} }
} }
...@@ -218,19 +214,14 @@ len_err: __db_err(dbp->dbenv, ...@@ -218,19 +214,14 @@ len_err: __db_err(dbp->dbenv,
needed += need_bytes - have_bytes; needed += need_bytes - have_bytes;
break; break;
default: default:
return (__db_unknown_flag(dbp->dbenv, "__bam_iitem", op)); return (__db_unknown_flag(dbenv, "DB->put", op));
} }
/* /*
* If there's not enough room, or the user has put a ceiling on the * If there's not enough room, or the user has put a ceiling on the
* number of keys permitted in the page, split the page. * number of keys permitted in the page, split the page.
*
* XXX
* The t->bt_maxkey test here may be insufficient -- do we have to
* check in the btree split code, so we don't undo it there!?!?
*/ */
if (P_FREESPACE(dbp, h) < needed || if (P_FREESPACE(dbp, h) < needed)
(t->bt_maxkey != 0 && NUM_ENT(h) > t->bt_maxkey))
return (DB_NEEDSPLIT); return (DB_NEEDSPLIT);
/* /*
...@@ -294,23 +285,24 @@ len_err: __db_err(dbp->dbenv, ...@@ -294,23 +285,24 @@ len_err: __db_err(dbp->dbenv,
* we deadlock or fail while deleting the overflow item or * we deadlock or fail while deleting the overflow item or
* replacing the non-overflow item, a subsequent cursor close * replacing the non-overflow item, a subsequent cursor close
* will try and remove the item because the cursor's delete * will try and remove the item because the cursor's delete
* flag is set * flag is set.
*/ */
(void)__bam_ca_delete(dbp, PGNO(h), indx, 0); (void)__bam_ca_delete(dbp, PGNO(h), indx, 0);
if (TYPE(h) == P_LBTREE) { if (TYPE(h) == P_LBTREE) {
++indx; ++indx;
dupadjust = 1; dupadjust = 1;
}
/* /*
* In a Btree deleted records aren't counted (deleted * In a Btree deleted records aren't counted (deleted records
* records are counted in a Recno because all accesses * are counted in a Recno because all accesses are based on
* are based on record number). If it's a Btree and * record number). If it's a Btree and it's a DB_CURRENT
* it's a DB_CURRENT operation overwriting a previously * operation overwriting a previously deleted record, increment
* deleted record, increment the record count. * the record count.
*/ */
if (TYPE(h) == P_LBTREE || TYPE(h) == P_LDUP)
was_deleted = B_DISSET(bk->type); was_deleted = B_DISSET(bk->type);
}
/* /*
* 4. Delete and re-add the data item. * 4. Delete and re-add the data item.
...@@ -331,7 +323,7 @@ len_err: __db_err(dbp->dbenv, ...@@ -331,7 +323,7 @@ len_err: __db_err(dbp->dbenv,
replace = 1; replace = 1;
break; break;
default: default:
return (__db_unknown_flag(dbp->dbenv, "__bam_iitem", op)); return (__db_unknown_flag(dbenv, "DB->put", op));
} }
/* Add the data. */ /* Add the data. */
...@@ -360,7 +352,7 @@ len_err: __db_err(dbp->dbenv, ...@@ -360,7 +352,7 @@ len_err: __db_err(dbp->dbenv,
if (ret != 0) if (ret != 0)
return (ret); return (ret);
} }
if ((ret = mpf->set(mpf, h, DB_MPOOL_DIRTY)) != 0) if ((ret = __memp_fset(mpf, h, DB_MPOOL_DIRTY)) != 0)
return (ret); return (ret);
/* /*
...@@ -648,7 +640,7 @@ __bam_ritem(dbc, h, indx, data) ...@@ -648,7 +640,7 @@ __bam_ritem(dbc, h, indx, data)
if (p == t) /* First index is fast. */ if (p == t) /* First index is fast. */
inp[indx] += nbytes; inp[indx] += nbytes;
else { /* Else, shift the page. */ else { /* Else, shift the page. */
memmove(p + nbytes, p, t - p); memmove(p + nbytes, p, (size_t)(t - p));
/* Adjust the indices' offsets. */ /* Adjust the indices' offsets. */
off = inp[indx]; off = inp[indx];
...@@ -700,12 +692,16 @@ __bam_dup_convert(dbc, h, indx) ...@@ -700,12 +692,16 @@ __bam_dup_convert(dbc, h, indx)
*/ */
while (indx > 0 && inp[indx] == inp[indx - P_INDX]) while (indx > 0 && inp[indx] == inp[indx - P_INDX])
indx -= P_INDX; indx -= P_INDX;
for (cnt = 0, sz = 0, first = indx;; ++cnt, indx += P_INDX) {
if (indx >= NUM_ENT(h) || inp[first] != inp[indx]) /* Count the key once. */
break; bk = GET_BKEYDATA(dbp, h, indx);
bk = GET_BKEYDATA(dbp, h, indx); sz = B_TYPE(bk->type) == B_KEYDATA ?
sz += B_TYPE(bk->type) == B_KEYDATA ? BKEYDATA_PSIZE(bk->len) : BOVERFLOW_PSIZE;
BKEYDATA_PSIZE(bk->len) : BOVERFLOW_PSIZE;
/* Sum up all the data items. */
for (cnt = 0, first = indx;
indx < NUM_ENT(h) && inp[first] == inp[indx];
++cnt, indx += P_INDX) {
bk = GET_BKEYDATA(dbp, h, indx + O_INDX); bk = GET_BKEYDATA(dbp, h, indx + O_INDX);
sz += B_TYPE(bk->type) == B_KEYDATA ? sz += B_TYPE(bk->type) == B_KEYDATA ?
BKEYDATA_PSIZE(bk->len) : BOVERFLOW_PSIZE; BKEYDATA_PSIZE(bk->len) : BOVERFLOW_PSIZE;
...@@ -800,14 +796,14 @@ __bam_dup_convert(dbc, h, indx) ...@@ -800,14 +796,14 @@ __bam_dup_convert(dbc, h, indx)
B_DUPLICATE, dp->pgno, h, first + 1, NULL)) != 0) B_DUPLICATE, dp->pgno, h, first + 1, NULL)) != 0)
goto err; goto err;
/* Adjust cursors for all the above movments. */ /* Adjust cursors for all the above movements. */
if ((ret = __bam_ca_di(dbc, if ((ret = __bam_ca_di(dbc,
PGNO(h), first + P_INDX, first + P_INDX - indx)) != 0) PGNO(h), first + P_INDX, (int)(first + P_INDX - indx))) != 0)
goto err; goto err;
return (mpf->put(mpf, dp, DB_MPOOL_DIRTY)); return (__memp_fput(mpf, dp, DB_MPOOL_DIRTY));
err: (void)mpf->put(mpf, dp, 0); err: (void)__memp_fput(mpf, dp, 0);
return (ret); return (ret);
} }
......
This diff is collapsed.
/*- /*-
* See the file LICENSE for redistribution information. * See the file LICENSE for redistribution information.
* *
* Copyright (c) 1998-2002 * Copyright (c) 1998-2004
* Sleepycat Software. All rights reserved. * Sleepycat Software. All rights reserved.
*
* $Id: bt_reclaim.c,v 11.15 2004/01/28 03:35:49 bostic Exp $
*/ */
#include "db_config.h" #include "db_config.h"
#ifndef lint
static const char revid[] = "$Id: bt_reclaim.c,v 11.11 2002/03/29 20:46:26 bostic Exp $";
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h> #include <sys/types.h>
...@@ -36,7 +34,7 @@ __bam_reclaim(dbp, txn) ...@@ -36,7 +34,7 @@ __bam_reclaim(dbp, txn)
int ret, t_ret; int ret, t_ret;
/* Acquire a cursor. */ /* Acquire a cursor. */
if ((ret = dbp->cursor(dbp, txn, &dbc, 0)) != 0) if ((ret = __db_cursor(dbp, txn, &dbc, 0)) != 0)
return (ret); return (ret);
/* Walk the tree, freeing pages. */ /* Walk the tree, freeing pages. */
...@@ -44,7 +42,7 @@ __bam_reclaim(dbp, txn) ...@@ -44,7 +42,7 @@ __bam_reclaim(dbp, txn)
DB_LOCK_WRITE, dbc->internal->root, __db_reclaim_callback, dbc); DB_LOCK_WRITE, dbc->internal->root, __db_reclaim_callback, dbc);
/* Discard the cursor. */ /* Discard the cursor. */
if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0) if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
return (ret); return (ret);
...@@ -54,32 +52,23 @@ __bam_reclaim(dbp, txn) ...@@ -54,32 +52,23 @@ __bam_reclaim(dbp, txn)
* __bam_truncate -- * __bam_truncate --
* Truncate a database. * Truncate a database.
* *
* PUBLIC: int __bam_truncate __P((DB *, DB_TXN *, u_int32_t *)); * PUBLIC: int __bam_truncate __P((DBC *, u_int32_t *));
*/ */
int int
__bam_truncate(dbp, txn, countp) __bam_truncate(dbc, countp)
DB *dbp; DBC *dbc;
DB_TXN *txn;
u_int32_t *countp; u_int32_t *countp;
{ {
DBC *dbc;
db_trunc_param trunc; db_trunc_param trunc;
int ret, t_ret; int ret;
/* Acquire a cursor. */
if ((ret = dbp->cursor(dbp, txn, &dbc, 0)) != 0)
return (ret);
trunc.count = 0; trunc.count = 0;
trunc.dbc = dbc; trunc.dbc = dbc;
/* Walk the tree, freeing pages. */ /* Walk the tree, freeing pages. */
ret = __bam_traverse(dbc, ret = __bam_traverse(dbc,
DB_LOCK_WRITE, dbc->internal->root, __db_truncate_callback, &trunc); DB_LOCK_WRITE, dbc->internal->root, __db_truncate_callback, &trunc);
/* Discard the cursor. */
if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0)
ret = t_ret;
*countp = trunc.count; *countp = trunc.count;
return (ret); return (ret);
......
/*- /*-
* See the file LICENSE for redistribution information. * See the file LICENSE for redistribution information.
* *
* Copyright (c) 1997-2002 * Copyright (c) 1997-2004
* Sleepycat Software. All rights reserved. * Sleepycat Software. All rights reserved.
*
* $Id: bt_recno.c,v 11.117 2004/03/28 17:01:01 bostic Exp $
*/ */
#include "db_config.h" #include "db_config.h"
#ifndef lint
static const char revid[] = "$Id: bt_recno.c,v 11.106 2002/08/16 04:56:30 ubell Exp $";
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h> #include <sys/types.h>
#include <limits.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#endif #endif
...@@ -58,7 +54,7 @@ static int __ram_update __P((DBC *, db_recno_t, int)); ...@@ -58,7 +54,7 @@ static int __ram_update __P((DBC *, db_recno_t, int));
} \ } \
} }
#define CD_ISSET(cp) \ #define CD_ISSET(cp) \
(F_ISSET(cp, C_RENUMBER) && F_ISSET(cp, C_DELETED)) (F_ISSET(cp, C_RENUMBER) && F_ISSET(cp, C_DELETED) ? 1 : 0)
/* /*
* Macros for comparing the ordering of two cursors. * Macros for comparing the ordering of two cursors.
...@@ -91,11 +87,13 @@ static int __ram_update __P((DBC *, db_recno_t, int)); ...@@ -91,11 +87,13 @@ static int __ram_update __P((DBC *, db_recno_t, int));
* After a search, copy the found page into the cursor, discarding any * After a search, copy the found page into the cursor, discarding any
* currently held lock. * currently held lock.
*/ */
#define STACK_TO_CURSOR(cp) { \ #define STACK_TO_CURSOR(cp, ret) { \
int __t_ret; \
(cp)->page = (cp)->csp->page; \ (cp)->page = (cp)->csp->page; \
(cp)->pgno = (cp)->csp->page->pgno; \ (cp)->pgno = (cp)->csp->page->pgno; \
(cp)->indx = (cp)->csp->indx; \ (cp)->indx = (cp)->csp->indx; \
(void)__TLPUT(dbc, (cp)->lock); \ if ((__t_ret = __TLPUT(dbc, (cp)->lock)) != 0 && (ret) == 0) \
ret = __t_ret; \
(cp)->lock = (cp)->csp->lock; \ (cp)->lock = (cp)->csp->lock; \
(cp)->lock_mode = (cp)->csp->lock_mode; \ (cp)->lock_mode = (cp)->csp->lock_mode; \
} }
...@@ -122,9 +120,6 @@ __ram_open(dbp, txn, name, base_pgno, flags) ...@@ -122,9 +120,6 @@ __ram_open(dbp, txn, name, base_pgno, flags)
COMPQUIET(name, NULL); COMPQUIET(name, NULL);
t = dbp->bt_internal; t = dbp->bt_internal;
/* Initialize the remaining fields/methods of the DB. */
dbp->stat = __bam_stat;
/* Start up the tree. */ /* Start up the tree. */
if ((ret = __bam_read_root(dbp, txn, base_pgno, flags)) != 0) if ((ret = __bam_read_root(dbp, txn, base_pgno, flags)) != 0)
return (ret); return (ret);
...@@ -143,7 +138,7 @@ __ram_open(dbp, txn, name, base_pgno, flags) ...@@ -143,7 +138,7 @@ __ram_open(dbp, txn, name, base_pgno, flags)
/* If we're snapshotting an underlying source file, do it now. */ /* If we're snapshotting an underlying source file, do it now. */
if (F_ISSET(dbp, DB_AM_SNAPSHOT)) { if (F_ISSET(dbp, DB_AM_SNAPSHOT)) {
/* Allocate a cursor. */ /* Allocate a cursor. */
if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0) if ((ret = __db_cursor(dbp, NULL, &dbc, 0)) != 0)
return (ret); return (ret);
/* Do the snapshot. */ /* Do the snapshot. */
...@@ -152,7 +147,7 @@ __ram_open(dbp, txn, name, base_pgno, flags) ...@@ -152,7 +147,7 @@ __ram_open(dbp, txn, name, base_pgno, flags)
ret = 0; ret = 0;
/* Discard the cursor. */ /* Discard the cursor. */
if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0) if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
} }
...@@ -209,7 +204,7 @@ __ram_c_del(dbc) ...@@ -209,7 +204,7 @@ __ram_c_del(dbc)
DB_LSN lsn; DB_LSN lsn;
DBT hdr, data; DBT hdr, data;
EPG *epg; EPG *epg;
int exact, ret, stack; int exact, ret, stack, t_ret;
dbp = dbc->dbp; dbp = dbc->dbp;
cp = (BTREE_CURSOR *)dbc->internal; cp = (BTREE_CURSOR *)dbc->internal;
...@@ -240,7 +235,9 @@ __ram_c_del(dbc) ...@@ -240,7 +235,9 @@ __ram_c_del(dbc)
stack = 1; stack = 1;
/* Copy the page into the cursor. */ /* Copy the page into the cursor. */
STACK_TO_CURSOR(cp); STACK_TO_CURSOR(cp, ret);
if (ret != 0)
goto err;
/* /*
* If re-numbering records, the on-page deleted flag can only mean * If re-numbering records, the on-page deleted flag can only mean
...@@ -262,7 +259,8 @@ __ram_c_del(dbc) ...@@ -262,7 +259,8 @@ __ram_c_del(dbc)
/* Delete the item, adjust the counts, adjust the cursors. */ /* Delete the item, adjust the counts, adjust the cursors. */
if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0) if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0)
goto err; goto err;
__bam_adjust(dbc, -1); if ((ret = __bam_adjust(dbc, -1)) != 0)
goto err;
if (__ram_ca(dbc, CA_DELETE) > 0 && if (__ram_ca(dbc, CA_DELETE) > 0 &&
CURADJ_LOG(dbc) && (ret = __bam_rcuradj_log(dbp, dbc->txn, CURADJ_LOG(dbc) && (ret = __bam_rcuradj_log(dbp, dbc->txn,
&lsn, 0, CA_DELETE, cp->root, cp->recno, cp->order)) != 0) &lsn, 0, CA_DELETE, cp->root, cp->recno, cp->order)) != 0)
...@@ -325,8 +323,8 @@ __ram_c_del(dbc) ...@@ -325,8 +323,8 @@ __ram_c_del(dbc)
t->re_modified = 1; t->re_modified = 1;
err: if (stack) err: if (stack && (t_ret = __bam_stkrel(dbc, STK_CLRDBC)) != 0 && ret == 0)
__bam_stkrel(dbc, STK_CLRDBC); ret = t_ret;
return (ret); return (ret);
} }
...@@ -388,8 +386,13 @@ retry: switch (flags) { ...@@ -388,8 +386,13 @@ retry: switch (flags) {
* we have to avoid incrementing the record number so that we * we have to avoid incrementing the record number so that we
* return the right record by virtue of renumbering the tree. * return the right record by virtue of renumbering the tree.
*/ */
if (CD_ISSET(cp)) if (CD_ISSET(cp)) {
/*
* Clear the flag, we've moved off the deleted record.
*/
CD_CLR(cp);
break; break;
}
if (cp->recno != RECNO_OOB) { if (cp->recno != RECNO_OOB) {
++cp->recno; ++cp->recno;
...@@ -494,7 +497,9 @@ retry: switch (flags) { ...@@ -494,7 +497,9 @@ retry: switch (flags) {
} }
/* Copy the page into the cursor. */ /* Copy the page into the cursor. */
STACK_TO_CURSOR(cp); STACK_TO_CURSOR(cp, ret);
if (ret != 0)
goto err;
/* /*
* If re-numbering records, the on-page deleted flag means this * If re-numbering records, the on-page deleted flag means this
...@@ -607,9 +612,11 @@ __ram_c_put(dbc, key, data, flags, pgnop) ...@@ -607,9 +612,11 @@ __ram_c_put(dbc, key, data, flags, pgnop)
return (ret); return (ret);
if (CURADJ_LOG(dbc) && if (CURADJ_LOG(dbc) &&
(ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0, (ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0,
CA_ICURRENT, cp->root, cp->recno, cp->order))) CA_ICURRENT, cp->root, cp->recno, cp->order)) != 0)
return (ret); return (ret);
return (0); return (0);
default:
break;
} }
/* /*
...@@ -650,7 +657,9 @@ split: if ((ret = __bam_rsearch(dbc, &cp->recno, S_INSERT, 1, &exact)) != 0) ...@@ -650,7 +657,9 @@ split: if ((ret = __bam_rsearch(dbc, &cp->recno, S_INSERT, 1, &exact)) != 0)
DB_ASSERT(exact || CD_ISSET(cp)); DB_ASSERT(exact || CD_ISSET(cp));
/* Copy the page into the cursor. */ /* Copy the page into the cursor. */
STACK_TO_CURSOR(cp); STACK_TO_CURSOR(cp, ret);
if (ret != 0)
goto err;
ret = __bam_iitem(dbc, key, data, iiflags, 0); ret = __bam_iitem(dbc, key, data, iiflags, 0);
t_ret = __bam_stkrel(dbc, STK_CLRDBC); t_ret = __bam_stkrel(dbc, STK_CLRDBC);
...@@ -708,6 +717,8 @@ split: if ((ret = __bam_rsearch(dbc, &cp->recno, S_INSERT, 1, &exact)) != 0) ...@@ -708,6 +717,8 @@ split: if ((ret = __bam_rsearch(dbc, &cp->recno, S_INSERT, 1, &exact)) != 0)
CA_ICURRENT, cp->root, cp->recno, cp->order)) != 0) CA_ICURRENT, cp->root, cp->recno, cp->order)) != 0)
goto err; goto err;
break; break;
default:
break;
} }
/* Return the key if we've created a new record. */ /* Return the key if we've created a new record. */
...@@ -983,7 +994,7 @@ __ram_source(dbp) ...@@ -983,7 +994,7 @@ __ram_source(dbp)
* when it comes time to write the database back to the source. * when it comes time to write the database back to the source.
*/ */
if ((t->re_fp = fopen(t->re_source, "r")) == NULL) { if ((t->re_fp = fopen(t->re_source, "r")) == NULL) {
ret = errno; ret = __os_get_errno();
__db_err(dbp->dbenv, "%s: %s", t->re_source, db_strerror(ret)); __db_err(dbp->dbenv, "%s: %s", t->re_source, db_strerror(ret));
return (ret); return (ret);
} }
...@@ -1027,7 +1038,7 @@ __ram_writeback(dbp) ...@@ -1027,7 +1038,7 @@ __ram_writeback(dbp)
} }
/* Allocate a cursor. */ /* Allocate a cursor. */
if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0) if ((ret = __db_cursor(dbp, NULL, &dbc, 0)) != 0)
return (ret); return (ret);
/* /*
...@@ -1060,13 +1071,13 @@ __ram_writeback(dbp) ...@@ -1060,13 +1071,13 @@ __ram_writeback(dbp)
*/ */
if (t->re_fp != NULL) { if (t->re_fp != NULL) {
if (fclose(t->re_fp) != 0) { if (fclose(t->re_fp) != 0) {
ret = errno; ret = __os_get_errno();
goto err; goto err;
} }
t->re_fp = NULL; t->re_fp = NULL;
} }
if ((fp = fopen(t->re_source, "w")) == NULL) { if ((fp = fopen(t->re_source, "w")) == NULL) {
ret = errno; ret = __os_get_errno();
__db_err(dbenv, "%s: %s", t->re_source, db_strerror(ret)); __db_err(dbenv, "%s: %s", t->re_source, db_strerror(ret));
goto err; goto err;
} }
...@@ -1088,23 +1099,24 @@ __ram_writeback(dbp) ...@@ -1088,23 +1099,24 @@ __ram_writeback(dbp)
* and the pad character if we're doing fixed-length records. * and the pad character if we're doing fixed-length records.
*/ */
delim = t->re_delim; delim = t->re_delim;
if (F_ISSET(dbp, DB_AM_FIXEDLEN)) {
if ((ret = __os_malloc(dbenv, t->re_len, &pad)) != 0)
goto err;
memset(pad, t->re_pad, t->re_len);
}
for (keyno = 1;; ++keyno) { for (keyno = 1;; ++keyno) {
switch (ret = dbp->get(dbp, NULL, &key, &data, 0)) { switch (ret = __db_get(dbp, NULL, &key, &data, 0)) {
case 0: case 0:
if (data.size != 0 && (u_int32_t)fwrite( if (data.size != 0 &&
data.data, 1, data.size, fp) != data.size) fwrite(data.data, 1, data.size, fp) != data.size)
goto write_err; goto write_err;
break; break;
case DB_KEYEMPTY: case DB_KEYEMPTY:
if (F_ISSET(dbp, DB_AM_FIXEDLEN) && if (F_ISSET(dbp, DB_AM_FIXEDLEN)) {
(u_int32_t)fwrite(pad, 1, t->re_len, fp) != if (pad == NULL) {
t->re_len) if ((ret = __os_malloc(
goto write_err; dbenv, t->re_len, &pad)) != 0)
goto err;
memset(pad, t->re_pad, t->re_len);
}
if (fwrite(pad, 1, t->re_len, fp) != t->re_len)
goto write_err;
}
break; break;
case DB_NOTFOUND: case DB_NOTFOUND:
ret = 0; ret = 0;
...@@ -1114,8 +1126,8 @@ __ram_writeback(dbp) ...@@ -1114,8 +1126,8 @@ __ram_writeback(dbp)
} }
if (!F_ISSET(dbp, DB_AM_FIXEDLEN) && if (!F_ISSET(dbp, DB_AM_FIXEDLEN) &&
fwrite(&delim, 1, 1, fp) != 1) { fwrite(&delim, 1, 1, fp) != 1) {
write_err: ret = errno; write_err: ret = __os_get_errno();
__db_err(dbp->dbenv, __db_err(dbenv,
"%s: write failed to backing file: %s", "%s: write failed to backing file: %s",
t->re_source, strerror(ret)); t->re_source, strerror(ret));
goto err; goto err;
...@@ -1125,13 +1137,14 @@ write_err: ret = errno; ...@@ -1125,13 +1137,14 @@ write_err: ret = errno;
err: err:
done: /* Close the file descriptor. */ done: /* Close the file descriptor. */
if (fp != NULL && fclose(fp) != 0) { if (fp != NULL && fclose(fp) != 0) {
t_ret = __os_get_errno();
if (ret == 0) if (ret == 0)
ret = errno; ret = t_ret;
__db_err(dbenv, "%s: %s", t->re_source, db_strerror(errno)); __db_err(dbenv, "%s: %s", t->re_source, db_strerror(t_ret));
} }
/* Discard the cursor. */ /* Discard the cursor. */
if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0) if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
/* Discard memory allocated to hold the data items. */ /* Discard memory allocated to hold the data items. */
...@@ -1259,7 +1272,7 @@ __ram_add(dbc, recnop, data, flags, bi_flags) ...@@ -1259,7 +1272,7 @@ __ram_add(dbc, recnop, data, flags, bi_flags)
u_int32_t flags, bi_flags; u_int32_t flags, bi_flags;
{ {
BTREE_CURSOR *cp; BTREE_CURSOR *cp;
int exact, ret, stack; int exact, ret, stack, t_ret;
cp = (BTREE_CURSOR *)dbc->internal; cp = (BTREE_CURSOR *)dbc->internal;
...@@ -1270,7 +1283,9 @@ __ram_add(dbc, recnop, data, flags, bi_flags) ...@@ -1270,7 +1283,9 @@ __ram_add(dbc, recnop, data, flags, bi_flags)
stack = 1; stack = 1;
/* Copy the page into the cursor. */ /* Copy the page into the cursor. */
STACK_TO_CURSOR(cp); STACK_TO_CURSOR(cp, ret);
if (ret != 0)
goto err;
/* /*
* The application may modify the data based on the selected record * The application may modify the data based on the selected record
...@@ -1320,8 +1335,8 @@ __ram_add(dbc, recnop, data, flags, bi_flags) ...@@ -1320,8 +1335,8 @@ __ram_add(dbc, recnop, data, flags, bi_flags)
goto err; goto err;
} }
err: if (stack) err: if (stack && (t_ret = __bam_stkrel(dbc, STK_CLRDBC)) != 0 && ret == 0)
__bam_stkrel(dbc, STK_CLRDBC); ret = t_ret;
return (ret); return (ret);
} }
/*- /*-
* See the file LICENSE for redistribution information. * See the file LICENSE for redistribution information.
* *
* Copyright (c) 1996-2002 * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved. * Sleepycat Software. All rights reserved.
*/ */
/* /*
...@@ -35,14 +35,12 @@ ...@@ -35,14 +35,12 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
*
* $Id: bt_rsearch.c,v 11.40 2004/07/23 17:21:09 bostic Exp $
*/ */
#include "db_config.h" #include "db_config.h"
#ifndef lint
static const char revid[] = "$Id: bt_rsearch.c,v 11.34 2002/07/03 19:03:50 bostic Exp $";
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h> #include <sys/types.h>
#endif #endif
...@@ -52,6 +50,7 @@ static const char revid[] = "$Id: bt_rsearch.c,v 11.34 2002/07/03 19:03:50 bosti ...@@ -52,6 +50,7 @@ static const char revid[] = "$Id: bt_rsearch.c,v 11.34 2002/07/03 19:03:50 bosti
#include "dbinc/btree.h" #include "dbinc/btree.h"
#include "dbinc/db_shash.h" #include "dbinc/db_shash.h"
#include "dbinc/lock.h" #include "dbinc/lock.h"
#include "dbinc/mp.h"
/* /*
* __bam_rsearch -- * __bam_rsearch --
...@@ -77,11 +76,12 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp) ...@@ -77,11 +76,12 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
db_lockmode_t lock_mode; db_lockmode_t lock_mode;
db_pgno_t pg; db_pgno_t pg;
db_recno_t recno, t_recno, total; db_recno_t recno, t_recno, total;
int ret, stack; int ret, stack, t_ret;
dbp = dbc->dbp; dbp = dbc->dbp;
mpf = dbp->mpf; mpf = dbp->mpf;
cp = (BTREE_CURSOR *)dbc->internal; cp = (BTREE_CURSOR *)dbc->internal;
h = NULL;
BT_STK_CLR(cp); BT_STK_CLR(cp);
...@@ -105,7 +105,7 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp) ...@@ -105,7 +105,7 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
lock_mode = stack ? DB_LOCK_WRITE : DB_LOCK_READ; lock_mode = stack ? DB_LOCK_WRITE : DB_LOCK_READ;
if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0) if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
return (ret); return (ret);
if ((ret = mpf->get(mpf, &pg, 0, &h)) != 0) { if ((ret = __memp_fget(mpf, &pg, 0, &h)) != 0) {
/* Did not read it, so we can release the lock */ /* Did not read it, so we can release the lock */
(void)__LPUT(dbc, lock); (void)__LPUT(dbc, lock);
return (ret); return (ret);
...@@ -122,12 +122,15 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp) ...@@ -122,12 +122,15 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
if (!stack && if (!stack &&
((LF_ISSET(S_PARENT) && (u_int8_t)(stop + 1) >= h->level) || ((LF_ISSET(S_PARENT) && (u_int8_t)(stop + 1) >= h->level) ||
(LF_ISSET(S_WRITE) && h->level == LEAFLEVEL))) { (LF_ISSET(S_WRITE) && h->level == LEAFLEVEL))) {
(void)mpf->put(mpf, h, 0); ret = __memp_fput(mpf, h, 0);
(void)__LPUT(dbc, lock); if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
ret = t_ret;
if (ret != 0)
return (ret);
lock_mode = DB_LOCK_WRITE; lock_mode = DB_LOCK_WRITE;
if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0) if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
return (ret); return (ret);
if ((ret = mpf->get(mpf, &pg, 0, &h)) != 0) { if ((ret = __memp_fget(mpf, &pg, 0, &h)) != 0) {
/* Did not read it, so we can release the lock */ /* Did not read it, so we can release the lock */
(void)__LPUT(dbc, lock); (void)__LPUT(dbc, lock);
return (ret); return (ret);
...@@ -166,9 +169,11 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp) ...@@ -166,9 +169,11 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
* eliminate any concurrency. A possible fix * eliminate any concurrency. A possible fix
* would be to lock the last leaf page instead. * would be to lock the last leaf page instead.
*/ */
(void)mpf->put(mpf, h, 0); ret = __memp_fput(mpf, h, 0);
(void)__TLPUT(dbc, lock); if ((t_ret =
return (DB_NOTFOUND); __TLPUT(dbc, lock)) != 0 && ret == 0)
ret = t_ret;
return (ret == 0 ? DB_NOTFOUND : ret);
} }
} }
} }
...@@ -200,7 +205,13 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp) ...@@ -200,7 +205,13 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
*exactp = 0; *exactp = 0;
if (!LF_ISSET(S_PAST_EOF) || if (!LF_ISSET(S_PAST_EOF) ||
recno > t_recno + 1) { recno > t_recno + 1) {
ret = DB_NOTFOUND; ret = __memp_fput(mpf, h, 0);
h = NULL;
if ((t_ret = __TLPUT(dbc,
lock)) != 0 && ret == 0)
ret = t_ret;
if (ret == 0)
ret = DB_NOTFOUND;
goto err; goto err;
} }
} }
...@@ -262,6 +273,7 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp) ...@@ -262,6 +273,7 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
cp, h, indx, lock, lock_mode, ret); cp, h, indx, lock, lock_mode, ret);
if (ret != 0) if (ret != 0)
goto err; goto err;
h = NULL;
lock_mode = DB_LOCK_WRITE; lock_mode = DB_LOCK_WRITE;
if ((ret = if ((ret =
...@@ -278,7 +290,9 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp) ...@@ -278,7 +290,9 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
(h->level - 1) == LEAFLEVEL) (h->level - 1) == LEAFLEVEL)
stack = 1; stack = 1;
(void)mpf->put(mpf, h, 0); if ((ret = __memp_fput(mpf, h, 0)) != 0)
goto err;
h = NULL;
lock_mode = stack && lock_mode = stack &&
LF_ISSET(S_WRITE) ? DB_LOCK_WRITE : DB_LOCK_READ; LF_ISSET(S_WRITE) ? DB_LOCK_WRITE : DB_LOCK_READ;
...@@ -289,18 +303,22 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp) ...@@ -289,18 +303,22 @@ __bam_rsearch(dbc, recnop, flags, stop, exactp)
* is OK because this only happens when we are * is OK because this only happens when we are
* descending the tree holding read-locks. * descending the tree holding read-locks.
*/ */
__LPUT(dbc, lock); (void)__LPUT(dbc, lock);
goto err; goto err;
} }
} }
if ((ret = mpf->get(mpf, &pg, 0, &h)) != 0) if ((ret = __memp_fget(mpf, &pg, 0, &h)) != 0)
goto err; goto err;
} }
/* NOTREACHED */ /* NOTREACHED */
err: BT_STK_POP(cp); err: if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
ret = t_ret;
BT_STK_POP(cp);
__bam_stkrel(dbc, 0); __bam_stkrel(dbc, 0);
return (ret); return (ret);
} }
...@@ -352,7 +370,7 @@ __bam_adjust(dbc, adjust) ...@@ -352,7 +370,7 @@ __bam_adjust(dbc, adjust)
if (PGNO(h) == root_pgno) if (PGNO(h) == root_pgno)
RE_NREC_ADJ(h, adjust); RE_NREC_ADJ(h, adjust);
if ((ret = mpf->set(mpf, h, DB_MPOOL_DIRTY)) != 0) if ((ret = __memp_fset(mpf, h, DB_MPOOL_DIRTY)) != 0)
return (ret); return (ret);
} }
} }
...@@ -375,7 +393,7 @@ __bam_nrecs(dbc, rep) ...@@ -375,7 +393,7 @@ __bam_nrecs(dbc, rep)
DB_MPOOLFILE *mpf; DB_MPOOLFILE *mpf;
PAGE *h; PAGE *h;
db_pgno_t pgno; db_pgno_t pgno;
int ret; int ret, t_ret;
dbp = dbc->dbp; dbp = dbc->dbp;
mpf = dbp->mpf; mpf = dbp->mpf;
...@@ -383,15 +401,16 @@ __bam_nrecs(dbc, rep) ...@@ -383,15 +401,16 @@ __bam_nrecs(dbc, rep)
pgno = dbc->internal->root; pgno = dbc->internal->root;
if ((ret = __db_lget(dbc, 0, pgno, DB_LOCK_READ, 0, &lock)) != 0) if ((ret = __db_lget(dbc, 0, pgno, DB_LOCK_READ, 0, &lock)) != 0)
return (ret); return (ret);
if ((ret = mpf->get(mpf, &pgno, 0, &h)) != 0) if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0)
return (ret); return (ret);
*rep = RE_NREC(h); *rep = RE_NREC(h);
(void)mpf->put(mpf, h, 0); ret = __memp_fput(mpf, h, 0);
(void)__TLPUT(dbc, lock); if ((t_ret = __TLPUT(dbc, lock)) != 0 && ret == 0)
ret = t_ret;
return (0); return (ret);
} }
/* /*
......
/*- /*-
* See the file LICENSE for redistribution information. * See the file LICENSE for redistribution information.
* *
* Copyright (c) 1996-2002 * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved. * Sleepycat Software. All rights reserved.
*/ */
/* /*
...@@ -38,14 +38,12 @@ ...@@ -38,14 +38,12 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
*
* $Id: bt_search.c,v 11.50 2004/07/23 17:21:09 bostic Exp $
*/ */
#include "db_config.h" #include "db_config.h"
#ifndef lint
static const char revid[] = "$Id: bt_search.c,v 11.43 2002/07/03 19:03:50 bostic Exp $";
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h> #include <sys/types.h>
...@@ -57,6 +55,7 @@ static const char revid[] = "$Id: bt_search.c,v 11.43 2002/07/03 19:03:50 bostic ...@@ -57,6 +55,7 @@ static const char revid[] = "$Id: bt_search.c,v 11.43 2002/07/03 19:03:50 bostic
#include "dbinc/db_shash.h" #include "dbinc/db_shash.h"
#include "dbinc/btree.h" #include "dbinc/btree.h"
#include "dbinc/lock.h" #include "dbinc/lock.h"
#include "dbinc/mp.h"
/* /*
* __bam_search -- * __bam_search --
...@@ -84,12 +83,13 @@ __bam_search(dbc, root_pgno, key, flags, stop, recnop, exactp) ...@@ -84,12 +83,13 @@ __bam_search(dbc, root_pgno, key, flags, stop, recnop, exactp)
db_lockmode_t lock_mode; db_lockmode_t lock_mode;
db_pgno_t pg; db_pgno_t pg;
db_recno_t recno; db_recno_t recno;
int adjust, cmp, deloffset, ret, stack; int adjust, cmp, deloffset, ret, stack, t_ret;
int (*func) __P((DB *, const DBT *, const DBT *)); int (*func) __P((DB *, const DBT *, const DBT *));
dbp = dbc->dbp; dbp = dbc->dbp;
mpf = dbp->mpf; mpf = dbp->mpf;
cp = (BTREE_CURSOR *)dbc->internal; cp = (BTREE_CURSOR *)dbc->internal;
h = NULL;
t = dbp->bt_internal; t = dbp->bt_internal;
recno = 0; recno = 0;
...@@ -117,7 +117,7 @@ __bam_search(dbc, root_pgno, key, flags, stop, recnop, exactp) ...@@ -117,7 +117,7 @@ __bam_search(dbc, root_pgno, key, flags, stop, recnop, exactp)
lock_mode = stack ? DB_LOCK_WRITE : DB_LOCK_READ; lock_mode = stack ? DB_LOCK_WRITE : DB_LOCK_READ;
if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0) if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
return (ret); return (ret);
if ((ret = mpf->get(mpf, &pg, 0, &h)) != 0) { if ((ret = __memp_fget(mpf, &pg, 0, &h)) != 0) {
/* Did not read it, so we can release the lock */ /* Did not read it, so we can release the lock */
(void)__LPUT(dbc, lock); (void)__LPUT(dbc, lock);
return (ret); return (ret);
...@@ -134,12 +134,15 @@ __bam_search(dbc, root_pgno, key, flags, stop, recnop, exactp) ...@@ -134,12 +134,15 @@ __bam_search(dbc, root_pgno, key, flags, stop, recnop, exactp)
if (!stack && if (!stack &&
((LF_ISSET(S_PARENT) && (u_int8_t)(stop + 1) >= h->level) || ((LF_ISSET(S_PARENT) && (u_int8_t)(stop + 1) >= h->level) ||
(LF_ISSET(S_WRITE) && h->level == LEAFLEVEL))) { (LF_ISSET(S_WRITE) && h->level == LEAFLEVEL))) {
(void)mpf->put(mpf, h, 0); ret = __memp_fput(mpf, h, 0);
(void)__LPUT(dbc, lock); if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
ret = t_ret;
if (ret != 0)
return (ret);
lock_mode = DB_LOCK_WRITE; lock_mode = DB_LOCK_WRITE;
if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0) if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
return (ret); return (ret);
if ((ret = mpf->get(mpf, &pg, 0, &h)) != 0) { if ((ret = __memp_fget(mpf, &pg, 0, &h)) != 0) {
/* Did not read it, so we can release the lock */ /* Did not read it, so we can release the lock */
(void)__LPUT(dbc, lock); (void)__LPUT(dbc, lock);
return (ret); return (ret);
...@@ -148,8 +151,11 @@ __bam_search(dbc, root_pgno, key, flags, stop, recnop, exactp) ...@@ -148,8 +151,11 @@ __bam_search(dbc, root_pgno, key, flags, stop, recnop, exactp)
(u_int8_t)(stop + 1) >= h->level) || (u_int8_t)(stop + 1) >= h->level) ||
(LF_ISSET(S_WRITE) && h->level == LEAFLEVEL))) { (LF_ISSET(S_WRITE) && h->level == LEAFLEVEL))) {
/* Someone else split the root, start over. */ /* Someone else split the root, start over. */
(void)mpf->put(mpf, h, 0); ret = __memp_fput(mpf, h, 0);
(void)__LPUT(dbc, lock); if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
ret = t_ret;
if (ret != 0)
return (ret);
goto try_again; goto try_again;
} }
stack = 1; stack = 1;
...@@ -197,13 +203,19 @@ __bam_search(dbc, root_pgno, key, flags, stop, recnop, exactp) ...@@ -197,13 +203,19 @@ __bam_search(dbc, root_pgno, key, flags, stop, recnop, exactp)
if (TYPE(h) == P_LBTREE || TYPE(h) == P_LDUP) { if (TYPE(h) == P_LBTREE || TYPE(h) == P_LDUP) {
*exactp = 0; *exactp = 0;
if (LF_ISSET(S_EXACT)) if (LF_ISSET(S_EXACT)) {
goto notfound; ret = DB_NOTFOUND;
goto err;
}
if (LF_ISSET(S_STK_ONLY)) { if (LF_ISSET(S_STK_ONLY)) {
BT_STK_NUM(dbp->dbenv, cp, h, base, ret); BT_STK_NUM(dbp->dbenv, cp, h, base, ret);
__LPUT(dbc, lock); if ((t_ret =
(void)mpf->put(mpf, h, 0); __LPUT(dbc, lock)) != 0 && ret == 0)
ret = t_ret;
if ((t_ret =
__memp_fput(mpf, h, 0)) != 0 && ret == 0)
ret = t_ret;
return (ret); return (ret);
} }
...@@ -243,12 +255,17 @@ next: if (recnop != NULL) ...@@ -243,12 +255,17 @@ next: if (recnop != NULL)
if (LF_ISSET(S_STK_ONLY)) { if (LF_ISSET(S_STK_ONLY)) {
if (stop == h->level) { if (stop == h->level) {
BT_STK_NUM(dbp->dbenv, cp, h, indx, ret); BT_STK_NUM(dbp->dbenv, cp, h, indx, ret);
__LPUT(dbc, lock); if ((t_ret =
(void)mpf->put(mpf, h, 0); __LPUT(dbc, lock)) != 0 && ret == 0)
ret = t_ret;
if ((t_ret =
__memp_fput(mpf, h, 0)) != 0 && ret == 0)
ret = t_ret;
return (ret); return (ret);
} }
BT_STK_NUMPUSH(dbp->dbenv, cp, h, indx, ret); BT_STK_NUMPUSH(dbp->dbenv, cp, h, indx, ret);
(void)mpf->put(mpf, h, 0); (void)__memp_fput(mpf, h, 0);
h = NULL;
if ((ret = __db_lget(dbc, if ((ret = __db_lget(dbc,
LCK_COUPLE_ALWAYS, pg, lock_mode, 0, &lock)) != 0) { LCK_COUPLE_ALWAYS, pg, lock_mode, 0, &lock)) != 0) {
/* /*
...@@ -256,7 +273,7 @@ next: if (recnop != NULL) ...@@ -256,7 +273,7 @@ next: if (recnop != NULL)
* is OK because it only happens when descending * is OK because it only happens when descending
* the tree holding read-locks. * the tree holding read-locks.
*/ */
__LPUT(dbc, lock); (void)__LPUT(dbc, lock);
return (ret); return (ret);
} }
} else if (stack) { } else if (stack) {
...@@ -272,6 +289,7 @@ next: if (recnop != NULL) ...@@ -272,6 +289,7 @@ next: if (recnop != NULL)
cp, h, indx, lock, lock_mode, ret); cp, h, indx, lock, lock_mode, ret);
if (ret != 0) if (ret != 0)
goto err; goto err;
h = NULL;
lock_mode = DB_LOCK_WRITE; lock_mode = DB_LOCK_WRITE;
if ((ret = if ((ret =
...@@ -288,7 +306,9 @@ next: if (recnop != NULL) ...@@ -288,7 +306,9 @@ next: if (recnop != NULL)
(h->level - 1) == LEAFLEVEL) (h->level - 1) == LEAFLEVEL)
stack = 1; stack = 1;
(void)mpf->put(mpf, h, 0); if ((ret = __memp_fput(mpf, h, 0)) != 0)
goto err;
h = NULL;
lock_mode = stack && lock_mode = stack &&
LF_ISSET(S_WRITE) ? DB_LOCK_WRITE : DB_LOCK_READ; LF_ISSET(S_WRITE) ? DB_LOCK_WRITE : DB_LOCK_READ;
...@@ -299,25 +319,17 @@ next: if (recnop != NULL) ...@@ -299,25 +319,17 @@ next: if (recnop != NULL)
* is OK because this only happens when we are * is OK because this only happens when we are
* descending the tree holding read-locks. * descending the tree holding read-locks.
*/ */
__LPUT(dbc, lock); (void)__LPUT(dbc, lock);
goto err; goto err;
} }
} }
if ((ret = mpf->get(mpf, &pg, 0, &h)) != 0) if ((ret = __memp_fget(mpf, &pg, 0, &h)) != 0)
goto err; goto err;
} }
/* NOTREACHED */ /* NOTREACHED */
found: *exactp = 1; found: *exactp = 1;
/*
* If we're trying to calculate the record number, add in the
* offset on this page and correct for the fact that records
* in the tree are 0-based.
*/
if (recnop != NULL)
*recnop = recno + (indx / P_INDX) + 1;
/* /*
* If we got here, we know that we have a Btree leaf or off-page * If we got here, we know that we have a Btree leaf or off-page
* duplicates page. If it's a Btree leaf page, we have to handle * duplicates page. If it's a Btree leaf page, we have to handle
...@@ -345,6 +357,7 @@ found: *exactp = 1; ...@@ -345,6 +357,7 @@ found: *exactp = 1;
* not move from the original found key on the basis of the S_DELNO * not move from the original found key on the basis of the S_DELNO
* flag.) * flag.)
*/ */
DB_ASSERT(recnop == NULL || LF_ISSET(S_DELNO));
if (LF_ISSET(S_DELNO)) { if (LF_ISSET(S_DELNO)) {
deloffset = TYPE(h) == P_LBTREE ? O_INDX : 0; deloffset = TYPE(h) == P_LBTREE ? O_INDX : 0;
if (LF_ISSET(S_DUPLAST)) if (LF_ISSET(S_DUPLAST))
...@@ -363,29 +376,53 @@ found: *exactp = 1; ...@@ -363,29 +376,53 @@ found: *exactp = 1;
* If we weren't able to find a non-deleted duplicate, return * If we weren't able to find a non-deleted duplicate, return
* DB_NOTFOUND. * DB_NOTFOUND.
*/ */
if (B_DISSET(GET_BKEYDATA(dbp, h, indx + deloffset)->type)) if (B_DISSET(GET_BKEYDATA(dbp, h, indx + deloffset)->type)) {
goto notfound; ret = DB_NOTFOUND;
goto err;
}
/*
* Increment the record counter to point to the found element.
* Ignore any deleted key/data pairs. There doesn't need to
* be any correction for duplicates, as Btree doesn't support
* duplicates and record numbers in the same tree.
*/
if (recnop != NULL) {
DB_ASSERT(TYPE(h) == P_LBTREE);
for (i = 0; i < indx; i += P_INDX)
if (!B_DISSET(
GET_BKEYDATA(dbp, h, i + O_INDX)->type))
++recno;
/* Correct the number for a 0-base. */
*recnop = recno + 1;
}
} }
if (LF_ISSET(S_STK_ONLY)) { if (LF_ISSET(S_STK_ONLY)) {
BT_STK_NUM(dbp->dbenv, cp, h, indx, ret); BT_STK_NUM(dbp->dbenv, cp, h, indx, ret);
__LPUT(dbc, lock); if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
(void)mpf->put(mpf, h, 0); ret = t_ret;
} else { if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
ret = t_ret;
} else
BT_STK_ENTER(dbp->dbenv, cp, h, indx, lock, lock_mode, ret); BT_STK_ENTER(dbp->dbenv, cp, h, indx, lock, lock_mode, ret);
if (ret != 0) if (ret != 0)
goto err; goto err;
}
return (0); return (0);
notfound: err: if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
/* Keep the page locked for serializability. */ ret = t_ret;
(void)mpf->put(mpf, h, 0);
(void)__TLPUT(dbc, lock); /* Keep any not-found page locked for serializability. */
ret = DB_NOTFOUND; if ((t_ret = __TLPUT(dbc, lock)) != 0 && ret == 0)
ret = t_ret;
err: BT_STK_POP(cp); BT_STK_POP(cp);
__bam_stkrel(dbc, 0); __bam_stkrel(dbc, 0);
return (ret); return (ret);
} }
...@@ -423,7 +460,7 @@ __bam_stkrel(dbc, flags) ...@@ -423,7 +460,7 @@ __bam_stkrel(dbc, flags)
LOCK_INIT(cp->lock); LOCK_INIT(cp->lock);
} }
if ((t_ret = if ((t_ret =
mpf->put(mpf, epg->page, 0)) != 0 && ret == 0) __memp_fput(mpf, epg->page, 0)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
/* /*
* XXX * XXX
...@@ -434,10 +471,12 @@ __bam_stkrel(dbc, flags) ...@@ -434,10 +471,12 @@ __bam_stkrel(dbc, flags)
*/ */
epg->page = NULL; epg->page = NULL;
} }
if (LF_ISSET(STK_NOLOCK)) if (LF_ISSET(STK_NOLOCK)) {
(void)__LPUT(dbc, epg->lock); if ((t_ret = __LPUT(dbc, epg->lock)) != 0 && ret == 0)
else ret = t_ret;
(void)__TLPUT(dbc, epg->lock); } else
if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
ret = t_ret;
} }
/* Clear the stack, all pages have been released. */ /* Clear the stack, all pages have been released. */
......
/*- /*-
* See the file LICENSE for redistribution information. * See the file LICENSE for redistribution information.
* *
* Copyright (c) 1996-2002 * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved. * Sleepycat Software. All rights reserved.
*/ */
/* /*
...@@ -35,18 +35,15 @@ ...@@ -35,18 +35,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
*
* $Id: bt_split.c,v 11.66 2004/10/01 13:00:21 bostic Exp $
*/ */
#include "db_config.h" #include "db_config.h"
#ifndef lint
static const char revid[] = "$Id: bt_split.c,v 11.58 2002/07/03 19:03:50 bostic Exp $";
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h> #include <sys/types.h>
#include <limits.h>
#include <string.h> #include <string.h>
#endif #endif
...@@ -54,6 +51,7 @@ static const char revid[] = "$Id: bt_split.c,v 11.58 2002/07/03 19:03:50 bostic ...@@ -54,6 +51,7 @@ static const char revid[] = "$Id: bt_split.c,v 11.58 2002/07/03 19:03:50 bostic
#include "dbinc/db_page.h" #include "dbinc/db_page.h"
#include "dbinc/db_shash.h" #include "dbinc/db_shash.h"
#include "dbinc/lock.h" #include "dbinc/lock.h"
#include "dbinc/mp.h"
#include "dbinc/btree.h" #include "dbinc/btree.h"
static int __bam_broot __P((DBC *, PAGE *, PAGE *, PAGE *)); static int __bam_broot __P((DBC *, PAGE *, PAGE *, PAGE *));
...@@ -119,7 +117,7 @@ __bam_split(dbc, arg, root_pgnop) ...@@ -119,7 +117,7 @@ __bam_split(dbc, arg, root_pgnop)
arg, S_WRPAIR, level, NULL, &exact) : arg, S_WRPAIR, level, NULL, &exact) :
__bam_rsearch(dbc, __bam_rsearch(dbc,
(db_recno_t *)arg, S_WRPAIR, level, &exact))) != 0) (db_recno_t *)arg, S_WRPAIR, level, &exact))) != 0)
return (ret); break;
if (root_pgnop != NULL) if (root_pgnop != NULL)
*root_pgnop = cp->csp[0].page->pgno == root_pgno ? *root_pgnop = cp->csp[0].page->pgno == root_pgno ?
...@@ -133,7 +131,7 @@ __bam_split(dbc, arg, root_pgnop) ...@@ -133,7 +131,7 @@ __bam_split(dbc, arg, root_pgnop)
if (2 * B_MAXSIZEONPAGE(cp->ovflsize) if (2 * B_MAXSIZEONPAGE(cp->ovflsize)
<= (db_indx_t)P_FREESPACE(dbc->dbp, cp->csp[0].page)) { <= (db_indx_t)P_FREESPACE(dbc->dbp, cp->csp[0].page)) {
__bam_stkrel(dbc, STK_NOLOCK); __bam_stkrel(dbc, STK_NOLOCK);
return (0); break;
} }
ret = cp->csp[0].page->pgno == root_pgno ? ret = cp->csp[0].page->pgno == root_pgno ?
__bam_root(dbc, &cp->csp[0]) : __bam_root(dbc, &cp->csp[0]) :
...@@ -161,10 +159,13 @@ __bam_split(dbc, arg, root_pgnop) ...@@ -161,10 +159,13 @@ __bam_split(dbc, arg, root_pgnop)
dir = UP; dir = UP;
break; break;
default: default:
return (ret); goto err;
} }
} }
/* NOTREACHED */
err: if (root_pgnop != NULL)
*root_pgnop = cp->root;
return (ret);
} }
/* /*
...@@ -183,10 +184,11 @@ __bam_root(dbc, cp) ...@@ -183,10 +184,11 @@ __bam_root(dbc, cp)
PAGE *lp, *rp; PAGE *lp, *rp;
db_indx_t split; db_indx_t split;
u_int32_t opflags; u_int32_t opflags;
int ret; int ret, t_ret;
dbp = dbc->dbp; dbp = dbc->dbp;
mpf = dbp->mpf; mpf = dbp->mpf;
lp = rp = NULL;
/* Yeah, right. */ /* Yeah, right. */
if (cp->page->level >= MAXBTREELEVEL) { if (cp->page->level >= MAXBTREELEVEL) {
...@@ -197,7 +199,6 @@ __bam_root(dbc, cp) ...@@ -197,7 +199,6 @@ __bam_root(dbc, cp)
} }
/* Create new left and right pages for the split. */ /* Create new left and right pages for the split. */
lp = rp = NULL;
if ((ret = __db_new(dbc, TYPE(cp->page), &lp)) != 0 || if ((ret = __db_new(dbc, TYPE(cp->page), &lp)) != 0 ||
(ret = __db_new(dbc, TYPE(cp->page), &rp)) != 0) (ret = __db_new(dbc, TYPE(cp->page), &rp)) != 0)
goto err; goto err;
...@@ -237,24 +238,21 @@ __bam_root(dbc, cp) ...@@ -237,24 +238,21 @@ __bam_root(dbc, cp)
goto err; goto err;
/* Adjust any cursors. */ /* Adjust any cursors. */
if ((ret = __bam_ca_split(dbc, ret = __bam_ca_split(dbc, cp->page->pgno, lp->pgno, rp->pgno, split, 1);
cp->page->pgno, lp->pgno, rp->pgno, split, 1)) != 0)
goto err;
/* Success -- write the real pages back to the store. */ /* Success or error: release pages and locks. */
(void)mpf->put(mpf, cp->page, DB_MPOOL_DIRTY); err: if ((t_ret =
(void)__TLPUT(dbc, cp->lock); __memp_fput(mpf, cp->page, DB_MPOOL_DIRTY)) != 0 && ret == 0)
(void)mpf->put(mpf, lp, DB_MPOOL_DIRTY); ret = t_ret;
(void)mpf->put(mpf, rp, DB_MPOOL_DIRTY); if ((t_ret = __TLPUT(dbc, cp->lock)) != 0 && ret == 0)
ret = t_ret;
return (0); if (lp != NULL &&
(t_ret = __memp_fput(mpf, lp, DB_MPOOL_DIRTY)) != 0 && ret == 0)
ret = t_ret;
if (rp != NULL &&
(t_ret = __memp_fput(mpf, rp, DB_MPOOL_DIRTY)) != 0 && ret == 0)
ret = t_ret;
err: if (lp != NULL)
(void)mpf->put(mpf, lp, 0);
if (rp != NULL)
(void)mpf->put(mpf, rp, 0);
(void)mpf->put(mpf, cp->page, 0);
(void)__TLPUT(dbc, cp->lock);
return (ret); return (ret);
} }
...@@ -358,7 +356,7 @@ __bam_page(dbc, pp, cp) ...@@ -358,7 +356,7 @@ __bam_page(dbc, pp, cp)
if ((ret = __db_lget(dbc, if ((ret = __db_lget(dbc,
0, NEXT_PGNO(cp->page), DB_LOCK_WRITE, 0, &tplock)) != 0) 0, NEXT_PGNO(cp->page), DB_LOCK_WRITE, 0, &tplock)) != 0)
goto err; goto err;
if ((ret = mpf->get(mpf, &NEXT_PGNO(cp->page), 0, &tp)) != 0) if ((ret = __memp_fget(mpf, &NEXT_PGNO(cp->page), 0, &tp)) != 0)
goto err; goto err;
} }
...@@ -370,9 +368,13 @@ __bam_page(dbc, pp, cp) ...@@ -370,9 +368,13 @@ __bam_page(dbc, pp, cp)
goto err; goto err;
/* /*
* Lock the new page. We need to do this because someone * Lock the new page. We need to do this for two reasons: first, the
* could get here through bt_lpgno if this page was recently * fast-lookup code might have a reference to this page in bt_lpgno if
* dealocated. They can't look at it before we commit. * the page was recently deleted from the tree, and that code doesn't
* walk the tree and so won't encounter the parent's page lock.
* Second, a dirty reader could get to this page via the parent or old
* page after the split is done but before the transaction is committed
* or aborted.
*/ */
if ((ret = __db_lget(dbc, if ((ret = __db_lget(dbc,
0, PGNO(alloc_rp), DB_LOCK_WRITE, 0, &rplock)) != 0) 0, PGNO(alloc_rp), DB_LOCK_WRITE, 0, &rplock)) != 0)
...@@ -456,20 +458,27 @@ __bam_page(dbc, pp, cp) ...@@ -456,20 +458,27 @@ __bam_page(dbc, pp, cp)
* releasing locks on the pages that reference it. We're finished * releasing locks on the pages that reference it. We're finished
* modifying the page so it's not really necessary, but it's neater. * modifying the page so it's not really necessary, but it's neater.
*/ */
if ((t_ret = mpf->put(mpf, alloc_rp, DB_MPOOL_DIRTY)) != 0 && ret == 0) if ((t_ret =
__memp_fput(mpf, alloc_rp, DB_MPOOL_DIRTY)) != 0 && ret == 0)
ret = t_ret;
if ((t_ret = __TLPUT(dbc, rplock)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
(void)__TLPUT(dbc, rplock); if ((t_ret =
if ((t_ret = mpf->put(mpf, pp->page, DB_MPOOL_DIRTY)) != 0 && ret == 0) __memp_fput(mpf, pp->page, DB_MPOOL_DIRTY)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
(void)__TLPUT(dbc, pp->lock); if ((t_ret = __TLPUT(dbc, pp->lock)) != 0 && ret == 0)
if ((t_ret = mpf->put(mpf, cp->page, DB_MPOOL_DIRTY)) != 0 && ret == 0) ret = t_ret;
if ((t_ret =
__memp_fput(mpf, cp->page, DB_MPOOL_DIRTY)) != 0 && ret == 0)
ret = t_ret;
if ((t_ret = __TLPUT(dbc, cp->lock)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
(void)__TLPUT(dbc, cp->lock);
if (tp != NULL) { if (tp != NULL) {
if ((t_ret = if ((t_ret =
mpf->put(mpf, tp, DB_MPOOL_DIRTY)) != 0 && ret == 0) __memp_fput(mpf, tp, DB_MPOOL_DIRTY)) != 0 && ret == 0)
ret = t_ret;
if ((t_ret = __TLPUT(dbc, tplock)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
(void)__TLPUT(dbc, tplock);
} }
return (ret); return (ret);
...@@ -478,21 +487,21 @@ err: if (lp != NULL) ...@@ -478,21 +487,21 @@ err: if (lp != NULL)
if (rp != NULL) if (rp != NULL)
__os_free(dbp->dbenv, rp); __os_free(dbp->dbenv, rp);
if (alloc_rp != NULL) if (alloc_rp != NULL)
(void)mpf->put(mpf, alloc_rp, 0); (void)__memp_fput(mpf, alloc_rp, 0);
if (tp != NULL) if (tp != NULL)
(void)mpf->put(mpf, tp, 0); (void)__memp_fput(mpf, tp, 0);
/* We never updated the new or next pages, we can release them. */ /* We never updated the new or next pages, we can release them. */
(void)__LPUT(dbc, rplock); (void)__LPUT(dbc, rplock);
(void)__LPUT(dbc, tplock); (void)__LPUT(dbc, tplock);
(void)mpf->put(mpf, pp->page, 0); (void)__memp_fput(mpf, pp->page, 0);
if (ret == DB_NEEDSPLIT) if (ret == DB_NEEDSPLIT)
(void)__LPUT(dbc, pp->lock); (void)__LPUT(dbc, pp->lock);
else else
(void)__TLPUT(dbc, pp->lock); (void)__TLPUT(dbc, pp->lock);
(void)mpf->put(mpf, cp->page, 0); (void)__memp_fput(mpf, cp->page, 0);
if (ret == DB_NEEDSPLIT) if (ret == DB_NEEDSPLIT)
(void)__LPUT(dbc, cp->lock); (void)__LPUT(dbc, cp->lock);
else else
......
This diff is collapsed.
/*- /*-
* See the file LICENSE for redistribution information. * See the file LICENSE for redistribution information.
* *
* Copyright (c) 1996-2002 * Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved. * Sleepycat Software. All rights reserved.
*
* $Id: bt_upgrade.c,v 11.30 2004/01/28 03:35:49 bostic Exp $
*/ */
#include "db_config.h" #include "db_config.h"
#ifndef lint
static const char revid[] = "$Id: bt_upgrade.c,v 11.25 2002/08/06 06:11:13 bostic Exp $";
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h> #include <sys/types.h>
#include <limits.h>
#include <string.h> #include <string.h>
#endif #endif
#include "db_int.h" #include "db_int.h"
#include "dbinc/db_page.h" #include "dbinc/db_page.h"
#include "dbinc/db_am.h"
#include "dbinc/db_upgrade.h" #include "dbinc/db_upgrade.h"
#include "dbinc/btree.h"
/* /*
* __bam_30_btreemeta -- * __bam_30_btreemeta --
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -42,7 +42,7 @@ RSC=rc.exe ...@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /I "../dbinc" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
...@@ -71,7 +71,7 @@ PostBuild_Cmds=copy Release\*.exe . ...@@ -71,7 +71,7 @@ PostBuild_Cmds=copy Release\*.exe .
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /I "../dbinc" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -20,7 +20,7 @@ BEGIN ...@@ -20,7 +20,7 @@ BEGIN
VALUE "FileDescription", "Berkeley DB 3.0 DLL\0" VALUE "FileDescription", "Berkeley DB 3.0 DLL\0"
VALUE "FileVersion", "%MAJOR%.%MINOR%.%PATCH%\0" VALUE "FileVersion", "%MAJOR%.%MINOR%.%PATCH%\0"
VALUE "InternalName", "libdb.dll\0" VALUE "InternalName", "libdb.dll\0"
VALUE "LegalCopyright", "Copyright Sleepycat Software Inc. 1997-2002\0" VALUE "LegalCopyright", "Copyright Sleepycat Software Inc. 1997-2004\0"
VALUE "OriginalFilename", "libdb.dll\0" VALUE "OriginalFilename", "libdb.dll\0"
VALUE "ProductName", "Sleepycat Software libdb\0" VALUE "ProductName", "Sleepycat Software libdb\0"
VALUE "ProductVersion", "%MAJOR%.%MINOR%.%PATCH%\0" VALUE "ProductVersion", "%MAJOR%.%MINOR%.%PATCH%\0"
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment