158f0484fSRodney W. Grimes /*- 2ef5d438eSPaul Traina * Copyright (c) 1990, 1993, 1994 358f0484fSRodney W. Grimes * The Regents of the University of California. All rights reserved. 458f0484fSRodney W. Grimes * 558f0484fSRodney W. Grimes * This code is derived from software contributed to Berkeley by 658f0484fSRodney W. Grimes * Mike Olson. 758f0484fSRodney W. Grimes * 858f0484fSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 958f0484fSRodney W. Grimes * modification, are permitted provided that the following conditions 1058f0484fSRodney W. Grimes * are met: 1158f0484fSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 1258f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 1358f0484fSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 1458f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 1558f0484fSRodney W. Grimes * documentation and/or other materials provided with the distribution. 1658f0484fSRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 1758f0484fSRodney W. Grimes * must display the following acknowledgement: 1858f0484fSRodney W. Grimes * This product includes software developed by the University of 1958f0484fSRodney W. Grimes * California, Berkeley and its contributors. 2058f0484fSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 2158f0484fSRodney W. Grimes * may be used to endorse or promote products derived from this software 2258f0484fSRodney W. Grimes * without specific prior written permission. 2358f0484fSRodney W. Grimes * 2458f0484fSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2558f0484fSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2658f0484fSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2758f0484fSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2858f0484fSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2958f0484fSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3058f0484fSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3158f0484fSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3258f0484fSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3358f0484fSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3458f0484fSRodney W. Grimes * SUCH DAMAGE. 3558f0484fSRodney W. Grimes */ 3658f0484fSRodney W. Grimes 3758f0484fSRodney W. Grimes #if defined(LIBC_SCCS) && !defined(lint) 38ef5d438eSPaul Traina static char sccsid[] = "@(#)bt_debug.c 8.5 (Berkeley) 8/17/94"; 3958f0484fSRodney W. Grimes #endif /* LIBC_SCCS and not lint */ 40333fc21eSDavid E. O'Brien #include <sys/cdefs.h> 41333fc21eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 4258f0484fSRodney W. Grimes 4358f0484fSRodney W. Grimes #include <sys/param.h> 4458f0484fSRodney W. Grimes 4558f0484fSRodney W. Grimes #include <stdio.h> 4658f0484fSRodney W. Grimes #include <stdlib.h> 4758f0484fSRodney W. Grimes #include <string.h> 4858f0484fSRodney W. Grimes 4958f0484fSRodney W. Grimes #include <db.h> 5058f0484fSRodney W. Grimes #include "btree.h" 5158f0484fSRodney W. Grimes 5258f0484fSRodney W. Grimes #ifdef DEBUG 5358f0484fSRodney W. Grimes /* 5458f0484fSRodney W. Grimes * BT_DUMP -- Dump the tree 5558f0484fSRodney W. Grimes * 5658f0484fSRodney W. Grimes * Parameters: 5758f0484fSRodney W. Grimes * dbp: pointer to the DB 5858f0484fSRodney W. Grimes */ 5958f0484fSRodney W. Grimes void 6058f0484fSRodney W. Grimes __bt_dump(dbp) 6158f0484fSRodney W. Grimes DB *dbp; 6258f0484fSRodney W. Grimes { 6358f0484fSRodney W. Grimes BTREE *t; 6458f0484fSRodney W. Grimes PAGE *h; 6558f0484fSRodney W. Grimes pgno_t i; 6658f0484fSRodney W. Grimes char *sep; 6758f0484fSRodney W. Grimes 6858f0484fSRodney W. Grimes t = dbp->internal; 6958f0484fSRodney W. Grimes (void)fprintf(stderr, "%s: pgsz %d", 70ef5d438eSPaul Traina F_ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize); 71ef5d438eSPaul Traina if (F_ISSET(t, R_RECNO)) 7258f0484fSRodney W. Grimes (void)fprintf(stderr, " keys %lu", t->bt_nrecs); 7358f0484fSRodney W. Grimes #undef X 7458f0484fSRodney W. Grimes #define X(flag, name) \ 75ef5d438eSPaul Traina if (F_ISSET(t, flag)) { \ 7658f0484fSRodney W. Grimes (void)fprintf(stderr, "%s%s", sep, name); \ 7758f0484fSRodney W. Grimes sep = ", "; \ 7858f0484fSRodney W. Grimes } 79ef5d438eSPaul Traina if (t->flags != 0) { 8058f0484fSRodney W. Grimes sep = " flags ("; 8158f0484fSRodney W. Grimes X(R_FIXLEN, "FIXLEN"); 8258f0484fSRodney W. Grimes X(B_INMEM, "INMEM"); 8358f0484fSRodney W. Grimes X(B_NODUPS, "NODUPS"); 8458f0484fSRodney W. Grimes X(B_RDONLY, "RDONLY"); 8558f0484fSRodney W. Grimes X(R_RECNO, "RECNO"); 8658f0484fSRodney W. Grimes X(B_METADIRTY,"METADIRTY"); 8758f0484fSRodney W. Grimes (void)fprintf(stderr, ")\n"); 8858f0484fSRodney W. Grimes } 8958f0484fSRodney W. Grimes #undef X 9058f0484fSRodney W. Grimes 9158f0484fSRodney W. Grimes for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) { 9258f0484fSRodney W. Grimes __bt_dpage(h); 9358f0484fSRodney W. Grimes (void)mpool_put(t->bt_mp, h, 0); 9458f0484fSRodney W. Grimes } 9558f0484fSRodney W. Grimes } 9658f0484fSRodney W. Grimes 9758f0484fSRodney W. Grimes /* 9858f0484fSRodney W. Grimes * BT_DMPAGE -- Dump the meta page 9958f0484fSRodney W. Grimes * 10058f0484fSRodney W. Grimes * Parameters: 10158f0484fSRodney W. Grimes * h: pointer to the PAGE 10258f0484fSRodney W. Grimes */ 10358f0484fSRodney W. Grimes void 10458f0484fSRodney W. Grimes __bt_dmpage(h) 10558f0484fSRodney W. Grimes PAGE *h; 10658f0484fSRodney W. Grimes { 10758f0484fSRodney W. Grimes BTMETA *m; 10858f0484fSRodney W. Grimes char *sep; 10958f0484fSRodney W. Grimes 11058f0484fSRodney W. Grimes m = (BTMETA *)h; 111ef5d438eSPaul Traina (void)fprintf(stderr, "magic %lx\n", m->magic); 112ef5d438eSPaul Traina (void)fprintf(stderr, "version %lu\n", m->version); 113ef5d438eSPaul Traina (void)fprintf(stderr, "psize %lu\n", m->psize); 114ef5d438eSPaul Traina (void)fprintf(stderr, "free %lu\n", m->free); 115ef5d438eSPaul Traina (void)fprintf(stderr, "nrecs %lu\n", m->nrecs); 116ef5d438eSPaul Traina (void)fprintf(stderr, "flags %lu", m->flags); 11758f0484fSRodney W. Grimes #undef X 11858f0484fSRodney W. Grimes #define X(flag, name) \ 119ef5d438eSPaul Traina if (m->flags & flag) { \ 12058f0484fSRodney W. Grimes (void)fprintf(stderr, "%s%s", sep, name); \ 12158f0484fSRodney W. Grimes sep = ", "; \ 12258f0484fSRodney W. Grimes } 123ef5d438eSPaul Traina if (m->flags) { 12458f0484fSRodney W. Grimes sep = " ("; 12558f0484fSRodney W. Grimes X(B_NODUPS, "NODUPS"); 12658f0484fSRodney W. Grimes X(R_RECNO, "RECNO"); 12758f0484fSRodney W. Grimes (void)fprintf(stderr, ")"); 12858f0484fSRodney W. Grimes } 12958f0484fSRodney W. Grimes } 13058f0484fSRodney W. Grimes 13158f0484fSRodney W. Grimes /* 13258f0484fSRodney W. Grimes * BT_DNPAGE -- Dump the page 13358f0484fSRodney W. Grimes * 13458f0484fSRodney W. Grimes * Parameters: 13558f0484fSRodney W. Grimes * n: page number to dump. 13658f0484fSRodney W. Grimes */ 13758f0484fSRodney W. Grimes void 13858f0484fSRodney W. Grimes __bt_dnpage(dbp, pgno) 13958f0484fSRodney W. Grimes DB *dbp; 14058f0484fSRodney W. Grimes pgno_t pgno; 14158f0484fSRodney W. Grimes { 14258f0484fSRodney W. Grimes BTREE *t; 14358f0484fSRodney W. Grimes PAGE *h; 14458f0484fSRodney W. Grimes 14558f0484fSRodney W. Grimes t = dbp->internal; 14658f0484fSRodney W. Grimes if ((h = mpool_get(t->bt_mp, pgno, 0)) != NULL) { 14758f0484fSRodney W. Grimes __bt_dpage(h); 14858f0484fSRodney W. Grimes (void)mpool_put(t->bt_mp, h, 0); 14958f0484fSRodney W. Grimes } 15058f0484fSRodney W. Grimes } 15158f0484fSRodney W. Grimes 15258f0484fSRodney W. Grimes /* 15358f0484fSRodney W. Grimes * BT_DPAGE -- Dump the page 15458f0484fSRodney W. Grimes * 15558f0484fSRodney W. Grimes * Parameters: 15658f0484fSRodney W. Grimes * h: pointer to the PAGE 15758f0484fSRodney W. Grimes */ 15858f0484fSRodney W. Grimes void 15958f0484fSRodney W. Grimes __bt_dpage(h) 16058f0484fSRodney W. Grimes PAGE *h; 16158f0484fSRodney W. Grimes { 16258f0484fSRodney W. Grimes BINTERNAL *bi; 16358f0484fSRodney W. Grimes BLEAF *bl; 16458f0484fSRodney W. Grimes RINTERNAL *ri; 16558f0484fSRodney W. Grimes RLEAF *rl; 16658f0484fSRodney W. Grimes indx_t cur, top; 16758f0484fSRodney W. Grimes char *sep; 16858f0484fSRodney W. Grimes 16958f0484fSRodney W. Grimes (void)fprintf(stderr, " page %d: (", h->pgno); 17058f0484fSRodney W. Grimes #undef X 17158f0484fSRodney W. Grimes #define X(flag, name) \ 17258f0484fSRodney W. Grimes if (h->flags & flag) { \ 17358f0484fSRodney W. Grimes (void)fprintf(stderr, "%s%s", sep, name); \ 17458f0484fSRodney W. Grimes sep = ", "; \ 17558f0484fSRodney W. Grimes } 17658f0484fSRodney W. Grimes sep = ""; 17758f0484fSRodney W. Grimes X(P_BINTERNAL, "BINTERNAL") /* types */ 17858f0484fSRodney W. Grimes X(P_BLEAF, "BLEAF") 17958f0484fSRodney W. Grimes X(P_RINTERNAL, "RINTERNAL") /* types */ 18058f0484fSRodney W. Grimes X(P_RLEAF, "RLEAF") 18158f0484fSRodney W. Grimes X(P_OVERFLOW, "OVERFLOW") 18258f0484fSRodney W. Grimes X(P_PRESERVE, "PRESERVE"); 18358f0484fSRodney W. Grimes (void)fprintf(stderr, ")\n"); 18458f0484fSRodney W. Grimes #undef X 18558f0484fSRodney W. Grimes 18658f0484fSRodney W. Grimes (void)fprintf(stderr, "\tprev %2d next %2d", h->prevpg, h->nextpg); 18758f0484fSRodney W. Grimes if (h->flags & P_OVERFLOW) 18858f0484fSRodney W. Grimes return; 18958f0484fSRodney W. Grimes 19058f0484fSRodney W. Grimes top = NEXTINDEX(h); 19158f0484fSRodney W. Grimes (void)fprintf(stderr, " lower %3d upper %3d nextind %d\n", 19258f0484fSRodney W. Grimes h->lower, h->upper, top); 19358f0484fSRodney W. Grimes for (cur = 0; cur < top; cur++) { 19458f0484fSRodney W. Grimes (void)fprintf(stderr, "\t[%03d] %4d ", cur, h->linp[cur]); 19558f0484fSRodney W. Grimes switch (h->flags & P_TYPE) { 19658f0484fSRodney W. Grimes case P_BINTERNAL: 19758f0484fSRodney W. Grimes bi = GETBINTERNAL(h, cur); 19858f0484fSRodney W. Grimes (void)fprintf(stderr, 19958f0484fSRodney W. Grimes "size %03d pgno %03d", bi->ksize, bi->pgno); 20058f0484fSRodney W. Grimes if (bi->flags & P_BIGKEY) 20158f0484fSRodney W. Grimes (void)fprintf(stderr, " (indirect)"); 20258f0484fSRodney W. Grimes else if (bi->ksize) 20358f0484fSRodney W. Grimes (void)fprintf(stderr, 20458f0484fSRodney W. Grimes " {%.*s}", (int)bi->ksize, bi->bytes); 20558f0484fSRodney W. Grimes break; 20658f0484fSRodney W. Grimes case P_RINTERNAL: 20758f0484fSRodney W. Grimes ri = GETRINTERNAL(h, cur); 20858f0484fSRodney W. Grimes (void)fprintf(stderr, "entries %03d pgno %03d", 20958f0484fSRodney W. Grimes ri->nrecs, ri->pgno); 21058f0484fSRodney W. Grimes break; 21158f0484fSRodney W. Grimes case P_BLEAF: 21258f0484fSRodney W. Grimes bl = GETBLEAF(h, cur); 21358f0484fSRodney W. Grimes if (bl->flags & P_BIGKEY) 21458f0484fSRodney W. Grimes (void)fprintf(stderr, 21558f0484fSRodney W. Grimes "big key page %lu size %u/", 21658f0484fSRodney W. Grimes *(pgno_t *)bl->bytes, 217ef5d438eSPaul Traina *(u_int32_t *)(bl->bytes + sizeof(pgno_t))); 21858f0484fSRodney W. Grimes else if (bl->ksize) 21958f0484fSRodney W. Grimes (void)fprintf(stderr, "%s/", bl->bytes); 22058f0484fSRodney W. Grimes if (bl->flags & P_BIGDATA) 22158f0484fSRodney W. Grimes (void)fprintf(stderr, 22258f0484fSRodney W. Grimes "big data page %lu size %u", 22358f0484fSRodney W. Grimes *(pgno_t *)(bl->bytes + bl->ksize), 224ef5d438eSPaul Traina *(u_int32_t *)(bl->bytes + bl->ksize + 22558f0484fSRodney W. Grimes sizeof(pgno_t))); 22658f0484fSRodney W. Grimes else if (bl->dsize) 22758f0484fSRodney W. Grimes (void)fprintf(stderr, "%.*s", 22858f0484fSRodney W. Grimes (int)bl->dsize, bl->bytes + bl->ksize); 22958f0484fSRodney W. Grimes break; 23058f0484fSRodney W. Grimes case P_RLEAF: 23158f0484fSRodney W. Grimes rl = GETRLEAF(h, cur); 23258f0484fSRodney W. Grimes if (rl->flags & P_BIGDATA) 23358f0484fSRodney W. Grimes (void)fprintf(stderr, 23458f0484fSRodney W. Grimes "big data page %lu size %u", 23558f0484fSRodney W. Grimes *(pgno_t *)rl->bytes, 236ef5d438eSPaul Traina *(u_int32_t *)(rl->bytes + sizeof(pgno_t))); 23758f0484fSRodney W. Grimes else if (rl->dsize) 23858f0484fSRodney W. Grimes (void)fprintf(stderr, 23958f0484fSRodney W. Grimes "%.*s", (int)rl->dsize, rl->bytes); 24058f0484fSRodney W. Grimes break; 24158f0484fSRodney W. Grimes } 24258f0484fSRodney W. Grimes (void)fprintf(stderr, "\n"); 24358f0484fSRodney W. Grimes } 24458f0484fSRodney W. Grimes } 24558f0484fSRodney W. Grimes #endif 24658f0484fSRodney W. Grimes 24758f0484fSRodney W. Grimes #ifdef STATISTICS 24858f0484fSRodney W. Grimes /* 24958f0484fSRodney W. Grimes * BT_STAT -- Gather/print the tree statistics 25058f0484fSRodney W. Grimes * 25158f0484fSRodney W. Grimes * Parameters: 25258f0484fSRodney W. Grimes * dbp: pointer to the DB 25358f0484fSRodney W. Grimes */ 25458f0484fSRodney W. Grimes void 25558f0484fSRodney W. Grimes __bt_stat(dbp) 25658f0484fSRodney W. Grimes DB *dbp; 25758f0484fSRodney W. Grimes { 25858f0484fSRodney W. Grimes extern u_long bt_cache_hit, bt_cache_miss, bt_pfxsaved, bt_rootsplit; 25958f0484fSRodney W. Grimes extern u_long bt_sortsplit, bt_split; 26058f0484fSRodney W. Grimes BTREE *t; 26158f0484fSRodney W. Grimes PAGE *h; 26258f0484fSRodney W. Grimes pgno_t i, pcont, pinternal, pleaf; 26358f0484fSRodney W. Grimes u_long ifree, lfree, nkeys; 26458f0484fSRodney W. Grimes int levels; 26558f0484fSRodney W. Grimes 26658f0484fSRodney W. Grimes t = dbp->internal; 26758f0484fSRodney W. Grimes pcont = pinternal = pleaf = 0; 26858f0484fSRodney W. Grimes nkeys = ifree = lfree = 0; 26958f0484fSRodney W. Grimes for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) { 27058f0484fSRodney W. Grimes switch (h->flags & P_TYPE) { 27158f0484fSRodney W. Grimes case P_BINTERNAL: 27258f0484fSRodney W. Grimes case P_RINTERNAL: 27358f0484fSRodney W. Grimes ++pinternal; 27458f0484fSRodney W. Grimes ifree += h->upper - h->lower; 27558f0484fSRodney W. Grimes break; 27658f0484fSRodney W. Grimes case P_BLEAF: 27758f0484fSRodney W. Grimes case P_RLEAF: 27858f0484fSRodney W. Grimes ++pleaf; 27958f0484fSRodney W. Grimes lfree += h->upper - h->lower; 28058f0484fSRodney W. Grimes nkeys += NEXTINDEX(h); 28158f0484fSRodney W. Grimes break; 28258f0484fSRodney W. Grimes case P_OVERFLOW: 28358f0484fSRodney W. Grimes ++pcont; 28458f0484fSRodney W. Grimes break; 28558f0484fSRodney W. Grimes } 28658f0484fSRodney W. Grimes (void)mpool_put(t->bt_mp, h, 0); 28758f0484fSRodney W. Grimes } 28858f0484fSRodney W. Grimes 28958f0484fSRodney W. Grimes /* Count the levels of the tree. */ 29058f0484fSRodney W. Grimes for (i = P_ROOT, levels = 0 ;; ++levels) { 29158f0484fSRodney W. Grimes h = mpool_get(t->bt_mp, i, 0); 29258f0484fSRodney W. Grimes if (h->flags & (P_BLEAF|P_RLEAF)) { 29358f0484fSRodney W. Grimes if (levels == 0) 29458f0484fSRodney W. Grimes levels = 1; 29558f0484fSRodney W. Grimes (void)mpool_put(t->bt_mp, h, 0); 29658f0484fSRodney W. Grimes break; 29758f0484fSRodney W. Grimes } 298ef5d438eSPaul Traina i = F_ISSET(t, R_RECNO) ? 29958f0484fSRodney W. Grimes GETRINTERNAL(h, 0)->pgno : 30058f0484fSRodney W. Grimes GETBINTERNAL(h, 0)->pgno; 30158f0484fSRodney W. Grimes (void)mpool_put(t->bt_mp, h, 0); 30258f0484fSRodney W. Grimes } 30358f0484fSRodney W. Grimes 30458f0484fSRodney W. Grimes (void)fprintf(stderr, "%d level%s with %ld keys", 30558f0484fSRodney W. Grimes levels, levels == 1 ? "" : "s", nkeys); 306ef5d438eSPaul Traina if (F_ISSET(t, R_RECNO)) 30758f0484fSRodney W. Grimes (void)fprintf(stderr, " (%ld header count)", t->bt_nrecs); 30858f0484fSRodney W. Grimes (void)fprintf(stderr, 30958f0484fSRodney W. Grimes "\n%lu pages (leaf %ld, internal %ld, overflow %ld)\n", 31058f0484fSRodney W. Grimes pinternal + pleaf + pcont, pleaf, pinternal, pcont); 31158f0484fSRodney W. Grimes (void)fprintf(stderr, "%ld cache hits, %ld cache misses\n", 31258f0484fSRodney W. Grimes bt_cache_hit, bt_cache_miss); 31358f0484fSRodney W. Grimes (void)fprintf(stderr, "%ld splits (%ld root splits, %ld sort splits)\n", 31458f0484fSRodney W. Grimes bt_split, bt_rootsplit, bt_sortsplit); 31558f0484fSRodney W. Grimes pleaf *= t->bt_psize - BTDATAOFF; 31658f0484fSRodney W. Grimes if (pleaf) 31758f0484fSRodney W. Grimes (void)fprintf(stderr, 31858f0484fSRodney W. Grimes "%.0f%% leaf fill (%ld bytes used, %ld bytes free)\n", 31958f0484fSRodney W. Grimes ((double)(pleaf - lfree) / pleaf) * 100, 32058f0484fSRodney W. Grimes pleaf - lfree, lfree); 32158f0484fSRodney W. Grimes pinternal *= t->bt_psize - BTDATAOFF; 32258f0484fSRodney W. Grimes if (pinternal) 32358f0484fSRodney W. Grimes (void)fprintf(stderr, 32458f0484fSRodney W. Grimes "%.0f%% internal fill (%ld bytes used, %ld bytes free\n", 32558f0484fSRodney W. Grimes ((double)(pinternal - ifree) / pinternal) * 100, 32658f0484fSRodney W. Grimes pinternal - ifree, ifree); 32758f0484fSRodney W. Grimes if (bt_pfxsaved) 32858f0484fSRodney W. Grimes (void)fprintf(stderr, "prefix checking removed %lu bytes.\n", 32958f0484fSRodney W. Grimes bt_pfxsaved); 33058f0484fSRodney W. Grimes } 33158f0484fSRodney W. Grimes #endif 332