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
00041
00042
00043 #include "config.h"
00044
00045 #ifndef lint
00046 static const char revid[] = "$Id: hash__rec_8c-source.html,v 1.1 2008/06/08 10:19:37 sebdiaz Exp $";
00047 #endif
00048
00049 #ifndef NO_SYSTEM_INCLUDES
00050 #include <sys/types.h>
00051
00052 #include <errno.h>
00053 #include <string.h>
00054 #endif
00055
00056 #include "db_int.h"
00057 #include "db_page.h"
00058 #include "db_shash.h"
00059 #include "btree.h"
00060 #include "hash.h"
00061 #include "lock.h"
00062 #include "log.h"
00063 #include "mp.h"
00064
00065 static int __ham_alloc_pages __P((DB *, __ham_groupalloc_args *));
00066 static int __ham_free_pages __P((DB *, DBMETA *, __ham_groupalloc_args *));
00067
00068
00069
00070
00071
00072
00073
00074 int
00075 CDB___ham_insdel_recover(dbenv, dbtp, lsnp, op, info)
00076 DB_ENV *dbenv;
00077 DBT *dbtp;
00078 DB_LSN *lsnp;
00079 db_recops op;
00080 void *info;
00081 {
00082 __ham_insdel_args *argp;
00083 DB *file_dbp;
00084 DBC *dbc;
00085 DB_MPOOLFILE *mpf;
00086 PAGE *pagep;
00087 u_int32_t opcode;
00088 int cmp_n, cmp_p, getmeta, ret, type;
00089
00090 COMPQUIET(info, NULL);
00091
00092 getmeta = 0;
00093 REC_PRINT(CDB___ham_insdel_print);
00094 REC_INTRO(CDB___ham_insdel_read, 1);
00095
00096 if ((ret = CDB_memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00097 if (DB_UNDO(op)) {
00098
00099
00100
00101
00102
00103
00104 goto done;
00105 } else if ((ret = CDB_memp_fget(mpf, &argp->pgno,
00106 DB_MPOOL_CREATE, &pagep)) != 0)
00107 goto out;
00108 }
00109
00110 if ((ret = CDB___ham_get_meta(dbc)) != 0)
00111 goto out;
00112 getmeta = 1;
00113
00114 cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00115 cmp_p = CDB_log_compare(&LSN(pagep), &argp->pagelsn);
00116 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->pagelsn);
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 opcode = OPCODE_OF(argp->opcode);
00128
00129 if ((opcode == DELPAIR && cmp_n == 0 && DB_UNDO(op)) ||
00130 (opcode == PUTPAIR && cmp_p == 0 && DB_REDO(op))) {
00131
00132
00133
00134
00135
00136
00137 if (opcode != DELPAIR ||
00138 argp->ndx == (u_int32_t)NUM_ENT(pagep)) {
00139 CDB___ham_putitem(pagep, &argp->key,
00140 DB_UNDO(op) || PAIR_ISKEYBIG(argp->opcode) ?
00141 H_OFFPAGE : H_KEYDATA);
00142
00143 if (PAIR_ISDATADUP(argp->opcode))
00144 type = H_DUPLICATE;
00145 else if (DB_UNDO(op) || PAIR_ISDATABIG(argp->opcode))
00146 type = H_OFFPAGE;
00147 else
00148 type = H_KEYDATA;
00149 CDB___ham_putitem(pagep, &argp->data, type);
00150 } else
00151 (void) CDB___ham_reputpair(pagep, file_dbp->pgsize,
00152 argp->ndx, &argp->key, &argp->data);
00153
00154 LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn;
00155 if ((ret = CDB___ham_put_page(file_dbp, pagep, 1)) != 0)
00156 goto out;
00157
00158 } else if ((opcode == DELPAIR && cmp_p == 0 && DB_REDO(op))
00159 || (opcode == PUTPAIR && cmp_n == 0 && DB_UNDO(op))) {
00160
00161 CDB___ham_dpair(file_dbp, pagep, argp->ndx);
00162 LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn;
00163 if ((ret = CDB___ham_put_page(file_dbp, (PAGE *)pagep, 1)) != 0)
00164 goto out;
00165 } else
00166 if ((ret = CDB___ham_put_page(file_dbp, (PAGE *)pagep, 0)) != 0)
00167 goto out;
00168
00169
00170 done: *lsnp = argp->prev_lsn;
00171 ret = 0;
00172
00173 out: if (getmeta)
00174 (void)CDB___ham_release_meta(dbc);
00175 REC_CLOSE;
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 int
00187 CDB___ham_newpage_recover(dbenv, dbtp, lsnp, op, info)
00188 DB_ENV *dbenv;
00189 DBT *dbtp;
00190 DB_LSN *lsnp;
00191 db_recops op;
00192 void *info;
00193 {
00194 __ham_newpage_args *argp;
00195 DB *file_dbp;
00196 DBC *dbc;
00197 DB_MPOOLFILE *mpf;
00198 PAGE *pagep;
00199 int cmp_n, cmp_p, change, getmeta, ret;
00200
00201 COMPQUIET(info, NULL);
00202
00203 getmeta = 0;
00204 REC_PRINT(CDB___ham_newpage_print);
00205 REC_INTRO(CDB___ham_newpage_read, 1);
00206
00207 if ((ret = CDB_memp_fget(mpf, &argp->new_pgno, 0, &pagep)) != 0) {
00208 if (DB_UNDO(op)) {
00209
00210
00211
00212
00213
00214
00215 ret = 0;
00216 goto ppage;
00217 } else if ((ret = CDB_memp_fget(mpf, &argp->new_pgno,
00218 DB_MPOOL_CREATE, &pagep)) != 0)
00219 goto out;
00220 }
00221
00222 if ((ret = CDB___ham_get_meta(dbc)) != 0)
00223 goto out;
00224 getmeta = 1;
00225
00226
00227
00228
00229
00230
00231
00232 cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00233 cmp_p = CDB_log_compare(&LSN(pagep), &argp->pagelsn);
00234 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->pagelsn);
00235 change = 0;
00236
00237 if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == PUTOVFL) ||
00238 (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DELOVFL)) {
00239
00240 P_INIT(pagep, file_dbp->pgsize, argp->new_pgno,
00241 argp->prev_pgno, argp->next_pgno, 0, P_HASH, 0);
00242 change = 1;
00243 } else if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == DELOVFL) ||
00244 (cmp_n == 0 && DB_UNDO(op) && argp->opcode == PUTOVFL)) {
00245
00246
00247
00248
00249 change = 1;
00250 }
00251
00252 if (!change) {
00253 if ((ret = CDB___ham_put_page(file_dbp, (PAGE *)pagep, 0)) != 0)
00254 goto out;
00255 } else {
00256 LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn;
00257 if ((ret = CDB___ham_put_page(file_dbp, (PAGE *)pagep, 1)) != 0)
00258 goto out;
00259 }
00260
00261
00262 ppage: if (argp->prev_pgno != PGNO_INVALID) {
00263 if ((ret = CDB_memp_fget(mpf, &argp->prev_pgno, 0, &pagep)) != 0) {
00264 if (DB_UNDO(op)) {
00265
00266
00267
00268
00269
00270
00271 ret = 0;
00272 goto npage;
00273 } else if ((ret =
00274 CDB_memp_fget(mpf, &argp->prev_pgno,
00275 DB_MPOOL_CREATE, &pagep)) != 0)
00276 goto out;
00277 }
00278
00279 cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00280 cmp_p = CDB_log_compare(&LSN(pagep), &argp->prevlsn);
00281 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->prevlsn);
00282 change = 0;
00283
00284 if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == PUTOVFL) ||
00285 (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DELOVFL)) {
00286
00287 pagep->next_pgno = argp->new_pgno;
00288 change = 1;
00289 } else if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == DELOVFL) ||
00290 (cmp_n == 0 && DB_UNDO(op) && argp->opcode == PUTOVFL)) {
00291
00292 pagep->next_pgno = argp->next_pgno;
00293 change = 1;
00294 }
00295
00296 if (!change) {
00297 if ((ret =
00298 CDB___ham_put_page(file_dbp, (PAGE *)pagep, 0)) != 0)
00299 goto out;
00300 } else {
00301 LSN(pagep) = DB_REDO(op) ? *lsnp : argp->prevlsn;
00302 if ((ret =
00303 CDB___ham_put_page(file_dbp, (PAGE *)pagep, 1)) != 0)
00304 goto out;
00305 }
00306 }
00307
00308
00309 npage: if (argp->next_pgno != PGNO_INVALID) {
00310 if ((ret = CDB_memp_fget(mpf, &argp->next_pgno, 0, &pagep)) != 0) {
00311 if (DB_UNDO(op)) {
00312
00313
00314
00315
00316
00317
00318 goto done;
00319 } else if ((ret =
00320 CDB_memp_fget(mpf, &argp->next_pgno,
00321 DB_MPOOL_CREATE, &pagep)) != 0)
00322 goto out;
00323 }
00324
00325 cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00326 cmp_p = CDB_log_compare(&LSN(pagep), &argp->nextlsn);
00327 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->nextlsn);
00328 change = 0;
00329
00330 if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == PUTOVFL) ||
00331 (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DELOVFL)) {
00332
00333 pagep->prev_pgno = argp->new_pgno;
00334 change = 1;
00335 } else if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == DELOVFL) ||
00336 (cmp_n == 0 && DB_UNDO(op) && argp->opcode == PUTOVFL)) {
00337
00338 pagep->prev_pgno = argp->prev_pgno;
00339 change = 1;
00340 }
00341
00342 if (!change) {
00343 if ((ret =
00344 CDB___ham_put_page(file_dbp, (PAGE *)pagep, 0)) != 0)
00345 goto out;
00346 } else {
00347 LSN(pagep) = DB_REDO(op) ? *lsnp : argp->nextlsn;
00348 if ((ret =
00349 CDB___ham_put_page(file_dbp, (PAGE *)pagep, 1)) != 0)
00350 goto out;
00351 }
00352 }
00353 done: *lsnp = argp->prev_lsn;
00354 ret = 0;
00355
00356 out: if (getmeta)
00357 (void)CDB___ham_release_meta(dbc);
00358 REC_CLOSE;
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 int
00371 CDB___ham_replace_recover(dbenv, dbtp, lsnp, op, info)
00372 DB_ENV *dbenv;
00373 DBT *dbtp;
00374 DB_LSN *lsnp;
00375 db_recops op;
00376 void *info;
00377 {
00378 __ham_replace_args *argp;
00379 DB *file_dbp;
00380 DBC *dbc;
00381 DB_MPOOLFILE *mpf;
00382 DBT dbt;
00383 PAGE *pagep;
00384 int32_t grow;
00385 int change, cmp_n, cmp_p, getmeta, ret;
00386 u_int8_t *hk;
00387
00388 COMPQUIET(info, NULL);
00389
00390 getmeta = 0;
00391 REC_PRINT(CDB___ham_replace_print);
00392 REC_INTRO(CDB___ham_replace_read, 1);
00393
00394 if ((ret = CDB_memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00395 if (DB_UNDO(op)) {
00396
00397
00398
00399
00400
00401
00402 goto done;
00403 } else if ((ret = CDB_memp_fget(mpf, &argp->pgno,
00404 DB_MPOOL_CREATE, &pagep)) != 0)
00405 goto out;
00406 }
00407
00408 if ((ret = CDB___ham_get_meta(dbc)) != 0)
00409 goto out;
00410 getmeta = 1;
00411
00412 cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00413 cmp_p = CDB_log_compare(&LSN(pagep), &argp->pagelsn);
00414 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->pagelsn);
00415
00416 memset(&dbt, 0, sizeof(dbt));
00417 if (cmp_p == 0 && DB_REDO(op)) {
00418 change = 1;
00419
00420 dbt.data = argp->newitem.data;
00421 dbt.size = argp->newitem.size;
00422 grow = argp->newitem.size - argp->olditem.size;
00423 LSN(pagep) = *lsnp;
00424 } else if (cmp_n == 0 && DB_UNDO(op)) {
00425 change = 1;
00426
00427 dbt.data = argp->olditem.data;
00428 dbt.size = argp->olditem.size;
00429 grow = argp->olditem.size - argp->newitem.size;
00430 LSN(pagep) = argp->pagelsn;
00431 } else {
00432 change = 0;
00433 grow = 0;
00434 }
00435
00436 if (change) {
00437 CDB___ham_onpage_replace(pagep,
00438 file_dbp->pgsize, argp->ndx, argp->off, grow, &dbt);
00439 if (argp->makedup) {
00440 hk = P_ENTRY(pagep, argp->ndx);
00441 if (DB_REDO(op))
00442 HPAGE_PTYPE(hk) = H_DUPLICATE;
00443 else
00444 HPAGE_PTYPE(hk) = H_KEYDATA;
00445 }
00446 }
00447
00448 if ((ret = CDB___ham_put_page(file_dbp, pagep, change)) != 0)
00449 goto out;
00450
00451 done: *lsnp = argp->prev_lsn;
00452 ret = 0;
00453
00454 out: if (getmeta)
00455 (void)CDB___ham_release_meta(dbc);
00456 REC_CLOSE;
00457 }
00458
00459
00460
00461
00462
00463
00464
00465 int
00466 CDB___ham_splitdata_recover(dbenv, dbtp, lsnp, op, info)
00467 DB_ENV *dbenv;
00468 DBT *dbtp;
00469 DB_LSN *lsnp;
00470 db_recops op;
00471 void *info;
00472 {
00473 __ham_splitdata_args *argp;
00474 DB *file_dbp;
00475 DBC *dbc;
00476 DB_MPOOLFILE *mpf;
00477 PAGE *pagep;
00478 int change, cmp_n, cmp_p, getmeta, ret;
00479
00480 COMPQUIET(info, NULL);
00481
00482 getmeta = 0;
00483 REC_PRINT(CDB___ham_splitdata_print);
00484 REC_INTRO(CDB___ham_splitdata_read, 1);
00485
00486 if ((ret = CDB_memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00487 if (DB_UNDO(op)) {
00488
00489
00490
00491
00492
00493
00494 goto done;
00495 } else if ((ret = CDB_memp_fget(mpf, &argp->pgno,
00496 DB_MPOOL_CREATE, &pagep)) != 0)
00497 goto out;
00498 }
00499
00500 if ((ret = CDB___ham_get_meta(dbc)) != 0)
00501 goto out;
00502 getmeta = 1;
00503
00504 cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00505 cmp_p = CDB_log_compare(&LSN(pagep), &argp->pagelsn);
00506 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->pagelsn);
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 change = 0;
00519 if (cmp_p == 0 && DB_REDO(op)) {
00520 if (argp->opcode == SPLITNEW)
00521
00522 memcpy(pagep, argp->pageimage.data,
00523 argp->pageimage.size);
00524 LSN(pagep) = *lsnp;
00525 change = 1;
00526 } else if (cmp_n == 0 && DB_UNDO(op)) {
00527 if (argp->opcode == SPLITOLD) {
00528
00529 memcpy(pagep, argp->pageimage.data,
00530 argp->pageimage.size);
00531 } else
00532 P_INIT(pagep, file_dbp->pgsize, argp->pgno,
00533 PGNO_INVALID, PGNO_INVALID, 0, P_HASH, 0);
00534 LSN(pagep) = argp->pagelsn;
00535 change = 1;
00536 }
00537 if ((ret = CDB___ham_put_page(file_dbp, pagep, change)) != 0)
00538 goto out;
00539
00540 done: *lsnp = argp->prev_lsn;
00541 ret = 0;
00542
00543 out: if (getmeta)
00544 (void)CDB___ham_release_meta(dbc);
00545 REC_CLOSE;
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555 int
00556 CDB___ham_copypage_recover(dbenv, dbtp, lsnp, op, info)
00557 DB_ENV *dbenv;
00558 DBT *dbtp;
00559 DB_LSN *lsnp;
00560 db_recops op;
00561 void *info;
00562 {
00563 __ham_copypage_args *argp;
00564 DB *file_dbp;
00565 DBC *dbc;
00566 DB_MPOOLFILE *mpf;
00567 PAGE *pagep;
00568 int cmp_n, cmp_p, getmeta, modified, ret;
00569
00570 COMPQUIET(info, NULL);
00571
00572 getmeta = 0;
00573 REC_PRINT(CDB___ham_copypage_print);
00574 REC_INTRO(CDB___ham_copypage_read, 1);
00575
00576 if ((ret = CDB___ham_get_meta(dbc)) != 0)
00577 goto out;
00578 getmeta = 1;
00579 modified = 0;
00580
00581
00582 if ((ret = CDB_memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
00583 if (DB_UNDO(op)) {
00584
00585
00586
00587
00588
00589
00590 ret = 0;
00591 goto donext;
00592 } else if ((ret = CDB_memp_fget(mpf, &argp->pgno,
00593 DB_MPOOL_CREATE, &pagep)) != 0)
00594 goto out;
00595 }
00596
00597 cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00598 cmp_p = CDB_log_compare(&LSN(pagep), &argp->pagelsn);
00599 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->pagelsn);
00600
00601 if (cmp_p == 0 && DB_REDO(op)) {
00602
00603 memcpy(pagep, argp->page.data, argp->page.size);
00604 LSN(pagep) = *lsnp;
00605 modified = 1;
00606 } else if (cmp_n == 0 && DB_UNDO(op)) {
00607
00608 P_INIT(pagep, file_dbp->pgsize, argp->pgno, PGNO_INVALID,
00609 argp->next_pgno, 0, P_HASH, 0);
00610 LSN(pagep) = argp->pagelsn;
00611 modified = 1;
00612 }
00613 if ((ret = CDB_memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00614 goto out;
00615
00616 donext:
00617 if ((ret = CDB_memp_fget(mpf, &argp->next_pgno, 0, &pagep)) != 0) {
00618 if (DB_UNDO(op)) {
00619
00620
00621
00622
00623
00624
00625 ret = 0;
00626 goto do_nn;
00627 } else if ((ret = CDB_memp_fget(mpf, &argp->next_pgno,
00628 DB_MPOOL_CREATE, &pagep)) != 0)
00629 goto out;
00630 }
00631
00632 modified = 0;
00633
00634 cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00635 cmp_p = CDB_log_compare(&LSN(pagep), &argp->nextlsn);
00636 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->nextlsn);
00637 if (cmp_p == 0 && DB_REDO(op)) {
00638 LSN(pagep) = *lsnp;
00639 modified = 1;
00640 } else if (cmp_n == 0 && DB_UNDO(op)) {
00641
00642 memcpy(pagep, argp->page.data, argp->page.size);
00643 modified = 1;
00644 }
00645 if ((ret = CDB_memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00646 goto out;
00647
00648
00649 do_nn: if (argp->nnext_pgno == PGNO_INVALID)
00650 goto done;
00651
00652 if ((ret = CDB_memp_fget(mpf, &argp->nnext_pgno, 0, &pagep)) != 0) {
00653 if (DB_UNDO(op)) {
00654
00655
00656
00657
00658
00659
00660 goto done;
00661 } else if ((ret = CDB_memp_fget(mpf, &argp->nnext_pgno,
00662 DB_MPOOL_CREATE, &pagep)) != 0)
00663 goto out;
00664 }
00665
00666 modified = 0;
00667 cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00668 cmp_p = CDB_log_compare(&LSN(pagep), &argp->nnextlsn);
00669 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->nnextlsn);
00670
00671 if (cmp_p == 0 && DB_REDO(op)) {
00672
00673 PREV_PGNO(pagep) = argp->pgno;
00674 LSN(pagep) = *lsnp;
00675 modified = 1;
00676 } else if (cmp_n == 0 && DB_UNDO(op)) {
00677
00678 PREV_PGNO(pagep) = argp->next_pgno;
00679 LSN(pagep) = argp->nnextlsn;
00680 modified = 1;
00681 }
00682 if ((ret = CDB_memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00683 goto out;
00684
00685 done: *lsnp = argp->prev_lsn;
00686 ret = 0;
00687
00688 out: if (getmeta)
00689 (void)CDB___ham_release_meta(dbc);
00690 REC_CLOSE;
00691 }
00692
00693
00694
00695
00696
00697
00698
00699
00700 int
00701 CDB___ham_metagroup_recover(dbenv, dbtp, lsnp, op, info)
00702 DB_ENV *dbenv;
00703 DBT *dbtp;
00704 DB_LSN *lsnp;
00705 db_recops op;
00706 void *info;
00707 {
00708 __ham_metagroup_args *argp;
00709 HASH_CURSOR *hcp;
00710 DB *file_dbp;
00711 DBC *dbc;
00712 DB_MPOOLFILE *mpf;
00713 PAGE *pagep;
00714 db_pgno_t last_pgno;
00715 int cmp_n, cmp_p, groupgrow, modified, ret;
00716
00717 COMPQUIET(info, NULL);
00718 REC_PRINT(CDB___ham_metagroup_print);
00719 REC_INTRO(CDB___ham_metagroup_read, 1);
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732 groupgrow =
00733 (u_int32_t)(1 << CDB___db_log2(argp->bucket + 1)) == argp->bucket + 1;
00734
00735 last_pgno = argp->pgno;
00736 if (groupgrow)
00737
00738 last_pgno += argp->bucket;
00739
00740 if ((ret = CDB_memp_fget(mpf, &last_pgno, DB_MPOOL_CREATE, &pagep)) != 0)
00741 goto out;
00742
00743 modified = 0;
00744 cmp_n = CDB_log_compare(lsnp, &LSN(pagep));
00745 cmp_p = CDB_log_compare(&LSN(pagep), &argp->pagelsn);
00746 CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->pagelsn);
00747
00748 if ((cmp_p == 0 && DB_REDO(op)) || (cmp_n == 0 && DB_UNDO(op))) {
00749
00750
00751
00752
00753 if (DB_REDO(op))
00754 pagep->lsn = *lsnp;
00755 else
00756 pagep->lsn = argp->pagelsn;
00757 modified = 1;
00758 }
00759 if ((ret = CDB_memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00760 goto out;
00761
00762
00763 hcp = (HASH_CURSOR *)dbc->internal;
00764 if ((ret = CDB___ham_get_meta(dbc)) != 0)
00765 goto out;
00766 cmp_n = CDB_log_compare(lsnp, &hcp->hdr->dbmeta.lsn);
00767 cmp_p = CDB_log_compare(&hcp->hdr->dbmeta.lsn, &argp->metalsn);
00768 CHECK_LSN(op, cmp_p, &hcp->hdr->dbmeta.lsn, &argp->metalsn);
00769 if ((cmp_p == 0 && DB_REDO(op)) || (cmp_n == 0 && DB_UNDO(op))) {
00770 if (DB_REDO(op)) {
00771
00772 ++hcp->hdr->max_bucket;
00773 if (groupgrow) {
00774 hcp->hdr->low_mask = hcp->hdr->high_mask;
00775 hcp->hdr->high_mask =
00776 (argp->bucket + 1) | hcp->hdr->low_mask;
00777 }
00778 hcp->hdr->dbmeta.lsn = *lsnp;
00779 } else {
00780
00781 --hcp->hdr->max_bucket;
00782 if (groupgrow) {
00783 hcp->hdr->high_mask = hcp->hdr->low_mask;
00784 hcp->hdr->low_mask = hcp->hdr->high_mask >> 1;
00785 }
00786 hcp->hdr->dbmeta.lsn = argp->metalsn;
00787 }
00788 if (groupgrow &&
00789 hcp->hdr->spares[CDB___db_log2(argp->bucket + 1) + 1] ==
00790 PGNO_INVALID)
00791 hcp->hdr->spares[CDB___db_log2(argp->bucket + 1) + 1] =
00792 argp->pgno - argp->bucket - 1;
00793 F_SET(hcp, H_DIRTY);
00794 }
00795 if ((ret = CDB___ham_release_meta(dbc)) != 0)
00796 goto out;
00797
00798 done: *lsnp = argp->prev_lsn;
00799 ret = 0;
00800
00801 out: REC_CLOSE;
00802 }
00803
00804
00805
00806
00807
00808
00809
00810
00811 int
00812 CDB___ham_groupalloc_recover(dbenv, dbtp, lsnp, op, info)
00813 DB_ENV *dbenv;
00814 DBT *dbtp;
00815 DB_LSN *lsnp;
00816 db_recops op;
00817 void *info;
00818 {
00819 __ham_groupalloc_args *argp;
00820 DBMETA *mmeta;
00821 DB_MPOOLFILE *mpf;
00822 DB *file_dbp;
00823 DBC *dbc;
00824 db_pgno_t pgno;
00825 int cmp_n, cmp_p, modified, ret;
00826
00827 modified = 0;
00828 COMPQUIET(info, NULL);
00829 REC_PRINT(CDB___ham_groupalloc_print);
00830 REC_INTRO(CDB___ham_groupalloc_read, 0);
00831
00832 pgno = PGNO_BASE_MD;
00833 if ((ret = CDB_memp_fget(mpf, &pgno, 0, &mmeta)) != 0) {
00834 if (DB_REDO(op)) {
00835
00836 (void)CDB___db_pgerr(file_dbp, pgno);
00837 goto out;
00838 } else {
00839 ret = 0;
00840 goto done;
00841 }
00842 }
00843
00844 cmp_n = CDB_log_compare(lsnp, &mmeta->alloc_lsn);
00845 cmp_p = CDB_log_compare(&mmeta->alloc_lsn, &argp->alloc_lsn);
00846 CHECK_LSN(op, cmp_p, &mmeta->alloc_lsn, &argp->alloc_lsn);
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858 if (DB_REDO(op)) {
00859 if ((ret = __ham_alloc_pages(file_dbp, argp)) != 0)
00860 goto out1;
00861 if (cmp_p == 0) {
00862 mmeta->alloc_lsn = *lsnp;
00863 if (CDB_log_compare(&LSN(mmeta), &argp->meta_lsn) == 0)
00864 LSN(mmeta) = *lsnp;
00865 modified = 1;
00866 }
00867 }
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879 else if (DB_UNDO(op)) {
00880 if (cmp_n != 0 ||
00881 (mmeta->free >= argp->start_pgno &&
00882 mmeta->free < argp->start_pgno + argp->num))
00883 mmeta->free = argp->free;
00884 if ((ret = __ham_free_pages(file_dbp, mmeta, argp)) != 0)
00885 goto out1;
00886 mmeta->alloc_lsn = argp->alloc_lsn;
00887 if (CDB_log_compare(lsnp, &LSN(mmeta)) == 0)
00888 LSN(mmeta) = argp->meta_lsn;
00889 modified = 1;
00890 }
00891
00892 out1: if ((ret = CDB_memp_fput(mpf, mmeta, modified ? DB_MPOOL_DIRTY : 0)) != 0)
00893 goto out;
00894
00895 done: if (ret == 0)
00896 *lsnp = argp->prev_lsn;
00897
00898 out: REC_CLOSE;
00899 }
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913 static int
00914 __ham_free_pages(dbp, mmeta, argp)
00915 DB *dbp;
00916 DBMETA *mmeta;
00917 __ham_groupalloc_args *argp;
00918 {
00919 DB_MPOOLFILE *mpf;
00920 PAGE *pagep;
00921 u_int32_t i;
00922 db_pgno_t last_free, pgno;
00923 int ret;
00924
00925 mpf = dbp->mpf;
00926 last_free = mmeta->free;
00927
00928 for (i = 0; i < argp->num; i++, last_free = pgno) {
00929 pgno = argp->start_pgno + i;
00930 if ((ret =
00931 CDB_memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &pagep)) != 0) {
00932 (void)CDB___db_pgerr(dbp, pgno);
00933 return (ret);
00934 }
00935
00936
00937 P_INIT(pagep,
00938 dbp->pgsize, pgno, PGNO_INVALID, last_free, 0, P_INVALID, 0);
00939 ZERO_LSN(pagep->lsn);
00940
00941 if ((ret = CDB_memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0)
00942 return (ret);
00943 }
00944
00945 mmeta->free = last_free;
00946 return (0);
00947 }
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959 static int
00960 __ham_alloc_pages(dbp, argp)
00961 DB *dbp;
00962 __ham_groupalloc_args *argp;
00963 {
00964 DB_MPOOLFILE *mpf;
00965 PAGE *pagep;
00966 db_pgno_t pgno;
00967 int ret;
00968
00969 mpf = dbp->mpf;
00970
00971
00972 pgno = argp->start_pgno + argp->num - 1;
00973
00974
00975 if ((ret = CDB_memp_fget(mpf, &pgno, 0, &pagep)) == 0) {
00976 if ((TYPE(pagep) == P_INVALID) && IS_ZERO_LSN(pagep->lsn))
00977 goto reinit_page;
00978 if ((ret = CDB_memp_fput(mpf, pagep, 0)) != 0)
00979 return (ret);
00980 return (0);
00981 }
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991 if ((ret = CDB___os_fpinit(dbp->dbenv, &mpf->fh,
00992 argp->start_pgno, argp->num, dbp->pgsize)) != 0)
00993 return (ret);
00994
00995 if ((ret = CDB_memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &pagep)) != 0) {
00996 (void)CDB___db_pgerr(dbp, pgno);
00997 return (ret);
00998 }
00999
01000 reinit_page:
01001
01002 P_INIT(pagep,
01003 dbp->pgsize, pgno, PGNO_INVALID, PGNO_INVALID, 0, P_HASH, 0);
01004 ZERO_LSN(pagep->lsn);
01005
01006 if ((ret = CDB_memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0)
01007 return (ret);
01008
01009 return (0);
01010 }