1/*
2 * PREF_FUNC_recover --
3 *	Recovery function for FUNC.
4 *
5 * PUBLIC: int PREF_FUNC_recover
6 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
7 */
8int
9PREF_FUNC_recover(env, dbtp, lsnp, op, info)
10	env *env;
11	DBT *dbtp;
12	DB_LSN *lsnp;
13	db_recops op;
14	void *info;
15{
16	PREF_DUP_args *argp;
17	DB *file_dbp;
18	DBC *dbc;
19	DB_MPOOLFILE *mpf;
20	DB_THREAD_INFO *ip;
21	PAGE *pagep;
22	int cmp_n, cmp_p, modified, ret;
23
24	ip = ((DB_TXNHEAD *)info)->thread_info;
25
26	REC_PRINT(PREF_DUP_print);
27	REC_INTRO(PREF_DUP_read, ip, 0);
28
29	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
30		if (DB_REDO(op)) {
31			if ((ret = mpf->get(mpf,
32			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
33				goto out;
34		} else {
35			*lsnp = argp->prev_lsn;
36			ret = 0;
37			goto out;
38		}
39
40	modified = 0;
41	cmp_n = log_compare(lsnp, &LSN(pagep));
42
43	/*
44	 * Use this when there is something like "pagelsn" in the argp
45	 * structure.  Sometimes, you might need to compare meta-data
46	 * lsn's instead.
47	 *
48	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
49	 */
50	if (cmp_p == 0 && DB_REDO(op)) {
51		/* Need to redo update described. */
52		modified = 1;
53	} else if (cmp_n == 0 && !DB_REDO(op)) {
54		/* Need to undo update described. */
55		modified = 1;
56	}
57	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
58		goto out;
59
60	*lsnp = argp->prev_lsn;
61	ret = 0;
62
63out:	REC_CLOSE;
64}
65
66