Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

bt_compare.c

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 }

Generated on Sun Dec 25 12:14:12 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2