]>
git.saurik.com Git - apple/libc.git/blob - db.subproj/btree.subproj/bt_search.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1990, 1993
24 * The Regents of the University of California. All rights reserved.
26 * This code is derived from software contributed to Berkeley by
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 #include <sys/types.h>
66 static int bt_snext
__P((BTREE
*, PAGE
*, const DBT
*, int *));
67 static int bt_sprev
__P((BTREE
*, PAGE
*, const DBT
*, int *));
70 * __BT_SEARCH -- Search a btree for a key.
75 * exactp: pointer to exact match flag
78 * The EPG for matching record, if any, or the EPG for the location
79 * of the key, if it were inserted into the tree, is entered into
80 * the bt_cur field of the tree. A pointer to the field is returned.
83 __bt_search(t
, key
, exactp
)
89 indx_t base
, index
, lim
;
95 if ((h
= mpool_get(t
->bt_mp
, pg
, 0)) == NULL
)
98 /* Do a binary search on the current page. */
100 for (base
= 0, lim
= NEXTINDEX(h
); lim
; lim
>>= 1) {
101 t
->bt_cur
.index
= index
= base
+ (lim
>> 1);
102 if ((cmp
= __bt_cmp(t
, key
, &t
->bt_cur
)) == 0) {
103 if (h
->flags
& P_BLEAF
) {
116 * If it's a leaf page, and duplicates aren't allowed, we're
117 * done. If duplicates are allowed, it's possible that there
118 * were duplicate keys on duplicate pages, and they were later
119 * deleted, so we could be on a page with no matches while
120 * there are matches on other pages. If we're at the start or
121 * end of a page, check on both sides.
123 if (h
->flags
& P_BLEAF
) {
124 t
->bt_cur
.index
= base
;
126 if (!ISSET(t
, B_NODUPS
)) {
128 bt_sprev(t
, h
, key
, exactp
))
130 if (base
== NEXTINDEX(h
) &&
131 bt_snext(t
, h
, key
, exactp
))
138 * No match found. Base is the smallest index greater than
139 * key and may be zero or a last + 1 index. If it's non-zero,
140 * decrement by one, and record the internal page which should
141 * be a parent page for the key. If a split later occurs, the
142 * inserted page will be to the right of the saved page.
144 index
= base
? base
- 1 : base
;
146 next
: if (__bt_push(t
, h
->pgno
, index
) == RET_ERROR
)
148 pg
= GETBINTERNAL(h
, index
)->pgno
;
149 mpool_put(t
->bt_mp
, h
, 0);
154 * BT_SNEXT -- Check for an exact match after the key.
160 * exactp: pointer to exact match flag
163 * If an exact match found.
166 bt_snext(t
, h
, key
, exactp
)
176 /* Skip until reach the end of the tree or a key. */
177 for (pg
= h
->nextpg
; pg
!= P_INVALID
;) {
178 if ((tp
= mpool_get(t
->bt_mp
, pg
, 0)) == NULL
) {
179 mpool_put(t
->bt_mp
, h
, 0);
182 if (NEXTINDEX(tp
) != 0)
185 mpool_put(t
->bt_mp
, tp
, 0);
188 * The key is either an exact match, or not as good as
189 * the one we already have.
191 if (pg
!= P_INVALID
) {
193 e
.index
= NEXTINDEX(tp
) - 1;
194 if (__bt_cmp(t
, key
, &e
) == 0) {
195 mpool_put(t
->bt_mp
, h
, 0);
205 * BT_SPREV -- Check for an exact match before the key.
211 * exactp: pointer to exact match flag
214 * If an exact match found.
217 bt_sprev(t
, h
, key
, exactp
)
227 /* Skip until reach the beginning of the tree or a key. */
228 for (pg
= h
->prevpg
; pg
!= P_INVALID
;) {
229 if ((tp
= mpool_get(t
->bt_mp
, pg
, 0)) == NULL
) {
230 mpool_put(t
->bt_mp
, h
, 0);
233 if (NEXTINDEX(tp
) != 0)
236 mpool_put(t
->bt_mp
, tp
, 0);
239 * The key is either an exact match, or not as good as
240 * the one we already have.
242 if (pg
!= P_INVALID
) {
244 e
.index
= NEXTINDEX(tp
) - 1;
245 if (__bt_cmp(t
, key
, &e
) == 0) {
246 mpool_put(t
->bt_mp
, h
, 0);