/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996, 1997, 1998
* Sleepycat Software. All rights reserved.
*/
#include "config.h"
#ifndef lint
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES
#include <errno.h>
#include <string.h>
#endif
#include "db_int.h"
#include "db_page.h"
#include "shqueue.h"
#include "hash.h"
#include "btree.h"
#include "log.h"
#include "common_ext.h"
/*
* __bam_pg_alloc_recover --
* Recovery function for pg_alloc.
*
* PUBLIC: int __bam_pg_alloc_recover
* PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
*/
int
int redo;
void *info;
{
/*
* Fix up the allocated page. If we're redoing the operation, we have
* to get the page (creating it if it doesn't exist), and update its
* LSN. If we're undoing the operation, we have to reset the page's
* LSN and put it on the free list.
*
* Fix up the metadata page. If we're redoing the operation, we have
* to get the metadata page and update its LSN and its free pointer.
* If we're undoing the operation and the page was ever created, we put
* it on the freelist.
*/
/* The metadata page must always exist. */
goto out;
}
/*
* We specify creation and check for it later, because this
* operation was supposed to create the page, and even in
* the undo case it's going to get linked onto the freelist
* which we're also fixing up.
*/
goto out;
}
/* Fix up the allocated page. */
modified = 0;
/* Need to redo update described. */
modified = 1;
/* Need to undo update described. */
modified = 1;
}
goto out;
}
/* Fix up the metadata page. */
modified = 0;
/* Need to redo update described. */
modified = 1;
/* Need to undo update described. */
modified = 1;
}
goto out;
ret = 0;
}
/*
* __bam_pg_free_recover --
* Recovery function for pg_free.
*
* PUBLIC: int __bam_pg_free_recover
* PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
*/
int
int redo;
void *info;
{
/*
* Fix up the freed page. If we're redoing the operation we get the
* page and explicitly discard its contents, then update its LSN. If
* we're undoing the operation, we get the page and restore its header.
*/
/*
* We don't automatically create the page. The only way the
* page might not exist is if the alloc never happened, and
* the only way the alloc might never have happened is if we
* are undoing, in which case there's no reason to create the
* page.
*/
if (!redo)
goto done;
goto out;
}
modified = 0;
/* Need to redo update described. */
modified = 1;
/* Need to undo update described. */
modified = 1;
}
goto out;
/*
* Fix up the metadata page. If we're redoing or undoing the operation
* we get the page and update its LSN and free pointer.
*/
/* The metadata page must always exist. */
goto out;
}
modified = 0;
/* Need to redo update described. */
modified = 1;
/* Need to undo update described. */
modified = 1;
}
goto out;
ret = 0;
}
/*
* __bam_split_recover --
* Recovery function for split.
*
* PUBLIC: int __bam_split_recover
* PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
*/
int
int redo;
void *info;
{
/*
* There are two kinds of splits that we have to recover from. The
* first is a root-page split, where the root page is split from a
* leaf page into an internal page and two new leaf pages are created.
* The second is where a page is split into two pages, and a new key
* is inserted into the parent page.
*/
if (redo) {
/*
* Decide if we need to resplit the page.
*
* If this is a root split, then the root has to exist, it's
* the page we're splitting and it gets modified. If this is
* not a root split, then the left page has to exist, for the
* same reason.
*/
if (rootsplit) {
goto out;
}
p_update =
} else
goto out;
}
l_update = 1;
r_update = 1;
goto done;
goto out;
if (rootsplit) {
} else {
}
/* Split the page. */
goto out;
/* If the left child is wrong, update it. */
goto out;
}
if (l_update) {
goto out;
}
/* If the right child is wrong, update it. */
goto out;
}
if (r_update) {
goto out;
}
/*
* If the parent page is wrong, update it. This is of interest
* only if it was a root split, since root splits create parent
* pages. All other splits modify a parent page, but those are
* separately logged and recovered.
*/
else
goto out;
}
/*
* Finally, redo the next-page link if necessary. This is of
* interest only if it wasn't a root split -- inserting a new
* page in the tree requires that any following page have its
* previous-page pointer updated to our new page. The next
* page must exist because we're redoing the operation.
*/
goto out;
}
if ((ret =
goto out;
}
}
} else {
/*
* If the split page is wrong, replace its contents with the
* logged page contents. If the page doesn't exist, it means
* that the create of the page never happened, nor did any of
* the adds onto the page that caused the split, and there's
* really no undo-ing to be done.
*/
goto lrundo;
}
goto out;
}
/*
* If it's a root split and the left child ever existed, update
* its LSN. (If it's not a root split, we've updated the left
* page already -- it's the same as the split page.) If the
* right child ever existed, root split or not, update its LSN.
* The undo of the page allocation(s) will restore them to the
* free list.
*/
if ((ret =
goto out;
}
if ((ret =
goto out;
}
}
/*
* Finally, undo the next-page link if necessary. This is of
* interest only if it wasn't a root split -- inserting a new
* page in the tree requires that any following page have its
* previous-page pointer updated to our new page. Since it's
* possible that the next-page never existed, we ignore it as
* if there's nothing to undo.
*/
goto done;
}
goto out;
}
}
}
ret = 0;
out: /* Free any pages that weren't dirtied. */
/* Free any allocated space. */
}
/*
* __bam_rsplit_recover --
* Recovery function for a reverse split.
*
* PUBLIC: int __bam_rsplit_recover
* PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
*/
int
int redo;
void *info;
{
/* Fix the root page. */
/* The root page must always exist. */
goto out;
}
modified = 0;
/* Need to redo update described. */
modified = 1;
/* Need to undo update described. */
goto out;
modified = 1;
}
goto out;
/*
* Fix the page copied over the root page. It's possible that the
* page never made it to disk, so if we're undo-ing and the page
* doesn't exist, it's okay and there's nothing further to do.
*/
if (!redo)
goto done;
goto out;
}
modified = 0;
/* Need to redo update described. */
modified = 1;
/* Need to undo update described. */
modified = 1;
}
goto out;
ret = 0;
}
/*
* __bam_adj_recover --
* Recovery function for adj.
*
* PUBLIC: int __bam_adj_recover
* PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
*/
int
int redo;
void *info;
{
/* Get the page; if it never existed and we're undoing, we're done. */
if (!redo)
goto done;
goto out;
}
modified = 0;
/* Need to redo update described. */
goto err;
modified = 1;
/* Need to undo update described. */
goto err;
modified = 1;
}
goto out;
ret = 0;
if (0) {
}
}
/*
* __bam_cadjust_recover --
* Recovery function for the adjust of a count change in an internal
* page.
*
* PUBLIC: int __bam_cadjust_recover
* PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
*/
int
int redo;
void *info;
{
/* Get the page; if it never existed and we're undoing, we're done. */
if (!redo)
goto done;
goto out;
}
modified = 0;
/* Need to redo update described. */
}
}
modified = 1;
/* Need to undo update described. */
}
}
modified = 1;
}
goto out;
ret = 0;
}
/*
* __bam_cdel_recover --
* Recovery function for the intent-to-delete of a cursor record.
*
* PUBLIC: int __bam_cdel_recover
* PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
*/
int
int redo;
void *info;
{
/* Get the page; if it never existed and we're undoing, we're done. */
if (!redo)
goto done;
goto out;
}
modified = 0;
/* Need to redo update described. */
else
modified = 1;
/* Need to undo update described. */
else
modified = 1;
}
goto out;
ret = 0;
}
/*
* __bam_repl_recover --
* Recovery function for page item replacement.
*
* PUBLIC: int __bam_repl_recover
* PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
*/
int
int redo;
void *info;
{
u_int8_t *p;
/* Get the page; if it never existed and we're undoing, we're done. */
if (!redo)
goto done;
goto out;
}
modified = 0;
/*
* Need to redo update described.
*
* Re-build the replacement item.
*/
goto err;
if (ret != 0)
goto err;
modified = 1;
/*
* Need to undo update described.
*
* Re-build the original item.
*/
goto err;
if (ret != 0)
goto err;
/* Reset the deleted flag, if necessary. */
modified = 1;
}
goto out;
ret = 0;
if (0) {
}
}