Merge the recursive tree traversal changes from the mit kerberos tree. This
Also make the tracefile customizable. Unfortunately we can't merge any of the hash changes because they have a different on-disk format. That does not matter really because we've fixed most of the problems...
This commit is contained in:
parent
d42d73761d
commit
86147b1c32
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bt_close.c,v 1.15 2016/08/31 06:23:51 christos Exp $ */
|
||||
/* $NetBSD: bt_close.c,v 1.16 2016/09/24 20:11:12 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
|
@ -37,7 +37,7 @@
|
|||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: bt_close.c,v 1.15 2016/08/31 06:23:51 christos Exp $");
|
||||
__RCSID("$NetBSD: bt_close.c,v 1.16 2016/09/24 20:11:12 christos Exp $");
|
||||
|
||||
#include "namespace.h"
|
||||
|
||||
|
@ -164,7 +164,7 @@ bt_meta(BTREE *t)
|
|||
BTMETA m;
|
||||
void *p;
|
||||
|
||||
if ((p = mpool_get(t->bt_mp, P_META, 0)) == NULL)
|
||||
if ((p = mpool_getf(t->bt_mp, P_META, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
|
||||
/* Fill in metadata. */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bt_conv.c,v 1.14 2008/09/10 17:52:35 joerg Exp $ */
|
||||
/* $NetBSD: bt_conv.c,v 1.15 2016/09/24 20:11:12 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
|
@ -37,10 +37,11 @@
|
|||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: bt_conv.c,v 1.14 2008/09/10 17:52:35 joerg Exp $");
|
||||
__RCSID("$NetBSD: bt_conv.c,v 1.15 2016/09/24 20:11:12 christos Exp $");
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include <db.h>
|
||||
#include "btree.h"
|
||||
|
@ -64,6 +65,7 @@ __bt_pgin(void *t, pgno_t pg, void *pp)
|
|||
indx_t i, top;
|
||||
uint8_t flags;
|
||||
char *p;
|
||||
uint32_t ksize;
|
||||
|
||||
if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
|
||||
return;
|
||||
|
@ -101,6 +103,7 @@ __bt_pgin(void *t, pgno_t pg, void *pp)
|
|||
M_16_SWAP(h->linp[i]);
|
||||
p = (char *)(void *)GETBLEAF(h, i);
|
||||
P_32_SWAP(p);
|
||||
memcpy(&ksize, p, sizeof(ksize));
|
||||
p += sizeof(uint32_t);
|
||||
P_32_SWAP(p);
|
||||
p += sizeof(uint32_t);
|
||||
|
@ -113,7 +116,7 @@ __bt_pgin(void *t, pgno_t pg, void *pp)
|
|||
P_32_SWAP(p);
|
||||
}
|
||||
if (flags & P_BIGDATA) {
|
||||
p += sizeof(uint32_t);
|
||||
p += ksize;
|
||||
P_32_SWAP(p);
|
||||
p += sizeof(pgno_t);
|
||||
P_32_SWAP(p);
|
||||
|
@ -129,6 +132,7 @@ __bt_pgout(void *t, pgno_t pg, void *pp)
|
|||
indx_t i, top;
|
||||
uint8_t flags;
|
||||
char *p;
|
||||
uint32_t ksize;
|
||||
|
||||
if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
|
||||
return;
|
||||
|
@ -157,6 +161,7 @@ __bt_pgout(void *t, pgno_t pg, void *pp)
|
|||
else if ((h->flags & P_TYPE) == P_BLEAF)
|
||||
for (i = 0; i < top; i++) {
|
||||
p = (char *)(void *)GETBLEAF(h, i);
|
||||
ksize = GETBLEAF(h, i)->ksize;
|
||||
P_32_SWAP(p);
|
||||
p += sizeof(uint32_t);
|
||||
P_32_SWAP(p);
|
||||
|
@ -170,7 +175,7 @@ __bt_pgout(void *t, pgno_t pg, void *pp)
|
|||
P_32_SWAP(p);
|
||||
}
|
||||
if (flags & P_BIGDATA) {
|
||||
p += sizeof(uint32_t);
|
||||
p += ksize;
|
||||
P_32_SWAP(p);
|
||||
p += sizeof(pgno_t);
|
||||
P_32_SWAP(p);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bt_debug.c,v 1.16 2011/07/17 20:47:39 christos Exp $ */
|
||||
/* $NetBSD: bt_debug.c,v 1.17 2016/09/24 20:11:12 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
|
@ -37,7 +37,7 @@
|
|||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: bt_debug.c,v 1.16 2011/07/17 20:47:39 christos Exp $");
|
||||
__RCSID("$NetBSD: bt_debug.c,v 1.17 2016/09/24 20:11:12 christos Exp $");
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
@ -47,6 +47,29 @@ __RCSID("$NetBSD: bt_debug.c,v 1.16 2011/07/17 20:47:39 christos Exp $");
|
|||
#include <db.h>
|
||||
#include "btree.h"
|
||||
|
||||
#if defined(DEBUG) || defined(STATISTICS)
|
||||
|
||||
static FILE *tracefp;
|
||||
|
||||
/*
|
||||
* __bt_dinit --
|
||||
* initialize debugging.
|
||||
*/
|
||||
static void
|
||||
__bt_dinit(void)
|
||||
{
|
||||
if (tracefp != NULL)
|
||||
return;
|
||||
|
||||
#ifndef TRACE_TO_STDERR
|
||||
if ((tracefp = fopen("/tmp/__bt_debug", "w")) != NULL)
|
||||
return;
|
||||
#endif
|
||||
tracefp = stderr;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* BT_DUMP -- Dump the tree
|
||||
|
@ -62,15 +85,17 @@ __bt_dump(DB *dbp)
|
|||
pgno_t i;
|
||||
const char *sep;
|
||||
|
||||
__bt_dinit();
|
||||
|
||||
t = dbp->internal;
|
||||
(void)fprintf(stderr, "%s: pgsz %d",
|
||||
(void)fprintf(tracefp, "%s: pgsz %d",
|
||||
F_ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize);
|
||||
if (F_ISSET(t, R_RECNO))
|
||||
(void)fprintf(stderr, " keys %lu", (unsigned long) t->bt_nrecs);
|
||||
(void)fprintf(tracefp, " keys %lu", (unsigned long) t->bt_nrecs);
|
||||
#undef X
|
||||
#define X(flag, name) \
|
||||
if (F_ISSET(t, flag)) { \
|
||||
(void)fprintf(stderr, "%s%s", sep, name); \
|
||||
(void)fprintf(tracefp, "%s%s", sep, name); \
|
||||
sep = ", "; \
|
||||
}
|
||||
if (t->flags != 0) {
|
||||
|
@ -81,14 +106,15 @@ __bt_dump(DB *dbp)
|
|||
X(B_RDONLY, "RDONLY");
|
||||
X(R_RECNO, "RECNO");
|
||||
X(B_METADIRTY,"METADIRTY");
|
||||
(void)fprintf(stderr, ")\n");
|
||||
(void)fprintf(tracefp, ")\n");
|
||||
}
|
||||
#undef X
|
||||
|
||||
for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) {
|
||||
for (i = P_ROOT; i < t->bt_mp->npages &&
|
||||
(h = mpool_getf(t->bt_mp, i, MPOOL_IGNOREPIN)) != NULL; ++i)
|
||||
__bt_dpage(h);
|
||||
(void)mpool_put(t->bt_mp, h, 0);
|
||||
}
|
||||
|
||||
(void)fflush(tracefp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -104,24 +130,26 @@ __bt_dmpage(PAGE *h)
|
|||
const char *sep;
|
||||
|
||||
m = (BTMETA *)(void *)h;
|
||||
(void)fprintf(stderr, "magic %lx\n", (unsigned long) m->magic);
|
||||
(void)fprintf(stderr, "version %lu\n", (unsigned long) m->version);
|
||||
(void)fprintf(stderr, "psize %lu\n", (unsigned long) m->psize);
|
||||
(void)fprintf(stderr, "free %lu\n", (unsigned long) m->free);
|
||||
(void)fprintf(stderr, "nrecs %lu\n", (unsigned long) m->nrecs);
|
||||
(void)fprintf(stderr, "flags %lu", (unsigned long) m->flags);
|
||||
(void)fprintf(tracefp, "magic %lx\n", (unsigned long) m->magic);
|
||||
(void)fprintf(tracefp, "version %lu\n", (unsigned long) m->version);
|
||||
(void)fprintf(tracefp, "psize %lu\n", (unsigned long) m->psize);
|
||||
(void)fprintf(tracefp, "free %lu\n", (unsigned long) m->free);
|
||||
(void)fprintf(tracefp, "nrecs %lu\n", (unsigned long) m->nrecs);
|
||||
(void)fprintf(tracefp, "flags %lu", (unsigned long) m->flags);
|
||||
#undef X
|
||||
#define X(flag, name) \
|
||||
if (m->flags & flag) { \
|
||||
(void)fprintf(stderr, "%s%s", sep, name); \
|
||||
(void)fprintf(tracefp, "%s%s", sep, name); \
|
||||
sep = ", "; \
|
||||
}
|
||||
if (m->flags) {
|
||||
sep = " (";
|
||||
X(B_NODUPS, "NODUPS");
|
||||
X(R_RECNO, "RECNO");
|
||||
(void)fprintf(stderr, ")");
|
||||
(void)fprintf(tracefp, ")");
|
||||
}
|
||||
(void)fprintf(tracefp, "\n");
|
||||
(void)fflush(tracefp);
|
||||
}
|
||||
|
||||
static pgno_t
|
||||
|
@ -152,11 +180,14 @@ __bt_dnpage(DB *dbp, pgno_t pgno)
|
|||
BTREE *t;
|
||||
PAGE *h;
|
||||
|
||||
__bt_dinit();
|
||||
|
||||
t = dbp->internal;
|
||||
if ((h = mpool_get(t->bt_mp, pgno, 0)) != NULL) {
|
||||
if ((h = mpool_getf(t->bt_mp, pgno, MPOOL_IGNOREPIN)) != NULL) {
|
||||
__bt_dpage(h);
|
||||
(void)mpool_put(t->bt_mp, h, 0);
|
||||
}
|
||||
(void)fflush(tracefp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -175,11 +206,13 @@ __bt_dpage(PAGE *h)
|
|||
indx_t cur, top;
|
||||
const char *sep;
|
||||
|
||||
(void)fprintf(stderr, " page %d: (", h->pgno);
|
||||
__bt_dinit();
|
||||
|
||||
(void)fprintf(tracefp, " page %d: (", h->pgno);
|
||||
#undef X
|
||||
#define X(flag, name) \
|
||||
if (h->flags & flag) { \
|
||||
(void)fprintf(stderr, "%s%s", sep, name); \
|
||||
(void)fprintf(tracefp, "%s%s", sep, name); \
|
||||
sep = ", "; \
|
||||
}
|
||||
sep = "";
|
||||
|
@ -189,68 +222,69 @@ __bt_dpage(PAGE *h)
|
|||
X(P_RLEAF, "RLEAF")
|
||||
X(P_OVERFLOW, "OVERFLOW")
|
||||
X(P_PRESERVE, "PRESERVE");
|
||||
(void)fprintf(stderr, ")\n");
|
||||
(void)fprintf(tracefp, ")\n");
|
||||
#undef X
|
||||
|
||||
(void)fprintf(stderr, "\tprev %2d next %2d", h->prevpg, h->nextpg);
|
||||
(void)fprintf(tracefp, "\tprev %2d next %2d", h->prevpg, h->nextpg);
|
||||
if (h->flags & P_OVERFLOW)
|
||||
return;
|
||||
|
||||
top = NEXTINDEX(h);
|
||||
(void)fprintf(stderr, " lower %3d upper %3d nextind %d\n",
|
||||
(void)fprintf(tracefp, " lower %3d upper %3d nextind %d\n",
|
||||
h->lower, h->upper, top);
|
||||
for (cur = 0; cur < top; cur++) {
|
||||
(void)fprintf(stderr, "\t[%03d] %4d ", cur, h->linp[cur]);
|
||||
(void)fprintf(tracefp, "\t[%03d] %4d ", cur, h->linp[cur]);
|
||||
switch (h->flags & P_TYPE) {
|
||||
case P_BINTERNAL:
|
||||
bi = GETBINTERNAL(h, cur);
|
||||
(void)fprintf(stderr,
|
||||
(void)fprintf(tracefp,
|
||||
"size %03d pgno %03d", bi->ksize, bi->pgno);
|
||||
if (bi->flags & P_BIGKEY)
|
||||
(void)fprintf(stderr, " (indirect)");
|
||||
(void)fprintf(tracefp, " (indirect)");
|
||||
else if (bi->ksize)
|
||||
(void)fprintf(stderr,
|
||||
(void)fprintf(tracefp,
|
||||
" {%.*s}", (int)bi->ksize, bi->bytes);
|
||||
break;
|
||||
case P_RINTERNAL:
|
||||
ri = GETRINTERNAL(h, cur);
|
||||
(void)fprintf(stderr, "entries %03d pgno %03d",
|
||||
(void)fprintf(tracefp, "entries %03d pgno %03d",
|
||||
ri->nrecs, ri->pgno);
|
||||
break;
|
||||
case P_BLEAF:
|
||||
bl = GETBLEAF(h, cur);
|
||||
if (bl->flags & P_BIGKEY)
|
||||
(void)fprintf(stderr,
|
||||
(void)fprintf(tracefp,
|
||||
"big key page %lu size %u/",
|
||||
(unsigned long) __bt_pgno_t(bl->bytes),
|
||||
__bt_uint32_t(bl->bytes + sizeof(pgno_t)));
|
||||
else if (bl->ksize)
|
||||
(void)fprintf(stderr, "%s/", bl->bytes);
|
||||
(void)fprintf(tracefp, "%s/", bl->bytes);
|
||||
if (bl->flags & P_BIGDATA)
|
||||
(void)fprintf(stderr,
|
||||
(void)fprintf(tracefp,
|
||||
"big data page %lu size %u",
|
||||
(unsigned long)
|
||||
__bt_pgno_t(bl->bytes + bl->ksize),
|
||||
__bt_uint32_t(bl->bytes + bl->ksize +
|
||||
sizeof(pgno_t)));
|
||||
else if (bl->dsize)
|
||||
(void)fprintf(stderr, "%.*s",
|
||||
(void)fprintf(tracefp, "%.*s",
|
||||
(int)bl->dsize, bl->bytes + bl->ksize);
|
||||
break;
|
||||
case P_RLEAF:
|
||||
rl = GETRLEAF(h, cur);
|
||||
if (rl->flags & P_BIGDATA)
|
||||
(void)fprintf(stderr,
|
||||
(void)fprintf(tracefp,
|
||||
"big data page %lu size %u",
|
||||
(unsigned long) __bt_pgno_t(rl->bytes),
|
||||
__bt_uint32_t(rl->bytes + sizeof(pgno_t)));
|
||||
else if (rl->dsize)
|
||||
(void)fprintf(stderr,
|
||||
(void)fprintf(tracefp,
|
||||
"%.*s", (int)rl->dsize, rl->bytes);
|
||||
break;
|
||||
}
|
||||
(void)fprintf(stderr, "\n");
|
||||
(void)fprintf(tracefp, "\n");
|
||||
}
|
||||
(void)fflush(tracefp);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -272,10 +306,13 @@ __bt_stat(DB *dbp)
|
|||
unsigned long ifree, lfree, nkeys;
|
||||
int levels;
|
||||
|
||||
__bt_dinit();
|
||||
|
||||
t = dbp->internal;
|
||||
pcont = pinternal = pleaf = 0;
|
||||
nkeys = ifree = lfree = 0;
|
||||
for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) {
|
||||
for (i = P_ROOT; i < t->bt_mp->npages &&
|
||||
(h = mpool_getf(t->bt_mp, i, MPOOL_IGNOREPIN)) != NULL; ++i)
|
||||
switch (h->flags & P_TYPE) {
|
||||
case P_BINTERNAL:
|
||||
case P_RINTERNAL:
|
||||
|
@ -297,7 +334,7 @@ __bt_stat(DB *dbp)
|
|||
|
||||
/* Count the levels of the tree. */
|
||||
for (i = P_ROOT, levels = 0 ;; ++levels) {
|
||||
h = mpool_get(t->bt_mp, i, 0);
|
||||
h = mpool_getf(t->bt_mp, i, MPOOL_IGNOREPIN);
|
||||
if (h->flags & (P_BLEAF|P_RLEAF)) {
|
||||
if (levels == 0)
|
||||
levels = 1;
|
||||
|
@ -310,32 +347,33 @@ __bt_stat(DB *dbp)
|
|||
(void)mpool_put(t->bt_mp, h, 0);
|
||||
}
|
||||
|
||||
(void)fprintf(stderr, "%d level%s with %ld keys",
|
||||
(void)fprintf(tracefp, "%d level%s with %ld keys",
|
||||
levels, levels == 1 ? "" : "s", nkeys);
|
||||
if (F_ISSET(t, R_RECNO))
|
||||
(void)fprintf(stderr, " (%ld header count)", (long)t->bt_nrecs);
|
||||
(void)fprintf(stderr,
|
||||
(void)fprintf(tracefp, " (%ld header count)", (long)t->bt_nrecs);
|
||||
(void)fprintf(tracefp,
|
||||
"\n%lu pages (leaf %ld, internal %ld, overflow %ld)\n",
|
||||
(long)pinternal + pleaf + pcont, (long)pleaf, (long)pinternal,
|
||||
(long)pcont);
|
||||
(void)fprintf(stderr, "%ld cache hits, %ld cache misses\n",
|
||||
(void)fprintf(tracefp, "%ld cache hits, %ld cache misses\n",
|
||||
bt_cache_hit, bt_cache_miss);
|
||||
(void)fprintf(stderr, "%ld splits (%ld root splits, %ld sort splits)\n",
|
||||
(void)fprintf(tracefp, "%ld splits (%ld root splits, %ld sort splits)\n",
|
||||
bt_split, bt_rootsplit, bt_sortsplit);
|
||||
pleaf *= t->bt_psize - BTDATAOFF;
|
||||
if (pleaf)
|
||||
(void)fprintf(stderr,
|
||||
(void)fprintf(tracefp,
|
||||
"%.0f%% leaf fill (%ld bytes used, %ld bytes free)\n",
|
||||
((double)(pleaf - lfree) / pleaf) * 100,
|
||||
pleaf - lfree, lfree);
|
||||
pinternal *= t->bt_psize - BTDATAOFF;
|
||||
if (pinternal)
|
||||
(void)fprintf(stderr,
|
||||
(void)fprintf(tracefp,
|
||||
"%.0f%% internal fill (%ld bytes used, %ld bytes free\n",
|
||||
((double)(pinternal - ifree) / pinternal) * 100,
|
||||
pinternal - ifree, ifree);
|
||||
if (bt_pfxsaved)
|
||||
(void)fprintf(stderr, "prefix checking removed %lu bytes.\n",
|
||||
(void)fprintf(tracefp, "prefix checking removed %lu bytes.\n",
|
||||
bt_pfxsaved);
|
||||
(void)fflush(tracefp);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bt_delete.c,v 1.17 2009/01/29 02:02:36 lukem Exp $ */
|
||||
/* $NetBSD: bt_delete.c,v 1.18 2016/09/24 20:11:12 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
|
@ -37,7 +37,7 @@
|
|||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: bt_delete.c,v 1.17 2009/01/29 02:02:36 lukem Exp $");
|
||||
__RCSID("$NetBSD: bt_delete.c,v 1.18 2016/09/24 20:11:12 christos Exp $");
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
|
@ -53,7 +53,6 @@ __RCSID("$NetBSD: bt_delete.c,v 1.17 2009/01/29 02:02:36 lukem Exp $");
|
|||
static int __bt_bdelete(BTREE *, const DBT *);
|
||||
static int __bt_curdel(BTREE *, const DBT *, PAGE *, u_int);
|
||||
static int __bt_pdelete(BTREE *, PAGE *);
|
||||
static int __bt_relink(BTREE *, PAGE *);
|
||||
static int __bt_stkacq(BTREE *, PAGE **, CURSOR *);
|
||||
|
||||
/*
|
||||
|
@ -97,7 +96,7 @@ __bt_delete(const DB *dbp, const DBT *key, u_int flags)
|
|||
if (F_ISSET(c, CURS_INIT)) {
|
||||
if (F_ISSET(c, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE))
|
||||
return (RET_SPECIAL);
|
||||
if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, c->pg.pgno, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
|
||||
/*
|
||||
|
@ -181,7 +180,7 @@ __bt_stkacq(BTREE *t, PAGE **hp, CURSOR *c)
|
|||
/* Move up the stack. */
|
||||
for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {
|
||||
/* Get the parent page. */
|
||||
if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, parent->pgno, 0)) == NULL)
|
||||
return (1);
|
||||
|
||||
/* Move to the next index. */
|
||||
|
@ -204,12 +203,12 @@ __bt_stkacq(BTREE *t, PAGE **hp, CURSOR *c)
|
|||
mpool_put(t->bt_mp, h, 0);
|
||||
|
||||
/* Get the next level down. */
|
||||
if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, pgno, 0)) == NULL)
|
||||
return (1);
|
||||
idx = 0;
|
||||
}
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
if ((h = mpool_get(t->bt_mp, nextpg, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, nextpg, 0)) == NULL)
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
@ -236,7 +235,7 @@ __bt_stkacq(BTREE *t, PAGE **hp, CURSOR *c)
|
|||
/* Move up the stack. */
|
||||
for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {
|
||||
/* Get the parent page. */
|
||||
if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, parent->pgno, 0)) == NULL)
|
||||
return (1);
|
||||
|
||||
/* Move to the next index. */
|
||||
|
@ -258,20 +257,20 @@ __bt_stkacq(BTREE *t, PAGE **hp, CURSOR *c)
|
|||
mpool_put(t->bt_mp, h, 0);
|
||||
|
||||
/* Get the next level down. */
|
||||
if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, pgno, 0)) == NULL)
|
||||
return (1);
|
||||
|
||||
idx = NEXTINDEX(h) - 1;
|
||||
BT_PUSH(t, pgno, idx);
|
||||
}
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
if ((h = mpool_get(t->bt_mp, prevpg, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, prevpg, 0)) == NULL)
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
ret: mpool_put(t->bt_mp, h, 0);
|
||||
return ((*hp = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL);
|
||||
return ((*hp = mpool_getf(t->bt_mp, c->pg.pgno, 0)) == NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -394,7 +393,7 @@ __bt_pdelete(BTREE *t, PAGE *h)
|
|||
*/
|
||||
while ((parent = BT_POP(t)) != NULL) {
|
||||
/* Get the parent page. */
|
||||
if ((pg = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
|
||||
if ((pg = mpool_getf(t->bt_mp, parent->pgno, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
|
||||
idx = parent->index;
|
||||
|
@ -577,7 +576,7 @@ __bt_curdel(BTREE *t, const DBT *key, PAGE *h, u_int idx)
|
|||
}
|
||||
/* Check previous key if at the beginning of the page. */
|
||||
if (idx == 0 && h->prevpg != P_INVALID) {
|
||||
if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
|
||||
if ((pg = mpool_getf(t->bt_mp, h->prevpg, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
e.page = pg;
|
||||
e.index = NEXTINDEX(pg) - 1;
|
||||
|
@ -589,7 +588,7 @@ __bt_curdel(BTREE *t, const DBT *key, PAGE *h, u_int idx)
|
|||
}
|
||||
/* Check next key if at the end of the page. */
|
||||
if (idx == (unsigned)(NEXTINDEX(h) - 1) && h->nextpg != P_INVALID) {
|
||||
if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
|
||||
if ((pg = mpool_getf(t->bt_mp, h->nextpg, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
e.page = pg;
|
||||
e.index = 0;
|
||||
|
@ -621,19 +620,19 @@ dup2: c->pg.pgno = e.page->pgno;
|
|||
* t: tree
|
||||
* h: page to be deleted
|
||||
*/
|
||||
static int
|
||||
int
|
||||
__bt_relink(BTREE *t, PAGE *h)
|
||||
{
|
||||
PAGE *pg;
|
||||
|
||||
if (h->nextpg != P_INVALID) {
|
||||
if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
|
||||
if ((pg = mpool_getf(t->bt_mp, h->nextpg, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
pg->prevpg = h->prevpg;
|
||||
mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
|
||||
}
|
||||
if (h->prevpg != P_INVALID) {
|
||||
if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
|
||||
if ((pg = mpool_getf(t->bt_mp, h->prevpg, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
pg->nextpg = h->nextpg;
|
||||
mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bt_open.c,v 1.27 2013/12/01 00:22:48 christos Exp $ */
|
||||
/* $NetBSD: bt_open.c,v 1.28 2016/09/24 20:11:12 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
|
@ -37,7 +37,7 @@
|
|||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: bt_open.c,v 1.27 2013/12/01 00:22:48 christos Exp $");
|
||||
__RCSID("$NetBSD: bt_open.c,v 1.28 2016/09/24 20:11:12 christos Exp $");
|
||||
|
||||
/*
|
||||
* Implementation of btree access method for 4.4BSD.
|
||||
|
@ -354,18 +354,25 @@ nroot(BTREE *t)
|
|||
PAGE *meta, *root;
|
||||
pgno_t npg;
|
||||
|
||||
if ((meta = mpool_get(t->bt_mp, 0, 0)) != NULL) {
|
||||
mpool_put(t->bt_mp, meta, 0);
|
||||
return (RET_SUCCESS);
|
||||
if ((root = mpool_getf(t->bt_mp, 1, 0)) != NULL) {
|
||||
if (root->lower == 0 &&
|
||||
root->pgno == 0 &&
|
||||
root->linp[0] == 0) {
|
||||
mpool_delete(t->bt_mp, root);
|
||||
errno = EINVAL;
|
||||
} else {
|
||||
mpool_put(t->bt_mp, root, 0);
|
||||
return RET_SUCCESS;
|
||||
}
|
||||
}
|
||||
if (errno != EINVAL) /* It's OK to not exist. */
|
||||
return (RET_ERROR);
|
||||
errno = 0;
|
||||
|
||||
if ((meta = mpool_new(t->bt_mp, &npg)) == NULL)
|
||||
if ((meta = mpool_newf(t->bt_mp, &npg, MPOOL_PAGE_NEXT)) == NULL)
|
||||
return (RET_ERROR);
|
||||
|
||||
if ((root = mpool_new(t->bt_mp, &npg)) == NULL)
|
||||
if ((root = mpool_newf(t->bt_mp, &npg, MPOOL_PAGE_NEXT)) == NULL)
|
||||
return (RET_ERROR);
|
||||
|
||||
if (npg != P_ROOT)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bt_overflow.c,v 1.20 2013/12/14 18:04:56 christos Exp $ */
|
||||
/* $NetBSD: bt_overflow.c,v 1.21 2016/09/24 20:11:12 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
|
@ -37,7 +37,7 @@
|
|||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: bt_overflow.c,v 1.20 2013/12/14 18:04:56 christos Exp $");
|
||||
__RCSID("$NetBSD: bt_overflow.c,v 1.21 2016/09/24 20:11:12 christos Exp $");
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/param.h>
|
||||
|
@ -112,7 +112,7 @@ __ovfl_get(BTREE *t, void *p, size_t *ssz, void **buf, size_t *bufsz)
|
|||
_DBFIT(temp, uint32_t);
|
||||
plen = (uint32_t)temp;
|
||||
for (p = *buf;; p = (char *)p + nb, pg = h->nextpg) {
|
||||
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, pg, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
|
||||
nb = MIN(sz, plen);
|
||||
|
@ -208,7 +208,7 @@ __ovfl_delete(BTREE *t, void *p)
|
|||
if (pg == P_INVALID || sz == 0)
|
||||
abort();
|
||||
#endif
|
||||
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, pg, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
|
||||
/* Don't delete chains used by internal pages. */
|
||||
|
@ -226,7 +226,7 @@ __ovfl_delete(BTREE *t, void *p)
|
|||
__bt_free(t, h);
|
||||
if (sz <= plen)
|
||||
break;
|
||||
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, pg, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
}
|
||||
return (RET_SUCCESS);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bt_page.c,v 1.13 2008/09/11 12:58:00 joerg Exp $ */
|
||||
/* $NetBSD: bt_page.c,v 1.14 2016/09/24 20:11:12 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
|
@ -34,7 +34,7 @@
|
|||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: bt_page.c,v 1.13 2008/09/11 12:58:00 joerg Exp $");
|
||||
__RCSID("$NetBSD: bt_page.c,v 1.14 2016/09/24 20:11:12 christos Exp $");
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
|
@ -89,7 +89,7 @@ __bt_new(BTREE *t, pgno_t *npg)
|
|||
PAGE *h;
|
||||
|
||||
if (t->bt_free != P_INVALID &&
|
||||
(h = mpool_get(t->bt_mp, t->bt_free, 0)) != NULL) {
|
||||
(h = mpool_getf(t->bt_mp, t->bt_free, 0)) != NULL) {
|
||||
*npg = t->bt_free;
|
||||
t->bt_free = h->nextpg;
|
||||
F_SET(t, B_METADIRTY);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bt_put.c,v 1.20 2011/06/26 22:20:31 christos Exp $ */
|
||||
/* $NetBSD: bt_put.c,v 1.21 2016/09/24 20:11:12 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
|
@ -37,7 +37,7 @@
|
|||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: bt_put.c,v 1.20 2011/06/26 22:20:31 christos Exp $");
|
||||
__RCSID("$NetBSD: bt_put.c,v 1.21 2016/09/24 20:11:12 christos Exp $");
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
|
@ -152,7 +152,7 @@ storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR)
|
|||
|
||||
/* Replace the cursor. */
|
||||
if (flags == R_CURSOR) {
|
||||
if ((h = mpool_get(t->bt_mp, t->bt_cursor.pg.pgno, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, t->bt_cursor.pg.pgno, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
idx = t->bt_cursor.pg.index;
|
||||
goto delete;
|
||||
|
@ -271,7 +271,7 @@ bt_fast(BTREE *t, const DBT *key, const DBT *data, int *exactp)
|
|||
uint32_t nbytes;
|
||||
int cmp;
|
||||
|
||||
if ((h = mpool_get(t->bt_mp, t->bt_last.pgno, 0)) == NULL) {
|
||||
if ((h = mpool_getf(t->bt_mp, t->bt_last.pgno, 0)) == NULL) {
|
||||
t->bt_order = NOT;
|
||||
return (NULL);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bt_search.c,v 1.17 2008/09/11 12:58:00 joerg Exp $ */
|
||||
/* $NetBSD: bt_search.c,v 1.18 2016/09/24 20:11:12 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
|
@ -37,7 +37,7 @@
|
|||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: bt_search.c,v 1.17 2008/09/11 12:58:00 joerg Exp $");
|
||||
__RCSID("$NetBSD: bt_search.c,v 1.18 2016/09/24 20:11:12 christos Exp $");
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
|
@ -75,7 +75,7 @@ __bt_search(BTREE *t, const DBT *key, int *exactp)
|
|||
|
||||
BT_CLR(t);
|
||||
for (pg = P_ROOT;;) {
|
||||
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, pg, 0)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
/* Do a binary search on the current page. */
|
||||
|
@ -150,23 +150,65 @@ next: BT_PUSH(t, h->pgno, idx);
|
|||
static int
|
||||
__bt_snext(BTREE *t, PAGE *h, const DBT *key, int *exactp)
|
||||
{
|
||||
BINTERNAL *bi;
|
||||
EPG e;
|
||||
EPGNO *parent;
|
||||
indx_t idx = 0;
|
||||
pgno_t pgno;
|
||||
int level;
|
||||
|
||||
/*
|
||||
* Get the next page. The key is either an exact
|
||||
* match, or not as good as the one we already have.
|
||||
*/
|
||||
if ((e.page = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
|
||||
return (0);
|
||||
if ((e.page = mpool_getf(t->bt_mp, h->nextpg, 0)) == NULL)
|
||||
return 0;
|
||||
e.index = 0;
|
||||
if (__bt_cmp(t, key, &e) == 0) {
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
t->bt_cur = e;
|
||||
*exactp = 1;
|
||||
return (1);
|
||||
if (__bt_cmp(t, key, &e) != 0) {
|
||||
mpool_put(t->bt_mp, e.page, 0);
|
||||
return 0;
|
||||
}
|
||||
mpool_put(t->bt_mp, e.page, 0);
|
||||
return (0);
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
t->bt_cur = e;
|
||||
*exactp = 1;
|
||||
|
||||
/*
|
||||
* Adjust the stack for the movement.
|
||||
*
|
||||
* Move up the stack.
|
||||
*/
|
||||
for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {
|
||||
/* Get the parent page. */
|
||||
if ((h = mpool_getf(t->bt_mp, parent->pgno, 0)) == NULL)
|
||||
return 0;
|
||||
|
||||
/* Move to the next index. */
|
||||
if (parent->index != NEXTINDEX(h) - 1) {
|
||||
idx = parent->index + 1;
|
||||
BT_PUSH(t, h->pgno, idx);
|
||||
break;
|
||||
}
|
||||
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
}
|
||||
|
||||
/* Restore the stack. */
|
||||
while (level--) {
|
||||
/* Push the next level down onto the stack. */
|
||||
bi = GETBINTERNAL(h, idx);
|
||||
pgno = bi->pgno;
|
||||
BT_PUSH(t, pgno, 0);
|
||||
|
||||
/* Lose the currently pinned page. */
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
|
||||
/* Get the next level down. */
|
||||
if ((h = mpool_getf(t->bt_mp, pgno, 0)) == NULL)
|
||||
return 0;
|
||||
idx = 0;
|
||||
}
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -185,21 +227,64 @@ __bt_snext(BTREE *t, PAGE *h, const DBT *key, int *exactp)
|
|||
static int
|
||||
__bt_sprev(BTREE *t, PAGE *h, const DBT *key, int *exactp)
|
||||
{
|
||||
BINTERNAL *bi;
|
||||
EPG e;
|
||||
EPGNO *parent;
|
||||
indx_t idx = 0;
|
||||
pgno_t pgno;
|
||||
int level;
|
||||
|
||||
/*
|
||||
* Get the previous page. The key is either an exact
|
||||
* match, or not as good as the one we already have.
|
||||
*/
|
||||
if ((e.page = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
|
||||
return (0);
|
||||
if ((e.page = mpool_getf(t->bt_mp, h->prevpg, 0)) == NULL)
|
||||
return 0;
|
||||
e.index = NEXTINDEX(e.page) - 1;
|
||||
if (__bt_cmp(t, key, &e) == 0) {
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
t->bt_cur = e;
|
||||
*exactp = 1;
|
||||
return (1);
|
||||
if (__bt_cmp(t, key, &e) != 0) {
|
||||
mpool_put(t->bt_mp, e.page, 0);
|
||||
return 0;
|
||||
}
|
||||
mpool_put(t->bt_mp, e.page, 0);
|
||||
return (0);
|
||||
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
t->bt_cur = e;
|
||||
*exactp = 1;
|
||||
|
||||
/*
|
||||
* Adjust the stack for the movement.
|
||||
*
|
||||
* Move up the stack.
|
||||
*/
|
||||
for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {
|
||||
/* Get the parent page. */
|
||||
if ((h = mpool_getf(t->bt_mp, parent->pgno, 0)) == NULL)
|
||||
return 1;
|
||||
|
||||
/* Move to the next index. */
|
||||
if (parent->index != 0) {
|
||||
idx = parent->index - 1;
|
||||
BT_PUSH(t, h->pgno, idx);
|
||||
break;
|
||||
}
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
}
|
||||
|
||||
/* Restore the stack. */
|
||||
while (level--) {
|
||||
/* Push the next level down onto the stack. */
|
||||
bi = GETBINTERNAL(h, idx);
|
||||
pgno = bi->pgno;
|
||||
|
||||
/* Lose the currently pinned page. */
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
|
||||
/* Get the next level down. */
|
||||
if ((h = mpool_getf(t->bt_mp, pgno, 0)) == NULL)
|
||||
return 1;
|
||||
|
||||
idx = NEXTINDEX(h) - 1;
|
||||
BT_PUSH(t, pgno, idx);
|
||||
}
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bt_seq.c,v 1.18 2013/09/04 13:03:22 ryoon Exp $ */
|
||||
/* $NetBSD: bt_seq.c,v 1.19 2016/09/24 20:11:12 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
|
@ -37,7 +37,7 @@
|
|||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: bt_seq.c,v 1.18 2013/09/04 13:03:22 ryoon Exp $");
|
||||
__RCSID("$NetBSD: bt_seq.c,v 1.19 2016/09/24 20:11:12 christos Exp $");
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
|
@ -54,6 +54,8 @@ __RCSID("$NetBSD: bt_seq.c,v 1.18 2013/09/04 13:03:22 ryoon Exp $");
|
|||
static int __bt_first(BTREE *, const DBT *, EPG *, int *);
|
||||
static int __bt_seqadv(BTREE *, EPG *, int);
|
||||
static int __bt_seqset(BTREE *, EPG *, DBT *, int);
|
||||
static int __bt_rseq_next(BTREE *, EPG *);
|
||||
static int __bt_rseq_prev(BTREE *, EPG *);
|
||||
|
||||
/*
|
||||
* Sequential scan support.
|
||||
|
@ -71,7 +73,7 @@ static int __bt_seqset(BTREE *, EPG *, DBT *, int);
|
|||
* dbp: pointer to access method
|
||||
* key: key for positioning and return value
|
||||
* data: data return value
|
||||
* flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
|
||||
* flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV, R_RNEXT, R_RPREV.
|
||||
*
|
||||
* Returns:
|
||||
* RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
|
||||
|
@ -99,6 +101,8 @@ __bt_seq(const DB *dbp, DBT *key, DBT *data, u_int flags)
|
|||
switch (flags) {
|
||||
case R_NEXT:
|
||||
case R_PREV:
|
||||
case R_RNEXT:
|
||||
case R_RPREV:
|
||||
if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
|
||||
status = __bt_seqadv(t, &e, (int)flags);
|
||||
break;
|
||||
|
@ -140,7 +144,7 @@ __bt_seq(const DB *dbp, DBT *key, DBT *data, u_int flags)
|
|||
* t: tree
|
||||
* ep: storage for returned key
|
||||
* key: key for initial scan position
|
||||
* flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV
|
||||
* flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV, R_RNEXT, R_RPREV.
|
||||
*
|
||||
* Side effects:
|
||||
* Pins the page the cursor references.
|
||||
|
@ -173,9 +177,11 @@ __bt_seqset(BTREE *t, EPG *ep, DBT *key, int flags)
|
|||
return (__bt_first(t, key, ep, &exact));
|
||||
case R_FIRST: /* First record. */
|
||||
case R_NEXT:
|
||||
case R_RNEXT:
|
||||
BT_CLR(t);
|
||||
/* Walk down the left-hand side of the tree. */
|
||||
for (pg = P_ROOT;;) {
|
||||
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, pg, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
|
||||
/* Check for an empty tree. */
|
||||
|
@ -187,6 +193,7 @@ __bt_seqset(BTREE *t, EPG *ep, DBT *key, int flags)
|
|||
if (h->flags & (P_BLEAF | P_RLEAF))
|
||||
break;
|
||||
pg = GETBINTERNAL(h, 0)->pgno;
|
||||
BT_PUSH(t, h->pgno, 0);
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
}
|
||||
ep->page = h;
|
||||
|
@ -194,9 +201,11 @@ __bt_seqset(BTREE *t, EPG *ep, DBT *key, int flags)
|
|||
break;
|
||||
case R_LAST: /* Last record. */
|
||||
case R_PREV:
|
||||
case R_RPREV:
|
||||
BT_CLR(t);
|
||||
/* Walk down the right-hand side of the tree. */
|
||||
for (pg = P_ROOT;;) {
|
||||
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, pg, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
|
||||
/* Check for an empty tree. */
|
||||
|
@ -208,6 +217,7 @@ __bt_seqset(BTREE *t, EPG *ep, DBT *key, int flags)
|
|||
if (h->flags & (P_BLEAF | P_RLEAF))
|
||||
break;
|
||||
pg = GETBINTERNAL(h, NEXTINDEX(h) - 1)->pgno;
|
||||
BT_PUSH(t, h->pgno, NEXTINDEX(h) - 1);
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
}
|
||||
|
||||
|
@ -224,7 +234,7 @@ __bt_seqset(BTREE *t, EPG *ep, DBT *key, int flags)
|
|||
*
|
||||
* Parameters:
|
||||
* t: tree
|
||||
* flags: R_NEXT, R_PREV
|
||||
* flags: R_NEXT, R_PREV, R_RNEXT, R_RPREV
|
||||
*
|
||||
* Side effects:
|
||||
* Pins the page the new key/data record is on.
|
||||
|
@ -239,7 +249,7 @@ __bt_seqadv(BTREE *t, EPG *ep, int flags)
|
|||
PAGE *h;
|
||||
indx_t idx = 0; /* pacify gcc */
|
||||
pgno_t pg;
|
||||
int exact;
|
||||
int exact, rval;
|
||||
|
||||
/*
|
||||
* There are a couple of states that we can be in. The cursor has
|
||||
|
@ -248,18 +258,48 @@ __bt_seqadv(BTREE *t, EPG *ep, int flags)
|
|||
c = &t->bt_cursor;
|
||||
|
||||
/*
|
||||
* The cursor was deleted where there weren't any duplicate records,
|
||||
* so the key was saved. Find out where that key would go in the
|
||||
* current tree. It doesn't matter if the returned key is an exact
|
||||
* match or not -- if it's an exact match, the record was added after
|
||||
* the delete so we can just return it. If not, as long as there's
|
||||
* a record there, return it.
|
||||
* The cursor was deleted and there weren't any duplicate records,
|
||||
* so the cursor's key was saved. Find out where that key would
|
||||
* be in the current tree. If the returned key is an exact match,
|
||||
* it means that a key/data pair was inserted into the tree after
|
||||
* the delete. We could reasonably return the key, but the problem
|
||||
* is that this is the access pattern we'll see if the user is
|
||||
* doing seq(..., R_NEXT)/put(..., 0) pairs, i.e. the put deletes
|
||||
* the cursor record and then replaces it, so the cursor was saved,
|
||||
* and we'll simply return the same "new" record until the user
|
||||
* notices and doesn't do a put() of it. Since the key is an exact
|
||||
* match, we could as easily put the new record before the cursor,
|
||||
* and we've made no guarantee to return it. So, move forward or
|
||||
* back a record if it's an exact match.
|
||||
*
|
||||
* XXX
|
||||
* In the current implementation, put's to the cursor are done with
|
||||
* delete/add pairs. This has two consequences. First, it means
|
||||
* that seq(..., R_NEXT)/put(..., R_CURSOR) pairs are going to exhibit
|
||||
* the same behavior as above. Second, you can return the same key
|
||||
* twice if you have duplicate records. The scenario is that the
|
||||
* cursor record is deleted, moving the cursor forward or backward
|
||||
* to a duplicate. The add then inserts the new record at a location
|
||||
* ahead of the cursor because duplicates aren't sorted in any way,
|
||||
* and the new record is later returned. This has to be fixed at some
|
||||
* point.
|
||||
*/
|
||||
if (F_ISSET(c, CURS_ACQUIRE))
|
||||
return (__bt_first(t, &c->key, ep, &exact));
|
||||
if (F_ISSET(c, CURS_ACQUIRE)) {
|
||||
if ((rval = __bt_first(t, &c->key, ep, &exact)) == RET_ERROR)
|
||||
return RET_ERROR;
|
||||
if (!exact)
|
||||
return rval;
|
||||
/*
|
||||
* XXX
|
||||
* Kluge -- get, release, get the page.
|
||||
*/
|
||||
c->pg.pgno = ep->page->pgno;
|
||||
c->pg.index = ep->index;
|
||||
mpool_put(t->bt_mp, ep->page, 0);
|
||||
}
|
||||
|
||||
/* Get the page referenced by the cursor. */
|
||||
if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, c->pg.pgno, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
|
||||
/*
|
||||
|
@ -268,6 +308,7 @@ __bt_seqadv(BTREE *t, EPG *ep, int flags)
|
|||
*/
|
||||
switch (flags) {
|
||||
case R_NEXT: /* Next record. */
|
||||
case R_RNEXT:
|
||||
/*
|
||||
* The cursor was deleted in duplicate records, and moved
|
||||
* forward to a record that has yet to be returned. Clear
|
||||
|
@ -277,16 +318,22 @@ __bt_seqadv(BTREE *t, EPG *ep, int flags)
|
|||
goto usecurrent;
|
||||
idx = c->pg.index;
|
||||
if (++idx == NEXTINDEX(h)) {
|
||||
if (flags == R_RNEXT) {
|
||||
ep->page = h;
|
||||
ep->index = idx;
|
||||
return __bt_rseq_next(t, ep);
|
||||
}
|
||||
pg = h->nextpg;
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
if (pg == P_INVALID)
|
||||
return (RET_SPECIAL);
|
||||
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
return RET_SPECIAL;
|
||||
if ((h = mpool_getf(t->bt_mp, pg, 0)) == NULL)
|
||||
return RET_ERROR;
|
||||
idx = 0;
|
||||
}
|
||||
break;
|
||||
case R_PREV: /* Previous record. */
|
||||
case R_RPREV:
|
||||
/*
|
||||
* The cursor was deleted in duplicate records, and moved
|
||||
* backward to a record that has yet to be returned. Clear
|
||||
|
@ -300,12 +347,17 @@ usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE);
|
|||
}
|
||||
idx = c->pg.index;
|
||||
if (idx == 0) {
|
||||
if (flags == R_RPREV) {
|
||||
ep->page = h;
|
||||
ep->index = idx;
|
||||
return __bt_rseq_prev(t, ep);
|
||||
}
|
||||
pg = h->prevpg;
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
if (pg == P_INVALID)
|
||||
return (RET_SPECIAL);
|
||||
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
return RET_SPECIAL;
|
||||
if ((h = mpool_getf(t->bt_mp, pg, 0)) == NULL)
|
||||
return RET_ERROR;
|
||||
idx = NEXTINDEX(h) - 1;
|
||||
} else
|
||||
--idx;
|
||||
|
@ -316,6 +368,83 @@ usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE);
|
|||
ep->index = idx;
|
||||
return (RET_SUCCESS);
|
||||
}
|
||||
/*
|
||||
* Get the first item on the next page, but by going up and down the tree.
|
||||
*/
|
||||
static int
|
||||
__bt_rseq_next(BTREE *t, EPG *ep)
|
||||
{
|
||||
PAGE *h;
|
||||
indx_t idx;
|
||||
EPGNO *up;
|
||||
pgno_t pg;
|
||||
|
||||
h = ep->page;
|
||||
idx = ep->index;
|
||||
do {
|
||||
/* Move up the tree. */
|
||||
up = BT_POP(t);
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
/* Did we hit the right edge of the root? */
|
||||
if (up == NULL)
|
||||
return RET_SPECIAL;
|
||||
if ((h = mpool_getf(t->bt_mp, up->pgno, 0)) == NULL)
|
||||
return RET_ERROR;
|
||||
idx = up->index;
|
||||
} while (++idx == NEXTINDEX(h));
|
||||
|
||||
while (!(h->flags & (P_BLEAF | P_RLEAF))) {
|
||||
/* Move back down the tree. */
|
||||
BT_PUSH(t, h->pgno, idx);
|
||||
pg = GETBINTERNAL(h, idx)->pgno;
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
if ((h = mpool_getf(t->bt_mp, pg, 0)) == NULL)
|
||||
return RET_ERROR;
|
||||
idx = 0;
|
||||
}
|
||||
ep->page = h;
|
||||
ep->index = idx;
|
||||
return RET_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the last item on the previous page, but by going up and down the tree.
|
||||
*/
|
||||
static int
|
||||
__bt_rseq_prev(BTREE *t, EPG *ep)
|
||||
{
|
||||
PAGE *h;
|
||||
indx_t idx;
|
||||
EPGNO *up;
|
||||
pgno_t pg;
|
||||
|
||||
h = ep->page;
|
||||
idx = ep->index;
|
||||
do {
|
||||
/* Move up the tree. */
|
||||
up = BT_POP(t);
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
/* Did we hit the left edge of the root? */
|
||||
if (up == NULL)
|
||||
return RET_SPECIAL;
|
||||
if ((h = mpool_getf(t->bt_mp, up->pgno, 0)) == NULL)
|
||||
return RET_ERROR;
|
||||
idx = up->index;
|
||||
} while (idx == 0);
|
||||
--idx;
|
||||
while (!(h->flags & (P_BLEAF | P_RLEAF))) {
|
||||
/* Move back down the tree. */
|
||||
BT_PUSH(t, h->pgno, idx);
|
||||
pg = GETBINTERNAL(h, idx)->pgno;
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
if ((h = mpool_getf(t->bt_mp, pg, 0)) == NULL)
|
||||
return RET_ERROR;
|
||||
idx = NEXTINDEX(h) - 1;
|
||||
}
|
||||
ep->page = h;
|
||||
ep->index = idx;
|
||||
return RET_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* __bt_first --
|
||||
|
@ -334,7 +463,7 @@ usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE);
|
|||
static int
|
||||
__bt_first(BTREE *t, const DBT *key, EPG *erval, int *exactp)
|
||||
{
|
||||
PAGE *h;
|
||||
PAGE *h, *hprev;
|
||||
EPG *ep, save;
|
||||
pgno_t pg;
|
||||
|
||||
|
@ -347,13 +476,13 @@ __bt_first(BTREE *t, const DBT *key, EPG *erval, int *exactp)
|
|||
* page) and return it.
|
||||
*/
|
||||
if ((ep = __bt_search(t, key, exactp)) == NULL)
|
||||
return (0);
|
||||
return RET_SPECIAL;
|
||||
if (*exactp) {
|
||||
if (F_ISSET(t, B_NODUPS)) {
|
||||
*erval = *ep;
|
||||
return (RET_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Walk backwards, as long as the entry matches and there are
|
||||
* keys left in the tree. Save a copy of each match in case
|
||||
|
@ -378,10 +507,14 @@ __bt_first(BTREE *t, const DBT *key, EPG *erval, int *exactp)
|
|||
break;
|
||||
if (h->pgno != save.page->pgno)
|
||||
mpool_put(t->bt_mp, h, 0);
|
||||
if ((h = mpool_get(t->bt_mp,
|
||||
h->prevpg, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
ep->page = h;
|
||||
if ((hprev = mpool_getf(t->bt_mp,
|
||||
h->prevpg, 0)) == NULL) {
|
||||
if (h->pgno == save.page->pgno)
|
||||
mpool_put(t->bt_mp,
|
||||
save.page, 0);
|
||||
return RET_ERROR;
|
||||
}
|
||||
ep->page = h = hprev;
|
||||
ep->index = NEXTINDEX(h);
|
||||
}
|
||||
--ep->index;
|
||||
|
@ -406,7 +539,7 @@ __bt_first(BTREE *t, const DBT *key, EPG *erval, int *exactp)
|
|||
mpool_put(t->bt_mp, h, 0);
|
||||
if (pg == P_INVALID)
|
||||
return (RET_SPECIAL);
|
||||
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, pg, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
ep->index = 0;
|
||||
ep->page = h;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bt_split.c,v 1.20 2011/06/20 09:11:17 mrg Exp $ */
|
||||
/* $NetBSD: bt_split.c,v 1.21 2016/09/24 20:11:12 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
|
@ -37,7 +37,7 @@
|
|||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: bt_split.c,v 1.20 2011/06/20 09:11:17 mrg Exp $");
|
||||
__RCSID("$NetBSD: bt_split.c,v 1.21 2016/09/24 20:11:12 christos Exp $");
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
|
@ -153,7 +153,7 @@ __bt_split(BTREE *t, PAGE *sp, const DBT *key, const DBT *data, int flags,
|
|||
rchild = r;
|
||||
|
||||
/* Get the parent page. */
|
||||
if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, parent->pgno, 0)) == NULL)
|
||||
goto err2;
|
||||
|
||||
/*
|
||||
|
@ -401,7 +401,7 @@ bt_page(BTREE *t, PAGE *h, PAGE **lp, PAGE **rp, indx_t *skip, size_t ilen)
|
|||
|
||||
/* Fix up the previous pointer of the page after the split page. */
|
||||
if (h->nextpg != P_INVALID) {
|
||||
if ((tp = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) {
|
||||
if ((tp = mpool_getf(t->bt_mp, h->nextpg, 0)) == NULL) {
|
||||
free(l);
|
||||
/* XXX mpool_free(t->bt_mp, r->pgno); */
|
||||
return (NULL);
|
||||
|
@ -799,7 +799,7 @@ bt_preserve(BTREE *t, pgno_t pg)
|
|||
{
|
||||
PAGE *h;
|
||||
|
||||
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, pg, 0)) == NULL)
|
||||
return (RET_ERROR);
|
||||
h->flags |= P_PRESERVE;
|
||||
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: extern.h,v 1.12 2008/09/26 11:41:06 tsutsui Exp $ */
|
||||
/* $NetBSD: extern.h,v 1.13 2016/09/24 20:11:12 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
|
@ -48,6 +48,7 @@ void __bt_pgin(void *, pgno_t, void *);
|
|||
void __bt_pgout(void *, pgno_t, void *);
|
||||
int __bt_push(BTREE *, pgno_t, int);
|
||||
int __bt_put(const DB *dbp, DBT *, const DBT *, unsigned int);
|
||||
int __bt_relink(BTREE *, PAGE *);
|
||||
int __bt_ret(BTREE *, EPG *, DBT *, DBT *, DBT *, DBT *, int);
|
||||
EPG *__bt_search(BTREE *, const DBT *, int *);
|
||||
int __bt_seq(const DB *, DBT *, DBT *, unsigned int);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mpool.c,v 1.21 2013/12/14 18:04:00 christos Exp $ */
|
||||
/* $NetBSD: mpool.c,v 1.22 2016/09/24 20:11:12 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
|
@ -34,7 +34,7 @@
|
|||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: mpool.c,v 1.21 2013/12/14 18:04:00 christos Exp $");
|
||||
__RCSID("$NetBSD: mpool.c,v 1.22 2016/09/24 20:11:12 christos Exp $");
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/queue.h>
|
||||
|
@ -55,7 +55,9 @@ __RCSID("$NetBSD: mpool.c,v 1.21 2013/12/14 18:04:00 christos Exp $");
|
|||
__weak_alias(mpool_close,_mpool_close)
|
||||
__weak_alias(mpool_filter,_mpool_filter)
|
||||
__weak_alias(mpool_get,_mpool_get)
|
||||
__weak_alias(mpool_getf,_mpool_getf)
|
||||
__weak_alias(mpool_new,_mpool_new)
|
||||
__weak_alias(mpool_newf,_mpool_newf)
|
||||
__weak_alias(mpool_open,_mpool_open)
|
||||
__weak_alias(mpool_put,_mpool_put)
|
||||
__weak_alias(mpool_sync,_mpool_sync)
|
||||
|
@ -121,7 +123,7 @@ mpool_filter(MPOOL *mp, void (*pgin)(void *, pgno_t, void *),
|
|||
* Get a new page of memory.
|
||||
*/
|
||||
void *
|
||||
mpool_new( MPOOL *mp, pgno_t *pgnoaddr)
|
||||
mpool_newf(MPOOL *mp, pgno_t *pgnoaddr, unsigned int flags)
|
||||
{
|
||||
struct _hqh *head;
|
||||
BKT *bp;
|
||||
|
@ -140,8 +142,14 @@ mpool_new( MPOOL *mp, pgno_t *pgnoaddr)
|
|||
*/
|
||||
if ((bp = mpool_bkt(mp)) == NULL)
|
||||
return NULL;
|
||||
*pgnoaddr = bp->pgno = mp->npages++;
|
||||
bp->flags = MPOOL_PINNED;
|
||||
|
||||
if (flags == MPOOL_PAGE_REQUEST) {
|
||||
mp->npages++;
|
||||
bp->pgno = *pgnoaddr;
|
||||
} else
|
||||
bp->pgno = *pgnoaddr = mp->npages++;
|
||||
|
||||
bp->flags = MPOOL_PINNED | MPOOL_INUSE;
|
||||
|
||||
head = &mp->hqh[HASHKEY(bp->pgno)];
|
||||
TAILQ_INSERT_HEAD(head, bp, hq);
|
||||
|
@ -149,13 +157,44 @@ mpool_new( MPOOL *mp, pgno_t *pgnoaddr)
|
|||
return bp->page;
|
||||
}
|
||||
|
||||
void *
|
||||
mpool_new(MPOOL *mp, pgno_t *pgnoaddr)
|
||||
{
|
||||
return mpool_newf(mp, pgnoaddr, 0);
|
||||
}
|
||||
|
||||
int
|
||||
mpool_delete(MPOOL *mp, void *page)
|
||||
{
|
||||
struct _hqh *head;
|
||||
BKT *bp;
|
||||
|
||||
bp = (void *)((char *)page - sizeof(BKT));
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!(bp->flags & MPOOL_PINNED)) {
|
||||
(void)fprintf(stderr,
|
||||
"%s: page %d not pinned\n", __func__, bp->pgno);
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Remove from the hash and lru queues. */
|
||||
head = &mp->hqh[HASHKEY(bp->pgno)];
|
||||
TAILQ_REMOVE(head, bp, hq);
|
||||
TAILQ_REMOVE(&mp->lqh, bp, q);
|
||||
|
||||
free(bp);
|
||||
return RET_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* mpool_get
|
||||
* Get a page.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void *
|
||||
mpool_get(MPOOL *mp, pgno_t pgno, u_int flags)
|
||||
mpool_getf(MPOOL *mp, pgno_t pgno, unsigned int flags)
|
||||
{
|
||||
struct _hqh *head;
|
||||
BKT *bp;
|
||||
|
@ -175,7 +214,7 @@ mpool_get(MPOOL *mp, pgno_t pgno, u_int flags)
|
|||
/* Check for a page that is cached. */
|
||||
if ((bp = mpool_look(mp, pgno)) != NULL) {
|
||||
#ifdef DEBUG
|
||||
if (bp->flags & MPOOL_PINNED) {
|
||||
if (!(flags & MPOOL_IGNOREPIN) && bp->flags & MPOOL_PINNED) {
|
||||
(void)fprintf(stderr,
|
||||
"mpool_get: page %d already pinned\n", bp->pgno);
|
||||
abort();
|
||||
|
@ -192,7 +231,8 @@ mpool_get(MPOOL *mp, pgno_t pgno, u_int flags)
|
|||
TAILQ_INSERT_TAIL(&mp->lqh, bp, q);
|
||||
|
||||
/* Return a pinned page. */
|
||||
bp->flags |= MPOOL_PINNED;
|
||||
if (!(flags & MPOOL_IGNOREPIN))
|
||||
bp->flags |= MPOOL_PINNED;
|
||||
return bp->page;
|
||||
}
|
||||
|
||||
|
@ -205,15 +245,32 @@ mpool_get(MPOOL *mp, pgno_t pgno, u_int flags)
|
|||
++mp->pageread;
|
||||
#endif
|
||||
off = mp->pagesize * pgno;
|
||||
if (off / mp->pagesize != pgno) {
|
||||
/* Run past the end of the file, or at least the part we
|
||||
can address without large-file support? */
|
||||
errno = E2BIG;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((nr = pread(mp->fd, bp->page, (size_t)mp->pagesize, off)) != (int)mp->pagesize) {
|
||||
if (nr >= 0)
|
||||
if (nr > 0) {
|
||||
errno = EFTYPE;
|
||||
return NULL;
|
||||
return NULL;
|
||||
} else if (nr == 0) {
|
||||
/*
|
||||
* A zero-length reads, means you need to create a
|
||||
* new page.
|
||||
*/
|
||||
memset(bp->page, 0, mp->pagesize);
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set the page number, pin the page. */
|
||||
bp->pgno = pgno;
|
||||
bp->flags = MPOOL_PINNED;
|
||||
if (!(flags & MPOOL_IGNOREPIN))
|
||||
bp->flags = MPOOL_PINNED;
|
||||
bp->flags |= MPOOL_INUSE;
|
||||
|
||||
/*
|
||||
* Add the page to the head of the hash chain and the tail
|
||||
|
@ -230,6 +287,12 @@ mpool_get(MPOOL *mp, pgno_t pgno, u_int flags)
|
|||
return bp->page;
|
||||
}
|
||||
|
||||
void *
|
||||
mpool_get(MPOOL *mp, pgno_t pgno)
|
||||
{
|
||||
return mpool_getf(mp, pgno, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* mpool_put
|
||||
* Return a page.
|
||||
|
@ -252,7 +315,8 @@ mpool_put(MPOOL *mp, void *page, u_int flags)
|
|||
}
|
||||
#endif
|
||||
bp->flags &= ~MPOOL_PINNED;
|
||||
bp->flags |= flags & MPOOL_DIRTY;
|
||||
if (flags & MPOOL_DIRTY)
|
||||
bp->flags |= flags & MPOOL_DIRTY;
|
||||
return (RET_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -371,6 +435,13 @@ mpool_write(MPOOL *mp, BKT *bp)
|
|||
(mp->pgout)(mp->pgcookie, bp->pgno, bp->page);
|
||||
|
||||
off = mp->pagesize * bp->pgno;
|
||||
if (off / mp->pagesize != bp->pgno) {
|
||||
/* Run past the end of the file, or at least the part we
|
||||
can address without large-file support? */
|
||||
errno = E2BIG;
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
if (pwrite(mp->fd, bp->page, (size_t)mp->pagesize, off) !=
|
||||
(ssize_t)mp->pagesize)
|
||||
return RET_ERROR;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: rec_open.c,v 1.20 2013/12/01 00:22:48 christos Exp $ */
|
||||
/* $NetBSD: rec_open.c,v 1.21 2016/09/24 20:11:12 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
|
@ -37,7 +37,7 @@
|
|||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: rec_open.c,v 1.20 2013/12/01 00:22:48 christos Exp $");
|
||||
__RCSID("$NetBSD: rec_open.c,v 1.21 2016/09/24 20:11:12 christos Exp $");
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
|
@ -197,7 +197,7 @@ slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL)
|
|||
dbp->sync = __rec_sync;
|
||||
|
||||
/* If the root page was created, reset the flags. */
|
||||
if ((h = mpool_get(t->bt_mp, P_ROOT, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, P_ROOT, 0)) == NULL)
|
||||
goto err;
|
||||
if ((h->flags & P_TYPE) == P_BLEAF) {
|
||||
F_CLR(h, P_TYPE);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: rec_search.c,v 1.14 2008/09/11 12:58:00 joerg Exp $ */
|
||||
/* $NetBSD: rec_search.c,v 1.15 2016/09/24 20:11:12 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
|
@ -34,7 +34,7 @@
|
|||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: rec_search.c,v 1.14 2008/09/11 12:58:00 joerg Exp $");
|
||||
__RCSID("$NetBSD: rec_search.c,v 1.15 2016/09/24 20:11:12 christos Exp $");
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
|
@ -77,7 +77,7 @@ __rec_search(BTREE *t, recno_t recno, enum SRCHOP op)
|
|||
|
||||
BT_CLR(t);
|
||||
for (pg = P_ROOT, total = 0;;) {
|
||||
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, pg, 0)) == NULL)
|
||||
goto err;
|
||||
if (h->flags & P_RLEAF) {
|
||||
t->bt_cur.page = h;
|
||||
|
@ -113,7 +113,7 @@ __rec_search(BTREE *t, recno_t recno, enum SRCHOP op)
|
|||
err: sverrno = errno;
|
||||
if (op != SEARCH)
|
||||
while ((parent = BT_POP(t)) != NULL) {
|
||||
if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
|
||||
if ((h = mpool_getf(t->bt_mp, parent->pgno, 0)) == NULL)
|
||||
break;
|
||||
if (op == SINSERT)
|
||||
--GETRINTERNAL(h, parent->index)->nrecs;
|
||||
|
|
Loading…
Reference in New Issue