qam_stat.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:4k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1999, 2000
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char revid[] = "$Id: qam_stat.c,v 11.16 2001/01/10 04:50:54 ubell Exp $";
  10. #endif /* not lint */
  11. #ifndef NO_SYSTEM_INCLUDES
  12. #include <sys/types.h>
  13. #include <string.h>
  14. #endif
  15. #include "db_int.h"
  16. #include "db_page.h"
  17. #include "db_shash.h"
  18. #include "db_am.h"
  19. #include "lock.h"
  20. #include "qam.h"
  21. /*
  22.  * __qam_stat --
  23.  * Gather/print the qam statistics
  24.  *
  25.  * PUBLIC: int __qam_stat __P((DB *, void *, void *(*)(size_t), u_int32_t));
  26.  */
  27. int
  28. __qam_stat(dbp, spp, db_malloc, flags)
  29. DB *dbp;
  30. void *spp;
  31. void *(*db_malloc) __P((size_t));
  32. u_int32_t flags;
  33. {
  34. QUEUE *t;
  35. DBC *dbc;
  36. DB_LOCK lock;
  37. DB_QUEUE_STAT *sp;
  38. PAGE *h;
  39. QAMDATA *qp, *ep;
  40. QMETA *meta;
  41. db_indx_t indx;
  42. db_pgno_t first, last, pgno, pg_ext, stop;
  43. u_int32_t re_len;
  44. int ret, t_ret;
  45. PANIC_CHECK(dbp->dbenv);
  46. DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->stat");
  47. t = dbp->q_internal;
  48. sp = NULL;
  49. lock.off = LOCK_INVALID;
  50. /* Check for invalid flags. */
  51. if ((ret = __db_statchk(dbp, flags)) != 0)
  52. return (ret);
  53. if (spp == NULL)
  54. return (0);
  55. /* Acquire a cursor. */
  56. if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0)
  57. return (ret);
  58. DEBUG_LWRITE(dbc, NULL, "qam_stat", NULL, NULL, flags);
  59. /* Allocate and clear the structure. */
  60. if ((ret = __os_malloc(dbp->dbenv, sizeof(*sp), db_malloc, &sp)) != 0)
  61. goto err;
  62. memset(sp, 0, sizeof(*sp));
  63. re_len = ((QUEUE *)dbp->q_internal)->re_len;
  64. if (flags == DB_CACHED_COUNTS) {
  65. if ((ret = __db_lget(dbc,
  66.     0, t->q_meta, DB_LOCK_READ, 0, &lock)) != 0)
  67. goto err;
  68. if ((ret =
  69.     memp_fget(dbp->mpf, &t->q_meta, 0, (PAGE **)&meta)) != 0)
  70. goto err;
  71. sp->qs_nkeys = meta->dbmeta.key_count;
  72. sp->qs_ndata = meta->dbmeta.record_count;
  73. goto done;
  74. }
  75. /* Determine the last page of the database. */
  76. if ((ret = __db_lget(dbc,
  77.     0, t->q_meta, DB_LOCK_READ, 0, &lock)) != 0)
  78. goto err;
  79. if ((ret = memp_fget(dbp->mpf, &t->q_meta, 0, (PAGE **)&meta)) != 0)
  80. goto err;
  81. first = QAM_RECNO_PAGE(dbp, meta->first_recno);
  82. last = QAM_RECNO_PAGE(dbp, meta->cur_recno);
  83. if ((ret = memp_fput(dbp->mpf, meta, 0)) != 0)
  84. goto err;
  85. (void)__LPUT(dbc, lock);
  86. pgno = first;
  87. if (first > last)
  88. stop = QAM_RECNO_PAGE(dbp, UINT32_T_MAX);
  89. else
  90. stop = last;
  91. /* Dump each page. */
  92. pg_ext = ((QUEUE *)dbp->q_internal)->page_ext;
  93. begin:
  94. /* Walk through the pages and count. */
  95. for (; pgno <= stop; ++pgno) {
  96. if ((ret =
  97.     __db_lget(dbc,
  98.     0, pgno, DB_LOCK_READ, 0, &lock)) != 0)
  99. goto err;
  100. ret = __qam_fget(dbp, &pgno, DB_MPOOL_EXTENT, &h);
  101. if (ret == ENOENT) {
  102. pgno += pg_ext - 1;
  103. continue;
  104. }
  105. if (ret == EINVAL) {
  106. pgno += pg_ext - ((pgno - 1) % pg_ext) - 1;
  107. continue;
  108. }
  109. if (ret == EIO && first == last && pg_ext == 0)
  110. break;
  111. if (ret != 0)
  112. goto err;
  113. ++sp->qs_pages;
  114. ep = (QAMDATA *)((u_int8_t *)h + dbp->pgsize - re_len);
  115. for (indx = 0, qp = QAM_GET_RECORD(dbp, h, indx);
  116.     qp <= ep;
  117.     ++indx,  qp = QAM_GET_RECORD(dbp, h, indx)) {
  118. if (F_ISSET(qp, QAM_VALID))
  119. sp->qs_ndata++;
  120. else
  121. sp->qs_pgfree += re_len;
  122. }
  123. if ((ret = __qam_fput(dbp, pgno, h, 0)) != 0)
  124. goto err;
  125. (void)__LPUT(dbc, lock);
  126. }
  127. if (first > last) {
  128. pgno = 1;
  129. stop = last;
  130. first = last;
  131. goto begin;
  132. }
  133. /* Get the meta-data page. */
  134. if ((ret = __db_lget(dbc,
  135.     0, t->q_meta, F_ISSET(dbp, DB_AM_RDONLY) ?
  136.     DB_LOCK_READ : DB_LOCK_WRITE, 0, &lock)) != 0)
  137. goto err;
  138. if ((ret = memp_fget(dbp->mpf, &t->q_meta, 0, (PAGE **)&meta)) != 0)
  139. goto err;
  140. /* Get the metadata fields. */
  141. sp->qs_magic = meta->dbmeta.magic;
  142. sp->qs_version = meta->dbmeta.version;
  143. sp->qs_metaflags = meta->dbmeta.flags;
  144. sp->qs_pagesize = meta->dbmeta.pagesize;
  145. sp->qs_re_len = meta->re_len;
  146. sp->qs_re_pad = meta->re_pad;
  147. sp->qs_first_recno = meta->first_recno;
  148. sp->qs_cur_recno = meta->cur_recno;
  149. sp->qs_nkeys = sp->qs_ndata;
  150. if (!F_ISSET(dbp, DB_AM_RDONLY))
  151. meta->dbmeta.key_count =
  152.     meta->dbmeta.record_count = sp->qs_ndata;
  153. done:
  154. /* Discard the meta-data page. */
  155. if ((ret = memp_fput(dbp->mpf,
  156.     meta, F_ISSET(dbp, DB_AM_RDONLY) ? 0 : DB_MPOOL_DIRTY)) != 0)
  157. goto err;
  158. (void)__LPUT(dbc, lock);
  159. *(DB_QUEUE_STAT **)spp = sp;
  160. ret = 0;
  161. if (0) {
  162. err: if (sp != NULL)
  163. __os_free(sp, sizeof(*sp));
  164. }
  165. if (lock.off != LOCK_INVALID)
  166. (void)__LPUT(dbc, lock);
  167. if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0)
  168. ret = t_ret;
  169. return (ret);
  170. }