00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "config.h"
00041
00042 #ifndef lint
00043 static const char revid[] = "$Id: bt__rsearch_8c-source.html,v 1.1 2008/06/08 10:13:44 sebdiaz Exp $";
00044 #endif
00045
00046 #ifndef NO_SYSTEM_INCLUDES
00047 #include <sys/types.h>
00048 #endif
00049
00050 #include "db_int.h"
00051 #include "db_page.h"
00052 #include "btree.h"
00053 #include "db_shash.h"
00054 #include "lock.h"
00055
00056
00057
00058
00059
00060
00061
00062 int
00063 CDB___bam_rsearch(dbc, recnop, flags, stop, exactp)
00064 DBC *dbc;
00065 db_recno_t *recnop;
00066 u_int32_t flags;
00067 int stop, *exactp;
00068 {
00069 BINTERNAL *bi;
00070 BTREE_CURSOR *cp;
00071 DB *dbp;
00072 DB_LOCK lock;
00073 PAGE *h;
00074 RINTERNAL *ri;
00075 db_indx_t adjust, deloffset, indx, top;
00076 db_lockmode_t lock_mode;
00077 db_pgno_t pg;
00078 db_recno_t recno, t_recno, total;
00079 int ret, stack;
00080
00081 dbp = dbc->dbp;
00082 cp = (BTREE_CURSOR *)dbc->internal;
00083
00084 BT_STK_CLR(cp);
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 pg = cp->root;
00102 stack = LF_ISSET(S_STACK);
00103 lock_mode = stack ? DB_LOCK_WRITE : DB_LOCK_READ;
00104 if ((ret = CDB___db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
00105 return (ret);
00106 if ((ret = CDB_memp_fget(dbp->mpf, &pg, 0, &h)) != 0) {
00107
00108 (void)__LPUT(dbc, lock);
00109 return (ret);
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 if (!stack &&
00121 ((LF_ISSET(S_PARENT) && (u_int8_t)(stop + 1) >= h->level) ||
00122 (LF_ISSET(S_WRITE) && h->level == LEAFLEVEL))) {
00123 (void)CDB_memp_fput(dbp->mpf, h, 0);
00124 (void)__LPUT(dbc, lock);
00125 lock_mode = DB_LOCK_WRITE;
00126 if ((ret = CDB___db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
00127 return (ret);
00128 if ((ret = CDB_memp_fget(dbp->mpf, &pg, 0, &h)) != 0) {
00129
00130 (void)__LPUT(dbc, lock);
00131 return (ret);
00132 }
00133 stack = 1;
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 total = RE_NREC(h);
00149 if (LF_ISSET(S_APPEND)) {
00150 *exactp = 0;
00151 *recnop = recno = total + 1;
00152 } else {
00153 recno = *recnop;
00154 if (recno <= total)
00155 *exactp = 1;
00156 else {
00157 *exactp = 0;
00158 if (!LF_ISSET(S_PAST_EOF) || recno > total + 1) {
00159
00160
00161
00162
00163
00164
00165
00166
00167 (void)CDB_memp_fput(dbp->mpf, h, 0);
00168 (void)__TLPUT(dbc, lock);
00169 return (DB_NOTFOUND);
00170 }
00171 }
00172 }
00173
00174
00175
00176
00177
00178
00179
00180 for (total = 0;;) {
00181 switch (TYPE(h)) {
00182 case P_LBTREE:
00183 case P_LDUP:
00184 recno -= total;
00185
00186
00187
00188
00189 if (TYPE(h) == P_LBTREE) {
00190 adjust = P_INDX;
00191 deloffset = O_INDX;
00192 } else {
00193 adjust = O_INDX;
00194 deloffset = 0;
00195 }
00196 for (t_recno = 0, indx = 0;; indx += adjust) {
00197 if (indx >= NUM_ENT(h)) {
00198 *exactp = 0;
00199 if (!LF_ISSET(S_PAST_EOF) ||
00200 recno > t_recno + 1) {
00201 ret = DB_NOTFOUND;
00202 goto err;
00203 }
00204 }
00205 if (!B_DISSET(
00206 GET_BKEYDATA(h, indx + deloffset)->type) &&
00207 ++t_recno == recno)
00208 break;
00209 }
00210
00211
00212 BT_STK_ENTER(dbp->dbenv,
00213 cp, h, indx, lock, lock_mode, ret);
00214 if (ret != 0)
00215 goto err;
00216 return (0);
00217 case P_IBTREE:
00218 for (indx = 0, top = NUM_ENT(h);;) {
00219 bi = GET_BINTERNAL(h, indx);
00220 if (++indx == top || total + bi->nrecs >= recno)
00221 break;
00222 total += bi->nrecs;
00223 }
00224 pg = bi->pgno;
00225 break;
00226 case P_LRECNO:
00227 recno -= total;
00228
00229
00230 --recno;
00231 BT_STK_ENTER(dbp->dbenv,
00232 cp, h, recno, lock, lock_mode, ret);
00233 if (ret != 0)
00234 goto err;
00235 return (0);
00236 case P_IRECNO:
00237 for (indx = 0, top = NUM_ENT(h);;) {
00238 ri = GET_RINTERNAL(h, indx);
00239 if (++indx == top || total + ri->nrecs >= recno)
00240 break;
00241 total += ri->nrecs;
00242 }
00243 pg = ri->pgno;
00244 break;
00245 default:
00246 return (CDB___db_pgfmt(dbp, h->pgno));
00247 }
00248 --indx;
00249
00250 if (stack) {
00251
00252 if (LF_ISSET(S_PARENT) && stop == h->level) {
00253 BT_STK_ENTER(dbp->dbenv,
00254 cp, h, indx, lock, lock_mode, ret);
00255 if (ret != 0)
00256 goto err;
00257 return (0);
00258 }
00259 BT_STK_PUSH(dbp->dbenv,
00260 cp, h, indx, lock, lock_mode, ret);
00261 if (ret != 0)
00262 goto err;
00263
00264 lock_mode = DB_LOCK_WRITE;
00265 if ((ret =
00266 CDB___db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
00267 goto err;
00268 } else {
00269
00270
00271
00272
00273
00274 if ((LF_ISSET(S_PARENT) &&
00275 (u_int8_t)(stop + 1) >= (u_int8_t)(h->level - 1)) ||
00276 (h->level - 1) == LEAFLEVEL)
00277 stack = 1;
00278
00279 (void)CDB_memp_fput(dbp->mpf, h, 0);
00280
00281 lock_mode = stack &&
00282 LF_ISSET(S_WRITE) ? DB_LOCK_WRITE : DB_LOCK_READ;
00283 if ((ret = CDB___db_lget(dbc,
00284 LCK_COUPLE, pg, lock_mode, 0, &lock)) != 0) {
00285
00286
00287
00288
00289
00290 __LPUT(dbc, lock);
00291 goto err;
00292 }
00293 }
00294
00295 if ((ret = CDB_memp_fget(dbp->mpf, &pg, 0, &h)) != 0)
00296 goto err;
00297 }
00298
00299
00300 err: BT_STK_POP(cp);
00301 CDB___bam_stkrel(dbc, 0);
00302 return (ret);
00303 }
00304
00305
00306
00307
00308
00309
00310
00311 int
00312 CDB___bam_adjust(dbc, adjust)
00313 DBC *dbc;
00314 int32_t adjust;
00315 {
00316 BTREE_CURSOR *cp;
00317 DB *dbp;
00318 EPG *epg;
00319 PAGE *h;
00320 db_pgno_t root_pgno;
00321 int ret;
00322
00323 dbp = dbc->dbp;
00324 cp = (BTREE_CURSOR *)dbc->internal;
00325 root_pgno = cp->root;
00326
00327
00328 for (epg = cp->sp; epg <= cp->csp; ++epg) {
00329 h = epg->page;
00330 if (TYPE(h) == P_IBTREE || TYPE(h) == P_IRECNO) {
00331 if (DB_LOGGING(dbc) &&
00332 (ret = CDB___bam_cadjust_log(dbp->dbenv,
00333 dbc->txn, &LSN(h), 0, dbp->log_fileid,
00334 PGNO(h), &LSN(h), (u_int32_t)epg->indx, adjust,
00335 PGNO(h) == root_pgno ? CAD_UPDATEROOT : 0)) != 0)
00336 return (ret);
00337
00338 if (TYPE(h) == P_IBTREE)
00339 GET_BINTERNAL(h, epg->indx)->nrecs += adjust;
00340 else
00341 GET_RINTERNAL(h, epg->indx)->nrecs += adjust;
00342
00343 if (PGNO(h) == root_pgno)
00344 RE_NREC_ADJ(h, adjust);
00345
00346 if ((ret = CDB_memp_fset(dbp->mpf, h, DB_MPOOL_DIRTY)) != 0)
00347 return (ret);
00348 }
00349 }
00350 return (0);
00351 }
00352
00353
00354
00355
00356
00357
00358
00359 int
00360 CDB___bam_nrecs(dbc, rep)
00361 DBC *dbc;
00362 db_recno_t *rep;
00363 {
00364 DB *dbp;
00365 DB_LOCK lock;
00366 PAGE *h;
00367 db_pgno_t pgno;
00368 int ret;
00369
00370 dbp = dbc->dbp;
00371
00372 pgno = dbc->internal->root;
00373 if ((ret = CDB___db_lget(dbc, 0, pgno, DB_LOCK_READ, 0, &lock)) != 0)
00374 return (ret);
00375 if ((ret = CDB_memp_fget(dbp->mpf, &pgno, 0, &h)) != 0)
00376 return (ret);
00377
00378 *rep = RE_NREC(h);
00379
00380 (void)CDB_memp_fput(dbp->mpf, h, 0);
00381 (void)__TLPUT(dbc, lock);
00382
00383 return (0);
00384 }
00385
00386
00387
00388
00389
00390
00391
00392 db_recno_t
00393 CDB___bam_total(h)
00394 PAGE *h;
00395 {
00396 db_recno_t nrecs;
00397 db_indx_t indx, top;
00398
00399 nrecs = 0;
00400 top = NUM_ENT(h);
00401
00402 switch (TYPE(h)) {
00403 case P_LBTREE:
00404
00405 for (indx = 0; indx < top; indx += P_INDX)
00406 if (!B_DISSET(GET_BKEYDATA(h, indx + O_INDX)->type))
00407 ++nrecs;
00408 break;
00409 case P_LDUP:
00410
00411 for (indx = 0; indx < top; indx += O_INDX)
00412 if (!B_DISSET(GET_BKEYDATA(h, indx)->type))
00413 ++nrecs;
00414 break;
00415 case P_IBTREE:
00416 for (indx = 0; indx < top; indx += O_INDX)
00417 nrecs += GET_BINTERNAL(h, indx)->nrecs;
00418 break;
00419 case P_LRECNO:
00420 nrecs = NUM_ENT(h);
00421 break;
00422 case P_IRECNO:
00423 for (indx = 0; indx < top; indx += O_INDX)
00424 nrecs += GET_RINTERNAL(h, indx)->nrecs;
00425 break;
00426 }
00427
00428 return (nrecs);
00429 }