158f0484fSRodney W. Grimes /*- 2*8a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 3*8a16b7a1SPedro F. Giffuni * 4ef5d438eSPaul Traina * Copyright (c) 1990, 1993, 1994 558f0484fSRodney W. Grimes * The Regents of the University of California. All rights reserved. 658f0484fSRodney W. Grimes * 758f0484fSRodney W. Grimes * This code is derived from software contributed to Berkeley by 858f0484fSRodney W. Grimes * Mike Olson. 958f0484fSRodney W. Grimes * 1058f0484fSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 1158f0484fSRodney W. Grimes * modification, are permitted provided that the following conditions 1258f0484fSRodney W. Grimes * are met: 1358f0484fSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 1458f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 1558f0484fSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 1658f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 1758f0484fSRodney W. Grimes * documentation and/or other materials provided with the distribution. 18fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 1958f0484fSRodney W. Grimes * may be used to endorse or promote products derived from this software 2058f0484fSRodney W. Grimes * without specific prior written permission. 2158f0484fSRodney W. Grimes * 2258f0484fSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2358f0484fSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2458f0484fSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2558f0484fSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2658f0484fSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2758f0484fSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2858f0484fSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2958f0484fSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3058f0484fSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3158f0484fSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3258f0484fSRodney W. Grimes * SUCH DAMAGE. 3358f0484fSRodney W. Grimes */ 3458f0484fSRodney W. Grimes 3558f0484fSRodney W. Grimes #if defined(LIBC_SCCS) && !defined(lint) 36ef5d438eSPaul Traina static char sccsid[] = "@(#)bt_debug.c 8.5 (Berkeley) 8/17/94"; 3758f0484fSRodney W. Grimes #endif /* LIBC_SCCS and not lint */ 38333fc21eSDavid E. O'Brien #include <sys/cdefs.h> 39333fc21eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 4058f0484fSRodney W. Grimes 4158f0484fSRodney W. Grimes #include <sys/param.h> 4258f0484fSRodney W. Grimes 4358f0484fSRodney W. Grimes #include <stdio.h> 4458f0484fSRodney W. Grimes #include <stdlib.h> 4558f0484fSRodney W. Grimes #include <string.h> 4658f0484fSRodney W. Grimes 4758f0484fSRodney W. Grimes #include <db.h> 4858f0484fSRodney W. Grimes #include "btree.h" 4958f0484fSRodney W. Grimes 5058f0484fSRodney W. Grimes #ifdef DEBUG 5158f0484fSRodney W. Grimes /* 5258f0484fSRodney W. Grimes * BT_DUMP -- Dump the tree 5358f0484fSRodney W. Grimes * 5458f0484fSRodney W. Grimes * Parameters: 5558f0484fSRodney W. Grimes * dbp: pointer to the DB 5658f0484fSRodney W. Grimes */ 5758f0484fSRodney W. Grimes void 580ac22237SXin LI __bt_dump(DB *dbp) 5958f0484fSRodney W. Grimes { 6058f0484fSRodney W. Grimes BTREE *t; 6158f0484fSRodney W. Grimes PAGE *h; 6258f0484fSRodney W. Grimes pgno_t i; 6358f0484fSRodney W. Grimes char *sep; 6458f0484fSRodney W. Grimes 6558f0484fSRodney W. Grimes t = dbp->internal; 667efabbb9SXin LI (void)fprintf(stderr, "%s: pgsz %u", 67ef5d438eSPaul Traina F_ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize); 68ef5d438eSPaul Traina if (F_ISSET(t, R_RECNO)) 69312f1851SJun Kuriyama (void)fprintf(stderr, " keys %u", t->bt_nrecs); 7058f0484fSRodney W. Grimes #undef X 7158f0484fSRodney W. Grimes #define X(flag, name) \ 72ef5d438eSPaul Traina if (F_ISSET(t, flag)) { \ 7358f0484fSRodney W. Grimes (void)fprintf(stderr, "%s%s", sep, name); \ 7458f0484fSRodney W. Grimes sep = ", "; \ 7558f0484fSRodney W. Grimes } 76ef5d438eSPaul Traina if (t->flags != 0) { 7758f0484fSRodney W. Grimes sep = " flags ("; 7858f0484fSRodney W. Grimes X(R_FIXLEN, "FIXLEN"); 7958f0484fSRodney W. Grimes X(B_INMEM, "INMEM"); 8058f0484fSRodney W. Grimes X(B_NODUPS, "NODUPS"); 8158f0484fSRodney W. Grimes X(B_RDONLY, "RDONLY"); 8258f0484fSRodney W. Grimes X(R_RECNO, "RECNO"); 8358f0484fSRodney W. Grimes X(B_METADIRTY,"METADIRTY"); 8458f0484fSRodney W. Grimes (void)fprintf(stderr, ")\n"); 8558f0484fSRodney W. Grimes } 8658f0484fSRodney W. Grimes #undef X 8758f0484fSRodney W. Grimes 889fc74a87SXin LI for (i = P_ROOT; 899fc74a87SXin LI (h = mpool_get(t->bt_mp, i, MPOOL_IGNOREPIN)) != NULL; ++i) 9058f0484fSRodney W. Grimes __bt_dpage(h); 9158f0484fSRodney W. Grimes } 9258f0484fSRodney W. Grimes 9358f0484fSRodney W. Grimes /* 9458f0484fSRodney W. Grimes * BT_DMPAGE -- Dump the meta page 9558f0484fSRodney W. Grimes * 9658f0484fSRodney W. Grimes * Parameters: 9758f0484fSRodney W. Grimes * h: pointer to the PAGE 9858f0484fSRodney W. Grimes */ 9958f0484fSRodney W. Grimes void 1000ac22237SXin LI __bt_dmpage(PAGE *h) 10158f0484fSRodney W. Grimes { 10258f0484fSRodney W. Grimes BTMETA *m; 10358f0484fSRodney W. Grimes char *sep; 10458f0484fSRodney W. Grimes 10558f0484fSRodney W. Grimes m = (BTMETA *)h; 106312f1851SJun Kuriyama (void)fprintf(stderr, "magic %x\n", m->magic); 107312f1851SJun Kuriyama (void)fprintf(stderr, "version %u\n", m->version); 108312f1851SJun Kuriyama (void)fprintf(stderr, "psize %u\n", m->psize); 109312f1851SJun Kuriyama (void)fprintf(stderr, "free %u\n", m->free); 110312f1851SJun Kuriyama (void)fprintf(stderr, "nrecs %u\n", m->nrecs); 111312f1851SJun Kuriyama (void)fprintf(stderr, "flags %u", m->flags); 11258f0484fSRodney W. Grimes #undef X 11358f0484fSRodney W. Grimes #define X(flag, name) \ 114ef5d438eSPaul Traina if (m->flags & flag) { \ 11558f0484fSRodney W. Grimes (void)fprintf(stderr, "%s%s", sep, name); \ 11658f0484fSRodney W. Grimes sep = ", "; \ 11758f0484fSRodney W. Grimes } 118ef5d438eSPaul Traina if (m->flags) { 11958f0484fSRodney W. Grimes sep = " ("; 12058f0484fSRodney W. Grimes X(B_NODUPS, "NODUPS"); 12158f0484fSRodney W. Grimes X(R_RECNO, "RECNO"); 12258f0484fSRodney W. Grimes (void)fprintf(stderr, ")"); 12358f0484fSRodney W. Grimes } 12458f0484fSRodney W. Grimes } 12558f0484fSRodney W. Grimes 12658f0484fSRodney W. Grimes /* 12758f0484fSRodney W. Grimes * BT_DNPAGE -- Dump the page 12858f0484fSRodney W. Grimes * 12958f0484fSRodney W. Grimes * Parameters: 13058f0484fSRodney W. Grimes * n: page number to dump. 13158f0484fSRodney W. Grimes */ 13258f0484fSRodney W. Grimes void 1330ac22237SXin LI __bt_dnpage(DB *dbp, pgno_t pgno) 13458f0484fSRodney W. Grimes { 13558f0484fSRodney W. Grimes BTREE *t; 13658f0484fSRodney W. Grimes PAGE *h; 13758f0484fSRodney W. Grimes 13858f0484fSRodney W. Grimes t = dbp->internal; 1399fc74a87SXin LI if ((h = mpool_get(t->bt_mp, pgno, MPOOL_IGNOREPIN)) != NULL) 14058f0484fSRodney W. Grimes __bt_dpage(h); 14158f0484fSRodney W. Grimes } 14258f0484fSRodney W. Grimes 14358f0484fSRodney W. Grimes /* 14458f0484fSRodney W. Grimes * BT_DPAGE -- Dump the page 14558f0484fSRodney W. Grimes * 14658f0484fSRodney W. Grimes * Parameters: 14758f0484fSRodney W. Grimes * h: pointer to the PAGE 14858f0484fSRodney W. Grimes */ 14958f0484fSRodney W. Grimes void 1500ac22237SXin LI __bt_dpage(PAGE *h) 15158f0484fSRodney W. Grimes { 15258f0484fSRodney W. Grimes BINTERNAL *bi; 15358f0484fSRodney W. Grimes BLEAF *bl; 15458f0484fSRodney W. Grimes RINTERNAL *ri; 15558f0484fSRodney W. Grimes RLEAF *rl; 15658f0484fSRodney W. Grimes indx_t cur, top; 15758f0484fSRodney W. Grimes char *sep; 15858f0484fSRodney W. Grimes 1597efabbb9SXin LI (void)fprintf(stderr, " page %u: (", h->pgno); 16058f0484fSRodney W. Grimes #undef X 16158f0484fSRodney W. Grimes #define X(flag, name) \ 16258f0484fSRodney W. Grimes if (h->flags & flag) { \ 16358f0484fSRodney W. Grimes (void)fprintf(stderr, "%s%s", sep, name); \ 16458f0484fSRodney W. Grimes sep = ", "; \ 16558f0484fSRodney W. Grimes } 16658f0484fSRodney W. Grimes sep = ""; 16758f0484fSRodney W. Grimes X(P_BINTERNAL, "BINTERNAL") /* types */ 16858f0484fSRodney W. Grimes X(P_BLEAF, "BLEAF") 16958f0484fSRodney W. Grimes X(P_RINTERNAL, "RINTERNAL") /* types */ 17058f0484fSRodney W. Grimes X(P_RLEAF, "RLEAF") 17158f0484fSRodney W. Grimes X(P_OVERFLOW, "OVERFLOW") 17258f0484fSRodney W. Grimes X(P_PRESERVE, "PRESERVE"); 17358f0484fSRodney W. Grimes (void)fprintf(stderr, ")\n"); 17458f0484fSRodney W. Grimes #undef X 17558f0484fSRodney W. Grimes 1767efabbb9SXin LI (void)fprintf(stderr, "\tprev %2u next %2u", h->prevpg, h->nextpg); 17758f0484fSRodney W. Grimes if (h->flags & P_OVERFLOW) 17858f0484fSRodney W. Grimes return; 17958f0484fSRodney W. Grimes 18058f0484fSRodney W. Grimes top = NEXTINDEX(h); 18158f0484fSRodney W. Grimes (void)fprintf(stderr, " lower %3d upper %3d nextind %d\n", 18258f0484fSRodney W. Grimes h->lower, h->upper, top); 18358f0484fSRodney W. Grimes for (cur = 0; cur < top; cur++) { 18458f0484fSRodney W. Grimes (void)fprintf(stderr, "\t[%03d] %4d ", cur, h->linp[cur]); 18558f0484fSRodney W. Grimes switch (h->flags & P_TYPE) { 18658f0484fSRodney W. Grimes case P_BINTERNAL: 18758f0484fSRodney W. Grimes bi = GETBINTERNAL(h, cur); 18858f0484fSRodney W. Grimes (void)fprintf(stderr, 18958f0484fSRodney W. Grimes "size %03d pgno %03d", bi->ksize, bi->pgno); 19058f0484fSRodney W. Grimes if (bi->flags & P_BIGKEY) 19158f0484fSRodney W. Grimes (void)fprintf(stderr, " (indirect)"); 19258f0484fSRodney W. Grimes else if (bi->ksize) 19358f0484fSRodney W. Grimes (void)fprintf(stderr, 19458f0484fSRodney W. Grimes " {%.*s}", (int)bi->ksize, bi->bytes); 19558f0484fSRodney W. Grimes break; 19658f0484fSRodney W. Grimes case P_RINTERNAL: 19758f0484fSRodney W. Grimes ri = GETRINTERNAL(h, cur); 19858f0484fSRodney W. Grimes (void)fprintf(stderr, "entries %03d pgno %03d", 19958f0484fSRodney W. Grimes ri->nrecs, ri->pgno); 20058f0484fSRodney W. Grimes break; 20158f0484fSRodney W. Grimes case P_BLEAF: 20258f0484fSRodney W. Grimes bl = GETBLEAF(h, cur); 20358f0484fSRodney W. Grimes if (bl->flags & P_BIGKEY) 20458f0484fSRodney W. Grimes (void)fprintf(stderr, 205312f1851SJun Kuriyama "big key page %u size %u/", 20658f0484fSRodney W. Grimes *(pgno_t *)bl->bytes, 207ef5d438eSPaul Traina *(u_int32_t *)(bl->bytes + sizeof(pgno_t))); 20858f0484fSRodney W. Grimes else if (bl->ksize) 209312f1851SJun Kuriyama (void)fprintf(stderr, "%.*s/", 210312f1851SJun Kuriyama bl->ksize, bl->bytes); 21158f0484fSRodney W. Grimes if (bl->flags & P_BIGDATA) 21258f0484fSRodney W. Grimes (void)fprintf(stderr, 213312f1851SJun Kuriyama "big data page %u size %u", 21458f0484fSRodney W. Grimes *(pgno_t *)(bl->bytes + bl->ksize), 215ef5d438eSPaul Traina *(u_int32_t *)(bl->bytes + bl->ksize + 21658f0484fSRodney W. Grimes sizeof(pgno_t))); 21758f0484fSRodney W. Grimes else if (bl->dsize) 21858f0484fSRodney W. Grimes (void)fprintf(stderr, "%.*s", 21958f0484fSRodney W. Grimes (int)bl->dsize, bl->bytes + bl->ksize); 22058f0484fSRodney W. Grimes break; 22158f0484fSRodney W. Grimes case P_RLEAF: 22258f0484fSRodney W. Grimes rl = GETRLEAF(h, cur); 22358f0484fSRodney W. Grimes if (rl->flags & P_BIGDATA) 22458f0484fSRodney W. Grimes (void)fprintf(stderr, 225312f1851SJun Kuriyama "big data page %u size %u", 22658f0484fSRodney W. Grimes *(pgno_t *)rl->bytes, 227ef5d438eSPaul Traina *(u_int32_t *)(rl->bytes + sizeof(pgno_t))); 22858f0484fSRodney W. Grimes else if (rl->dsize) 22958f0484fSRodney W. Grimes (void)fprintf(stderr, 23058f0484fSRodney W. Grimes "%.*s", (int)rl->dsize, rl->bytes); 23158f0484fSRodney W. Grimes break; 23258f0484fSRodney W. Grimes } 23358f0484fSRodney W. Grimes (void)fprintf(stderr, "\n"); 23458f0484fSRodney W. Grimes } 23558f0484fSRodney W. Grimes } 23658f0484fSRodney W. Grimes #endif 23758f0484fSRodney W. Grimes 23858f0484fSRodney W. Grimes #ifdef STATISTICS 23958f0484fSRodney W. Grimes /* 24058f0484fSRodney W. Grimes * BT_STAT -- Gather/print the tree statistics 24158f0484fSRodney W. Grimes * 24258f0484fSRodney W. Grimes * Parameters: 24358f0484fSRodney W. Grimes * dbp: pointer to the DB 24458f0484fSRodney W. Grimes */ 24558f0484fSRodney W. Grimes void 2460ac22237SXin LI __bt_stat(DB *dbp) 24758f0484fSRodney W. Grimes { 24858f0484fSRodney W. Grimes extern u_long bt_cache_hit, bt_cache_miss, bt_pfxsaved, bt_rootsplit; 24958f0484fSRodney W. Grimes extern u_long bt_sortsplit, bt_split; 25058f0484fSRodney W. Grimes BTREE *t; 25158f0484fSRodney W. Grimes PAGE *h; 25258f0484fSRodney W. Grimes pgno_t i, pcont, pinternal, pleaf; 25358f0484fSRodney W. Grimes u_long ifree, lfree, nkeys; 25458f0484fSRodney W. Grimes int levels; 25558f0484fSRodney W. Grimes 25658f0484fSRodney W. Grimes t = dbp->internal; 25758f0484fSRodney W. Grimes pcont = pinternal = pleaf = 0; 25858f0484fSRodney W. Grimes nkeys = ifree = lfree = 0; 2599fc74a87SXin LI for (i = P_ROOT; 2609fc74a87SXin LI (h = mpool_get(t->bt_mp, i, MPOOL_IGNOREPIN)) != NULL; ++i) 26158f0484fSRodney W. Grimes switch (h->flags & P_TYPE) { 26258f0484fSRodney W. Grimes case P_BINTERNAL: 26358f0484fSRodney W. Grimes case P_RINTERNAL: 26458f0484fSRodney W. Grimes ++pinternal; 26558f0484fSRodney W. Grimes ifree += h->upper - h->lower; 26658f0484fSRodney W. Grimes break; 26758f0484fSRodney W. Grimes case P_BLEAF: 26858f0484fSRodney W. Grimes case P_RLEAF: 26958f0484fSRodney W. Grimes ++pleaf; 27058f0484fSRodney W. Grimes lfree += h->upper - h->lower; 27158f0484fSRodney W. Grimes nkeys += NEXTINDEX(h); 27258f0484fSRodney W. Grimes break; 27358f0484fSRodney W. Grimes case P_OVERFLOW: 27458f0484fSRodney W. Grimes ++pcont; 27558f0484fSRodney W. Grimes break; 27658f0484fSRodney W. Grimes } 27758f0484fSRodney W. Grimes 27858f0484fSRodney W. Grimes /* Count the levels of the tree. */ 27958f0484fSRodney W. Grimes for (i = P_ROOT, levels = 0 ;; ++levels) { 2809fc74a87SXin LI h = mpool_get(t->bt_mp, i, MPOOL_IGNOREPIN); 28158f0484fSRodney W. Grimes if (h->flags & (P_BLEAF|P_RLEAF)) { 28258f0484fSRodney W. Grimes if (levels == 0) 28358f0484fSRodney W. Grimes levels = 1; 28458f0484fSRodney W. Grimes break; 28558f0484fSRodney W. Grimes } 286ef5d438eSPaul Traina i = F_ISSET(t, R_RECNO) ? 28758f0484fSRodney W. Grimes GETRINTERNAL(h, 0)->pgno : 28858f0484fSRodney W. Grimes GETBINTERNAL(h, 0)->pgno; 28958f0484fSRodney W. Grimes } 29058f0484fSRodney W. Grimes 2917efabbb9SXin LI (void)fprintf(stderr, "%d level%s with %lu keys", 29258f0484fSRodney W. Grimes levels, levels == 1 ? "" : "s", nkeys); 293ef5d438eSPaul Traina if (F_ISSET(t, R_RECNO)) 2947efabbb9SXin LI (void)fprintf(stderr, " (%u header count)", t->bt_nrecs); 29558f0484fSRodney W. Grimes (void)fprintf(stderr, 2967efabbb9SXin LI "\n%u pages (leaf %u, internal %u, overflow %u)\n", 29758f0484fSRodney W. Grimes pinternal + pleaf + pcont, pleaf, pinternal, pcont); 2987efabbb9SXin LI (void)fprintf(stderr, "%lu cache hits, %lu cache misses\n", 29958f0484fSRodney W. Grimes bt_cache_hit, bt_cache_miss); 300312f1851SJun Kuriyama (void)fprintf(stderr, "%lu splits (%lu root splits, %lu sort splits)\n", 30158f0484fSRodney W. Grimes bt_split, bt_rootsplit, bt_sortsplit); 30258f0484fSRodney W. Grimes pleaf *= t->bt_psize - BTDATAOFF; 30358f0484fSRodney W. Grimes if (pleaf) 30458f0484fSRodney W. Grimes (void)fprintf(stderr, 3057efabbb9SXin LI "%.0f%% leaf fill (%lu bytes used, %lu bytes free)\n", 30658f0484fSRodney W. Grimes ((double)(pleaf - lfree) / pleaf) * 100, 30758f0484fSRodney W. Grimes pleaf - lfree, lfree); 30858f0484fSRodney W. Grimes pinternal *= t->bt_psize - BTDATAOFF; 30958f0484fSRodney W. Grimes if (pinternal) 31058f0484fSRodney W. Grimes (void)fprintf(stderr, 3117efabbb9SXin LI "%.0f%% internal fill (%lu bytes used, %lu bytes free\n", 31258f0484fSRodney W. Grimes ((double)(pinternal - ifree) / pinternal) * 100, 31358f0484fSRodney W. Grimes pinternal - ifree, ifree); 31458f0484fSRodney W. Grimes if (bt_pfxsaved) 31558f0484fSRodney W. Grimes (void)fprintf(stderr, "prefix checking removed %lu bytes.\n", 31658f0484fSRodney W. Grimes bt_pfxsaved); 31758f0484fSRodney W. Grimes } 31858f0484fSRodney W. Grimes #endif 319