qam_rec.c

Go to the documentation of this file.
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: qam__rec_8c-source.html,v 1.1 2008/06/08 10:21:46 sebdiaz Exp $";
00012 #endif /* not lint */
00013 
00014 #ifndef NO_SYSTEM_INCLUDES
00015 #include <sys/types.h>
00016 
00017 #include <errno.h>
00018 #include <string.h>
00019 #endif
00020 
00021 #include "db_int.h"
00022 #include "db_page.h"
00023 #include "db_shash.h"
00024 #include "lock.h"
00025 #include "db_am.h"
00026 #include "qam.h"
00027 #include "log.h"
00028 
00029 /*
00030  * CDB___qam_inc_recover --
00031  *      Recovery function for inc.
00032  *
00033  * PUBLIC: int CDB___qam_inc_recover __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
00034  */
00035 int
00036 CDB___qam_inc_recover(dbenv, dbtp, lsnp, op, info)
00037         DB_ENV *dbenv;
00038         DBT *dbtp;
00039         DB_LSN *lsnp;
00040         db_recops op;
00041         void *info;
00042 {
00043         __qam_inc_args *argp;
00044         DB *file_dbp;
00045         DBC *dbc;
00046         DB_LOCK lock;
00047         DB_MPOOLFILE *mpf;
00048         QMETA *meta;
00049         db_pgno_t metapg;
00050         int cmp_p, modified, ret;
00051 
00052         COMPQUIET(info, NULL);
00053         REC_PRINT(CDB___qam_inc_print);
00054         REC_INTRO(CDB___qam_inc_read, 1);
00055 
00056         metapg = ((QUEUE *)file_dbp->q_internal)->q_meta;
00057 
00058         if ((ret = CDB___db_lget(dbc,
00059             LCK_ROLLBACK, metapg,  DB_LOCK_WRITE, 0, &lock)) != 0)
00060                 goto done;
00061         if ((ret = CDB_memp_fget(mpf, &metapg, 0, &meta)) != 0) {
00062                 if (DB_REDO(op)) {
00063                         if ((ret = CDB_memp_fget(mpf,
00064                             &metapg, DB_MPOOL_CREATE, &meta)) != 0) {
00065                                 (void)__LPUT(dbc, lock);
00066                                 goto out;
00067                         }
00068                         meta->dbmeta.pgno = metapg;
00069                         meta->dbmeta.type = P_QAMMETA;
00070 
00071                 } else {
00072                         *lsnp = argp->prev_lsn;
00073                         ret = 0;
00074                         (void)__LPUT(dbc, lock);
00075                         goto out;
00076                 }
00077         }
00078 
00079         modified = 0;
00080         cmp_p = CDB_log_compare(&LSN(meta), &argp->lsn);
00081         CHECK_LSN(op, cmp_p, &LSN(meta), &argp->lsn);
00082 
00083         /*
00084          * The cur_recno never goes backwards.  It is a point of
00085          * contention among appenders.  If one fails cur_recno will
00086          * most likely be beyond that one when it aborts.
00087          * We move it ahead on either an abort or a commit
00088          * and make the LSN reflect that fact.
00089          */
00090         if (cmp_p == 0) {
00091                 modified = 1;
00092                 meta->cur_recno++;
00093                 meta->dbmeta.lsn = *lsnp;
00094         }
00095         if ((ret = CDB_memp_fput(mpf, meta, modified ? DB_MPOOL_DIRTY : 0)))
00096                 goto out;
00097 
00098         (void)__LPUT(dbc, lock);
00099 
00100 done:   *lsnp = argp->prev_lsn;
00101         ret = 0;
00102 
00103 out:    REC_CLOSE;
00104 }
00105 
00106 /*
00107  * CDB___qam_incfirst_recover --
00108  *      Recovery function for incfirst.
00109  *
00110  * PUBLIC: int CDB___qam_incfirst_recover
00111  * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
00112  */
00113 int
00114 CDB___qam_incfirst_recover(dbenv, dbtp, lsnp, op, info)
00115         DB_ENV *dbenv;
00116         DBT *dbtp;
00117         DB_LSN *lsnp;
00118         db_recops op;
00119         void *info;
00120 {
00121         __qam_incfirst_args *argp;
00122         DB *file_dbp;
00123         DBC *dbc;
00124         DB_LOCK lock;
00125         DB_MPOOLFILE *mpf;
00126         QMETA *meta;
00127         db_pgno_t metapg;
00128         int modified, ret;
00129 
00130         COMPQUIET(info, NULL);
00131         REC_PRINT(CDB___qam_incfirst_print);
00132         REC_INTRO(CDB___qam_incfirst_read, 1);
00133 
00134         metapg = ((QUEUE *)file_dbp->q_internal)->q_meta;
00135 
00136         if ((ret = CDB___db_lget(dbc,
00137             LCK_ROLLBACK, metapg,  DB_LOCK_WRITE, 0, &lock)) != 0)
00138                 goto done;
00139         if ((ret = CDB_memp_fget(mpf, &metapg, 0, &meta)) != 0) {
00140                 if (DB_REDO(op)) {
00141                         if ((ret = CDB_memp_fget(mpf,
00142                             &metapg, DB_MPOOL_CREATE, &meta)) != 0) {
00143                                 (void)__LPUT(dbc, lock);
00144                                 goto out;
00145                         }
00146                         meta->dbmeta.pgno = metapg;
00147                         meta->dbmeta.type = P_QAMMETA;
00148                 } else {
00149                         *lsnp = argp->prev_lsn;
00150                         ret = 0;
00151                         (void)__LPUT(dbc, lock);
00152                         goto out;
00153                 }
00154         }
00155 
00156         modified = 0;
00157 
00158         /*
00159          * Only move first_recno backwards so we pick up the aborted delete.
00160          * If we are going forward then we could patch first up, but it will
00161          * get fixed by normal operations.
00162          */
00163         if (DB_UNDO(op)) {
00164                 if (meta->first_recno > argp->recno) {
00165                         meta->first_recno = argp->recno;
00166                         modified = 1;
00167                 }
00168         }
00169 
00170         if ((ret = CDB_memp_fput(mpf, meta, modified ? DB_MPOOL_DIRTY : 0)))
00171                 goto out;
00172 
00173         (void)__LPUT(dbc, lock);
00174 
00175 done:   *lsnp = argp->prev_lsn;
00176         ret = 0;
00177 
00178 out:    REC_CLOSE;
00179 }
00180 
00181 /*
00182  * CDB___qam_mvptr_recover --
00183  *      Recovery function for mvptr.
00184  *
00185  * PUBLIC: int CDB___qam_mvptr_recover
00186  * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
00187  */
00188 int
00189 CDB___qam_mvptr_recover(dbenv, dbtp, lsnp, op, info)
00190         DB_ENV *dbenv;
00191         DBT *dbtp;
00192         DB_LSN *lsnp;
00193         db_recops op;
00194         void *info;
00195 {
00196         __qam_mvptr_args *argp;
00197         DB *file_dbp;
00198         DBC *dbc;
00199         DB_LOCK lock;
00200         DB_MPOOLFILE *mpf;
00201         QMETA *meta;
00202         db_pgno_t metapg;
00203         int cmp_p, modified, ret;
00204 
00205         COMPQUIET(info, NULL);
00206         REC_PRINT(CDB___qam_mvptr_print);
00207         REC_INTRO(CDB___qam_mvptr_read, 1);
00208 
00209         metapg = ((QUEUE *)file_dbp->q_internal)->q_meta;
00210 
00211         if ((ret = CDB___db_lget(dbc,
00212             LCK_ROLLBACK, metapg,  DB_LOCK_WRITE, 0, &lock)) != 0)
00213                 goto done;
00214         if ((ret = CDB_memp_fget(mpf, &metapg, 0, &meta)) != 0) {
00215                 if (DB_REDO(op)) {
00216                         if ((ret = CDB_memp_fget(mpf,
00217                             &metapg, DB_MPOOL_CREATE, &meta)) != 0) {
00218                                 (void)__LPUT(dbc, lock);
00219                                 goto out;
00220                         }
00221                         meta->dbmeta.pgno = metapg;
00222                         meta->dbmeta.type = P_QAMMETA;
00223                 } else {
00224                         *lsnp = argp->prev_lsn;
00225                         ret = 0;
00226                         (void)__LPUT(dbc, lock);
00227                         goto out;
00228                 }
00229         }
00230 
00231         modified = 0;
00232         cmp_p = CDB_log_compare(&meta->dbmeta.lsn, &argp->metalsn);
00233 
00234         /*
00235          * We never undo a movement of one of the pointers.
00236          * Just move them along regardless of abort/commit.
00237          */
00238         if (cmp_p == 0) {
00239                 if (argp->opcode & QAM_SETFIRST)
00240                         meta->first_recno = argp->new_first;
00241 
00242                 if (argp->opcode & QAM_SETCUR)
00243                         meta->cur_recno = argp->new_cur;
00244 
00245                 modified = 1;
00246                 meta->dbmeta.lsn = *lsnp;
00247         }
00248 
00249         if ((ret = CDB_memp_fput(mpf, meta, modified ? DB_MPOOL_DIRTY : 0)))
00250                 goto out;
00251 
00252         (void)__LPUT(dbc, lock);
00253 
00254 done:   *lsnp = argp->prev_lsn;
00255         ret = 0;
00256 
00257 out:    REC_CLOSE;
00258 }
00259 /*
00260  * CDB___qam_del_recover --
00261  *      Recovery function for del.
00262  *
00263  * PUBLIC: int CDB___qam_del_recover __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
00264  */
00265 int
00266 CDB___qam_del_recover(dbenv, dbtp, lsnp, op, info)
00267         DB_ENV *dbenv;
00268         DBT *dbtp;
00269         DB_LSN *lsnp;
00270         db_recops op;
00271         void *info;
00272 {
00273         __qam_del_args *argp;
00274         DB *file_dbp;
00275         DBC *dbc;
00276         DB_LOCK lock;
00277         DB_MPOOLFILE *mpf;
00278         QAMDATA *qp;
00279         QMETA *meta;
00280         QPAGE *pagep;
00281         db_pgno_t metapg;
00282         int cmp_n, modified, ret;
00283 
00284         COMPQUIET(info, NULL);
00285         REC_PRINT(CDB___qam_del_print);
00286         REC_INTRO(CDB___qam_del_read, 1);
00287 
00288         if ((ret = CDB_memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00289                 if (DB_REDO(op)) {
00290                         if ((ret = CDB_memp_fget(mpf,
00291                             &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
00292                                 goto out;
00293                         pagep->pgno = argp->pgno;
00294                         pagep->type = P_QAMDATA;
00295                 } else {
00296                         *lsnp = argp->prev_lsn;
00297                         ret = 0;
00298                         goto out;
00299                 }
00300         }
00301 
00302         modified = 0;
00303         cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00304 
00305         if (cmp_n > 0 && DB_REDO(op)) {
00306                 /* Need to redo delete - clear the valid bit */
00307                 qp = QAM_GET_RECORD(file_dbp, pagep, argp->indx);
00308                 F_CLR(qp, QAM_VALID);
00309                 LSN(pagep) = *lsnp;
00310                 modified = 1;
00311         } else if (cmp_n <= 0 && DB_UNDO(op)) {
00312                 /* make sure first is behind us */
00313                 metapg = ((QUEUE *)file_dbp->q_internal)->q_meta;
00314                 if ((ret = CDB___db_lget(dbc,
00315                     LCK_ROLLBACK, metapg, DB_LOCK_WRITE, 0, &lock)) != 0)
00316                         return (ret);
00317                 if ((ret = CDB_memp_fget(file_dbp->mpf, &metapg, 0, &meta)) != 0) {
00318                         (void)__LPUT(dbc, lock);
00319                         goto done;
00320                 }
00321                 if (argp->recno < meta->first_recno) {
00322                         meta->first_recno = argp->recno;
00323                         (void)CDB_memp_fput(file_dbp->mpf, meta, DB_MPOOL_DIRTY);
00324                 } else
00325                         (void)CDB_memp_fput(file_dbp->mpf, meta, 0);
00326                 (void)__LPUT(dbc, lock);
00327 
00328                 /* Need to undo delete - mark the record as present */
00329                 qp = QAM_GET_RECORD(file_dbp, pagep, argp->indx);
00330                 F_SET(qp, QAM_VALID);
00331                 LSN(pagep) = argp->lsn;
00332                 modified = 1;
00333         }
00334         if ((ret = CDB_memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)))
00335                 goto out;
00336 
00337 done:   *lsnp = argp->prev_lsn;
00338         ret = 0;
00339 
00340 out:    REC_CLOSE;
00341 }
00342 
00343 /*
00344  * CDB___qam_add_recover --
00345  *      Recovery function for add.
00346  *
00347  * PUBLIC: int CDB___qam_add_recover __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
00348  */
00349 int
00350 CDB___qam_add_recover(dbenv, dbtp, lsnp, op, info)
00351         DB_ENV *dbenv;
00352         DBT *dbtp;
00353         DB_LSN *lsnp;
00354         db_recops op;
00355         void *info;
00356 {
00357         __qam_add_args *argp;
00358         DB *file_dbp;
00359         DBC *dbc;
00360         DB_MPOOLFILE *mpf;
00361         QAMDATA *qp;
00362         QPAGE *pagep;
00363         int cmp_n, cmp_p, modified, ret;
00364 
00365         COMPQUIET(info, NULL);
00366         REC_PRINT(CDB___qam_add_print);
00367         REC_INTRO(CDB___qam_add_read, 1);
00368 
00369         modified = 0;
00370         if ((ret = CDB_memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00371                 if ((ret = CDB_memp_fget(mpf,
00372                     &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
00373                         goto out;
00374                 pagep->pgno = argp->pgno;
00375                 pagep->type = P_QAMDATA;
00376                 modified = 1;
00377         }
00378 
00379         cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00380         cmp_p = CDB_log_compare(&LSN(pagep), &argp->lsn);
00381 
00382         if (cmp_p <= 0 && DB_REDO(op)) {
00383                 /* Need to redo add - put the record on page */
00384                 if ((ret = CDB___qam_pitem(dbc, pagep, argp->indx, argp->recno,
00385                                 &argp->data)) != 0)
00386                         goto err;
00387                 LSN(pagep) = *lsnp;
00388                 modified = 1;
00389         } else if (cmp_n >= 0 && DB_UNDO(op)) {
00390                 /*
00391                  * Need to undo add
00392                  *      If this was an overwrite, put old record back.
00393                  *      Otherwise just clear the valid bit
00394                  */
00395                 if (argp->olddata.size != 0) {
00396                         if ((ret = CDB___qam_pitem(dbc, pagep,
00397                             argp->indx, argp->recno, &argp->olddata)) != 0)
00398                                 goto err;
00399 
00400                         if (!(argp->vflag & QAM_VALID)) {
00401                                 qp = QAM_GET_RECORD(
00402                                     file_dbp, pagep, argp->indx);
00403                                 F_CLR(qp, QAM_VALID);
00404                         }
00405                         modified = 1;
00406                 } else {
00407                         qp = QAM_GET_RECORD(file_dbp, pagep, argp->indx);
00408                         qp->flags = 0;
00409                         modified = 1;
00410                 }
00411                 LSN(pagep) = argp->lsn;
00412         }
00413 
00414 err:    if ((ret = CDB_memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)))
00415                 goto out;
00416 
00417 done:   *lsnp = argp->prev_lsn;
00418         ret = 0;
00419 
00420 out:    REC_CLOSE;
00421 }

Generated on Sun Jun 8 10:56:39 2008 for GNUmifluz by  doxygen 1.5.5