2 * Copyright (c) 1990, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * @(#)bt_debug.c 8.5 (Berkeley) 8/17/94
33 * $DragonFly: src/lib/libc/db/btree/bt_debug.c,v 1.4 2005/11/12 23:01:54 swildner Exp $
36 #include <sys/param.h>
47 * BT_DUMP -- Dump the tree
50 * dbp: pointer to the DB
61 fprintf(stderr
, "%s: pgsz %d",
62 F_ISSET(t
, B_INMEM
) ? "memory" : "disk", t
->bt_psize
);
63 if (F_ISSET(t
, R_RECNO
))
64 fprintf(stderr
, " keys %u", t
->bt_nrecs
);
66 #define X(flag, name) \
67 if (F_ISSET(t, flag)) { \
68 fprintf(stderr, "%s%s", sep, name); \
73 X(R_FIXLEN
, "FIXLEN");
75 X(B_NODUPS
, "NODUPS");
76 X(B_RDONLY
, "RDONLY");
78 X(B_METADIRTY
,"METADIRTY");
79 fprintf(stderr
, ")\n");
83 for (i
= P_ROOT
; (h
= mpool_get(t
->bt_mp
, i
, 0)) != NULL
; ++i
) {
85 mpool_put(t
->bt_mp
, h
, 0);
90 * BT_DMPAGE -- Dump the meta page
93 * h: pointer to the PAGE
102 fprintf(stderr
, "magic %x\n", m
->magic
);
103 fprintf(stderr
, "version %u\n", m
->version
);
104 fprintf(stderr
, "psize %u\n", m
->psize
);
105 fprintf(stderr
, "free %u\n", m
->free
);
106 fprintf(stderr
, "nrecs %u\n", m
->nrecs
);
107 fprintf(stderr
, "flags %u", m
->flags
);
109 #define X(flag, name) \
110 if (m->flags & flag) { \
111 fprintf(stderr, "%s%s", sep, name); \
116 X(B_NODUPS
, "NODUPS");
118 fprintf(stderr
, ")");
123 * BT_DNPAGE -- Dump the page
126 * n: page number to dump.
129 __bt_dnpage(DB
*dbp
, pgno_t pgno
)
135 if ((h
= mpool_get(t
->bt_mp
, pgno
, 0)) != NULL
) {
137 mpool_put(t
->bt_mp
, h
, 0);
142 * BT_DPAGE -- Dump the page
145 * h: pointer to the PAGE
157 fprintf(stderr
, " page %d: (", h
->pgno
);
159 #define X(flag, name) \
160 if (h->flags & flag) { \
161 fprintf(stderr, "%s%s", sep, name); \
165 X(P_BINTERNAL
, "BINTERNAL") /* types */
167 X(P_RINTERNAL
, "RINTERNAL") /* types */
169 X(P_OVERFLOW
, "OVERFLOW")
170 X(P_PRESERVE
, "PRESERVE");
171 fprintf(stderr
, ")\n");
174 fprintf(stderr
, "\tprev %2d next %2d", h
->prevpg
, h
->nextpg
);
175 if (h
->flags
& P_OVERFLOW
)
179 fprintf(stderr
, " lower %3d upper %3d nextind %d\n",
180 h
->lower
, h
->upper
, top
);
181 for (cur
= 0; cur
< top
; cur
++) {
182 fprintf(stderr
, "\t[%03d] %4d ", cur
, h
->linp
[cur
]);
183 switch (h
->flags
& P_TYPE
) {
185 bi
= GETBINTERNAL(h
, cur
);
187 "size %03d pgno %03d", bi
->ksize
, bi
->pgno
);
188 if (bi
->flags
& P_BIGKEY
)
189 fprintf(stderr
, " (indirect)");
192 " {%.*s}", (int)bi
->ksize
, bi
->bytes
);
195 ri
= GETRINTERNAL(h
, cur
);
196 fprintf(stderr
, "entries %03d pgno %03d",
197 ri
->nrecs
, ri
->pgno
);
200 bl
= GETBLEAF(h
, cur
);
201 if (bl
->flags
& P_BIGKEY
)
203 "big key page %u size %u/",
204 *(pgno_t
*)bl
->bytes
,
205 *(u_int32_t
*)(bl
->bytes
+ sizeof(pgno_t
)));
207 fprintf(stderr
, "%.*s/",
208 bl
->ksize
, bl
->bytes
);
209 if (bl
->flags
& P_BIGDATA
)
211 "big data page %u size %u",
212 *(pgno_t
*)(bl
->bytes
+ bl
->ksize
),
213 *(u_int32_t
*)(bl
->bytes
+ bl
->ksize
+
216 fprintf(stderr
, "%.*s",
217 (int)bl
->dsize
, bl
->bytes
+ bl
->ksize
);
220 rl
= GETRLEAF(h
, cur
);
221 if (rl
->flags
& P_BIGDATA
)
223 "big data page %u size %u",
224 *(pgno_t
*)rl
->bytes
,
225 *(u_int32_t
*)(rl
->bytes
+ sizeof(pgno_t
)));
228 "%.*s", (int)rl
->dsize
, rl
->bytes
);
231 fprintf(stderr
, "\n");
238 * BT_STAT -- Gather/print the tree statistics
241 * dbp: pointer to the DB
246 extern u_long bt_cache_hit
, bt_cache_miss
, bt_pfxsaved
, bt_rootsplit
;
247 extern u_long bt_sortsplit
, bt_split
;
250 pgno_t i
, pcont
, pinternal
, pleaf
;
251 u_long ifree
, lfree
, nkeys
;
255 pcont
= pinternal
= pleaf
= 0;
256 nkeys
= ifree
= lfree
= 0;
257 for (i
= P_ROOT
; (h
= mpool_get(t
->bt_mp
, i
, 0)) != NULL
; ++i
) {
258 switch (h
->flags
& P_TYPE
) {
262 ifree
+= h
->upper
- h
->lower
;
267 lfree
+= h
->upper
- h
->lower
;
268 nkeys
+= NEXTINDEX(h
);
274 mpool_put(t
->bt_mp
, h
, 0);
277 /* Count the levels of the tree. */
278 for (i
= P_ROOT
, levels
= 0 ;; ++levels
) {
279 h
= mpool_get(t
->bt_mp
, i
, 0);
280 if (h
->flags
& (P_BLEAF
|P_RLEAF
)) {
283 mpool_put(t
->bt_mp
, h
, 0);
286 i
= F_ISSET(t
, R_RECNO
) ?
287 GETRINTERNAL(h
, 0)->pgno
:
288 GETBINTERNAL(h
, 0)->pgno
;
289 mpool_put(t
->bt_mp
, h
, 0);
292 fprintf(stderr
, "%d level%s with %ld keys",
293 levels
, levels
== 1 ? "" : "s", nkeys
);
294 if (F_ISSET(t
, R_RECNO
))
295 fprintf(stderr
, " (%d header count)", t
->bt_nrecs
);
297 "\n%u pages (leaf %d, internal %d, overflow %d)\n",
298 pinternal
+ pleaf
+ pcont
, pleaf
, pinternal
, pcont
);
299 fprintf(stderr
, "%ld cache hits, %ld cache misses\n",
300 bt_cache_hit
, bt_cache_miss
);
301 fprintf(stderr
, "%lu splits (%lu root splits, %lu sort splits)\n",
302 bt_split
, bt_rootsplit
, bt_sortsplit
);
303 pleaf
*= t
->bt_psize
- BTDATAOFF
;
306 "%.0f%% leaf fill (%ld bytes used, %ld bytes free)\n",
307 ((double)(pleaf
- lfree
) / pleaf
) * 100,
308 pleaf
- lfree
, lfree
);
309 pinternal
*= t
->bt_psize
- BTDATAOFF
;
312 "%.0f%% internal fill (%ld bytes used, %ld bytes free\n",
313 ((double)(pinternal
- ifree
) / pinternal
) * 100,
314 pinternal
- ifree
, ifree
);
316 fprintf(stderr
, "prefix checking removed %lu bytes.\n",