/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996, 1997, 1998
* Sleepycat Software. All rights reserved.
*/
#include "config.h"
#ifndef lint
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#endif
#include "db_int.h"
#include "db_page.h"
#include "btree.h"
#include "hash.h"
#include "db_am.h"
static void __db_proff __P((void *));
/*
* __db_loadme --
* Force loading of this file.
*
* PUBLIC: void __db_loadme __P((void));
*/
void
{
getpid();
}
/*
* 64K is the maximum page size, so by default we check for offsets
* larger than that, and, where possible, we refine the test.
*/
/*
* __db_prinit --
* Initialize tree printing routines.
*
* PUBLIC: FILE *__db_prinit __P((FILE *));
*/
FILE *
{
return (set_fp);
}
/*
* __db_dump --
* Dump the tree to a file.
*
* PUBLIC: int __db_dump __P((DB *, char *, int));
*/
int
char *name;
int all;
{
if (set_psize == PSIZE_BOUNDARY)
return (errno);
} else
(void)__db_prhash(dbp);
else
(void)__db_prbtree(dbp);
}
return (0);
}
/*
* __db_prdb --
* Print out the DB structure information.
*
* PUBLIC: int __db_prdb __P((DB *));
*/
int
{
{ DB_AM_DUP, "duplicates" },
{ DB_AM_INMEM, "in-memory" },
{ DB_AM_LOCKING, "locking" },
{ DB_AM_LOGGING, "logging" },
{ DB_AM_MLOCAL, "local mpool" },
{ DB_AM_PGDEF, "default page size" },
{ DB_AM_RDONLY, "read-only" },
{ DB_AM_SWAP, "needswap" },
{ DB_AM_THREAD, "thread" },
{ DB_BT_RECNUM, "btree:recnum" },
{ DB_DBM_ERROR, "dbm/ndbm error" },
{ DB_RE_DELIMITER, "recno:delimiter" },
{ DB_RE_FIXEDLEN, "recno:fixed-length" },
{ DB_RE_PAD, "recno:pad" },
{ DB_RE_RENUMBER, "recno:renumber" },
{ DB_RE_SNAPSHOT, "recno:snapshot" },
{ 0 },
};
const char *t;
case DB_BTREE:
t = "btree";
break;
case DB_HASH:
t = "hash";
break;
case DB_RECNO:
t = "recno";
break;
default:
t = "UNKNOWN";
break;
}
return (0);
}
/*
* __db_prbtree --
* Print out the btree internal information.
*
* PUBLIC: int __db_prbtree __P((DB *));
*/
int
{
{ BTM_DUP, "duplicates" },
{ BTM_RECNO, "recno" },
{ BTM_RECNUM, "btree:recnum" },
{ BTM_FIXEDLEN, "recno:fixed-length" },
{ BTM_RENUMBER, "recno:renumber" },
{ 0 },
};
BTREE *t;
PAGE *h;
db_pgno_t i;
const char *sep;
return (ret);
i = PGNO_METADATA;
return (ret);
}
return (ret);
i = h->next_pgno;
if (++cnt % 10 == 0) {
cnt = 0;
sep = "";
} else
sep = ", ";
}
"re_delim: %#lx re_pad: %#lx re_len: %lu re_source: %s\n",
"cmap: %#lx smap: %#lx emap: %#lx msize: %lu\n",
}
}
/*
* __db_prhash --
* Print out the hash internal information.
*
* PUBLIC: int __db_prhash __P((DB *));
*/
int
{
return (ret);
/*
* In this case, hcp->hdr will never be null, if we decide
* to pass dbc's to this routine instead, then it could be.
*/
return (ret);
put_page = 1;
} else
put_page = 0;
for (i = 0; i < NCACHED; i++)
if (put_page) {
}
}
/*
* __db_prtree --
* Print out the entire tree.
*
* PUBLIC: int __db_prtree __P((DB_MPOOLFILE *, int));
*/
int
int all;
{
PAGE *h;
db_pgno_t i;
if (set_psize == PSIZE_BOUNDARY)
for (i = PGNO_ROOT;; ++i) {
break;
(void)__db_prpage(h, all);
}
return (0);
}
/*
* __db_prnpage
* -- Print out a specific page.
*
* PUBLIC: int __db_prnpage __P((DB_MPOOLFILE *, db_pgno_t));
*/
int
{
PAGE *h;
int ret;
if (set_psize == PSIZE_BOUNDARY)
return (ret);
return (ret);
}
/*
* __db_prpage
* -- Print out a page.
*
* PUBLIC: int __db_prpage __P((PAGE *, int));
*/
int
PAGE *h;
int all;
{
const char *s;
void *sp;
switch (TYPE(h)) {
case P_DUPLICATE:
s = "duplicate";
break;
case P_HASH:
s = "hash";
break;
case P_IBTREE:
s = "btree internal";
break;
case P_INVALID:
s = "invalid";
break;
case P_IRECNO:
s = "recno internal";
break;
case P_LBTREE:
s = "btree leaf";
break;
case P_LRECNO:
s = "recno leaf";
break;
case P_OVERFLOW:
s = "overflow";
break;
default:
return (1);
}
if (TYPE(h) == P_OVERFLOW) {
return (0);
}
return (0);
ret = 0;
for (i = 0; i < NUM_ENT(h); i++) {
"ILLEGAL PAGE OFFSET: indx: %lu of %lu\n",
continue;
}
deleted = 0;
switch (TYPE(h)) {
case P_HASH:
case P_IBTREE:
case P_IRECNO:
break;
case P_LBTREE:
deleted = i % 2 == 0 &&
break;
case P_LRECNO:
case P_DUPLICATE:
break;
default:
continue;
}
switch (TYPE(h)) {
case P_HASH:
switch (HPAGE_PTYPE(hk)) {
case H_OFFDUP:
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(h, 0, i);
else
len = 1;
for (p = HKEYDATA_DATA(hk),
p += sizeof(db_indx_t);
}
break;
case H_KEYDATA:
if (i != 0)
LEN_HKEYDATA(h, 0, i));
else
break;
case H_OFFPAGE:
"overflow: total len: %4lu page: %4lu\n",
break;
}
break;
case P_IBTREE:
case B_KEYDATA:
break;
case B_DUPLICATE:
case B_OVERFLOW:
break;
default:
break;
}
break;
case P_IRECNO:
break;
case P_LBTREE:
case P_LRECNO:
case P_DUPLICATE:
case B_KEYDATA:
break;
case B_DUPLICATE:
case B_OVERFLOW:
__db_proff(bk);
break;
default:
break;
}
break;
}
}
return (ret);
}
/*
* __db_isbad
* -- Decide if a page is corrupted.
*
* PUBLIC: int __db_isbad __P((PAGE *, int));
*/
int
PAGE *h;
int die;
{
db_indx_t i;
switch (TYPE(h)) {
case P_DUPLICATE:
case P_HASH:
case P_IBTREE:
case P_INVALID:
case P_IRECNO:
case P_LBTREE:
case P_LRECNO:
case P_OVERFLOW:
break;
default:
goto bad;
}
for (i = 0; i < NUM_ENT(h); i++) {
"ILLEGAL PAGE OFFSET: indx: %lu of %lu\n",
goto bad;
}
switch (TYPE(h)) {
case P_HASH:
type = HPAGE_TYPE(h, i);
type != H_DUPLICATE &&
goto bad;
}
break;
case P_IBTREE:
bi = GET_BINTERNAL(h, i);
goto bad;
}
break;
case P_IRECNO:
case P_LBTREE:
case P_LRECNO:
break;
case P_DUPLICATE:
bk = GET_BKEYDATA(h, i);
goto bad;
}
break;
default:
goto bad;
}
}
return (0);
abort();
/* NOTREACHED */
}
return (1);
}
/*
* __db_pr --
* Print out a data element.
*
* PUBLIC: void __db_pr __P((u_int8_t *, u_int32_t));
*/
void
u_int8_t *p;
{
int i;
lastch = '.';
if (len != 0) {
lastch = *p;
if (isprint(*p) || *p == '\n')
else
}
if (len > 20) {
lastch = '.';
}
}
if (lastch != '\n')
}
/*
* __db_prdbt --
* Print out a DBT data element.
*
* PUBLIC: int __db_prdbt __P((DBT *, int, FILE *));
*/
int
int checkprint;
{
u_int8_t *p;
/*
* !!!
* 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 (checkprint) {
if (isprint(*p)) {
return (EIO);
return (EIO);
} else
return (EIO);
} else
return (EIO);
}
/*
* __db_proff --
* Print out an off-page element.
*/
static void
void *vp;
{
case B_OVERFLOW:
break;
case B_DUPLICATE:
break;
}
}
/*
* __db_prflags --
* Print out flags values.
*
* PUBLIC: void __db_prflags __P((u_int32_t, const FN *, FILE *));
*/
void
{
int found;
const char *sep;
sep = " (";
sep = ", ";
found = 1;
}
if (found)
}
/*
* __db_psize --
* Get the page size.
*/
static void
{
return;
case DB_BTREEMAGIC:
case DB_HASHMAGIC:
break;
}
}