about summary refs log tree commit diff
path: root/db2/hash/hash_rec.c
diff options
context:
space:
mode:
Diffstat (limited to 'db2/hash/hash_rec.c')
-rw-r--r--db2/hash/hash_rec.c146
1 files changed, 142 insertions, 4 deletions
diff --git a/db2/hash/hash_rec.c b/db2/hash/hash_rec.c
index 1b30be337d..d239e3d0df 100644
--- a/db2/hash/hash_rec.c
+++ b/db2/hash/hash_rec.c
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash_rec.c	10.13 (Sleepycat) 9/15/97";
+static const char sccsid[] = "@(#)hash_rec.c	10.14 (Sleepycat) 11/2/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -756,7 +756,6 @@ __ham_ovfl_recover(logp, dbtp, lsnp, redo, info)
 	hashp = (HTAB *)file_dbp->internal;
 	GET_META(file_dbp, hashp);
 	getmeta = 1;
-	file_dbp = NULL;
 
 	cmp_n = log_compare(lsnp, &hashp->hdr->lsn);
 	cmp_p = log_compare(&hashp->hdr->lsn, &argp->metalsn);
@@ -764,12 +763,12 @@ __ham_ovfl_recover(logp, dbtp, lsnp, redo, info)
 	if (cmp_p == 0 && redo) {
 		/* Redo the allocation. */
 		hashp->hdr->last_freed = argp->start_pgno;
-		hashp->hdr->spares[argp->npages  - 1] += argp->npages;
+		hashp->hdr->spares[argp->ovflpoint] += argp->npages;
 		hashp->hdr->lsn = *lsnp;
 		F_SET(file_dbp, DB_HS_DIRTYMETA);
 	} else if (cmp_n == 0 && !redo) {
 		hashp->hdr->last_freed = argp->free_pgno;
-		hashp->hdr->spares[argp->npages  - 1] -= argp->npages;
+		hashp->hdr->spares[argp->ovflpoint] -= argp->npages;
 		hashp->hdr->lsn = argp->metalsn;
 		F_SET(file_dbp, DB_HS_DIRTYMETA);
 	}
@@ -808,3 +807,142 @@ out:	if (getmeta)
 		RELEASE_META(file_dbp, hashp);
 	REC_CLOSE;
 }
+
+/*
+ * __ham_copypage_recover --
+ *	Recovery function for copypage.
+ * 
+ * PUBLIC: int __ham_copypage_recover
+ * PUBLIC:   __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
+ */
+int
+__ham_copypage_recover(logp, dbtp, lsnp, redo, info)
+	DB_LOG *logp;
+	DBT *dbtp;
+	DB_LSN *lsnp;
+	int redo;
+	void *info;
+{
+	__ham_copypage_args *argp;
+	DB *file_dbp, *mdbp;
+	DB_MPOOLFILE *mpf;
+	HTAB *hashp;
+	PAGE *pagep;
+	int cmp_n, cmp_p, getmeta, modified, ret;
+
+	getmeta = 0;
+	hashp = NULL;				/* XXX: shut the compiler up. */
+	REC_PRINT(__ham_copypage_print);
+	REC_INTRO(__ham_copypage_read);
+
+	hashp = (HTAB *)file_dbp->internal;
+	GET_META(file_dbp, hashp);
+	getmeta = 1;
+	modified = 0;
+
+	/* This is the bucket page. */
+	ret = memp_fget(mpf, &argp->pgno, 0, &pagep);
+	if (ret != 0)
+		if (!redo) {
+			/*
+			 * We are undoing and the page doesn't exist.  That
+			 * is equivalent to having a pagelsn of 0, so we
+			 * would not have to undo anything.  In this case,
+			 * don't bother creating a page.
+			 */
+			ret = 0;
+			goto donext;
+		} else if ((ret = memp_fget(mpf, &argp->pgno,
+		    DB_MPOOL_CREATE, &pagep)) != 0)
+			goto out;
+
+	cmp_n = log_compare(lsnp, &LSN(pagep));
+	cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
+
+	if (cmp_p == 0 && redo) {
+		/* Need to redo update described. */
+		memcpy(pagep, argp->page.data, argp->page.size);
+		LSN(pagep) = *lsnp;
+		modified = 1;
+	} else if (cmp_n == 0 && !redo) {
+		/* Need to undo update described. */
+		P_INIT(pagep, hashp->hdr->pagesize, argp->pgno, PGNO_INVALID,
+		    argp->next_pgno, 0, P_HASH);
+		LSN(pagep) = argp->pagelsn;
+		modified = 1;
+	}
+	if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
+		goto out;
+
+	/* Now fix up the "next" page. */
+donext:	ret = memp_fget(mpf, &argp->next_pgno, 0, &pagep);
+	if (ret != 0)
+		if (!redo) {
+			/*
+			 * We are undoing and the page doesn't exist.  That
+			 * is equivalent to having a pagelsn of 0, so we
+			 * would not have to undo anything.  In this case,
+			 * don't bother creating a page.
+			 */
+			ret = 0;
+			goto do_nn;
+		} else if ((ret = memp_fget(mpf, &argp->next_pgno,
+		    DB_MPOOL_CREATE, &pagep)) != 0)
+			goto out;
+
+	/* There is nothing to do in the REDO case; only UNDO. */
+
+	cmp_n = log_compare(lsnp, &LSN(pagep));
+	if (cmp_n == 0 && !redo) {
+		/* Need to undo update described. */
+		memcpy(pagep, argp->page.data, argp->page.size);
+		modified = 1;
+	}
+	if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
+		goto out;
+
+	/* Now fix up the next's next page. */
+do_nn:	if (argp->nnext_pgno == PGNO_INVALID) {
+		*lsnp = argp->prev_lsn;
+		goto out;
+	}
+
+	ret = memp_fget(mpf, &argp->nnext_pgno, 0, &pagep);
+	if (ret != 0)
+		if (!redo) {
+			/*
+			 * We are undoing and the page doesn't exist.  That
+			 * is equivalent to having a pagelsn of 0, so we
+			 * would not have to undo anything.  In this case,
+			 * don't bother creating a page.
+			 */
+			ret = 0;
+			*lsnp = argp->prev_lsn;
+			goto out;
+		} else if ((ret = memp_fget(mpf, &argp->nnext_pgno,
+		    DB_MPOOL_CREATE, &pagep)) != 0)
+			goto out;
+
+	cmp_n = log_compare(lsnp, &LSN(pagep));
+	cmp_p = log_compare(&LSN(pagep), &argp->nnextlsn);
+
+	if (cmp_p == 0 && redo) {
+		/* Need to redo update described. */
+		PREV_PGNO(pagep) = argp->pgno;
+		LSN(pagep) = *lsnp;
+		modified = 1;
+	} else if (cmp_n == 0 && !redo) {
+		/* Need to undo update described. */
+		PREV_PGNO(pagep) = argp->next_pgno;
+		LSN(pagep) = argp->nnextlsn;
+		modified = 1;
+	}
+	if ((ret = memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
+		goto out;
+
+	*lsnp = argp->prev_lsn;
+
+out:	if (getmeta)
+		RELEASE_META(file_dbp, hashp);
+	REC_CLOSE;
+}