rec_seq.c revision 92986
1139749Simp/*- 2119853Scg * Copyright (c) 1991, 1993, 1994 370291Scg * The Regents of the University of California. All rights reserved. 470291Scg * 570291Scg * Redistribution and use in source and binary forms, with or without 670291Scg * modification, are permitted provided that the following conditions 770291Scg * are met: 870291Scg * 1. Redistributions of source code must retain the above copyright 970291Scg * notice, this list of conditions and the following disclaimer. 1070291Scg * 2. Redistributions in binary form must reproduce the above copyright 1170291Scg * notice, this list of conditions and the following disclaimer in the 1270291Scg * documentation and/or other materials provided with the distribution. 1370291Scg * 3. All advertising materials mentioning features or use of this software 1470291Scg * must display the following acknowledgement: 1570291Scg * This product includes software developed by the University of 1670291Scg * California, Berkeley and its contributors. 1770291Scg * 4. Neither the name of the University nor the names of its contributors 1870291Scg * may be used to endorse or promote products derived from this software 1970291Scg * without specific prior written permission. 2070291Scg * 2170291Scg * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2270291Scg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2370291Scg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2470291Scg * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2570291Scg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2670291Scg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2770291Scg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2870291Scg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2974763Scg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3074763Scg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3182180Scg * SUCH DAMAGE. 3282180Scg */ 3374763Scg 34125136Struckman#ifndef lint 3574763Scgstatic char sccsid[] = "@(#)rec_seq.c 8.3 (Berkeley) 7/14/94"; 3674763Scg#endif /* not lint */ 3774763Scg#include <sys/cdefs.h> 38111119Simp__FBSDID("$FreeBSD: head/lib/libc/db/recno/rec_seq.c 92986 2002-03-22 21:53:29Z obrien $"); 3974763Scg 4089834Scg#include <sys/types.h> 41125136Struckman 4289834Scg#include <errno.h> 4374763Scg#include <limits.h> 4474763Scg#include <stdio.h> 4574763Scg#include <string.h> 4674763Scg 4774763Scg#include <db.h> 4874763Scg#include "recno.h" 49167773Sariff 5074763Scg/* 5174763Scg * __REC_SEQ -- Recno sequential scan interface. 5274763Scg * 53111183Scognet * Parameters: 54111183Scognet * dbp: pointer to access method 55111183Scognet * key: key for positioning and return value 56111183Scognet * data: data return value 57111183Scognet * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV. 58111183Scognet * 5970291Scg * Returns: 6070291Scg * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key. 6170291Scg */ 6274763Scgint 6370291Scg__rec_seq(dbp, key, data, flags) 6470291Scg const DB *dbp; 65136531Syongari DBT *key, *data; 66136531Syongari u_int flags; 67136531Syongari{ 6870291Scg BTREE *t; 69136531Syongari EPG *e; 70136531Syongari recno_t nrec; 71136531Syongari int status; 72136531Syongari 7370291Scg t = dbp->internal; 7470291Scg 7570291Scg /* Toss any page pinned across calls. */ 7674763Scg if (t->bt_pinned != NULL) { 7774763Scg mpool_put(t->bt_mp, t->bt_pinned, 0); 7870291Scg t->bt_pinned = NULL; 79111183Scognet } 8070291Scg 81168847Sariff switch(flags) { 82168847Sariff case R_CURSOR: 8370291Scg if ((nrec = *(recno_t *)key->data) == 0) 84136531Syongari goto einval; 85136531Syongari break; 8670291Scg case R_NEXT: 87168847Sariff if (F_ISSET(&t->bt_cursor, CURS_INIT)) { 8870291Scg nrec = t->bt_cursor.rcursor + 1; 8970291Scg break; 90136531Syongari } 91166393Sariff /* FALLTHROUGH */ 92168847Sariff case R_FIRST: 93167773Sariff nrec = 1; 94167773Sariff break; 95136531Syongari case R_PREV: 96167773Sariff if (F_ISSET(&t->bt_cursor, CURS_INIT)) { 97136531Syongari if ((nrec = t->bt_cursor.rcursor - 1) == 0) 98136531Syongari return (RET_SPECIAL); 99167773Sariff break; 100136531Syongari } 101136531Syongari /* FALLTHROUGH */ 102136531Syongari case R_LAST: 103136531Syongari if (!F_ISSET(t, R_EOF | R_INMEM) && 104136531Syongari t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) 105136531Syongari return (RET_ERROR); 106167773Sariff nrec = t->bt_nrecs; 107136531Syongari break; 10870291Scg default: 10970291Scgeinval: errno = EINVAL; 11070291Scg return (RET_ERROR); 11174763Scg } 11270291Scg 113167773Sariff if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) { 114166393Sariff if (!F_ISSET(t, R_EOF | R_INMEM) && 115166393Sariff (status = t->bt_irec(t, nrec)) != RET_SUCCESS) 11670291Scg return (status); 11770291Scg if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) 11870291Scg return (RET_SPECIAL); 11970291Scg } 12070291Scg 12170291Scg if ((e = __rec_search(t, nrec - 1, SEARCH)) == NULL) 12270291Scg return (RET_ERROR); 12374763Scg 12470291Scg F_SET(&t->bt_cursor, CURS_INIT); 12574763Scg t->bt_cursor.rcursor = nrec; 12674763Scg 12774763Scg status = __rec_ret(t, e, nrec, key, data); 128162588Snetchild if (F_ISSET(t, B_DB_LOCK)) 129162588Snetchild mpool_put(t->bt_mp, e->page, 0); 130167773Sariff else 131167773Sariff t->bt_pinned = e->page; 132167773Sariff return (status); 133167773Sariff} 134167773Sariff