1 /*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1996, 1997, 1998, 1999, 2000
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 "config.h"
41
42 #ifndef lint
43 static const char revid[] = "$Id: db_conv.c,v 1.5 2014/04/17 20:27:26 sebdiaz Exp $";
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_ENV *, db_pgno_t, void *, DBT *));
66 */
67 int
CDB___db_pgin(dbenv,pg,pp,cookie)68 CDB___db_pgin(dbenv, pg, pp, cookie)
69 DB_ENV *dbenv;
70 db_pgno_t pg;
71 void *pp;
72 DBT *cookie;
73 {
74
75
76
77 switch (TYPE(pp)) {
78 case P_HASH:
79 case P_HASHMETA:
80 case P_INVALID:
81 return (CDB___ham_pgin(dbenv, pg, pp, cookie));
82 case P_BTREEMETA:
83 case P_IBTREE:
84 case P_IRECNO:
85 case P_LBTREE:
86 case P_LDUP:
87 case P_LRECNO:
88 case P_OVERFLOW:
89 return (CDB___bam_pgin(dbenv, pg, pp, cookie));
90 case P_QAMMETA:
91 case P_QAMDATA:
92 return (CDB___qam_pgin_out(dbenv, pg, pp, cookie));
93 default:
94 break;
95 }
96 return (CDB___db_unknown_type(dbenv, "CDB___db_pgin", ((PAGE *)pp)->type));
97 }
98
99 /*
100 * CDB___db_pgout --
101 * Primary page-swap routine.
102 *
103 * PUBLIC: int CDB___db_pgout __P((DB_ENV *, db_pgno_t, void *, DBT *));
104 */
105 int
CDB___db_pgout(dbenv,pg,pp,cookie)106 CDB___db_pgout(dbenv, pg, pp, cookie)
107 DB_ENV *dbenv;
108 db_pgno_t pg;
109 void *pp;
110 DBT *cookie;
111 {
112
113 switch (TYPE(pp)) {
114 case P_HASH:
115 case P_HASHMETA:
116 case P_INVALID:
117 return (CDB___ham_pgout(dbenv, pg, pp, cookie));
118 case P_BTREEMETA:
119 case P_IBTREE:
120 case P_IRECNO:
121 case P_LBTREE:
122 case P_LDUP:
123 case P_LRECNO:
124 case P_OVERFLOW:
125 return (CDB___bam_pgout(dbenv, pg, pp, cookie));
126 case P_QAMMETA:
127 case P_QAMDATA:
128 return (CDB___qam_pgin_out(dbenv, pg, pp, cookie));
129 default:
130 break;
131 }
132 return (CDB___db_unknown_type(dbenv, "CDB___db_pgout", ((PAGE *)pp)->type));
133 }
134
135 /*
136 * CDB___db_metaswap --
137 * Byteswap the common part of the meta-data page.
138 *
139 * PUBLIC: void CDB___db_metaswap __P((PAGE *));
140 */
141 void
CDB___db_metaswap(pg)142 CDB___db_metaswap(pg)
143 PAGE *pg;
144 {
145 u_int8_t *p;
146
147 p = (u_int8_t *)pg;
148
149 /* Swap the meta-data information. */
150 SWAP32(p); /* lsn.file */
151 SWAP32(p); /* lsn.offset */
152 SWAP32(p); /* pgno */
153 SWAP32(p); /* magic */
154 SWAP32(p); /* version */
155 SWAP32(p); /* pagesize */
156 p += 4; /* unused, page type, unused, unused */
157 SWAP32(p); /* free */
158 SWAP32(p); /* alloc_lsn part 1 */
159 SWAP32(p); /* alloc_lsn part 2 */
160 SWAP32(p); /* cached key count */
161 SWAP32(p); /* cached record count */
162 SWAP32(p); /* flags */
163 }
164
165 /*
166 * CDB___db_byteswap --
167 * Byteswap a page.
168 *
169 * PUBLIC: int CDB___db_byteswap __P((DB_ENV *, db_pgno_t, PAGE *, size_t, int));
170 */
171 int
CDB___db_byteswap(dbenv,pg,h,pagesize,pgin)172 CDB___db_byteswap(dbenv, pg, h, pagesize, pgin)
173 DB_ENV *dbenv;
174 db_pgno_t pg;
175 PAGE *h;
176 size_t pagesize;
177 int pgin;
178 {
179 if(pg){}
180 BINTERNAL *bi;
181 BKEYDATA *bk;
182 BOVERFLOW *bo;
183 RINTERNAL *ri;
184 db_indx_t i, len, tmp;
185 u_int8_t *p, *end;
186
187 COMPQUIET(pg, 0);
188
189 if (pgin) {
190 M_32_SWAP(h->lsn.file);
191 M_32_SWAP(h->lsn.offset);
192 M_32_SWAP(h->pgno);
193 M_32_SWAP(h->prev_pgno);
194 M_32_SWAP(h->next_pgno);
195 M_16_SWAP(h->entries);
196 M_16_SWAP(h->hf_offset);
197 }
198
199 switch (TYPE(h)) {
200 case P_HASH:
201 for (i = 0; i < NUM_ENT(h); i++) {
202 if (pgin)
203 M_16_SWAP(h->inp[i]);
204
205 switch (HPAGE_TYPE(h, i)) {
206 case H_KEYDATA:
207 break;
208 case H_DUPLICATE:
209 len = LEN_HKEYDATA(h, pagesize, i);
210 p = HKEYDATA_DATA(P_ENTRY(h, i));
211 for (end = p + len; p < end;) {
212 if (pgin) {
213 P_16_SWAP(p);
214 memcpy(&tmp,
215 p, sizeof(db_indx_t));
216 p += sizeof(db_indx_t);
217 } else {
218 memcpy(&tmp,
219 p, sizeof(db_indx_t));
220 SWAP16(p);
221 }
222 p += tmp;
223 SWAP16(p);
224 }
225 break;
226 case H_OFFDUP:
227 p = HOFFPAGE_PGNO(P_ENTRY(h, i));
228 SWAP32(p); /* pgno */
229 break;
230 case H_OFFPAGE:
231 p = HOFFPAGE_PGNO(P_ENTRY(h, i));
232 SWAP32(p); /* pgno */
233 SWAP32(p); /* tlen */
234 break;
235 }
236
237 }
238
239 /*
240 * The offsets in the inp array are used to determine
241 * the size of entries on a page; therefore they
242 * cannot be converted until we've done all the
243 * entries.
244 */
245 if (!pgin)
246 for (i = 0; i < NUM_ENT(h); i++)
247 M_16_SWAP(h->inp[i]);
248 break;
249 case P_LBTREE:
250 case P_LDUP:
251 case P_LRECNO:
252 for (i = 0; i < NUM_ENT(h); i++) {
253 if (pgin)
254 M_16_SWAP(h->inp[i]);
255
256 /*
257 * In the case of on-page duplicates, key information
258 * should only be swapped once.
259 */
260 if (TYPE(h) == P_LBTREE && i > 1) {
261 if (pgin) {
262 if (h->inp[i] == h->inp[i - 2])
263 continue;
264 } else {
265 M_16_SWAP(h->inp[i]);
266 if (h->inp[i] == h->inp[i - 2])
267 continue;
268 M_16_SWAP(h->inp[i]);
269 }
270 }
271
272 bk = GET_BKEYDATA(h, i);
273 switch (B_TYPE(bk->type)) {
274 case B_KEYDATA:
275 M_16_SWAP(bk->len);
276 break;
277 case B_DUPLICATE:
278 case B_OVERFLOW:
279 bo = (BOVERFLOW *)bk;
280 M_32_SWAP(bo->pgno);
281 M_32_SWAP(bo->tlen);
282 break;
283 }
284
285 if (!pgin)
286 M_16_SWAP(h->inp[i]);
287 }
288 break;
289 case P_IBTREE:
290 for (i = 0; i < NUM_ENT(h); i++) {
291 if (pgin)
292 M_16_SWAP(h->inp[i]);
293
294 bi = GET_BINTERNAL(h, i);
295 M_16_SWAP(bi->len);
296 M_32_SWAP(bi->pgno);
297 M_32_SWAP(bi->nrecs);
298
299 switch (B_TYPE(bi->type)) {
300 case B_KEYDATA:
301 break;
302 case B_DUPLICATE:
303 case B_OVERFLOW:
304 bo = (BOVERFLOW *)bi->data;
305 M_32_SWAP(bo->pgno);
306 M_32_SWAP(bo->tlen);
307 break;
308 }
309
310 if (!pgin)
311 M_16_SWAP(h->inp[i]);
312 }
313 break;
314 case P_IRECNO:
315 for (i = 0; i < NUM_ENT(h); i++) {
316 if (pgin)
317 M_16_SWAP(h->inp[i]);
318
319 ri = GET_RINTERNAL(h, i);
320 M_32_SWAP(ri->pgno);
321 M_32_SWAP(ri->nrecs);
322
323 if (!pgin)
324 M_16_SWAP(h->inp[i]);
325 }
326 break;
327 case P_OVERFLOW:
328 case P_INVALID:
329 /* Nothing to do. */
330 break;
331 default:
332 return (CDB___db_unknown_type(dbenv, "CDB___db_byteswap", h->type));
333 }
334
335 if (!pgin) {
336 /* Swap the header information. */
337 M_32_SWAP(h->lsn.file);
338 M_32_SWAP(h->lsn.offset);
339 M_32_SWAP(h->pgno);
340 M_32_SWAP(h->prev_pgno);
341 M_32_SWAP(h->next_pgno);
342 M_16_SWAP(h->entries);
343 M_16_SWAP(h->hf_offset);
344 }
345 return (0);
346 }
347