]> git.saurik.com Git - apple/libc.git/blame - db/btree/bt_utils.c
Libc-262.3.2.tar.gz
[apple/libc.git] / db / btree / bt_utils.c
CommitLineData
e9ce8d39
A
1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
734aad71 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
e9ce8d39 7 *
734aad71
A
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
e9ce8d39
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
734aad71
A
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
e9ce8d39
A
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25/*
26 * Copyright (c) 1990, 1993
27 * The Regents of the University of California. All rights reserved.
28 *
29 * This code is derived from software contributed to Berkeley by
30 * Mike Olson.
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. All advertising materials mentioning features or use of this software
41 * must display the following acknowledgement:
42 * This product includes software developed by the University of
43 * California, Berkeley and its contributors.
44 * 4. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 */
60
61
62#include <sys/param.h>
63
64#include <stdio.h>
65#include <stdlib.h>
66#include <string.h>
67
68#include <db.h>
69#include "btree.h"
70
71/*
72 * __BT_RET -- Build return key/data pair as a result of search or scan.
73 *
74 * Parameters:
75 * t: tree
76 * d: LEAF to be returned to the user.
77 * key: user's key structure (NULL if not to be filled in)
78 * data: user's data structure
79 *
80 * Returns:
81 * RET_SUCCESS, RET_ERROR.
82 */
83int
84__bt_ret(t, e, key, data)
85 BTREE *t;
86 EPG *e;
87 DBT *key, *data;
88{
89 register BLEAF *bl;
90 register void *p;
91
92 bl = GETBLEAF(e->page, e->index);
93
94 /*
95 * We always copy big keys/data to make them contigous. Otherwise,
96 * we leave the page pinned and don't copy unless the user specified
97 * concurrent access.
98 */
99 if (bl->flags & P_BIGDATA) {
100 if (__ovfl_get(t, bl->bytes + bl->ksize,
101 &data->size, &t->bt_dbuf, &t->bt_dbufsz))
102 return (RET_ERROR);
103 data->data = t->bt_dbuf;
104 } else if (ISSET(t, B_DB_LOCK)) {
105 /* Use +1 in case the first record retrieved is 0 length. */
106 if (bl->dsize + 1 > t->bt_dbufsz) {
107 if ((p =
108 (void *)realloc(t->bt_dbuf, bl->dsize + 1)) == NULL)
109 return (RET_ERROR);
110 t->bt_dbuf = p;
111 t->bt_dbufsz = bl->dsize + 1;
112 }
113 memmove(t->bt_dbuf, bl->bytes + bl->ksize, bl->dsize);
114 data->size = bl->dsize;
115 data->data = t->bt_dbuf;
116 } else {
117 data->size = bl->dsize;
118 data->data = bl->bytes + bl->ksize;
119 }
120
121 if (key == NULL)
122 return (RET_SUCCESS);
123
124 if (bl->flags & P_BIGKEY) {
125 if (__ovfl_get(t, bl->bytes,
126 &key->size, &t->bt_kbuf, &t->bt_kbufsz))
127 return (RET_ERROR);
128 key->data = t->bt_kbuf;
129 } else if (ISSET(t, B_DB_LOCK)) {
130 if (bl->ksize > t->bt_kbufsz) {
131 if ((p =
132 (void *)realloc(t->bt_kbuf, bl->ksize)) == NULL)
133 return (RET_ERROR);
134 t->bt_kbuf = p;
135 t->bt_kbufsz = bl->ksize;
136 }
137 memmove(t->bt_kbuf, bl->bytes, bl->ksize);
138 key->size = bl->ksize;
139 key->data = t->bt_kbuf;
140 } else {
141 key->size = bl->ksize;
142 key->data = bl->bytes;
143 }
144 return (RET_SUCCESS);
145}
146
147/*
148 * __BT_CMP -- Compare a key to a given record.
149 *
150 * Parameters:
151 * t: tree
152 * k1: DBT pointer of first arg to comparison
153 * e: pointer to EPG for comparison
154 *
155 * Returns:
156 * < 0 if k1 is < record
157 * = 0 if k1 is = record
158 * > 0 if k1 is > record
159 */
160int
161__bt_cmp(t, k1, e)
162 BTREE *t;
163 const DBT *k1;
164 EPG *e;
165{
166 BINTERNAL *bi;
167 BLEAF *bl;
168 DBT k2;
169 PAGE *h;
170 void *bigkey;
171
172 /*
173 * The left-most key on internal pages, at any level of the tree, is
174 * guaranteed by the following code to be less than any user key.
175 * This saves us from having to update the leftmost key on an internal
176 * page when the user inserts a new key in the tree smaller than
177 * anything we've yet seen.
178 */
179 h = e->page;
180 if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & P_BLEAF))
181 return (1);
182
183 bigkey = NULL;
184 if (h->flags & P_BLEAF) {
185 bl = GETBLEAF(h, e->index);
186 if (bl->flags & P_BIGKEY)
187 bigkey = bl->bytes;
188 else {
189 k2.data = bl->bytes;
190 k2.size = bl->ksize;
191 }
192 } else {
193 bi = GETBINTERNAL(h, e->index);
194 if (bi->flags & P_BIGKEY)
195 bigkey = bi->bytes;
196 else {
197 k2.data = bi->bytes;
198 k2.size = bi->ksize;
199 }
200 }
201
202 if (bigkey) {
203 if (__ovfl_get(t, bigkey,
204 &k2.size, &t->bt_dbuf, &t->bt_dbufsz))
205 return (RET_ERROR);
206 k2.data = t->bt_dbuf;
207 }
208 return ((*t->bt_cmp)(k1, &k2));
209}
210
211/*
212 * __BT_DEFCMP -- Default comparison routine.
213 *
214 * Parameters:
215 * a: DBT #1
216 * b: DBT #2
217 *
218 * Returns:
219 * < 0 if a is < b
220 * = 0 if a is = b
221 * > 0 if a is > b
222 */
223int
224__bt_defcmp(a, b)
225 const DBT *a, *b;
226{
227 register size_t len;
228 register u_char *p1, *p2;
229
230 /*
231 * XXX
232 * If a size_t doesn't fit in an int, this routine can lose.
233 * What we need is a integral type which is guaranteed to be
234 * larger than a size_t, and there is no such thing.
235 */
236 len = MIN(a->size, b->size);
237 for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2)
238 if (*p1 != *p2)
239 return ((int)*p1 - (int)*p2);
240 return ((int)a->size - (int)b->size);
241}
242
243/*
244 * __BT_DEFPFX -- Default prefix routine.
245 *
246 * Parameters:
247 * a: DBT #1
248 * b: DBT #2
249 *
250 * Returns:
251 * Number of bytes needed to distinguish b from a.
252 */
253size_t
254__bt_defpfx(a, b)
255 const DBT *a, *b;
256{
257 register u_char *p1, *p2;
258 register size_t cnt, len;
259
260 cnt = 1;
261 len = MIN(a->size, b->size);
262 for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt)
263 if (*p1 != *p2)
264 return (cnt);
265
266 /* a->size must be <= b->size, or they wouldn't be in this order. */
267 return (a->size < b->size ? a->size + 1 : a->size);
268}