diff options
Diffstat (limited to 'contrib/netbsd-tests/lib/libc/db/h_db.c')
-rw-r--r-- | contrib/netbsd-tests/lib/libc/db/h_db.c | 77 |
1 files changed, 70 insertions, 7 deletions
diff --git a/contrib/netbsd-tests/lib/libc/db/h_db.c b/contrib/netbsd-tests/lib/libc/db/h_db.c index dfb1385..dd19a03 100644 --- a/contrib/netbsd-tests/lib/libc/db/h_db.c +++ b/contrib/netbsd-tests/lib/libc/db/h_db.c @@ -1,4 +1,4 @@ -/* $NetBSD: h_db.c,v 1.1 2011/01/07 15:05:58 pgoyette Exp $ */ +/* $NetBSD: h_db.c,v 1.3 2016/09/24 21:18:22 christos Exp $ */ /*- * Copyright (c) 1992, 1993, 1994 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1992, 1993, 1994\ #if 0 static char sccsid[] = "@(#)dbtest.c 8.17 (Berkeley) 9/1/94"; #else -__RCSID("$NetBSD: h_db.c,v 1.1 2011/01/07 15:05:58 pgoyette Exp $"); +__RCSID("$NetBSD: h_db.c,v 1.3 2016/09/24 21:18:22 christos Exp $"); #endif #endif /* not lint */ @@ -57,12 +57,13 @@ __RCSID("$NetBSD: h_db.c,v 1.1 2011/01/07 15:05:58 pgoyette Exp $"); #include <unistd.h> #include <err.h> #include <db.h> +#include "btree.h" enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA }; static void compare(DBT *, DBT *); static DBTYPE dbtype(const char *); -static void dump(DB *, int); +static void dump(DB *, int, int); static void get(DB *, DBT *); static void getdata(DB *, DBT *, DBT *); static void put(DB *, DBT *, DBT *); @@ -73,6 +74,9 @@ static void *rfile(char *, size_t *); static void seq(DB *, DBT *); static u_int setflags(char *); static void *setinfo(DBTYPE, char *); +#ifdef __NetBSD__ +static void unlinkpg(DB *); +#endif static void usage(void) __attribute__((__noreturn__)); static void *xcopy(void *, size_t); static void chkcmd(enum S); @@ -82,6 +86,9 @@ static void chkkey(enum S); #ifdef STATISTICS extern void __bt_stat(DB *); #endif +#ifdef __NetBSD__ +extern int __bt_relink(BTREE *, PAGE *); +#endif static DBTYPE type; /* Database type. */ static void *infop; /* Iflags. */ @@ -315,8 +322,16 @@ lkey: switch (command) { } break; case 'o': - dump(dbp, p[1] == 'r'); + dump(dbp, p[1] == 'r', 0); + break; +#ifdef __NetBSD__ + case 'O': + dump(dbp, p[1] == 'r', 1); break; + case 'u': + unlinkpg(dbp); + break; +#endif default: errx(1, "line %zu: %s: unknown command character", lineno, p); @@ -483,17 +498,25 @@ seq(DB *dbp, DBT *kp) } static void -dump(DB *dbp, int rev) +dump(DB *dbp, int rev, int recurse) { DBT key, data; int xflags, nflags; if (rev) { xflags = R_LAST; +#ifdef __NetBSD__ + nflags = recurse ? R_RPREV : R_PREV; +#else nflags = R_PREV; +#endif } else { xflags = R_FIRST; +#ifdef __NetBSD__ + nflags = recurse ? R_RNEXT : R_NEXT; +#else nflags = R_NEXT; +#endif } for (;; xflags = nflags) switch (dbp->seq(dbp, &key, &data, xflags)) { @@ -511,6 +534,42 @@ dump(DB *dbp, int rev) done: return; } +#ifdef __NetBSD__ +void +unlinkpg(DB *dbp) +{ + BTREE *t = dbp->internal; + PAGE *h = NULL; + pgno_t pg; + + for (pg = P_ROOT; pg < t->bt_mp->npages; + mpool_put(t->bt_mp, h, 0), pg++) { + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + break; + /* Look for a nonempty leaf page that has both left + * and right siblings. */ + if (h->prevpg == P_INVALID || h->nextpg == P_INVALID) + continue; + if (NEXTINDEX(h) == 0) + continue; + if ((h->flags & (P_BLEAF | P_RLEAF))) + break; + } + if (h == NULL || pg == t->bt_mp->npages) { + errx(1, "%s: no appropriate page found", __func__); + return; + } + if (__bt_relink(t, h) != 0) { + perror("unlinkpg"); + goto cleanup; + } + h->prevpg = P_INVALID; + h->nextpg = P_INVALID; +cleanup: + mpool_put(t->bt_mp, h, MPOOL_DIRTY); +} +#endif + static u_int setflags(char *s) { @@ -725,7 +784,11 @@ static void usage(void) { (void)fprintf(stderr, - "Usage: %s [-l] [-f file] [-i info] [-o file] type script\n", - getprogname()); +#ifdef __NetBSD__ + "Usage: %s [-lu] [-f file] [-i info] [-o file] [-O file] " +#else + "Usage: %s [-l] [-f file] [-i info] [-o file] " +#endif + "type script\n", getprogname()); exit(1); } |