00001
00002
00003
00004
00005
00006
00007
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
00020 static int __bam_opd_cursor __P((DB *, DBC *, db_pgno_t, u_int32_t, u_int32_t));
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 int
00041 __bam_ca_delete(dbp, pgno, indx, delete, countp)
00042 DB *dbp;
00043 db_pgno_t pgno;
00044 u_int32_t indx;
00045 int delete, *countp;
00046 {
00047 BTREE_CURSOR *cp;
00048 DB *ldbp;
00049 DB_ENV *dbenv;
00050 DBC *dbc;
00051 int count;
00052
00053 dbenv = dbp->dbenv;
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
00067 for (count = 0, ldbp = __dblist_get(dbenv, dbp->adj_fileid);
00068 ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
00069 ldbp = LIST_NEXT(ldbp, dblistlinks)) {
00070 MUTEX_LOCK(dbenv, dbp->mutex);
00071 for (dbc = TAILQ_FIRST(&ldbp->active_queue);
00072 dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
00073 cp = (BTREE_CURSOR *)dbc->internal;
00074 if (cp->pgno == pgno && cp->indx == indx) {
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 if (delete)
00089 F_SET(cp, C_DELETED);
00090 else
00091 F_CLR(cp, C_DELETED);
00092 ++count;
00093 }
00094 }
00095 MUTEX_UNLOCK(dbenv, dbp->mutex);
00096 }
00097 MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
00098
00099 if (countp != NULL)
00100 *countp = count;
00101 return (0);
00102 }
00103
00104
00105
00106
00107
00108
00109
00110 int
00111 __ram_ca_delete(dbp, root_pgno, foundp)
00112 DB *dbp;
00113 db_pgno_t root_pgno;
00114 int *foundp;
00115 {
00116 DB *ldbp;
00117 DBC *dbc;
00118 DB_ENV *dbenv;
00119 int found;
00120
00121 found = 0;
00122 dbenv = dbp->dbenv;
00123
00124
00125
00126
00127 MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
00128 for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
00129 found == 0 && ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
00130 ldbp = LIST_NEXT(ldbp, dblistlinks)) {
00131 MUTEX_LOCK(dbenv, dbp->mutex);
00132 for (dbc = TAILQ_FIRST(&ldbp->active_queue);
00133 found == 0 && dbc != NULL; dbc = TAILQ_NEXT(dbc, links))
00134 if (dbc->internal->root == root_pgno)
00135 found = 1;
00136 MUTEX_UNLOCK(dbenv, dbp->mutex);
00137 }
00138 MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
00139
00140 *foundp = found;
00141 return (0);
00142 }
00143
00144
00145
00146
00147
00148
00149
00150 int
00151 __bam_ca_di(my_dbc, pgno, indx, adjust)
00152 DBC *my_dbc;
00153 db_pgno_t pgno;
00154 u_int32_t indx;
00155 int adjust;
00156 {
00157 DB *dbp, *ldbp;
00158 DB_ENV *dbenv;
00159 DB_LSN lsn;
00160 DB_TXN *my_txn;
00161 DBC *dbc;
00162 DBC_INTERNAL *cp;
00163 int found, ret;
00164
00165 dbp = my_dbc->dbp;
00166 dbenv = dbp->dbenv;
00167
00168 my_txn = IS_SUBTRANSACTION(my_dbc->txn) ? my_dbc->txn : NULL;
00169
00170
00171
00172
00173 found = 0;
00174 MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
00175 for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
00176 ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
00177 ldbp = LIST_NEXT(ldbp, dblistlinks)) {
00178 MUTEX_LOCK(dbenv, dbp->mutex);
00179 for (dbc = TAILQ_FIRST(&ldbp->active_queue);
00180 dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
00181 if (dbc->dbtype == DB_RECNO)
00182 continue;
00183 cp = dbc->internal;
00184 if (cp->pgno == pgno && cp->indx >= indx) {
00185
00186 DB_ASSERT(cp->indx != 0 || adjust > 0);
00187
00188
00189
00190
00191 cp->indx += adjust;
00192 if (my_txn != NULL && dbc->txn != my_txn)
00193 found = 1;
00194 }
00195 }
00196 MUTEX_UNLOCK(dbenv, dbp->mutex);
00197 }
00198 MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
00199
00200 if (found != 0 && DBC_LOGGING(my_dbc)) {
00201 if ((ret = __bam_curadj_log(dbp, my_dbc->txn, &lsn, 0,
00202 DB_CA_DI, pgno, 0, 0, (u_int32_t)adjust, indx, 0)) != 0)
00203 return (ret);
00204 }
00205
00206 return (0);
00207 }
00208
00209
00210
00211
00212 static int
00213 __bam_opd_cursor(dbp, dbc, first, tpgno, ti)
00214 DB *dbp;
00215 DBC *dbc;
00216 db_pgno_t tpgno;
00217 u_int32_t first, ti;
00218 {
00219 BTREE_CURSOR *cp, *orig_cp;
00220 DBC *dbc_nopd;
00221 int ret;
00222
00223 orig_cp = (BTREE_CURSOR *)dbc->internal;
00224 dbc_nopd = NULL;
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 DB_ASSERT(orig_cp->opd == NULL);
00236 if ((ret = __db_c_newopd(dbc, tpgno, orig_cp->opd, &dbc_nopd)) != 0)
00237 return (ret);
00238
00239 cp = (BTREE_CURSOR *)dbc_nopd->internal;
00240 cp->pgno = tpgno;
00241 cp->indx = ti;
00242
00243 if (dbp->dup_compare == NULL) {
00244
00245
00246
00247
00248
00249 cp->recno = ti + 1;
00250 }
00251
00252
00253
00254
00255
00256 if (F_ISSET(orig_cp, C_DELETED)) {
00257 F_SET(cp, C_DELETED);
00258 F_CLR(orig_cp, C_DELETED);
00259 }
00260
00261
00262 orig_cp->opd = dbc_nopd;
00263 orig_cp->indx = first;
00264 return (0);
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 int
00276 __bam_ca_dup(my_dbc, first, fpgno, fi, tpgno, ti)
00277 DBC *my_dbc;
00278 db_pgno_t fpgno, tpgno;
00279 u_int32_t first, fi, ti;
00280 {
00281 BTREE_CURSOR *orig_cp;
00282 DB *dbp, *ldbp;
00283 DBC *dbc;
00284 DB_ENV *dbenv;
00285 DB_LSN lsn;
00286 DB_TXN *my_txn;
00287 int found, ret;
00288
00289 dbp = my_dbc->dbp;
00290 dbenv = dbp->dbenv;
00291 my_txn = IS_SUBTRANSACTION(my_dbc->txn) ? my_dbc->txn : NULL;
00292
00293
00294
00295
00296 found = 0;
00297 MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
00298 for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
00299 ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
00300 ldbp = LIST_NEXT(ldbp, dblistlinks)) {
00301 loop: MUTEX_LOCK(dbenv, dbp->mutex);
00302 for (dbc = TAILQ_FIRST(&ldbp->active_queue);
00303 dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
00304
00305 orig_cp = (BTREE_CURSOR *)dbc->internal;
00306 if (orig_cp->pgno != fpgno || orig_cp->indx != fi)
00307 continue;
00308
00309
00310
00311
00312
00313 if (orig_cp->opd != NULL)
00314 continue;
00315
00316 MUTEX_UNLOCK(dbenv, dbp->mutex);
00317
00318
00319
00320
00321 if ((ret = __bam_opd_cursor(dbp,
00322 dbc, first, tpgno, ti)) !=0)
00323 return (ret);
00324 if (my_txn != NULL && dbc->txn != my_txn)
00325 found = 1;
00326
00327 goto loop;
00328 }
00329 MUTEX_UNLOCK(dbenv, dbp->mutex);
00330 }
00331 MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
00332
00333 if (found != 0 && DBC_LOGGING(my_dbc)) {
00334 if ((ret = __bam_curadj_log(dbp, my_dbc->txn,
00335 &lsn, 0, DB_CA_DUP, fpgno, tpgno, 0, first, fi, ti)) != 0)
00336 return (ret);
00337 }
00338 return (0);
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 int
00351 __bam_ca_undodup(dbp, first, fpgno, fi, ti)
00352 DB *dbp;
00353 db_pgno_t fpgno;
00354 u_int32_t first, fi, ti;
00355 {
00356 BTREE_CURSOR *orig_cp;
00357 DB *ldbp;
00358 DBC *dbc;
00359 DB_ENV *dbenv;
00360 int ret;
00361
00362 dbenv = dbp->dbenv;
00363
00364
00365
00366
00367 MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
00368 for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
00369 ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
00370 ldbp = LIST_NEXT(ldbp, dblistlinks)) {
00371 loop: MUTEX_LOCK(dbenv, dbp->mutex);
00372 for (dbc = TAILQ_FIRST(&ldbp->active_queue);
00373 dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
00374 orig_cp = (BTREE_CURSOR *)dbc->internal;
00375
00376
00377
00378
00379
00380
00381
00382
00383 if (orig_cp->pgno != fpgno ||
00384 orig_cp->indx != first ||
00385 orig_cp->opd == NULL || ((BTREE_CURSOR *)
00386 orig_cp->opd->internal)->indx != ti)
00387 continue;
00388 MUTEX_UNLOCK(dbenv, dbp->mutex);
00389 if ((ret = __db_c_close(orig_cp->opd)) != 0)
00390 return (ret);
00391 orig_cp->opd = NULL;
00392 orig_cp->indx = fi;
00393
00394
00395
00396
00397 goto loop;
00398 }
00399 MUTEX_UNLOCK(dbenv, dbp->mutex);
00400 }
00401 MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
00402
00403 return (0);
00404 }
00405
00406
00407
00408
00409
00410
00411
00412 int
00413 __bam_ca_rsplit(my_dbc, fpgno, tpgno)
00414 DBC* my_dbc;
00415 db_pgno_t fpgno, tpgno;
00416 {
00417 DB *dbp, *ldbp;
00418 DBC *dbc;
00419 DB_ENV *dbenv;
00420 DB_LSN lsn;
00421 DB_TXN *my_txn;
00422 int found, ret;
00423
00424 dbp = my_dbc->dbp;
00425 dbenv = dbp->dbenv;
00426 my_txn = IS_SUBTRANSACTION(my_dbc->txn) ? my_dbc->txn : NULL;
00427
00428
00429
00430
00431 found = 0;
00432 MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
00433 for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
00434 ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
00435 ldbp = LIST_NEXT(ldbp, dblistlinks)) {
00436 MUTEX_LOCK(dbenv, dbp->mutex);
00437 for (dbc = TAILQ_FIRST(&ldbp->active_queue);
00438 dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
00439 if (dbc->dbtype == DB_RECNO)
00440 continue;
00441 if (dbc->internal->pgno == fpgno) {
00442 dbc->internal->pgno = tpgno;
00443
00444
00445
00446
00447 if (my_txn != NULL && dbc->txn != my_txn)
00448 found = 1;
00449 }
00450 }
00451 MUTEX_UNLOCK(dbenv, dbp->mutex);
00452 }
00453 MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
00454
00455 if (found != 0 && DBC_LOGGING(my_dbc)) {
00456 if ((ret = __bam_curadj_log(dbp, my_dbc->txn,
00457 &lsn, 0, DB_CA_RSPLIT, fpgno, tpgno, 0, 0, 0, 0)) != 0)
00458 return (ret);
00459 }
00460 return (0);
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470 int
00471 __bam_ca_split(my_dbc, ppgno, lpgno, rpgno, split_indx, cleft)
00472 DBC *my_dbc;
00473 db_pgno_t ppgno, lpgno, rpgno;
00474 u_int32_t split_indx;
00475 int cleft;
00476 {
00477 DB *dbp, *ldbp;
00478 DBC *dbc;
00479 DBC_INTERNAL *cp;
00480 DB_ENV *dbenv;
00481 DB_LSN lsn;
00482 DB_TXN *my_txn;
00483 int found, ret;
00484
00485 dbp = my_dbc->dbp;
00486 dbenv = dbp->dbenv;
00487 my_txn = IS_SUBTRANSACTION(my_dbc->txn) ? my_dbc->txn : NULL;
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 found = 0;
00500 MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
00501 for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
00502 ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
00503 ldbp = LIST_NEXT(ldbp, dblistlinks)) {
00504 MUTEX_LOCK(dbenv, dbp->mutex);
00505 for (dbc = TAILQ_FIRST(&ldbp->active_queue);
00506 dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
00507 if (dbc->dbtype == DB_RECNO)
00508 continue;
00509 cp = dbc->internal;
00510 if (cp->pgno == ppgno) {
00511
00512
00513
00514
00515 if (my_txn != NULL && dbc->txn != my_txn)
00516 found = 1;
00517 if (cp->indx < split_indx) {
00518 if (cleft)
00519 cp->pgno = lpgno;
00520 } else {
00521 cp->pgno = rpgno;
00522 cp->indx -= split_indx;
00523 }
00524 }
00525 }
00526 MUTEX_UNLOCK(dbenv, dbp->mutex);
00527 }
00528 MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
00529
00530 if (found != 0 && DBC_LOGGING(my_dbc)) {
00531 if ((ret = __bam_curadj_log(dbp,
00532 my_dbc->txn, &lsn, 0, DB_CA_SPLIT, ppgno, rpgno,
00533 cleft ? lpgno : PGNO_INVALID, 0, split_indx, 0)) != 0)
00534 return (ret);
00535 }
00536
00537 return (0);
00538 }
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550 int
00551 __bam_ca_undosplit(dbp, frompgno, topgno, lpgno, split_indx)
00552 DB *dbp;
00553 db_pgno_t frompgno, topgno, lpgno;
00554 u_int32_t split_indx;
00555 {
00556 DB *ldbp;
00557 DBC *dbc;
00558 DB_ENV *dbenv;
00559 DBC_INTERNAL *cp;
00560
00561 dbenv = dbp->dbenv;
00562
00563
00564
00565
00566
00567
00568
00569 MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
00570 for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);
00571 ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
00572 ldbp = LIST_NEXT(ldbp, dblistlinks)) {
00573 MUTEX_LOCK(dbenv, dbp->mutex);
00574 for (dbc = TAILQ_FIRST(&ldbp->active_queue);
00575 dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
00576 if (dbc->dbtype == DB_RECNO)
00577 continue;
00578 cp = dbc->internal;
00579 if (cp->pgno == topgno) {
00580 cp->pgno = frompgno;
00581 cp->indx += split_indx;
00582 } else if (cp->pgno == lpgno)
00583 cp->pgno = frompgno;
00584 }
00585 MUTEX_UNLOCK(dbenv, dbp->mutex);
00586 }
00587 MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
00588
00589 return (0);
00590 }