Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/db/recno/rec_search.c
39507 views
1
/*-
2
* SPDX-License-Identifier: BSD-3-Clause
3
*
4
* Copyright (c) 1990, 1993
5
* The Regents of the University of California. All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
* 3. Neither the name of the University nor the names of its contributors
16
* may be used to endorse or promote products derived from this software
17
* without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29
* SUCH DAMAGE.
30
*/
31
32
#include <sys/types.h>
33
34
#include <errno.h>
35
#include <stdio.h>
36
37
#include <db.h>
38
#include "recno.h"
39
40
/*
41
* __REC_SEARCH -- Search a btree for a key.
42
*
43
* Parameters:
44
* t: tree to search
45
* recno: key to find
46
* op: search operation
47
*
48
* Returns:
49
* EPG for matching record, if any, or the EPG for the location of the
50
* key, if it were inserted into the tree.
51
*
52
* Returns:
53
* The EPG for matching record, if any, or the EPG for the location
54
* of the key, if it were inserted into the tree, is entered into
55
* the bt_cur field of the tree. A pointer to the field is returned.
56
*/
57
EPG *
58
__rec_search(BTREE *t, recno_t recno, enum SRCHOP op)
59
{
60
indx_t idx;
61
PAGE *h;
62
EPGNO *parent;
63
RINTERNAL *r;
64
pgno_t pg;
65
indx_t top;
66
recno_t total;
67
int sverrno;
68
69
BT_CLR(t);
70
for (pg = P_ROOT, total = 0;;) {
71
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
72
goto err;
73
if (h->flags & P_RLEAF) {
74
t->bt_cur.page = h;
75
t->bt_cur.index = recno - total;
76
return (&t->bt_cur);
77
}
78
for (idx = 0, top = NEXTINDEX(h);;) {
79
r = GETRINTERNAL(h, idx);
80
if (++idx == top || total + r->nrecs > recno)
81
break;
82
total += r->nrecs;
83
}
84
85
BT_PUSH(t, pg, idx - 1);
86
87
pg = r->pgno;
88
switch (op) {
89
case SDELETE:
90
--GETRINTERNAL(h, (idx - 1))->nrecs;
91
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
92
break;
93
case SINSERT:
94
++GETRINTERNAL(h, (idx - 1))->nrecs;
95
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
96
break;
97
case SEARCH:
98
mpool_put(t->bt_mp, h, 0);
99
break;
100
}
101
102
}
103
/* Try and recover the tree. */
104
err: sverrno = errno;
105
if (op != SEARCH)
106
while ((parent = BT_POP(t)) != NULL) {
107
if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
108
break;
109
if (op == SINSERT)
110
--GETRINTERNAL(h, parent->index)->nrecs;
111
else
112
++GETRINTERNAL(h, parent->index)->nrecs;
113
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
114
}
115
errno = sverrno;
116
return (NULL);
117
}
118
119