📄 db_pr.c
字号:
return (ret); ret = __db_prpage(dbp, h, fp, DB_PR_PAGE); if ((t_ret = mpf->put(mpf, h, 0)) != 0 && ret == 0) ret = t_ret; return (ret);}/* * __db_prpage * -- Print out a page. * * PUBLIC: int __db_prpage __P((DB *, PAGE *, FILE *, u_int32_t)); */int__db_prpage(dbp, h, fp, flags) DB *dbp; PAGE *h; FILE *fp; u_int32_t flags;{ BINTERNAL *bi; BKEYDATA *bk; HOFFPAGE a_hkd; QAMDATA *qp, *qep; RINTERNAL *ri; db_indx_t dlen, len, i, *inp; db_pgno_t pgno; db_recno_t recno; u_int32_t pagesize, qlen; u_int8_t *ep, *hk, *p; int deleted, ret; const char *s; void *sp; /* * If we're doing recovery testing and this page is P_INVALID, * assume it's a page that's on the free list, and don't display it. */ if (LF_ISSET(DB_PR_RECOVERYTEST) && TYPE(h) == P_INVALID) return (0); s = __db_pagetype_to_string(TYPE(h)); if (s == NULL) { fprintf(fp, "ILLEGAL PAGE TYPE: page: %lu type: %lu\n", (u_long)h->pgno, (u_long)TYPE(h)); return (1); } /* * !!! * Find out the page size. We don't want to do it the "right" way, * by reading the value from the meta-data page, that's going to be * slow. Reach down into the mpool region. */ pagesize = (u_int32_t)dbp->mpf->mfp->stat.st_pagesize; /* Page number, page type. */ fprintf(fp, "page %lu: %s level: %lu", (u_long)h->pgno, s, (u_long)h->level); /* Record count. */ if (TYPE(h) == P_IBTREE || TYPE(h) == P_IRECNO || (TYPE(h) == P_LRECNO && h->pgno == ((BTREE *)dbp->bt_internal)->bt_root)) fprintf(fp, " records: %lu", (u_long)RE_NREC(h)); /* LSN. */ if (!LF_ISSET(DB_PR_RECOVERYTEST)) fprintf(fp, " (lsn.file: %lu lsn.offset: %lu)\n", (u_long)LSN(h).file, (u_long)LSN(h).offset); switch (TYPE(h)) { case P_BTREEMETA: return (__db_bmeta(dbp, fp, (BTMETA *)h, flags)); case P_HASHMETA: return (__db_hmeta(dbp, fp, (HMETA *)h, flags)); case P_QAMMETA: return (__db_qmeta(dbp, fp, (QMETA *)h, flags)); case P_QAMDATA: /* Should be meta->start. */ if (!LF_ISSET(DB_PR_PAGE)) return (0); qlen = ((QUEUE *)dbp->q_internal)->re_len; recno = (h->pgno - 1) * QAM_RECNO_PER_PAGE(dbp) + 1; i = 0; qep = (QAMDATA *)((u_int8_t *)h + pagesize - qlen); for (qp = QAM_GET_RECORD(dbp, h, i); qp < qep; recno++, i++, qp = QAM_GET_RECORD(dbp, h, i)) { if (!F_ISSET(qp, QAM_SET)) continue; fprintf(fp, "%s", F_ISSET(qp, QAM_VALID) ? "\t" : " D"); fprintf(fp, "[%03lu] %4lu ", (u_long)recno, (u_long)((u_int8_t *)qp - (u_int8_t *)h)); __db_pr(qp->data, qlen, fp); } return (0); } /* LSN. */ if (LF_ISSET(DB_PR_RECOVERYTEST)) fprintf(fp, " (lsn.file: %lu lsn.offset: %lu)\n", (u_long)LSN(h).file, (u_long)LSN(h).offset); s = "\t"; if (TYPE(h) != P_IBTREE && TYPE(h) != P_IRECNO) { fprintf(fp, "%sprev: %4lu next: %4lu", s, (u_long)PREV_PGNO(h), (u_long)NEXT_PGNO(h)); s = " "; } if (TYPE(h) == P_OVERFLOW) { fprintf(fp, "%sref cnt: %4lu ", s, (u_long)OV_REF(h)); __db_pr((u_int8_t *)h + P_OVERHEAD(dbp), OV_LEN(h), fp); return (0); } fprintf(fp, "%sentries: %4lu", s, (u_long)NUM_ENT(h)); fprintf(fp, " offset: %4lu\n", (u_long)HOFFSET(h)); if (TYPE(h) == P_INVALID || !LF_ISSET(DB_PR_PAGE)) return (0); ret = 0; inp = P_INP(dbp, h); for (i = 0; i < NUM_ENT(h); i++) { if ((db_alignp_t)(P_ENTRY(dbp, h, i) - (u_int8_t *)h) < (db_alignp_t)(P_OVERHEAD(dbp)) || (size_t)(P_ENTRY(dbp, h, i) - (u_int8_t *)h) >= pagesize) { fprintf(fp, "ILLEGAL PAGE OFFSET: indx: %lu of %lu\n", (u_long)i, (u_long)inp[i]); ret = EINVAL; continue; } deleted = 0; switch (TYPE(h)) { case P_HASH: case P_IBTREE: case P_IRECNO: sp = P_ENTRY(dbp, h, i); break; case P_LBTREE: sp = P_ENTRY(dbp, h, i); deleted = i % 2 == 0 && B_DISSET(GET_BKEYDATA(dbp, h, i + O_INDX)->type); break; case P_LDUP: case P_LRECNO: sp = P_ENTRY(dbp, h, i); deleted = B_DISSET(GET_BKEYDATA(dbp, h, i)->type); break; default: fprintf(fp, "ILLEGAL PAGE ITEM: %lu\n", (u_long)TYPE(h)); ret = EINVAL; continue; } fprintf(fp, "%s", deleted ? " D" : "\t"); fprintf(fp, "[%03lu] %4lu ", (u_long)i, (u_long)inp[i]); switch (TYPE(h)) { case P_HASH: hk = sp; switch (HPAGE_PTYPE(hk)) { case H_OFFDUP: memcpy(&pgno, HOFFDUP_PGNO(hk), sizeof(db_pgno_t)); fprintf(fp, "%4lu [offpage dups]\n", (u_long)pgno); break; case H_DUPLICATE: /* * If this is the first item on a page, then * we cannot figure out how long it is, so * we only print the first one in the duplicate * set. */ if (i != 0) len = LEN_HKEYDATA(dbp, h, 0, i); else len = 1; fprintf(fp, "Duplicates:\n"); for (p = HKEYDATA_DATA(hk), ep = p + len; p < ep;) { memcpy(&dlen, p, sizeof(db_indx_t)); p += sizeof(db_indx_t); fprintf(fp, "\t\t"); __db_pr(p, dlen, fp); p += sizeof(db_indx_t) + dlen; } break; case H_KEYDATA: __db_pr(HKEYDATA_DATA(hk), LEN_HKEYDATA(dbp, h, i == 0 ? pagesize : 0, i), fp); break; case H_OFFPAGE: memcpy(&a_hkd, hk, HOFFPAGE_SIZE); fprintf(fp, "overflow: total len: %4lu page: %4lu\n", (u_long)a_hkd.tlen, (u_long)a_hkd.pgno); break; } break; case P_IBTREE: bi = sp; fprintf(fp, "count: %4lu pgno: %4lu type: %4lu", (u_long)bi->nrecs, (u_long)bi->pgno, (u_long)bi->type); switch (B_TYPE(bi->type)) { case B_KEYDATA: __db_pr(bi->data, bi->len, fp); break; case B_DUPLICATE: case B_OVERFLOW: __db_proff(bi->data, fp); break; default: fprintf(fp, "ILLEGAL BINTERNAL TYPE: %lu\n", (u_long)B_TYPE(bi->type)); ret = EINVAL; break; } break; case P_IRECNO: ri = sp; fprintf(fp, "entries %4lu pgno %4lu\n", (u_long)ri->nrecs, (u_long)ri->pgno); break; case P_LBTREE: case P_LDUP: case P_LRECNO: bk = sp; switch (B_TYPE(bk->type)) { case B_KEYDATA: __db_pr(bk->data, bk->len, fp); break; case B_DUPLICATE: case B_OVERFLOW: __db_proff(bk, fp); break; default: fprintf(fp, "ILLEGAL DUPLICATE/LBTREE/LRECNO TYPE: %lu\n", (u_long)B_TYPE(bk->type)); ret = EINVAL; break; } break; } } (void)fflush(fp); return (ret);}/* * __db_pr -- * Print out a data element. * * PUBLIC: void __db_pr __P((u_int8_t *, u_int32_t, FILE *)); */void__db_pr(p, len, fp) u_int8_t *p; u_int32_t len; FILE *fp;{ u_int lastch; int i; fprintf(fp, "len: %3lu", (u_long)len); lastch = '.'; if (len != 0) { fprintf(fp, " data: "); for (i = len <= 20 ? len : 20; i > 0; --i, ++p) { lastch = *p; if (isprint((int)*p) || *p == '\n') fprintf(fp, "%c", *p); else fprintf(fp, "0x%.2x", (u_int)*p); } if (len > 20) { fprintf(fp, "..."); lastch = '.'; } } if (lastch != '\n') fprintf(fp, "\n");}/* * __db_prdbt -- * Print out a DBT data element. * * PUBLIC: int __db_prdbt __P((DBT *, int, const char *, void *, * PUBLIC: int (*)(void *, const void *), int, VRFY_DBINFO *)); */int__db_prdbt(dbtp, checkprint, prefix, handle, callback, is_recno, vdp) DBT *dbtp; int checkprint; const char *prefix; void *handle; int (*callback) __P((void *, const void *)); int is_recno; VRFY_DBINFO *vdp;{ static const char hex[] = "0123456789abcdef"; db_recno_t recno; u_int32_t len; int ret;#define DBTBUFLEN 100 char *p, *hp, buf[DBTBUFLEN], hbuf[DBTBUFLEN]; if (vdp != NULL) { /* * If vdp is non-NULL, we might be the first key in the * "fake" subdatabase used for key/data pairs we can't * associate with a known subdb. * * Check and clear the SALVAGE_PRINTHEADER flag; if * it was set, print a subdatabase header. */ if (F_ISSET(vdp, SALVAGE_PRINTHEADER)) (void)__db_prheader(NULL, "__OTHER__", 0, 0, handle, callback, vdp, 0); F_CLR(vdp, SALVAGE_PRINTHEADER); F_SET(vdp, SALVAGE_PRINTFOOTER); /* * Even if the printable flag wasn't set by our immediate * caller, it may be set on a salvage-wide basis. */ if (F_ISSET(vdp, SALVAGE_PRINTABLE)) checkprint = 1; } /* * !!! * This routine is the routine that dumps out items in the format * used by db_dump(1) and db_load(1). This means that the format * cannot change. */ if (prefix != NULL && (ret = callback(handle, prefix)) != 0) return (ret); if (is_recno) { /* * We're printing a record number, and this has to be done * in a platform-independent way. So we use the numeral in * straight ASCII. */ (void)__ua_memcpy(&recno, dbtp->data, sizeof(recno)); snprintf(buf, DBTBUFLEN, "%lu", (u_long)recno); /* If we're printing data as hex, print keys as hex too. */ if (!checkprint) { for (len = (u_int32_t)strlen(buf), p = buf, hp = hbuf; len-- > 0; ++p) { *hp++ = hex[(u_int8_t)(*p & 0xf0) >> 4]; *hp++ = hex[*p & 0x0f]; } *hp = '\0'; ret = callback(handle, hbuf); } else ret = callback(handle, buf); if (ret != 0) return (ret); } else if (checkprint) { for (len = dbtp->size, p = dbtp->data; len--; ++p) if (isprint((int)*p)) { if (*p == '\\' && (ret = callback(handle, "\\")) != 0) return (ret); snprintf(buf, DBTBUFLEN, "%c", *p); if ((ret = callback(handle, buf)) != 0) return (ret); } else { snprintf(buf, DBTBUFLEN, "\\%c%c", hex[(u_int8_t)(*p & 0xf0) >> 4], hex[*p & 0x0f]); if ((ret = callback(handle, buf)) != 0) return (ret); } } else for (len = dbtp->size, p = dbtp->data; len--; ++p) { snprintf(buf, DBTBUFLEN, "%c%c", hex[(u_int8_t)(*p & 0xf0) >> 4], hex[*p & 0x0f]); if ((ret = callback(handle, buf)) != 0) return (ret); } return (callback(handle, "\n"));}/* * __db_proff -- * Print out an off-page element. */static void__db_proff(vp, fp) void *vp; FILE *fp;{ BOVERFLOW *bo; bo = vp; switch (B_TYPE(bo->type)) { case B_OVERFLOW: fprintf(fp, "overflow: total len: %4lu page: %4lu\n", (u_long)bo->tlen, (u_long)bo->pgno); break; case B_DUPLICATE: fprintf(fp, "duplicate: page: %4lu\n", (u_long)bo->pgno); break; }}/* * __db_prflags -- * Print out flags values. * * PUBLIC: void __db_prflags __P((u_int32_t, const FN *, void *)); */void__db_prflags(flags, fn, vfp) u_int32_t flags; FN const *fn;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -