~ubuntu-branches/ubuntu/maverick/krb5/maverick

« back to all changes in this revision

Viewing changes to src/plugins/kdb/db2/libdb2/btree/bt_utils.c

  • Committer: Bazaar Package Importer
  • Author(s): Sam Hartman, Russ Allbery, Sam Hartman
  • Date: 2008-08-21 10:41:41 UTC
  • mfrom: (11.1.15 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080821104141-a0f9c4o4cpo8xd0o
Tags: 1.6.dfsg.4~beta1-4
[ Russ Allbery ]
* Translation updates:
  - Swedish, thanks Martin Bagge.  (Closes: #487669, #491774)
  - Italian, thanks Luca Monducci.  (Closes: #493962)

[ Sam Hartman ]
* Translation Updates:
    - Dutch, Thanks Vincent Zweije, Closes: #495733

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-
 
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:
 
11
 * 1. Redistributions of source code must retain the above copyright
 
12
 *    notice, this list of conditions and the following disclaimer.
 
13
 * 2. Redistributions in binary form must reproduce the above copyright
 
14
 *    notice, this list of conditions and the following disclaimer in the
 
15
 *    documentation and/or other materials provided with the distribution.
 
16
 * 3. All advertising materials mentioning features or use of this software
 
17
 *    must display the following acknowledgement:
 
18
 *      This product includes software developed by the University of
 
19
 *      California, Berkeley and its contributors.
 
20
 * 4. Neither the name of the University nor the names of its contributors
 
21
 *    may be used to endorse or promote products derived from this software
 
22
 *    without specific prior written permission.
 
23
 *
 
24
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 
25
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
26
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
27
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 
28
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
29
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
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)
 
38
static char sccsid[] = "@(#)bt_utils.c  8.8 (Berkeley) 7/20/94";
 
39
#endif /* LIBC_SCCS and not lint */
 
40
 
 
41
#include <sys/param.h>
 
42
 
 
43
#include <stdio.h>
 
44
#include <stdlib.h>
 
45
#include <string.h>
 
46
 
 
47
#include "db-int.h"
 
48
#include "btree.h"
 
49
 
 
50
/*
 
51
 * __bt_ret --
 
52
 *      Build return key/data pair.
 
53
 *
 
54
 * Parameters:
 
55
 *      t:      tree
 
56
 *      e:      key/data pair to be returned
 
57
 *      key:    user's key structure (NULL if not to be filled in)
 
58
 *      rkey:   memory area to hold key
 
59
 *      data:   user's data structure (NULL if not to be filled in)
 
60
 *      rdata:  memory area to hold data
 
61
 *       copy:  always copy the key/data item
 
62
 *
 
63
 * Returns:
 
64
 *      RET_SUCCESS, RET_ERROR.
 
65
 */
 
66
int
 
67
__bt_ret(t, e, key, rkey, data, rdata, copy)
 
68
        BTREE *t;
 
69
        EPG *e;
 
70
        DBT *key, *rkey, *data, *rdata;
 
71
        int copy;
 
72
{
 
73
        BLEAF *bl;
 
74
        void *p;
 
75
 
 
76
        bl = GETBLEAF(e->page, e->index);
 
77
 
 
78
        /*
 
79
         * We must copy big keys/data to make them contigous.  Otherwise,
 
80
         * leave the page pinned and don't copy unless the user specified
 
81
         * concurrent access.
 
82
         */
 
83
        if (key == NULL)
 
84
                goto dataonly;
 
85
 
 
86
        if (bl->flags & P_BIGKEY) {
 
87
                if (__ovfl_get(t, bl->bytes,
 
88
                    &key->size, &rkey->data, &rkey->size))
 
89
                        return (RET_ERROR);
 
90
                key->data = rkey->data;
 
91
        } else if (copy || F_ISSET(t, B_DB_LOCK)) {
 
92
                if (bl->ksize > rkey->size) {
 
93
                        p = (void *)(rkey->data == NULL ?
 
94
                            malloc(bl->ksize) : realloc(rkey->data, bl->ksize));
 
95
                        if (p == NULL)
 
96
                                return (RET_ERROR);
 
97
                        rkey->data = p;
 
98
                        rkey->size = bl->ksize;
 
99
                }
 
100
                memmove(rkey->data, bl->bytes, bl->ksize);
 
101
                key->size = bl->ksize;
 
102
                key->data = rkey->data;
 
103
        } else {
 
104
                key->size = bl->ksize;
 
105
                key->data = bl->bytes;
 
106
        }
 
107
 
 
108
dataonly:
 
109
        if (data == NULL)
 
110
                return (RET_SUCCESS);
 
111
 
 
112
        if (bl->flags & P_BIGDATA) {
 
113
                if (__ovfl_get(t, bl->bytes + bl->ksize,
 
114
                    &data->size, &rdata->data, &rdata->size))
 
115
                        return (RET_ERROR);
 
116
                data->data = rdata->data;
 
117
        } else if (copy || F_ISSET(t, B_DB_LOCK)) {
 
118
                /* Use +1 in case the first record retrieved is 0 length. */
 
119
                if (bl->dsize + 1 > rdata->size) {
 
120
                        p = (void *)(rdata->data == NULL ?
 
121
                            malloc(bl->dsize + 1) :
 
122
                            realloc(rdata->data, bl->dsize + 1));
 
123
                        if (p == NULL)
 
124
                                return (RET_ERROR);
 
125
                        rdata->data = p;
 
126
                        rdata->size = bl->dsize + 1;
 
127
                }
 
128
                memmove(rdata->data, bl->bytes + bl->ksize, bl->dsize);
 
129
                data->size = bl->dsize;
 
130
                data->data = rdata->data;
 
131
        } else {
 
132
                data->size = bl->dsize;
 
133
                data->data = bl->bytes + bl->ksize;
 
134
        }
 
135
 
 
136
        return (RET_SUCCESS);
 
137
}
 
138
 
 
139
/*
 
140
 * __BT_CMP -- Compare a key to a given record.
 
141
 *
 
142
 * Parameters:
 
143
 *      t:      tree
 
144
 *      k1:     DBT pointer of first arg to comparison
 
145
 *      e:      pointer to EPG for comparison
 
146
 *
 
147
 * Returns:
 
148
 *      < 0 if k1 is < record
 
149
 *      = 0 if k1 is = record
 
150
 *      > 0 if k1 is > record
 
151
 */
 
152
int
 
153
__bt_cmp(t, k1, e)
 
154
        BTREE *t;
 
155
        const DBT *k1;
 
156
        EPG *e;
 
157
{
 
158
        BINTERNAL *bi;
 
159
        BLEAF *bl;
 
160
        DBT k2;
 
161
        PAGE *h;
 
162
        void *bigkey;
 
163
 
 
164
        /*
 
165
         * The left-most key on internal pages, at any level of the tree, is
 
166
         * guaranteed by the following code to be less than any user key.
 
167
         * This saves us from having to update the leftmost key on an internal
 
168
         * page when the user inserts a new key in the tree smaller than
 
169
         * anything we've yet seen.
 
170
         */
 
171
        h = e->page;
 
172
        if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & P_BLEAF))
 
173
                return (1);
 
174
 
 
175
        bigkey = NULL;
 
176
        if (h->flags & P_BLEAF) {
 
177
                bl = GETBLEAF(h, e->index);
 
178
                if (bl->flags & P_BIGKEY)
 
179
                        bigkey = bl->bytes;
 
180
                else {
 
181
                        k2.data = bl->bytes;
 
182
                        k2.size = bl->ksize;
 
183
                }
 
184
        } else {
 
185
                bi = GETBINTERNAL(h, e->index);
 
186
                if (bi->flags & P_BIGKEY)
 
187
                        bigkey = bi->bytes;
 
188
                else {
 
189
                        k2.data = bi->bytes;
 
190
                        k2.size = bi->ksize;
 
191
                }
 
192
        }
 
193
 
 
194
        if (bigkey) {
 
195
                if (__ovfl_get(t, bigkey,
 
196
                    &k2.size, &t->bt_rdata.data, &t->bt_rdata.size))
 
197
                        return (RET_ERROR);
 
198
                k2.data = t->bt_rdata.data;
 
199
        }
 
200
        return ((*t->bt_cmp)(k1, &k2));
 
201
}
 
202
 
 
203
/*
 
204
 * __BT_DEFCMP -- Default comparison routine.
 
205
 *
 
206
 * Parameters:
 
207
 *      a:      DBT #1
 
208
 *      b:      DBT #2
 
209
 *
 
210
 * Returns:
 
211
 *      < 0 if a is < b
 
212
 *      = 0 if a is = b
 
213
 *      > 0 if a is > b
 
214
 */
 
215
int
 
216
__bt_defcmp(a, b)
 
217
        const DBT *a, *b;
 
218
{
 
219
        register size_t len;
 
220
        register u_char *p1, *p2;
 
221
 
 
222
        /*
 
223
         * XXX
 
224
         * If a size_t doesn't fit in an int, this routine can lose.
 
225
         * What we need is a integral type which is guaranteed to be
 
226
         * larger than a size_t, and there is no such thing.
 
227
         */
 
228
        len = MIN(a->size, b->size);
 
229
        for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2)
 
230
                if (*p1 != *p2)
 
231
                        return ((int)*p1 - (int)*p2);
 
232
        return ((int)a->size - (int)b->size);
 
233
}
 
234
 
 
235
/*
 
236
 * __BT_DEFPFX -- Default prefix routine.
 
237
 *
 
238
 * Parameters:
 
239
 *      a:      DBT #1
 
240
 *      b:      DBT #2
 
241
 *
 
242
 * Returns:
 
243
 *      Number of bytes needed to distinguish b from a.
 
244
 */
 
245
size_t
 
246
__bt_defpfx(a, b)
 
247
        const DBT *a, *b;
 
248
{
 
249
        register u_char *p1, *p2;
 
250
        register size_t cnt, len;
 
251
 
 
252
        cnt = 1;
 
253
        len = MIN(a->size, b->size);
 
254
        for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt)
 
255
                if (*p1 != *p2)
 
256
                        return (cnt);
 
257
 
 
258
        /* a->size must be <= b->size, or they wouldn't be in this order. */
 
259
        return (a->size < b->size ? a->size + 1 : a->size);
 
260
}