xref: /csrg-svn/lib/libc/db/recno/rec_search.c (revision 66195)
150995Sbostic /*-
261207Sbostic  * Copyright (c) 1990, 1993
361207Sbostic  *	The Regents of the University of California.  All rights reserved.
450995Sbostic  *
550995Sbostic  * %sccs.include.redist.c%
650995Sbostic  */
750995Sbostic 
850995Sbostic #if defined(LIBC_SCCS) && !defined(lint)
9*66195Sbostic static char sccsid[] = "@(#)rec_search.c	8.3 (Berkeley) 02/21/94";
1050995Sbostic #endif /* LIBC_SCCS and not lint */
1150995Sbostic 
1250995Sbostic #include <sys/types.h>
1356759Sbostic 
1450995Sbostic #include <errno.h>
1550995Sbostic #include <stdio.h>
1656759Sbostic 
1757933Sbostic #include <db.h>
1851092Sbostic #include "recno.h"
1950995Sbostic 
2050995Sbostic /*
2150995Sbostic  * __REC_SEARCH -- Search a btree for a key.
2250995Sbostic  *
2350995Sbostic  * Parameters:
2450995Sbostic  *	t:	tree to search
2554284Sbostic  *	recno:	key to find
2651092Sbostic  *	op: 	search operation
2750995Sbostic  *
2850995Sbostic  * Returns:
2950995Sbostic  *	EPG for matching record, if any, or the EPG for the location of the
3050995Sbostic  *	key, if it were inserted into the tree.
3150995Sbostic  *
3264485Sbostic  * Returns:
3364485Sbostic  *	The EPG for matching record, if any, or the EPG for the location
3464485Sbostic  *	of the key, if it were inserted into the tree, is entered into
3564485Sbostic  *	the bt_cur field of the tree.  A pointer to the field is returned.
3650995Sbostic  */
3750995Sbostic EPG *
__rec_search(t,recno,op)3851092Sbostic __rec_search(t, recno, op)
3950995Sbostic 	BTREE *t;
4050995Sbostic 	recno_t recno;
4151092Sbostic 	enum SRCHOP op;
4250995Sbostic {
4357988Sbostic 	register indx_t index;
4450995Sbostic 	register PAGE *h;
4551092Sbostic 	EPGNO *parent;
4650995Sbostic 	RINTERNAL *r;
4750995Sbostic 	pgno_t pg;
4857988Sbostic 	indx_t top;
4950995Sbostic 	recno_t total;
50*66195Sbostic 	int sverrno;
5150995Sbostic 
5257447Sbostic 	BT_CLR(t);
5350995Sbostic 	for (pg = P_ROOT, total = 0;;) {
5450995Sbostic 		if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
5551092Sbostic 			goto err;
5650995Sbostic 		if (h->flags & P_RLEAF) {
5764485Sbostic 			t->bt_cur.page = h;
5864485Sbostic 			t->bt_cur.index = recno - total;
5964485Sbostic 			return (&t->bt_cur);
6050995Sbostic 		}
6150995Sbostic 		for (index = 0, top = NEXTINDEX(h);;) {
6250995Sbostic 			r = GETRINTERNAL(h, index);
6356042Sbostic 			if (++index == top || total + r->nrecs > recno)
6450995Sbostic 				break;
6550995Sbostic 			total += r->nrecs;
6650995Sbostic 		}
6750995Sbostic 
6854284Sbostic 		if (__bt_push(t, pg, index - 1) == RET_ERROR)
6950995Sbostic 			return (NULL);
7051092Sbostic 
7151092Sbostic 		pg = r->pgno;
7251092Sbostic 		switch (op) {
7351092Sbostic 		case SDELETE:
7456042Sbostic 			--GETRINTERNAL(h, (index - 1))->nrecs;
7551092Sbostic 			mpool_put(t->bt_mp, h, MPOOL_DIRTY);
7651092Sbostic 			break;
7751092Sbostic 		case SINSERT:
7856042Sbostic 			++GETRINTERNAL(h, (index - 1))->nrecs;
7951092Sbostic 			mpool_put(t->bt_mp, h, MPOOL_DIRTY);
8051092Sbostic 			break;
8151092Sbostic 		case SEARCH:
8251092Sbostic 			mpool_put(t->bt_mp, h, 0);
8351092Sbostic 			break;
8451092Sbostic 		}
8550995Sbostic 
8650995Sbostic 	}
8751092Sbostic 	/* Try and recover the tree. */
88*66195Sbostic err:	sverrno = errno;
8951092Sbostic 	if (op != SEARCH)
9051092Sbostic 		while  ((parent = BT_POP(t)) != NULL) {
9151092Sbostic 			if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
9251092Sbostic 				break;
9351092Sbostic 			if (op == SINSERT)
9451092Sbostic 				--GETRINTERNAL(h, parent->index)->nrecs;
9551092Sbostic 			else
9651092Sbostic 				++GETRINTERNAL(h, parent->index)->nrecs;
9751092Sbostic                         mpool_put(t->bt_mp, h, MPOOL_DIRTY);
9851092Sbostic                 }
99*66195Sbostic 	errno = sverrno;
10051092Sbostic 	return (NULL);
10150995Sbostic }
102