00001 /*- 00002 * See the file LICENSE for redistribution information. 00003 * 00004 * Copyright (c) 1996, 1997, 1998, 1999, 2000 00005 * Sleepycat Software. All rights reserved. 00006 */ 00007 /* 00008 * Copyright (c) 1990, 1993, 1994, 1995, 1996 00009 * Keith Bostic. All rights reserved. 00010 */ 00011 /* 00012 * Copyright (c) 1990, 1993, 1994, 1995 00013 * The Regents of the University of California. All rights reserved. 00014 * 00015 * Redistribution and use in source and binary forms, with or without 00016 * modification, are permitted provided that the following conditions 00017 * are met: 00018 * 1. Redistributions of source code must retain the above copyright 00019 * notice, this list of conditions and the following disclaimer. 00020 * 2. Redistributions in binary form must reproduce the above copyright 00021 * notice, this list of conditions and the following disclaimer in the 00022 * documentation and/or other materials provided with the distribution. 00023 * 3. Neither the name of the University nor the names of its contributors 00024 * may be used to endorse or promote products derived from this software 00025 * without specific prior written permission. 00026 * 00027 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 00028 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00029 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00030 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 00031 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00032 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00033 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00034 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00035 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00036 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00037 * SUCH DAMAGE. 00038 */ 00039 00040 #include "config.h" 00041 00042 #ifndef lint 00043 static const char revid[] = "$Id: db__conv_8c-source.html,v 1.1 2008年06月08日 10:17:24 sebdiaz Exp $"; 00044 #endif /* not lint */ 00045 00046 #ifndef NO_SYSTEM_INCLUDES 00047 #include <sys/types.h> 00048 00049 #include <errno.h> 00050 #include <string.h> 00051 #endif 00052 00053 #include "db_int.h" 00054 #include "db_page.h" 00055 #include "db_swap.h" 00056 #include "db_am.h" 00057 #include "btree.h" 00058 #include "hash.h" 00059 #include "qam.h" 00060 00061 /* 00062 * CDB___db_pgin -- 00063 * Primary page-swap routine. 00064 * 00065 * PUBLIC: int CDB___db_pgin __P((DB_ENV *, db_pgno_t, void *, DBT *)); 00066 */ 00067 int 00068 CDB___db_pgin(dbenv, pg, pp, cookie) 00069 DB_ENV *dbenv; 00070 db_pgno_t pg; 00071 void *pp; 00072 DBT *cookie; 00073 { 00074 DB_PGINFO *pginfo; 00075 00076 pginfo = (DB_PGINFO *)cookie->data; 00077 00078 switch (TYPE(pp)) { 00079 case P_HASH: 00080 case P_HASHMETA: 00081 case P_INVALID: 00082 return (CDB___ham_pgin(dbenv, pg, pp, cookie)); 00083 case P_BTREEMETA: 00084 case P_IBTREE: 00085 case P_IRECNO: 00086 case P_LBTREE: 00087 case P_LDUP: 00088 case P_LRECNO: 00089 case P_OVERFLOW: 00090 return (CDB___bam_pgin(dbenv, pg, pp, cookie)); 00091 case P_QAMMETA: 00092 case P_QAMDATA: 00093 return (CDB___qam_pgin_out(dbenv, pg, pp, cookie)); 00094 default: 00095 break; 00096 } 00097 return (CDB___db_unknown_type(dbenv, "CDB___db_pgin", ((PAGE *)pp)->type)); 00098 } 00099 00100 /* 00101 * CDB___db_pgout -- 00102 * Primary page-swap routine. 00103 * 00104 * PUBLIC: int CDB___db_pgout __P((DB_ENV *, db_pgno_t, void *, DBT *)); 00105 */ 00106 int 00107 CDB___db_pgout(dbenv, pg, pp, cookie) 00108 DB_ENV *dbenv; 00109 db_pgno_t pg; 00110 void *pp; 00111 DBT *cookie; 00112 { 00113 DB_PGINFO *pginfo; 00114 00115 pginfo = (DB_PGINFO *)cookie->data; 00116 00117 switch (TYPE(pp)) { 00118 case P_HASH: 00119 case P_HASHMETA: 00120 case P_INVALID: 00121 return (CDB___ham_pgout(dbenv, pg, pp, cookie)); 00122 case P_BTREEMETA: 00123 case P_IBTREE: 00124 case P_IRECNO: 00125 case P_LBTREE: 00126 case P_LDUP: 00127 case P_LRECNO: 00128 case P_OVERFLOW: 00129 return (CDB___bam_pgout(dbenv, pg, pp, cookie)); 00130 case P_QAMMETA: 00131 case P_QAMDATA: 00132 return (CDB___qam_pgin_out(dbenv, pg, pp, cookie)); 00133 default: 00134 break; 00135 } 00136 return (CDB___db_unknown_type(dbenv, "CDB___db_pgout", ((PAGE *)pp)->type)); 00137 } 00138 00139 /* 00140 * CDB___db_metaswap -- 00141 * Byteswap the common part of the meta-data page. 00142 * 00143 * PUBLIC: void CDB___db_metaswap __P((PAGE *)); 00144 */ 00145 void 00146 CDB___db_metaswap(pg) 00147 PAGE *pg; 00148 { 00149 u_int8_t *p; 00150 00151 p = (u_int8_t *)pg; 00152 00153 /* Swap the meta-data information. */ 00154 SWAP32(p); /* lsn.file */ 00155 SWAP32(p); /* lsn.offset */ 00156 SWAP32(p); /* pgno */ 00157 SWAP32(p); /* magic */ 00158 SWAP32(p); /* version */ 00159 SWAP32(p); /* pagesize */ 00160 p += 4; /* unused, page type, unused, unused */ 00161 SWAP32(p); /* free */ 00162 SWAP32(p); /* alloc_lsn part 1 */ 00163 SWAP32(p); /* alloc_lsn part 2 */ 00164 SWAP32(p); /* cached key count */ 00165 SWAP32(p); /* cached record count */ 00166 SWAP32(p); /* flags */ 00167 } 00168 00169 /* 00170 * CDB___db_byteswap -- 00171 * Byteswap a page. 00172 * 00173 * PUBLIC: int CDB___db_byteswap __P((DB_ENV *, db_pgno_t, PAGE *, size_t, int)); 00174 */ 00175 int 00176 CDB___db_byteswap(dbenv, pg, h, pagesize, pgin) 00177 DB_ENV *dbenv; 00178 db_pgno_t pg; 00179 PAGE *h; 00180 size_t pagesize; 00181 int pgin; 00182 { 00183 BINTERNAL *bi; 00184 BKEYDATA *bk; 00185 BOVERFLOW *bo; 00186 RINTERNAL *ri; 00187 db_indx_t i, len, tmp; 00188 u_int8_t *p, *end; 00189 00190 COMPQUIET(pg, 0); 00191 00192 if (pgin) { 00193 M_32_SWAP(h->lsn.file); 00194 M_32_SWAP(h->lsn.offset); 00195 M_32_SWAP(h->pgno); 00196 M_32_SWAP(h->prev_pgno); 00197 M_32_SWAP(h->next_pgno); 00198 M_16_SWAP(h->entries); 00199 M_16_SWAP(h->hf_offset); 00200 } 00201 00202 switch (TYPE(h)) { 00203 case P_HASH: 00204 for (i = 0; i < NUM_ENT(h); i++) { 00205 if (pgin) 00206 M_16_SWAP(h->inp[i]); 00207 00208 switch (HPAGE_TYPE(h, i)) { 00209 case H_KEYDATA: 00210 break; 00211 case H_DUPLICATE: 00212 len = LEN_HKEYDATA(h, pagesize, i); 00213 p = HKEYDATA_DATA(P_ENTRY(h, i)); 00214 for (end = p + len; p < end;) { 00215 if (pgin) { 00216 P_16_SWAP(p); 00217 memcpy(&tmp, 00218 p, sizeof(db_indx_t)); 00219 p += sizeof(db_indx_t); 00220 } else { 00221 memcpy(&tmp, 00222 p, sizeof(db_indx_t)); 00223 SWAP16(p); 00224 } 00225 p += tmp; 00226 SWAP16(p); 00227 } 00228 break; 00229 case H_OFFDUP: 00230 p = HOFFPAGE_PGNO(P_ENTRY(h, i)); 00231 SWAP32(p); /* pgno */ 00232 break; 00233 case H_OFFPAGE: 00234 p = HOFFPAGE_PGNO(P_ENTRY(h, i)); 00235 SWAP32(p); /* pgno */ 00236 SWAP32(p); /* tlen */ 00237 break; 00238 } 00239 00240 } 00241 00242 /* 00243 * The offsets in the inp array are used to determine 00244 * the size of entries on a page; therefore they 00245 * cannot be converted until we've done all the 00246 * entries. 00247 */ 00248 if (!pgin) 00249 for (i = 0; i < NUM_ENT(h); i++) 00250 M_16_SWAP(h->inp[i]); 00251 break; 00252 case P_LBTREE: 00253 case P_LDUP: 00254 case P_LRECNO: 00255 for (i = 0; i < NUM_ENT(h); i++) { 00256 if (pgin) 00257 M_16_SWAP(h->inp[i]); 00258 00259 /* 00260 * In the case of on-page duplicates, key information 00261 * should only be swapped once. 00262 */ 00263 if (TYPE(h) == P_LBTREE && i > 1) { 00264 if (pgin) { 00265 if (h->inp[i] == h->inp[i - 2]) 00266 continue; 00267 } else { 00268 M_16_SWAP(h->inp[i]); 00269 if (h->inp[i] == h->inp[i - 2]) 00270 continue; 00271 M_16_SWAP(h->inp[i]); 00272 } 00273 } 00274 00275 bk = GET_BKEYDATA(h, i); 00276 switch (B_TYPE(bk->type)) { 00277 case B_KEYDATA: 00278 M_16_SWAP(bk->len); 00279 break; 00280 case B_DUPLICATE: 00281 case B_OVERFLOW: 00282 bo = (BOVERFLOW *)bk; 00283 M_32_SWAP(bo->pgno); 00284 M_32_SWAP(bo->tlen); 00285 break; 00286 } 00287 00288 if (!pgin) 00289 M_16_SWAP(h->inp[i]); 00290 } 00291 break; 00292 case P_IBTREE: 00293 for (i = 0; i < NUM_ENT(h); i++) { 00294 if (pgin) 00295 M_16_SWAP(h->inp[i]); 00296 00297 bi = GET_BINTERNAL(h, i); 00298 M_16_SWAP(bi->len); 00299 M_32_SWAP(bi->pgno); 00300 M_32_SWAP(bi->nrecs); 00301 00302 switch (B_TYPE(bi->type)) { 00303 case B_KEYDATA: 00304 break; 00305 case B_DUPLICATE: 00306 case B_OVERFLOW: 00307 bo = (BOVERFLOW *)bi->data; 00308 M_32_SWAP(bo->pgno); 00309 M_32_SWAP(bo->tlen); 00310 break; 00311 } 00312 00313 if (!pgin) 00314 M_16_SWAP(h->inp[i]); 00315 } 00316 break; 00317 case P_IRECNO: 00318 for (i = 0; i < NUM_ENT(h); i++) { 00319 if (pgin) 00320 M_16_SWAP(h->inp[i]); 00321 00322 ri = GET_RINTERNAL(h, i); 00323 M_32_SWAP(ri->pgno); 00324 M_32_SWAP(ri->nrecs); 00325 00326 if (!pgin) 00327 M_16_SWAP(h->inp[i]); 00328 } 00329 break; 00330 case P_OVERFLOW: 00331 case P_INVALID: 00332 /* Nothing to do. */ 00333 break; 00334 default: 00335 return (CDB___db_unknown_type(dbenv, "CDB___db_byteswap", h->type)); 00336 } 00337 00338 if (!pgin) { 00339 /* Swap the header information. */ 00340 M_32_SWAP(h->lsn.file); 00341 M_32_SWAP(h->lsn.offset); 00342 M_32_SWAP(h->pgno); 00343 M_32_SWAP(h->prev_pgno); 00344 M_32_SWAP(h->next_pgno); 00345 M_16_SWAP(h->entries); 00346 M_16_SWAP(h->hf_offset); 00347 } 00348 return (0); 00349 }