Add preliminary db1.c from Aymeric Vincent <xmimic@free.fr>
[nvi.git] / common / vi_rec.c
blob740cc309b8b63a73c763a575e24f3e143b3d9fc8
1 #include "db_config.h"
3 #ifndef NO_SYSTEM_INCLUDES
4 #include <sys/types.h>
6 #include <string.h>
7 #endif
9 #include "common.h"
11 #include "db_int.h"
12 #include "db_page.h"
13 #include <log.h>
14 #include "hash.h"
15 #include "btree.h"
17 #define LOG_CURSOR_HIT -1000
20 * __vi_marker_recover --
21 * Recovery function for marker.
23 * PUBLIC: int __vi_marker_recover
24 * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
26 int
27 __vi_marker_recover(dbenv, dbtp, lsnp, op, info)
28 DB_ENV *dbenv;
29 DBT *dbtp;
30 DB_LSN *lsnp;
31 db_recops op;
32 void *info;
34 __vi_marker_args *argp;
35 int ret;
37 REC_PRINT(__vi_marker_print);
38 REC_NOOP_INTRO(__vi_marker_read);
40 *lsnp = argp->prev_lsn;
41 ret = 0;
43 REC_NOOP_CLOSE;
47 * __vi_cursor_recover --
48 * Recovery function for cursor.
50 * PUBLIC: int __vi_cursor_recover
51 * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
53 int
54 __vi_cursor_recover(dbenv, dbtp, lsnp, op, info)
55 DB_ENV *dbenv;
56 DBT *dbtp;
57 DB_LSN *lsnp;
58 db_recops op;
59 void *info;
61 __vi_cursor_args *argp;
62 int ret;
63 SCR *sp;
65 REC_PRINT(__vi_cursor_print);
66 REC_NOOP_INTRO(__vi_cursor_read);
68 sp = (SCR *)dbenv->app_private;
70 *lsnp = argp->prev_lsn;
71 ret = argp->opcode == (DB_UNDO(op) ? LOG_CURSOR_INIT : LOG_CURSOR_END)
72 ? LOG_CURSOR_HIT : 0;
73 if (ret) {
74 sp->state.pos.lno = argp->lno;
75 sp->state.pos.cno = argp->cno;
78 REC_NOOP_CLOSE;
82 * __vi_mark_recover --
83 * Recovery function for mark.
85 * PUBLIC: int __vi_mark_recover
86 * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
88 int
89 __vi_mark_recover(dbenv, dbtp, lsnp, op, info)
90 DB_ENV *dbenv;
91 DBT *dbtp;
92 DB_LSN *lsnp;
93 db_recops op;
94 void *info;
96 __vi_mark_args *argp;
97 int ret;
98 MARK m;
99 SCR *sp;
101 REC_PRINT(__vi_mark_print);
102 REC_NOOP_INTRO(__vi_mark_read);
104 sp = (SCR *)dbenv->app_private;
105 *lsnp = argp->prev_lsn;
106 m.lno = argp->lmp.lno;
107 m.cno = argp->lmp.cno;
108 ret = mark_set(sp, argp->lmp.name, &m, 0);
110 REC_NOOP_CLOSE;
114 * __vi_change_recover --
115 * Recovery function for change.
117 * PUBLIC: int __vi_change_recover
118 * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
121 __vi_change_recover(dbenv, dbtp, lsnp, op, info)
122 DB_ENV *dbenv;
123 DBT *dbtp;
124 DB_LSN *lsnp;
125 db_recops op;
126 void *info;
128 __vi_change_args *argp;
129 int ret;
130 SCR *sp;
132 REC_PRINT(__vi_change_print);
133 REC_NOOP_INTRO(__vi_change_read);
135 ret = 0;
137 sp = (SCR *)dbenv->app_private;
138 if (DB_UNDO(op) != (argp->opcode & 1))
139 switch (argp->opcode) {
140 case LOG_LINE_RESET_B:
141 case LOG_LINE_RESET_F:
142 ret = line_insdel(sp, LINE_RESET, argp->lno);
143 ret = scr_update(sp, argp->lno, LINE_RESET, 1) || ret;
144 break;
145 case LOG_LINE_APPEND_B:
146 case LOG_LINE_DELETE_F:
147 ret = line_insdel(sp, LINE_DELETE, argp->lno);
148 ret = scr_update(sp, argp->lno, LINE_DELETE, 1) || ret;
149 break;
150 case LOG_LINE_DELETE_B:
151 case LOG_LINE_APPEND_F:
152 ret = line_insdel(sp, LINE_INSERT, argp->lno);
153 ret = scr_update(sp, argp->lno, LINE_INSERT, 1) || ret;
154 break;
157 *lsnp = argp->prev_lsn;
159 REC_NOOP_CLOSE;
164 * PUBLIC: int __vi_log_truncate __P((EXF *ep));
167 __vi_log_truncate(EXF *ep)
169 DB_LSN ckplsn;
171 ZERO_LSN(ckplsn);
172 return __log_vtruncate(ep->env, &ep->lsn_cur, &ckplsn);
173 /*return __log_vtruncate(ep->env, &ep->lsn_cur, &ep->lsn_first);*/
178 * PUBLIC: int __vi_log_dispatch __P((DB_ENV *dbenv, DBT *data, DB_LSN *lsn, db_recops ops));
181 __vi_log_dispatch(DB_ENV *dbenv, DBT *data, DB_LSN *lsn, db_recops ops)
183 u_int32_t rectype;
184 char s[100];
186 memcpy(&rectype, data->data, sizeof(rectype));
187 snprintf(s,100,"%d\n", rectype);
188 return dbenv->dtab[rectype](dbenv, data, lsn, ops, NULL);
191 static int
192 vi_log_get(SCR *sp, DB_LOGC *logc, DBT *data, u_int32_t which)
194 size_t nlen;
195 EXF *ep;
197 ep = sp->ep;
199 nlen = 1024;
200 retry:
201 BINC_GOTO(sp, sp->wp->l_lp, sp->wp->l_len, nlen);
202 memset(data, 0, sizeof(*data));
203 data->data = sp->wp->l_lp;
204 data->ulen = sp->wp->l_len;
205 data->flags = DB_DBT_USERMEM;
206 switch ((sp->db_error = logc->get(logc, &ep->lsn_cur, data, which))) {
207 case ENOMEM:
208 nlen = data->size;
209 goto retry;
210 default:
211 alloc_err:
212 msgq(sp, M_DBERR, "logc->get");
213 F_SET(ep, F_NOLOG);
214 return (1);
215 case 0:
218 return 0;
223 * PUBLIC: int __vi_log_traverse __P((SCR *sp, db_recops ops, MARK *));
226 __vi_log_traverse(SCR *sp, db_recops ops, MARK *rp)
228 DB_LOGC *logc;
229 DBT data;
230 EXF *ep;
231 int ret;
232 DB_LSN lsn;
233 u_int32_t which;
235 ep = sp->ep;
237 F_SET(ep, F_NOLOG); /* Turn off logging. */
239 ep->env->app_private = sp;
240 if ((sp->db_error = ep->env->log_cursor(ep->env, &logc, 0))
241 != 0) {
242 msgq(sp, M_DBERR, "env->log_cursor");
243 return (1);
245 if (vi_log_get(sp, logc, &data, DB_SET))
246 return 1;
247 if (ops == DB_TXN_BACKWARD_ROLL) {
248 which = DB_PREV;
249 } else {
250 which = DB_NEXT;
251 if (vi_log_get(sp, logc, &data, DB_NEXT))
252 return 1;
255 for (;;) {
256 MEMCPY(&lsn, &ep->lsn_cur, 1);
257 ret = __vi_log_dispatch(ep->env, &data, &lsn, ops);
258 if (ret != 0) {
259 if (ret == LOG_CURSOR_HIT)
260 break;
263 if (vi_log_get(sp, logc, &data, which))
264 return 1;
266 if (ops == DB_TXN_BACKWARD_ROLL)
267 if (vi_log_get(sp, logc, &data, DB_PREV))
268 return 1;
270 logc->close(logc, 0);
272 ep->env->app_private = NULL;
274 MEMMOVE(rp, &sp->state.pos, 1);
276 F_CLR(ep, F_NOLOG);
278 return 0;
282 vi_db_init_recover(DB_ENV *dbenv)
284 int ret;
286 if ((ret = __db_init_recover(dbenv)) != 0)
287 return (ret);
288 if ((ret = __bam_init_recover(dbenv)) != 0)
289 return (ret);
291 return 0;