00001 /*- 00002 * See the file LICENSE for redistribution information. 00003 * 00004 * Copyright (c) 1999, 2000 00005 * Sleepycat Software. All rights reserved. 00006 */ 00007 00008 #include "config.h" 00009 00010 #ifndef lint 00011 static const char revid[] = "$Id: bt__method_8c-source.html,v 1.1 2008年06月08日 10:13:36 sebdiaz Exp $"; 00012 #endif /* not lint */ 00013 00014 #ifndef NO_SYSTEM_INCLUDES 00015 #include <sys/types.h> 00016 00017 #include <errno.h> 00018 #endif 00019 00020 #include "db_int.h" 00021 #include "db_page.h" 00022 #include "btree.h" 00023 #include "qam.h" 00024 00025 static int __bam_set_bt_compare __P((DB *, int (*)(const DBT *, const DBT *))); 00026 static int __bam_set_bt_maxkey __P((DB *, u_int32_t)); 00027 static int __bam_set_bt_minkey __P((DB *, u_int32_t)); 00028 static int __bam_set_bt_prefix __P((DB *, size_t(*)(const DBT *, const DBT *))); 00029 static int __ram_set_re_delim __P((DB *, int)); 00030 static int __ram_set_re_len __P((DB *, u_int32_t)); 00031 static int __ram_set_re_pad __P((DB *, int)); 00032 static int __ram_set_re_source __P((DB *, const char *)); 00033 00034 /* 00035 * CDB___bam_db_create -- 00036 * Btree specific initialization of the DB structure. 00037 * 00038 * PUBLIC: int CDB___bam_db_create __P((DB *)); 00039 */ 00040 int 00041 CDB___bam_db_create(dbp) 00042 DB *dbp; 00043 { 00044 BTREE *t; 00045 int ret; 00046 00047 /* Allocate and initialize the private btree structure. */ 00048 if ((ret = CDB___os_calloc(dbp->dbenv, 1, sizeof(BTREE), &t)) != 0) 00049 return (ret); 00050 dbp->bt_internal = t; 00051 00052 t->bt_minkey = DEFMINKEYPAGE; /* Btree */ 00053 t->bt_compare = CDB___bam_defcmp; 00054 t->bt_prefix = CDB___bam_defpfx; 00055 00056 dbp->set_bt_compare = __bam_set_bt_compare; 00057 dbp->set_bt_maxkey = __bam_set_bt_maxkey; 00058 dbp->set_bt_minkey = __bam_set_bt_minkey; 00059 dbp->set_bt_prefix = __bam_set_bt_prefix; 00060 00061 t->re_delim = '\n'; /* Recno */ 00062 t->re_pad = ' '; 00063 00064 dbp->set_re_delim = __ram_set_re_delim; 00065 dbp->set_re_len = __ram_set_re_len; 00066 dbp->set_re_pad = __ram_set_re_pad; 00067 dbp->set_re_source = __ram_set_re_source; 00068 00069 return (0); 00070 } 00071 00072 /* 00073 * CDB___bam_db_close -- 00074 * Btree specific discard of the DB structure. 00075 * 00076 * PUBLIC: int CDB___bam_db_close __P((DB *)); 00077 */ 00078 int 00079 CDB___bam_db_close(dbp) 00080 DB *dbp; 00081 { 00082 BTREE *t; 00083 00084 t = dbp->bt_internal; 00085 /* Recno */ 00086 /* Close any underlying mmap region. */ 00087 if (t->re_smap != NULL) 00088 (void)CDB___os_unmapfile(dbp->dbenv, t->re_smap, t->re_msize); 00089 00090 /* Close any backing source file descriptor. */ 00091 if (F_ISSET(&t->re_fh, DB_FH_VALID)) 00092 (void)CDB___os_closehandle(&t->re_fh); 00093 00094 /* Free any backing source file name. */ 00095 if (t->re_source != NULL) 00096 CDB___os_freestr(t->re_source); 00097 00098 CDB___os_free(t, sizeof(BTREE)); 00099 dbp->bt_internal = NULL; 00100 00101 return (0); 00102 } 00103 00104 /* 00105 * CDB___bam_set_flags -- 00106 * Set Btree specific flags. 00107 * 00108 * PUBLIC: int CDB___bam_set_flags __P((DB *, u_int32_t *flagsp)); 00109 */ 00110 int 00111 CDB___bam_set_flags(dbp, flagsp) 00112 DB *dbp; 00113 u_int32_t *flagsp; 00114 { 00115 u_int32_t flags; 00116 00117 flags = *flagsp; 00118 if (LF_ISSET(DB_DUP | DB_DUPSORT | DB_RECNUM | DB_REVSPLITOFF)) { 00119 DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_flags"); 00120 00121 /* 00122 * The DB_DUP and DB_DUPSORT flags are shared by the Hash 00123 * and Btree access methods. 00124 */ 00125 if (LF_ISSET(DB_DUP | DB_DUPSORT)) 00126 DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH); 00127 00128 if (LF_ISSET(DB_RECNUM | DB_REVSPLITOFF)) 00129 DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); 00130 00131 if (LF_ISSET(DB_DUP | DB_DUPSORT)) { 00132 /* DB_DUP/DB_DUPSORT is incompatible with DB_RECNUM. */ 00133 if (F_ISSET(dbp, DB_BT_RECNUM)) 00134 goto incompat; 00135 00136 if (LF_ISSET(DB_DUPSORT)) { 00137 if (dbp->dup_compare == NULL) 00138 dbp->dup_compare = CDB___bam_defcmp; 00139 F_SET(dbp, DB_AM_DUPSORT); 00140 } 00141 00142 F_SET(dbp, DB_AM_DUP); 00143 LF_CLR(DB_DUP | DB_DUPSORT); 00144 } 00145 00146 if (LF_ISSET(DB_RECNUM)) { 00147 /* DB_RECNUM is incompatible with DB_DUP/DB_DUPSORT. */ 00148 if (F_ISSET(dbp, DB_AM_DUP)) 00149 goto incompat; 00150 00151 F_SET(dbp, DB_BT_RECNUM); 00152 LF_CLR(DB_RECNUM); 00153 } 00154 00155 if (LF_ISSET(DB_REVSPLITOFF)) { 00156 F_SET(dbp, DB_BT_REVSPLIT); 00157 LF_CLR(DB_REVSPLITOFF); 00158 } 00159 00160 *flagsp = flags; 00161 } 00162 return (0); 00163 00164 incompat: 00165 return (CDB___db_ferr(dbp->dbenv, "DB->set_flags", 1)); 00166 } 00167 00168 /* 00169 * __bam_set_bt_compare -- 00170 * Set the comparison function. 00171 */ 00172 static int 00173 __bam_set_bt_compare(dbp, func) 00174 DB *dbp; 00175 int (*func) __P((const DBT *, const DBT *)); 00176 { 00177 BTREE *t; 00178 00179 DB_ILLEGAL_AFTER_OPEN(dbp, "set_bt_compare"); 00180 DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); 00181 00182 t = dbp->bt_internal; 00183 00184 /* 00185 * Can't default the prefix routine if the user supplies a comparison 00186 * routine; shortening the keys can break their comparison algorithm. 00187 */ 00188 t->bt_compare = func; 00189 if (t->bt_prefix == CDB___bam_defpfx) 00190 t->bt_prefix = NULL; 00191 00192 return (0); 00193 } 00194 00195 /* 00196 * __bam_set_bt_maxkey -- 00197 * Set the maximum keys per page. 00198 */ 00199 static int 00200 __bam_set_bt_maxkey(dbp, bt_maxkey) 00201 DB *dbp; 00202 u_int32_t bt_maxkey; 00203 { 00204 BTREE *t; 00205 00206 DB_ILLEGAL_AFTER_OPEN(dbp, "set_bt_maxkey"); 00207 DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); 00208 00209 t = dbp->bt_internal; 00210 00211 if (bt_maxkey < 1) { 00212 CDB___db_err(dbp->dbenv, "minimum bt_maxkey value is 1"); 00213 return (EINVAL); 00214 } 00215 00216 t->bt_maxkey = bt_maxkey; 00217 return (0); 00218 } 00219 00220 /* 00221 * __bam_set_bt_minkey -- 00222 * Set the minimum keys per page. 00223 */ 00224 static int 00225 __bam_set_bt_minkey(dbp, bt_minkey) 00226 DB *dbp; 00227 u_int32_t bt_minkey; 00228 { 00229 BTREE *t; 00230 00231 DB_ILLEGAL_AFTER_OPEN(dbp, "set_bt_minkey"); 00232 DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); 00233 00234 t = dbp->bt_internal; 00235 00236 if (bt_minkey < 2) { 00237 CDB___db_err(dbp->dbenv, "minimum bt_minkey value is 2"); 00238 return (EINVAL); 00239 } 00240 00241 t->bt_minkey = bt_minkey; 00242 return (0); 00243 } 00244 00245 /* 00246 * __bam_set_bt_prefix -- 00247 * Set the prefix function. 00248 */ 00249 static int 00250 __bam_set_bt_prefix(dbp, func) 00251 DB *dbp; 00252 size_t (*func) __P((const DBT *, const DBT *)); 00253 { 00254 BTREE *t; 00255 00256 DB_ILLEGAL_AFTER_OPEN(dbp, "set_bt_prefix"); 00257 DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); 00258 00259 t = dbp->bt_internal; 00260 00261 t->bt_prefix = func; 00262 return (0); 00263 } 00264 00265 /* 00266 * CDB___ram_set_flags -- 00267 * Set Recno specific flags. 00268 * 00269 * PUBLIC: int CDB___ram_set_flags __P((DB *, u_int32_t *flagsp)); 00270 */ 00271 int 00272 CDB___ram_set_flags(dbp, flagsp) 00273 DB *dbp; 00274 u_int32_t *flagsp; 00275 { 00276 u_int32_t flags; 00277 00278 flags = *flagsp; 00279 if (LF_ISSET(DB_RENUMBER | DB_SNAPSHOT)) { 00280 DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_flags"); 00281 00282 DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); 00283 00284 if (LF_ISSET(DB_RENUMBER)) { 00285 F_SET(dbp, DB_RE_RENUMBER); 00286 LF_CLR(DB_RENUMBER); 00287 } 00288 00289 if (LF_ISSET(DB_SNAPSHOT)) { 00290 F_SET(dbp, DB_RE_SNAPSHOT); 00291 LF_CLR(DB_SNAPSHOT); 00292 } 00293 00294 *flagsp = flags; 00295 } 00296 return (0); 00297 } 00298 00299 /* 00300 * __ram_set_re_delim -- 00301 * Set the variable-length input record delimiter. 00302 */ 00303 static int 00304 __ram_set_re_delim(dbp, re_delim) 00305 DB *dbp; 00306 int re_delim; 00307 { 00308 BTREE *t; 00309 00310 DB_ILLEGAL_AFTER_OPEN(dbp, "set_re_delim"); 00311 DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); 00312 00313 t = dbp->bt_internal; 00314 00315 t->re_delim = re_delim; 00316 F_SET(dbp, DB_RE_DELIMITER); 00317 00318 return (0); 00319 } 00320 00321 /* 00322 * __ram_set_re_len -- 00323 * Set the variable-length input record length. 00324 */ 00325 static int 00326 __ram_set_re_len(dbp, re_len) 00327 DB *dbp; 00328 u_int32_t re_len; 00329 { 00330 BTREE *t; 00331 QUEUE *q; 00332 00333 DB_ILLEGAL_AFTER_OPEN(dbp, "set_re_len"); 00334 DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO); 00335 00336 t = dbp->bt_internal; 00337 t->re_len = re_len; 00338 00339 q = dbp->q_internal; 00340 q->re_len = re_len; 00341 00342 F_SET(dbp, DB_RE_FIXEDLEN); 00343 00344 return (0); 00345 } 00346 00347 /* 00348 * __ram_set_re_pad -- 00349 * Set the fixed-length record pad character. 00350 */ 00351 static int 00352 __ram_set_re_pad(dbp, re_pad) 00353 DB *dbp; 00354 int re_pad; 00355 { 00356 BTREE *t; 00357 QUEUE *q; 00358 00359 DB_ILLEGAL_AFTER_OPEN(dbp, "set_re_pad"); 00360 DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO); 00361 00362 t = dbp->bt_internal; 00363 t->re_pad = re_pad; 00364 00365 q = dbp->q_internal; 00366 q->re_pad = re_pad; 00367 00368 F_SET(dbp, DB_RE_PAD); 00369 00370 return (0); 00371 } 00372 00373 /* 00374 * __ram_set_re_source -- 00375 * Set the backing source file name. 00376 */ 00377 static int 00378 __ram_set_re_source(dbp, re_source) 00379 DB *dbp; 00380 const char *re_source; 00381 { 00382 BTREE *t; 00383 00384 DB_ILLEGAL_AFTER_OPEN(dbp, "set_re_source"); 00385 DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); 00386 00387 t = dbp->bt_internal; 00388 00389 return (CDB___os_strdup(dbp->dbenv, re_source, &t->re_source)); 00390 }