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__stat_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 <string.h> 00018 #endif 00019 00020 #include "db_int.h" 00021 #include "db_page.h" 00022 #include "db_shash.h" 00023 #include "db_am.h" 00024 #include "lock.h" 00025 #include "qam.h" 00026 00027 /* 00028 * CDB___qam_stat -- 00029 * Gather/print the qam statistics 00030 * 00031 * PUBLIC: int CDB___qam_stat __P((DB *, void *, void *(*)(size_t), u_int32_t)); 00032 */ 00033 int 00034 CDB___qam_stat(dbp, spp, db_malloc, flags) 00035 DB *dbp; 00036 void *spp; 00037 void *(*db_malloc) __P((size_t)); 00038 u_int32_t flags; 00039 { 00040 QUEUE *t; 00041 DBC *dbc; 00042 DB_LOCK lock; 00043 DB_QUEUE_STAT *sp; 00044 PAGE *h; 00045 QAMDATA *qp, *ep; 00046 QMETA *meta; 00047 db_indx_t indx; 00048 db_pgno_t lastpgno, pgno; 00049 u_int32_t re_len; 00050 int ret, t_ret; 00051 00052 PANIC_CHECK(dbp->dbenv); 00053 DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->stat"); 00054 00055 t = dbp->q_internal; 00056 sp = NULL; 00057 lock.off = LOCK_INVALID; 00058 00059 /* Check for invalid flags. */ 00060 if ((ret = CDB___db_statchk(dbp, flags)) != 0) 00061 return (ret); 00062 00063 if (spp == NULL) 00064 return (0); 00065 00066 /* Acquire a cursor. */ 00067 if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0) 00068 return (ret); 00069 00070 DEBUG_LWRITE(dbc, NULL, "qam_stat", NULL, NULL, flags); 00071 00072 /* Allocate and clear the structure. */ 00073 if ((ret = CDB___os_malloc(dbp->dbenv, sizeof(*sp), db_malloc, &sp)) != 0) 00074 goto err; 00075 memset(sp, 0, sizeof(*sp)); 00076 00077 re_len = ((QUEUE *)dbp->q_internal)->re_len; 00078 if (flags == DB_CACHED_COUNTS) { 00079 if ((ret = CDB___db_lget(dbc, 00080 0, t->q_meta, DB_LOCK_READ, 0, &lock)) != 0) 00081 goto err; 00082 if ((ret = 00083 CDB_memp_fget(dbp->mpf, &t->q_meta, 0, (PAGE **)&meta)) != 0) 00084 goto err; 00085 sp->qs_nkeys = meta->dbmeta.key_count; 00086 sp->qs_ndata = meta->dbmeta.record_count; 00087 00088 goto done; 00089 } 00090 00091 /* Determine the last page of the database. */ 00092 if ((ret = CDB_memp_fget(dbp->mpf, &lastpgno, DB_MPOOL_LAST, &h)) != 0) 00093 goto err; 00094 if ((ret = CDB_memp_fput(dbp->mpf, h, 0)) != 0) 00095 goto err; 00096 00097 /* Walk through the pages and count. */ 00098 for (pgno = t->q_root; pgno <= lastpgno; ++pgno) { 00099 if ((ret = 00100 CDB___db_lget(dbc, 0, pgno, DB_LOCK_READ, 0, &lock)) != 0) 00101 goto err; 00102 if ((ret = CDB_memp_fget(dbp->mpf, &pgno, 0, &h)) != 0) 00103 goto err; 00104 00105 ++sp->qs_pages; 00106 00107 ep = (QAMDATA *)((u_int8_t *)h + dbp->pgsize - re_len); 00108 for (indx = 0, qp = QAM_GET_RECORD(dbp, h, indx); 00109 qp <= ep; 00110 ++indx, qp = QAM_GET_RECORD(dbp, h, indx)) { 00111 if (F_ISSET(qp, QAM_VALID)) 00112 sp->qs_ndata++; 00113 else 00114 sp->qs_pgfree += re_len; 00115 } 00116 00117 if ((ret = CDB_memp_fput(dbp->mpf, h, 0)) != 0) 00118 goto err; 00119 (void)__LPUT(dbc, lock); 00120 } 00121 00122 /* Get the meta-data page. */ 00123 if ((ret = CDB___db_lget(dbc, 00124 0, t->q_meta, F_ISSET(dbp, DB_AM_RDONLY) ? 00125 DB_LOCK_READ : DB_LOCK_WRITE, 0, &lock)) != 0) 00126 goto err; 00127 if ((ret = CDB_memp_fget(dbp->mpf, &t->q_meta, 0, (PAGE **)&meta)) != 0) 00128 goto err; 00129 00130 /* Get the metadata fields. */ 00131 sp->qs_magic = meta->dbmeta.magic; 00132 sp->qs_version = meta->dbmeta.version; 00133 sp->qs_metaflags = meta->dbmeta.flags; 00134 sp->qs_pagesize = meta->dbmeta.pagesize; 00135 sp->qs_re_len = meta->re_len; 00136 sp->qs_re_pad = meta->re_pad; 00137 sp->qs_start = meta->start; 00138 sp->qs_first_recno = meta->first_recno; 00139 sp->qs_cur_recno = meta->cur_recno; 00140 sp->qs_nkeys = sp->qs_ndata; 00141 if (!F_ISSET(dbp, DB_AM_RDONLY)) 00142 meta->dbmeta.key_count = 00143 meta->dbmeta.record_count = sp->qs_ndata; 00144 00145 done: 00146 /* Discard the meta-data page. */ 00147 if ((ret = CDB_memp_fput(dbp->mpf, meta, !F_ISSET(dbp, DB_AM_RDONLY))) != 0) 00148 goto err; 00149 (void)__LPUT(dbc, lock); 00150 00151 *(DB_QUEUE_STAT **)spp = sp; 00152 ret = 0; 00153 00154 if (0) { 00155 err: if (sp != NULL) 00156 CDB___os_free(sp, sizeof(*sp)); 00157 } 00158 00159 if (lock.off != LOCK_INVALID) 00160 (void)__LPUT(dbc, lock); 00161 00162 if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0) 00163 ret = t_ret; 00164 00165 return (ret); 00166 }