/*-1* SPDX-License-Identifier: BSD-3-Clause2*3* Copyright (c) 1990, 19934* The Regents of the University of California. All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14* 3. Neither the name of the University nor the names of its contributors15* may be used to endorse or promote products derived from this software16* without specific prior written permission.17*18* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND19* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE20* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE21* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE22* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL23* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS24* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)25* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT26* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY27* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF28* SUCH DAMAGE.29*/3031#include <sys/types.h>3233#include <errno.h>34#include <stdio.h>3536#include <db.h>37#include "recno.h"3839/*40* __REC_SEARCH -- Search a btree for a key.41*42* Parameters:43* t: tree to search44* recno: key to find45* op: search operation46*47* Returns:48* EPG for matching record, if any, or the EPG for the location of the49* key, if it were inserted into the tree.50*51* Returns:52* The EPG for matching record, if any, or the EPG for the location53* of the key, if it were inserted into the tree, is entered into54* the bt_cur field of the tree. A pointer to the field is returned.55*/56EPG *57__rec_search(BTREE *t, recno_t recno, enum SRCHOP op)58{59indx_t idx;60PAGE *h;61EPGNO *parent;62RINTERNAL *r;63pgno_t pg;64indx_t top;65recno_t total;66int sverrno;6768BT_CLR(t);69for (pg = P_ROOT, total = 0;;) {70if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)71goto err;72if (h->flags & P_RLEAF) {73t->bt_cur.page = h;74t->bt_cur.index = recno - total;75return (&t->bt_cur);76}77for (idx = 0, top = NEXTINDEX(h);;) {78r = GETRINTERNAL(h, idx);79if (++idx == top || total + r->nrecs > recno)80break;81total += r->nrecs;82}8384BT_PUSH(t, pg, idx - 1);8586pg = r->pgno;87switch (op) {88case SDELETE:89--GETRINTERNAL(h, (idx - 1))->nrecs;90mpool_put(t->bt_mp, h, MPOOL_DIRTY);91break;92case SINSERT:93++GETRINTERNAL(h, (idx - 1))->nrecs;94mpool_put(t->bt_mp, h, MPOOL_DIRTY);95break;96case SEARCH:97mpool_put(t->bt_mp, h, 0);98break;99}100101}102/* Try and recover the tree. */103err: sverrno = errno;104if (op != SEARCH)105while ((parent = BT_POP(t)) != NULL) {106if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)107break;108if (op == SINSERT)109--GETRINTERNAL(h, parent->index)->nrecs;110else111++GETRINTERNAL(h, parent->index)->nrecs;112mpool_put(t->bt_mp, h, MPOOL_DIRTY);113}114errno = sverrno;115return (NULL);116}117118119