1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-19 15:33:56 +00:00

Fix conflicts and merge into mainline

This commit is contained in:
Paul Traina 1996-02-27 19:42:00 +00:00
parent 79dd972e3e
commit f1e396bc53
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=14287
16 changed files with 719 additions and 25281 deletions

40
lib/libc/db/README Normal file
View File

@ -0,0 +1,40 @@
# @(#)README 8.27 (Berkeley) 9/1/94
This is version 1.85 of the Berkeley DB code.
For information on compiling and installing this software, see the file
PORT/README.
Newer versions of this software will periodically be made available by
anonymous ftp from ftp.cs.berkeley.edu. An archive in compressed format
is in ucb/4bsd/db.tar.Z, or in gzip format in ucb/4bsd/db.tar.gz. If
you'd like to receive announcements of future releases of this software,
send email to the contact address below.
Email questions may be addressed to Keith Bostic at bostic@cs.berkeley.edu.
============================================
Distribution contents:
Makefile.inc Ignore this, it's the 4.4BSD subsystem Makefile.
PORT The per OS/architecture directories to use to build
libdb.a, if you're not running 4.4BSD. See the file
PORT/README for more information.
README This file.
btree The B+tree routines.
changelog List of changes, per version.
db The dbopen(3) interface routine.
docs Various USENIX papers, and the formatted manual pages.
hash The extended linear hashing routines.
man The unformatted manual pages.
mpool The memory pool routines.
recno The fixed/variable length record routines.
test Test package.
============================================
Debugging:
If you're running a memory checker (e.g. Purify) on DB, make sure that
you recompile it with "-DPURIFY" in the CFLAGS, first. By default,
allocated pages are not initialized by the DB code, and they will show
up as reads of uninitialized memory in the buffer write routines.

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1990, 1993
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_close.c 8.3 (Berkeley) 2/21/94";
static char sccsid[] = "@(#)bt_close.c 8.7 (Berkeley) 8/17/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@ -75,25 +75,30 @@ __bt_close(dbp)
t->bt_pinned = NULL;
}
/*
* Delete any already deleted record that we've been saving
* because the cursor pointed to it.
*/
if (ISSET(t, B_DELCRSR) && __bt_crsrdel(t, &t->bt_bcursor))
return (RET_ERROR);
/* Sync the tree. */
if (__bt_sync(dbp, 0) == RET_ERROR)
return (RET_ERROR);
/* Close the memory pool. */
if (mpool_close(t->bt_mp) == RET_ERROR)
return (RET_ERROR);
if (t->bt_stack)
free(t->bt_stack);
if (t->bt_kbuf)
free(t->bt_kbuf);
if (t->bt_dbuf)
free(t->bt_dbuf);
/* Free random memory. */
if (t->bt_cursor.key.data != NULL) {
free(t->bt_cursor.key.data);
t->bt_cursor.key.size = 0;
t->bt_cursor.key.data = NULL;
}
if (t->bt_rkey.data) {
free(t->bt_rkey.data);
t->bt_rkey.size = 0;
t->bt_rkey.data = NULL;
}
if (t->bt_rdata.data) {
free(t->bt_rdata.data);
t->bt_rdata.size = 0;
t->bt_rdata.data = NULL;
}
fd = t->bt_fd;
free(t);
@ -117,8 +122,6 @@ __bt_sync(dbp, flags)
{
BTREE *t;
int status;
PAGE *h;
void *p;
t = dbp->internal;
@ -134,40 +137,15 @@ __bt_sync(dbp, flags)
return (RET_ERROR);
}
if (ISSET(t, B_INMEM | B_RDONLY) || !ISSET(t, B_MODIFIED))
if (F_ISSET(t, B_INMEM | B_RDONLY) || !F_ISSET(t, B_MODIFIED))
return (RET_SUCCESS);
if (ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR)
if (F_ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR)
return (RET_ERROR);
/*
* Nastiness. If the cursor has been marked for deletion, but not
* actually deleted, we have to make a copy of the page, delete the
* key/data item, sync the file, and then restore the original page
* contents.
*/
if (ISSET(t, B_DELCRSR)) {
if ((p = (void *)malloc(t->bt_psize)) == NULL)
return (RET_ERROR);
if ((h = mpool_get(t->bt_mp, t->bt_bcursor.pgno, 0)) == NULL)
return (RET_ERROR);
memmove(p, h, t->bt_psize);
if ((status =
__bt_dleaf(t, h, t->bt_bcursor.index)) == RET_ERROR)
goto ecrsr;
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
}
if ((status = mpool_sync(t->bt_mp)) == RET_SUCCESS)
CLR(t, B_MODIFIED);
F_CLR(t, B_MODIFIED);
ecrsr: if (ISSET(t, B_DELCRSR)) {
if ((h = mpool_get(t->bt_mp, t->bt_bcursor.pgno, 0)) == NULL)
return (RET_ERROR);
memmove(h, p, t->bt_psize);
free(p);
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
}
return (status);
}
@ -191,12 +169,12 @@ bt_meta(t)
return (RET_ERROR);
/* Fill in metadata. */
m.m_magic = BTREEMAGIC;
m.m_version = BTREEVERSION;
m.m_psize = t->bt_psize;
m.m_free = t->bt_free;
m.m_nrecs = t->bt_nrecs;
m.m_flags = t->bt_flags & SAVEMETA;
m.magic = BTREEMAGIC;
m.version = BTREEVERSION;
m.psize = t->bt_psize;
m.free = t->bt_free;
m.nrecs = t->bt_nrecs;
m.flags = F_ISSET(t, SAVEMETA);
memmove(p, &m, sizeof(BTMETA));
mpool_put(t->bt_mp, p, MPOOL_DIRTY);

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1990, 1993
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_open.c 8.5 (Berkeley) 2/21/94";
static char sccsid[] = "@(#)bt_open.c 8.10 (Berkeley) 8/17/94";
#endif /* LIBC_SCCS and not lint */
/*
@ -61,6 +61,11 @@ static char sccsid[] = "@(#)bt_open.c 8.5 (Berkeley) 2/21/94";
#include <db.h>
#include "btree.h"
#ifdef DEBUG
#undef MINPSIZE
#define MINPSIZE 128
#endif
static int byteorder __P((void));
static int nroot __P((BTREE *));
static int tmp __P((void));
@ -157,7 +162,6 @@ __bt_open(fname, flags, mode, openinfo, dflags)
if ((t = (BTREE *)malloc(sizeof(BTREE))) == NULL)
goto err;
memset(t, 0, sizeof(BTREE));
t->bt_bcursor.pgno = P_INVALID;
t->bt_fd = -1; /* Don't close unopened fd on error. */
t->bt_lorder = b.lorder;
t->bt_order = NOT;
@ -167,9 +171,9 @@ __bt_open(fname, flags, mode, openinfo, dflags)
if ((t->bt_dbp = dbp = (DB *)malloc(sizeof(DB))) == NULL)
goto err;
t->bt_flags = 0;
memset(t->bt_dbp, 0, sizeof(DB));
if (t->bt_lorder != machine_lorder)
SET(t, B_NEEDSWAP);
F_SET(t, B_NEEDSWAP);
dbp->type = DB_BTREE;
dbp->internal = t;
@ -186,9 +190,9 @@ __bt_open(fname, flags, mode, openinfo, dflags)
* open a backing temporary file. Otherwise, it's a disk-based tree.
*/
if (fname) {
switch(flags & O_ACCMODE) {
switch (flags & O_ACCMODE) {
case O_RDONLY:
SET(t, B_RDONLY);
F_SET(t, B_RDONLY);
break;
case O_RDWR:
break;
@ -196,7 +200,7 @@ __bt_open(fname, flags, mode, openinfo, dflags)
default:
goto einval;
}
if ((t->bt_fd = open(fname, flags, mode)) < 0)
goto err;
@ -205,7 +209,7 @@ __bt_open(fname, flags, mode, openinfo, dflags)
goto einval;
if ((t->bt_fd = tmp()) == -1)
goto err;
SET(t, B_INMEM);
F_SET(t, B_INMEM);
}
if (fcntl(t->bt_fd, F_SETFD, 1) == -1)
@ -214,8 +218,7 @@ __bt_open(fname, flags, mode, openinfo, dflags)
if (fstat(t->bt_fd, &sb))
goto err;
if (sb.st_size) {
nr = read(t->bt_fd, &m, sizeof(BTMETA));
if (nr < 0)
if ((nr = read(t->bt_fd, &m, sizeof(BTMETA))) < 0)
goto err;
if (nr != sizeof(BTMETA))
goto eftype;
@ -228,28 +231,28 @@ __bt_open(fname, flags, mode, openinfo, dflags)
* don't bother to return an error, we just clear the NEEDSWAP
* bit.
*/
if (m.m_magic == BTREEMAGIC)
CLR(t, B_NEEDSWAP);
if (m.magic == BTREEMAGIC)
F_CLR(t, B_NEEDSWAP);
else {
SET(t, B_NEEDSWAP);
M_32_SWAP(m.m_magic);
M_32_SWAP(m.m_version);
M_32_SWAP(m.m_psize);
M_32_SWAP(m.m_free);
M_32_SWAP(m.m_nrecs);
M_32_SWAP(m.m_flags);
F_SET(t, B_NEEDSWAP);
M_32_SWAP(m.magic);
M_32_SWAP(m.version);
M_32_SWAP(m.psize);
M_32_SWAP(m.free);
M_32_SWAP(m.nrecs);
M_32_SWAP(m.flags);
}
if (m.m_magic != BTREEMAGIC || m.m_version != BTREEVERSION)
if (m.magic != BTREEMAGIC || m.version != BTREEVERSION)
goto eftype;
if (m.m_psize < MINPSIZE || m.m_psize > MAX_PAGE_OFFSET + 1 ||
m.m_psize & sizeof(indx_t) - 1)
if (m.psize < MINPSIZE || m.psize > MAX_PAGE_OFFSET + 1 ||
m.psize & sizeof(indx_t) - 1)
goto eftype;
if (m.m_flags & ~SAVEMETA)
if (m.flags & ~SAVEMETA)
goto eftype;
b.psize = m.m_psize;
t->bt_flags |= m.m_flags;
t->bt_free = m.m_free;
t->bt_nrecs = m.m_nrecs;
b.psize = m.psize;
F_SET(t, m.flags);
t->bt_free = m.free;
t->bt_nrecs = m.nrecs;
} else {
/*
* Set the page size to the best value for I/O to this file.
@ -265,11 +268,11 @@ __bt_open(fname, flags, mode, openinfo, dflags)
/* Set flag if duplicates permitted. */
if (!(b.flags & R_DUP))
SET(t, B_NODUPS);
F_SET(t, B_NODUPS);
t->bt_free = P_INVALID;
t->bt_nrecs = 0;
SET(t, B_METADIRTY);
F_SET(t, B_METADIRTY);
}
t->bt_psize = b.psize;
@ -304,7 +307,7 @@ __bt_open(fname, flags, mode, openinfo, dflags)
if ((t->bt_mp =
mpool_open(NULL, t->bt_fd, t->bt_psize, ncache)) == NULL)
goto err;
if (!ISSET(t, B_INMEM))
if (!F_ISSET(t, B_INMEM))
mpool_filter(t->bt_mp, __bt_pgin, __bt_pgout, t);
/* Create a root page if new tree. */
@ -313,11 +316,11 @@ __bt_open(fname, flags, mode, openinfo, dflags)
/* Global flags. */
if (dflags & DB_LOCK)
SET(t, B_DB_LOCK);
F_SET(t, B_DB_LOCK);
if (dflags & DB_SHMEM)
SET(t, B_DB_SHMEM);
F_SET(t, B_DB_SHMEM);
if (dflags & DB_TXN)
SET(t, B_DB_TXN);
F_SET(t, B_DB_TXN);
return (dbp);
@ -357,8 +360,9 @@ nroot(t)
mpool_put(t->bt_mp, meta, 0);
return (RET_SUCCESS);
}
if (errno != EINVAL)
if (errno != EINVAL) /* It's OK to not exist. */
return (RET_ERROR);
errno = 0;
if ((meta = mpool_new(t->bt_mp, &npg)) == NULL)
return (RET_ERROR);
@ -432,7 +436,7 @@ __bt_fd(dbp)
}
/* In-memory database can't have a file descriptor. */
if (ISSET(t, B_INMEM)) {
if (F_ISSET(t, B_INMEM)) {
errno = ENOENT;
return (-1);
}

View File

@ -1,92 +0,0 @@
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_stack.c 8.3 (Berkeley) 2/21/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <db.h>
#include "btree.h"
/*
* When a page splits, a new record has to be inserted into its parent page.
* This page may have to split as well, all the way up to the root. Since
* parent pointers in each page would be expensive, we maintain a stack of
* parent pages as we descend the tree.
*
* XXX
* This is a concurrency problem -- if user a builds a stack, then user b
* splits the tree, then user a tries to split the tree, there's a new level
* in the tree that user a doesn't know about.
*/
/*
* __BT_PUSH -- Push parent page info onto the stack (LIFO).
*
* Parameters:
* t: tree
* pgno: page
* index: page index
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__bt_push(t, pgno, index)
BTREE *t;
pgno_t pgno;
indx_t index;
{
if (t->bt_sp == t->bt_maxstack) {
t->bt_maxstack += 50;
if ((t->bt_stack = (EPGNO *)realloc(t->bt_stack,
t->bt_maxstack * sizeof(EPGNO))) == NULL) {
t->bt_maxstack -= 50;
return (RET_ERROR);
}
}
t->bt_stack[t->bt_sp].pgno = pgno;
t->bt_stack[t->bt_sp].index = index;
++t->bt_sp;
return (RET_SUCCESS);
}

View File

@ -1,39 +1,45 @@
# @(#)VERSION 8.9 (Berkeley) 4/2/94
1.84 -> 1.85
recno: #ifdef out use of mmap, it's not portable enough.
This is version 1.74 of the Berkeley DB code.
1.83 -> 1.84 Thu Aug 18 15:46:07 EDT 1994
recno: Rework fixed-length records so that closing and reopening
the file now works. Pad short records on input. Never do
signed comparison in recno input reading functions.
If your version of the DB code doesn't have a copy
of this version file, it's really old, please update it!
1.82 -> 1.83 Tue Jul 26 15:33:44 EDT 1994
btree: Rework cursor deletion code yet again; bugs with
deleting empty pages that only contained the cursor
record.
New versions of this software are periodically made
available by anonymous ftp from ftp.cs.berkeley.edu,
in the file ucb/4bsd/db.tar.Z, or from ftp.uu.net.
If you'd like to get announcements of future releases
of this software, send email to the contact address
below.
1.81 -> 1.82 Sat Jul 16 11:01:50 EDT 1994
btree: Fix bugs introduced by new cursor/deletion code.
Replace return kbuf/dbuf with real DBT's.
Email questions may be addressed to Keith Bostic at
bostic@cs.berkeley.edu.
1.80 -> 1.81
btree: Fix bugs introduced by new cursor/deletion code.
all: Add #defines for Purify.
============================================
Distribution contents:
1.79 -> 1.80 Wed Jul 13 22:41:54 EDT 1994
btree Change deletion to coalesce empty pages. This is a major
change, cursors and duplicate pages all had to be reworked.
Return to a fixed stack.
recno: Affected by cursor changes. New cursor structures should
permit multiple cursors in the future.
Makefile.inc Ignore this, it's the 4.4BSD subsystem Makefile.
PORT The per OS/architecture directories to use to build
libdb.a, if you're not running 4.4BSD. See the file
PORT/README for more information.
README This file.
VERSION This file.
btree B+tree routines.
db Dbopen(3) interface routine.
doc USENIX papers, formatted manual pages.
hash Extended linear hashing routines.
man Unformatted manual pages.
mpool Memory pool routines.
recno Fixed/variable length record routines.
test Test package.
1.78 -> 1.79 Mon Jun 20 17:36:47 EDT 1994
all: Minor cleanups of 1.78 for porting reasons; only
major change was inlining check of NULL pointer
so that __fix_realloc goes away.
1.77 -> 1.78 Thu Jun 16 19:06:43 EDT 1994
all: Move "standard" size typedef's into db.h.
1.76 -> 1.77 Thu Jun 16 16:48:38 EDT 1994
hash: Delete __init_ routine, has special meaning to OSF 2.0.
1.74 -> 1.76
all: Finish up the port to the Alpha.
============================================
1.73 -> 1.74
recno: Don't put the record if rec_search fails, in rec_rdelete.
Create fixed-length intermediate records past "end" of DB
@ -52,7 +58,7 @@ test Test package.
1.7 -> 1.72 12 Oct 1993
hash: Support NET/2 hash formats.
1.7 -> 1.71 16 Sep 1993
btree/recno:
Fix bug in internal search routines that caused

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1990, 1993
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)hash.c 8.7 (Berkeley) 2/21/94";
static char sccsid[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@ -60,13 +60,13 @@ static int alloc_segs __P((HTAB *, int));
static int flush_meta __P((HTAB *));
static int hash_access __P((HTAB *, ACTION, DBT *, DBT *));
static int hash_close __P((DB *));
static int hash_delete __P((const DB *, const DBT *, u_int));
static int hash_delete __P((const DB *, const DBT *, u_int32_t));
static int hash_fd __P((const DB *));
static int hash_get __P((const DB *, const DBT *, DBT *, u_int));
static int hash_put __P((const DB *, DBT *, const DBT *, u_int));
static int hash_get __P((const DB *, const DBT *, DBT *, u_int32_t));
static int hash_put __P((const DB *, DBT *, const DBT *, u_int32_t));
static void *hash_realloc __P((SEGMENT **, int, int));
static int hash_seq __P((const DB *, DBT *, DBT *, u_int));
static int hash_sync __P((const DB *, u_int));
static int hash_seq __P((const DB *, DBT *, DBT *, u_int32_t));
static int hash_sync __P((const DB *, u_int32_t));
static int hdestroy __P((HTAB *));
static HTAB *init_hash __P((HTAB *, const char *, HASHINFO *));
static int init_htab __P((HTAB *, int));
@ -86,7 +86,7 @@ static void swap_header_copy __P((HASHHDR *, HASHHDR *));
#define ABNORMAL (1)
#ifdef HASH_STATISTICS
long hash_accesses, hash_collisions, hash_expansions, hash_overflows;
int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
#endif
/************************** INTERFACE ROUTINES ***************************/
@ -186,7 +186,7 @@ __hash_open(file, flags, mode, info, dflags)
(hashp->BSHIFT + BYTE_SHIFT);
hashp->nmaps = bpages;
(void)memset(&hashp->mapp[0], 0, bpages * sizeof(u_long *));
(void)memset(&hashp->mapp[0], 0, bpages * sizeof(u_int32_t *));
}
/* Initialize Buffer Manager */
@ -373,7 +373,7 @@ init_htab(hashp, nelem)
hashp->LAST_FREED = 2;
/* First bitmap page is at: splitpoint l2 page offset 1 */
if (__init_bitmap(hashp, OADDR_OF(l2, 1), l2 + 1, 0))
if (__ibitmap(hashp, OADDR_OF(l2, 1), l2 + 1, 0))
return (-1);
hashp->MAX_BUCKET = hashp->LOW_MASK = nbuckets - 1;
@ -458,7 +458,7 @@ hdestroy(hashp)
static int
hash_sync(dbp, flags)
const DB *dbp;
u_int flags;
u_int32_t flags;
{
HTAB *hashp;
@ -537,7 +537,7 @@ hash_get(dbp, key, data, flag)
const DB *dbp;
const DBT *key;
DBT *data;
u_int flag;
u_int32_t flag;
{
HTAB *hashp;
@ -554,7 +554,7 @@ hash_put(dbp, key, data, flag)
const DB *dbp;
DBT *key;
const DBT *data;
u_int flag;
u_int32_t flag;
{
HTAB *hashp;
@ -575,7 +575,7 @@ static int
hash_delete(dbp, key, flag)
const DB *dbp;
const DBT *key;
u_int flag; /* Ignored */
u_int32_t flag; /* Ignored */
{
HTAB *hashp;
@ -602,10 +602,10 @@ hash_access(hashp, action, key, val)
{
register BUFHEAD *rbufp;
BUFHEAD *bufp, *save_bufp;
register u_short *bp;
register u_int16_t *bp;
register int n, ndx, off, size;
register char *kp;
u_short pageno;
u_int16_t pageno;
#ifdef HASH_STATISTICS
hash_accesses++;
@ -621,7 +621,7 @@ hash_access(hashp, action, key, val)
/* Pin the bucket chain */
rbufp->flags |= BUF_PIN;
for (bp = (u_short *)rbufp->page, n = *bp++, ndx = 1; ndx < n;)
for (bp = (u_int16_t *)rbufp->page, n = *bp++, ndx = 1; ndx < n;)
if (bp[1] >= REAL_KEY) {
/* Real key/data pair */
if (size == off - *bp &&
@ -640,7 +640,7 @@ hash_access(hashp, action, key, val)
return (ERROR);
}
/* FOR LOOP INIT */
bp = (u_short *)rbufp->page;
bp = (u_int16_t *)rbufp->page;
n = *bp++;
ndx = 1;
off = hashp->BSIZE;
@ -662,7 +662,7 @@ hash_access(hashp, action, key, val)
return (ERROR);
}
/* FOR LOOP INIT */
bp = (u_short *)rbufp->page;
bp = (u_int16_t *)rbufp->page;
n = *bp++;
ndx = 1;
off = hashp->BSIZE;
@ -696,7 +696,7 @@ hash_access(hashp, action, key, val)
save_bufp->flags &= ~BUF_PIN;
return (ABNORMAL);
case HASH_GET:
bp = (u_short *)rbufp->page;
bp = (u_int16_t *)rbufp->page;
if (bp[ndx + 1] < REAL_KEY) {
if (__big_return(hashp, rbufp, ndx, val, 0))
return (ERROR);
@ -727,12 +727,12 @@ static int
hash_seq(dbp, key, data, flag)
const DB *dbp;
DBT *key, *data;
u_int flag;
u_int32_t flag;
{
register u_int bucket;
register u_int32_t bucket;
register BUFHEAD *bufp;
HTAB *hashp;
u_short *bp, ndx;
u_int16_t *bp, ndx;
hashp = (HTAB *)dbp->internal;
if (flag && flag != R_FIRST && flag != R_NEXT) {
@ -757,7 +757,7 @@ hash_seq(dbp, key, data, flag)
if (!bufp)
return (ERROR);
hashp->cpage = bufp;
bp = (u_short *)bufp->page;
bp = (u_int16_t *)bufp->page;
if (bp[0])
break;
}
@ -767,7 +767,7 @@ hash_seq(dbp, key, data, flag)
return (ABNORMAL);
}
} else
bp = (u_short *)hashp->cpage->page;
bp = (u_int16_t *)hashp->cpage->page;
#ifdef DEBUG
assert(bp);
@ -778,7 +778,7 @@ hash_seq(dbp, key, data, flag)
__get_buf(hashp, bp[hashp->cndx], bufp, 0);
if (!bufp)
return (ERROR);
bp = (u_short *)(bufp->page);
bp = (u_int16_t *)(bufp->page);
hashp->cndx = 1;
}
if (!bp[0]) {
@ -817,7 +817,7 @@ extern int
__expand_table(hashp)
HTAB *hashp;
{
u_int old_bucket, new_bucket;
u_int32_t old_bucket, new_bucket;
int dirsize, new_segnum, spare_ndx;
#ifdef HASH_STATISTICS
@ -884,7 +884,7 @@ hash_realloc(p_ptr, oldsize, newsize)
return (p);
}
extern u_int
extern u_int32_t
__call_hash(hashp, k, len)
HTAB *hashp;
char *k;

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1990, 1993
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@ -33,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)hash.h 8.2 (Berkeley) 2/21/94
* @(#)hash.h 8.3 (Berkeley) 5/31/94
*/
/* Operations */
@ -45,12 +45,12 @@ typedef enum {
typedef struct _bufhead BUFHEAD;
struct _bufhead {
BUFHEAD *prev; /* LRU links */
BUFHEAD *next; /* LRU links */
BUFHEAD *ovfl; /* Overflow page buffer header */
u_int addr; /* Address of this page */
char *page; /* Actual page data */
char flags;
BUFHEAD *prev; /* LRU links */
BUFHEAD *next; /* LRU links */
BUFHEAD *ovfl; /* Overflow page buffer header */
u_int32_t addr; /* Address of this page */
char *page; /* Actual page data */
char flags;
#define BUF_MOD 0x0001
#define BUF_DISK 0x0002
#define BUF_BUCKET 0x0004
@ -62,51 +62,60 @@ struct _bufhead {
typedef BUFHEAD **SEGMENT;
/* Hash Table Information */
typedef struct hashhdr { /* Disk resident portion */
int magic; /* Magic NO for hash tables */
int version; /* Version ID */
long lorder; /* Byte Order */
int bsize; /* Bucket/Page Size */
int bshift; /* Bucket shift */
int dsize; /* Directory Size */
int ssize; /* Segment Size */
int sshift; /* Segment shift */
int ovfl_point; /* Where overflow pages are being allocated */
int last_freed; /* Last overflow page freed */
int max_bucket; /* ID of Maximum bucket in use */
int high_mask; /* Mask to modulo into entire table */
int low_mask; /* Mask to modulo into lower half of table */
int ffactor; /* Fill factor */
int nkeys; /* Number of keys in hash table */
int hdrpages; /* Size of table header */
int h_charkey; /* value of hash(CHARKEY) */
#define NCACHED 32 /* number of bit maps and spare points */
int spares[NCACHED];/* spare pages for overflow */
u_short bitmaps[NCACHED]; /* address of overflow page bitmaps */
typedef struct hashhdr { /* Disk resident portion */
int magic; /* Magic NO for hash tables */
int version; /* Version ID */
u_int32_t lorder; /* Byte Order */
int bsize; /* Bucket/Page Size */
int bshift; /* Bucket shift */
int dsize; /* Directory Size */
int ssize; /* Segment Size */
int sshift; /* Segment shift */
int ovfl_point; /* Where overflow pages are being
* allocated */
int last_freed; /* Last overflow page freed */
int max_bucket; /* ID of Maximum bucket in use */
int high_mask; /* Mask to modulo into entire table */
int low_mask; /* Mask to modulo into lower half of
* table */
int ffactor; /* Fill factor */
int nkeys; /* Number of keys in hash table */
int hdrpages; /* Size of table header */
int h_charkey; /* value of hash(CHARKEY) */
#define NCACHED 32 /* number of bit maps and spare
* points */
int spares[NCACHED];/* spare pages for overflow */
u_int16_t bitmaps[NCACHED]; /* address of overflow page
* bitmaps */
} HASHHDR;
typedef struct htab { /* Memory resident data structure */
HASHHDR hdr; /* Header */
int nsegs; /* Number of allocated segments */
int exsegs; /* Number of extra allocated segments */
u_int32_t /* Hash function */
typedef struct htab { /* Memory resident data structure */
HASHHDR hdr; /* Header */
int nsegs; /* Number of allocated segments */
int exsegs; /* Number of extra allocated
* segments */
u_int32_t /* Hash function */
(*hash)__P((const void *, size_t));
int flags; /* Flag values */
int fp; /* File pointer */
char *tmp_buf; /* Temporary Buffer for BIG data */
char *tmp_key; /* Temporary Buffer for BIG keys */
BUFHEAD *cpage; /* Current page */
int cbucket; /* Current bucket */
int cndx; /* Index of next item on cpage */
int error; /* Error Number -- for DBM compatability */
int new_file; /* Indicates if fd is backing store or no */
int save_file; /* Indicates whether we need to flush file at
* exit */
u_long *mapp[NCACHED]; /* Pointers to page maps */
int nmaps; /* Initial number of bitmaps */
int nbufs; /* Number of buffers left to allocate */
BUFHEAD bufhead; /* Header of buffer lru list */
SEGMENT *dir; /* Hash Bucket directory */
int flags; /* Flag values */
int fp; /* File pointer */
char *tmp_buf; /* Temporary Buffer for BIG data */
char *tmp_key; /* Temporary Buffer for BIG keys */
BUFHEAD *cpage; /* Current page */
int cbucket; /* Current bucket */
int cndx; /* Index of next item on cpage */
int error; /* Error Number -- for DBM
* compatability */
int new_file; /* Indicates if fd is backing store
* or no */
int save_file; /* Indicates whether we need to flush
* file at
* exit */
u_int32_t *mapp[NCACHED]; /* Pointers to page maps */
int nmaps; /* Initial number of bitmaps */
int nbufs; /* Number of buffers left to
* allocate */
BUFHEAD bufhead; /* Header of buffer lru list */
SEGMENT *dir; /* Hash Bucket directory */
} HTAB;
/*
@ -129,14 +138,14 @@ typedef struct htab { /* Memory resident data structure */
#define BYTE_SHIFT 3
#define INT_TO_BYTE 2
#define INT_BYTE_SHIFT 5
#define ALL_SET ((u_int)0xFFFFFFFF)
#define ALL_SET ((u_int32_t)0xFFFFFFFF)
#define ALL_CLEAR 0
#define PTROF(X) ((BUFHEAD *)((u_int)(X)&~0x3))
#define ISMOD(X) ((u_int)(X)&0x1)
#define DOMOD(X) ((X) = (char *)((u_int)(X)|0x1))
#define ISDISK(X) ((u_int)(X)&0x2)
#define DODISK(X) ((X) = (char *)((u_int)(X)|0x2))
#define PTROF(X) ((BUFHEAD *)((ptrdiff_t)(X)&~0x3))
#define ISMOD(X) ((u_int32_t)(ptrdiff_t)(X)&0x1)
#define DOMOD(X) ((X) = (char *)((ptrdiff_t)(X)|0x1))
#define ISDISK(X) ((u_int32_t)(ptrdiff_t)(X)&0x2)
#define DODISK(X) ((X) = (char *)((ptrdiff_t)(X)|0x2))
#define BITS_PER_MAP 32
@ -156,9 +165,9 @@ typedef struct htab { /* Memory resident data structure */
#define SPLITSHIFT 11
#define SPLITMASK 0x7FF
#define SPLITNUM(N) (((u_int)(N)) >> SPLITSHIFT)
#define SPLITNUM(N) (((u_int32_t)(N)) >> SPLITSHIFT)
#define OPAGENUM(N) ((N) & SPLITMASK)
#define OADDR_OF(S,O) ((u_int)((u_int)(S) << SPLITSHIFT) + (O))
#define OADDR_OF(S,O) ((u_int32_t)((u_int32_t)(S) << SPLITSHIFT) + (O))
#define BUCKET_TO_PAGE(B) \
(B) + hashp->HDRPAGES + ((B) ? hashp->SPARES[__log2((B)+1)-1] : 0)

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1990, 1993
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)hash_page.c 8.4 (Berkeley) 2/21/94";
static char sccsid[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94";
#endif /* LIBC_SCCS and not lint */
/*
@ -72,19 +72,19 @@ static char sccsid[] = "@(#)hash_page.c 8.4 (Berkeley) 2/21/94";
#include "page.h"
#include "extern.h"
static u_long *fetch_bitmap __P((HTAB *, int));
static u_long first_free __P((u_long));
static u_int32_t *fetch_bitmap __P((HTAB *, int));
static u_int32_t first_free __P((u_int32_t));
static int open_temp __P((HTAB *));
static u_short overflow_page __P((HTAB *));
static u_int16_t overflow_page __P((HTAB *));
static void putpair __P((char *, const DBT *, const DBT *));
static void squeeze_key __P((u_short *, const DBT *, const DBT *));
static void squeeze_key __P((u_int16_t *, const DBT *, const DBT *));
static int ugly_split
__P((HTAB *, u_int, BUFHEAD *, BUFHEAD *, int, int));
__P((HTAB *, u_int32_t, BUFHEAD *, BUFHEAD *, int, int));
#define PAGE_INIT(P) { \
((u_short *)(P))[0] = 0; \
((u_short *)(P))[1] = hashp->BSIZE - 3 * sizeof(u_short); \
((u_short *)(P))[2] = hashp->BSIZE; \
((u_int16_t *)(P))[0] = 0; \
((u_int16_t *)(P))[1] = hashp->BSIZE - 3 * sizeof(u_int16_t); \
((u_int16_t *)(P))[2] = hashp->BSIZE; \
}
/*
@ -97,9 +97,9 @@ putpair(p, key, val)
char *p;
const DBT *key, *val;
{
register u_short *bp, n, off;
register u_int16_t *bp, n, off;
bp = (u_short *)p;
bp = (u_int16_t *)p;
/* Enter the key first. */
n = bp[0];
@ -115,7 +115,7 @@ putpair(p, key, val)
/* Adjust page info. */
bp[0] = n;
bp[n + 1] = off - ((n + 3) * sizeof(u_short));
bp[n + 1] = off - ((n + 3) * sizeof(u_int16_t));
bp[n + 2] = off;
}
@ -130,11 +130,11 @@ __delpair(hashp, bufp, ndx)
BUFHEAD *bufp;
register int ndx;
{
register u_short *bp, newoff;
register u_int16_t *bp, newoff;
register int n;
u_short pairlen;
u_int16_t pairlen;
bp = (u_short *)bufp->page;
bp = (u_int16_t *)bufp->page;
n = bp[0];
if (bp[ndx + 1] < REAL_KEY)
@ -165,7 +165,7 @@ __delpair(hashp, bufp, ndx)
}
/* Finally adjust the page data */
bp[n] = OFFSET(bp) + pairlen;
bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(u_short);
bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(u_int16_t);
bp[0] = n - 2;
hashp->NKEYS--;
@ -180,18 +180,18 @@ __delpair(hashp, bufp, ndx)
extern int
__split_page(hashp, obucket, nbucket)
HTAB *hashp;
u_int obucket, nbucket;
u_int32_t obucket, nbucket;
{
register BUFHEAD *new_bufp, *old_bufp;
register u_short *ino;
register u_int16_t *ino;
register char *np;
DBT key, val;
int n, ndx, retval;
u_short copyto, diff, off, moved;
u_int16_t copyto, diff, off, moved;
char *op;
copyto = (u_short)hashp->BSIZE;
off = (u_short)hashp->BSIZE;
copyto = (u_int16_t)hashp->BSIZE;
off = (u_int16_t)hashp->BSIZE;
old_bufp = __get_buf(hashp, obucket, NULL, 0);
if (old_bufp == NULL)
return (-1);
@ -202,7 +202,7 @@ __split_page(hashp, obucket, nbucket)
old_bufp->flags |= (BUF_MOD | BUF_PIN);
new_bufp->flags |= (BUF_MOD | BUF_PIN);
ino = (u_short *)(op = old_bufp->page);
ino = (u_int16_t *)(op = old_bufp->page);
np = new_bufp->page;
moved = 0;
@ -244,13 +244,13 @@ __split_page(hashp, obucket, nbucket)
/* Now clean up the page */
ino[0] -= moved;
FREESPACE(ino) = copyto - sizeof(u_short) * (ino[0] + 3);
FREESPACE(ino) = copyto - sizeof(u_int16_t) * (ino[0] + 3);
OFFSET(ino) = copyto;
#ifdef DEBUG3
(void)fprintf(stderr, "split %d/%d\n",
((u_short *)np)[0] / 2,
((u_short *)op)[0] / 2);
((u_int16_t *)np)[0] / 2,
((u_int16_t *)op)[0] / 2);
#endif
/* unpin both pages */
old_bufp->flags &= ~BUF_PIN;
@ -276,28 +276,28 @@ __split_page(hashp, obucket, nbucket)
static int
ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved)
HTAB *hashp;
u_int obucket; /* Same as __split_page. */
u_int32_t obucket; /* Same as __split_page. */
BUFHEAD *old_bufp, *new_bufp;
int copyto; /* First byte on page which contains key/data values. */
int moved; /* Number of pairs moved to new page. */
{
register BUFHEAD *bufp; /* Buffer header for ino */
register u_short *ino; /* Page keys come off of */
register u_short *np; /* New page */
register u_short *op; /* Page keys go on to if they aren't moving */
register u_int16_t *ino; /* Page keys come off of */
register u_int16_t *np; /* New page */
register u_int16_t *op; /* Page keys go on to if they aren't moving */
BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */
DBT key, val;
SPLIT_RETURN ret;
u_short n, off, ov_addr, scopyto;
u_int16_t n, off, ov_addr, scopyto;
char *cino; /* Character value of ino */
bufp = old_bufp;
ino = (u_short *)old_bufp->page;
np = (u_short *)new_bufp->page;
op = (u_short *)old_bufp->page;
ino = (u_int16_t *)old_bufp->page;
np = (u_int16_t *)new_bufp->page;
op = (u_int16_t *)old_bufp->page;
last_bfp = NULL;
scopyto = (u_short)copyto; /* ANSI */
scopyto = (u_int16_t)copyto; /* ANSI */
n = ino[0] - 1;
while (n < ino[0]) {
@ -308,16 +308,16 @@ ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved)
old_bufp = ret.oldp;
if (!old_bufp)
return (-1);
op = (u_short *)old_bufp->page;
op = (u_int16_t *)old_bufp->page;
new_bufp = ret.newp;
if (!new_bufp)
return (-1);
np = (u_short *)new_bufp->page;
np = (u_int16_t *)new_bufp->page;
bufp = ret.nextp;
if (!bufp)
return (0);
cino = (char *)bufp->page;
ino = (u_short *)cino;
ino = (u_int16_t *)cino;
last_bfp = ret.nextp;
} else if (ino[n + 1] == OVFLPAGE) {
ov_addr = ino[n];
@ -327,14 +327,14 @@ ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved)
*/
ino[0] -= (moved + 2);
FREESPACE(ino) =
scopyto - sizeof(u_short) * (ino[0] + 3);
scopyto - sizeof(u_int16_t) * (ino[0] + 3);
OFFSET(ino) = scopyto;
bufp = __get_buf(hashp, ov_addr, bufp, 0);
if (!bufp)
return (-1);
ino = (u_short *)bufp->page;
ino = (u_int16_t *)bufp->page;
n = 1;
scopyto = hashp->BSIZE;
moved = 0;
@ -362,7 +362,7 @@ ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved)
__add_ovflpage(hashp, old_bufp);
if (!old_bufp)
return (-1);
op = (u_short *)old_bufp->page;
op = (u_int16_t *)old_bufp->page;
putpair((char *)op, &key, &val);
}
old_bufp->flags |= BUF_MOD;
@ -375,7 +375,7 @@ ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved)
__add_ovflpage(hashp, new_bufp);
if (!new_bufp)
return (-1);
np = (u_short *)new_bufp->page;
np = (u_int16_t *)new_bufp->page;
putpair((char *)np, &key, &val);
}
new_bufp->flags |= BUF_MOD;
@ -400,10 +400,10 @@ __addel(hashp, bufp, key, val)
BUFHEAD *bufp;
const DBT *key, *val;
{
register u_short *bp, *sop;
register u_int16_t *bp, *sop;
int do_expand;
bp = (u_short *)bufp->page;
bp = (u_int16_t *)bufp->page;
do_expand = 0;
while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY))
/* Exception case */
@ -415,7 +415,7 @@ __addel(hashp, bufp, key, val)
bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
if (!bufp)
return (-1);
bp = (u_short *)bufp->page;
bp = (u_int16_t *)bufp->page;
} else
/* Try to squeeze key on this page */
if (FREESPACE(bp) > PAIRSIZE(key, val)) {
@ -425,7 +425,7 @@ __addel(hashp, bufp, key, val)
bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
if (!bufp)
return (-1);
bp = (u_short *)bufp->page;
bp = (u_int16_t *)bufp->page;
}
if (PAIRFITS(bp, key, val))
@ -435,7 +435,7 @@ __addel(hashp, bufp, key, val)
bufp = __add_ovflpage(hashp, bufp);
if (!bufp)
return (-1);
sop = (u_short *)bufp->page;
sop = (u_int16_t *)bufp->page;
if (PAIRFITS(sop, key, val))
putpair((char *)sop, key, val);
@ -466,12 +466,12 @@ __add_ovflpage(hashp, bufp)
HTAB *hashp;
BUFHEAD *bufp;
{
register u_short *sp;
u_short ndx, ovfl_num;
register u_int16_t *sp;
u_int16_t ndx, ovfl_num;
#ifdef DEBUG1
int tmp1, tmp2;
#endif
sp = (u_short *)bufp->page;
sp = (u_int16_t *)bufp->page;
/* Check if we are dynamically determining the fill factor */
if (hashp->FFACTOR == DEF_FFACTOR) {
@ -518,12 +518,12 @@ extern int
__get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap)
HTAB *hashp;
char *p;
u_int bucket;
u_int32_t bucket;
int is_bucket, is_disk, is_bitmap;
{
register int fd, page, size;
int rsize;
u_short *bp;
u_int16_t *bp;
fd = hashp->fp;
size = hashp->BSIZE;
@ -539,7 +539,7 @@ __get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap)
if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
((rsize = read(fd, p, size)) == -1))
return (-1);
bp = (u_short *)p;
bp = (u_int16_t *)p;
if (!rsize)
bp[0] = 0; /* We hit the EOF, so initialize a new page */
else
@ -556,7 +556,7 @@ __get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap)
if (is_bitmap) {
max = hashp->BSIZE >> 2; /* divide by 4 */
for (i = 0; i < max; i++)
M_32_SWAP(((long *)p)[i]);
M_32_SWAP(((int *)p)[i]);
} else {
M_16_SWAP(bp[0]);
max = bp[0] + 2;
@ -578,7 +578,7 @@ extern int
__put_page(hashp, p, bucket, is_bucket, is_bitmap)
HTAB *hashp;
char *p;
u_int bucket;
u_int32_t bucket;
int is_bucket, is_bitmap;
{
register int fd, page, size;
@ -596,11 +596,11 @@ __put_page(hashp, p, bucket, is_bucket, is_bitmap)
if (is_bitmap) {
max = hashp->BSIZE >> 2; /* divide by 4 */
for (i = 0; i < max; i++)
M_32_SWAP(((long *)p)[i]);
M_32_SWAP(((int *)p)[i]);
} else {
max = ((u_short *)p)[0] + 2;
max = ((u_int16_t *)p)[0] + 2;
for (i = 0; i <= max; i++)
M_16_SWAP(((u_short *)p)[i]);
M_16_SWAP(((u_int16_t *)p)[i]);
}
}
if (is_bucket)
@ -624,14 +624,14 @@ __put_page(hashp, p, bucket, is_bucket, is_bitmap)
* once they are read in.
*/
extern int
__init_bitmap(hashp, pnum, nbits, ndx)
__ibitmap(hashp, pnum, nbits, ndx)
HTAB *hashp;
int pnum, nbits, ndx;
{
u_long *ip;
u_int32_t *ip;
int clearbytes, clearints;
if ((ip = (u_long *)malloc(hashp->BSIZE)) == NULL)
if ((ip = (u_int32_t *)malloc(hashp->BSIZE)) == NULL)
return (1);
hashp->nmaps++;
clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1;
@ -641,16 +641,16 @@ __init_bitmap(hashp, pnum, nbits, ndx)
hashp->BSIZE - clearbytes);
ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK);
SETBIT(ip, 0);
hashp->BITMAPS[ndx] = (u_short)pnum;
hashp->BITMAPS[ndx] = (u_int16_t)pnum;
hashp->mapp[ndx] = ip;
return (0);
}
static u_long
static u_int32_t
first_free(map)
u_long map;
u_int32_t map;
{
register u_long i, mask;
register u_int32_t i, mask;
mask = 0x1;
for (i = 0; i < BITS_PER_MAP; i++) {
@ -661,13 +661,13 @@ first_free(map)
return (i);
}
static u_short
static u_int16_t
overflow_page(hashp)
HTAB *hashp;
{
register u_long *freep;
register u_int32_t *freep;
register int max_free, offset, splitnum;
u_short addr;
u_int16_t addr;
int bit, first_page, free_bit, free_page, i, in_use_bits, j;
#ifdef DEBUG2
int tmp1, tmp2;
@ -681,9 +681,9 @@ overflow_page(hashp)
/* Look through all the free maps to find the first free block */
first_page = hashp->LAST_FREED >>(hashp->BSHIFT + BYTE_SHIFT);
for ( i = first_page; i <= free_page; i++ ) {
if (!(freep = (u_long *)hashp->mapp[i]) &&
if (!(freep = (u_int32_t *)hashp->mapp[i]) &&
!(freep = fetch_bitmap(hashp, i)))
return (NULL);
return (0);
if (i == free_page)
in_use_bits = free_bit;
else
@ -713,7 +713,7 @@ overflow_page(hashp)
if (offset > SPLITMASK) {
if (++splitnum >= NCACHED) {
(void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
return (NULL);
return (0);
}
hashp->OVFL_POINT = splitnum;
hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
@ -726,7 +726,7 @@ overflow_page(hashp)
free_page++;
if (free_page >= NCACHED) {
(void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
return (NULL);
return (0);
}
/*
* This is tricky. The 1 indicates that you want the new page
@ -739,9 +739,9 @@ overflow_page(hashp)
* don't have to if we tell init_bitmap not to leave it clear
* in the first place.
*/
if (__init_bitmap(hashp, (int)OADDR_OF(splitnum, offset),
1, free_page))
return (NULL);
if (__ibitmap(hashp,
(int)OADDR_OF(splitnum, offset), 1, free_page))
return (0);
hashp->SPARES[splitnum]++;
#ifdef DEBUG2
free_bit = 2;
@ -751,7 +751,7 @@ overflow_page(hashp)
if (++splitnum >= NCACHED) {
(void)write(STDERR_FILENO, OVMSG,
sizeof(OVMSG) - 1);
return (NULL);
return (0);
}
hashp->OVFL_POINT = splitnum;
hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
@ -795,7 +795,7 @@ overflow_page(hashp)
for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++);
offset = (i ? bit - hashp->SPARES[i - 1] : bit);
if (offset >= SPLITMASK)
return (NULL); /* Out of overflow pages */
return (0); /* Out of overflow pages */
addr = OADDR_OF(i, offset);
#ifdef DEBUG2
(void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
@ -814,16 +814,16 @@ __free_ovflpage(hashp, obufp)
HTAB *hashp;
BUFHEAD *obufp;
{
register u_short addr;
u_long *freep;
register u_int16_t addr;
u_int32_t *freep;
int bit_address, free_page, free_bit;
u_short ndx;
u_int16_t ndx;
addr = obufp->addr;
#ifdef DEBUG1
(void)fprintf(stderr, "Freeing %d\n", addr);
#endif
ndx = (((u_short)addr) >> SPLITSHIFT);
ndx = (((u_int16_t)addr) >> SPLITSHIFT);
bit_address =
(ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1;
if (bit_address < hashp->LAST_FREED)
@ -879,11 +879,11 @@ open_temp(hashp)
*/
static void
squeeze_key(sp, key, val)
u_short *sp;
u_int16_t *sp;
const DBT *key, *val;
{
register char *p;
u_short free_space, n, off, pageno;
u_int16_t free_space, n, off, pageno;
p = (char *)sp;
n = sp[0];
@ -904,14 +904,14 @@ squeeze_key(sp, key, val)
OFFSET(sp) = off;
}
static u_long *
static u_int32_t *
fetch_bitmap(hashp, ndx)
HTAB *hashp;
int ndx;
{
if (ndx >= hashp->nmaps)
return (NULL);
if ((hashp->mapp[ndx] = (u_long *)malloc(hashp->BSIZE)) == NULL)
if ((hashp->mapp[ndx] = (u_int32_t *)malloc(hashp->BSIZE)) == NULL)
return (NULL);
if (__get_page(hashp,
(char *)hashp->mapp[ndx], hashp->BITMAPS[ndx], 0, 1, 1)) {

View File

@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)ndbm.c 8.2 (Berkeley) 9/11/93";
static char sccsid[] = "@(#)ndbm.c 8.4 (Berkeley) 7/21/94";
#endif /* LIBC_SCCS and not lint */
/*
@ -45,10 +45,10 @@ static char sccsid[] = "@(#)ndbm.c 8.2 (Berkeley) 9/11/93";
#include <sys/param.h>
#include <ndbm.h>
#include <stdio.h>
#include <string.h>
#include <ndbm.h>
#include "hash.h"
/*
@ -67,7 +67,7 @@ dbm_open(file, flags, mode)
info.bsize = 4096;
info.ffactor = 40;
info.nelem = 1;
info.cachesize = NULL;
info.cachesize = 0;
info.hash = NULL;
info.lorder = 0;
(void)strcpy(path, file);

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1990, 1993
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,10 +32,11 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)mpool.c 8.2 (Berkeley) 2/21/94";
static char sccsid[] = "@(#)mpool.c 8.5 (Berkeley) 7/26/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <errno.h>
@ -45,31 +46,21 @@ static char sccsid[] = "@(#)mpool.c 8.2 (Berkeley) 2/21/94";
#include <unistd.h>
#include <db.h>
#define __MPOOLINTERFACE_PRIVATE
#include "mpool.h"
#include <mpool.h>
static BKT *mpool_bkt __P((MPOOL *));
static BKT *mpool_look __P((MPOOL *, pgno_t));
static int mpool_write __P((MPOOL *, BKT *));
#ifdef DEBUG
static void __mpoolerr __P((const char *fmt, ...));
#endif
/*
* MPOOL_OPEN -- initialize a memory pool.
*
* Parameters:
* key: Shared buffer key.
* fd: File descriptor.
* pagesize: File page size.
* maxcache: Max number of cached pages.
*
* Returns:
* MPOOL pointer, NULL on error.
* mpool_open --
* Initialize a memory pool.
*/
MPOOL *
mpool_open(key, fd, pagesize, maxcache)
DBT *key;
void *key;
int fd;
pgno_t pagesize, maxcache;
{
@ -77,49 +68,35 @@ mpool_open(key, fd, pagesize, maxcache)
MPOOL *mp;
int entry;
/*
* Get information about the file.
*
* XXX
* We don't currently handle pipes, although we should.
*/
if (fstat(fd, &sb))
return (NULL);
/* XXX
* We should only set st_size to 0 for pipes -- 4.4BSD has the fix so
* that stat(2) returns true for ISSOCK on pipes. Until then, this is
* fairly close.
*/
if (!S_ISREG(sb.st_mode)) {
errno = ESPIPE;
return (NULL);
}
if ((mp = (MPOOL *)malloc(sizeof(MPOOL))) == NULL)
/* Allocate and initialize the MPOOL cookie. */
if ((mp = (MPOOL *)calloc(1, sizeof(MPOOL))) == NULL)
return (NULL);
mp->free.cnext = mp->free.cprev = (BKT *)&mp->free;
mp->lru.cnext = mp->lru.cprev = (BKT *)&mp->lru;
CIRCLEQ_INIT(&mp->lqh);
for (entry = 0; entry < HASHSIZE; ++entry)
mp->hashtable[entry].hnext = mp->hashtable[entry].hprev =
mp->hashtable[entry].cnext = mp->hashtable[entry].cprev =
(BKT *)&mp->hashtable[entry];
mp->curcache = 0;
CIRCLEQ_INIT(&mp->hqh[entry]);
mp->maxcache = maxcache;
mp->pagesize = pagesize;
mp->npages = sb.st_size / pagesize;
mp->pagesize = pagesize;
mp->fd = fd;
mp->pgcookie = NULL;
mp->pgin = mp->pgout = NULL;
#ifdef STATISTICS
mp->cachehit = mp->cachemiss = mp->pagealloc = mp->pageflush =
mp->pageget = mp->pagenew = mp->pageput = mp->pageread =
mp->pagewrite = 0;
#endif
return (mp);
}
/*
* MPOOL_FILTER -- initialize input/output filters.
*
* Parameters:
* pgin: Page in conversion routine.
* pgout: Page out conversion routine.
* pgcookie: Cookie for page in/out routines.
* mpool_filter --
* Initialize input/output filters.
*/
void
mpool_filter(mp, pgin, pgout, pgcookie)
@ -132,126 +109,130 @@ mpool_filter(mp, pgin, pgout, pgcookie)
mp->pgout = pgout;
mp->pgcookie = pgcookie;
}
/*
* MPOOL_NEW -- get a new page
*
* Parameters:
* mp: mpool cookie
* pgnoadddr: place to store new page number
* Returns:
* RET_ERROR, RET_SUCCESS
* mpool_new --
* Get a new page of memory.
*/
void *
mpool_new(mp, pgnoaddr)
MPOOL *mp;
pgno_t *pgnoaddr;
{
BKT *b;
BKTHDR *hp;
struct _hqh *head;
BKT *bp;
if (mp->npages == MAX_PAGE_NUMBER) {
(void)fprintf(stderr, "mpool_new: page allocation overflow.\n");
abort();
}
#ifdef STATISTICS
++mp->pagenew;
#endif
/*
* Get a BKT from the cache. Assign a new page number, attach it to
* the hash and lru chains and return.
* Get a BKT from the cache. Assign a new page number, attach
* it to the head of the hash chain, the tail of the lru chain,
* and return.
*/
if ((b = mpool_bkt(mp)) == NULL)
if ((bp = mpool_bkt(mp)) == NULL)
return (NULL);
*pgnoaddr = b->pgno = mp->npages++;
b->flags = MPOOL_PINNED;
inshash(b, b->pgno);
inschain(b, &mp->lru);
return (b->page);
*pgnoaddr = bp->pgno = mp->npages++;
bp->flags = MPOOL_PINNED;
head = &mp->hqh[HASHKEY(bp->pgno)];
CIRCLEQ_INSERT_HEAD(head, bp, hq);
CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
return (bp->page);
}
/*
* MPOOL_GET -- get a page from the pool
*
* Parameters:
* mp: mpool cookie
* pgno: page number
* flags: not used
*
* Returns:
* RET_ERROR, RET_SUCCESS
* mpool_get
* Get a page.
*/
void *
mpool_get(mp, pgno, flags)
MPOOL *mp;
pgno_t pgno;
u_int flags; /* XXX not used? */
u_int flags; /* XXX not used? */
{
BKT *b;
BKTHDR *hp;
struct _hqh *head;
BKT *bp;
off_t off;
int nr;
/*
* If asking for a specific page that is already in the cache, find
* it and return it.
*/
if (b = mpool_look(mp, pgno)) {
#ifdef STATISTICS
++mp->pageget;
#endif
#ifdef DEBUG
if (b->flags & MPOOL_PINNED)
__mpoolerr("mpool_get: page %d already pinned",
b->pgno);
#endif
rmchain(b);
inschain(b, &mp->lru);
b->flags |= MPOOL_PINNED;
return (b->page);
}
/* Not allowed to retrieve a non-existent page. */
/* Check for attempt to retrieve a non-existent page. */
if (pgno >= mp->npages) {
errno = EINVAL;
return (NULL);
}
/* Get a page from the cache. */
if ((b = mpool_bkt(mp)) == NULL)
return (NULL);
b->pgno = pgno;
b->flags = MPOOL_PINNED;
#ifdef STATISTICS
++mp->pageget;
#endif
/* Check for a page that is cached. */
if ((bp = mpool_look(mp, pgno)) != NULL) {
#ifdef DEBUG
if (bp->flags & MPOOL_PINNED) {
(void)fprintf(stderr,
"mpool_get: page %d already pinned\n", bp->pgno);
abort();
}
#endif
/*
* Move the page to the head of the hash chain and the tail
* of the lru chain.
*/
head = &mp->hqh[HASHKEY(bp->pgno)];
CIRCLEQ_REMOVE(head, bp, hq);
CIRCLEQ_INSERT_HEAD(head, bp, hq);
CIRCLEQ_REMOVE(&mp->lqh, bp, q);
CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
/* Return a pinned page. */
bp->flags |= MPOOL_PINNED;
return (bp->page);
}
/* Get a page from the cache. */
if ((bp = mpool_bkt(mp)) == NULL)
return (NULL);
/* Read in the contents. */
#ifdef STATISTICS
++mp->pageread;
#endif
/* Read in the contents. */
off = mp->pagesize * pgno;
if (lseek(mp->fd, off, SEEK_SET) != off)
return (NULL);
if ((nr = read(mp->fd, b->page, mp->pagesize)) != mp->pagesize) {
if ((nr = read(mp->fd, bp->page, mp->pagesize)) != mp->pagesize) {
if (nr >= 0)
errno = EFTYPE;
return (NULL);
}
if (mp->pgin)
(mp->pgin)(mp->pgcookie, b->pgno, b->page);
inshash(b, b->pgno);
inschain(b, &mp->lru);
#ifdef STATISTICS
++mp->pageget;
#endif
return (b->page);
/* Set the page number, pin the page. */
bp->pgno = pgno;
bp->flags = MPOOL_PINNED;
/*
* Add the page to the head of the hash chain and the tail
* of the lru chain.
*/
head = &mp->hqh[HASHKEY(bp->pgno)];
CIRCLEQ_INSERT_HEAD(head, bp, hq);
CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
/* Run through the user's filter. */
if (mp->pgin != NULL)
(mp->pgin)(mp->pgcookie, bp->pgno, bp->page);
return (bp->page);
}
/*
* MPOOL_PUT -- return a page to the pool
*
* Parameters:
* mp: mpool cookie
* page: page pointer
* pgno: page number
*
* Returns:
* RET_ERROR, RET_SUCCESS
* mpool_put
* Return a page.
*/
int
mpool_put(mp, page, flags)
@ -259,193 +240,172 @@ mpool_put(mp, page, flags)
void *page;
u_int flags;
{
BKT *baddr;
#ifdef DEBUG
BKT *b;
#endif
BKT *bp;
#ifdef STATISTICS
++mp->pageput;
#endif
baddr = (BKT *)((char *)page - sizeof(BKT));
bp = (BKT *)((char *)page - sizeof(BKT));
#ifdef DEBUG
if (!(baddr->flags & MPOOL_PINNED))
__mpoolerr("mpool_put: page %d not pinned", b->pgno);
for (b = mp->lru.cnext; b != (BKT *)&mp->lru; b = b->cnext) {
if (b == (BKT *)&mp->lru)
__mpoolerr("mpool_put: %0x: bad address", baddr);
if (b == baddr)
break;
if (!(bp->flags & MPOOL_PINNED)) {
(void)fprintf(stderr,
"mpool_put: page %d not pinned\n", bp->pgno);
abort();
}
#endif
baddr->flags &= ~MPOOL_PINNED;
baddr->flags |= flags & MPOOL_DIRTY;
bp->flags &= ~MPOOL_PINNED;
bp->flags |= flags & MPOOL_DIRTY;
return (RET_SUCCESS);
}
/*
* MPOOL_CLOSE -- close the buffer pool
*
* Parameters:
* mp: mpool cookie
*
* Returns:
* RET_ERROR, RET_SUCCESS
* mpool_close
* Close the buffer pool.
*/
int
mpool_close(mp)
MPOOL *mp;
{
BKT *b, *next;
BKT *bp;
/* Free up any space allocated to the lru pages. */
for (b = mp->lru.cprev; b != (BKT *)&mp->lru; b = next) {
next = b->cprev;
free(b);
while ((bp = mp->lqh.cqh_first) != (void *)&mp->lqh) {
CIRCLEQ_REMOVE(&mp->lqh, mp->lqh.cqh_first, q);
free(bp);
}
/* Free the MPOOL cookie. */
free(mp);
return (RET_SUCCESS);
}
/*
* MPOOL_SYNC -- sync the file to disk.
*
* Parameters:
* mp: mpool cookie
*
* Returns:
* RET_ERROR, RET_SUCCESS
* mpool_sync
* Sync the pool to disk.
*/
int
mpool_sync(mp)
MPOOL *mp;
{
BKT *b;
BKT *bp;
for (b = mp->lru.cprev; b != (BKT *)&mp->lru; b = b->cprev)
if (b->flags & MPOOL_DIRTY && mpool_write(mp, b) == RET_ERROR)
/* Walk the lru chain, flushing any dirty pages to disk. */
for (bp = mp->lqh.cqh_first;
bp != (void *)&mp->lqh; bp = bp->q.cqe_next)
if (bp->flags & MPOOL_DIRTY &&
mpool_write(mp, bp) == RET_ERROR)
return (RET_ERROR);
/* Sync the file descriptor. */
return (fsync(mp->fd) ? RET_ERROR : RET_SUCCESS);
}
/*
* MPOOL_BKT -- get/create a BKT from the cache
*
* Parameters:
* mp: mpool cookie
*
* Returns:
* NULL on failure and a pointer to the BKT on success
* mpool_bkt
* Get a page from the cache (or create one).
*/
static BKT *
mpool_bkt(mp)
MPOOL *mp;
{
BKT *b;
struct _hqh *head;
BKT *bp;
/* If under the max cached, always create a new page. */
if (mp->curcache < mp->maxcache)
goto new;
/*
* If the cache is maxxed out, search the lru list for a buffer we
* can flush. If we find one, write it if necessary and take it off
* any lists. If we don't find anything we grow the cache anyway.
* If the cache is max'd out, walk the lru list for a buffer we
* can flush. If we find one, write it (if necessary) and take it
* off any lists. If we don't find anything we grow the cache anyway.
* The cache never shrinks.
*/
for (b = mp->lru.cprev; b != (BKT *)&mp->lru; b = b->cprev)
if (!(b->flags & MPOOL_PINNED)) {
if (b->flags & MPOOL_DIRTY &&
mpool_write(mp, b) == RET_ERROR)
for (bp = mp->lqh.cqh_first;
bp != (void *)&mp->lqh; bp = bp->q.cqe_next)
if (!(bp->flags & MPOOL_PINNED)) {
/* Flush if dirty. */
if (bp->flags & MPOOL_DIRTY &&
mpool_write(mp, bp) == RET_ERROR)
return (NULL);
rmhash(b);
rmchain(b);
#ifdef STATISTICS
++mp->pageflush;
#endif
/* Remove from the hash and lru queues. */
head = &mp->hqh[HASHKEY(bp->pgno)];
CIRCLEQ_REMOVE(head, bp, hq);
CIRCLEQ_REMOVE(&mp->lqh, bp, q);
#ifdef DEBUG
{
void *spage;
spage = b->page;
memset(b, 0xff, sizeof(BKT) + mp->pagesize);
b->page = spage;
{ void *spage;
spage = bp->page;
memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
bp->page = spage;
}
#endif
return (b);
return (bp);
}
new: if ((b = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL)
new: if ((bp = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL)
return (NULL);
#ifdef STATISTICS
++mp->pagealloc;
#endif
#ifdef DEBUG
memset(b, 0xff, sizeof(BKT) + mp->pagesize);
#if defined(DEBUG) || defined(PURIFY)
memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
#endif
b->page = (char *)b + sizeof(BKT);
bp->page = (char *)bp + sizeof(BKT);
++mp->curcache;
return (b);
return (bp);
}
/*
* MPOOL_WRITE -- sync a page to disk
*
* Parameters:
* mp: mpool cookie
*
* Returns:
* RET_ERROR, RET_SUCCESS
* mpool_write
* Write a page to disk.
*/
static int
mpool_write(mp, b)
mpool_write(mp, bp)
MPOOL *mp;
BKT *b;
BKT *bp;
{
off_t off;
if (mp->pgout)
(mp->pgout)(mp->pgcookie, b->pgno, b->page);
#ifdef STATISTICS
++mp->pagewrite;
#endif
off = mp->pagesize * b->pgno;
/* Run through the user's filter. */
if (mp->pgout)
(mp->pgout)(mp->pgcookie, bp->pgno, bp->page);
off = mp->pagesize * bp->pgno;
if (lseek(mp->fd, off, SEEK_SET) != off)
return (RET_ERROR);
if (write(mp->fd, b->page, mp->pagesize) != mp->pagesize)
if (write(mp->fd, bp->page, mp->pagesize) != mp->pagesize)
return (RET_ERROR);
b->flags &= ~MPOOL_DIRTY;
bp->flags &= ~MPOOL_DIRTY;
return (RET_SUCCESS);
}
/*
* MPOOL_LOOK -- lookup a page
*
* Parameters:
* mp: mpool cookie
* pgno: page number
*
* Returns:
* NULL on failure and a pointer to the BKT on success
* mpool_look
* Lookup a page in the cache.
*/
static BKT *
mpool_look(mp, pgno)
MPOOL *mp;
pgno_t pgno;
{
register BKT *b;
register BKTHDR *tb;
struct _hqh *head;
BKT *bp;
/* XXX
* If find the buffer, put it first on the hash chain so can
* find it again quickly.
*/
tb = &mp->hashtable[HASHKEY(pgno)];
for (b = tb->hnext; b != (BKT *)tb; b = b->hnext)
if (b->pgno == pgno) {
head = &mp->hqh[HASHKEY(pgno)];
for (bp = head->cqh_first; bp != (void *)head; bp = bp->hq.cqe_next)
if (bp->pgno == pgno) {
#ifdef STATISTICS
++mp->cachehit;
#endif
return (b);
return (bp);
}
#ifdef STATISTICS
++mp->cachemiss;
@ -455,16 +415,14 @@ mpool_look(mp, pgno)
#ifdef STATISTICS
/*
* MPOOL_STAT -- cache statistics
*
* Parameters:
* mp: mpool cookie
* mpool_stat
* Print out cache statistics.
*/
void
mpool_stat(mp)
MPOOL *mp;
{
BKT *b;
BKT *bp;
int cnt;
char *sep;
@ -478,7 +436,7 @@ mpool_stat(mp)
mp->pagealloc, mp->pageflush);
if (mp->cachehit + mp->cachemiss)
(void)fprintf(stderr,
"%.0f%% cache hit rate (%lu hits, %lu misses)\n",
"%.0f%% cache hit rate (%lu hits, %lu misses)\n",
((double)mp->cachehit / (mp->cachehit + mp->cachemiss))
* 100, mp->cachehit, mp->cachemiss);
(void)fprintf(stderr, "%lu page reads, %lu page writes\n",
@ -486,49 +444,20 @@ mpool_stat(mp)
sep = "";
cnt = 0;
for (b = mp->lru.cnext; b != (BKT *)&mp->lru; b = b->cnext) {
(void)fprintf(stderr, "%s%d", sep, b->pgno);
if (b->flags & MPOOL_DIRTY)
for (bp = mp->lqh.cqh_first;
bp != (void *)&mp->lqh; bp = bp->q.cqe_next) {
(void)fprintf(stderr, "%s%d", sep, bp->pgno);
if (bp->flags & MPOOL_DIRTY)
(void)fprintf(stderr, "d");
if (b->flags & MPOOL_PINNED)
if (bp->flags & MPOOL_PINNED)
(void)fprintf(stderr, "P");
if (++cnt == 10) {
sep = "\n";
cnt = 0;
} else
sep = ", ";
}
(void)fprintf(stderr, "\n");
}
#endif
#ifdef DEBUG
#if __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
static void
#if __STDC__
__mpoolerr(const char *fmt, ...)
#else
__mpoolerr(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
va_list ap;
#if __STDC__
va_start(ap, fmt);
#else
va_start(ap);
#endif
(void)vfprintf(stderr, fmt, ap);
va_end(ap);
(void)fprintf(stderr, "\n");
abort();
/* NOTREACHED */
}
#endif

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1990, 1993
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,7 +32,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)rec_put.c 8.3 (Berkeley) 3/1/94";
static char sccsid[] = "@(#)rec_put.c 8.7 (Berkeley) 8/18/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@ -66,7 +66,7 @@ __rec_put(dbp, key, data, flags)
u_int flags;
{
BTREE *t;
DBT tdata;
DBT fdata, tdata;
recno_t nrec;
int status;
@ -78,11 +78,38 @@ __rec_put(dbp, key, data, flags)
t->bt_pinned = NULL;
}
/*
* If using fixed-length records, and the record is long, return
* EINVAL. If it's short, pad it out. Use the record data return
* memory, it's only short-term.
*/
if (F_ISSET(t, R_FIXLEN) && data->size != t->bt_reclen) {
if (data->size > t->bt_reclen)
goto einval;
if (t->bt_rdata.size < t->bt_reclen) {
t->bt_rdata.data = t->bt_rdata.data == NULL ?
malloc(t->bt_reclen) :
realloc(t->bt_rdata.data, t->bt_reclen);
if (t->bt_rdata.data == NULL)
return (RET_ERROR);
t->bt_rdata.size = t->bt_reclen;
}
memmove(t->bt_rdata.data, data->data, data->size);
memset((char *)t->bt_rdata.data + data->size,
t->bt_bval, t->bt_reclen - data->size);
fdata.data = t->bt_rdata.data;
fdata.size = t->bt_reclen;
} else {
fdata.data = data->data;
fdata.size = data->size;
}
switch (flags) {
case R_CURSOR:
if (!ISSET(t, B_SEQINIT))
if (!F_ISSET(&t->bt_cursor, CURS_INIT))
goto einval;
nrec = t->bt_rcursor;
nrec = t->bt_cursor.rcursor;
break;
case R_SETCURSOR:
if ((nrec = *(recno_t *)key->data) == 0)
@ -115,11 +142,11 @@ einval: errno = EINVAL;
* already in the database. If skipping records, create empty ones.
*/
if (nrec > t->bt_nrecs) {
if (!ISSET(t, R_EOF | R_INMEM) &&
if (!F_ISSET(t, R_EOF | R_INMEM) &&
t->bt_irec(t, nrec) == RET_ERROR)
return (RET_ERROR);
if (nrec > t->bt_nrecs + 1) {
if (ISSET(t, R_FIXLEN)) {
if (F_ISSET(t, R_FIXLEN)) {
if ((tdata.data =
(void *)malloc(t->bt_reclen)) == NULL)
return (RET_ERROR);
@ -133,18 +160,18 @@ einval: errno = EINVAL;
if (__rec_iput(t,
t->bt_nrecs, &tdata, 0) != RET_SUCCESS)
return (RET_ERROR);
if (ISSET(t, R_FIXLEN))
if (F_ISSET(t, R_FIXLEN))
free(tdata.data);
}
}
if ((status = __rec_iput(t, nrec - 1, data, flags)) != RET_SUCCESS)
if ((status = __rec_iput(t, nrec - 1, &fdata, flags)) != RET_SUCCESS)
return (status);
if (flags == R_SETCURSOR)
t->bt_rcursor = nrec;
SET(t, R_MODIFIED);
t->bt_cursor.rcursor = nrec;
F_SET(t, R_MODIFIED);
return (__rec_ret(t, NULL, nrec, key, NULL));
}
@ -171,7 +198,7 @@ __rec_iput(t, nrec, data, flags)
PAGE *h;
indx_t index, nxtindex;
pgno_t pg;
size_t nbytes;
u_int32_t nbytes;
int dflags, status;
char *dest, db[NOVFLSIZE];
@ -187,7 +214,7 @@ __rec_iput(t, nrec, data, flags)
tdata.data = db;
tdata.size = NOVFLSIZE;
*(pgno_t *)db = pg;
*(size_t *)(db + sizeof(pgno_t)) = data->size;
*(u_int32_t *)(db + sizeof(pgno_t)) = data->size;
dflags = P_BIGDATA;
data = &tdata;
} else
@ -246,7 +273,7 @@ __rec_iput(t, nrec, data, flags)
WR_RLEAF(dest, data, dflags);
++t->bt_nrecs;
SET(t, B_MODIFIED);
F_SET(t, B_MODIFIED);
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
return (RET_SUCCESS);

View File

@ -32,7 +32,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)rec_search.c 8.3 (Berkeley) 2/21/94";
static char sccsid[] = "@(#)rec_search.c 8.4 (Berkeley) 7/14/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@ -91,9 +91,8 @@ __rec_search(t, recno, op)
total += r->nrecs;
}
if (__bt_push(t, pg, index - 1) == RET_ERROR)
return (NULL);
BT_PUSH(t, pg, index - 1);
pg = r->pgno;
switch (op) {
case SDELETE:

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1991, 1993
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,7 +32,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)rec_seq.c 8.2 (Berkeley) 9/7/93";
static char sccsid[] = "@(#)rec_seq.c 8.3 (Berkeley) 7/14/94";
#endif /* not lint */
#include <sys/types.h>
@ -82,8 +82,8 @@ __rec_seq(dbp, key, data, flags)
goto einval;
break;
case R_NEXT:
if (ISSET(t, B_SEQINIT)) {
nrec = t->bt_rcursor + 1;
if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
nrec = t->bt_cursor.rcursor + 1;
break;
}
/* FALLTHROUGH */
@ -91,14 +91,14 @@ __rec_seq(dbp, key, data, flags)
nrec = 1;
break;
case R_PREV:
if (ISSET(t, B_SEQINIT)) {
if ((nrec = t->bt_rcursor - 1) == 0)
if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
if ((nrec = t->bt_cursor.rcursor - 1) == 0)
return (RET_SPECIAL);
break;
}
/* FALLTHROUGH */
case R_LAST:
if (!ISSET(t, R_EOF | R_INMEM) &&
if (!F_ISSET(t, R_EOF | R_INMEM) &&
t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
return (RET_ERROR);
nrec = t->bt_nrecs;
@ -107,9 +107,9 @@ __rec_seq(dbp, key, data, flags)
einval: errno = EINVAL;
return (RET_ERROR);
}
if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) {
if (!ISSET(t, R_EOF | R_INMEM) &&
if (!F_ISSET(t, R_EOF | R_INMEM) &&
(status = t->bt_irec(t, nrec)) != RET_SUCCESS)
return (status);
if (t->bt_nrecs == 0 || nrec > t->bt_nrecs)
@ -119,11 +119,11 @@ einval: errno = EINVAL;
if ((e = __rec_search(t, nrec - 1, SEARCH)) == NULL)
return (RET_ERROR);
SET(t, B_SEQINIT);
t->bt_rcursor = nrec;
F_SET(&t->bt_cursor, CURS_INIT);
t->bt_cursor.rcursor = nrec;
status = __rec_ret(t, e, nrec, key, data);
if (ISSET(t, B_DB_LOCK))
if (F_ISSET(t, B_DB_LOCK))
mpool_put(t->bt_mp, e->page, 0);
else
t->bt_pinned = e->page;

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1992, 1993
* Copyright (c) 1992, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -33,12 +33,12 @@
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1992, 1993\n\
"@(#) Copyright (c) 1992, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)dbtest.c 8.8 (Berkeley) 2/21/94";
static char sccsid[] = "@(#)dbtest.c 8.17 (Berkeley) 9/1/94";
#endif /* not lint */
#include <sys/param.h>
@ -65,6 +65,8 @@ void get __P((DB *, DBT *));
void getdata __P((DB *, DBT *, DBT *));
void put __P((DB *, DBT *, DBT *));
void rem __P((DB *, DBT *));
char *sflags __P((int));
void synk __P((DB *));
void *rfile __P((char *, size_t *));
void seq __P((DB *, DBT *));
u_int setflags __P((char *));
@ -72,13 +74,14 @@ void *setinfo __P((DBTYPE, char *));
void usage __P((void));
void *xmalloc __P((char *, size_t));
DBTYPE type;
void *infop;
u_long lineno;
u_int flags;
int ofd = STDOUT_FILENO;
DBTYPE type; /* Database type. */
void *infop; /* Iflags. */
u_long lineno; /* Current line in test script. */
u_int flags; /* Current DB flags. */
int ofd = STDOUT_FILENO; /* Standard output fd. */
DB *XXdbp; /* Global for gdb. */
int XXlineno; /* Fast breakpoint for gdb. */
int
main(argc, argv)
@ -91,14 +94,15 @@ main(argc, argv)
DB *dbp;
DBT data, key, keydata;
size_t len;
int ch, oflags;
char *fname, *infoarg, *p, buf[8 * 1024];
int ch, oflags, sflag;
char *fname, *infoarg, *p, *t, buf[8 * 1024];
infoarg = NULL;
fname = NULL;
oflags = O_CREAT | O_RDWR;
while ((ch = getopt(argc, argv, "f:i:lo:")) != EOF)
switch(ch) {
sflag = 0;
while ((ch = getopt(argc, argv, "f:i:lo:s")) != EOF)
switch (ch) {
case 'f':
fname = optarg;
break;
@ -113,6 +117,9 @@ main(argc, argv)
O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
err("%s: %s", optarg, strerror(errno));
break;
case 's':
sflag = 1;
break;
case '?':
default:
usage();
@ -127,8 +134,8 @@ main(argc, argv)
type = dbtype(*argv++);
/* Open the descriptor file. */
if (freopen(*argv, "r", stdin) == NULL)
err("%s: %s", *argv, strerror(errno));
if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL)
err("%s: %s", *argv, strerror(errno));
/* Set up the db structure as necessary. */
if (infoarg == NULL)
@ -139,7 +146,10 @@ main(argc, argv)
if (*p != '\0')
infop = setinfo(type, p);
/* Open the DB. */
/*
* Open the DB. Delete any preexisting copy, you almost never
* want it around, and it often screws up tests.
*/
if (fname == NULL) {
p = getenv("TMPDIR");
if (p == NULL)
@ -147,7 +157,9 @@ main(argc, argv)
(void)sprintf(buf, "%s/__dbtest", p);
fname = buf;
(void)unlink(buf);
}
} else if (!sflag)
(void)unlink(fname);
if ((dbp = dbopen(fname,
oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL)
err("dbopen: %s", strerror(errno));
@ -156,8 +168,16 @@ main(argc, argv)
state = COMMAND;
for (lineno = 1;
(p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) {
len = strlen(buf);
switch(*p) {
/* Delete the newline, displaying the key/data is easier. */
if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL)
*t = '\0';
if ((len = strlen(buf)) == 0 || isspace(*p) || *p == '#')
continue;
/* Convenient gdb break point. */
if (XXlineno == lineno)
XXlineno = 1;
switch (*p) {
case 'c': /* compare */
if (state != COMMAND)
err("line %lu: not expecting command", lineno);
@ -170,7 +190,8 @@ main(argc, argv)
/* Don't display the newline, if CR at EOL. */
if (p[len - 2] == '\r')
--len;
if (write(ofd, p + 1, len - 1) != len - 1)
if (write(ofd, p + 1, len - 1) != len - 1 ||
write(ofd, "\n", 1) != 1)
err("write: %s", strerror(errno));
break;
case 'g': /* get */
@ -188,8 +209,19 @@ main(argc, argv)
case 'r': /* remove */
if (state != COMMAND)
err("line %lu: not expecting command", lineno);
state = KEY;
command = REMOVE;
if (flags == R_CURSOR) {
rem(dbp, &key);
state = COMMAND;
} else {
state = KEY;
command = REMOVE;
}
break;
case 'S': /* sync */
if (state != COMMAND)
err("line %lu: not expecting command", lineno);
synk(dbp);
state = COMMAND;
break;
case 's': /* seq */
if (state != COMMAND)
@ -213,7 +245,7 @@ main(argc, argv)
err("line %lu: not expecting data", lineno);
data.data = xmalloc(p + 1, len - 1);
data.size = len - 1;
ldata: switch(command) {
ldata: switch (command) {
case COMPARE:
compare(&keydata, &data);
break;
@ -249,7 +281,7 @@ ldata: switch(command) {
key.data = xmalloc(p + 1, len - 1);
key.size = len - 1;
}
lkey: switch(command) {
lkey: switch (command) {
case COMPARE:
getdata(dbp, &key, &keydata);
state = DATA;
@ -265,13 +297,13 @@ lkey: switch(command) {
break;
case REMOVE:
rem(dbp, &key);
if (type != DB_RECNO)
if ((type != DB_RECNO) && (flags != R_CURSOR))
free(key.data);
state = COMMAND;
break;
case SEQ:
seq(dbp, &key);
if (type != DB_RECNO)
if ((type != DB_RECNO) && (flags != R_CURSOR))
free(key.data);
state = COMMAND;
break;
@ -285,11 +317,15 @@ lkey: switch(command) {
break;
default:
err("line %lu: %s: unknown command character",
p, lineno);
lineno, p);
}
}
#ifdef STATISTICS
if (type == DB_BTREE)
/*
* -l must be used (DB_LOCK must be set) for this to be
* used, otherwise a page will be locked and it will fail.
*/
if (type == DB_BTREE && oflags & DB_LOCK)
__bt_stat(dbp);
#endif
if (dbp->close(dbp))
@ -299,7 +335,6 @@ lkey: switch(command) {
}
#define NOOVERWRITE "put failed, would overwrite key\n"
#define NOSUCHKEY "get failed, no such key\n"
void
compare(db1, db2)
@ -328,17 +363,23 @@ get(dbp, kp)
{
DBT data;
switch(dbp->get(dbp, kp, &data, flags)) {
switch (dbp->get(dbp, kp, &data, flags)) {
case 0:
(void)write(ofd, data.data, data.size);
if (ofd == STDOUT_FILENO)
(void)write(ofd, "\n", 1);
break;
case -1:
err("line %lu: get: %s", lineno, strerror(errno));
/* NOTREACHED */
case 1:
(void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
(void)fprintf(stderr, "%d: %.*s: %s\n",
lineno, kp->size, kp->data, NOSUCHKEY);
#define NOSUCHKEY "get failed, no such key\n"
if (ofd != STDOUT_FILENO)
(void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
else
(void)fprintf(stderr, "%d: %.*s: %s",
lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY);
#undef NOSUCHKEY
break;
}
}
@ -348,14 +389,14 @@ getdata(dbp, kp, dp)
DB *dbp;
DBT *kp, *dp;
{
switch(dbp->get(dbp, kp, dp, flags)) {
switch (dbp->get(dbp, kp, dp, flags)) {
case 0:
return;
case -1:
err("line %lu: getdata: %s", lineno, strerror(errno));
/* NOTREACHED */
case 1:
err("line %lu: get failed, no such key", lineno);
err("line %lu: getdata failed, no such key", lineno);
/* NOTREACHED */
}
}
@ -365,7 +406,7 @@ put(dbp, kp, dp)
DB *dbp;
DBT *kp, *dp;
{
switch(dbp->put(dbp, kp, dp, flags)) {
switch (dbp->put(dbp, kp, dp, flags)) {
case 0:
break;
case -1:
@ -382,18 +423,40 @@ rem(dbp, kp)
DB *dbp;
DBT *kp;
{
switch(dbp->del(dbp, kp, flags)) {
switch (dbp->del(dbp, kp, flags)) {
case 0:
break;
case -1:
err("line %lu: get: %s", lineno, strerror(errno));
err("line %lu: rem: %s", lineno, strerror(errno));
/* NOTREACHED */
case 1:
(void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
#define NOSUCHKEY "rem failed, no such key\n"
if (ofd != STDOUT_FILENO)
(void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
else if (flags != R_CURSOR)
(void)fprintf(stderr, "%d: %.*s: %s",
lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY);
else
(void)fprintf(stderr,
"%d: rem of cursor failed\n", lineno);
#undef NOSUCHKEY
break;
}
}
void
synk(dbp)
DB *dbp;
{
switch (dbp->sync(dbp, flags)) {
case 0:
break;
case -1:
err("line %lu: synk: %s", lineno, strerror(errno));
/* NOTREACHED */
}
}
void
seq(dbp, kp)
DB *dbp;
@ -401,15 +464,26 @@ seq(dbp, kp)
{
DBT data;
switch(dbp->seq(dbp, kp, &data, flags)) {
switch (dbp->seq(dbp, kp, &data, flags)) {
case 0:
(void)write(ofd, data.data, data.size);
if (ofd == STDOUT_FILENO)
(void)write(ofd, "\n", 1);
break;
case -1:
err("line %lu: seq: %s", lineno, strerror(errno));
/* NOTREACHED */
case 1:
(void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
#define NOSUCHKEY "seq failed, no such key\n"
if (ofd != STDOUT_FILENO)
(void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
else if (flags == R_CURSOR)
(void)fprintf(stderr, "%d: %.*s: %s",
lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY);
else
(void)fprintf(stderr,
"%d: seq (%s) failed\n", lineno, sflags(flags));
#undef NOSUCHKEY
break;
}
}
@ -430,9 +504,11 @@ dump(dbp, rev)
nflags = R_NEXT;
}
for (;; flags = nflags)
switch(dbp->seq(dbp, &key, &data, flags)) {
switch (dbp->seq(dbp, &key, &data, flags)) {
case 0:
(void)write(ofd, data.data, data.size);
if (ofd == STDOUT_FILENO)
(void)write(ofd, "\n", 1);
break;
case 1:
goto done;
@ -443,7 +519,7 @@ dump(dbp, rev)
}
done: return;
}
u_int
setflags(s)
char *s;
@ -451,32 +527,43 @@ setflags(s)
char *p, *index();
for (; isspace(*s); ++s);
if (*s == '\n')
if (*s == '\n' || *s == '\0')
return (0);
if ((p = index(s, '\n')) != NULL)
*p = '\0';
if (!strcmp(s, "R_CURSOR"))
return (R_CURSOR);
if (!strcmp(s, "R_FIRST"))
return (R_FIRST);
if (!strcmp(s, "R_IAFTER"))
return (R_IAFTER);
if (!strcmp(s, "R_IBEFORE"))
return (R_IBEFORE);
if (!strcmp(s, "R_LAST"))
return (R_LAST);
if (!strcmp(s, "R_NEXT"))
return (R_NEXT);
if (!strcmp(s, "R_NOOVERWRITE"))
return (R_NOOVERWRITE);
if (!strcmp(s, "R_PREV"))
return (R_PREV);
if (!strcmp(s, "R_SETCURSOR"))
return (R_SETCURSOR);
if (!strcmp(s, "R_CURSOR")) return (R_CURSOR);
if (!strcmp(s, "R_FIRST")) return (R_FIRST);
if (!strcmp(s, "R_IAFTER")) return (R_IAFTER);
if (!strcmp(s, "R_IBEFORE")) return (R_IBEFORE);
if (!strcmp(s, "R_LAST")) return (R_LAST);
if (!strcmp(s, "R_NEXT")) return (R_NEXT);
if (!strcmp(s, "R_NOOVERWRITE")) return (R_NOOVERWRITE);
if (!strcmp(s, "R_PREV")) return (R_PREV);
if (!strcmp(s, "R_SETCURSOR")) return (R_SETCURSOR);
err("line %lu: %s: unknown flag", lineno, s);
/* NOTREACHED */
}
char *
sflags(flags)
int flags;
{
switch (flags) {
case R_CURSOR: return ("R_CURSOR");
case R_FIRST: return ("R_FIRST");
case R_IAFTER: return ("R_IAFTER");
case R_IBEFORE: return ("R_IBEFORE");
case R_LAST: return ("R_LAST");
case R_NEXT: return ("R_NEXT");
case R_NOOVERWRITE: return ("R_NOOVERWRITE");
case R_PREV: return ("R_PREV");
case R_SETCURSOR: return ("R_SETCURSOR");
}
return ("UNKNOWN!");
}
DBTYPE
dbtype(s)
char *s;
@ -506,8 +593,8 @@ setinfo(type, s)
*eq++ = '\0';
if (!isdigit(*eq))
err("%s: structure set statement must be a number", s);
switch(type) {
switch (type) {
case DB_BTREE:
if (!strcmp("flags", s)) {
ib.flags = atoi(eq);