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*64485Sbostic static char sccsid[] = "@(#)rec_search.c 8.2 (Berkeley) 09/14/93"; 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 * 32*64485Sbostic * Returns: 33*64485Sbostic * The EPG for matching record, if any, or the EPG for the location 34*64485Sbostic * of the key, if it were inserted into the tree, is entered into 35*64485Sbostic * the bt_cur field of the tree. A pointer to the field is returned. 3650995Sbostic */ 3750995Sbostic EPG * 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; 5051092Sbostic int serrno; 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) { 57*64485Sbostic t->bt_cur.page = h; 58*64485Sbostic t->bt_cur.index = recno - total; 59*64485Sbostic 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. */ 8851092Sbostic err: serrno = 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 } 9951092Sbostic errno = serrno; 10051092Sbostic return (NULL); 10150995Sbostic } 102