00001 /*- 00002 * See the file LICENSE for redistribution information. 00003 * 00004 * Copyright (c) 1996-2005 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 * This code is derived from software contributed to Berkeley by 00016 * Mike Olson. 00017 * 00018 * Redistribution and use in source and binary forms, with or without 00019 * modification, are permitted provided that the following conditions 00020 * are met: 00021 * 1. Redistributions of source code must retain the above copyright 00022 * notice, this list of conditions and the following disclaimer. 00023 * 2. Redistributions in binary form must reproduce the above copyright 00024 * notice, this list of conditions and the following disclaimer in the 00025 * documentation and/or other materials provided with the distribution. 00026 * 3. Neither the name of the University nor the names of its contributors 00027 * may be used to endorse or promote products derived from this software 00028 * without specific prior written permission. 00029 * 00030 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 00031 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00032 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00033 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 00034 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00035 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00036 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00037 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00038 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00039 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00040 * SUCH DAMAGE. 00041 * 00042 * $Id: bt_compare.c,v 12.1 2005/06/16 20:20:13 bostic Exp $ 00043 */ 00044 00045 #include "db_config.h" 00046 00047 #ifndef NO_SYSTEM_INCLUDES 00048 #include <sys/types.h> 00049 #endif 00050 00051 #include "db_int.h" 00052 #include "dbinc/db_page.h" 00053 #include "dbinc/btree.h" 00054 00055 /* 00056 * __bam_cmp -- 00057 * Compare a key to a given record. 00058 * 00059 * PUBLIC: int __bam_cmp __P((DB *, const DBT *, PAGE *, 00060 * PUBLIC: u_int32_t, int (*)(DB *, const DBT *, const DBT *), int *)); 00061 */ 00062 int 00063 __bam_cmp(dbp, dbt, h, indx, func, cmpp) 00064 DB *dbp; 00065 const DBT *dbt; 00066 PAGE *h; 00067 u_int32_t indx; 00068 int (*func)__P((DB *, const DBT *, const DBT *)); 00069 int *cmpp; 00070 { 00071 BINTERNAL *bi; 00072 BKEYDATA *bk; 00073 BOVERFLOW *bo; 00074 DBT pg_dbt; 00075 00076 /* 00077 * Returns: 00078 * < 0 if dbt is < page record 00079 * = 0 if dbt is = page record 00080 * > 0 if dbt is > page record 00081 * 00082 * !!! 00083 * We do not clear the pg_dbt DBT even though it's likely to contain 00084 * random bits. That should be okay, because the app's comparison 00085 * routine had better not be looking at fields other than data/size. 00086 * We don't clear it because we go through this path a lot and it's 00087 * expensive. 00088 */ 00089 switch (TYPE(h)) { 00090 case P_LBTREE: 00091 case P_LDUP: 00092 case P_LRECNO: 00093 bk = GET_BKEYDATA(dbp, h, indx); 00094 if (B_TYPE(bk->type) == B_OVERFLOW) 00095 bo = (BOVERFLOW *)bk; 00096 else { 00097 pg_dbt.data = bk->data; 00098 pg_dbt.size = bk->len; 00099 *cmpp = func(dbp, dbt, &pg_dbt); 00100 return (0); 00101 } 00102 break; 00103 case P_IBTREE: 00104 /* 00105 * The following code guarantees that the left-most key on an 00106 * internal page at any place in the tree sorts less than any 00107 * user-specified key. The reason is that if we have reached 00108 * this internal page, we know the user key must sort greater 00109 * than the key we're storing for this page in any internal 00110 * pages at levels above us in the tree. It then follows that 00111 * any user-specified key cannot sort less than the first page 00112 * which we reference, and so there's no reason to call the 00113 * comparison routine. While this may save us a comparison 00114 * routine call or two, the real reason for this is because 00115 * we don't maintain a copy of the smallest key in the tree, 00116 * so that we don't have to update all the levels of the tree 00117 * should the application store a new smallest key. And, so, 00118 * we may not have a key to compare, which makes doing the 00119 * comparison difficult and error prone. 00120 */ 00121 if (indx == 0) { 00122 *cmpp = 1; 00123 return (0); 00124 } 00125 00126 bi = GET_BINTERNAL(dbp, h, indx); 00127 if (B_TYPE(bi->type) == B_OVERFLOW) 00128 bo = (BOVERFLOW *)(bi->data); 00129 else { 00130 pg_dbt.data = bi->data; 00131 pg_dbt.size = bi->len; 00132 *cmpp = func(dbp, dbt, &pg_dbt); 00133 return (0); 00134 } 00135 break; 00136 default: 00137 return (__db_pgfmt(dbp->dbenv, PGNO(h))); 00138 } 00139 00140 /* 00141 * Overflow. 00142 */ 00143 return (__db_moff(dbp, dbt, 00144 bo->pgno, bo->tlen, func == __bam_defcmp ? NULL : func, cmpp)); 00145 } 00146 00147 /* 00148 * __bam_defcmp -- 00149 * Default comparison routine. 00150 * 00151 * PUBLIC: int __bam_defcmp __P((DB *, const DBT *, const DBT *)); 00152 */ 00153 int 00154 __bam_defcmp(dbp, a, b) 00155 DB *dbp; 00156 const DBT *a, *b; 00157 { 00158 size_t len; 00159 u_int8_t *p1, *p2; 00160 00161 COMPQUIET(dbp, NULL); 00162 00163 /* 00164 * Returns: 00165 * < 0 if a is < b 00166 * = 0 if a is = b 00167 * > 0 if a is > b 00168 * 00169 * XXX 00170 * If a size_t doesn't fit into a long, or if the difference between 00171 * any two characters doesn't fit into an int, this routine can lose. 00172 * What we need is a signed integral type that's guaranteed to be at 00173 * least as large as a size_t, and there is no such thing. 00174 */ 00175 len = a->size > b->size ? b->size : a->size; 00176 for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2) 00177 if (*p1 != *p2) 00178 return ((long)*p1 - (long)*p2); 00179 return ((long)a->size - (long)b->size); 00180 } 00181 00182 /* 00183 * __bam_defpfx -- 00184 * Default prefix routine. 00185 * 00186 * PUBLIC: size_t __bam_defpfx __P((DB *, const DBT *, const DBT *)); 00187 */ 00188 size_t 00189 __bam_defpfx(dbp, a, b) 00190 DB *dbp; 00191 const DBT *a, *b; 00192 { 00193 size_t cnt, len; 00194 u_int8_t *p1, *p2; 00195 00196 COMPQUIET(dbp, NULL); 00197 00198 cnt = 1; 00199 len = a->size > b->size ? b->size : a->size; 00200 for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt) 00201 if (*p1 != *p2) 00202 return (cnt); 00203 00204 /* 00205 * They match up to the smaller of the two sizes. 00206 * Collate the longer after the shorter. 00207 */ 00208 if (a->size < b->size) 00209 return (a->size + 1); 00210 if (b->size < a->size) 00211 return (b->size + 1); 00212 return (b->size); 00213 }