1#include "db_config.h"
2
3#include "db_int.h"
4#include "dbinc/db_page.h"
5#include "dbinc/__qam.h"
6#include "dbinc/log.h"
7
8/*
9 * __qam_incfirst_recover --
10 *	Recovery function for incfirst.
11 *
12 * PUBLIC: int __qam_incfirst_recover
13 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
14 */
15int
16__qam_incfirst_recover(env, dbtp, lsnp, op, info)
17	env *env;
18	DBT *dbtp;
19	DB_LSN *lsnp;
20	db_recops op;
21	void *info;
22{
23	__qam_incfirst_args *argp;
24	DB *file_dbp;
25	DBC *dbc;
26	DB_MPOOLFILE *mpf;
27	DB_THREAD_INFO *ip;
28	PAGE *pagep;
29	int cmp_n, cmp_p, modified, ret;
30
31	ip = ((DB_TXNHEAD *)info)->thread_info;
32
33	REC_PRINT(__qam_incfirst_print);
34	REC_INTRO(__qam_incfirst_read, ip, 0);
35
36	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
37		if (DB_REDO(op)) {
38			if ((ret = mpf->get(mpf,
39			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
40				goto out;
41		} else {
42			*lsnp = argp->prev_lsn;
43			ret = 0;
44			goto out;
45		}
46
47	modified = 0;
48	cmp_n = log_compare(lsnp, &LSN(pagep));
49
50	/*
51	 * Use this when there is something like "pagelsn" in the argp
52	 * structure.  Sometimes, you might need to compare meta-data
53	 * lsn's instead.
54	 *
55	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
56	 */
57	if (cmp_p == 0 && DB_REDO(op)) {
58		/* Need to redo update described. */
59		modified = 1;
60	} else if (cmp_n == 0 && !DB_REDO(op)) {
61		/* Need to undo update described. */
62		modified = 1;
63	}
64	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
65		goto out;
66
67	*lsnp = argp->prev_lsn;
68	ret = 0;
69
70out:	REC_CLOSE;
71}
72
73/*
74 * __qam_mvptr_recover --
75 *	Recovery function for mvptr.
76 *
77 * PUBLIC: int __qam_mvptr_recover
78 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
79 */
80int
81__qam_mvptr_recover(env, dbtp, lsnp, op, info)
82	env *env;
83	DBT *dbtp;
84	DB_LSN *lsnp;
85	db_recops op;
86	void *info;
87{
88	__qam_mvptr_args *argp;
89	DB *file_dbp;
90	DBC *dbc;
91	DB_MPOOLFILE *mpf;
92	DB_THREAD_INFO *ip;
93	PAGE *pagep;
94	int cmp_n, cmp_p, modified, ret;
95
96	ip = ((DB_TXNHEAD *)info)->thread_info;
97
98	REC_PRINT(__qam_mvptr_print);
99	REC_INTRO(__qam_mvptr_read, ip, 0);
100
101	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
102		if (DB_REDO(op)) {
103			if ((ret = mpf->get(mpf,
104			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
105				goto out;
106		} else {
107			*lsnp = argp->prev_lsn;
108			ret = 0;
109			goto out;
110		}
111
112	modified = 0;
113	cmp_n = log_compare(lsnp, &LSN(pagep));
114
115	/*
116	 * Use this when there is something like "pagelsn" in the argp
117	 * structure.  Sometimes, you might need to compare meta-data
118	 * lsn's instead.
119	 *
120	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
121	 */
122	if (cmp_p == 0 && DB_REDO(op)) {
123		/* Need to redo update described. */
124		modified = 1;
125	} else if (cmp_n == 0 && !DB_REDO(op)) {
126		/* Need to undo update described. */
127		modified = 1;
128	}
129	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
130		goto out;
131
132	*lsnp = argp->prev_lsn;
133	ret = 0;
134
135out:	REC_CLOSE;
136}
137
138/*
139 * __qam_del_recover --
140 *	Recovery function for del.
141 *
142 * PUBLIC: int __qam_del_recover
143 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
144 */
145int
146__qam_del_recover(env, dbtp, lsnp, op, info)
147	env *env;
148	DBT *dbtp;
149	DB_LSN *lsnp;
150	db_recops op;
151	void *info;
152{
153	__qam_del_args *argp;
154	DB *file_dbp;
155	DBC *dbc;
156	DB_MPOOLFILE *mpf;
157	DB_THREAD_INFO *ip;
158	PAGE *pagep;
159	int cmp_n, cmp_p, modified, ret;
160
161	ip = ((DB_TXNHEAD *)info)->thread_info;
162
163	REC_PRINT(__qam_del_print);
164	REC_INTRO(__qam_del_read, ip, 0);
165
166	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
167		if (DB_REDO(op)) {
168			if ((ret = mpf->get(mpf,
169			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
170				goto out;
171		} else {
172			*lsnp = argp->prev_lsn;
173			ret = 0;
174			goto out;
175		}
176
177	modified = 0;
178	cmp_n = log_compare(lsnp, &LSN(pagep));
179
180	/*
181	 * Use this when there is something like "pagelsn" in the argp
182	 * structure.  Sometimes, you might need to compare meta-data
183	 * lsn's instead.
184	 *
185	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
186	 */
187	if (cmp_p == 0 && DB_REDO(op)) {
188		/* Need to redo update described. */
189		modified = 1;
190	} else if (cmp_n == 0 && !DB_REDO(op)) {
191		/* Need to undo update described. */
192		modified = 1;
193	}
194	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
195		goto out;
196
197	*lsnp = argp->prev_lsn;
198	ret = 0;
199
200out:	REC_CLOSE;
201}
202
203/*
204 * __qam_add_recover --
205 *	Recovery function for add.
206 *
207 * PUBLIC: int __qam_add_recover
208 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
209 */
210int
211__qam_add_recover(env, dbtp, lsnp, op, info)
212	env *env;
213	DBT *dbtp;
214	DB_LSN *lsnp;
215	db_recops op;
216	void *info;
217{
218	__qam_add_args *argp;
219	DB *file_dbp;
220	DBC *dbc;
221	DB_MPOOLFILE *mpf;
222	DB_THREAD_INFO *ip;
223	PAGE *pagep;
224	int cmp_n, cmp_p, modified, ret;
225
226	ip = ((DB_TXNHEAD *)info)->thread_info;
227
228	REC_PRINT(__qam_add_print);
229	REC_INTRO(__qam_add_read, ip, 0);
230
231	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
232		if (DB_REDO(op)) {
233			if ((ret = mpf->get(mpf,
234			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
235				goto out;
236		} else {
237			*lsnp = argp->prev_lsn;
238			ret = 0;
239			goto out;
240		}
241
242	modified = 0;
243	cmp_n = log_compare(lsnp, &LSN(pagep));
244
245	/*
246	 * Use this when there is something like "pagelsn" in the argp
247	 * structure.  Sometimes, you might need to compare meta-data
248	 * lsn's instead.
249	 *
250	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
251	 */
252	if (cmp_p == 0 && DB_REDO(op)) {
253		/* Need to redo update described. */
254		modified = 1;
255	} else if (cmp_n == 0 && !DB_REDO(op)) {
256		/* Need to undo update described. */
257		modified = 1;
258	}
259	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
260		goto out;
261
262	*lsnp = argp->prev_lsn;
263	ret = 0;
264
265out:	REC_CLOSE;
266}
267
268/*
269 * __qam_delext_recover --
270 *	Recovery function for delext.
271 *
272 * PUBLIC: int __qam_delext_recover
273 * PUBLIC:   __P((env *, DBT *, DB_LSN *, db_recops, void *));
274 */
275int
276__qam_delext_recover(env, dbtp, lsnp, op, info)
277	env *env;
278	DBT *dbtp;
279	DB_LSN *lsnp;
280	db_recops op;
281	void *info;
282{
283	__qam_delext_args *argp;
284	DB *file_dbp;
285	DBC *dbc;
286	DB_MPOOLFILE *mpf;
287	DB_THREAD_INFO *ip;
288	PAGE *pagep;
289	int cmp_n, cmp_p, modified, ret;
290
291	ip = ((DB_TXNHEAD *)info)->thread_info;
292
293	REC_PRINT(__qam_delext_print);
294	REC_INTRO(__qam_delext_read, ip, 0);
295
296	if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0)
297		if (DB_REDO(op)) {
298			if ((ret = mpf->get(mpf,
299			    &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
300				goto out;
301		} else {
302			*lsnp = argp->prev_lsn;
303			ret = 0;
304			goto out;
305		}
306
307	modified = 0;
308	cmp_n = log_compare(lsnp, &LSN(pagep));
309
310	/*
311	 * Use this when there is something like "pagelsn" in the argp
312	 * structure.  Sometimes, you might need to compare meta-data
313	 * lsn's instead.
314	 *
315	 * cmp_p = log_compare(&LSN(pagep), argp->pagelsn);
316	 */
317	if (cmp_p == 0 && DB_REDO(op)) {
318		/* Need to redo update described. */
319		modified = 1;
320	} else if (cmp_n == 0 && !DB_REDO(op)) {
321		/* Need to undo update described. */
322		modified = 1;
323	}
324	if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0))
325		goto out;
326
327	*lsnp = argp->prev_lsn;
328	ret = 0;
329
330out:	REC_CLOSE;
331}
332
333