Deleted Added
full compact
bt_search.c (1573) bt_search.c (14272)
1/*-
1/*-
2 * Copyright (c) 1990, 1993
2 * Copyright (c) 1990, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Mike Olson.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:

--- 19 unchanged lines hidden (view full) ---

30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Mike Olson.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:

--- 19 unchanged lines hidden (view full) ---

30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char sccsid[] = "@(#)bt_search.c 8.6 (Berkeley) 3/15/94";
38static char sccsid[] = "@(#)bt_search.c 8.8 (Berkeley) 7/31/94";
39#endif /* LIBC_SCCS and not lint */
40
41#include <sys/types.h>
42
43#include <stdio.h>
44
45#include <db.h>
46#include "btree.h"
47
39#endif /* LIBC_SCCS and not lint */
40
41#include <sys/types.h>
42
43#include <stdio.h>
44
45#include <db.h>
46#include "btree.h"
47
48static int bt_snext __P((BTREE *, PAGE *, const DBT *, int *));
49static int bt_sprev __P((BTREE *, PAGE *, const DBT *, int *));
48static int __bt_snext __P((BTREE *, PAGE *, const DBT *, int *));
49static int __bt_sprev __P((BTREE *, PAGE *, const DBT *, int *));
50
51/*
50
51/*
52 * __BT_SEARCH -- Search a btree for a key.
52 * __bt_search --
53 * Search a btree for a key.
53 *
54 * Parameters:
55 * t: tree to search
56 * key: key to find
57 * exactp: pointer to exact match flag
58 *
59 * Returns:
60 * The EPG for matching record, if any, or the EPG for the location

--- 29 unchanged lines hidden (view full) ---

90 }
91 if (cmp > 0) {
92 base = index + 1;
93 --lim;
94 }
95 }
96
97 /*
54 *
55 * Parameters:
56 * t: tree to search
57 * key: key to find
58 * exactp: pointer to exact match flag
59 *
60 * Returns:
61 * The EPG for matching record, if any, or the EPG for the location

--- 29 unchanged lines hidden (view full) ---

91 }
92 if (cmp > 0) {
93 base = index + 1;
94 --lim;
95 }
96 }
97
98 /*
98 * If it's a leaf page, and duplicates aren't allowed, we're
99 * done. If duplicates are allowed, it's possible that there
100 * were duplicate keys on duplicate pages, and they were later
101 * deleted, so we could be on a page with no matches while
102 * there are matches on other pages. If we're at the start or
103 * end of a page, check on both sides.
99 * If it's a leaf page, we're almost done. If no duplicates
100 * are allowed, or we have an exact match, we're done. Else,
101 * it's possible that there were matching keys on this page,
102 * which later deleted, and we're on a page with no matches
103 * while there are matches on other pages. If at the start or
104 * end of a page, check the adjacent page.
104 */
105 if (h->flags & P_BLEAF) {
105 */
106 if (h->flags & P_BLEAF) {
106 t->bt_cur.index = base;
107 *exactp = 0;
108 if (!ISSET(t, B_NODUPS)) {
107 if (!F_ISSET(t, B_NODUPS)) {
109 if (base == 0 &&
108 if (base == 0 &&
110 bt_sprev(t, h, key, exactp))
109 h->prevpg != P_INVALID &&
110 __bt_sprev(t, h, key, exactp))
111 return (&t->bt_cur);
112 if (base == NEXTINDEX(h) &&
111 return (&t->bt_cur);
112 if (base == NEXTINDEX(h) &&
113 bt_snext(t, h, key, exactp))
113 h->nextpg != P_INVALID &&
114 __bt_snext(t, h, key, exactp))
114 return (&t->bt_cur);
115 }
115 return (&t->bt_cur);
116 }
117 *exactp = 0;
118 t->bt_cur.index = base;
116 return (&t->bt_cur);
117 }
118
119 /*
120 * No match found. Base is the smallest index greater than
121 * key and may be zero or a last + 1 index. If it's non-zero,
122 * decrement by one, and record the internal page which should
123 * be a parent page for the key. If a split later occurs, the
124 * inserted page will be to the right of the saved page.
125 */
126 index = base ? base - 1 : base;
127
119 return (&t->bt_cur);
120 }
121
122 /*
123 * No match found. Base is the smallest index greater than
124 * key and may be zero or a last + 1 index. If it's non-zero,
125 * decrement by one, and record the internal page which should
126 * be a parent page for the key. If a split later occurs, the
127 * inserted page will be to the right of the saved page.
128 */
129 index = base ? base - 1 : base;
130
128next: if (__bt_push(t, h->pgno, index) == RET_ERROR)
129 return (NULL);
131next: BT_PUSH(t, h->pgno, index);
130 pg = GETBINTERNAL(h, index)->pgno;
131 mpool_put(t->bt_mp, h, 0);
132 }
133}
134
135/*
132 pg = GETBINTERNAL(h, index)->pgno;
133 mpool_put(t->bt_mp, h, 0);
134 }
135}
136
137/*
136 * BT_SNEXT -- Check for an exact match after the key.
138 * __bt_snext --
139 * Check for an exact match after the key.
137 *
138 * Parameters:
140 *
141 * Parameters:
139 * t: tree to search
140 * h: current page.
141 * key: key to find
142 * t: tree
143 * h: current page
144 * key: key
142 * exactp: pointer to exact match flag
143 *
144 * Returns:
145 * If an exact match found.
146 */
147static int
145 * exactp: pointer to exact match flag
146 *
147 * Returns:
148 * If an exact match found.
149 */
150static int
148bt_snext(t, h, key, exactp)
151__bt_snext(t, h, key, exactp)
149 BTREE *t;
150 PAGE *h;
151 const DBT *key;
152 int *exactp;
153{
154 EPG e;
152 BTREE *t;
153 PAGE *h;
154 const DBT *key;
155 int *exactp;
156{
157 EPG e;
155 PAGE *tp;
156 pgno_t pg;
157
158
158 /* Skip until reach the end of the tree or a key. */
159 for (pg = h->nextpg; pg != P_INVALID;) {
160 if ((tp = mpool_get(t->bt_mp, pg, 0)) == NULL) {
161 mpool_put(t->bt_mp, h, 0);
162 return (NULL);
163 }
164 if (NEXTINDEX(tp) != 0)
165 break;
166 pg = tp->prevpg;
167 mpool_put(t->bt_mp, tp, 0);
168 }
169 /*
159 /*
170 * The key is either an exact match, or not as good as
171 * the one we already have.
160 * Get the next page. The key is either an exact
161 * match, or not as good as the one we already have.
172 */
162 */
173 if (pg != P_INVALID) {
174 e.page = tp;
175 e.index = NEXTINDEX(tp) - 1;
176 if (__bt_cmp(t, key, &e) == 0) {
177 mpool_put(t->bt_mp, h, 0);
178 t->bt_cur = e;
179 *exactp = 1;
180 return (1);
181 }
163 if ((e.page = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
164 return (0);
165 e.index = 0;
166 if (__bt_cmp(t, key, &e) == 0) {
167 mpool_put(t->bt_mp, h, 0);
168 t->bt_cur = e;
169 *exactp = 1;
170 return (1);
182 }
171 }
172 mpool_put(t->bt_mp, e.page, 0);
183 return (0);
184}
185
186/*
173 return (0);
174}
175
176/*
187 * BT_SPREV -- Check for an exact match before the key.
177 * __bt_sprev --
178 * Check for an exact match before the key.
188 *
189 * Parameters:
179 *
180 * Parameters:
190 * t: tree to search
191 * h: current page.
192 * key: key to find
181 * t: tree
182 * h: current page
183 * key: key
193 * exactp: pointer to exact match flag
194 *
195 * Returns:
196 * If an exact match found.
197 */
198static int
184 * exactp: pointer to exact match flag
185 *
186 * Returns:
187 * If an exact match found.
188 */
189static int
199bt_sprev(t, h, key, exactp)
190__bt_sprev(t, h, key, exactp)
200 BTREE *t;
201 PAGE *h;
202 const DBT *key;
203 int *exactp;
204{
205 EPG e;
191 BTREE *t;
192 PAGE *h;
193 const DBT *key;
194 int *exactp;
195{
196 EPG e;
206 PAGE *tp;
207 pgno_t pg;
208
197
209 /* Skip until reach the beginning of the tree or a key. */
210 for (pg = h->prevpg; pg != P_INVALID;) {
211 if ((tp = mpool_get(t->bt_mp, pg, 0)) == NULL) {
212 mpool_put(t->bt_mp, h, 0);
213 return (NULL);
214 }
215 if (NEXTINDEX(tp) != 0)
216 break;
217 pg = tp->prevpg;
218 mpool_put(t->bt_mp, tp, 0);
219 }
220 /*
198 /*
221 * The key is either an exact match, or not as good as
222 * the one we already have.
199 * Get the previous page. The key is either an exact
200 * match, or not as good as the one we already have.
223 */
201 */
224 if (pg != P_INVALID) {
225 e.page = tp;
226 e.index = NEXTINDEX(tp) - 1;
227 if (__bt_cmp(t, key, &e) == 0) {
228 mpool_put(t->bt_mp, h, 0);
229 t->bt_cur = e;
230 *exactp = 1;
231 return (1);
232 }
202 if ((e.page = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
203 return (0);
204 e.index = NEXTINDEX(e.page) - 1;
205 if (__bt_cmp(t, key, &e) == 0) {
206 mpool_put(t->bt_mp, h, 0);
207 t->bt_cur = e;
208 *exactp = 1;
209 return (1);
233 }
210 }
211 mpool_put(t->bt_mp, e.page, 0);
234 return (0);
235}
212 return (0);
213}