xref: /csrg-svn/lib/libc/db/recno/rec_search.c (revision 56042)
150995Sbostic /*-
250995Sbostic  * Copyright (c) 1990 The Regents of the University of California.
350995Sbostic  * All rights reserved.
450995Sbostic  *
550995Sbostic  * %sccs.include.redist.c%
650995Sbostic  */
750995Sbostic 
850995Sbostic #if defined(LIBC_SCCS) && !defined(lint)
9*56042Sbostic static char sccsid[] = "@(#)rec_search.c	5.4 (Berkeley) 08/26/92";
1050995Sbostic #endif /* LIBC_SCCS and not lint */
1150995Sbostic 
1250995Sbostic #include <sys/types.h>
1350995Sbostic #include <errno.h>
1450995Sbostic #include <db.h>
1550995Sbostic #include <stdio.h>
1651092Sbostic #include "recno.h"
1750995Sbostic 
1850995Sbostic /*
1950995Sbostic  * __REC_SEARCH -- Search a btree for a key.
2050995Sbostic  *
2150995Sbostic  * Parameters:
2250995Sbostic  *	t:	tree to search
2354284Sbostic  *	recno:	key to find
2451092Sbostic  *	op: 	search operation
2550995Sbostic  *
2650995Sbostic  * Returns:
2750995Sbostic  *	EPG for matching record, if any, or the EPG for the location of the
2850995Sbostic  *	key, if it were inserted into the tree.
2950995Sbostic  *
3050995Sbostic  * Warnings:
3150995Sbostic  *	The EPG returned is in static memory, and will be overwritten by the
3250995Sbostic  *	next search of any kind in any tree.
3350995Sbostic  */
3450995Sbostic EPG *
3551092Sbostic __rec_search(t, recno, op)
3650995Sbostic 	BTREE *t;
3750995Sbostic 	recno_t recno;
3851092Sbostic 	enum SRCHOP op;
3950995Sbostic {
4050995Sbostic 	static EPG e;
4150995Sbostic 	register index_t index;
4250995Sbostic 	register PAGE *h;
4351092Sbostic 	EPGNO *parent;
4450995Sbostic 	RINTERNAL *r;
4550995Sbostic 	pgno_t pg;
4650995Sbostic 	index_t top;
4750995Sbostic 	recno_t total;
4851092Sbostic 	int serrno;
4950995Sbostic 
5050995Sbostic 	for (pg = P_ROOT, total = 0;;) {
5150995Sbostic 		if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
5251092Sbostic 			goto err;
5350995Sbostic 		if (h->flags & P_RLEAF) {
5450995Sbostic 			e.page = h;
5550995Sbostic 			e.index = recno - total;
5650995Sbostic 			return (&e);
5750995Sbostic 		}
5850995Sbostic 		for (index = 0, top = NEXTINDEX(h);;) {
5950995Sbostic 			r = GETRINTERNAL(h, index);
60*56042Sbostic 			if (++index == top || total + r->nrecs > recno)
6150995Sbostic 				break;
6250995Sbostic 			total += r->nrecs;
6350995Sbostic 		}
6450995Sbostic 
6554284Sbostic 		if (__bt_push(t, pg, index - 1) == RET_ERROR)
6650995Sbostic 			return (NULL);
6751092Sbostic 
6851092Sbostic 		pg = r->pgno;
6951092Sbostic 		switch (op) {
7051092Sbostic 		case SDELETE:
71*56042Sbostic 			--GETRINTERNAL(h, (index - 1))->nrecs;
7251092Sbostic 			mpool_put(t->bt_mp, h, MPOOL_DIRTY);
7351092Sbostic 			break;
7451092Sbostic 		case SINSERT:
75*56042Sbostic 			++GETRINTERNAL(h, (index - 1))->nrecs;
7651092Sbostic 			mpool_put(t->bt_mp, h, MPOOL_DIRTY);
7751092Sbostic 			break;
7851092Sbostic 		case SEARCH:
7951092Sbostic 			mpool_put(t->bt_mp, h, 0);
8051092Sbostic 			break;
8151092Sbostic 		}
8250995Sbostic 
8350995Sbostic 	}
8451092Sbostic 	/* Try and recover the tree. */
8551092Sbostic err:	serrno = errno;
8651092Sbostic 	if (op != SEARCH)
8751092Sbostic 		while  ((parent = BT_POP(t)) != NULL) {
8851092Sbostic 			if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
8951092Sbostic 				break;
9051092Sbostic 			if (op == SINSERT)
9151092Sbostic 				--GETRINTERNAL(h, parent->index)->nrecs;
9251092Sbostic 			else
9351092Sbostic 				++GETRINTERNAL(h, parent->index)->nrecs;
9451092Sbostic                         mpool_put(t->bt_mp, h, MPOOL_DIRTY);
9551092Sbostic                 }
9651092Sbostic 	errno = serrno;
9751092Sbostic 	return (NULL);
9850995Sbostic }
99