db

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

AltStyle によって変換されたページ (->オリジナル) /