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

bt_method.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1999-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: bt_method.c,v 12.2 2005/06/16 20:20:16 bostic Exp $
00008  */
00009 
00010 #include "db_config.h"
00011 
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014 #endif
00015 
00016 #include "db_int.h"
00017 #include "dbinc/db_page.h"
00018 #include "dbinc/btree.h"
00019 #include "dbinc/qam.h"
00020 
00021 static int __bam_set_bt_minkey __P((DB *, u_int32_t));
00022 static int __bam_set_bt_prefix
00023                __P((DB *, size_t(*)(DB *, const DBT *, const DBT *)));
00024 static int __ram_get_re_delim __P((DB *, int *));
00025 static int __ram_set_re_delim __P((DB *, int));
00026 static int __ram_set_re_len __P((DB *, u_int32_t));
00027 static int __ram_set_re_pad __P((DB *, int));
00028 static int __ram_get_re_source __P((DB *, const char **));
00029 static int __ram_set_re_source __P((DB *, const char *));
00030 
00031 /*
00032  * __bam_db_create --
00033  *      Btree specific initialization of the DB structure.
00034  *
00035  * PUBLIC: int __bam_db_create __P((DB *));
00036  */
00037 int
00038 __bam_db_create(dbp)
00039         DB *dbp;
00040 {
00041         BTREE *t;
00042         int ret;
00043 
00044         /* Allocate and initialize the private btree structure. */
00045         if ((ret = __os_calloc(dbp->dbenv, 1, sizeof(BTREE), &t)) != 0)
00046                 return (ret);
00047         dbp->bt_internal = t;
00048 
00049         t->bt_minkey = DEFMINKEYPAGE;           /* Btree */
00050         t->bt_compare = __bam_defcmp;
00051         t->bt_prefix = __bam_defpfx;
00052 
00053         dbp->set_bt_compare = __bam_set_bt_compare;
00054         dbp->get_bt_minkey = __bam_get_bt_minkey;
00055         dbp->set_bt_minkey = __bam_set_bt_minkey;
00056         dbp->set_bt_prefix = __bam_set_bt_prefix;
00057 
00058         t->re_pad = ' ';                        /* Recno */
00059         t->re_delim = '\n';
00060         t->re_eof = 1;
00061 
00062         dbp->get_re_delim = __ram_get_re_delim;
00063         dbp->set_re_delim = __ram_set_re_delim;
00064         dbp->get_re_len = __ram_get_re_len;
00065         dbp->set_re_len = __ram_set_re_len;
00066         dbp->get_re_pad = __ram_get_re_pad;
00067         dbp->set_re_pad = __ram_set_re_pad;
00068         dbp->get_re_source = __ram_get_re_source;
00069         dbp->set_re_source = __ram_set_re_source;
00070 
00071         return (0);
00072 }
00073 
00074 /*
00075  * __bam_db_close --
00076  *      Btree specific discard of the DB structure.
00077  *
00078  * PUBLIC: int __bam_db_close __P((DB *));
00079  */
00080 int
00081 __bam_db_close(dbp)
00082         DB *dbp;
00083 {
00084         BTREE *t;
00085 
00086         if ((t = dbp->bt_internal) == NULL)
00087                 return (0);
00088                                                 /* Recno */
00089         /* Close any backing source file descriptor. */
00090         if (t->re_fp != NULL)
00091                 (void)fclose(t->re_fp);
00092 
00093         /* Free any backing source file name. */
00094         if (t->re_source != NULL)
00095                 __os_free(dbp->dbenv, t->re_source);
00096 
00097         __os_free(dbp->dbenv, t);
00098         dbp->bt_internal = NULL;
00099 
00100         return (0);
00101 }
00102 
00103 /*
00104  * __bam_map_flags --
00105  *      Map Btree specific flags from public to the internal values.
00106  *
00107  * PUBLIC: void __bam_map_flags __P((DB *, u_int32_t *, u_int32_t *));
00108  */
00109 void
00110 __bam_map_flags(dbp, inflagsp, outflagsp)
00111         DB *dbp;
00112         u_int32_t *inflagsp, *outflagsp;
00113 {
00114         COMPQUIET(dbp, NULL);
00115 
00116         if (FLD_ISSET(*inflagsp, DB_DUP)) {
00117                 FLD_SET(*outflagsp, DB_AM_DUP);
00118                 FLD_CLR(*inflagsp, DB_DUP);
00119         }
00120         if (FLD_ISSET(*inflagsp, DB_DUPSORT)) {
00121                 FLD_SET(*outflagsp, DB_AM_DUP | DB_AM_DUPSORT);
00122                 FLD_CLR(*inflagsp, DB_DUPSORT);
00123         }
00124         if (FLD_ISSET(*inflagsp, DB_RECNUM)) {
00125                 FLD_SET(*outflagsp, DB_AM_RECNUM);
00126                 FLD_CLR(*inflagsp, DB_RECNUM);
00127         }
00128         if (FLD_ISSET(*inflagsp, DB_REVSPLITOFF)) {
00129                 FLD_SET(*outflagsp, DB_AM_REVSPLITOFF);
00130                 FLD_CLR(*inflagsp, DB_REVSPLITOFF);
00131         }
00132 }
00133 
00134 /*
00135  * __bam_set_flags --
00136  *      Set Btree specific flags.
00137  *
00138  * PUBLIC: int __bam_set_flags __P((DB *, u_int32_t *flagsp));
00139  */
00140 int
00141 __bam_set_flags(dbp, flagsp)
00142         DB *dbp;
00143         u_int32_t *flagsp;
00144 {
00145         u_int32_t flags;
00146 
00147         flags = *flagsp;
00148         if (LF_ISSET(DB_DUP | DB_DUPSORT | DB_RECNUM | DB_REVSPLITOFF))
00149                 DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_flags");
00150 
00151         /*
00152          * The DB_DUP and DB_DUPSORT flags are shared by the Hash
00153          * and Btree access methods.
00154          */
00155         if (LF_ISSET(DB_DUP | DB_DUPSORT))
00156                 DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH);
00157 
00158         if (LF_ISSET(DB_RECNUM | DB_REVSPLITOFF))
00159                 DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
00160 
00161         /* DB_DUP/DB_DUPSORT is incompatible with DB_RECNUM. */
00162         if (LF_ISSET(DB_DUP | DB_DUPSORT) && F_ISSET(dbp, DB_AM_RECNUM))
00163                 goto incompat;
00164 
00165         /* DB_RECNUM is incompatible with DB_DUP/DB_DUPSORT. */
00166         if (LF_ISSET(DB_RECNUM) && F_ISSET(dbp, DB_AM_DUP))
00167                 goto incompat;
00168 
00169         if (LF_ISSET(DB_DUPSORT) && dbp->dup_compare == NULL)
00170                 dbp->dup_compare = __bam_defcmp;
00171 
00172         __bam_map_flags(dbp, flagsp, &dbp->flags);
00173         return (0);
00174 
00175 incompat:
00176         return (__db_ferr(dbp->dbenv, "DB->set_flags", 1));
00177 }
00178 
00179 /*
00180  * __bam_set_bt_compare --
00181  *      Set the comparison function.
00182  *
00183  * PUBLIC: int __bam_set_bt_compare
00184  * PUBLIC:         __P((DB *, int (*)(DB *, const DBT *, const DBT *)));
00185  */
00186 int
00187 __bam_set_bt_compare(dbp, func)
00188         DB *dbp;
00189         int (*func) __P((DB *, const DBT *, const DBT *));
00190 {
00191         BTREE *t;
00192 
00193         DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_compare");
00194         DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
00195 
00196         t = dbp->bt_internal;
00197 
00198         /*
00199          * Can't default the prefix routine if the user supplies a comparison
00200          * routine; shortening the keys can break their comparison algorithm.
00201          */
00202         t->bt_compare = func;
00203         if (t->bt_prefix == __bam_defpfx)
00204                 t->bt_prefix = NULL;
00205 
00206         return (0);
00207 }
00208 
00209 /*
00210  * __db_get_bt_minkey --
00211  *      Get the minimum keys per page.
00212  *
00213  * PUBLIC: int __bam_get_bt_minkey __P((DB *, u_int32_t *));
00214  */
00215 int
00216 __bam_get_bt_minkey(dbp, bt_minkeyp)
00217         DB *dbp;
00218         u_int32_t *bt_minkeyp;
00219 {
00220         BTREE *t;
00221 
00222         DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
00223 
00224         t = dbp->bt_internal;
00225         *bt_minkeyp = t->bt_minkey;
00226         return (0);
00227 }
00228 
00229 /*
00230  * __bam_set_bt_minkey --
00231  *      Set the minimum keys per page.
00232  */
00233 static int
00234 __bam_set_bt_minkey(dbp, bt_minkey)
00235         DB *dbp;
00236         u_int32_t bt_minkey;
00237 {
00238         BTREE *t;
00239 
00240         DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_minkey");
00241         DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
00242 
00243         t = dbp->bt_internal;
00244 
00245         if (bt_minkey < 2) {
00246                 __db_err(dbp->dbenv, "minimum bt_minkey value is 2");
00247                 return (EINVAL);
00248         }
00249 
00250         t->bt_minkey = bt_minkey;
00251         return (0);
00252 }
00253 
00254 /*
00255  * __bam_set_bt_prefix --
00256  *      Set the prefix function.
00257  */
00258 static int
00259 __bam_set_bt_prefix(dbp, func)
00260         DB *dbp;
00261         size_t (*func) __P((DB *, const DBT *, const DBT *));
00262 {
00263         BTREE *t;
00264 
00265         DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_prefix");
00266         DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
00267 
00268         t = dbp->bt_internal;
00269 
00270         t->bt_prefix = func;
00271         return (0);
00272 }
00273 
00274 /*
00275  * __ram_map_flags --
00276  *      Map Recno specific flags from public to the internal values.
00277  *
00278  * PUBLIC: void __ram_map_flags __P((DB *, u_int32_t *, u_int32_t *));
00279  */
00280 void
00281 __ram_map_flags(dbp, inflagsp, outflagsp)
00282         DB *dbp;
00283         u_int32_t *inflagsp, *outflagsp;
00284 {
00285         COMPQUIET(dbp, NULL);
00286 
00287         if (FLD_ISSET(*inflagsp, DB_RENUMBER)) {
00288                 FLD_SET(*outflagsp, DB_AM_RENUMBER);
00289                 FLD_CLR(*inflagsp, DB_RENUMBER);
00290         }
00291         if (FLD_ISSET(*inflagsp, DB_SNAPSHOT)) {
00292                 FLD_SET(*outflagsp, DB_AM_SNAPSHOT);
00293                 FLD_CLR(*inflagsp, DB_SNAPSHOT);
00294         }
00295 }
00296 
00297 /*
00298  * __ram_set_flags --
00299  *      Set Recno specific flags.
00300  *
00301  * PUBLIC: int __ram_set_flags __P((DB *, u_int32_t *flagsp));
00302  */
00303 int
00304 __ram_set_flags(dbp, flagsp)
00305         DB *dbp;
00306         u_int32_t *flagsp;
00307 {
00308         u_int32_t flags;
00309 
00310         flags = *flagsp;
00311         if (LF_ISSET(DB_RENUMBER | DB_SNAPSHOT)) {
00312                 DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_flags");
00313                 DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
00314         }
00315 
00316         __ram_map_flags(dbp, flagsp, &dbp->flags);
00317         return (0);
00318 }
00319 
00320 /*
00321  * __db_get_re_delim --
00322  *      Get the variable-length input record delimiter.
00323  */
00324 static int
00325 __ram_get_re_delim(dbp, re_delimp)
00326         DB *dbp;
00327         int *re_delimp;
00328 {
00329         BTREE *t;
00330 
00331         DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
00332         t = dbp->bt_internal;
00333         *re_delimp = t->re_delim;
00334         return (0);
00335 }
00336 
00337 /*
00338  * __ram_set_re_delim --
00339  *      Set the variable-length input record delimiter.
00340  */
00341 static int
00342 __ram_set_re_delim(dbp, re_delim)
00343         DB *dbp;
00344         int re_delim;
00345 {
00346         BTREE *t;
00347 
00348         DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_delim");
00349         DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
00350 
00351         t = dbp->bt_internal;
00352 
00353         t->re_delim = re_delim;
00354         F_SET(dbp, DB_AM_DELIMITER);
00355 
00356         return (0);
00357 }
00358 
00359 /*
00360  * __db_get_re_len --
00361  *      Get the variable-length input record length.
00362  *
00363  * PUBLIC: int __ram_get_re_len __P((DB *, u_int32_t *));
00364  */
00365 int
00366 __ram_get_re_len(dbp, re_lenp)
00367         DB *dbp;
00368         u_int32_t *re_lenp;
00369 {
00370         BTREE *t;
00371         QUEUE *q;
00372 
00373         DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
00374 
00375         /*
00376          * This has to work for all access methods, before or after opening the
00377          * database.  When the record length is set with __ram_set_re_len, the
00378          * value in both the BTREE and QUEUE structs will be correct.
00379          * Otherwise, this only makes sense after the database in opened, in
00380          * which case we know the type.
00381          */
00382         if (dbp->type == DB_QUEUE) {
00383                 q = dbp->q_internal;
00384                 *re_lenp = q->re_len;
00385         } else {
00386                 t = dbp->bt_internal;
00387                 *re_lenp = t->re_len;
00388         }
00389 
00390         return (0);
00391 }
00392 
00393 /*
00394  * __ram_set_re_len --
00395  *      Set the variable-length input record length.
00396  */
00397 static int
00398 __ram_set_re_len(dbp, re_len)
00399         DB *dbp;
00400         u_int32_t re_len;
00401 {
00402         BTREE *t;
00403         QUEUE *q;
00404 
00405         DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_len");
00406         DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
00407 
00408         t = dbp->bt_internal;
00409         t->re_len = re_len;
00410 
00411         q = dbp->q_internal;
00412         q->re_len = re_len;
00413 
00414         F_SET(dbp, DB_AM_FIXEDLEN);
00415 
00416         return (0);
00417 }
00418 
00419 /*
00420  * __db_get_re_pad --
00421  *      Get the fixed-length record pad character.
00422  *
00423  * PUBLIC: int __ram_get_re_pad __P((DB *, int *));
00424  */
00425 int
00426 __ram_get_re_pad(dbp, re_padp)
00427         DB *dbp;
00428         int *re_padp;
00429 {
00430         BTREE *t;
00431         QUEUE *q;
00432 
00433         DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
00434 
00435         /*
00436          * This has to work for all access methods, before or after opening the
00437          * database.  When the record length is set with __ram_set_re_pad, the
00438          * value in both the BTREE and QUEUE structs will be correct.
00439          * Otherwise, this only makes sense after the database in opened, in
00440          * which case we know the type.
00441          */
00442         if (dbp->type == DB_QUEUE) {
00443                 q = dbp->q_internal;
00444                 *re_padp = q->re_pad;
00445         } else {
00446                 t = dbp->bt_internal;
00447                 *re_padp = t->re_pad;
00448         }
00449 
00450         return (0);
00451 }
00452 
00453 /*
00454  * __ram_set_re_pad --
00455  *      Set the fixed-length record pad character.
00456  */
00457 static int
00458 __ram_set_re_pad(dbp, re_pad)
00459         DB *dbp;
00460         int re_pad;
00461 {
00462         BTREE *t;
00463         QUEUE *q;
00464 
00465         DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_pad");
00466         DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
00467 
00468         t = dbp->bt_internal;
00469         t->re_pad = re_pad;
00470 
00471         q = dbp->q_internal;
00472         q->re_pad = re_pad;
00473 
00474         F_SET(dbp, DB_AM_PAD);
00475 
00476         return (0);
00477 }
00478 
00479 /*
00480  * __db_get_re_source --
00481  *      Get the backing source file name.
00482  */
00483 static int
00484 __ram_get_re_source(dbp, re_sourcep)
00485         DB *dbp;
00486         const char **re_sourcep;
00487 {
00488         BTREE *t;
00489 
00490         DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
00491 
00492         t = dbp->bt_internal;
00493         *re_sourcep = t->re_source;
00494         return (0);
00495 }
00496 
00497 /*
00498  * __ram_set_re_source --
00499  *      Set the backing source file name.
00500  */
00501 static int
00502 __ram_set_re_source(dbp, re_source)
00503         DB *dbp;
00504         const char *re_source;
00505 {
00506         BTREE *t;
00507 
00508         DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_source");
00509         DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
00510 
00511         t = dbp->bt_internal;
00512 
00513         return (__os_strdup(dbp->dbenv, re_source, &t->re_source));
00514 }

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