150995Sbostic /*-
261207Sbostic * Copyright (c) 1991, 1993
361207Sbostic * The Regents of the University of California. All rights reserved.
450995Sbostic *
550995Sbostic * %sccs.include.redist.c%
650995Sbostic */
750995Sbostic
850995Sbostic #ifndef lint
9*64463Sbostic static char sccsid[] = "@(#)rec_seq.c 8.2 (Berkeley) 09/07/93";
1050995Sbostic #endif /* not lint */
1150995Sbostic
1250995Sbostic #include <sys/types.h>
1355316Sbostic
1450995Sbostic #include <errno.h>
1550995Sbostic #include <limits.h>
1650995Sbostic #include <stdio.h>
1757935Sbostic #include <string.h>
1856760Sbostic
1957933Sbostic #include <db.h>
2051091Sbostic #include "recno.h"
2150995Sbostic
2250995Sbostic /*
2350995Sbostic * __REC_SEQ -- Recno sequential scan interface.
2450995Sbostic *
2550995Sbostic * Parameters:
2650995Sbostic * dbp: pointer to access method
2750995Sbostic * key: key for positioning and return value
2850995Sbostic * data: data return value
2950995Sbostic * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
3050995Sbostic *
3150995Sbostic * Returns:
3250995Sbostic * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
3350995Sbostic */
3450995Sbostic int
__rec_seq(dbp,key,data,flags)3550995Sbostic __rec_seq(dbp, key, data, flags)
3650995Sbostic const DB *dbp;
3750995Sbostic DBT *key, *data;
3850995Sbostic u_int flags;
3950995Sbostic {
4050995Sbostic BTREE *t;
4150995Sbostic EPG *e;
4250995Sbostic recno_t nrec;
4351091Sbostic int status;
4450995Sbostic
4550995Sbostic t = dbp->internal;
46*64463Sbostic
47*64463Sbostic /* Toss any page pinned across calls. */
48*64463Sbostic if (t->bt_pinned != NULL) {
49*64463Sbostic mpool_put(t->bt_mp, t->bt_pinned, 0);
50*64463Sbostic t->bt_pinned = NULL;
51*64463Sbostic }
52*64463Sbostic
5350995Sbostic switch(flags) {
5450995Sbostic case R_CURSOR:
5556760Sbostic if ((nrec = *(recno_t *)key->data) == 0)
5656760Sbostic goto einval;
5750995Sbostic break;
5850995Sbostic case R_NEXT:
5960054Sbostic if (ISSET(t, B_SEQINIT)) {
6050995Sbostic nrec = t->bt_rcursor + 1;
6150995Sbostic break;
6250995Sbostic }
6350995Sbostic /* FALLTHROUGH */
6450995Sbostic case R_FIRST:
6550995Sbostic nrec = 1;
6650995Sbostic break;
6750995Sbostic case R_PREV:
6860054Sbostic if (ISSET(t, B_SEQINIT)) {
6956760Sbostic if ((nrec = t->bt_rcursor - 1) == 0)
7056760Sbostic return (RET_SPECIAL);
7150995Sbostic break;
7250995Sbostic }
7350995Sbostic /* FALLTHROUGH */
7450995Sbostic case R_LAST:
7560054Sbostic if (!ISSET(t, R_EOF | R_INMEM) &&
7656760Sbostic t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
7750995Sbostic return (RET_ERROR);
7850995Sbostic nrec = t->bt_nrecs;
7950995Sbostic break;
8050995Sbostic default:
8156760Sbostic einval: errno = EINVAL;
8250995Sbostic return (RET_ERROR);
8350995Sbostic }
8450995Sbostic
8554283Sbostic if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) {
8660054Sbostic if (!ISSET(t, R_EOF | R_INMEM) &&
8756760Sbostic (status = t->bt_irec(t, nrec)) != RET_SUCCESS)
8851091Sbostic return (status);
8954283Sbostic if (t->bt_nrecs == 0 || nrec > t->bt_nrecs)
9051091Sbostic return (RET_SPECIAL);
9151091Sbostic }
9250995Sbostic
9351091Sbostic if ((e = __rec_search(t, nrec - 1, SEARCH)) == NULL)
9450995Sbostic return (RET_ERROR);
9550995Sbostic
9660054Sbostic SET(t, B_SEQINIT);
9756760Sbostic t->bt_rcursor = nrec;
9856760Sbostic
9956760Sbostic status = __rec_ret(t, e, nrec, key, data);
100*64463Sbostic if (ISSET(t, B_DB_LOCK))
101*64463Sbostic mpool_put(t->bt_mp, e->page, 0);
102*64463Sbostic else
103*64463Sbostic t->bt_pinned = e->page;
10450995Sbostic return (status);
10550995Sbostic }
106