db_reclaim.c

Go to the documentation of this file.
00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1996, 1997, 1998, 1999, 2000
00005  *      Sleepycat Software.  All rights reserved.
00006  */
00007 
00008 #include "config.h"
00009 
00010 #ifndef lint
00011 static const char revid[] = "$Id: db__reclaim_8c-source.html,v 1.1 2008/06/08 10:18:15 sebdiaz Exp $";
00012 #endif /* not lint */
00013 
00014 #ifndef NO_SYSTEM_INCLUDES
00015 #include <sys/types.h>
00016 #endif
00017 
00018 #include "db_int.h"
00019 #include "db_page.h"
00020 #include "db_am.h"
00021 
00022 /*
00023  * Assume that we enter with a valid pgno.  We traverse a set of
00024  * duplicate pages.  The format of the callback routine is:
00025  * callback(dbp, page, cookie, did_put).  did_put is an output
00026  * value that will be set to 1 by the callback routine if it
00027  * already put the page back.  Otherwise, this routine must
00028  * put the page.
00029  *
00030  * PUBLIC: int CDB___db_traverse_dup __P((DB *,
00031  * PUBLIC:    db_pgno_t, int (*)(DB *, PAGE *, void *, int *), void *));
00032  */
00033 int
00034 CDB___db_traverse_dup(dbp, pgno, callback, cookie)
00035         DB *dbp;
00036         db_pgno_t pgno;
00037         int (*callback) __P((DB *, PAGE *, void *, int *));
00038         void *cookie;
00039 {
00040         PAGE *p;
00041         int did_put, i, opgno, ret;
00042 
00043         do {
00044                 did_put = 0;
00045                 if ((ret = CDB_memp_fget(dbp->mpf, &pgno, 0, &p)) != 0)
00046                         return (ret);
00047                 pgno = NEXT_PGNO(p);
00048 
00049                 for (i = 0; i < NUM_ENT(p); i++) {
00050                         if (B_TYPE(GET_BKEYDATA(p, i)->type) == B_OVERFLOW) {
00051                                 opgno = GET_BOVERFLOW(p, i)->pgno;
00052                                 if ((ret = CDB___db_traverse_big(dbp,
00053                                     opgno, callback, cookie)) != 0)
00054                                         goto err;
00055                         }
00056                 }
00057 
00058                 if ((ret = callback(dbp, p, cookie, &did_put)) != 0)
00059                         goto err;
00060 
00061                 if (!did_put)
00062                         if ((ret = CDB_memp_fput(dbp->mpf, p, 0)) != 0)
00063                                 return (ret);
00064         } while (pgno != PGNO_INVALID);
00065 
00066         if (0) {
00067 err:            if (did_put == 0)
00068                         (void)CDB_memp_fput(dbp->mpf, p, 0);
00069         }
00070         return (ret);
00071 }
00072 
00073 /*
00074  * CDB___db_traverse_big
00075  *      Traverse a chain of overflow pages and call the callback routine
00076  * on each one.  The calling convention for the callback is:
00077  *      callback(dbp, page, cookie, did_put),
00078  * where did_put is a return value indicating if the page in question has
00079  * already been returned to the mpool.
00080  *
00081  * PUBLIC: int CDB___db_traverse_big __P((DB *,
00082  * PUBLIC:     db_pgno_t, int (*)(DB *, PAGE *, void *, int *), void *));
00083  */
00084 int
00085 CDB___db_traverse_big(dbp, pgno, callback, cookie)
00086         DB *dbp;
00087         db_pgno_t pgno;
00088         int (*callback) __P((DB *, PAGE *, void *, int *));
00089         void *cookie;
00090 {
00091         PAGE *p;
00092         int did_put, ret;
00093 
00094         do {
00095                 did_put = 0;
00096                 if ((ret = CDB_memp_fget(dbp->mpf, &pgno, 0, &p)) != 0)
00097                         return (ret);
00098                 pgno = NEXT_PGNO(p);
00099                 if ((ret = callback(dbp, p, cookie, &did_put)) == 0 &&
00100                     !did_put)
00101                         ret = CDB_memp_fput(dbp->mpf, p, 0);
00102         } while (ret == 0 && pgno != PGNO_INVALID);
00103 
00104         return (ret);
00105 }
00106 
00107 /*
00108  * CDB___db_reclaim_callback
00109  * This is the callback routine used during a delete of a subdatabase.
00110  * we are traversing a btree or hash table and trying to free all the
00111  * pages.  Since they share common code for duplicates and overflow
00112  * items, we traverse them identically and use this routine to do the
00113  * actual free.  The reason that this is callback is because hash uses
00114  * the same traversal code for statistics gathering.
00115  *
00116  * PUBLIC: int CDB___db_reclaim_callback __P((DB *, PAGE *, void *, int *));
00117  */
00118 int
00119 CDB___db_reclaim_callback(dbp, p, cookie, putp)
00120         DB *dbp;
00121         PAGE *p;
00122         void *cookie;
00123         int *putp;
00124 {
00125         int ret;
00126 
00127         COMPQUIET(dbp, NULL);
00128 
00129         if ((ret = CDB___db_free(cookie, p)) != 0)
00130                 return (ret);
00131         *putp = 1;
00132 
00133         return (0);
00134 }

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