Update.
[glibc.git] / db2 / btree / bt_stat.c
blob2236434b384d7d304c60b5bd264d281bfd38d583
1 /*-
2 * See the file LICENSE for redistribution information.
4 * Copyright (c) 1996, 1997, 1998
5 * Sleepycat Software. All rights reserved.
6 */
8 #include "config.h"
10 #ifndef lint
11 static const char sccsid[] = "@(#)bt_stat.c 10.17 (Sleepycat) 4/26/98";
12 #endif /* not lint */
14 #ifndef NO_SYSTEM_INCLUDES
15 #include <sys/types.h>
17 #include <errno.h>
18 #include <string.h>
19 #endif
21 #include "db_int.h"
22 #include "db_page.h"
23 #include "btree.h"
25 static void __bam_add_rstat __P((DB_BTREE_LSTAT *, DB_BTREE_STAT *));
28 * __bam_stat --
29 * Gather/print the btree statistics
31 * PUBLIC: int __bam_stat __P((DB *, void *, void *(*)(size_t), u_int32_t));
33 int
34 __bam_stat(argdbp, spp, db_malloc, flags)
35 DB *argdbp;
36 void *spp;
37 void *(*db_malloc) __P((size_t));
38 u_int32_t flags;
40 BTMETA *meta;
41 BTREE *t;
42 DB *dbp;
43 DB_BTREE_STAT *sp;
44 DB_LOCK lock;
45 PAGE *h;
46 db_pgno_t lastpgno, pgno;
47 int ret;
49 DEBUG_LWRITE(argdbp, NULL, "bam_stat", NULL, NULL, flags);
51 /* Check for invalid flags. */
52 if ((ret = __db_statchk(argdbp, flags)) != 0)
53 return (ret);
55 if (spp == NULL)
56 return (0);
58 GETHANDLE(argdbp, NULL, &dbp, ret);
59 t = dbp->internal;
61 /* Allocate and clear the structure. */
62 if ((sp = db_malloc == NULL ?
63 (DB_BTREE_STAT *)__db_malloc(sizeof(*sp)) :
64 (DB_BTREE_STAT *)db_malloc(sizeof(*sp))) == NULL) {
65 ret = ENOMEM;
66 goto err;
68 memset(sp, 0, sizeof(*sp));
70 /* If the app just wants the record count, make it fast. */
71 if (LF_ISSET(DB_RECORDCOUNT)) {
72 pgno = PGNO_ROOT;
73 if ((ret = __bam_lget(dbp, 0, pgno, DB_LOCK_READ, &lock)) != 0)
74 goto err;
75 if ((ret = __bam_pget(dbp, (PAGE **)&h, &pgno, 0)) != 0)
76 goto err;
78 sp->bt_nrecs = RE_NREC(h);
80 (void)memp_fput(dbp->mpf, h, 0);
81 (void)__BT_LPUT(dbp, lock);
82 goto done;
85 /* Get the meta-data page. */
86 pgno = PGNO_METADATA;
87 if ((ret = __bam_lget(dbp, 0, pgno, DB_LOCK_READ, &lock)) != 0)
88 goto err;
89 if ((ret = __bam_pget(dbp, (PAGE **)&meta, &pgno, 0)) != 0)
90 goto err;
92 /* Translate the metadata flags. */
93 if (F_ISSET(meta, BTM_DUP))
94 sp->bt_flags |= DB_DUP;
95 if (F_ISSET(meta, BTM_FIXEDLEN))
96 sp->bt_flags |= DB_FIXEDLEN;
97 if (F_ISSET(meta, BTM_RECNUM))
98 sp->bt_flags |= DB_RECNUM;
99 if (F_ISSET(meta, BTM_RENUMBER))
100 sp->bt_flags |= DB_RENUMBER;
102 /* Get the remaining metadata fields. */
103 sp->bt_minkey = meta->minkey;
104 sp->bt_maxkey = meta->maxkey;
105 sp->bt_re_len = meta->re_len;
106 sp->bt_re_pad = meta->re_pad;
107 sp->bt_magic = meta->magic;
108 sp->bt_version = meta->version;
110 /* Get the page size from the DB. */
111 sp->bt_pagesize = dbp->pgsize;
113 /* Initialize counters with the meta-data page information. */
114 __bam_add_rstat(&meta->stat, sp);
117 * Add in the local information from this handle.
119 * !!!
120 * This is a bit odd, but it gets us closer to the truth.
122 __bam_add_rstat(&t->lstat, sp);
124 /* Walk the free list, counting pages. */
125 for (sp->bt_free = 0, pgno = meta->free; pgno != PGNO_INVALID;) {
126 ++sp->bt_free;
128 if ((ret = __bam_pget(dbp, &h, &pgno, 0)) != 0) {
129 (void)memp_fput(dbp->mpf, meta, 0);
130 (void)__BT_TLPUT(dbp, lock);
131 goto err;
133 pgno = h->next_pgno;
134 (void)memp_fput(dbp->mpf, h, 0);
137 /* Discard the meta-data page. */
138 (void)memp_fput(dbp->mpf, meta, 0);
139 (void)__BT_TLPUT(dbp, lock);
141 /* Determine the last page of the database. */
142 if ((ret = memp_fget(dbp->mpf, &lastpgno, DB_MPOOL_LAST, &h)) != 0)
143 goto err;
144 (void)memp_fput(dbp->mpf, h, 0);
146 /* Get the root page. */
147 pgno = PGNO_ROOT;
148 if ((ret = __bam_lget(dbp, 0, PGNO_ROOT, DB_LOCK_READ, &lock)) != 0)
149 goto err;
150 if ((ret = __bam_pget(dbp, &h, &pgno, 0)) != 0) {
151 (void)__BT_LPUT(dbp, lock);
152 goto err;
155 /* Get the levels from the root page. */
156 sp->bt_levels = h->level;
158 /* Walk the page list, counting things. */
159 for (;;) {
160 switch (TYPE(h)) {
161 case P_INVALID:
162 break;
163 case P_IBTREE:
164 case P_IRECNO:
165 ++sp->bt_int_pg;
166 sp->bt_int_pgfree += HOFFSET(h) - LOFFSET(h);
167 break;
168 case P_LBTREE:
169 ++sp->bt_leaf_pg;
170 sp->bt_leaf_pgfree += HOFFSET(h) - LOFFSET(h);
171 sp->bt_nrecs += NUM_ENT(h) / P_INDX;
172 break;
173 case P_LRECNO:
174 ++sp->bt_leaf_pg;
175 sp->bt_leaf_pgfree += HOFFSET(h) - LOFFSET(h);
176 sp->bt_nrecs += NUM_ENT(h);
177 break;
178 case P_DUPLICATE:
179 ++sp->bt_dup_pg;
180 /* XXX MARGO: sp->bt_dup_pgfree; */
181 break;
182 case P_OVERFLOW:
183 ++sp->bt_over_pg;
184 /* XXX MARGO: sp->bt_over_pgfree; */
185 break;
186 default:
187 (void)memp_fput(dbp->mpf, h, 0);
188 (void)__BT_LPUT(dbp, lock);
189 return (__db_pgfmt(dbp, pgno));
192 (void)memp_fput(dbp->mpf, h, 0);
193 (void)__BT_LPUT(dbp, lock);
195 if (++pgno > lastpgno)
196 break;
197 if (__bam_lget(dbp, 0, pgno, DB_LOCK_READ, &lock))
198 break;
199 if (memp_fget(dbp->mpf, &pgno, 0, &h) != 0) {
200 (void)__BT_LPUT(dbp, lock);
201 break;
205 done: *(DB_BTREE_STAT **)spp = sp;
206 ret = 0;
208 err: PUTHANDLE(dbp);
209 return (ret);
213 * __bam_add_mstat --
214 * Add the local statistics to the meta-data page statistics.
216 * PUBLIC: void __bam_add_mstat __P((DB_BTREE_LSTAT *, DB_BTREE_LSTAT *));
218 void
219 __bam_add_mstat(from, to)
220 DB_BTREE_LSTAT *from;
221 DB_BTREE_LSTAT *to;
223 to->bt_freed += from->bt_freed;
224 to->bt_pfxsaved += from->bt_pfxsaved;
225 to->bt_split += from->bt_split;
226 to->bt_rootsplit += from->bt_rootsplit;
227 to->bt_fastsplit += from->bt_fastsplit;
228 to->bt_added += from->bt_added;
229 to->bt_deleted += from->bt_deleted;
230 to->bt_get += from->bt_get;
231 to->bt_cache_hit += from->bt_cache_hit;
232 to->bt_cache_miss += from->bt_cache_miss;
236 * __bam_add_rstat --
237 * Add the local statistics to the returned statistics.
239 static void
240 __bam_add_rstat(from, to)
241 DB_BTREE_LSTAT *from;
242 DB_BTREE_STAT *to;
244 to->bt_freed += from->bt_freed;
245 to->bt_pfxsaved += from->bt_pfxsaved;
246 to->bt_split += from->bt_split;
247 to->bt_rootsplit += from->bt_rootsplit;
248 to->bt_fastsplit += from->bt_fastsplit;
249 to->bt_added += from->bt_added;
250 to->bt_deleted += from->bt_deleted;
251 to->bt_get += from->bt_get;
252 to->bt_cache_hit += from->bt_cache_hit;
253 to->bt_cache_miss += from->bt_cache_miss;