1 /*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1996, 1997, 1998, 1999
5 * Sleepycat Software. All rights reserved.
6 */
7 /*
8 * Copyright (c) 1990, 1993, 1994, 1995, 1996
9 * Keith Bostic. All rights reserved.
10 */
11 /*
12 * Copyright (c) 1990, 1993, 1994, 1995
13 * The Regents of the University of California. All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 */
39
40 #include "db_config.h"
41
42 #ifndef lint
43 static const char sccsid[] = "@(#)db_conv.c 11.4 (Sleepycat) 11/10/99";
44 #endif /* not lint */
45
46 #ifndef NO_SYSTEM_INCLUDES
47 #include <sys/types.h>
48
49 #include <errno.h>
50 #include <string.h>
51 #endif
52
53 #include "db_int.h"
54 #include "db_page.h"
55 #include "db_swap.h"
56 #include "db_am.h"
57 #include "btree.h"
58 #include "hash.h"
59 #include "qam.h"
60
61 /*
62 * CDB___db_pgin --
63 * Primary page-swap routine.
64 *
65 * PUBLIC: int CDB___db_pgin __P((db_pgno_t, void *, DBT *));
66 */
67 int
CDB___db_pgin(pg,pp,cookie)68 CDB___db_pgin(pg, pp, cookie)
69 db_pgno_t pg;
70 void *pp;
71 DBT *cookie;
72 {
73 DB_PGINFO *pginfo;
74
75 pginfo = (DB_PGINFO *)cookie->data;
76
77 switch (((PAGE *)pp)->type) {
78 case P_HASH:
79 case P_HASHMETA:
80 case P_INVALID:
81 return (CDB___ham_pgin(pg, pp, cookie));
82 case P_BTREEMETA:
83 case P_IBTREE:
84 case P_IRECNO:
85 case P_LBTREE:
86 case P_LRECNO:
87 case P_DUPLICATE:
88 case P_OVERFLOW:
89 return (CDB___bam_pgin(pg, pp, cookie));
90 case P_QAMMETA:
91 case P_QAMDATA:
92 return (CDB___qam_pgin_out(pg, pp, cookie));
93 default:
94 break;
95 }
96 return (EINVAL);
97 }
98
99 /*
100 * CDB___db_pgout --
101 * Primary page-swap routine.
102 *
103 * PUBLIC: int CDB___db_pgout __P((db_pgno_t, void *, DBT *));
104 */
105 int
CDB___db_pgout(pg,pp,cookie)106 CDB___db_pgout(pg, pp, cookie)
107 db_pgno_t pg;
108 void *pp;
109 DBT *cookie;
110 {
111 DB_PGINFO *pginfo;
112
113 pginfo = (DB_PGINFO *)cookie->data;
114
115 switch (((PAGE *)pp)->type) {
116 case P_HASH:
117 case P_HASHMETA:
118 case P_INVALID:
119 return (CDB___ham_pgout(pg, pp, cookie));
120 case P_BTREEMETA:
121 case P_IBTREE:
122 case P_IRECNO:
123 case P_LBTREE:
124 case P_LRECNO:
125 case P_DUPLICATE:
126 case P_OVERFLOW:
127 return (CDB___bam_pgout(pg, pp, cookie));
128 case P_QAMMETA:
129 case P_QAMDATA:
130 return (CDB___qam_pgin_out(pg, pp, cookie));
131 default:
132 break;
133 }
134 return (EINVAL);
135 }
136
137 /*
138 * CDB___db_metaswap --
139 * Byteswap the common part of the meta-data page.
140 *
141 * PUBLIC: void CDB___db_metaswap __P((PAGE *));
142 */
143 void
CDB___db_metaswap(pg)144 CDB___db_metaswap(pg)
145 PAGE *pg;
146 {
147 u_int8_t *p;
148
149 p = (u_int8_t *)pg;
150
151 /* Swap the meta-data information. */
152 SWAP32(p); /* lsn.file */
153 SWAP32(p); /* lsn.offset */
154 SWAP32(p); /* pgno */
155 SWAP32(p); /* magic */
156 SWAP32(p); /* version */
157 SWAP32(p); /* pagesize */
158 p += 4; /* unused, page type, unused, unused */
159 SWAP32(p); /* free */
160 SWAP32(p); /* flags */
161 }
162
163 /*
164 * CDB___db_byteswap --
165 * Byteswap a page.
166 *
167 * PUBLIC: int CDB___db_byteswap __P((db_pgno_t, PAGE *, size_t, int));
168 */
169 int
CDB___db_byteswap(pg,h,pagesize,pgin)170 CDB___db_byteswap(pg, h, pagesize, pgin)
171 db_pgno_t pg;
172 PAGE *h;
173 size_t pagesize;
174 int pgin;
175 {
176 BINTERNAL *bi;
177 BKEYDATA *bk;
178 BOVERFLOW *bo;
179 RINTERNAL *ri;
180 db_indx_t i, len, tmp;
181 u_int8_t *p, *end;
182
183 COMPQUIET(pg, 0);
184
185 if (pgin) {
186 M_32_SWAP(h->lsn.file);
187 M_32_SWAP(h->lsn.offset);
188 M_32_SWAP(h->pgno);
189 M_32_SWAP(h->prev_pgno);
190 M_32_SWAP(h->next_pgno);
191 M_16_SWAP(h->entries);
192 M_16_SWAP(h->hf_offset);
193 }
194
195 switch (h->type) {
196 case P_HASH:
197 for (i = 0; i < NUM_ENT(h); i++) {
198 if (pgin)
199 M_16_SWAP(h->inp[i]);
200
201 switch (HPAGE_TYPE(h, i)) {
202 case H_KEYDATA:
203 break;
204 case H_DUPLICATE:
205 len = LEN_HKEYDATA(h, pagesize, i);
206 p = HKEYDATA_DATA(P_ENTRY(h, i));
207 for (end = p + len; p < end;) {
208 if (pgin) {
209 P_16_SWAP(p);
210 memcpy(&tmp,
211 p, sizeof(db_indx_t));
212 p += sizeof(db_indx_t);
213 } else {
214 memcpy(&tmp,
215 p, sizeof(db_indx_t));
216 SWAP16(p);
217 }
218 p += tmp;
219 SWAP16(p);
220 }
221 break;
222 case H_OFFDUP:
223 p = HOFFPAGE_PGNO(P_ENTRY(h, i));
224 SWAP32(p); /* pgno */
225 break;
226 case H_OFFPAGE:
227 p = HOFFPAGE_PGNO(P_ENTRY(h, i));
228 SWAP32(p); /* pgno */
229 SWAP32(p); /* tlen */
230 break;
231 }
232
233 }
234
235 /*
236 * The offsets in the inp array are used to determine
237 * the size of entries on a page; therefore they
238 * cannot be converted until we've done all the
239 * entries.
240 */
241 if (!pgin)
242 for (i = 0; i < NUM_ENT(h); i++)
243 M_16_SWAP(h->inp[i]);
244 break;
245 case P_LBTREE:
246 case P_LRECNO:
247 case P_DUPLICATE:
248 for (i = 0; i < NUM_ENT(h); i++) {
249 if (pgin)
250 M_16_SWAP(h->inp[i]);
251
252 /*
253 * In the case of on-page duplicates, key information
254 * should only be swapped once.
255 */
256 if (h->type == P_LBTREE && i > 1) {
257 if (pgin) {
258 if (h->inp[i] == h->inp[i - 2])
259 continue;
260 } else {
261 M_16_SWAP(h->inp[i]);
262 if (h->inp[i] == h->inp[i - 2])
263 continue;
264 M_16_SWAP(h->inp[i]);
265 }
266 }
267
268 bk = GET_BKEYDATA(h, i);
269 switch (B_TYPE(bk->type)) {
270 case B_KEYDATA:
271 M_16_SWAP(bk->len);
272 break;
273 case B_DUPLICATE:
274 case B_OVERFLOW:
275 bo = (BOVERFLOW *)bk;
276 M_32_SWAP(bo->pgno);
277 M_32_SWAP(bo->tlen);
278 break;
279 }
280
281 if (!pgin)
282 M_16_SWAP(h->inp[i]);
283 }
284 break;
285 case P_IBTREE:
286 for (i = 0; i < NUM_ENT(h); i++) {
287 if (pgin)
288 M_16_SWAP(h->inp[i]);
289
290 bi = GET_BINTERNAL(h, i);
291 M_16_SWAP(bi->len);
292 M_32_SWAP(bi->pgno);
293 M_32_SWAP(bi->nrecs);
294
295 switch (B_TYPE(bi->type)) {
296 case B_KEYDATA:
297 break;
298 case B_DUPLICATE:
299 case B_OVERFLOW:
300 bo = (BOVERFLOW *)bi->data;
301 M_32_SWAP(bo->pgno);
302 M_32_SWAP(bo->tlen);
303 break;
304 }
305
306 if (!pgin)
307 M_16_SWAP(h->inp[i]);
308 }
309 break;
310 case P_IRECNO:
311 for (i = 0; i < NUM_ENT(h); i++) {
312 if (pgin)
313 M_16_SWAP(h->inp[i]);
314
315 ri = GET_RINTERNAL(h, i);
316 M_32_SWAP(ri->pgno);
317 M_32_SWAP(ri->nrecs);
318
319 if (!pgin)
320 M_16_SWAP(h->inp[i]);
321 }
322 break;
323 case P_OVERFLOW:
324 case P_INVALID:
325 /* Nothing to do. */
326 break;
327 default:
328 return (EINVAL);
329 }
330
331 if (!pgin) {
332 /* Swap the header information. */
333 M_32_SWAP(h->lsn.file);
334 M_32_SWAP(h->lsn.offset);
335 M_32_SWAP(h->pgno);
336 M_32_SWAP(h->prev_pgno);
337 M_32_SWAP(h->next_pgno);
338 M_16_SWAP(h->entries);
339 M_16_SWAP(h->hf_offset);
340 }
341 return (0);
342 }
343