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 * 4. Neither the name of the University nor the names of its contributors 1758f0484fSRodney W. Grimes * may be used to endorse or promote products derived from this software 1858f0484fSRodney W. Grimes * without specific prior written permission. 1958f0484fSRodney W. Grimes * 2058f0484fSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2158f0484fSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2258f0484fSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2358f0484fSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2458f0484fSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2558f0484fSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2658f0484fSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2758f0484fSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2858f0484fSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2958f0484fSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3058f0484fSRodney W. Grimes * SUCH DAMAGE. 3158f0484fSRodney W. Grimes */ 3258f0484fSRodney W. Grimes 3358f0484fSRodney W. Grimes #if defined(LIBC_SCCS) && !defined(lint) 34ef5d438eSPaul Traina static char sccsid[] = "@(#)bt_debug.c 8.5 (Berkeley) 8/17/94"; 3558f0484fSRodney W. Grimes #endif /* LIBC_SCCS and not lint */ 36333fc21eSDavid E. O'Brien #include <sys/cdefs.h> 37333fc21eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 3858f0484fSRodney W. Grimes 3958f0484fSRodney W. Grimes #include <sys/param.h> 4058f0484fSRodney W. Grimes 4158f0484fSRodney W. Grimes #include <stdio.h> 4258f0484fSRodney W. Grimes #include <stdlib.h> 4358f0484fSRodney W. Grimes #include <string.h> 4458f0484fSRodney W. Grimes 4558f0484fSRodney W. Grimes #include <db.h> 4658f0484fSRodney W. Grimes #include "btree.h" 4758f0484fSRodney W. Grimes 4858f0484fSRodney W. Grimes #ifdef DEBUG 4958f0484fSRodney W. Grimes /* 5058f0484fSRodney W. Grimes * BT_DUMP -- Dump the tree 5158f0484fSRodney W. Grimes * 5258f0484fSRodney W. Grimes * Parameters: 5358f0484fSRodney W. Grimes * dbp: pointer to the DB 5458f0484fSRodney W. Grimes */ 5558f0484fSRodney W. Grimes void 560ac22237SXin LI __bt_dump(DB *dbp) 5758f0484fSRodney W. Grimes { 5858f0484fSRodney W. Grimes BTREE *t; 5958f0484fSRodney W. Grimes PAGE *h; 6058f0484fSRodney W. Grimes pgno_t i; 6158f0484fSRodney W. Grimes char *sep; 6258f0484fSRodney W. Grimes 6358f0484fSRodney W. Grimes t = dbp->internal; 647efabbb9SXin LI (void)fprintf(stderr, "%s: pgsz %u", 65ef5d438eSPaul Traina F_ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize); 66ef5d438eSPaul Traina if (F_ISSET(t, R_RECNO)) 67312f1851SJun Kuriyama (void)fprintf(stderr, " keys %u", t->bt_nrecs); 6858f0484fSRodney W. Grimes #undef X 6958f0484fSRodney W. Grimes #define X(flag, name) \ 70ef5d438eSPaul Traina if (F_ISSET(t, flag)) { \ 7158f0484fSRodney W. Grimes (void)fprintf(stderr, "%s%s", sep, name); \ 7258f0484fSRodney W. Grimes sep = ", "; \ 7358f0484fSRodney W. Grimes } 74ef5d438eSPaul Traina if (t->flags != 0) { 7558f0484fSRodney W. Grimes sep = " flags ("; 7658f0484fSRodney W. Grimes X(R_FIXLEN, "FIXLEN"); 7758f0484fSRodney W. Grimes X(B_INMEM, "INMEM"); 7858f0484fSRodney W. Grimes X(B_NODUPS, "NODUPS"); 7958f0484fSRodney W. Grimes X(B_RDONLY, "RDONLY"); 8058f0484fSRodney W. Grimes X(R_RECNO, "RECNO"); 8158f0484fSRodney W. Grimes X(B_METADIRTY,"METADIRTY"); 8258f0484fSRodney W. Grimes (void)fprintf(stderr, ")\n"); 8358f0484fSRodney W. Grimes } 8458f0484fSRodney W. Grimes #undef X 8558f0484fSRodney W. Grimes 869fc74a87SXin LI for (i = P_ROOT; 879fc74a87SXin LI (h = mpool_get(t->bt_mp, i, MPOOL_IGNOREPIN)) != NULL; ++i) 8858f0484fSRodney W. Grimes __bt_dpage(h); 8958f0484fSRodney W. Grimes } 9058f0484fSRodney W. Grimes 9158f0484fSRodney W. Grimes /* 9258f0484fSRodney W. Grimes * BT_DMPAGE -- Dump the meta page 9358f0484fSRodney W. Grimes * 9458f0484fSRodney W. Grimes * Parameters: 9558f0484fSRodney W. Grimes * h: pointer to the PAGE 9658f0484fSRodney W. Grimes */ 9758f0484fSRodney W. Grimes void 980ac22237SXin LI __bt_dmpage(PAGE *h) 9958f0484fSRodney W. Grimes { 10058f0484fSRodney W. Grimes BTMETA *m; 10158f0484fSRodney W. Grimes char *sep; 10258f0484fSRodney W. Grimes 10358f0484fSRodney W. Grimes m = (BTMETA *)h; 104312f1851SJun Kuriyama (void)fprintf(stderr, "magic %x\n", m->magic); 105312f1851SJun Kuriyama (void)fprintf(stderr, "version %u\n", m->version); 106312f1851SJun Kuriyama (void)fprintf(stderr, "psize %u\n", m->psize); 107312f1851SJun Kuriyama (void)fprintf(stderr, "free %u\n", m->free); 108312f1851SJun Kuriyama (void)fprintf(stderr, "nrecs %u\n", m->nrecs); 109312f1851SJun Kuriyama (void)fprintf(stderr, "flags %u", m->flags); 11058f0484fSRodney W. Grimes #undef X 11158f0484fSRodney W. Grimes #define X(flag, name) \ 112ef5d438eSPaul Traina if (m->flags & flag) { \ 11358f0484fSRodney W. Grimes (void)fprintf(stderr, "%s%s", sep, name); \ 11458f0484fSRodney W. Grimes sep = ", "; \ 11558f0484fSRodney W. Grimes } 116ef5d438eSPaul Traina if (m->flags) { 11758f0484fSRodney W. Grimes sep = " ("; 11858f0484fSRodney W. Grimes X(B_NODUPS, "NODUPS"); 11958f0484fSRodney W. Grimes X(R_RECNO, "RECNO"); 12058f0484fSRodney W. Grimes (void)fprintf(stderr, ")"); 12158f0484fSRodney W. Grimes } 12258f0484fSRodney W. Grimes } 12358f0484fSRodney W. Grimes 12458f0484fSRodney W. Grimes /* 12558f0484fSRodney W. Grimes * BT_DNPAGE -- Dump the page 12658f0484fSRodney W. Grimes * 12758f0484fSRodney W. Grimes * Parameters: 12858f0484fSRodney W. Grimes * n: page number to dump. 12958f0484fSRodney W. Grimes */ 13058f0484fSRodney W. Grimes void 1310ac22237SXin LI __bt_dnpage(DB *dbp, pgno_t pgno) 13258f0484fSRodney W. Grimes { 13358f0484fSRodney W. Grimes BTREE *t; 13458f0484fSRodney W. Grimes PAGE *h; 13558f0484fSRodney W. Grimes 13658f0484fSRodney W. Grimes t = dbp->internal; 1379fc74a87SXin LI if ((h = mpool_get(t->bt_mp, pgno, MPOOL_IGNOREPIN)) != NULL) 13858f0484fSRodney W. Grimes __bt_dpage(h); 13958f0484fSRodney W. Grimes } 14058f0484fSRodney W. Grimes 14158f0484fSRodney W. Grimes /* 14258f0484fSRodney W. Grimes * BT_DPAGE -- Dump the page 14358f0484fSRodney W. Grimes * 14458f0484fSRodney W. Grimes * Parameters: 14558f0484fSRodney W. Grimes * h: pointer to the PAGE 14658f0484fSRodney W. Grimes */ 14758f0484fSRodney W. Grimes void 1480ac22237SXin LI __bt_dpage(PAGE *h) 14958f0484fSRodney W. Grimes { 15058f0484fSRodney W. Grimes BINTERNAL *bi; 15158f0484fSRodney W. Grimes BLEAF *bl; 15258f0484fSRodney W. Grimes RINTERNAL *ri; 15358f0484fSRodney W. Grimes RLEAF *rl; 15458f0484fSRodney W. Grimes indx_t cur, top; 15558f0484fSRodney W. Grimes char *sep; 15658f0484fSRodney W. Grimes 1577efabbb9SXin LI (void)fprintf(stderr, " page %u: (", h->pgno); 15858f0484fSRodney W. Grimes #undef X 15958f0484fSRodney W. Grimes #define X(flag, name) \ 16058f0484fSRodney W. Grimes if (h->flags & flag) { \ 16158f0484fSRodney W. Grimes (void)fprintf(stderr, "%s%s", sep, name); \ 16258f0484fSRodney W. Grimes sep = ", "; \ 16358f0484fSRodney W. Grimes } 16458f0484fSRodney W. Grimes sep = ""; 16558f0484fSRodney W. Grimes X(P_BINTERNAL, "BINTERNAL") /* types */ 16658f0484fSRodney W. Grimes X(P_BLEAF, "BLEAF") 16758f0484fSRodney W. Grimes X(P_RINTERNAL, "RINTERNAL") /* types */ 16858f0484fSRodney W. Grimes X(P_RLEAF, "RLEAF") 16958f0484fSRodney W. Grimes X(P_OVERFLOW, "OVERFLOW") 17058f0484fSRodney W. Grimes X(P_PRESERVE, "PRESERVE"); 17158f0484fSRodney W. Grimes (void)fprintf(stderr, ")\n"); 17258f0484fSRodney W. Grimes #undef X 17358f0484fSRodney W. Grimes 1747efabbb9SXin LI (void)fprintf(stderr, "\tprev %2u next %2u", h->prevpg, h->nextpg); 17558f0484fSRodney W. Grimes if (h->flags & P_OVERFLOW) 17658f0484fSRodney W. Grimes return; 17758f0484fSRodney W. Grimes 17858f0484fSRodney W. Grimes top = NEXTINDEX(h); 17958f0484fSRodney W. Grimes (void)fprintf(stderr, " lower %3d upper %3d nextind %d\n", 18058f0484fSRodney W. Grimes h->lower, h->upper, top); 18158f0484fSRodney W. Grimes for (cur = 0; cur < top; cur++) { 18258f0484fSRodney W. Grimes (void)fprintf(stderr, "\t[%03d] %4d ", cur, h->linp[cur]); 18358f0484fSRodney W. Grimes switch (h->flags & P_TYPE) { 18458f0484fSRodney W. Grimes case P_BINTERNAL: 18558f0484fSRodney W. Grimes bi = GETBINTERNAL(h, cur); 18658f0484fSRodney W. Grimes (void)fprintf(stderr, 18758f0484fSRodney W. Grimes "size %03d pgno %03d", bi->ksize, bi->pgno); 18858f0484fSRodney W. Grimes if (bi->flags & P_BIGKEY) 18958f0484fSRodney W. Grimes (void)fprintf(stderr, " (indirect)"); 19058f0484fSRodney W. Grimes else if (bi->ksize) 19158f0484fSRodney W. Grimes (void)fprintf(stderr, 19258f0484fSRodney W. Grimes " {%.*s}", (int)bi->ksize, bi->bytes); 19358f0484fSRodney W. Grimes break; 19458f0484fSRodney W. Grimes case P_RINTERNAL: 19558f0484fSRodney W. Grimes ri = GETRINTERNAL(h, cur); 19658f0484fSRodney W. Grimes (void)fprintf(stderr, "entries %03d pgno %03d", 19758f0484fSRodney W. Grimes ri->nrecs, ri->pgno); 19858f0484fSRodney W. Grimes break; 19958f0484fSRodney W. Grimes case P_BLEAF: 20058f0484fSRodney W. Grimes bl = GETBLEAF(h, cur); 20158f0484fSRodney W. Grimes if (bl->flags & P_BIGKEY) 20258f0484fSRodney W. Grimes (void)fprintf(stderr, 203312f1851SJun Kuriyama "big key page %u size %u/", 20458f0484fSRodney W. Grimes *(pgno_t *)bl->bytes, 205ef5d438eSPaul Traina *(u_int32_t *)(bl->bytes + sizeof(pgno_t))); 20658f0484fSRodney W. Grimes else if (bl->ksize) 207312f1851SJun Kuriyama (void)fprintf(stderr, "%.*s/", 208312f1851SJun Kuriyama bl->ksize, bl->bytes); 20958f0484fSRodney W. Grimes if (bl->flags & P_BIGDATA) 21058f0484fSRodney W. Grimes (void)fprintf(stderr, 211312f1851SJun Kuriyama "big data page %u size %u", 21258f0484fSRodney W. Grimes *(pgno_t *)(bl->bytes + bl->ksize), 213ef5d438eSPaul Traina *(u_int32_t *)(bl->bytes + bl->ksize + 21458f0484fSRodney W. Grimes sizeof(pgno_t))); 21558f0484fSRodney W. Grimes else if (bl->dsize) 21658f0484fSRodney W. Grimes (void)fprintf(stderr, "%.*s", 21758f0484fSRodney W. Grimes (int)bl->dsize, bl->bytes + bl->ksize); 21858f0484fSRodney W. Grimes break; 21958f0484fSRodney W. Grimes case P_RLEAF: 22058f0484fSRodney W. Grimes rl = GETRLEAF(h, cur); 22158f0484fSRodney W. Grimes if (rl->flags & P_BIGDATA) 22258f0484fSRodney W. Grimes (void)fprintf(stderr, 223312f1851SJun Kuriyama "big data page %u size %u", 22458f0484fSRodney W. Grimes *(pgno_t *)rl->bytes, 225ef5d438eSPaul Traina *(u_int32_t *)(rl->bytes + sizeof(pgno_t))); 22658f0484fSRodney W. Grimes else if (rl->dsize) 22758f0484fSRodney W. Grimes (void)fprintf(stderr, 22858f0484fSRodney W. Grimes "%.*s", (int)rl->dsize, rl->bytes); 22958f0484fSRodney W. Grimes break; 23058f0484fSRodney W. Grimes } 23158f0484fSRodney W. Grimes (void)fprintf(stderr, "\n"); 23258f0484fSRodney W. Grimes } 23358f0484fSRodney W. Grimes } 23458f0484fSRodney W. Grimes #endif 23558f0484fSRodney W. Grimes 23658f0484fSRodney W. Grimes #ifdef STATISTICS 23758f0484fSRodney W. Grimes /* 23858f0484fSRodney W. Grimes * BT_STAT -- Gather/print the tree statistics 23958f0484fSRodney W. Grimes * 24058f0484fSRodney W. Grimes * Parameters: 24158f0484fSRodney W. Grimes * dbp: pointer to the DB 24258f0484fSRodney W. Grimes */ 24358f0484fSRodney W. Grimes void 2440ac22237SXin LI __bt_stat(DB *dbp) 24558f0484fSRodney W. Grimes { 24658f0484fSRodney W. Grimes extern u_long bt_cache_hit, bt_cache_miss, bt_pfxsaved, bt_rootsplit; 24758f0484fSRodney W. Grimes extern u_long bt_sortsplit, bt_split; 24858f0484fSRodney W. Grimes BTREE *t; 24958f0484fSRodney W. Grimes PAGE *h; 25058f0484fSRodney W. Grimes pgno_t i, pcont, pinternal, pleaf; 25158f0484fSRodney W. Grimes u_long ifree, lfree, nkeys; 25258f0484fSRodney W. Grimes int levels; 25358f0484fSRodney W. Grimes 25458f0484fSRodney W. Grimes t = dbp->internal; 25558f0484fSRodney W. Grimes pcont = pinternal = pleaf = 0; 25658f0484fSRodney W. Grimes nkeys = ifree = lfree = 0; 2579fc74a87SXin LI for (i = P_ROOT; 2589fc74a87SXin LI (h = mpool_get(t->bt_mp, i, MPOOL_IGNOREPIN)) != NULL; ++i) 25958f0484fSRodney W. Grimes switch (h->flags & P_TYPE) { 26058f0484fSRodney W. Grimes case P_BINTERNAL: 26158f0484fSRodney W. Grimes case P_RINTERNAL: 26258f0484fSRodney W. Grimes ++pinternal; 26358f0484fSRodney W. Grimes ifree += h->upper - h->lower; 26458f0484fSRodney W. Grimes break; 26558f0484fSRodney W. Grimes case P_BLEAF: 26658f0484fSRodney W. Grimes case P_RLEAF: 26758f0484fSRodney W. Grimes ++pleaf; 26858f0484fSRodney W. Grimes lfree += h->upper - h->lower; 26958f0484fSRodney W. Grimes nkeys += NEXTINDEX(h); 27058f0484fSRodney W. Grimes break; 27158f0484fSRodney W. Grimes case P_OVERFLOW: 27258f0484fSRodney W. Grimes ++pcont; 27358f0484fSRodney W. Grimes break; 27458f0484fSRodney W. Grimes } 27558f0484fSRodney W. Grimes 27658f0484fSRodney W. Grimes /* Count the levels of the tree. */ 27758f0484fSRodney W. Grimes for (i = P_ROOT, levels = 0 ;; ++levels) { 2789fc74a87SXin LI h = mpool_get(t->bt_mp, i, MPOOL_IGNOREPIN); 27958f0484fSRodney W. Grimes if (h->flags & (P_BLEAF|P_RLEAF)) { 28058f0484fSRodney W. Grimes if (levels == 0) 28158f0484fSRodney W. Grimes levels = 1; 28258f0484fSRodney W. Grimes break; 28358f0484fSRodney W. Grimes } 284ef5d438eSPaul Traina i = F_ISSET(t, R_RECNO) ? 28558f0484fSRodney W. Grimes GETRINTERNAL(h, 0)->pgno : 28658f0484fSRodney W. Grimes GETBINTERNAL(h, 0)->pgno; 28758f0484fSRodney W. Grimes } 28858f0484fSRodney W. Grimes 2897efabbb9SXin LI (void)fprintf(stderr, "%d level%s with %lu keys", 29058f0484fSRodney W. Grimes levels, levels == 1 ? "" : "s", nkeys); 291ef5d438eSPaul Traina if (F_ISSET(t, R_RECNO)) 2927efabbb9SXin LI (void)fprintf(stderr, " (%u header count)", t->bt_nrecs); 29358f0484fSRodney W. Grimes (void)fprintf(stderr, 2947efabbb9SXin LI "\n%u pages (leaf %u, internal %u, overflow %u)\n", 29558f0484fSRodney W. Grimes pinternal + pleaf + pcont, pleaf, pinternal, pcont); 2967efabbb9SXin LI (void)fprintf(stderr, "%lu cache hits, %lu cache misses\n", 29758f0484fSRodney W. Grimes bt_cache_hit, bt_cache_miss); 298312f1851SJun Kuriyama (void)fprintf(stderr, "%lu splits (%lu root splits, %lu sort splits)\n", 29958f0484fSRodney W. Grimes bt_split, bt_rootsplit, bt_sortsplit); 30058f0484fSRodney W. Grimes pleaf *= t->bt_psize - BTDATAOFF; 30158f0484fSRodney W. Grimes if (pleaf) 30258f0484fSRodney W. Grimes (void)fprintf(stderr, 3037efabbb9SXin LI "%.0f%% leaf fill (%lu bytes used, %lu bytes free)\n", 30458f0484fSRodney W. Grimes ((double)(pleaf - lfree) / pleaf) * 100, 30558f0484fSRodney W. Grimes pleaf - lfree, lfree); 30658f0484fSRodney W. Grimes pinternal *= t->bt_psize - BTDATAOFF; 30758f0484fSRodney W. Grimes if (pinternal) 30858f0484fSRodney W. Grimes (void)fprintf(stderr, 3097efabbb9SXin LI "%.0f%% internal fill (%lu bytes used, %lu bytes free\n", 31058f0484fSRodney W. Grimes ((double)(pinternal - ifree) / pinternal) * 100, 31158f0484fSRodney W. Grimes pinternal - ifree, ifree); 31258f0484fSRodney W. Grimes if (bt_pfxsaved) 31358f0484fSRodney W. Grimes (void)fprintf(stderr, "prefix checking removed %lu bytes.\n", 31458f0484fSRodney W. Grimes bt_pfxsaved); 31558f0484fSRodney W. Grimes } 31658f0484fSRodney W. Grimes #endif 317