reset screen offset of top line if it exceeds the number of screens
[nvi.git] / common / vi_rec.c
blobcf89cd7e1beab811d2c65b916b1ac2bf61692bb9
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 * PUBLIC: #ifdef USE_DB4_LOGGING
23 * __vi_marker_recover --
24 * Recovery function for marker.
26 * PUBLIC: int __vi_marker_recover
27 * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
29 int
30 __vi_marker_recover(dbenv, dbtp, lsnp, op, info)
31 DB_ENV *dbenv;
32 DBT *dbtp;
33 DB_LSN *lsnp;
34 db_recops op;
35 void *info;
37 __vi_marker_args *argp;
38 int ret;
40 REC_PRINT(__vi_marker_print);
41 REC_NOOP_INTRO(__vi_marker_read);
43 *lsnp = argp->prev_lsn;
44 ret = 0;
46 REC_NOOP_CLOSE;
50 * __vi_cursor_recover --
51 * Recovery function for cursor.
53 * PUBLIC: int __vi_cursor_recover
54 * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
56 int
57 __vi_cursor_recover(dbenv, dbtp, lsnp, op, info)
58 DB_ENV *dbenv;
59 DBT *dbtp;
60 DB_LSN *lsnp;
61 db_recops op;
62 void *info;
64 __vi_cursor_args *argp;
65 int ret;
66 SCR *sp;
68 REC_PRINT(__vi_cursor_print);
69 REC_NOOP_INTRO(__vi_cursor_read);
71 sp = (SCR *)dbenv->app_private;
73 *lsnp = argp->prev_lsn;
74 if (sp->state.undo == UNDO_SETLINE) {
75 /* Why the check for ep->l_cur ? (copied from log.c)
77 ret = (argp->lno != sp->lno ||
78 (argp->opcode == LOG_CURSOR_INIT && sp->ep->l_cur == 1))
79 ? LOG_CURSOR_HIT : 0;
81 else {
82 ret = argp->opcode ==
83 (DB_UNDO(op) ? LOG_CURSOR_INIT : LOG_CURSOR_END)
84 ? LOG_CURSOR_HIT : 0;
85 if (ret) {
86 sp->state.pos.lno = argp->lno;
87 sp->state.pos.cno = argp->cno;
91 REC_NOOP_CLOSE;
95 * __vi_mark_recover --
96 * Recovery function for mark.
98 * PUBLIC: int __vi_mark_recover
99 * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
102 __vi_mark_recover(dbenv, dbtp, lsnp, op, info)
103 DB_ENV *dbenv;
104 DBT *dbtp;
105 DB_LSN *lsnp;
106 db_recops op;
107 void *info;
109 __vi_mark_args *argp;
110 int ret;
111 MARK m;
112 SCR *sp;
114 REC_PRINT(__vi_mark_print);
115 REC_NOOP_INTRO(__vi_mark_read);
117 sp = (SCR *)dbenv->app_private;
118 *lsnp = argp->prev_lsn;
119 m.lno = argp->lmp.lno;
120 m.cno = argp->lmp.cno;
121 ret = mark_set(sp, argp->lmp.name, &m, 0);
123 REC_NOOP_CLOSE;
127 * __vi_change_recover --
128 * Recovery function for change.
130 * PUBLIC: int __vi_change_recover
131 * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
134 __vi_change_recover(dbenv, dbtp, lsnp, op, info)
135 DB_ENV *dbenv;
136 DBT *dbtp;
137 DB_LSN *lsnp;
138 db_recops op;
139 void *info;
141 __vi_change_args *argp;
142 int ret;
143 SCR *sp;
145 REC_PRINT(__vi_change_print);
146 REC_NOOP_INTRO(__vi_change_read);
148 ret = 0;
150 sp = (SCR *)dbenv->app_private;
151 if (DB_UNDO(op) != (argp->opcode & 1))
152 switch (argp->opcode) {
153 case LOG_LINE_RESET_B:
154 case LOG_LINE_RESET_F:
155 ret = line_insdel(sp, LINE_RESET, argp->lno);
156 update_cache(sp, LINE_RESET, argp->lno);
157 ret = scr_update(sp, argp->lno, LINE_RESET, 1) || ret;
158 break;
159 case LOG_LINE_APPEND_B:
160 case LOG_LINE_DELETE_F:
161 ret = line_insdel(sp, LINE_DELETE, argp->lno);
162 update_cache(sp, LINE_DELETE, argp->lno);
163 ret = scr_update(sp, argp->lno, LINE_DELETE, 1) || ret;
164 break;
165 case LOG_LINE_DELETE_B:
166 case LOG_LINE_APPEND_F:
167 ret = line_insdel(sp, LINE_INSERT, argp->lno);
168 update_cache(sp, LINE_INSERT, argp->lno);
169 ret = scr_update(sp, argp->lno, LINE_INSERT, 1) || ret;
170 break;
173 *lsnp = argp->prev_lsn;
175 REC_NOOP_CLOSE;
180 * PUBLIC: int __vi_log_truncate __P((EXF *ep));
183 __vi_log_truncate(EXF *ep)
185 DB_LSN ckplsn;
187 ZERO_LSN(ckplsn);
188 return __log_vtruncate(ep->env, &ep->lsn_cur, &ckplsn);
189 /*return __log_vtruncate(ep->env, &ep->lsn_cur, &ep->lsn_first);*/
194 * PUBLIC: int __vi_log_dispatch __P((DB_ENV *dbenv, DBT *data, DB_LSN *lsn, db_recops ops));
197 __vi_log_dispatch(DB_ENV *dbenv, DBT *data, DB_LSN *lsn, db_recops ops)
199 u_int32_t rectype;
200 char s[100];
202 memcpy(&rectype, data->data, sizeof(rectype));
203 snprintf(s,100,"%d\n", rectype);
204 return dbenv->dtab[rectype](dbenv, data, lsn, ops, NULL);
207 static int
208 vi_log_get(SCR *sp, DB_LOGC *logc, DBT *data, u_int32_t which)
210 size_t nlen;
211 EXF *ep;
213 ep = sp->ep;
215 nlen = 1024;
216 retry:
217 BINC_GOTO(sp, sp->wp->l_lp, sp->wp->l_len, nlen);
218 memset(data, 0, sizeof(*data));
219 data->data = sp->wp->l_lp;
220 data->ulen = sp->wp->l_len;
221 data->flags = DB_DBT_USERMEM;
222 switch ((sp->db_error = logc->get(logc, &ep->lsn_cur, data, which))) {
223 case ENOMEM:
224 nlen = data->size;
225 goto retry;
226 default:
227 alloc_err:
228 msgq(sp, M_DBERR, "logc->get");
229 F_SET(ep, F_NOLOG);
230 return (1);
231 case 0:
234 return 0;
239 * PUBLIC: int __vi_log_traverse __P((SCR *sp, undo_t undo, MARK *));
242 __vi_log_traverse(SCR *sp, undo_t undo, MARK *rp)
244 DB_LOGC *logc;
245 DBT data;
246 EXF *ep;
247 int ret;
248 DB_LSN lsn;
249 u_int32_t which;
250 db_recops ops;
252 ep = sp->ep;
254 F_SET(ep, F_NOLOG); /* Turn off logging. */
256 sp->state.undo = undo;
257 ep->env->app_private = sp;
258 if ((sp->db_error = ep->env->log_cursor(ep->env, &logc, 0))
259 != 0) {
260 msgq(sp, M_DBERR, "env->log_cursor");
261 return (1);
263 if (vi_log_get(sp, logc, &data, DB_SET))
264 return 1;
265 if (undo == UNDO_FORWARD) {
266 ops = DB_TXN_FORWARD_ROLL;
267 which = DB_NEXT;
268 if (vi_log_get(sp, logc, &data, DB_NEXT))
269 return 1;
270 } else {
271 ops = DB_TXN_BACKWARD_ROLL;
272 which = DB_PREV;
275 for (;;) {
276 MEMCPY(&lsn, &ep->lsn_cur, 1);
277 ret = __vi_log_dispatch(ep->env, &data, &lsn, ops);
278 if (ret != 0) {
279 if (ret == LOG_CURSOR_HIT)
280 break;
283 if (vi_log_get(sp, logc, &data, which))
284 return 1;
285 if (undo == UNDO_SETLINE &&
286 log_compare(&ep->lsn_cur, &ep->lsn_first) <= 0) {
287 /* Move to previous record without dispatching. */
288 undo = UNDO_BACKWARD;
289 break;
292 if (undo == UNDO_BACKWARD)
293 if (vi_log_get(sp, logc, &data, DB_PREV))
294 return 1;
296 logc->close(logc, 0);
298 ep->env->app_private = NULL;
300 MEMMOVE(rp, &sp->state.pos, 1);
302 F_CLR(ep, F_NOLOG);
304 return 0;
308 vi_db_init_recover(DB_ENV *dbenv)
310 int ret;
312 if ((ret = __db_init_recover(dbenv)) != 0)
313 return (ret);
314 if ((ret = __bam_init_recover(dbenv)) != 0)
315 return (ret);
317 return 0;
320 * PUBLIC: #endif